diff --git a/.codeclimate.yml b/.codeclimate.yml index 975bbe566c8..009a4859a06 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -6,7 +6,6 @@ languages: exclude_paths: - "app/assets/javascripts/defer/*" - - "app/assets/javascripts/discourse/lib/Markdown.Editor.js" - "app/assets/javascripts/ember-addons/*" - "lib/autospec/*" - "lib/es6_module_transpiler/*" diff --git a/.eslintignore b/.eslintignore index 5b61bf6c51f..a520c62c910 100644 --- a/.eslintignore +++ b/.eslintignore @@ -6,9 +6,8 @@ app/assets/javascripts/pagedown_custom.js app/assets/javascripts/vendor.js app/assets/javascripts/locales/i18n.js app/assets/javascripts/defer/html-sanitizer-bundle.js -app/assets/javascripts/discourse/lib/Markdown.Editor.js app/assets/javascripts/ember-addons/ -jsapp/lib/Markdown.Editor.js +app/assets/javascripts/discourse/lib/autosize.js.es6 lib/javascripts/locale/ lib/javascripts/messageformat.js lib/javascripts/moment.js @@ -18,8 +17,8 @@ lib/es6_module_transpiler/support/es6-module-transpiler.js public/javascripts/ spec/phantom_js/smoke_test.js vendor/ -test/javascripts/helpers/ test/javascripts/test_helper.js test/javascripts/test_helper.js test/javascripts/fixtures +test/javascripts/helpers/assertions.js app/assets/javascripts/ember-addons/ diff --git a/.eslintrc b/.eslintrc index d2a13ae262d..2b3ed3ba7df 100644 --- a/.eslintrc +++ b/.eslintrc @@ -90,6 +90,7 @@ "no-undef": 2, "no-unused-vars": 2, "no-with": 2, + "no-this-before-super": 2, "semi": 2, "strict": 0, "valid-typeof": 2, diff --git a/.gitignore b/.gitignore index 7b2156d4d56..95d44c86f8a 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,7 @@ log/ !/plugins/emoji/ !/plugins/lazyYT/ !/plugins/poll/ +!/plugins/discourse-details/ /plugins/*/auto_generated/ /spec/fixtures/plugins/my_plugin/auto_generated @@ -57,6 +58,9 @@ log/ # Ignore Eclipse .buildpath file /.buildpath +# Ignore byebug history +/.byebug_history + # Ignore RubyMine settings /.idea diff --git a/.travis.yml b/.travis.yml index 62961abc4a2..b06b741d924 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,6 @@ env: - RUBY_GC_MALLOC_LIMIT=50000000 matrix: - "RAILS_MASTER=0" - - "RAILS42=1" - "RAILS_MASTER=1" addons: @@ -21,7 +20,6 @@ addons: matrix: allow_failures: - env: "RAILS_MASTER=1" - - env: "RAILS42=1" - rvm: rbx-2 fast_finish: true @@ -29,6 +27,7 @@ rvm: - 2.0.0 - 2.1 - 2.2 + - 2.3.0 services: - redis-server @@ -41,7 +40,7 @@ cache: before_install: - gem install bundler - - npm i -g eslint babel-eslint + - npm i -g eslint@2.2 babel-eslint - eslint app/assets/javascripts - eslint --ext .es6 app/assets/javascripts - eslint --ext .es6 test/javascripts @@ -51,7 +50,6 @@ before_script: - bundle exec rake db:create db:migrate install: - - bash -c "if [ '$RAILS42' == '1' ]; then bundle update --retry=3 --jobs=3 rails rails-observers; fi" - bash -c "if [ '$RAILS_MASTER' == '1' ]; then bundle update --retry=3 --jobs=3 arel rails rails-observers seed-fu; fi" - bash -c "if [ '$RAILS_MASTER' == '0' ]; then bundle install --without development --deployment --retry=3 --jobs=3; fi" diff --git a/.tx/config b/.tx/config index bba3633be7f..718e97b54cb 100644 --- a/.tx/config +++ b/.tx/config @@ -1,6 +1,6 @@ [main] host = https://www.transifex.com -lang_map = es_ES: es, fr_FR: fr, ko_KR: ko, pt_PT: pt +lang_map = es_ES: es, fr_FR: fr, ko_KR: ko, pt_PT: pt, sk_SK: sk, vi_VN: vi [discourse-org.clientenyml] file_filter = config/locales/client..yml diff --git a/Gemfile b/Gemfile index 30b8d469d71..9784a3ff5e9 100644 --- a/Gemfile +++ b/Gemfile @@ -6,48 +6,56 @@ def rails_master? ENV["RAILS_MASTER"] == '1' end -def rails_42? - ENV["RAILS42"] == '1' -end - if rails_master? gem 'arel', git: 'https://github.com/rails/arel.git' gem 'rails', git: 'https://github.com/rails/rails.git' gem 'rails-observers', git: 'https://github.com/rails/rails-observers.git' gem 'seed-fu', git: 'https://github.com/SamSaffron/seed-fu.git', branch: 'discourse' -elsif rails_42? - gem 'rails', '~> 4.2.1' - gem 'rails-observers', git: 'https://github.com/rails/rails-observers.git' - gem 'seed-fu', '~> 2.3.5' else - gem 'rails', '~> 4.1.10' + # Rails 5 is going to ship with Action Cable, we have no use for it as + # we already ship MessageBus, AC introduces dependencies on Event Machine, + # Celluloid and Faye Web Sockets. + # + # Note this means upgrading Rails is more annoying, to do so, comment out the + # explicit dependencies, and add gem 'rails', bundle update rails and then + # comment back the explicit dependencies. Leaving this in a comment till we + # upgrade to Rails 5 + # + # gem 'activesupport' + # gem 'actionpack' + # gem 'activerecord' + # gem 'actionmailer' + # gem 'activejob' + # gem 'railties' + # gem 'sprockets-rails' + gem 'rails', '~> 4.2' + gem 'rails-observers' - gem 'seed-fu', '~> 2.3.3' + gem 'seed-fu', '~> 2.3.5' end -# Rails 4.1.6+ will relax the mail gem version requirement to `~> 2.5, >= 2.5.4`. -# However, mail gem 2.6.x currently does not work with discourse because of the -# reference to `Mail::RFC2822Parser` in `lib/email.rb`. This ensure discourse -# would continue to work with Rails 4.1.6+ when it is released. -gem 'mail', '~> 2.5.4' +gem 'mail' +gem 'mime-types', require: 'mime/types/columnar' -#gem 'redis-rails' gem 'hiredis' gem 'redis', require: ["redis", "redis/connection/hiredis"] +gem 'redis-namespace' gem 'active_model_serializers', '~> 0.8.3' gem 'onebox' +gem 'http_accept_language', '~>2.0.5', require: false + gem 'ember-rails' gem 'ember-source', '1.12.2' gem 'barber' gem 'babel-transpiler' -gem 'message_bus' -gem 'rails_multisite', path: 'vendor/gems/rails_multisite' +gem 'message_bus', '2.0.0.beta.5' + +gem 'rails_multisite' -gem 'redcarpet', require: false gem 'fast_xs' gem 'fast_xor' @@ -58,7 +66,7 @@ gem 'aws-sdk', require: false gem 'excon', require: false gem 'unf', require: false -gem 'email_reply_parser' +gem 'email_reply_trimmer', '0.1.3' # note: for image_optim to correctly work you need to follow # https://github.com/toy/image_optim @@ -72,11 +80,13 @@ gem 'omniauth-openid' gem 'openid-redis-store' gem 'omniauth-facebook' gem 'omniauth-twitter' +gem 'omniauth-instagram' # forked while https://github.com/intridea/omniauth-github/pull/41 is being upstreamd gem 'omniauth-github-discourse', require: 'omniauth-github' gem 'omniauth-oauth2', require: false + gem 'omniauth-google-oauth2' gem 'oj' gem 'pg' @@ -130,9 +140,10 @@ group :test, :development do gem 'simplecov', require: false gem 'timecop' gem 'rspec-given' - gem 'pry-nav' + gem 'rspec-html-matchers' gem 'spork-rails' - gem 'byebug' + gem 'pry-nav' + gem 'byebug', require: ENV['RM_INFO'].nil? end group :development do @@ -173,12 +184,17 @@ gem 'simple-rss', require: false gem 'gctools', require: false, platform: :mri_21 begin - gem 'stackprof', require: false, platform: [:mri_21, :mri_22] - gem 'memory_profiler', require: false, platform: [:mri_21, :mri_22] + gem 'stackprof', require: false, platform: [:mri_21, :mri_22, :mri_23] + gem 'memory_profiler', require: false, platform: [:mri_21, :mri_22, :mri_23] rescue Bundler::GemfileError - STDERR.puts "You are running an old version of bundler, please upgrade bundler ASAP, if you are using Discourse docker, rebuild your container." - gem 'stackprof', require: false, platform: [:mri_21] - gem 'memory_profiler', require: false, platform: [:mri_21] + begin + STDERR.puts "You are running an old version of bundler, please upgrade bundler ASAP, if you are using Discourse docker, rebuild your container." + gem 'stackprof', require: false, platform: [:mri_21, :mri_22] + gem 'memory_profiler', require: false, platform: [:mri_21, :mri_22] + rescue Bundler::GemfileError + gem 'stackprof', require: false, platform: [:mri_21] + gem 'memory_profiler', require: false, platform: [:mri_21] + end end gem 'rmmseg-cpp', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 48b704161de..c94f88af50d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,52 +1,54 @@ -PATH - remote: vendor/gems/rails_multisite - specs: - rails_multisite (0.0.1) - GEM remote: https://rubygems.org/ specs: - actionmailer (4.1.10) - actionpack (= 4.1.10) - actionview (= 4.1.10) + actionmailer (4.2.6) + actionpack (= 4.2.6) + actionview (= 4.2.6) + activejob (= 4.2.6) mail (~> 2.5, >= 2.5.4) - actionpack (4.1.10) - actionview (= 4.1.10) - activesupport (= 4.1.10) - rack (~> 1.5.2) + rails-dom-testing (~> 1.0, >= 1.0.5) + actionpack (4.2.6) + actionview (= 4.2.6) + activesupport (= 4.2.6) + rack (~> 1.6) rack-test (~> 0.6.2) - actionview (4.1.10) - activesupport (= 4.1.10) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (4.2.6) + activesupport (= 4.2.6) builder (~> 3.1) erubis (~> 2.7.0) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.2) active_model_serializers (0.8.3) activemodel (>= 3.0) - activemodel (4.1.10) - activesupport (= 4.1.10) + activejob (4.2.6) + activesupport (= 4.2.6) + globalid (>= 0.3.0) + activemodel (4.2.6) + activesupport (= 4.2.6) builder (~> 3.1) - activerecord (4.1.10) - activemodel (= 4.1.10) - activesupport (= 4.1.10) - arel (~> 5.0.0) - activesupport (4.1.10) - i18n (~> 0.6, >= 0.6.9) + activerecord (4.2.6) + activemodel (= 4.2.6) + activesupport (= 4.2.6) + arel (~> 6.0) + activesupport (4.2.6) + i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) - thread_safe (~> 0.1) + thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - annotate (2.6.6) - activerecord (>= 2.3.0) - rake (~> 10.4.2, >= 10.4.2) - arel (5.0.1.20140414130214) - aws-sdk (2.0.45) - aws-sdk-resources (= 2.0.45) - aws-sdk-core (2.0.45) - builder (~> 3.0) + annotate (2.7.0) + activerecord (>= 3.2, < 6.0) + rake (~> 10.4) + arel (6.0.3) + aws-sdk (2.2.9) + aws-sdk-resources (= 2.2.9) + aws-sdk-core (2.2.9) jmespath (~> 1.0) - multi_json (~> 1.0) - aws-sdk-resources (2.0.45) - aws-sdk-core (= 2.0.45) - babel-source (5.8.19) + aws-sdk-resources (2.2.9) + aws-sdk-core (= 2.2.9) + babel-source (5.8.34) babel-transpiler (0.7.0) babel-source (>= 4.0, < 6) execjs (~> 2.0) @@ -60,23 +62,21 @@ GEM binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) builder (3.2.2) - byebug (5.0.0) - columnize (= 0.9.0) - celluloid (0.16.0) - timers (~> 4.0.0) + byebug (8.2.1) certified (1.0.0) coderay (1.1.0) - columnize (0.9.0) + concurrent-ruby (1.0.0) connection_pool (2.2.0) - crass (1.0.1) - daemons (1.2.2) + crass (1.0.2) + daemons (1.2.3) debug_inspector (0.0.2) diff-lcs (1.2.5) discourse-qunit-rails (0.0.8) railties docile (1.1.5) - dotenv (1.0.2) - email_reply_parser (0.5.8) + domain_name (0.5.25) + unf (>= 0.0.5, < 1.0.0) + email_reply_trimmer (0.1.3) ember-data-source (1.0.0.beta.16.1) ember-source (~> 1.8) ember-handlebars-template (0.1.5) @@ -91,15 +91,15 @@ GEM railties (>= 3.1) ember-source (1.12.2) erubis (2.7.0) - eventmachine (1.0.7) - excon (0.45.3) - execjs (2.5.2) - exifr (1.2.2) + eventmachine (1.0.8) + excon (0.45.4) + execjs (2.6.0) + exifr (1.2.4) fabrication (2.9.8) fakeweb (1.3.0) - faraday (0.9.1) + faraday (0.9.2) multipart-post (>= 1.2, < 3) - fast_blank (0.0.2) + fast_blank (1.0.0) fast_stack (0.1.0) rake rake-compiler @@ -108,23 +108,26 @@ GEM rake-compiler fast_xs (0.8.0) fastimage_discourse (1.6.6) - ffi (1.9.6) + ffi (1.9.10) flamegraph (0.1.0) fast_stack - foreman (0.77.0) - dotenv (~> 1.0.2) + foreman (0.78.0) thor (~> 0.19.1) fspath (2.1.1) gctools (0.2.3) - given_core (3.5.4) + given_core (3.7.1) sorcerer (>= 0.3.7) + globalid (0.3.6) + activesupport (>= 4.1.0) guess_html_encoding (0.0.11) - hashie (3.4.0) - highline (1.7.1) + hashie (3.4.3) + highline (1.7.8) hike (1.2.3) - hiredis (0.6.0) - hitimes (1.2.2) - htmlentities (4.3.3) + hiredis (0.6.1) + htmlentities (4.3.4) + http-cookie (1.0.2) + domain_name (~> 0.5) + http_accept_language (2.0.5) i18n (0.7.0) image_optim (0.20.2) exifr (~> 1.1, >= 1.1.3) @@ -134,46 +137,46 @@ GEM progress (~> 3.0, >= 3.0.1) image_size (1.4.1) in_threads (1.3.1) - jmespath (1.0.2) - multi_json (~> 1.0) - jquery-rails (3.1.2) - railties (>= 3.0, < 5.0) + jmespath (1.1.3) + jquery-rails (4.0.5) + rails-dom-testing (~> 1.0) + railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (1.8.3) - jwt (1.3.0) - kgio (2.9.3) + jwt (1.5.2) + kgio (2.10.0) librarian (0.1.2) highline thor (~> 0.15) - libv8 (3.16.14.7) + libv8 (3.16.14.13) listen (0.7.3) - logster (1.0.0.3.pre) + logster (1.2.2) + loofah (2.0.3) + nokogiri (>= 1.5.9) lru_redux (1.1.0) - mail (2.5.4) - mime-types (~> 1.16) - treetop (~> 1.4.8) - memory_profiler (0.9.3) - message_bus (1.0.16) + mail (2.6.4) + mime-types (>= 1.16, < 4) + memory_profiler (0.9.6) + message_bus (2.0.0.beta.5) rack (>= 1.1.3) - redis metaclass (0.0.4) method_source (0.8.2) - mime-types (1.25.1) - mini_portile (0.6.2) - minitest (5.6.1) + mime-types (2.99.1) + mini_portile2 (2.0.0) + minitest (5.8.4) mocha (1.1.0) metaclass (~> 0.0.1) - mock_redis (0.14.0) + mock_redis (0.15.4) moneta (0.8.0) - msgpack (0.5.11) + msgpack (0.7.4) multi_json (1.11.2) multi_xml (0.5.5) multipart-post (2.0.0) - mustache (1.0.2) - netrc (0.10.3) - nokogiri (1.6.6.2) - mini_portile (~> 0.6.0) - nokogumbo (1.2.0) + mustache (1.0.3) + netrc (0.11.0) + nokogiri (1.6.7.2) + mini_portile2 (~> 2.0.0.rc2) + nokogumbo (1.4.7) nokogiri oauth (0.4.7) oauth2 (1.0.0) @@ -182,33 +185,37 @@ GEM multi_json (~> 1.3) multi_xml (~> 0.5) rack (~> 1.2) - oj (2.12.9) - omniauth (1.2.2) + oj (2.14.3) + omniauth (1.3.1) hashie (>= 1.2, < 4) - rack (~> 1.0) - omniauth-facebook (2.0.0) + rack (>= 1.0, < 3) + omniauth-facebook (3.0.0) omniauth-oauth2 (~> 1.2) omniauth-github-discourse (1.1.2) omniauth (~> 1.0) omniauth-oauth2 (~> 1.1) - omniauth-google-oauth2 (0.2.5) - omniauth (> 1.0) - omniauth-oauth2 (~> 1.1) - omniauth-oauth (1.0.1) + omniauth-google-oauth2 (0.3.1) + jwt (~> 1.0) + multi_json (~> 1.3) + omniauth (>= 1.1.1) + omniauth-oauth2 (>= 1.3.1) + omniauth-instagram (1.0.2) + omniauth (~> 1) + omniauth-oauth2 (~> 1) + omniauth-oauth (1.1.0) oauth omniauth (~> 1.0) - omniauth-oauth2 (1.2.0) - faraday (>= 0.8, < 0.10) - multi_json (~> 1.3) + omniauth-oauth2 (1.3.1) oauth2 (~> 1.0) omniauth (~> 1.2) omniauth-openid (1.0.1) omniauth (~> 1.0) rack-openid (~> 1.3.1) - omniauth-twitter (1.0.1) - multi_json (~> 1.3) - omniauth-oauth (~> 1.0) - onebox (1.5.26) + omniauth-twitter (1.2.1) + json (~> 1.3) + omniauth-oauth (~> 1.1) + onebox (1.5.38) + htmlentities (~> 4.3.4) moneta (~> 0.8) multi_json (~> 1.11) mustache @@ -216,23 +223,21 @@ GEM openid-redis-store (0.0.2) redis ruby-openid - pg (0.18.1) - polyglot (0.3.5) - progress (3.1.0) - pry (0.10.1) + pg (0.18.4) + progress (3.1.1) + pry (0.10.3) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) pry-nav (0.2.4) pry (>= 0.9.10, < 0.11.0) - pry-rails (0.3.3) + pry-rails (0.3.4) pry (>= 0.9.10) - puma (2.11.1) - rack (>= 1.1, < 2.0) - r2 (0.2.5) - rack (1.5.5) - rack-mini-profiler (0.9.6) - rack (>= 1.1.3) + puma (3.2.0) + r2 (0.2.6) + rack (1.6.4) + rack-mini-profiler (0.9.9.2) + rack (>= 1.2.0) rack-openid (1.3.1) rack (>= 1.1.0) ruby-openid (>= 2.1.8) @@ -240,40 +245,50 @@ GEM rack rack-test (0.6.3) rack (>= 1.0) - rails (4.1.10) - actionmailer (= 4.1.10) - actionpack (= 4.1.10) - actionview (= 4.1.10) - activemodel (= 4.1.10) - activerecord (= 4.1.10) - activesupport (= 4.1.10) + rails (4.2.6) + actionmailer (= 4.2.6) + actionpack (= 4.2.6) + actionview (= 4.2.6) + activejob (= 4.2.6) + activemodel (= 4.2.6) + activerecord (= 4.2.6) + activesupport (= 4.2.6) bundler (>= 1.3.0, < 2.0) - railties (= 4.1.10) - sprockets-rails (~> 2.0) + railties (= 4.2.6) + sprockets-rails + rails-deprecated_sanitizer (1.0.3) + activesupport (>= 4.2.0.alpha) + rails-dom-testing (1.0.7) + activesupport (>= 4.2.0.beta, < 5.0) + nokogiri (~> 1.6.0) + rails-deprecated_sanitizer (>= 1.0.1) + rails-html-sanitizer (1.0.3) + loofah (~> 2.0) rails-observers (0.1.2) activemodel (~> 4.0) - railties (4.1.10) - actionpack (= 4.1.10) - activesupport (= 4.1.10) + rails_multisite (1.0.3) + railties (4.2.6) + actionpack (= 4.2.6) + activesupport (= 4.2.6) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - raindrops (0.13.0) - rake (10.4.2) - rake-compiler (0.9.4) + raindrops (0.15.0) + rake (10.5.0) + rake-compiler (0.9.5) rake - rb-fsevent (0.9.4) + rb-fsevent (0.9.7) rb-inotify (0.9.5) ffi (>= 0.5.0) rbtrace (0.4.7) ffi (>= 1.0.6) msgpack (>= 0.4.3) trollop (>= 1.16.2) - redcarpet (3.2.2) - redis (3.2.1) + redis (3.2.2) redis-namespace (1.5.2) redis (~> 3.0, >= 3.0.4) - ref (1.0.5) - rest-client (1.7.2) + ref (2.0.0) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 3.0) netrc (~> 0.7) rinku (1.7.3) @@ -287,13 +302,16 @@ GEM rspec-expectations (3.2.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.2.0) - rspec-given (3.5.4) - given_core (= 3.5.4) - rspec (>= 2.12) + rspec-given (3.7.1) + given_core (= 3.7.1) + rspec (>= 2.14.0) + rspec-html-matchers (0.7.0) + nokogiri (~> 1) + rspec (~> 3) rspec-mocks (3.2.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.2.0) - rspec-rails (3.2.1) + rspec-rails (3.2.3) actionpack (>= 3.0, < 4.3) activesupport (>= 3.0, < 4.3) railties (>= 3.0, < 4.3) @@ -303,14 +321,14 @@ GEM rspec-support (~> 3.2.0) rspec-support (3.2.2) rtlit (0.0.5) - ruby-openid (2.5.0) + ruby-openid (2.7.0) ruby-readability (0.7.0) guess_html_encoding (>= 0.0.4) nokogiri (>= 1.6.0) - sanitize (3.1.2) - crass (~> 1.0.1) + sanitize (4.0.1) + crass (~> 1.0.2) nokogiri (>= 1.4.4) - nokogumbo (= 1.2.0) + nokogumbo (~> 1.4.1) sass (3.2.19) sass-rails (4.0.5) railties (>= 4.0.0, < 5.0) @@ -324,26 +342,24 @@ GEM shoulda-context (~> 1.0, >= 1.0.1) shoulda-matchers (>= 1.4.1, < 3.0) shoulda-context (1.2.1) - shoulda-matchers (2.7.0) + shoulda-matchers (2.8.0) activesupport (>= 3.0.0) - sidekiq (3.4.2) - celluloid (~> 0.16.0) + sidekiq (4.0.2) + concurrent-ruby (~> 1.0) connection_pool (~> 2.2, >= 2.2.0) - json (~> 1.0) redis (~> 3.2, >= 3.2.1) - redis-namespace (~> 1.5, >= 1.5.2) - sidekiq-statistic (1.1.0) - sidekiq (~> 3.3, >= 3.3.4) + sidekiq-statistic (1.2.0) + sidekiq (>= 3.3.4, < 5) simple-rss (1.3.1) - simplecov (0.9.1) + simplecov (0.11.1) docile (~> 1.1.0) - multi_json (~> 1.0) - simplecov-html (~> 0.8.0) - simplecov-html (0.8.0) - sinatra (1.4.5) + json (~> 1.8) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) + sinatra (1.4.6) rack (~> 1.4) rack-protection (~> 1.4) - tilt (~> 1.3, >= 1.3.4) + tilt (>= 1.3, < 3) slop (3.6.0) sorcerer (1.0.2) spork (1.0.0rc4) @@ -363,29 +379,24 @@ GEM therubyracer (0.12.2) libv8 (~> 3.16.14.0) ref - thin (1.6.3) + thin (1.6.4) daemons (~> 1.0, >= 1.0.9) - eventmachine (~> 1.0) + eventmachine (~> 1.0, >= 1.0.4) rack (~> 1.0) thor (0.19.1) thread_safe (0.3.5) tilt (1.4.1) - timecop (0.7.3) - timers (4.0.1) - hitimes - treetop (1.4.15) - polyglot - polyglot (>= 0.3.1) - trollop (2.1.1) + timecop (0.8.0) + trollop (2.1.2) tzinfo (1.2.2) thread_safe (~> 0.1) - uglifier (2.7.1) + uglifier (2.7.2) execjs (>= 0.3.0) json (>= 1.8.0) unf (0.1.4) unf_ext - unf_ext (0.0.6) - unicorn (4.8.3) + unf_ext (0.0.7.1) + unicorn (5.0.1) kgio (~> 2.6) rack raindrops (~> 0.7) @@ -404,7 +415,7 @@ DEPENDENCIES byebug certified discourse-qunit-rails - email_reply_parser + email_reply_trimmer (= 0.1.3) ember-rails ember-source (= 1.12.2) excon @@ -420,14 +431,16 @@ DEPENDENCIES highline hiredis htmlentities + http_accept_language (~> 2.0.5) image_optim (= 0.20.2) librarian (>= 0.0.25) listen (= 0.7.3) logster lru_redux - mail (~> 2.5.4) + mail memory_profiler - message_bus + message_bus (= 2.0.0.beta.5) + mime-types minitest mocha mock_redis @@ -439,6 +452,7 @@ DEPENDENCIES omniauth-facebook omniauth-github-discourse omniauth-google-oauth2 + omniauth-instagram omniauth-oauth2 omniauth-openid omniauth-twitter @@ -451,27 +465,28 @@ DEPENDENCIES r2 (~> 0.2.5) rack-mini-profiler rack-protection - rails (~> 4.1.10) + rails (~> 4.2) rails-observers - rails_multisite! + rails_multisite rake rb-fsevent rb-inotify (~> 0.9) rbtrace - redcarpet redis + redis-namespace rest-client rinku rmmseg-cpp rspec (~> 3.2.0) rspec-given + rspec-html-matchers rspec-rails rtlit ruby-readability sanitize sass sass-rails (~> 4.0.5) - seed-fu (~> 2.3.3) + seed-fu (~> 2.3.5) shoulda sidekiq sidekiq-statistic @@ -488,4 +503,4 @@ DEPENDENCIES unicorn BUNDLED WITH - 1.10.6 + 1.11.2 diff --git a/README.md b/README.md index f9ec9f906ef..cdd0b8a9bd7 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ To learn more about the philosophy and goals of the project, [visit **discourse. ## Screenshots - - + + Atom   @@ -22,9 +22,9 @@ Browse [lots more notable Discourse instances](http://www.discourse.org/faq/cust ## Development -1. If you're **brand new to Ruby and Rails**, please see [**Discourse as Your First Rails App**](http://blog.discourse.org/2013/04/discourse-as-your-first-rails-app/) or our [**Discourse Vagrant Developer Guide**](docs/VAGRANT.md), which includes a development environment in a virtual machine. +1. If you're **brand new to Ruby and Rails**, please see [**Discourse as Your First Rails App**](http://blog.discourse.org/2013/04/discourse-as-your-first-rails-app/) or our [**Discourse Vagrant Developer Guide**](docs/VAGRANT.md), which includes a development environment in a virtual machine. -2. If you're familiar with how Rails works and are comfortable setting up your own environment, use our [**Discourse Advanced Developer Guide**](docs/DEVELOPER-ADVANCED.md). +2. If you're familiar with how Rails works and are comfortable setting up your own environment, use our [**Discourse Advanced Developer Guide**](docs/DEVELOPER-ADVANCED.md). Before you get started, ensure you have the following minimum versions: [Ruby 2.0.0+](http://www.ruby-lang.org/en/downloads/), [PostgreSQL 9.3+](http://www.postgresql.org/download/), [Redis 2.6+](http://redis.io/download). If you're having trouble, please see our [**TROUBLESHOOTING GUIDE**](docs/TROUBLESHOOTING.md) first! @@ -40,13 +40,11 @@ Discourse is built for the *next* 10 years of the Internet, so our requirements | Browsers | Tablets | Smartphones | | -------- | ------- | ----------- | -| Safari 5.1+| iPad 2+ | iOS 7+ | -| Google Chrome 23+ | Android 4.1+ | Android 4.1+ | +| Safari 5.1+| iPad 2+ | iOS 7+ | +| Google Chrome 23+ | Android 4.3+ | Android 4.3+ | | Internet Explorer 10+ | Windows 8 | Windows Phone 8 | | Firefox 16+ | | -Internet Explorer 9.0 will no longer be supported in 2016. - ## Built With - [Ruby on Rails](https://github.com/rails/rails) — Our back end API is a Rails app. It responds to requests RESTfully in JSON. @@ -58,7 +56,7 @@ Plus *lots* of Ruby Gems, a complete list of which is at [/master/Gemfile](https ## Contributing -[![Build Status](https://travis-ci.org/discourse/discourse.svg)](https://travis-ci.org/discourse/discourse) +[![Build Status](https://api.travis-ci.org/discourse/discourse.svg?branch=master)](https://travis-ci.org/discourse/discourse) [![Code Climate](https://codeclimate.com/github/discourse/discourse.svg)](https://codeclimate.com/github/discourse/discourse) Discourse is **100% free** and **open source**. We encourage and support an active, healthy community that @@ -69,7 +67,9 @@ Before contributing to Discourse: 1. Please read the complete mission statements on [**discourse.org**](http://www.discourse.org). Yes we actually believe this stuff; you should too. 2. Read and sign the [**Electronic Discourse Forums Contribution License Agreement**](http://discourse.org/cla). 3. Dig into [**CONTRIBUTING.MD**](CONTRIBUTING.md), which covers submitting bugs, requesting new features, preparing your code for a pull request, etc. -4. Not sure what to work on? [**We've got some ideas.**](http://meta.discourse.org/t/so-you-want-to-help-out-with-discourse/3823) +4. Always strive to collaborate [with mutual respect](https://github.com/discourse/discourse/blob/master/docs/code-of-conduct.md). +5. Not sure what to work on? [**We've got some ideas.**](http://meta.discourse.org/t/so-you-want-to-help-out-with-discourse/3823) + We look forward to seeing your pull requests! diff --git a/app/assets/fonts/FontAwesome.otf b/app/assets/fonts/FontAwesome.otf index 681bdd4d4c8..3ed7f8b48ad 100644 Binary files a/app/assets/fonts/FontAwesome.otf and b/app/assets/fonts/FontAwesome.otf differ diff --git a/app/assets/fonts/fontawesome-webfont.eot b/app/assets/fonts/fontawesome-webfont.eot index a30335d748c..9b6afaedc0f 100644 Binary files a/app/assets/fonts/fontawesome-webfont.eot and b/app/assets/fonts/fontawesome-webfont.eot differ diff --git a/app/assets/fonts/fontawesome-webfont.svg b/app/assets/fonts/fontawesome-webfont.svg index 6fd19abcb9e..d05688e9e28 100644 --- a/app/assets/fonts/fontawesome-webfont.svg +++ b/app/assets/fonts/fontawesome-webfont.svg @@ -1,6 +1,6 @@ - + @@ -219,8 +219,8 @@ - - + + @@ -362,7 +362,7 @@ - + @@ -410,7 +410,7 @@ - + @@ -454,7 +454,7 @@ - + @@ -555,7 +555,7 @@ - + @@ -600,11 +600,11 @@ - - + + - + @@ -621,20 +621,35 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/assets/fonts/fontawesome-webfont.ttf b/app/assets/fonts/fontawesome-webfont.ttf index d7994e13086..26dea7951a7 100644 Binary files a/app/assets/fonts/fontawesome-webfont.ttf and b/app/assets/fonts/fontawesome-webfont.ttf differ diff --git a/app/assets/fonts/fontawesome-webfont.woff b/app/assets/fonts/fontawesome-webfont.woff index 6fd4ede0f30..dc35ce3c2cf 100644 Binary files a/app/assets/fonts/fontawesome-webfont.woff and b/app/assets/fonts/fontawesome-webfont.woff differ diff --git a/app/assets/fonts/fontawesome-webfont.woff2 b/app/assets/fonts/fontawesome-webfont.woff2 index 5560193ccc5..500e5172534 100644 Binary files a/app/assets/fonts/fontawesome-webfont.woff2 and b/app/assets/fonts/fontawesome-webfont.woff2 differ diff --git a/app/assets/images/favicons/google_branding/logo_calendar_128px.png b/app/assets/images/favicons/google_branding/logo_calendar_128px.png new file mode 100644 index 00000000000..0adf29c12d3 Binary files /dev/null and b/app/assets/images/favicons/google_branding/logo_calendar_128px.png differ diff --git a/app/assets/images/favicons/google_branding/logo_docs_128px.png b/app/assets/images/favicons/google_branding/logo_docs_128px.png new file mode 100644 index 00000000000..a1c4e5f7bd5 Binary files /dev/null and b/app/assets/images/favicons/google_branding/logo_docs_128px.png differ diff --git a/app/assets/images/favicons/google_branding/logo_drive_128px.png b/app/assets/images/favicons/google_branding/logo_drive_128px.png new file mode 100644 index 00000000000..0eb48a7469f Binary files /dev/null and b/app/assets/images/favicons/google_branding/logo_drive_128px.png differ diff --git a/app/assets/images/favicons/google_branding/logo_forms_128px.png b/app/assets/images/favicons/google_branding/logo_forms_128px.png new file mode 100644 index 00000000000..621321b0cf7 Binary files /dev/null and b/app/assets/images/favicons/google_branding/logo_forms_128px.png differ diff --git a/app/assets/images/favicons/google_branding/logo_sheets_128px.png b/app/assets/images/favicons/google_branding/logo_sheets_128px.png new file mode 100644 index 00000000000..a99181d743d Binary files /dev/null and b/app/assets/images/favicons/google_branding/logo_sheets_128px.png differ diff --git a/app/assets/images/favicons/google_branding/logo_slides_128px.png b/app/assets/images/favicons/google_branding/logo_slides_128px.png new file mode 100644 index 00000000000..538226c80f4 Binary files /dev/null and b/app/assets/images/favicons/google_branding/logo_slides_128px.png differ diff --git a/app/assets/javascripts/admin/adapters/site-text-type.js.es6 b/app/assets/javascripts/admin/adapters/site-text-type.js.es6 deleted file mode 100644 index b547b06f3ca..00000000000 --- a/app/assets/javascripts/admin/adapters/site-text-type.js.es6 +++ /dev/null @@ -1,2 +0,0 @@ -import CustomizationBase from 'admin/adapters/customization-base'; -export default CustomizationBase; diff --git a/app/assets/javascripts/admin/components/embedding-setting.js.es6 b/app/assets/javascripts/admin/components/embedding-setting.js.es6 index 904afacfee1..f1d31fcf68b 100644 --- a/app/assets/javascripts/admin/components/embedding-setting.js.es6 +++ b/app/assets/javascripts/admin/components/embedding-setting.js.es6 @@ -16,7 +16,7 @@ export default Ember.Component.extend({ checked: { get(value) { return !!value; }, set(value) { - this.set('value', value); + this.set('value', value); return value; } } diff --git a/app/assets/javascripts/admin/components/expanding-text-area.js.es6 b/app/assets/javascripts/admin/components/expanding-text-area.js.es6 new file mode 100644 index 00000000000..f7259e83018 --- /dev/null +++ b/app/assets/javascripts/admin/components/expanding-text-area.js.es6 @@ -0,0 +1,24 @@ +import { on, observes } from 'ember-addons/ember-computed-decorators'; +import autosize from 'discourse/lib/autosize'; + +export default Ember.TextArea.extend({ + @on('didInsertElement') + _startWatching() { + Ember.run.scheduleOnce('afterRender', () => { + this.$().focus(); + autosize(this.element); + }); + }, + + @observes('value') + _updateAutosize() { + const evt = document.createEvent('Event'); + evt.initEvent('autosize:update', true, false); + this.element.dispatchEvent(evt); + }, + + @on('willDestroyElement') + _disableAutosize() { + autosize.destroy(this.$()); + } +}); diff --git a/app/assets/javascripts/admin/components/ip-lookup.js.es6 b/app/assets/javascripts/admin/components/ip-lookup.js.es6 index f1fe7a391c6..63f61dcc98c 100644 --- a/app/assets/javascripts/admin/components/ip-lookup.js.es6 +++ b/app/assets/javascripts/admin/components/ip-lookup.js.es6 @@ -1,3 +1,4 @@ + export default Ember.Component.extend({ classNames: ["ip-lookup"], @@ -42,7 +43,8 @@ export default Ember.Component.extend({ self.set("totalOthersWithSameIP", result.total); }); - Discourse.AdminUser.findAll("active", data).then(function (users) { + const AdminUser = require('admin/models/admin-user').default; + AdminUser.findAll("active", data).then(function (users) { self.setProperties({ other_accounts: users, otherAccountsLoading: false, diff --git a/app/assets/javascripts/admin/components/permalink-form.js.es6 b/app/assets/javascripts/admin/components/permalink-form.js.es6 index 1bb29e52eb6..2bde845c0c6 100644 --- a/app/assets/javascripts/admin/components/permalink-form.js.es6 +++ b/app/assets/javascripts/admin/components/permalink-form.js.es6 @@ -18,15 +18,17 @@ export default Ember.Component.extend({ actions: { submit: function() { + const Permalink = require('admin/models/permalink').default; + if (!this.get('formSubmitted')) { const self = this; self.set('formSubmitted', true); - const permalink = Discourse.Permalink.create({url: self.get('url'), permalink_type: self.get('permalinkType'), permalink_type_value: self.get('permalink_type_value')}); + const permalink = Permalink.create({url: self.get('url'), permalink_type: self.get('permalinkType'), permalink_type_value: self.get('permalink_type_value')}); permalink.save().then(function(result) { self.set('url', ''); self.set('permalink_type_value', ''); self.set('formSubmitted', false); - self.sendAction('action', Discourse.Permalink.create(result.permalink)); + self.sendAction('action', Permalink.create(result.permalink)); Em.run.schedule('afterRender', function() { self.$('.permalink-url').focus(); }); }, function(e) { self.set('formSubmitted', false); diff --git a/app/assets/javascripts/admin/components/resumable_upload_component.js b/app/assets/javascripts/admin/components/resumable-upload.js.es6 similarity index 96% rename from app/assets/javascripts/admin/components/resumable_upload_component.js rename to app/assets/javascripts/admin/components/resumable-upload.js.es6 index dc040464dd2..c71bdb4797c 100644 --- a/app/assets/javascripts/admin/components/resumable_upload_component.js +++ b/app/assets/javascripts/admin/components/resumable-upload.js.es6 @@ -10,7 +10,7 @@ uploadText="UPLOAD" }} **/ -Discourse.ResumableUploadComponent = Ember.Component.extend(Discourse.StringBuffer, { +const ResumableUploadComponent = Ember.Component.extend(Discourse.StringBuffer, { tagName: "button", classNames: ["btn", "ru"], classNameBindings: ["isUploading"], @@ -118,3 +118,5 @@ Discourse.ResumableUploadComponent = Ember.Component.extend(Discourse.StringBuff }.on("willDestroyElement") }); + +export default ResumableUploadComponent; diff --git a/app/assets/javascripts/admin/components/save-controls.js.es6 b/app/assets/javascripts/admin/components/save-controls.js.es6 new file mode 100644 index 00000000000..414bbf3661f --- /dev/null +++ b/app/assets/javascripts/admin/components/save-controls.js.es6 @@ -0,0 +1,18 @@ +import computed from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + classNames: ['controls'], + + buttonDisabled: Ember.computed.or('model.isSaving', 'saveDisabled'), + + @computed('model.isSaving') + savingText(saving) { + return saving ? 'saving' : 'save'; + }, + + actions: { + saveChanges() { + this.sendAction(); + } + } +}); diff --git a/app/assets/javascripts/admin/components/screened-ip-address-form.js.es6 b/app/assets/javascripts/admin/components/screened-ip-address-form.js.es6 new file mode 100644 index 00000000000..0f8a29ba8c3 --- /dev/null +++ b/app/assets/javascripts/admin/components/screened-ip-address-form.js.es6 @@ -0,0 +1,75 @@ +/** + A form to create an IP address that will be blocked or whitelisted. + Example usage: + + {{screened-ip-address-form action="recordAdded"}} + + where action is a callback on the controller or route that will get called after + the new record is successfully saved. It is called with the new ScreenedIpAddress record + as an argument. +**/ + +import ScreenedIpAddress from 'admin/models/screened-ip-address'; +import computed from 'ember-addons/ember-computed-decorators'; +import { on } from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + classNames: ['screened-ip-address-form'], + formSubmitted: false, + actionName: 'block', + + @computed + adminWhitelistEnabled() { + return Discourse.SiteSettings.use_admin_ip_whitelist; + }, + + @computed("adminWhitelistEnabled") + actionNames(adminWhitelistEnabled) { + if (adminWhitelistEnabled) { + return [ + {id: 'block', name: I18n.t('admin.logs.screened_ips.actions.block')}, + {id: 'do_nothing', name: I18n.t('admin.logs.screened_ips.actions.do_nothing')}, + {id: 'allow_admin', name: I18n.t('admin.logs.screened_ips.actions.allow_admin')} + ]; + } else { + return [ + {id: 'block', name: I18n.t('admin.logs.screened_ips.actions.block')}, + {id: 'do_nothing', name: I18n.t('admin.logs.screened_ips.actions.do_nothing')} + ]; + } + }, + + actions: { + submit() { + if (!this.get('formSubmitted')) { + this.set('formSubmitted', true); + const screenedIpAddress = ScreenedIpAddress.create({ + ip_address: this.get('ip_address'), + action_name: this.get('actionName') + }); + screenedIpAddress.save().then(result => { + this.setProperties({ ip_address: '', formSubmitted: false }); + this.sendAction('action', ScreenedIpAddress.create(result.screened_ip_address)); + Ember.run.schedule('afterRender', () => this.$('.ip-address-input').focus()); + }).catch(e => { + this.set('formSubmitted', false); + const msg = (e.responseJSON && e.responseJSON.errors) ? + I18n.t("generic_error_with_reason", {error: e.responseJSON.errors.join('. ')}) : + I18n.t("generic_error"); + bootbox.alert(msg, () => this.$('.ip-address-input').focus()); + }); + } + } + }, + + @on("didInsertElement") + _init() { + Ember.run.schedule('afterRender', () => { + this.$('.ip-address-input').keydown(e => { + if (e.keyCode === 13) { + this.send('submit'); + } + }); + }); + } +}); diff --git a/app/assets/javascripts/admin/components/screened_ip_address_form_component.js b/app/assets/javascripts/admin/components/screened_ip_address_form_component.js deleted file mode 100644 index 69c517f00bd..00000000000 --- a/app/assets/javascripts/admin/components/screened_ip_address_form_component.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - A form to create an IP address that will be blocked or whitelisted. - Example usage: - - {{screened-ip-address-form action="recordAdded"}} - - where action is a callback on the controller or route that will get called after - the new record is successfully saved. It is called with the new ScreenedIpAddress record - as an argument. - - @class ScreenedIpAddressFormComponent - @extends Ember.Component - @namespace Discourse - @module Discourse -**/ -Discourse.ScreenedIpAddressFormComponent = Ember.Component.extend({ - classNames: ['screened-ip-address-form'], - formSubmitted: false, - actionName: 'block', - - actionNames: function() { - return [ - {id: 'block', name: I18n.t('admin.logs.screened_ips.actions.block')}, - {id: 'do_nothing', name: I18n.t('admin.logs.screened_ips.actions.do_nothing')}, - {id: 'allow_admin', name: I18n.t('admin.logs.screened_ips.actions.allow_admin')} - ]; - }.property(), - - actions: { - submit: function() { - if (!this.get('formSubmitted')) { - var self = this; - this.set('formSubmitted', true); - var screenedIpAddress = Discourse.ScreenedIpAddress.create({ip_address: this.get('ip_address'), action_name: this.get('actionName')}); - screenedIpAddress.save().then(function(result) { - self.set('ip_address', ''); - self.set('formSubmitted', false); - self.sendAction('action', Discourse.ScreenedIpAddress.create(result.screened_ip_address)); - Em.run.schedule('afterRender', function() { self.$('.ip-address-input').focus(); }); - }, function(e) { - self.set('formSubmitted', false); - var msg; - if (e.responseJSON && e.responseJSON.errors) { - msg = I18n.t("generic_error_with_reason", {error: e.responseJSON.errors.join('. ')}); - } else { - msg = I18n.t("generic_error"); - } - bootbox.alert(msg, function() { self.$('.ip-address-input').focus(); }); - }); - } - } - }, - - didInsertElement: function() { - var self = this; - this._super(); - Em.run.schedule('afterRender', function() { - self.$('.ip-address-input').keydown(function(e) { - if (e.keyCode === 13) { // enter key - self.send('submit'); - } - }); - }); - } -}); diff --git a/app/assets/javascripts/admin/components/site-text-summary.js.es6 b/app/assets/javascripts/admin/components/site-text-summary.js.es6 new file mode 100644 index 00000000000..642164f8710 --- /dev/null +++ b/app/assets/javascripts/admin/components/site-text-summary.js.es6 @@ -0,0 +1,25 @@ +import { on } from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + classNames: ['site-text'], + classNameBindings: ['siteText.overridden'], + + @on('didInsertElement') + highlightTerm() { + const term = this.get('term'); + if (term) { + this.$('.site-text-id, .site-text-value').highlight(term, {className: 'text-highlight'}); + } + this.$('.site-text-value').ellipsis(); + }, + + click() { + this.send('edit'); + }, + + actions: { + edit() { + this.sendAction('editAction', this.get('siteText')); + } + } +}); diff --git a/app/assets/javascripts/admin/controllers/admin-api.js.es6 b/app/assets/javascripts/admin/controllers/admin-api.js.es6 index 6dc3ed9ab1c..1bb0a7dc2ff 100644 --- a/app/assets/javascripts/admin/controllers/admin-api.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-api.js.es6 @@ -1,3 +1,5 @@ +import ApiKey from 'admin/models/api-key'; + /** This controller supports the interface for dealing with API keys @@ -16,7 +18,7 @@ export default Ember.ArrayController.extend({ **/ generateMasterKey: function() { var self = this; - Discourse.ApiKey.generateMasterKey().then(function (key) { + ApiKey.generateMasterKey().then(function (key) { self.get('model').pushObject(key); }); }, @@ -25,7 +27,7 @@ export default Ember.ArrayController.extend({ Creates an API key instance with internal user object @method regenerateKey - @param {Discourse.ApiKey} key the key to regenerate + @param {ApiKey} key the key to regenerate **/ regenerateKey: function(key) { bootbox.confirm(I18n.t("admin.api.confirm_regen"), I18n.t("no_value"), I18n.t("yes_value"), function(result) { @@ -39,7 +41,7 @@ export default Ember.ArrayController.extend({ Revokes an API key @method revokeKey - @param {Discourse.ApiKey} key the key to revoke + @param {ApiKey} key the key to revoke **/ revokeKey: function(key) { var self = this; diff --git a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 index 96547435d89..5ec2cb45410 100644 --- a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 @@ -14,7 +14,6 @@ export default Ember.Controller.extend(BufferedContent, { readOnly: Ember.computed.alias('buffered.system'), showDisplayName: propertyNotEqual('name', 'displayName'), - canEditDescription: Em.computed.none('buffered.translatedDescription'), hasQuery: function() { const bQuery = this.get('buffered.query'); @@ -37,6 +36,7 @@ export default Ember.Controller.extend(BufferedContent, { 'listable', 'auto_revoke', 'enabled', 'show_posts', 'target_posts', 'name', 'description', + 'long_description', 'icon', 'image', 'query', 'badge_grouping_id', 'trigger', 'badge_type_id'], self = this; @@ -68,7 +68,8 @@ export default Ember.Controller.extend(BufferedContent, { model = this.get('model'); this.get('model').save(data).then(function() { if (newBadge) { - self.get('controllers.admin-badges').pushObject(model); + var adminBadgesController = self.get('controllers.admin-badges'); + if (!adminBadgesController.contains(model)) adminBadgesController.pushObject(model); self.transitionToRoute('adminBadges.show', model.get('id')); } else { self.commitBuffer(); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6 new file mode 100644 index 00000000000..1c8eb6b0860 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6 @@ -0,0 +1,37 @@ +import { popupAjaxError } from 'discourse/lib/ajax-error'; +import { bufferedProperty } from 'discourse/mixins/buffered-content'; + +export default Ember.Controller.extend(bufferedProperty('emailTemplate'), { + saved: false, + + hasMultipleSubjects: function() { + const buffered = this.get('buffered'); + if (buffered.getProperties('subject')['subject']) { + return false; + } else { + return buffered.getProperties('id')['id']; + } + }.property("buffered"), + + actions: { + saveChanges() { + const buffered = this.get('buffered'); + this.get('emailTemplate').save(buffered.getProperties('subject', 'body')).then(() => { + this.set('saved', true); + }).catch(popupAjaxError); + }, + + revertChanges() { + this.set('saved', false); + bootbox.confirm(I18n.t('admin.customize.email_templates.revert_confirm'), result => { + if (result) { + this.get('emailTemplate').revert().then(props => { + const buffered = this.get('buffered'); + buffered.setProperties(props); + this.commitBuffer(); + }).catch(popupAjaxError); + } + }); + } + } +}); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-email-templates.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-email-templates.js.es6 new file mode 100644 index 00000000000..fe9cd69804c --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-customize-email-templates.js.es6 @@ -0,0 +1,6 @@ +export default Ember.Controller.extend({ + titleSorting: ['title'], + emailTemplates: null, + + sortedTemplates: Ember.computed.sort('emailTemplates', 'titleSorting') +}); diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 index c712a8ac5a4..0e0b33b5130 100644 --- a/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 @@ -1,4 +1,5 @@ import { setting } from 'discourse/lib/computed'; +import AdminDashboard from 'admin/models/admin-dashboard'; // This controller supports the default interface when you enter the admin section. export default Ember.Controller.extend({ @@ -26,7 +27,7 @@ export default Ember.Controller.extend({ this.set('loadingProblems', true); this.set('problemsFetchedAt', new Date()); var c = this; - Discourse.AdminDashboard.fetchProblems().then(function(d) { + AdminDashboard.fetchProblems().then(function(d) { c.set('problems', d.problems); c.set('loadingProblems', false); if( d.problems && d.problems.length > 0 ) { diff --git a/app/assets/javascripts/admin/controllers/admin-email-all.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-all.js.es6 deleted file mode 100644 index 5f456c108fc..00000000000 --- a/app/assets/javascripts/admin/controllers/admin-email-all.js.es6 +++ /dev/null @@ -1,3 +0,0 @@ -import AdminEmailSkippedController from "admin/controllers/admin-email-skipped"; - -export default AdminEmailSkippedController.extend(); diff --git a/app/assets/javascripts/admin/controllers/admin-email-incomings.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-incomings.js.es6 new file mode 100644 index 00000000000..a6acd9af78f --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-email-incomings.js.es6 @@ -0,0 +1,21 @@ +import IncomingEmail from 'admin/models/incoming-email'; + +export default Ember.Controller.extend({ + loading: false, + + actions: { + + loadMore() { + if (this.get("loading") || this.get("model.allLoaded")) { return; } + this.set('loading', true); + + IncomingEmail.findAll(this.get("filter"), this.get("model.length")) + .then(incoming => { + if (incoming.length < 50) { this.get("model").set("allLoaded", true); } + this.get("model").addObjects(incoming); + }).finally(() => { + this.set('loading', false); + }); + } + } +}); diff --git a/app/assets/javascripts/admin/controllers/admin-email-logs.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-logs.js.es6 new file mode 100644 index 00000000000..44a38dfa324 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-email-logs.js.es6 @@ -0,0 +1,20 @@ +import EmailLog from 'admin/models/email-log'; + +export default Ember.Controller.extend({ + loading: false, + + actions: { + loadMore() { + if (this.get("loading") || this.get("model.allLoaded")) { return; } + + this.set('loading', true); + return EmailLog.findAll(this.get("filter"), this.get("model.length")) + .then(logs => { + if (logs.length < 50) { this.get("model").set("allLoaded", true); } + this.get("model").addObjects(logs); + }).finally(() => { + this.set('loading', false); + }); + } + } +}); diff --git a/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 index f259acba84f..160f998365b 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 @@ -1,3 +1,5 @@ +import EmailPreview from 'admin/models/email-preview'; + export default Ember.Controller.extend({ actions: { @@ -5,7 +7,7 @@ export default Ember.Controller.extend({ const model = this.get('model'); this.set('loading', true); - Discourse.EmailPreview.findDigest(this.get('lastSeen')).then(email => { + EmailPreview.findDigest(this.get('lastSeen'), this.get('username')).then(email => { model.setProperties(email.getProperties('html_content', 'text_content')); this.set('loading', false); }); diff --git a/app/assets/javascripts/admin/controllers/admin-email-received.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-received.js.es6 new file mode 100644 index 00000000000..69ebd5e4c49 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-email-received.js.es6 @@ -0,0 +1,9 @@ +import AdminEmailIncomingsController from 'admin/controllers/admin-email-incomings'; +import debounce from 'discourse/lib/debounce'; +import IncomingEmail from 'admin/models/incoming-email'; + +export default AdminEmailIncomingsController.extend({ + filterIncomingEmails: debounce(function() { + IncomingEmail.findAll(this.get("filter")).then(incomings => this.set("model", incomings)); + }, 250).observes("filter.{from,to,subject}") +}); diff --git a/app/assets/javascripts/admin/controllers/admin-email-rejected.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-rejected.js.es6 new file mode 100644 index 00000000000..317a669cd0e --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-email-rejected.js.es6 @@ -0,0 +1,9 @@ +import AdminEmailIncomingsController from 'admin/controllers/admin-email-incomings'; +import debounce from 'discourse/lib/debounce'; +import IncomingEmail from 'admin/models/incoming-email'; + +export default AdminEmailIncomingsController.extend({ + filterIncomingEmails: debounce(function() { + IncomingEmail.findAll(this.get("filter")).then(incomings => this.set("model", incomings)); + }, 250).observes("filter.{from,to,subject,error}") +}); diff --git a/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 index a03bd8212d7..d73d640adca 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 @@ -1,11 +1,9 @@ +import AdminEmailLogsController from 'admin/controllers/admin-email-logs'; import debounce from 'discourse/lib/debounce'; +import EmailLog from 'admin/models/email-log'; -export default Ember.Controller.extend({ - +export default AdminEmailLogsController.extend({ filterEmailLogs: debounce(function() { - var self = this; - Discourse.EmailLog.findAll(this.get("filter")).then(function(logs) { - self.set("model", logs); - }); - }, 250).observes("filter.user", "filter.address", "filter.type", "filter.reply_key") + EmailLog.findAll(this.get("filter")).then(logs => this.set("model", logs)); + }, 250).observes("filter.{user,address,type,reply_key}") }); diff --git a/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 index 1d83f14c6d8..ae75d187155 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 @@ -1,10 +1,9 @@ +import AdminEmailLogsController from 'admin/controllers/admin-email-logs'; import debounce from 'discourse/lib/debounce'; +import EmailLog from 'admin/models/email-log'; -export default Ember.Controller.extend({ +export default AdminEmailLogsController.extend({ filterEmailLogs: debounce(function() { - var self = this; - Discourse.EmailLog.findAll(this.get("filter")).then(function(logs) { - self.set("model", logs); - }); - }, 250).observes("filter.user", "filter.address", "filter.type", "filter.skipped_reason") + EmailLog.findAll(this.get("filter")).then(logs => this.set("model", logs)); + }, 250).observes("filter.{user,address,type,skipped_reason}") }); diff --git a/app/assets/javascripts/admin/controllers/admin-flags-list.js.es6 b/app/assets/javascripts/admin/controllers/admin-flags-list.js.es6 index 9ef1a432720..94de6841c53 100644 --- a/app/assets/javascripts/admin/controllers/admin-flags-list.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-flags-list.js.es6 @@ -1,3 +1,5 @@ +import FlaggedPost from 'admin/models/flagged-post'; + export default Ember.ArrayController.extend({ query: null, @@ -30,7 +32,7 @@ export default Ember.ArrayController.extend({ loadMore(){ var flags = this.get("model"); - return Discourse.FlaggedPost.findAll(this.get("query"),flags.length+1).then(function(data){ + return FlaggedPost.findAll(this.get("query"),flags.length+1).then(function(data){ if(data.length===0){ flags.set("allLoaded",true); } diff --git a/app/assets/javascripts/admin/controllers/admin-group.js.es6 b/app/assets/javascripts/admin/controllers/admin-group.js.es6 index dbe31af85ea..e477ba4b0a1 100644 --- a/app/assets/javascripts/admin/controllers/admin-group.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-group.js.es6 @@ -4,6 +4,7 @@ import { propertyEqual } from 'discourse/lib/computed'; export default Ember.Controller.extend({ needs: ['adminGroupsType'], disableSave: false, + savingStatus: '', currentPage: function() { if (this.get("model.user_count") === 0) { return 0; } @@ -67,6 +68,22 @@ export default Ember.Controller.extend({ }); }, + removeOwner(member) { + const self = this, + message = I18n.t("admin.groups.delete_owner_confirm", { username: member.get("username"), group: this.get("model.name") }); + return bootbox.confirm(message, I18n.t("no_value"), I18n.t("yes_value"), function(confirm) { + if (confirm) { + self.get("model").removeOwner(member); + } + }); + }, + + addOwners() { + if (Em.isEmpty(this.get("model.ownerUsernames"))) { return; } + this.get("model").addOwners(this.get("model.ownerUsernames")).catch(popupAjaxError); + this.set("model.ownerUsernames", null); + }, + addMembers() { if (Em.isEmpty(this.get("model.usernames"))) { return; } this.get("model").addMembers(this.get("model.usernames")).catch(popupAjaxError); @@ -79,12 +96,15 @@ export default Ember.Controller.extend({ groupType = groupsController.get("type"); this.set('disableSave', true); + this.set('savingStatus', I18n.t('saving')); let promise = group.get("id") ? group.save() : group.create().then(() => groupsController.addObject(group)); - promise.then(() => this.transitionToRoute("adminGroup", groupType, group.get('name'))) - .catch(popupAjaxError) - .finally(() => this.set('disableSave', false)); + promise.then(() => { + this.transitionToRoute("adminGroup", groupType, group.get('name')); + this.set('savingStatus', I18n.t('saved')); + }).catch(popupAjaxError) + .finally(() => this.set('disableSave', false)); }, destroy() { diff --git a/app/assets/javascripts/admin/controllers/admin-groups-bulk.js.es6 b/app/assets/javascripts/admin/controllers/admin-groups-bulk.js.es6 new file mode 100644 index 00000000000..6628a6fa726 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-groups-bulk.js.es6 @@ -0,0 +1,34 @@ +import computed from 'ember-addons/ember-computed-decorators'; +import { popupAjaxError } from 'discourse/lib/ajax-error'; + +export default Ember.Controller.extend({ + users: null, + groupId: null, + saving: false, + + @computed('saving', 'users', 'groupId') + buttonDisabled(saving, users, groupId) { + return saving || !groupId || !users || !users.length; + }, + + actions: { + addToGroup() { + if (this.get('saving')) { return; } + + const users = this.get('users').split("\n") + .uniq() + .reject(x => x.length === 0); + + this.set('saving', true); + Discourse.ajax('/admin/groups/bulk', { + data: { users, group_id: this.get('groupId') }, + method: 'PUT' + }).then(() => { + this.transitionToRoute('adminGroups.bulkComplete'); + }).catch(popupAjaxError).finally(() => { + this.set('saving', false); + }); + + } + } +}); diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6 index 77edccd3b1b..fe158a33aba 100644 --- a/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6 @@ -1,5 +1,6 @@ import { exportEntity } from 'discourse/lib/export-csv'; import { outputExportResult } from 'discourse/lib/export-result'; +import ScreenedEmail from 'admin/models/screened-email'; export default Ember.ArrayController.extend({ loading: false, @@ -20,7 +21,7 @@ export default Ember.ArrayController.extend({ show() { var self = this; self.set('loading', true); - Discourse.ScreenedEmail.findAll().then(function(result) { + ScreenedEmail.findAll().then(function(result) { self.set('model', result); self.set('loading', false); }); diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 index 987b07a3b66..88bc10f0e77 100644 --- a/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 @@ -1,6 +1,7 @@ import debounce from 'discourse/lib/debounce'; import { outputExportResult } from 'discourse/lib/export-result'; import { exportEntity } from 'discourse/lib/export-csv'; +import ScreenedIpAddress from 'admin/models/screened-ip-address'; export default Ember.ArrayController.extend({ loading: false, @@ -10,7 +11,7 @@ export default Ember.ArrayController.extend({ show: debounce(function() { var self = this; self.set('loading', true); - Discourse.ScreenedIpAddress.findAll(this.get("filter")).then(function(result) { + ScreenedIpAddress.findAll(this.get("filter")).then(function(result) { self.set('model', result); self.set('loading', false); }); @@ -26,7 +27,7 @@ export default Ember.ArrayController.extend({ return bootbox.confirm(I18n.t("admin.logs.screened_ips.roll_up_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function (confirmed) { if (confirmed) { self.set("loading", true); - return Discourse.ScreenedIpAddress.rollUp().then(function(results) { + return ScreenedIpAddress.rollUp().then(function(results) { if (results && results.subnets) { if (results.subnets.length > 0) { self.send("show"); diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6 index d573a738b61..5f5e3339608 100644 --- a/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6 @@ -1,5 +1,6 @@ import { exportEntity } from 'discourse/lib/export-csv'; import { outputExportResult } from 'discourse/lib/export-result'; +import ScreenedUrl from 'admin/models/screened-url'; export default Ember.ArrayController.extend({ loading: false, @@ -7,7 +8,7 @@ export default Ember.ArrayController.extend({ show() { const self = this; self.set('loading', true); - Discourse.ScreenedUrl.findAll().then(function(result) { + ScreenedUrl.findAll().then(function(result) { self.set('model', result); self.set('loading', false); }); diff --git a/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6 index 58b2583cedc..956a737e578 100644 --- a/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6 @@ -1,5 +1,6 @@ import { exportEntity } from 'discourse/lib/export-csv'; import { outputExportResult } from 'discourse/lib/export-result'; +import StaffActionLog from 'admin/models/staff-action-log'; export default Ember.ArrayController.extend({ loading: false, @@ -36,7 +37,7 @@ export default Ember.ArrayController.extend({ }); this.set('filterCount', count); - Discourse.StaffActionLog.findAll(params).then(function(result) { + StaffActionLog.findAll(params).then(function(result) { self.set('model', result); }).finally(function() { self.set('loading', false); diff --git a/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6 b/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6 index a0d38e7b8cc..9c5ab4bb3e8 100644 --- a/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6 @@ -1,4 +1,5 @@ import debounce from 'discourse/lib/debounce'; +import Permalink from 'admin/models/permalink'; export default Ember.ArrayController.extend({ loading: false, @@ -7,7 +8,7 @@ export default Ember.ArrayController.extend({ show: debounce(function() { var self = this; self.set('loading', true); - Discourse.Permalink.findAll(self.get("filter")).then(function(result) { + Permalink.findAll(self.get("filter")).then(function(result) { self.set('model', result); self.set('loading', false); }); diff --git a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 b/app/assets/javascripts/admin/controllers/admin-reports.js.es6 index d11e67305a8..9ceb1b0b093 100644 --- a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-reports.js.es6 @@ -1,5 +1,7 @@ import { exportEntity } from 'discourse/lib/export-csv'; import { outputExportResult } from 'discourse/lib/export-result'; +import Report from 'admin/models/report'; +import computed from 'ember-addons/ember-computed-decorators'; export default Ember.Controller.extend({ viewMode: 'table', @@ -8,22 +10,32 @@ export default Ember.Controller.extend({ startDate: null, endDate: null, categoryId: null, + groupId: null, refreshing: false, - categoryOptions: function() { - var arr = [{name: I18n.t('category.all'), value: 'all'}]; - return arr.concat( Discourse.Site.currentProp('sortedCategories').map(function(i) { return {name: i.get('name'), value: i.get('id') }; }) ); - }.property(), + @computed() + categoryOptions() { + const arr = [{name: I18n.t('category.all'), value: 'all'}]; + return arr.concat(Discourse.Site.currentProp('sortedCategories').map((i) => {return {name: i.get('name'), value: i.get('id')};})); + }, + + @computed() + groupOptions() { + const arr = [{name: I18n.t('admin.dashboard.reports.groups'), value: 'all'}]; + return arr.concat(this.site.groups.map((i) => {return {name: i['name'], value: i['id']};})); + }, + + @computed('model.type') + showGroupOptions(modelType) { + return modelType === "visits" || modelType === "signups" || modelType === "profile_views"; + }, actions: { refreshReport() { var q; this.set("refreshing", true); - if (this.get('categoryId') === "all") { - q = Discourse.Report.find(this.get("model.type"), this.get("startDate"), this.get("endDate")); - } else { - q = Discourse.Report.find(this.get("model.type"), this.get("startDate"), this.get("endDate"), this.get("categoryId")); - } + + q = Report.find(this.get("model.type"), this.get("startDate"), this.get("endDate"), this.get("categoryId"), this.get("groupId")); q.then(m => this.set("model", m)).finally(() => this.set("refreshing", false)); }, @@ -40,7 +52,8 @@ export default Ember.Controller.extend({ name: this.get("model.type"), start_date: this.get('startDate'), end_date: this.get('endDate'), - category_id: this.get('categoryId') === 'all' ? undefined : this.get('categoryId') + category_id: this.get('categoryId') === 'all' ? undefined : this.get('categoryId'), + group_id: this.get('groupId') === 'all' ? undefined : this.get('groupId') }).then(outputExportResult); } } diff --git a/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6 b/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6 index 97b1c9ace9a..b7c4302e87c 100644 --- a/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6 @@ -5,7 +5,7 @@ export default Ember.ArrayController.extend({ onlyOverridden: false, filtered: Ember.computed.notEmpty('filter'), - filterContentNow: function(category) { + filterContentNow(category) { // If we have no content, don't bother filtering anything if (!!Ember.isEmpty(this.get('allSiteSettings'))) return; @@ -20,12 +20,13 @@ export default Ember.ArrayController.extend({ return; } - const self = this, - matchesGroupedByCategory = [{nameKey: 'all_results', name: I18n.t('admin.site_settings.categories.all_results'), siteSettings: []}]; + const all = {nameKey: 'all_results', name: I18n.t('admin.site_settings.categories.all_results'), siteSettings: []}; + const matchesGroupedByCategory = [all]; - this.get('allSiteSettings').forEach(function(settingsCategory) { - const matches = settingsCategory.siteSettings.filter(function(item) { - if (self.get('onlyOverridden') && !item.get('overridden')) return false; + const matches = []; + this.get('allSiteSettings').forEach(settingsCategory => { + const siteSettings = settingsCategory.siteSettings.filter(item => { + if (this.get('onlyOverridden') && !item.get('overridden')) return false; if (filter) { if (item.get('setting').toLowerCase().indexOf(filter) > -1) return true; if (item.get('setting').toLowerCase().replace(/_/g, ' ').indexOf(filter) > -1) return true; @@ -36,16 +37,20 @@ export default Ember.ArrayController.extend({ return true; } }); - if (matches.length > 0) { - matchesGroupedByCategory[0].siteSettings.pushObjects(matches); + if (siteSettings.length > 0) { + matches.pushObjects(siteSettings); matchesGroupedByCategory.pushObject({ nameKey: settingsCategory.nameKey, name: I18n.t('admin.site_settings.categories.' + settingsCategory.nameKey), - siteSettings: matches + siteSettings, + count: siteSettings.length }); } }); + all.siteSettings.pushObjects(matches.slice(0, 30)); + all.count = matches.length; + this.set('model', matchesGroupedByCategory); this.transitionToRoute("adminSiteSettingsCategory", category || "all_results"); }, @@ -60,10 +65,7 @@ export default Ember.ArrayController.extend({ actions: { clearFilter() { - this.setProperties({ - filter: '', - onlyOverridden: false - }); + this.setProperties({ filter: '', onlyOverridden: false }); }, toggleMenu() { diff --git a/app/assets/javascripts/admin/controllers/admin-site-text-edit.js.es6 b/app/assets/javascripts/admin/controllers/admin-site-text-edit.js.es6 index 943317b1bfe..79de9efc354 100644 --- a/app/assets/javascripts/admin/controllers/admin-site-text-edit.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-site-text-edit.js.es6 @@ -1,16 +1,29 @@ -export default Ember.Controller.extend({ - saved: false, +import { popupAjaxError } from 'discourse/lib/ajax-error'; +import { bufferedProperty } from 'discourse/mixins/buffered-content'; - saveDisabled: function() { - if (this.get('model.isSaving')) { return true; } - if ((!this.get('allow_blank')) && Ember.isEmpty(this.get('model.value'))) { return true; } - return false; - }.property('model.iSaving', 'model.value'), +export default Ember.Controller.extend(bufferedProperty('siteText'), { + saved: false, actions: { saveChanges() { - const model = this.get('model'); - model.save(model.getProperties('value')).then(() => this.set('saved', true)); + const buffered = this.get('buffered'); + this.get('siteText').save(buffered.getProperties('value')).then(() => { + this.commitBuffer(); + this.set('saved', true); + }).catch(popupAjaxError); + }, + + revertChanges() { + this.set('saved', false); + bootbox.confirm(I18n.t('admin.site_text.revert_confirm'), result => { + if (result) { + this.get('siteText').revert().then(props => { + const buffered = this.get('buffered'); + buffered.setProperties(props); + this.commitBuffer(); + }).catch(popupAjaxError); + } + }); } } }); diff --git a/app/assets/javascripts/admin/controllers/admin-site-text-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-site-text-index.js.es6 new file mode 100644 index 00000000000..7be42698844 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-site-text-index.js.es6 @@ -0,0 +1,51 @@ +import { default as computed } from 'ember-addons/ember-computed-decorators'; + +export default Ember.Controller.extend({ + _q: null, + searching: false, + siteTexts: null, + preferred: false, + _overridden: null, + queryParams: ['q', 'overridden'], + + @computed + overridden: { + set(value) { + if (!value || value === "false") { value = false; } + this._overridden = value; + return value; + }, + get() { + return this._overridden; + } + }, + + @computed + q: { + set(value) { + if (Ember.isEmpty(value)) { value = null; } + this._q = value; + return value; + }, + get() { + return this._q; + } + }, + + _performSearch() { + this.store.find('site-text', this.getProperties('q', 'overridden')).then(results => { + this.set('siteTexts', results); + }).finally(() => this.set('searching', false)); + }, + + actions: { + edit(siteText) { + this.transitionToRoute('adminSiteText.edit', siteText.get('id')); + }, + + search() { + this.set('searching', true); + Ember.run.debounce(this, this._performSearch, 400); + } + } +}); diff --git a/app/assets/javascripts/admin/controllers/admin-site-text.js.es6 b/app/assets/javascripts/admin/controllers/admin-site-text.js.es6 deleted file mode 100644 index 24c4c051390..00000000000 --- a/app/assets/javascripts/admin/controllers/admin-site-text.js.es6 +++ /dev/null @@ -1 +0,0 @@ -export default Ember.ArrayController.extend(); diff --git a/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 index b85fbaf069d..8d919e5f263 100644 --- a/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 @@ -56,12 +56,12 @@ export default Ember.ArrayController.extend({ var badges = []; this.get('badges').forEach(function(badge) { - if (badge.get('multiple_grant') || !granted[badge.get('id')]) { + if (badge.get('enabled') && (badge.get('multiple_grant') || !granted[badge.get('id')])) { badges.push(badge); } }); - return _.sortBy(badges, "name"); + return _.sortBy(badges, badge => badge.get('name')); }.property('badges.@each', 'model.@each'), /** diff --git a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 index a0eaf6e1622..af4a0297ef6 100644 --- a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 @@ -1,5 +1,6 @@ import debounce from 'discourse/lib/debounce'; import { i18n } from 'discourse/lib/computed'; +import AdminUser from 'admin/models/admin-user'; export default Ember.ArrayController.extend({ query: null, @@ -42,7 +43,7 @@ export default Ember.ArrayController.extend({ var self = this; this.set('refreshing', true); - Discourse.AdminUser.findAll(this.get('query'), { filter: this.get('listFilter'), show_emails: this.get('showEmails') }).then(function (result) { + AdminUser.findAll(this.get('query'), { filter: this.get('listFilter'), show_emails: this.get('showEmails') }).then(function (result) { self.set('model', result); }).finally(function() { self.set('refreshing', false); @@ -51,14 +52,14 @@ export default Ember.ArrayController.extend({ actions: { approveUsers: function() { - Discourse.AdminUser.bulkApprove(this.get('model').filterProperty('selected')); + AdminUser.bulkApprove(this.get('model').filterProperty('selected')); this._refreshUsers(); }, rejectUsers: function() { var maxPostAge = this.siteSettings.delete_user_max_post_age; var controller = this; - Discourse.AdminUser.bulkReject(this.get('model').filterProperty('selected')).then(function(result){ + AdminUser.bulkReject(this.get('model').filterProperty('selected')).then(function(result){ var message = I18n.t("admin.users.reject_successful", {count: result.success}); if (result.failed > 0) { message += ' ' + I18n.t("admin.users.reject_failures", {count: result.failed}); diff --git a/app/assets/javascripts/admin/controllers/modals/admin-edit-badge-groupings.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-edit-badge-groupings.js.es6 index 74c4f79e6c4..6c0f6b9ccd9 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-edit-badge-groupings.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-edit-badge-groupings.js.es6 @@ -2,15 +2,13 @@ export default Ember.Controller.extend({ needs: ['modal'], modelChanged: function(){ - - var grouping = Em.Object.extend({}); - - var model = this.get('model'); - var copy = Em.A(); + const model = this.get('model'); + const copy = Em.A(); + const store = this.store; if(model){ model.forEach(function(o){ - copy.pushObject(grouping.create(o)); + copy.pushObject(store.createRecord('badge-grouping', o)); }); } @@ -18,8 +16,8 @@ export default Ember.Controller.extend({ }.observes('model'), moveItem: function(item, delta){ - var copy = this.get('workingCopy'); - var index = copy.indexOf(item); + const copy = this.get('workingCopy'); + const index = copy.indexOf(item); if (index + delta < 0 || index + delta >= copy.length){ return; } @@ -50,14 +48,14 @@ export default Ember.Controller.extend({ item.set("editing", false); }, add: function(){ - var obj = Em.Object.create({editing: true, name: "Enter Name"}); + const obj = this.store.createRecord('badge-grouping', {editing: true, name: I18n.t('admin.badges.badge_grouping')}); this.get('workingCopy').pushObject(obj); }, saveAll: function(){ - var self = this; + const self = this; var items = this.get('workingCopy'); - var groupIds = items.map(function(i){return i.get("id") || -1;}); - var names = items.map(function(i){return i.get("name");}); + const groupIds = items.map(function(i){return i.get("id") || -1;}); + const names = items.map(function(i){return i.get("name");}); Discourse.ajax('/admin/badges/badge_groupings',{ data: {ids: groupIds, names: names}, @@ -66,14 +64,13 @@ export default Ember.Controller.extend({ items = self.get("model"); items.clear(); data.badge_groupings.forEach(function(g){ - items.pushObject(Em.Object.create(g)); + items.pushObject(self.store.createRecord('badge-grouping', g)); }); self.set('model', null); self.set('workingCopy', null); self.send('closeModal'); },function(){ - // TODO we can do better - bootbox.alert("Something went wrong"); + bootbox.alert(I18n.t('generic_error')); }); } } diff --git a/app/assets/javascripts/admin/controllers/modals/admin-incoming-email.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-incoming-email.js.es6 new file mode 100644 index 00000000000..bc9cd2edd8d --- /dev/null +++ b/app/assets/javascripts/admin/controllers/modals/admin-incoming-email.js.es6 @@ -0,0 +1,17 @@ +import ModalFunctionality from 'discourse/mixins/modal-functionality'; +import IncomingEmail from 'admin/models/incoming-email'; +import computed from 'ember-addons/ember-computed-decorators'; +import { longDate } from 'discourse/lib/formatter'; + +export default Ember.Controller.extend(ModalFunctionality, { + + @computed("model.date") + date(d) { + return longDate(d); + }, + + load(id) { + return IncomingEmail.find(id).then(result => this.set("model", result)); + } + +}); diff --git a/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 index 682b1ba25dc..15cd838245b 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 @@ -1,4 +1,5 @@ import ModalFunctionality from 'discourse/mixins/modal-functionality'; +import Backup from 'admin/models/backup'; export default Ember.Controller.extend(ModalFunctionality, { needs: ["adminBackupsLogs"], @@ -6,7 +7,7 @@ export default Ember.Controller.extend(ModalFunctionality, { _startBackup: function (withUploads) { var self = this; Discourse.User.currentProp("hideReadOnlyAlert", true); - Discourse.Backup.start(withUploads).then(function() { + Backup.start(withUploads).then(function() { self.get("controllers.adminBackupsLogs").clear(); self.send("backupStarted"); }); diff --git a/app/assets/javascripts/admin/helpers/preserve-newlines.js.es6 b/app/assets/javascripts/admin/helpers/preserve-newlines.js.es6 new file mode 100644 index 00000000000..aeb9f30b377 --- /dev/null +++ b/app/assets/javascripts/admin/helpers/preserve-newlines.js.es6 @@ -0,0 +1,3 @@ +Em.Handlebars.helper('preserve-newlines', str => { + return new Handlebars.SafeString(Discourse.Utilities.escapeExpression(str).replace(/\n/g, "
")); +}); diff --git a/app/assets/javascripts/admin/models/admin_dashboard.js b/app/assets/javascripts/admin/models/admin-dashboard.js.es6 similarity index 68% rename from app/assets/javascripts/admin/models/admin_dashboard.js rename to app/assets/javascripts/admin/models/admin-dashboard.js.es6 index 4aaf0984687..866012b9529 100644 --- a/app/assets/javascripts/admin/models/admin_dashboard.js +++ b/app/assets/javascripts/admin/models/admin-dashboard.js.es6 @@ -1,15 +1,7 @@ -/** - A model that stores all or some data that is displayed on the dashboard. - @class AdminDashboard - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ +const AdminDashboard = Discourse.Model.extend({}); -Discourse.AdminDashboard = Discourse.Model.extend({}); - -Discourse.AdminDashboard.reopenClass({ +AdminDashboard.reopenClass({ /** Fetch all dashboard data. This can be an expensive request when the cached data @@ -20,7 +12,7 @@ Discourse.AdminDashboard.reopenClass({ **/ find: function() { return Discourse.ajax("/admin/dashboard.json").then(function(json) { - var model = Discourse.AdminDashboard.create(json); + var model = AdminDashboard.create(json); model.set('loaded', true); return model; }); @@ -38,9 +30,11 @@ Discourse.AdminDashboard.reopenClass({ type: 'GET', dataType: 'json' }).then(function(json) { - var model = Discourse.AdminDashboard.create(json); + var model = AdminDashboard.create(json); model.set('loaded', true); return model; }); } }); + +export default AdminDashboard; diff --git a/app/assets/javascripts/admin/models/admin-user.js.es6 b/app/assets/javascripts/admin/models/admin-user.js.es6 index 7cda05c8202..5c0660fedd9 100644 --- a/app/assets/javascripts/admin/models/admin-user.js.es6 +++ b/app/assets/javascripts/admin/models/admin-user.js.es6 @@ -1,17 +1,22 @@ import { propertyNotEqual } from 'discourse/lib/computed'; import { popupAjaxError } from 'discourse/lib/ajax-error'; +import ApiKey from 'admin/models/api-key'; +import Group from 'discourse/models/group'; +import TL3Requirements from 'admin/models/tl3-requirements'; const AdminUser = Discourse.User.extend({ - customGroups: Em.computed.filter("groups", (g) => !g.automatic && Discourse.Group.create(g)), - automaticGroups: Em.computed.filter("groups", (g) => g.automatic && Discourse.Group.create(g)), + customGroups: Em.computed.filter("groups", (g) => !g.automatic && Group.create(g)), + automaticGroups: Em.computed.filter("groups", (g) => g.automatic && Group.create(g)), + + canViewProfile: Ember.computed.or("active", "staged"), generateApiKey() { const self = this; return Discourse.ajax("/admin/users/" + this.get('id') + "/generate_api_key", { type: 'POST' }).then(function (result) { - const apiKey = Discourse.ApiKey.create(result.api_key); + const apiKey = ApiKey.create(result.api_key); self.set('api_key', apiKey); return apiKey; }); @@ -261,6 +266,7 @@ const AdminUser = Discourse.User.extend({ }, unblock() { + this.set('blockingUser', true); return Discourse.ajax('/admin/users/' + this.id + '/unblock', { type: 'PUT' }).then(function() { @@ -272,14 +278,33 @@ const AdminUser = Discourse.User.extend({ }, block() { - return Discourse.ajax('/admin/users/' + this.id + '/block', { - type: 'PUT' - }).then(function() { - window.location.reload(); - }).catch(function(e) { - var error = I18n.t('admin.user.block_failed', { error: "http: " + e.status + " - " + e.body }); - bootbox.alert(error); - }); + const user = this, + message = I18n.t("admin.user.block_confirm"); + + const performBlock = function() { + user.set('blockingUser', true); + return Discourse.ajax('/admin/users/' + user.id + '/block', { + type: 'PUT' + }).then(function() { + window.location.reload(); + }).catch(function(e) { + var error = I18n.t('admin.user.block_failed', { error: "http: " + e.status + " - " + e.body }); + bootbox.alert(error); + user.set('blockingUser', false); + }); + }; + + const buttons = [{ + "label": I18n.t("composer.cancel"), + "class": "cancel", + "link": true + }, { + "label": '' + I18n.t('admin.user.block_accept'), + "class": "btn btn-danger", + "callback": function() { performBlock(); } + }]; + + bootbox.dialog(message, buttons, { "classes": "delete-user-modal" }); }, sendActivationEmail() { @@ -288,10 +313,7 @@ const AdminUser = Discourse.User.extend({ data: { username: this.get('username') } }).then(function() { bootbox.alert( I18n.t('admin.user.activation_email_sent') ); - }).catch(function(e) { - var error = I18n.t('admin.user.send_activation_email_failed', { error: "http: " + e.status + " - " + e.body }); - bootbox.alert(error); - }); + }).catch(popupAjaxError); }, anonymizeForbidden: Em.computed.not("can_be_anonymized"), @@ -306,7 +328,7 @@ const AdminUser = Discourse.User.extend({ }).then(function(data) { if (data.success) { if (data.username) { - document.location = Discourse.getURL("/admin/users/" + data.username); + document.location = Discourse.getURL("/admin/users/" + user.get('id') + "/" + data.username); } else { document.location = Discourse.getURL("/admin/users/list/active"); } @@ -380,23 +402,23 @@ const AdminUser = Discourse.User.extend({ } } }).catch(function() { - Discourse.AdminUser.find( user.get('username') ).then(function(u){ user.setProperties(u); }); + AdminUser.find(user.get('id')).then(u => user.setProperties(u)); bootbox.alert(I18n.t("admin.user.delete_failed")); }); }; const buttons = [{ "label": I18n.t("composer.cancel"), - "class": "cancel", - "link": true - }, { - "label": I18n.t('admin.user.delete_dont_block'), "class": "btn", - "callback": function(){ performDestroy(false); } + "link": true }, { "label": '' + I18n.t('admin.user.delete_and_block'), "class": "btn btn-danger", "callback": function(){ performDestroy(true); } + }, { + "label": I18n.t('admin.user.delete_dont_block'), + "class": "btn btn-primary", + "callback": function(){ performDestroy(false); } }]; bootbox.dialog(message, buttons, { "classes": "delete-user-modal" }); @@ -453,7 +475,7 @@ const AdminUser = Discourse.User.extend({ if (user.get('loadedDetails')) { return Ember.RSVP.resolve(user); } - return Discourse.AdminUser.find(user.get('username_lower')).then(function (result) { + return AdminUser.find(user.get('id')).then(result => { user.setProperties(result); user.set('loadedDetails', true); }); @@ -461,19 +483,19 @@ const AdminUser = Discourse.User.extend({ tl3Requirements: function() { if (this.get('tl3_requirements')) { - return Discourse.TL3Requirements.create(this.get('tl3_requirements')); + return TL3Requirements.create(this.get('tl3_requirements')); } }.property('tl3_requirements'), suspendedBy: function() { if (this.get('suspended_by')) { - return Discourse.AdminUser.create(this.get('suspended_by')); + return AdminUser.create(this.get('suspended_by')); } }.property('suspended_by'), approvedBy: function() { if (this.get('approved_by')) { - return Discourse.AdminUser.create(this.get('approved_by')); + return AdminUser.create(this.get('approved_by')); } }.property('approved_by') @@ -511,10 +533,10 @@ AdminUser.reopenClass({ }); }, - find(username) { - return Discourse.ajax("/admin/users/" + username + ".json").then(function (result) { + find(user_id) { + return Discourse.ajax("/admin/users/" + user_id + ".json").then(result => { result.loadedDetails = true; - return Discourse.AdminUser.create(result); + return AdminUser.create(result); }); }, @@ -522,7 +544,7 @@ AdminUser.reopenClass({ return Discourse.ajax("/admin/users/list/" + query + ".json", { data: filter }).then(function(users) { - return users.map((u) => Discourse.AdminUser.create(u)); + return users.map((u) => AdminUser.create(u)); }); } }); diff --git a/app/assets/javascripts/admin/models/api_key.js b/app/assets/javascripts/admin/models/api-key.js.es6 similarity index 71% rename from app/assets/javascripts/admin/models/api_key.js rename to app/assets/javascripts/admin/models/api-key.js.es6 index 40968855841..7ef77195437 100644 --- a/app/assets/javascripts/admin/models/api_key.js +++ b/app/assets/javascripts/admin/models/api-key.js.es6 @@ -1,12 +1,4 @@ -/** - Our data model for representing an API key in the system - - @class ApiKey - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.ApiKey = Discourse.Model.extend({ +const ApiKey = Discourse.Model.extend({ /** Regenerates the api key @@ -34,19 +26,20 @@ Discourse.ApiKey = Discourse.Model.extend({ }); -Discourse.ApiKey.reopenClass({ +ApiKey.reopenClass({ /** Creates an API key instance with internal user object @method create @param {...} var_args the properties to initialize this with - @returns {Discourse.ApiKey} the ApiKey instance + @returns {ApiKey} the ApiKey instance **/ create: function() { + const AdminUser = require('admin/models/admin-user').default; var result = this._super.apply(this, arguments); if (result.user) { - result.user = Discourse.AdminUser.create(result.user); + result.user = AdminUser.create(result.user); } return result; }, @@ -55,12 +48,12 @@ Discourse.ApiKey.reopenClass({ Finds a list of API keys @method find - @returns {Promise} a promise that resolves to the array of `Discourse.ApiKey` instances + @returns {Promise} a promise that resolves to the array of `ApiKey` instances **/ find: function() { return Discourse.ajax("/admin/api").then(function(keys) { return keys.map(function (key) { - return Discourse.ApiKey.create(key); + return ApiKey.create(key); }); }); }, @@ -69,12 +62,14 @@ Discourse.ApiKey.reopenClass({ Generates a master api key and returns it. @method generateMasterKey - @returns {Promise} a promise that resolves to a master `Discourse.ApiKey` + @returns {Promise} a promise that resolves to a master `ApiKey` **/ generateMasterKey: function() { return Discourse.ajax("/admin/api/key", {type: 'POST'}).then(function (result) { - return Discourse.ApiKey.create(result.api_key); + return ApiKey.create(result.api_key); }); } }); + +export default ApiKey; diff --git a/app/assets/javascripts/admin/models/color_scheme_color.js b/app/assets/javascripts/admin/models/color-scheme-color.js.es6 similarity index 88% rename from app/assets/javascripts/admin/models/color_scheme_color.js rename to app/assets/javascripts/admin/models/color-scheme-color.js.es6 index 9b598961fcf..07e2bb95f83 100644 --- a/app/assets/javascripts/admin/models/color_scheme_color.js +++ b/app/assets/javascripts/admin/models/color-scheme-color.js.es6 @@ -1,13 +1,4 @@ -/** - Our data model for a color within a color scheme. - (It's a funny name for a class, but Color seemed too generic for what this class is.) - - @class ColorSchemeColor - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.ColorSchemeColor = Discourse.Model.extend({ +const ColorSchemeColor = Discourse.Model.extend({ init: function() { this._super(); @@ -78,3 +69,5 @@ Discourse.ColorSchemeColor = Discourse.Model.extend({ return this.get('hex').match(/^([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/) !== null; }.property('hex') }); + +export default ColorSchemeColor; diff --git a/app/assets/javascripts/admin/models/color_scheme.js b/app/assets/javascripts/admin/models/color-scheme.js.es6 similarity index 81% rename from app/assets/javascripts/admin/models/color_scheme.js rename to app/assets/javascripts/admin/models/color-scheme.js.es6 index e55cad1999c..512672230d4 100644 --- a/app/assets/javascripts/admin/models/color_scheme.js +++ b/app/assets/javascripts/admin/models/color-scheme.js.es6 @@ -1,12 +1,6 @@ -/** - Our data model for a color scheme. +import ColorSchemeColor from 'admin/models/color-scheme-color'; - @class ColorScheme - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.ColorScheme = Discourse.Model.extend(Ember.Copyable, { +const ColorScheme = Discourse.Model.extend(Ember.Copyable, { init: function() { this._super(); @@ -25,9 +19,9 @@ Discourse.ColorScheme = Discourse.Model.extend(Ember.Copyable, { }, copy: function() { - var newScheme = Discourse.ColorScheme.create({name: this.get('name'), enabled: false, can_edit: true, colors: Em.A()}); + var newScheme = ColorScheme.create({name: this.get('name'), enabled: false, can_edit: true, colors: Em.A()}); _.each(this.get('colors'), function(c){ - newScheme.colors.pushObject(Discourse.ColorSchemeColor.create({name: c.get('name'), hex: c.get('hex'), default_hex: c.get('default_hex')})); + newScheme.colors.pushObject(ColorSchemeColor.create({name: c.get('name'), hex: c.get('hex'), default_hex: c.get('default_hex')})); }); return newScheme; }, @@ -109,17 +103,17 @@ var ColorSchemes = Ember.ArrayProxy.extend({ }.observes('selectedItem') }); -Discourse.ColorScheme.reopenClass({ +ColorScheme.reopenClass({ findAll: function() { var colorSchemes = ColorSchemes.create({ content: [], loading: true }); Discourse.ajax('/admin/color_schemes').then(function(all) { _.each(all, function(colorScheme){ - colorSchemes.pushObject(Discourse.ColorScheme.create({ + colorSchemes.pushObject(ColorScheme.create({ id: colorScheme.id, name: colorScheme.name, enabled: colorScheme.enabled, is_base: colorScheme.is_base, - colors: colorScheme.colors.map(function(c) { return Discourse.ColorSchemeColor.create({name: c.name, hex: c.hex, default_hex: c.default_hex}); }) + colors: colorScheme.colors.map(function(c) { return ColorSchemeColor.create({name: c.name, hex: c.hex, default_hex: c.default_hex}); }) })); }); colorSchemes.set('loading', false); @@ -127,3 +121,5 @@ Discourse.ColorScheme.reopenClass({ return colorSchemes; } }); + +export default ColorScheme; diff --git a/app/assets/javascripts/admin/models/email-log.js.es6 b/app/assets/javascripts/admin/models/email-log.js.es6 new file mode 100644 index 00000000000..2b19eeff4f5 --- /dev/null +++ b/app/assets/javascripts/admin/models/email-log.js.es6 @@ -0,0 +1,29 @@ +import AdminUser from 'admin/models/admin-user'; + +const EmailLog = Discourse.Model.extend({}); + +EmailLog.reopenClass({ + + create(attrs) { + attrs = attrs || {}; + + if (attrs.user) { + attrs.user = AdminUser.create(attrs.user); + } + + return this._super(attrs); + }, + + findAll(filter, offset) { + filter = filter || {}; + offset = offset || 0; + + const status = filter.status || "sent"; + filter = _.omit(filter, "status"); + + return Discourse.ajax(`/admin/email/${status}.json?offset=${offset}`, { data: filter }) + .then(logs => _.map(logs, log => EmailLog.create(log))); + } +}); + +export default EmailLog; diff --git a/app/assets/javascripts/admin/models/email-preview.js.es6 b/app/assets/javascripts/admin/models/email-preview.js.es6 new file mode 100644 index 00000000000..12826f98ed0 --- /dev/null +++ b/app/assets/javascripts/admin/models/email-preview.js.es6 @@ -0,0 +1,22 @@ +const EmailPreview = Discourse.Model.extend({}); + +EmailPreview.reopenClass({ + findDigest: function(lastSeenAt, username) { + + if (Em.isEmpty(lastSeenAt)) { + lastSeenAt = moment().subtract(7, 'days').format('YYYY-MM-DD'); + } + + if (Em.isEmpty(username)) { + username = Discourse.User.current().username; + } + + return Discourse.ajax("/admin/email/preview-digest.json", { + data: { last_seen_at: lastSeenAt, username: username } + }).then(function (result) { + return EmailPreview.create(result); + }); + } +}); + +export default EmailPreview; diff --git a/app/assets/javascripts/admin/models/email-settings.js.es6 b/app/assets/javascripts/admin/models/email-settings.js.es6 new file mode 100644 index 00000000000..1b8f791f268 --- /dev/null +++ b/app/assets/javascripts/admin/models/email-settings.js.es6 @@ -0,0 +1,11 @@ +const EmailSettings = Discourse.Model.extend({}); + +EmailSettings.reopenClass({ + find: function() { + return Discourse.ajax("/admin/email.json").then(function (settings) { + return EmailSettings.create(settings); + }); + } +}); + +export default EmailSettings; diff --git a/app/assets/javascripts/admin/models/email-template.js.es6 b/app/assets/javascripts/admin/models/email-template.js.es6 new file mode 100644 index 00000000000..7e8e6579ac2 --- /dev/null +++ b/app/assets/javascripts/admin/models/email-template.js.es6 @@ -0,0 +1,10 @@ +import RestModel from 'discourse/models/rest'; +const { getProperties } = Ember; + +export default RestModel.extend({ + revert() { + return Discourse.ajax(`/admin/customize/email_templates/${this.get('id')}`, { + method: 'DELETE' + }).then(result => getProperties(result.email_template, 'subject', 'body', 'can_revert')); + } +}); diff --git a/app/assets/javascripts/admin/models/email_log.js b/app/assets/javascripts/admin/models/email_log.js deleted file mode 100644 index fe824866997..00000000000 --- a/app/assets/javascripts/admin/models/email_log.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - Our data model for representing an email log. - - @class EmailLog - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.EmailLog = Discourse.Model.extend({}); - -Discourse.EmailLog.reopenClass({ - - create: function(attrs) { - attrs = attrs || {}; - - if (attrs.user) { - attrs.user = Discourse.AdminUser.create(attrs.user); - } - - return this._super(attrs); - }, - - findAll: function(filter) { - filter = filter || {}; - var status = filter.status || "all"; - filter = _.omit(filter, "status"); - - return Discourse.ajax("/admin/email/" + status + ".json", { data: filter }).then(function(logs) { - return _.map(logs, function (log) { - return Discourse.EmailLog.create(log); - }); - }); - } -}); - - diff --git a/app/assets/javascripts/admin/models/email_preview.js b/app/assets/javascripts/admin/models/email_preview.js deleted file mode 100644 index b754095812c..00000000000 --- a/app/assets/javascripts/admin/models/email_preview.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - Our data model for showing a preview of an email - - @class EmailPreview - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.EmailPreview = Discourse.Model.extend({}); - -Discourse.EmailPreview.reopenClass({ - findDigest: function(lastSeenAt) { - - if (Em.isEmpty(lastSeenAt)) { - lastSeenAt = moment().subtract(7, 'days').format('YYYY-MM-DD'); - } - - return Discourse.ajax("/admin/email/preview-digest.json", { - data: {last_seen_at: lastSeenAt} - }).then(function (result) { - return Discourse.EmailPreview.create(result); - }); - } -}); - - diff --git a/app/assets/javascripts/admin/models/email_settings.js b/app/assets/javascripts/admin/models/email_settings.js deleted file mode 100644 index d061635515d..00000000000 --- a/app/assets/javascripts/admin/models/email_settings.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - Our data model for representing the current email settings - - @class EmailSettings - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.EmailSettings = Discourse.Model.extend({}); - -Discourse.EmailSettings.reopenClass({ - find: function() { - return Discourse.ajax("/admin/email.json").then(function (settings) { - return Discourse.EmailSettings.create(settings); - }); - } -}); diff --git a/app/assets/javascripts/admin/models/flagged_post.js b/app/assets/javascripts/admin/models/flagged-post.js.es6 similarity index 92% rename from app/assets/javascripts/admin/models/flagged_post.js rename to app/assets/javascripts/admin/models/flagged-post.js.es6 index e3a01948ca0..8492c4f8b7e 100644 --- a/app/assets/javascripts/admin/models/flagged_post.js +++ b/app/assets/javascripts/admin/models/flagged-post.js.es6 @@ -1,12 +1,9 @@ -/** - Our data model for interacting with flagged posts. +import AdminUser from 'admin/models/admin-user'; +import Topic from 'discourse/models/topic'; +import Post from 'discourse/models/post'; - @class FlaggedPost - @extends Discourse.Post - @namespace Discourse - @module Discourse -**/ -Discourse.FlaggedPost = Discourse.Post.extend({ + +const FlaggedPost = Post.extend({ summary: function () { return _(this.post_actions) @@ -140,7 +137,7 @@ Discourse.FlaggedPost = Discourse.Post.extend({ }); -Discourse.FlaggedPost.reopenClass({ +FlaggedPost.reopenClass({ findAll: function (filter, offset) { offset = offset || 0; @@ -151,18 +148,18 @@ Discourse.FlaggedPost.reopenClass({ // users var userLookup = {}; _.each(data.users, function (user) { - userLookup[user.id] = Discourse.AdminUser.create(user); + userLookup[user.id] = AdminUser.create(user); }); // topics var topicLookup = {}; _.each(data.topics, function (topic) { - topicLookup[topic.id] = Discourse.Topic.create(topic); + topicLookup[topic.id] = Topic.create(topic); }); // posts _.each(data.posts, function (post) { - var f = Discourse.FlaggedPost.create(post); + var f = FlaggedPost.create(post); f.userLookup = userLookup; f.topicLookup = topicLookup; result.pushObject(f); @@ -174,3 +171,5 @@ Discourse.FlaggedPost.reopenClass({ }); } }); + +export default FlaggedPost; diff --git a/app/assets/javascripts/admin/models/incoming-email.js.es6 b/app/assets/javascripts/admin/models/incoming-email.js.es6 new file mode 100644 index 00000000000..82534c5c43d --- /dev/null +++ b/app/assets/javascripts/admin/models/incoming-email.js.es6 @@ -0,0 +1,37 @@ +import AdminUser from 'admin/models/admin-user'; + +const IncomingEmail = Discourse.Model.extend({}); + +IncomingEmail.reopenClass({ + + create(attrs) { + attrs = attrs || {}; + + if (attrs.user) { + attrs.user = AdminUser.create(attrs.user); + } + + return this._super(attrs); + }, + + find(id) { + return Discourse.ajax(`/admin/email/incoming/${id}.json`); + }, + + findAll(filter, offset) { + filter = filter || {}; + offset = offset || 0; + + const status = filter.status || "received"; + filter = _.omit(filter, "status"); + + return Discourse.ajax(`/admin/email/${status}.json?offset=${offset}`, { data: filter }) + .then(incomings => _.map(incomings, incoming => IncomingEmail.create(incoming))); + }, + + loadRawEmail(id) { + return Discourse.ajax(`/admin/email/incoming/${id}/raw.json`); + } +}); + +export default IncomingEmail; diff --git a/app/assets/javascripts/admin/models/permalink.js.es6 b/app/assets/javascripts/admin/models/permalink.js.es6 index 761cd4ab51f..eb867adb315 100644 --- a/app/assets/javascripts/admin/models/permalink.js.es6 +++ b/app/assets/javascripts/admin/models/permalink.js.es6 @@ -14,7 +14,7 @@ const Permalink = Discourse.Model.extend({ Permalink.reopenClass({ findAll: function(filter) { return Discourse.ajax("/admin/permalinks.json", { data: { filter: filter } }).then(function(permalinks) { - return permalinks.map(p => Discourse.Permalink.create(p)); + return permalinks.map(p => Permalink.create(p)); }); } }); diff --git a/app/assets/javascripts/admin/models/report.js.es6 b/app/assets/javascripts/admin/models/report.js.es6 index a28601d0ce9..1891984b47e 100644 --- a/app/assets/javascripts/admin/models/report.js.es6 +++ b/app/assets/javascripts/admin/models/report.js.es6 @@ -131,12 +131,13 @@ const Report = Discourse.Model.extend({ Report.reopenClass({ - find(type, startDate, endDate, categoryId) { + find(type, startDate, endDate, categoryId, groupId) { return Discourse.ajax("/admin/reports/" + type, { data: { start_date: startDate, end_date: endDate, - category_id: categoryId + category_id: categoryId, + group_id: groupId } }).then(json => { // Add a percent field to each tuple @@ -147,7 +148,7 @@ Report.reopenClass({ if (maxY > 0) { json.report.data.forEach(row => row.percentage = Math.round((row.y / maxY) * 100)); } - const model = Discourse.Report.create({ type: type }); + const model = Report.create({ type: type }); model.setProperties(json.report); return model; }); diff --git a/app/assets/javascripts/admin/models/screened_email.js b/app/assets/javascripts/admin/models/screened-email.js.es6 similarity index 56% rename from app/assets/javascripts/admin/models/screened_email.js rename to app/assets/javascripts/admin/models/screened-email.js.es6 index 5e6a8ddf832..71c74d0ad0c 100644 --- a/app/assets/javascripts/admin/models/screened_email.js +++ b/app/assets/javascripts/admin/models/screened-email.js.es6 @@ -1,13 +1,4 @@ -/** - Represents an email address that is watched for during account registration, - and an action is taken. - - @class ScreenedEmail - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.ScreenedEmail = Discourse.Model.extend({ +const ScreenedEmail = Discourse.Model.extend({ actionName: function() { return I18n.t("admin.logs.screened_actions." + this.get('action')); }.property('action'), @@ -17,12 +8,14 @@ Discourse.ScreenedEmail = Discourse.Model.extend({ } }); -Discourse.ScreenedEmail.reopenClass({ +ScreenedEmail.reopenClass({ findAll: function() { return Discourse.ajax("/admin/logs/screened_emails.json").then(function(screened_emails) { return screened_emails.map(function(b) { - return Discourse.ScreenedEmail.create(b); + return ScreenedEmail.create(b); }); }); } }); + +export default ScreenedEmail; diff --git a/app/assets/javascripts/admin/models/screened_ip_address.js b/app/assets/javascripts/admin/models/screened-ip-address.js.es6 similarity index 79% rename from app/assets/javascripts/admin/models/screened_ip_address.js rename to app/assets/javascripts/admin/models/screened-ip-address.js.es6 index f487896206b..51f8ff5021a 100644 --- a/app/assets/javascripts/admin/models/screened_ip_address.js +++ b/app/assets/javascripts/admin/models/screened-ip-address.js.es6 @@ -1,8 +1,4 @@ -/** - Represents an IP address that is watched for during account registration - (and possibly other times), and an action is taken. -**/ -Discourse.ScreenedIpAddress = Discourse.Model.extend({ +const ScreenedIpAddress = Discourse.Model.extend({ actionName: function() { return I18n.t("admin.logs.screened_ips.actions." + this.get('action_name')); }.property('action_name'), @@ -27,11 +23,11 @@ Discourse.ScreenedIpAddress = Discourse.Model.extend({ } }); -Discourse.ScreenedIpAddress.reopenClass({ +ScreenedIpAddress.reopenClass({ findAll: function(filter) { return Discourse.ajax("/admin/logs/screened_ip_addresses.json", { data: { filter: filter } }).then(function(screened_ips) { return screened_ips.map(function(b) { - return Discourse.ScreenedIpAddress.create(b); + return ScreenedIpAddress.create(b); }); }); }, @@ -40,3 +36,5 @@ Discourse.ScreenedIpAddress.reopenClass({ return Discourse.ajax("/admin/logs/screened_ip_addresses/roll_up", { type: "POST" }); } }); + +export default ScreenedIpAddress; diff --git a/app/assets/javascripts/admin/models/screened_url.js b/app/assets/javascripts/admin/models/screened-url.js.es6 similarity index 51% rename from app/assets/javascripts/admin/models/screened_url.js rename to app/assets/javascripts/admin/models/screened-url.js.es6 index 60c4f984b4f..9b16c7faecb 100644 --- a/app/assets/javascripts/admin/models/screened_url.js +++ b/app/assets/javascripts/admin/models/screened-url.js.es6 @@ -1,23 +1,17 @@ -/** - Represents a URL that is watched for, and an action may be taken. - - @class ScreenedUrl - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.ScreenedUrl = Discourse.Model.extend({ +const ScreenedUrl = Discourse.Model.extend({ actionName: function() { return I18n.t("admin.logs.screened_actions." + this.get('action')); }.property('action') }); -Discourse.ScreenedUrl.reopenClass({ +ScreenedUrl.reopenClass({ findAll: function() { return Discourse.ajax("/admin/logs/screened_urls.json").then(function(screened_urls) { return screened_urls.map(function(b) { - return Discourse.ScreenedUrl.create(b); + return ScreenedUrl.create(b); }); }); } }); + +export default ScreenedUrl; diff --git a/app/assets/javascripts/admin/models/site-setting.js.es6 b/app/assets/javascripts/admin/models/site-setting.js.es6 index 1d769369cab..98b3ab896ee 100644 --- a/app/assets/javascripts/admin/models/site-setting.js.es6 +++ b/app/assets/javascripts/admin/models/site-setting.js.es6 @@ -35,7 +35,7 @@ SiteSetting.reopenClass({ if (!categories[s.category]) { categories[s.category] = []; } - categories[s.category].pushObject(Discourse.SiteSetting.create(s)); + categories[s.category].pushObject(SiteSetting.create(s)); }); return Object.keys(categories).map(function(n) { diff --git a/app/assets/javascripts/admin/models/site-text-type.js.es6 b/app/assets/javascripts/admin/models/site-text-type.js.es6 deleted file mode 100644 index 7cb1171e909..00000000000 --- a/app/assets/javascripts/admin/models/site-text-type.js.es6 +++ /dev/null @@ -1,2 +0,0 @@ -import RestModel from 'discourse/models/rest'; -export default RestModel.extend(); diff --git a/app/assets/javascripts/admin/models/site-text.js.es6 b/app/assets/javascripts/admin/models/site-text.js.es6 index edbaf2a4447..0d18ad7ea82 100644 --- a/app/assets/javascripts/admin/models/site-text.js.es6 +++ b/app/assets/javascripts/admin/models/site-text.js.es6 @@ -1,8 +1,10 @@ import RestModel from 'discourse/models/rest'; +const { getProperties } = Ember; export default RestModel.extend({ - markdown: Em.computed.equal('format', 'markdown'), - plainText: Em.computed.equal('format', 'plain'), - html: Em.computed.equal('format', 'html'), - css: Em.computed.equal('format', 'css'), + revert() { + return Discourse.ajax(`/admin/customize/site_texts/${this.get('id')}`, { + method: 'DELETE' + }).then(result => getProperties(result.site_text, 'value', 'can_revert')); + } }); diff --git a/app/assets/javascripts/admin/models/staff_action_log.js b/app/assets/javascripts/admin/models/staff-action-log.js.es6 similarity index 79% rename from app/assets/javascripts/admin/models/staff_action_log.js rename to app/assets/javascripts/admin/models/staff-action-log.js.es6 index 393ec7d484c..4f9e5cc9aec 100644 --- a/app/assets/javascripts/admin/models/staff_action_log.js +++ b/app/assets/javascripts/admin/models/staff-action-log.js.es6 @@ -1,4 +1,6 @@ -Discourse.StaffActionLog = Discourse.Model.extend({ +import AdminUser from 'admin/models/admin-user'; + +const StaffActionLog = Discourse.Model.extend({ showFullDetails: false, actionName: function() { @@ -11,6 +13,7 @@ Discourse.StaffActionLog = Discourse.Model.extend({ formatted += this.format('admin.logs.ip_address', 'ip_address'); formatted += this.format('admin.logs.topic_id', 'topic_id'); formatted += this.format('admin.logs.post_id', 'post_id'); + formatted += this.format('admin.logs.category_id', 'category_id'); if (!this.get('useCustomModalForDetails')) { formatted += this.format('admin.logs.staff_actions.new_value', 'new_value'); formatted += this.format('admin.logs.staff_actions.previous_value', 'previous_value'); @@ -19,7 +22,7 @@ Discourse.StaffActionLog = Discourse.Model.extend({ if (this.get('details')) formatted += Discourse.Utilities.escapeExpression(this.get('details')) + '
'; } return formatted; - }.property('ip_address', 'email', 'topic_id', 'post_id'), + }.property('ip_address', 'email', 'topic_id', 'post_id', 'category_id'), format: function(label, propertyName) { if (this.get(propertyName)) { @@ -38,15 +41,15 @@ Discourse.StaffActionLog = Discourse.Model.extend({ }.property('action_name') }); -Discourse.StaffActionLog.reopenClass({ +StaffActionLog.reopenClass({ create: function(attrs) { attrs = attrs || {}; if (attrs.acting_user) { - attrs.acting_user = Discourse.AdminUser.create(attrs.acting_user); + attrs.acting_user = AdminUser.create(attrs.acting_user); } if (attrs.target_user) { - attrs.target_user = Discourse.AdminUser.create(attrs.target_user); + attrs.target_user = AdminUser.create(attrs.target_user); } return this._super(attrs); }, @@ -54,8 +57,10 @@ Discourse.StaffActionLog.reopenClass({ findAll: function(filters) { return Discourse.ajax("/admin/logs/staff_action_logs.json", { data: filters }).then(function(staff_actions) { return staff_actions.map(function(s) { - return Discourse.StaffActionLog.create(s); + return StaffActionLog.create(s); }); }); } }); + +export default StaffActionLog; diff --git a/app/assets/javascripts/admin/models/leader_requirements.js b/app/assets/javascripts/admin/models/tl3-requirements.js.es6 similarity index 89% rename from app/assets/javascripts/admin/models/leader_requirements.js rename to app/assets/javascripts/admin/models/tl3-requirements.js.es6 index 9b42d122449..ac27b095a7b 100644 --- a/app/assets/javascripts/admin/models/leader_requirements.js +++ b/app/assets/javascripts/admin/models/tl3-requirements.js.es6 @@ -1,10 +1,10 @@ -Discourse.TL3Requirements = Discourse.Model.extend({ +const TL3Requirements = Discourse.Model.extend({ days_visited_percent: function() { - return ((this.get('days_visited') * 100) / this.get('time_period')); + return Math.round((this.get('days_visited') * 100) / this.get('time_period')); }.property('days_visited', 'time_period'), min_days_visited_percent: function() { - return ((this.get('min_days_visited') * 100) / this.get('time_period')); + return Math.round((this.get('min_days_visited') * 100) / this.get('time_period')); }.property('min_days_visited', 'time_period'), met: function() { @@ -38,3 +38,5 @@ Discourse.TL3Requirements = Discourse.Model.extend({ 'num_likes_received_users', 'min_likes_received_users', 'trust_level_locked') }); + +export default TL3Requirements; diff --git a/app/assets/javascripts/admin/models/version_check.js b/app/assets/javascripts/admin/models/version-check.js.es6 similarity index 80% rename from app/assets/javascripts/admin/models/version_check.js rename to app/assets/javascripts/admin/models/version-check.js.es6 index 2add3b7b2f0..4f9b2c4c660 100644 --- a/app/assets/javascripts/admin/models/version_check.js +++ b/app/assets/javascripts/admin/models/version-check.js.es6 @@ -1,12 +1,4 @@ -/** - Our data model for determining whether there's a new version of Discourse - - @class VersionCheck - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.VersionCheck = Discourse.Model.extend({ +const VersionCheck = Discourse.Model.extend({ noCheckPerformed: function() { return this.get('updated_at') === null; @@ -39,10 +31,12 @@ Discourse.VersionCheck = Discourse.Model.extend({ }.property('installed_sha') }); -Discourse.VersionCheck.reopenClass({ +VersionCheck.reopenClass({ find: function() { return Discourse.ajax('/admin/version_check').then(function(json) { - return Discourse.VersionCheck.create(json); + return VersionCheck.create(json); }); } }); + +export default VersionCheck; diff --git a/app/assets/javascripts/admin/routes/admin-api.js.es6 b/app/assets/javascripts/admin/routes/admin-api.js.es6 index 82212c96577..6142e2a2968 100644 --- a/app/assets/javascripts/admin/routes/admin-api.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-api.js.es6 @@ -1,5 +1,7 @@ +import ApiKey from 'admin/models/api-key'; + export default Ember.Route.extend({ model() { - return Discourse.ApiKey.find(); + return ApiKey.find(); } }); diff --git a/app/assets/javascripts/admin/routes/admin-backups-index.js.es6 b/app/assets/javascripts/admin/routes/admin-backups-index.js.es6 index 651551f857e..fce0b126d36 100644 --- a/app/assets/javascripts/admin/routes/admin-backups-index.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-backups-index.js.es6 @@ -1,5 +1,7 @@ +import Backup from 'admin/models/backup'; + export default Ember.Route.extend({ model() { - return Discourse.Backup.find(); + return Backup.find(); } }); diff --git a/app/assets/javascripts/admin/routes/admin-backups.js.es6 b/app/assets/javascripts/admin/routes/admin-backups.js.es6 index ac7f963cd44..f97d86f9318 100644 --- a/app/assets/javascripts/admin/routes/admin-backups.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-backups.js.es6 @@ -1,4 +1,6 @@ import showModal from 'discourse/lib/show-modal'; +import BackupStatus from 'admin/models/backup-status'; +import Backup from 'admin/models/backup'; const LOG_CHANNEL = "/admin/backups/logs"; @@ -31,7 +33,7 @@ export default Discourse.Route.extend({ return PreloadStore.getAndRemove("operations_status", function() { return Discourse.ajax("/admin/backups/status.json"); }).then(status => { - return Discourse.BackupStatus.create({ + return BackupStatus.create({ isOperationRunning: status.is_operation_running, canRollback: status.can_rollback, allowRestore: status.allow_restore @@ -98,7 +100,7 @@ export default Discourse.Route.extend({ I18n.t("yes_value"), function(confirmed) { if (confirmed) { - Discourse.Backup.cancel().then(function() { + Backup.cancel().then(function() { self.controllerFor("adminBackups").set("model.isOperationRunning", false); }); } @@ -112,7 +114,7 @@ export default Discourse.Route.extend({ I18n.t("no_value"), I18n.t("yes_value"), function(confirmed) { - if (confirmed) { Discourse.Backup.rollback(); } + if (confirmed) { Backup.rollback(); } } ); }, @@ -120,7 +122,7 @@ export default Discourse.Route.extend({ uploadSuccess(filename) { const self = this; bootbox.alert(I18n.t("admin.backups.upload.success", { filename: filename }), function() { - Discourse.Backup.find().then(function (backups) { + Backup.find().then(function (backups) { self.controllerFor("adminBackupsIndex").set("model", backups); }); }); diff --git a/app/assets/javascripts/admin/routes/admin-badges.js.es6 b/app/assets/javascripts/admin/routes/admin-badges.js.es6 index 59274376699..5efa86491fa 100644 --- a/app/assets/javascripts/admin/routes/admin-badges.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-badges.js.es6 @@ -1,4 +1,5 @@ import Badge from 'discourse/models/badge'; +import BadgeGrouping from 'discourse/models/badge-grouping'; export default Discourse.Route.extend({ _json: null, @@ -13,14 +14,19 @@ export default Discourse.Route.extend({ setupController: function(controller, model) { var json = this._json, - triggers = []; + triggers = [], + badgeGroupings = []; _.each(json.admin_badges.triggers,function(v,k){ triggers.push({id: v, name: I18n.t('admin.badges.trigger_type.'+k)}); }); + json.badge_groupings.forEach(function(badgeGroupingJson) { + badgeGroupings.push(BadgeGrouping.create(badgeGroupingJson)); + }); + controller.setProperties({ - badgeGroupings: json.badge_groupings, + badgeGroupings: badgeGroupings, badgeTypes: json.badge_types, protectedSystemFields: json.admin_badges.protected_system_fields, badgeTriggers: triggers, diff --git a/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6 index b0f4745a381..8a47f1ba212 100644 --- a/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6 @@ -1,7 +1,9 @@ +import ColorScheme from 'admin/models/color-scheme'; + export default Ember.Route.extend({ model() { - return Discourse.ColorScheme.findAll(); + return ColorScheme.findAll(); }, deactivate() { diff --git a/app/assets/javascripts/admin/routes/admin-customize-email-templates-edit.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-email-templates-edit.js.es6 new file mode 100644 index 00000000000..b6e4e36bf9f --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-customize-email-templates-edit.js.es6 @@ -0,0 +1,13 @@ +import { scrollTop } from 'discourse/mixins/scroll-top'; + +export default Ember.Route.extend({ + model(params) { + const all = this.modelFor('adminCustomizeEmailTemplates'); + return all.findProperty('id', params.id); + }, + + setupController(controller, emailTemplate) { + controller.setProperties({ emailTemplate, saved: false }); + scrollTop(); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-customize-email-templates.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-email-templates.js.es6 new file mode 100644 index 00000000000..8ad73730803 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-customize-email-templates.js.es6 @@ -0,0 +1,9 @@ +export default Ember.Route.extend({ + model() { + return this.store.findAll('email-template'); + }, + + setupController(controller, model) { + controller.set('emailTemplates', model); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-customize-index.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-index.js.es6 index 725b9fa8dd6..45cb6e21fbe 100644 --- a/app/assets/javascripts/admin/routes/admin-customize-index.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-customize-index.js.es6 @@ -1,5 +1,5 @@ export default Ember.Route.extend({ beforeModel() { - this.replaceWith('adminCustomize.colors'); + this.transitionTo('adminCustomize.colors'); } }); diff --git a/app/assets/javascripts/admin/routes/admin-dashboard.js.es6 b/app/assets/javascripts/admin/routes/admin-dashboard.js.es6 index 7bdb274e438..b080834d0bf 100644 --- a/app/assets/javascripts/admin/routes/admin-dashboard.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-dashboard.js.es6 @@ -1,3 +1,8 @@ +import AdminDashboard from 'admin/models/admin-dashboard'; +import VersionCheck from 'admin/models/version-check'; +import Report from 'admin/models/report'; +import AdminUser from 'admin/models/admin-user'; + export default Discourse.Route.extend({ setupController: function(c) { @@ -8,19 +13,19 @@ export default Discourse.Route.extend({ if( !c.get('dashboardFetchedAt') || moment().subtract(30, 'minutes').toDate() > c.get('dashboardFetchedAt') ) { c.set('dashboardFetchedAt', new Date()); var versionChecks = this.siteSettings.version_checks; - Discourse.AdminDashboard.find().then(function(d) { + AdminDashboard.find().then(function(d) { if (versionChecks) { - c.set('versionCheck', Discourse.VersionCheck.create(d.version_check)); + c.set('versionCheck', VersionCheck.create(d.version_check)); } ['global_reports', 'page_view_reports', 'private_message_reports', 'http_reports', 'user_reports', 'mobile_reports'].forEach(name => { - c.set(name, d[name].map(r => Discourse.Report.create(r))); + c.set(name, d[name].map(r => Report.create(r))); }); var topReferrers = d.top_referrers; if (topReferrers && topReferrers.data) { d.top_referrers.data = topReferrers.data.map(function (user) { - return Discourse.AdminUser.create(user); + return AdminUser.create(user); }); c.set('top_referrers', topReferrers); } diff --git a/app/assets/javascripts/admin/routes/admin-email-incomings.js.es6 b/app/assets/javascripts/admin/routes/admin-email-incomings.js.es6 new file mode 100644 index 00000000000..7eefb322cbb --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-email-incomings.js.es6 @@ -0,0 +1,14 @@ +import IncomingEmail from 'admin/models/incoming-email'; + +export default Discourse.Route.extend({ + + model() { + return IncomingEmail.findAll({ status: this.get("status") }); + }, + + setupController(controller, model) { + controller.set("model", model); + controller.set("filter", { status: this.get("status") }); + } + +}); diff --git a/app/assets/javascripts/admin/routes/admin-email-index.js.es6 b/app/assets/javascripts/admin/routes/admin-email-index.js.es6 new file mode 100644 index 00000000000..1b75e39f6f8 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-email-index.js.es6 @@ -0,0 +1,11 @@ +import EmailSettings from 'admin/models/email-settings'; + +export default Discourse.Route.extend({ + model() { + return EmailSettings.find(); + }, + + renderTemplate() { + this.render('admin/templates/email_index', { into: 'adminEmail' }); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-email-logs.js.es6 b/app/assets/javascripts/admin/routes/admin-email-logs.js.es6 new file mode 100644 index 00000000000..27791bcaec6 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-email-logs.js.es6 @@ -0,0 +1,14 @@ +import EmailLog from 'admin/models/email-log'; + +export default Discourse.Route.extend({ + + model() { + return EmailLog.findAll({ status: this.get("status") }); + }, + + setupController(controller, model) { + controller.set("model", model); + controller.set("filter", { status: this.get("status") }); + } + +}); diff --git a/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6 b/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6 index 94d48e400df..7ca2f727722 100644 --- a/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6 @@ -1,7 +1,9 @@ +import EmailPreview from 'admin/models/email-preview'; + export default Discourse.Route.extend({ model() { - return Discourse.EmailPreview.findDigest(); + return EmailPreview.findDigest(); }, afterModel(model) { diff --git a/app/assets/javascripts/admin/routes/admin-email-received.js.es6 b/app/assets/javascripts/admin/routes/admin-email-received.js.es6 new file mode 100644 index 00000000000..4bea62c1eb2 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-email-received.js.es6 @@ -0,0 +1,2 @@ +import AdminEmailIncomings from 'admin/routes/admin-email-incomings'; +export default AdminEmailIncomings.extend({ status: "received" }); diff --git a/app/assets/javascripts/admin/routes/admin-email-rejected.js.es6 b/app/assets/javascripts/admin/routes/admin-email-rejected.js.es6 new file mode 100644 index 00000000000..a7819b31a60 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-email-rejected.js.es6 @@ -0,0 +1,14 @@ +import showModal from 'discourse/lib/show-modal'; +import AdminEmailIncomings from 'admin/routes/admin-email-incomings'; + +export default AdminEmailIncomings.extend({ + status: "rejected", + + actions: { + showIncomingEmail(id) { + showModal('modals/admin-incoming-email'); + this.controllerFor("modals/admin-incoming-email").load(id); + } + } + +}); diff --git a/app/assets/javascripts/admin/routes/admin-email-sent.js.es6 b/app/assets/javascripts/admin/routes/admin-email-sent.js.es6 new file mode 100644 index 00000000000..cf445973718 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-email-sent.js.es6 @@ -0,0 +1,2 @@ +import AdminEmailLogs from 'admin/routes/admin-email-logs'; +export default AdminEmailLogs.extend({ status: "sent" }); diff --git a/app/assets/javascripts/admin/routes/admin-email-skipped.js.es6 b/app/assets/javascripts/admin/routes/admin-email-skipped.js.es6 new file mode 100644 index 00000000000..90afc8bc381 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-email-skipped.js.es6 @@ -0,0 +1,2 @@ +import AdminEmailLogs from 'admin/routes/admin-email-logs'; +export default AdminEmailLogs.extend({ status: "skipped" }); diff --git a/app/assets/javascripts/admin/routes/admin-flags-list.js.es6 b/app/assets/javascripts/admin/routes/admin-flags-list.js.es6 index e277ef4417a..ebbc3e6d2bc 100644 --- a/app/assets/javascripts/admin/routes/admin-flags-list.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-flags-list.js.es6 @@ -1,9 +1,10 @@ import showModal from 'discourse/lib/show-modal'; +import FlaggedPost from 'admin/models/flagged-post'; export default Discourse.Route.extend({ model(params) { this.filter = params.filter; - return Discourse.FlaggedPost.findAll(params.filter); + return FlaggedPost.findAll(params.filter); }, setupController(controller, model) { diff --git a/app/assets/javascripts/admin/routes/admin-group.js.es6 b/app/assets/javascripts/admin/routes/admin-group.js.es6 index b46022a6460..1555c4200a5 100644 --- a/app/assets/javascripts/admin/routes/admin-group.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-group.js.es6 @@ -21,6 +21,7 @@ export default Discourse.Route.extend({ setupController: function(controller, model) { controller.set("model", model); controller.set("model.usernames", null); + controller.set("savingStatus", ''); model.findMembers(); } diff --git a/app/assets/javascripts/admin/routes/admin-groups-bulk.js.es6 b/app/assets/javascripts/admin/routes/admin-groups-bulk.js.es6 new file mode 100644 index 00000000000..8d9554556f8 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-groups-bulk.js.es6 @@ -0,0 +1,13 @@ +import Group from 'discourse/models/group'; + +export default Ember.Route.extend({ + model() { + return Group.findAll().then(groups => { + return groups.filter(g => !g.get('automatic')); + }); + }, + + setupController(controller, groups) { + controller.setProperties({ groups, groupId: null, users: null }); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-groups-type.js.es6 b/app/assets/javascripts/admin/routes/admin-groups-type.js.es6 index def99aa7c15..52e383bf9a0 100644 --- a/app/assets/javascripts/admin/routes/admin-groups-type.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-groups-type.js.es6 @@ -1,7 +1,9 @@ +import Group from 'discourse/models/group'; + export default Discourse.Route.extend({ model(params) { this.set("type", params.type); - return Discourse.Group.findAll().then(function(groups) { + return Group.findAll().then(function(groups) { return groups.filterBy("type", params.type); }); }, diff --git a/app/assets/javascripts/admin/routes/admin-logs-index.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-index.js.es6 new file mode 100644 index 00000000000..c3ee93bb012 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-logs-index.js.es6 @@ -0,0 +1,5 @@ +export default Discourse.Route.extend({ + redirect: function() { + this.transitionTo('adminLogs.staffActionLogs'); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6 new file mode 100644 index 00000000000..1008dc1c1db --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6 @@ -0,0 +1,9 @@ +export default Discourse.Route.extend({ + renderTemplate: function() { + this.render('admin/templates/logs/screened_emails', {into: 'adminLogs'}); + }, + + setupController: function() { + return this.controllerFor('adminLogsScreenedEmails').show(); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6 new file mode 100644 index 00000000000..4aa57c17e21 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6 @@ -0,0 +1,9 @@ +export default Discourse.Route.extend({ + renderTemplate: function() { + this.render('admin/templates/logs/screened_ip_addresses', {into: 'adminLogs'}); + }, + + setupController: function() { + return this.controllerFor('adminLogsScreenedIpAddresses').show(); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6 new file mode 100644 index 00000000000..093dd263319 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6 @@ -0,0 +1,9 @@ +export default Discourse.Route.extend({ + renderTemplate: function() { + this.render('admin/templates/logs/screened_urls', {into: 'adminLogs'}); + }, + + setupController: function() { + return this.controllerFor('adminLogsScreenedUrls').show(); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-permalinks.js.es6 b/app/assets/javascripts/admin/routes/admin-permalinks.js.es6 index 72b7f444d2f..cd9c79cffcb 100644 --- a/app/assets/javascripts/admin/routes/admin-permalinks.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-permalinks.js.es6 @@ -1,6 +1,8 @@ +import Permalink from 'admin/models/permalink'; + export default Discourse.Route.extend({ model() { - return Discourse.Permalink.findAll(); + return Permalink.findAll(); }, setupController(controller, model) { diff --git a/app/assets/javascripts/admin/routes/admin_reports_route.js b/app/assets/javascripts/admin/routes/admin-reports.js.es6 similarity index 76% rename from app/assets/javascripts/admin/routes/admin_reports_route.js rename to app/assets/javascripts/admin/routes/admin-reports.js.es6 index 2e11a0d39e0..f3209a4e772 100644 --- a/app/assets/javascripts/admin/routes/admin_reports_route.js +++ b/app/assets/javascripts/admin/routes/admin-reports.js.es6 @@ -6,9 +6,10 @@ @namespace Discourse @module Discourse **/ -Discourse.AdminReportsRoute = Discourse.Route.extend({ +export default Discourse.Route.extend({ model: function(params) { - return Discourse.Report.find(params.type); + const Report = require('admin/models/report').default; + return Report.find(params.type); }, setupController: function(controller, model) { diff --git a/app/assets/javascripts/admin/routes/admin-route-map.js.es6 b/app/assets/javascripts/admin/routes/admin-route-map.js.es6 index e01d0f8f0d6..64a8e393a01 100644 --- a/app/assets/javascripts/admin/routes/admin-route-map.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-route-map.js.es6 @@ -8,9 +8,10 @@ export default { }); this.resource('adminEmail', { path: '/email'}, function() { - this.route('all'); this.route('sent'); this.route('skipped'); + this.route('received'); + this.route('rejected'); this.route('previewDigest', { path: '/preview-digest' }); }); @@ -22,12 +23,16 @@ export default { }); this.resource('adminSiteText', { path: '/site_texts' }, function() { - this.route('edit', {path: '/:text_type'}); + this.route('edit', { path: '/:id' }); }); + this.resource('adminUserFields', { path: '/user_fields' }); this.resource('adminEmojis', { path: '/emojis' }); this.resource('adminPermalinks', { path: '/permalinks' }); this.resource('adminEmbedding', { path: '/embedding' }); + this.resource('adminCustomizeEmailTemplates', { path: '/email_templates' }, function() { + this.route('edit', { path: '/:id' }); + }); }); this.route('api'); @@ -49,13 +54,15 @@ export default { }); this.resource('adminGroups', { path: '/groups' }, function() { + this.route('bulk'); + this.route('bulkComplete', { path: 'bulk-complete' }); this.resource('adminGroupsType', { path: '/:type' }, function() { this.resource('adminGroup', { path: '/:name' }); }); }); this.resource('adminUsers', { path: '/users' }, function() { - this.resource('adminUser', { path: '/:username' }, function() { + this.resource('adminUser', { path: '/:user_id/:username' }, function() { this.route('badges'); this.route('tl3Requirements', { path: '/tl3_requirements' }); }); diff --git a/app/assets/javascripts/admin/routes/admin-site-text-edit.js.es6 b/app/assets/javascripts/admin/routes/admin-site-text-edit.js.es6 index 847746d0396..2774f0aec9e 100644 --- a/app/assets/javascripts/admin/routes/admin-site-text-edit.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-site-text-edit.js.es6 @@ -1,5 +1,9 @@ -export default Discourse.Route.extend({ +export default Ember.Route.extend({ model(params) { - return this.store.find('site-text', params.text_type); + return this.store.find('site-text', params.id); + }, + + setupController(controller, siteText) { + controller.setProperties({ siteText, saved: false }); } }); diff --git a/app/assets/javascripts/admin/routes/admin-site-text-index.js.es6 b/app/assets/javascripts/admin/routes/admin-site-text-index.js.es6 new file mode 100644 index 00000000000..510fd93deea --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-site-text-index.js.es6 @@ -0,0 +1,14 @@ +export default Ember.Route.extend({ + queryParams: { + q: { replace: true }, + overridden: { replace: true } + }, + + model(params) { + return this.store.find('site-text', Ember.getProperties(params, 'q', 'overridden')); + }, + + setupController(controller, model) { + controller.set('siteTexts', model); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-user-index.js.es6 b/app/assets/javascripts/admin/routes/admin-user-index.js.es6 index fdcf844abd8..5a3afa10caa 100644 --- a/app/assets/javascripts/admin/routes/admin-user-index.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-user-index.js.es6 @@ -1,4 +1,5 @@ import showModal from 'discourse/lib/show-modal'; +import Group from 'discourse/models/group'; export default Discourse.Route.extend({ model() { @@ -8,7 +9,7 @@ export default Discourse.Route.extend({ afterModel(model) { if (this.currentUser.get('admin')) { const self = this; - return Discourse.Group.findAll().then(function(groups){ + return Group.findAll().then(function(groups){ self._availableGroups = groups.filterBy('automatic', false); return model; }); diff --git a/app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6 b/app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6 new file mode 100644 index 00000000000..40c874eaaa1 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6 @@ -0,0 +1,5 @@ +export default Discourse.Route.extend({ + model: function() { + return this.modelFor('adminUser'); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-user.js.es6 b/app/assets/javascripts/admin/routes/admin-user.js.es6 index 03c236ab9be..35a105a1052 100644 --- a/app/assets/javascripts/admin/routes/admin-user.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-user.js.es6 @@ -1,10 +1,12 @@ +import AdminUser from 'admin/models/admin-user'; + export default Discourse.Route.extend({ serialize(model) { - return { username: model.get('username').toLowerCase() }; + return { user_id: model.get('id'), username: model.get('username').toLowerCase() }; }, model(params) { - return Discourse.AdminUser.find(Em.get(params, 'username').toLowerCase()); + return AdminUser.find(Em.get(params, 'user_id')); }, renderTemplate() { diff --git a/app/assets/javascripts/admin/routes/admin-users-list-index.js.es6 b/app/assets/javascripts/admin/routes/admin-users-list-index.js.es6 index 09c09197d5d..4f2d30218e4 100644 --- a/app/assets/javascripts/admin/routes/admin-users-list-index.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-users-list-index.js.es6 @@ -1,5 +1,5 @@ export default Discourse.Route.extend({ beforeModel: function() { - this.replaceWith('adminUsersList.show', 'active'); + this.transitionTo('adminUsersList.show', 'active'); } }); diff --git a/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6 b/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6 index 87d5fce68c9..eacefeb15a6 100644 --- a/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6 @@ -1,7 +1,9 @@ +import AdminUser from 'admin/models/admin-user'; + export default Discourse.Route.extend({ model: function(params) { this.userFilter = params.filter; - return Discourse.AdminUser.findAll(params.filter); + return AdminUser.findAll(params.filter); }, setupController: function(controller, model) { diff --git a/app/assets/javascripts/admin/routes/admin-users-list.js.es6 b/app/assets/javascripts/admin/routes/admin-users-list.js.es6 index 1a2b08d29ea..ab72eb893c2 100644 --- a/app/assets/javascripts/admin/routes/admin-users-list.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-users-list.js.es6 @@ -1,19 +1,20 @@ import { exportEntity } from 'discourse/lib/export-csv'; import { outputExportResult } from 'discourse/lib/export-result'; +import AdminUser from 'admin/models/admin-user'; export default Discourse.Route.extend({ actions: { - exportUsers: function() { - exportEntity('user_list').then(outputExportResult); + exportUsers() { + exportEntity('user_list', {trust_level: this.controllerFor('admin-users-list-show').get('query')}).then(outputExportResult); }, - sendInvites: function() { + sendInvites() { this.transitionTo('userInvited', Discourse.User.current()); }, - deleteUser: function(user) { - Discourse.AdminUser.create(user).destroy({ deletePosts: true }); + deleteUser(user) { + AdminUser.create(user).destroy({ deletePosts: true }); } } diff --git a/app/assets/javascripts/admin/routes/admin_email_index_route.js b/app/assets/javascripts/admin/routes/admin_email_index_route.js deleted file mode 100644 index 479d5911711..00000000000 --- a/app/assets/javascripts/admin/routes/admin_email_index_route.js +++ /dev/null @@ -1,9 +0,0 @@ -Discourse.AdminEmailIndexRoute = Discourse.Route.extend({ - model: function() { - return Discourse.EmailSettings.find(); - }, - - renderTemplate: function() { - this.render('admin/templates/email_index', { into: 'adminEmail' }); - } -}); diff --git a/app/assets/javascripts/admin/routes/admin_email_logs_routes.js b/app/assets/javascripts/admin/routes/admin_email_logs_routes.js deleted file mode 100644 index 757cded71d4..00000000000 --- a/app/assets/javascripts/admin/routes/admin_email_logs_routes.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - Handles routes related to viewing email logs. - - @class AdminEmailSentRoute - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.AdminEmailLogsRoute = Discourse.Route.extend({ - - model: function() { - return Discourse.EmailLog.findAll({ status: this.get("status") }); - }, - - setupController: function(controller, model) { - controller.set("model", model); - // resets the filters - controller.set("filter", { status: this.get("status") }); - }, - - renderTemplate: function() { - this.render("admin/templates/email_" + this.get("status"), { into: "adminEmail" }); - } - -}); - -Discourse.AdminEmailAllRoute = Discourse.AdminEmailLogsRoute.extend({ status: "all" }); -Discourse.AdminEmailSentRoute = Discourse.AdminEmailLogsRoute.extend({ status: "sent" }); -Discourse.AdminEmailSkippedRoute = Discourse.AdminEmailLogsRoute.extend({ status: "skipped" }); diff --git a/app/assets/javascripts/admin/routes/admin_logs_routes.js b/app/assets/javascripts/admin/routes/admin_logs_routes.js deleted file mode 100644 index ad54a895d4e..00000000000 --- a/app/assets/javascripts/admin/routes/admin_logs_routes.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - Index redirects to a default logs index. - - @class AdminLogsIndexRoute - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.AdminLogsIndexRoute = Discourse.Route.extend({ - redirect: function() { - this.transitionTo('adminLogs.staffActionLogs'); - } -}); - -/** - The route that lists blocked email addresses. - - @class AdminLogsScreenedEmailsRoute - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.AdminLogsScreenedEmailsRoute = Discourse.Route.extend({ - renderTemplate: function() { - this.render('admin/templates/logs/screened_emails', {into: 'adminLogs'}); - }, - - setupController: function() { - return this.controllerFor('adminLogsScreenedEmails').show(); - } -}); - -/** - The route that lists screened IP addresses. - - @class AdminLogsScreenedIpAddresses - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.AdminLogsScreenedIpAddressesRoute = Discourse.Route.extend({ - renderTemplate: function() { - this.render('admin/templates/logs/screened_ip_addresses', {into: 'adminLogs'}); - }, - - setupController: function() { - return this.controllerFor('adminLogsScreenedIpAddresses').show(); - } -}); - -/** - The route that lists screened URLs. - - @class AdminLogsScreenedUrlsRoute - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.AdminLogsScreenedUrlsRoute = Discourse.Route.extend({ - renderTemplate: function() { - this.render('admin/templates/logs/screened_urls', {into: 'adminLogs'}); - }, - - setupController: function() { - return this.controllerFor('adminLogsScreenedUrls').show(); - } -}); diff --git a/app/assets/javascripts/admin/routes/admin_user_tl3_requirements_route.js b/app/assets/javascripts/admin/routes/admin_user_tl3_requirements_route.js deleted file mode 100644 index 934ccbb556c..00000000000 --- a/app/assets/javascripts/admin/routes/admin_user_tl3_requirements_route.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - Shows all the requirements for being at trust level 3 and if the - given user is meeting them. - - @class AdminUserLeaderRequirementsRoute - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.AdminUserTl3RequirementsRoute = Discourse.Route.extend({ - model: function() { - return this.modelFor('adminUser'); - } -}); diff --git a/app/assets/javascripts/admin/templates/admin.hbs b/app/assets/javascripts/admin/templates/admin.hbs index c7746a6d4a6..13afd577f77 100644 --- a/app/assets/javascripts/admin/templates/admin.hbs +++ b/app/assets/javascripts/admin/templates/admin.hbs @@ -7,18 +7,18 @@ {{#if currentUser.admin}} {{nav-item route='adminSiteSettings' label='admin.site_settings.title'}} {{/if}} - {{nav-item route='adminUsersList.show' routeParam='active' label='admin.users.title'}} + {{nav-item route='adminUsersList' label='admin.users.title'}} {{#if showBadges}} - {{nav-item route='adminBadges.index' label='admin.badges.title'}} + {{nav-item route='adminBadges' label='admin.badges.title'}} {{/if}} {{#if currentUser.admin}} {{nav-item route='adminGroups' label='admin.groups.title'}} + {{nav-item route='adminEmail' label='admin.email.title'}} {{/if}} - {{nav-item route='adminEmail' label='admin.email.title'}} {{nav-item route='adminFlags' label='admin.flags.title'}} {{nav-item route='adminLogs' label='admin.logs.title'}} {{#if currentUser.admin}} - {{nav-item route='adminCustomize.colors' label='admin.customize.title'}} + {{nav-item route='adminCustomize' label='admin.customize.title'}} {{nav-item route='admin.api' label='admin.api.title'}} {{nav-item route='admin.backups' label='admin.backups.title'}} {{/if}} diff --git a/app/assets/javascripts/admin/templates/badges-show.hbs b/app/assets/javascripts/admin/templates/badges-show.hbs index 2a6b74f1694..419dc47c07e 100644 --- a/app/assets/javascripts/admin/templates/badges-show.hbs +++ b/app/assets/javascripts/admin/templates/badges-show.hbs @@ -2,25 +2,22 @@
- {{input type="text" name="name" value=buffered.name}} + {{#if readOnly}} + {{input type="text" name="name" value=buffered.displayName disabled=true}} + {{else}} + {{input type="text" name="name" value=buffered.name}} + {{/if}}
- {{#if showDisplayName}} -
- {{i18n 'admin.badges.display_name'}} - {{buffered.displayName}} -
- {{/if}} -
- - {{input type="text" name="name" value=buffered.icon}} + + {{input type="text" name="icon" value=buffered.icon}}

{{i18n 'admin.badges.icon_help'}}

- - {{input type="text" name="name" value=buffered.image}} + + {{input type="text" name="image" value=buffered.image}}

{{i18n 'admin.badges.icon_help'}}

@@ -40,17 +37,26 @@ value=buffered.badge_grouping_id content=badgeGroupings optionValuePath="content.id" - optionLabelPath="content.name"}} + optionLabelPath="content.displayName"}}  
- {{#if canEditDescription}} - {{textarea name="description" value=buffered.description}} - {{else}} + {{#if buffered.system}} {{textarea name="description" value=buffered.displayDescription disabled=true}} + {{else}} + {{textarea name="description" value=buffered.description}} + {{/if}} +
+ +
+ + {{#if buffered.system}} + {{textarea name="long_description" value=buffered.long_description disabled=true}} + {{else}} + {{textarea name="long_description" value=buffered.long_description}} {{/if}}
diff --git a/app/assets/javascripts/admin/templates/components/admin-report-trust-level-counts.hbs b/app/assets/javascripts/admin/templates/components/admin-report-trust-level-counts.hbs index 93df84f2bc1..c78e2630035 100644 --- a/app/assets/javascripts/admin/templates/components/admin-report-trust-level-counts.hbs +++ b/app/assets/javascripts/admin/templates/components/admin-report-trust-level-counts.hbs @@ -1,6 +1,6 @@ {{report.title}} {{#link-to 'adminUsersList.show' 'newuser'}}{{value-at-tl report.data level="0"}}{{/link-to}} {{#link-to 'adminUsersList.show' 'basic'}}{{value-at-tl report.data level="1"}}{{/link-to}} -{{#link-to 'adminUsersList.show' 'regular'}}{{value-at-tl report.data level="2"}}{{/link-to}} -{{#link-to 'adminUsersList.show' 'leader'}}{{value-at-tl report.data level="3"}}{{/link-to}} -{{#link-to 'adminUsersList.show' 'elder'}}{{value-at-tl report.data level="4"}}{{/link-to}} +{{#link-to 'adminUsersList.show' 'member'}}{{value-at-tl report.data level="2"}}{{/link-to}} +{{#link-to 'adminUsersList.show' 'regular'}}{{value-at-tl report.data level="3"}}{{/link-to}} +{{#link-to 'adminUsersList.show' 'leader'}}{{value-at-tl report.data level="4"}}{{/link-to}} diff --git a/app/assets/javascripts/admin/templates/components/embedding-setting.hbs b/app/assets/javascripts/admin/templates/components/embedding-setting.hbs index 36dbb886925..eb63c40af9e 100644 --- a/app/assets/javascripts/admin/templates/components/embedding-setting.hbs +++ b/app/assets/javascripts/admin/templates/components/embedding-setting.hbs @@ -5,7 +5,7 @@ {{else}} - {{input value=value id=inputId}} + {{input value=value id=inputId placeholder=placeholder}} {{/if}}
diff --git a/app/assets/javascripts/admin/templates/components/save-controls.hbs b/app/assets/javascripts/admin/templates/components/save-controls.hbs new file mode 100644 index 00000000000..00ac91331fa --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/save-controls.hbs @@ -0,0 +1,7 @@ +{{d-button action="saveChanges" disabled=buttonDisabled label=savingText class="btn-primary save-changes"}} +{{yield}} +
+ {{#if saved}} +
{{i18n 'saved'}}
+ {{/if}} +
diff --git a/app/assets/javascripts/discourse/templates/components/screened-ip-address-form.hbs b/app/assets/javascripts/admin/templates/components/screened-ip-address-form.hbs similarity index 65% rename from app/assets/javascripts/discourse/templates/components/screened-ip-address-form.hbs rename to app/assets/javascripts/admin/templates/components/screened-ip-address-form.hbs index 5f58a282c40..e846b1c6527 100644 --- a/app/assets/javascripts/discourse/templates/components/screened-ip-address-form.hbs +++ b/app/assets/javascripts/admin/templates/components/screened-ip-address-form.hbs @@ -1,4 +1,4 @@ {{i18n 'admin.logs.screened_ips.form.label'}} {{text-field value=ip_address disabled=formSubmitted class="ip-address-input" placeholderKey="admin.logs.screened_ips.form.ip_address" autocorrect="off" autocapitalize="off"}} {{combo-box content=actionNames value=actionName}} - +{{d-button action="submit" disabled=formSubmitted label="admin.logs.screened_ips.form.add"}} diff --git a/app/assets/javascripts/admin/templates/components/site-setting.hbs b/app/assets/javascripts/admin/templates/components/site-setting.hbs index be0d4d8a08c..32510bef5fe 100644 --- a/app/assets/javascripts/admin/templates/components/site-setting.hbs +++ b/app/assets/javascripts/admin/templates/components/site-setting.hbs @@ -2,7 +2,7 @@

{{unbound settingName}}

-{{component componentName setting=setting value=buffered.value validationMessage=validationMessage}} + {{component componentName setting=setting value=buffered.value validationMessage=validationMessage}}
{{#if dirty}}
diff --git a/app/assets/javascripts/admin/templates/components/site-text-summary.hbs b/app/assets/javascripts/admin/templates/components/site-text-summary.hbs new file mode 100644 index 00000000000..bf5ee8c7f03 --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/site-text-summary.hbs @@ -0,0 +1,5 @@ +{{d-button label="admin.site_text.edit" class='edit' action="edit"}} +

{{siteText.id}}

+
{{siteText.value}}
+ +
diff --git a/app/assets/javascripts/admin/templates/customize-email-templates-edit.hbs b/app/assets/javascripts/admin/templates/customize-email-templates-edit.hbs new file mode 100644 index 00000000000..c23e3caef09 --- /dev/null +++ b/app/assets/javascripts/admin/templates/customize-email-templates-edit.hbs @@ -0,0 +1,18 @@ + diff --git a/app/assets/javascripts/admin/templates/customize-email-templates-index.hbs b/app/assets/javascripts/admin/templates/customize-email-templates-index.hbs new file mode 100644 index 00000000000..46dcce149fa --- /dev/null +++ b/app/assets/javascripts/admin/templates/customize-email-templates-index.hbs @@ -0,0 +1 @@ +

{{i18n "admin.customize.email_templates.none_selected"}}

diff --git a/app/assets/javascripts/admin/templates/customize-email-templates.hbs b/app/assets/javascripts/admin/templates/customize-email-templates.hbs new file mode 100644 index 00000000000..152c02e44a2 --- /dev/null +++ b/app/assets/javascripts/admin/templates/customize-email-templates.hbs @@ -0,0 +1,15 @@ +
+
+
    + {{#each sortedTemplates as |et|}} +
  • + {{#link-to 'adminCustomizeEmailTemplates.edit' et}}{{et.title}}{{/link-to}} +
  • + {{/each}} +
+
+ +
+ {{outlet}} +
+
diff --git a/app/assets/javascripts/admin/templates/customize.hbs b/app/assets/javascripts/admin/templates/customize.hbs index 8ab4c662e74..7696b34811f 100644 --- a/app/assets/javascripts/admin/templates/customize.hbs +++ b/app/assets/javascripts/admin/templates/customize.hbs @@ -1,13 +1,16 @@ -{{#admin-nav}} - {{nav-item route='adminCustomize.colors' label='admin.customize.colors.title'}} - {{nav-item route='adminCustomizeCssHtml.index' label='admin.customize.css_html.title'}} - {{nav-item route='adminSiteText' label='admin.site_text.title'}} - {{nav-item route='adminUserFields' label='admin.user_fields.title'}} - {{nav-item route='adminEmojis' label='admin.emoji.title'}} - {{nav-item route='adminPermalinks' label='admin.permalink.title'}} - {{nav-item route='adminEmbedding' label='admin.embedding.title'}} -{{/admin-nav}} +
+ {{#admin-nav}} + {{nav-item route='adminCustomize.colors' label='admin.customize.colors.title'}} + {{nav-item route='adminCustomizeCssHtml' label='admin.customize.css_html.title'}} + {{nav-item route='adminSiteText' label='admin.site_text.title'}} + {{nav-item route='adminCustomizeEmailTemplates' label='admin.customize.email_templates.title'}} + {{nav-item route='adminUserFields' label='admin.user_fields.title'}} + {{nav-item route='adminEmojis' label='admin.emoji.title'}} + {{nav-item route='adminPermalinks' label='admin.permalink.title'}} + {{nav-item route='adminEmbedding' label='admin.embedding.title'}} + {{/admin-nav}} -
- {{outlet}} +
+ {{outlet}} +
diff --git a/app/assets/javascripts/admin/templates/dashboard.hbs b/app/assets/javascripts/admin/templates/dashboard.hbs index 9a3d98496a7..74356abfa64 100644 --- a/app/assets/javascripts/admin/templates/dashboard.hbs +++ b/app/assets/javascripts/admin/templates/dashboard.hbs @@ -1,3 +1,5 @@ +{{plugin-outlet "admin-dashboard-top"}} +
{{#if showVersionChecks}} {{partial 'admin/templates/version-checks'}} @@ -145,7 +147,7 @@ {{i18n 'admin.dashboard.uploads'}} {{disk_space.uploads_used}} ({{i18n 'admin.dashboard.space_free' size=disk_space.uploads_free}}) - {{i18n 'admin.dashboard.backups'}} + {{#if currentUser.admin}}{{i18n 'admin.dashboard.backups'}}{{/if}} {{disk_space.backups_used}} ({{i18n 'admin.dashboard.space_free' size=disk_space.backups_free}}) {{/unless}} @@ -283,7 +285,7 @@ {{#each r in top_referrers.data}} - {{#link-to 'adminUser' r}}{{unbound r.username}}{{/link-to}} + {{#link-to 'adminUser' r.user_id r.username}}{{unbound r.username}}{{/link-to}} {{r.num_clicks}} {{r.num_topics}} diff --git a/app/assets/javascripts/admin/templates/email-received.hbs b/app/assets/javascripts/admin/templates/email-received.hbs new file mode 100644 index 00000000000..e6e3bcbec96 --- /dev/null +++ b/app/assets/javascripts/admin/templates/email-received.hbs @@ -0,0 +1,57 @@ +{{#load-more selector=".email-list tr" action="loadMore"}} + + + + + + + + + + + + + + + + + + {{#each email in model}} + + + + + + + {{else}} + + {{/each}} + + +{{/load-more}} + +{{conditional-loading-spinner condition=loading}} diff --git a/app/assets/javascripts/admin/templates/email-rejected.hbs b/app/assets/javascripts/admin/templates/email-rejected.hbs new file mode 100644 index 00000000000..664eb728669 --- /dev/null +++ b/app/assets/javascripts/admin/templates/email-rejected.hbs @@ -0,0 +1,56 @@ +{{#load-more selector=".email-list tr" action="loadMore"}} + + + + + + + + + + + + + + + + + + + + {{#each email in model}} + + + + + + + + {{else}} + + {{/each}} + + +{{/load-more}} + +{{conditional-loading-spinner condition=loading}} diff --git a/app/assets/javascripts/admin/templates/email-sent.hbs b/app/assets/javascripts/admin/templates/email-sent.hbs new file mode 100644 index 00000000000..ca5fb4aaa2a --- /dev/null +++ b/app/assets/javascripts/admin/templates/email-sent.hbs @@ -0,0 +1,49 @@ +{{#load-more selector=".email-list tr" action="loadMore"}} + + + + + + + + + + + + + + + + + + + + {{#each l in model}} + + + + + + + + {{else}} + + {{/each}} + + +{{/load-more}} + +{{conditional-loading-spinner condition=loading}} diff --git a/app/assets/javascripts/admin/templates/email-skipped.hbs b/app/assets/javascripts/admin/templates/email-skipped.hbs new file mode 100644 index 00000000000..9c21c428cd9 --- /dev/null +++ b/app/assets/javascripts/admin/templates/email-skipped.hbs @@ -0,0 +1,49 @@ +{{#load-more selector=".email-list tr" action="loadMore"}} + + + + + + + + + + + + + + + + + + + + {{#each l in model}} + + + + + + + + {{else}} + + {{/each}} + + +{{/load-more}} + +{{conditional-loading-spinner condition=loading}} diff --git a/app/assets/javascripts/admin/templates/email.hbs b/app/assets/javascripts/admin/templates/email.hbs index 73886537778..1a7d5bbfe7b 100644 --- a/app/assets/javascripts/admin/templates/email.hbs +++ b/app/assets/javascripts/admin/templates/email.hbs @@ -1,9 +1,11 @@ {{#admin-nav}} {{nav-item route='adminEmail.index' label='admin.email.settings'}} - {{nav-item route='adminEmail.all' label='admin.email.all'}} + {{nav-item route='adminEmail.previewDigest' label='admin.email.preview_digest'}} + {{nav-item route='adminCustomizeEmailTemplates' label='admin.email.templates'}} {{nav-item route='adminEmail.sent' label='admin.email.sent'}} {{nav-item route='adminEmail.skipped' label='admin.email.skipped'}} - {{nav-item route='adminEmail.previewDigest' label='admin.email.preview_digest'}} + {{nav-item route='adminEmail.received' label='admin.email.received'}} + {{nav-item route='adminEmail.rejected' label='admin.email.rejected'}} {{/admin-nav}}
diff --git a/app/assets/javascripts/admin/templates/email_all.hbs b/app/assets/javascripts/admin/templates/email_all.hbs deleted file mode 100644 index c2c6d261a7e..00000000000 --- a/app/assets/javascripts/admin/templates/email_all.hbs +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - {{#each l in model}} - - - - - - - - {{else}} - - {{/each}} - -
{{i18n 'admin.email.time'}}{{i18n 'admin.email.user'}}{{i18n 'admin.email.to_address'}}{{i18n 'admin.email.email_type'}}{{i18n 'admin.email.skipped_reason'}}
{{i18n 'admin.email.logs.filters.title'}}{{text-field value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}}{{text-field value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}}{{text-field value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}}{{text-field value=filter.skipped_reason placeholderKey="admin.email.logs.filters.skipped_reason_placeholder"}}
{{format-date l.created_at}} - {{#if l.user}} - {{#link-to 'adminUser' l.user}}{{avatar l.user imageSize="tiny"}}{{/link-to}} - {{#link-to 'adminUser' l.user}}{{l.user.username}}{{/link-to}} - {{else}} - — - {{/if}} - {{l.to_address}}{{l.email_type}}{{l.skipped_reason}}
{{i18n 'admin.email.logs.none'}}
diff --git a/app/assets/javascripts/admin/templates/email_preview_digest.hbs b/app/assets/javascripts/admin/templates/email_preview_digest.hbs index 83d99db35ff..630260f1317 100644 --- a/app/assets/javascripts/admin/templates/email_preview_digest.hbs +++ b/app/assets/javascripts/admin/templates/email_preview_digest.hbs @@ -4,6 +4,8 @@
{{input type="date" value=lastSeen id="last-seen"}} + + {{user-selector single="true" usernames=username}}
diff --git a/app/assets/javascripts/admin/templates/email_sent.hbs b/app/assets/javascripts/admin/templates/email_sent.hbs deleted file mode 100644 index 0287492f178..00000000000 --- a/app/assets/javascripts/admin/templates/email_sent.hbs +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - {{#each l in model}} - - - - - - - - {{else}} - - {{/each}} - -
{{i18n 'admin.email.sent_at'}}{{i18n 'admin.email.user'}}{{i18n 'admin.email.to_address'}}{{i18n 'admin.email.email_type'}}{{i18n 'admin.email.reply_key'}}
{{i18n 'admin.email.logs.filters.title'}}{{text-field value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}}{{text-field value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}}{{text-field value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}}{{text-field value=filter.reply_key placeholderKey="admin.email.logs.filters.reply_key_placeholder"}}
{{format-date l.created_at}} - {{#if l.user}} - {{#link-to 'adminUser' l.user}}{{avatar l.user imageSize="tiny"}}{{/link-to}} - {{#link-to 'adminUser' l.user}}{{l.user.username}}{{/link-to}} - {{else}} - — - {{/if}} - {{l.to_address}}{{l.email_type}}{{l.reply_key}}
{{i18n 'admin.email.logs.none'}}
diff --git a/app/assets/javascripts/admin/templates/email_skipped.hbs b/app/assets/javascripts/admin/templates/email_skipped.hbs deleted file mode 100644 index c2c6d261a7e..00000000000 --- a/app/assets/javascripts/admin/templates/email_skipped.hbs +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - {{#each l in model}} - - - - - - - - {{else}} - - {{/each}} - -
{{i18n 'admin.email.time'}}{{i18n 'admin.email.user'}}{{i18n 'admin.email.to_address'}}{{i18n 'admin.email.email_type'}}{{i18n 'admin.email.skipped_reason'}}
{{i18n 'admin.email.logs.filters.title'}}{{text-field value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}}{{text-field value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}}{{text-field value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}}{{text-field value=filter.skipped_reason placeholderKey="admin.email.logs.filters.skipped_reason_placeholder"}}
{{format-date l.created_at}} - {{#if l.user}} - {{#link-to 'adminUser' l.user}}{{avatar l.user imageSize="tiny"}}{{/link-to}} - {{#link-to 'adminUser' l.user}}{{l.user.username}}{{/link-to}} - {{else}} - — - {{/if}} - {{l.to_address}}{{l.email_type}}{{l.skipped_reason}}
{{i18n 'admin.email.logs.none'}}
diff --git a/app/assets/javascripts/admin/templates/embedding.hbs b/app/assets/javascripts/admin/templates/embedding.hbs index 15d021a9c17..6fbe31c124c 100644 --- a/app/assets/javascripts/admin/templates/embedding.hbs +++ b/app/assets/javascripts/admin/templates/embedding.hbs @@ -46,8 +46,17 @@

{{i18n "admin.embedding.crawling_settings"}}

{{i18n "admin.embedding.crawling_description"}}

- {{embedding-setting field="embed_whitelist_selector" value=embedding.embed_whitelist_selector}} - {{embedding-setting field="embed_blacklist_selector" value=embedding.embed_blacklist_selector}} + {{embedding-setting field="embed_whitelist_selector" + value=embedding.embed_whitelist_selector + placeholder="article, #story, .post"}} + + {{embedding-setting field="embed_blacklist_selector" + value=embedding.embed_blacklist_selector + placeholder=".ad-unit, header"}} + + {{embedding-setting field="embed_classname_whitelist" + value=embedding.embed_classname_whitelist + placeholder="emoji, classname"}}
diff --git a/app/assets/javascripts/admin/templates/group.hbs b/app/assets/javascripts/admin/templates/group.hbs index ac1f979691c..585df0bcaf7 100644 --- a/app/assets/javascripts/admin/templates/group.hbs +++ b/app/assets/javascripts/admin/templates/group.hbs @@ -10,6 +10,23 @@
{{#if model.id}} + {{#unless model.automatic}} + {{#if model.hasOwners}} +
+ +
+ {{#each model.owners as |member|}} + {{group-member member=member removeAction="removeOwner"}} + {{/each}} +
+
+ {{/if}} +
+ + {{user-selector usernames=model.ownerUsernames placeholderKey="admin.groups.selector_placeholder" id="owner-selector"}} + {{d-button action="addOwners" class="add" icon="plus" label="admin.groups.add"}} +
+ {{/unless}}
@@ -75,6 +92,13 @@ {{combo-box name="grant_trust_level" valueAttribute="value" value=model.grant_trust_level content=trustLevelOptions}}
+ + {{#if siteSettings.email_in}} +
+ + {{text-field name="incoming_email" value=model.incoming_email placeholderKey="admin.groups.incoming_email_placeholder"}} +
+ {{/if}} {{/unless}}
@@ -82,6 +106,7 @@ {{#unless model.automatic}} {{/unless}} + {{savingStatus}}
diff --git a/app/assets/javascripts/admin/templates/groups-bulk-complete.hbs b/app/assets/javascripts/admin/templates/groups-bulk-complete.hbs new file mode 100644 index 00000000000..51eb3e4394b --- /dev/null +++ b/app/assets/javascripts/admin/templates/groups-bulk-complete.hbs @@ -0,0 +1 @@ +

{{i18n "admin.groups.bulk_complete"}}

diff --git a/app/assets/javascripts/admin/templates/groups-bulk.hbs b/app/assets/javascripts/admin/templates/groups-bulk.hbs new file mode 100644 index 00000000000..baf3a63cda0 --- /dev/null +++ b/app/assets/javascripts/admin/templates/groups-bulk.hbs @@ -0,0 +1,19 @@ +
+

{{i18n "admin.groups.bulk_paste"}}

+ +
+ {{textarea value=users class="paste-users"}} +
+ +
+ {{combo-box content=groups valueAttribute="id" value=groupId none="admin.groups.bulk_select"}} +
+ +
+ {{d-button disabled=buttonDisabled + class="btn-primary" + action="addToGroup" + icon="plus" + label="admin.groups.bulk"}} +
+
diff --git a/app/assets/javascripts/admin/templates/groups.hbs b/app/assets/javascripts/admin/templates/groups.hbs index 2d767c38442..aa7d9213ca8 100644 --- a/app/assets/javascripts/admin/templates/groups.hbs +++ b/app/assets/javascripts/admin/templates/groups.hbs @@ -1,6 +1,7 @@ {{#admin-nav}} {{nav-item route='adminGroupsType' routeParam='custom' label='admin.groups.custom'}} {{nav-item route='adminGroupsType' routeParam='automatic' label='admin.groups.automatic'}} + {{nav-item route='adminGroups.bulk' label='admin.groups.bulk'}} {{/admin-nav}}
diff --git a/app/assets/javascripts/admin/templates/groups_type.hbs b/app/assets/javascripts/admin/templates/groups_type.hbs index 980ca08c8f6..3c4fc3e5061 100644 --- a/app/assets/javascripts/admin/templates/groups_type.hbs +++ b/app/assets/javascripts/admin/templates/groups_type.hbs @@ -4,7 +4,11 @@
    {{#each group in controller}}
  • - {{#link-to "adminGroup" group.type group.name}}{{group.name}} {{group.userCountDisplay}}{{/link-to}} + {{#link-to "adminGroup" group.type group.name}}{{group.name}} + {{#if group.userCountDisplay}} + {{group.userCountDisplay}} + {{/if}} + {{/link-to}}
  • {{/each}}
diff --git a/app/assets/javascripts/admin/templates/logs/screened_ip_addresses.hbs b/app/assets/javascripts/admin/templates/logs/screened_ip_addresses.hbs index 515c22a3a0b..5aaada9ea2f 100644 --- a/app/assets/javascripts/admin/templates/logs/screened_ip_addresses.hbs +++ b/app/assets/javascripts/admin/templates/logs/screened_ip_addresses.hbs @@ -1,11 +1,14 @@

{{i18n 'admin.logs.screened_ips.description'}}

+
{{text-field value=filter class="ip-address-input" placeholderKey="admin.logs.screened_ips.form.filter" autocorrect="off" autocapitalize="off"}} - - + {{d-button action="rollUp" title="admin.logs.screened_ips.roll_up.title" label="admin.logs.screened_ips.roll_up.text"}} + {{d-button action="exportScreenedIpList" icon="download" title="admin.export_csv.button_title.screened_ip" label="admin.export_csv.button_text"}} +
+ +
+ {{screened-ip-address-form action="recordAdded"}}
-{{screened-ip-address-form action="recordAdded"}} -
{{#conditional-loading-spinner condition=loading}} {{#if model.length}} diff --git a/app/assets/javascripts/admin/templates/modal/admin_agree_flag.hbs b/app/assets/javascripts/admin/templates/modal/admin_agree_flag.hbs index 14e1ae9c517..6c494e0e2c3 100644 --- a/app/assets/javascripts/admin/templates/modal/admin_agree_flag.hbs +++ b/app/assets/javascripts/admin/templates/modal/admin_agree_flag.hbs @@ -1,11 +1,11 @@ -{{#if user_deleted}} +{{#if model.user_deleted}} {{else}} - {{#unless postHidden}} + {{#unless model.postHidden}} {{/unless}} {{/if}} -{{#if canDeleteAsSpammer}} - +{{#if model.canDeleteAsSpammer}} + {{/if}} diff --git a/app/assets/javascripts/admin/templates/modal/admin_badge_preview.hbs b/app/assets/javascripts/admin/templates/modal/admin_badge_preview.hbs index 835a105cda9..e244d5b0ef9 100644 --- a/app/assets/javascripts/admin/templates/modal/admin_badge_preview.hbs +++ b/app/assets/javascripts/admin/templates/modal/admin_badge_preview.hbs @@ -14,7 +14,13 @@ --> {{else}} -

{{{i18n 'admin.badges.preview.grant_count' count=count}}}

+

+ {{#if count}} + {{{i18n 'admin.badges.preview.grant_count' count=count}}} + {{else}} + {{{i18n 'admin.badges.preview.no_grant_count'}}} + {{/if}} +

{{#if count_warning}}
diff --git a/app/assets/javascripts/admin/templates/modal/admin_delete_flag.hbs b/app/assets/javascripts/admin/templates/modal/admin_delete_flag.hbs index 5762101a1ff..926f81bd21f 100644 --- a/app/assets/javascripts/admin/templates/modal/admin_delete_flag.hbs +++ b/app/assets/javascripts/admin/templates/modal/admin_delete_flag.hbs @@ -1,5 +1,5 @@ -{{#if canDeleteAsSpammer}} - +{{#if model.canDeleteAsSpammer}} + {{/if}} diff --git a/app/assets/javascripts/admin/templates/modal/admin_edit_badge_groupings.hbs b/app/assets/javascripts/admin/templates/modal/admin_edit_badge_groupings.hbs index 1dd273e0fc4..f2a6581bbe6 100644 --- a/app/assets/javascripts/admin/templates/modal/admin_edit_badge_groupings.hbs +++ b/app/assets/javascripts/admin/templates/modal/admin_edit_badge_groupings.hbs @@ -5,15 +5,15 @@
  • {{#if wc.editing}} {{input value=wc.name}} - + {{else}} - {{wc.name}} + {{wc.displayName}} {{/if}}
    - - - - + + + +
  • {{/each}} diff --git a/app/assets/javascripts/admin/templates/modal/admin_incoming_email.hbs b/app/assets/javascripts/admin/templates/modal/admin_incoming_email.hbs new file mode 100644 index 00000000000..87f63b3a2f4 --- /dev/null +++ b/app/assets/javascripts/admin/templates/modal/admin_incoming_email.hbs @@ -0,0 +1,45 @@ +
    + +
    +

    {{model.error}}

    + {{#if model.error_description}} +

    {{model.error_description}}

    + {{/if}} +
    +
    + +
    + +
    + +
    + {{textarea value=model.headers wrap="off"}} +
    +
    + +
    + +
    + {{model.subject}} +
    +
    + +
    + +
    + {{textarea value=model.body}} +
    +
    + +{{#if model.rejection_message}} + +
    + +
    + +
    + {{textarea value=model.rejection_message}} +
    +
    + +{{/if}} diff --git a/app/assets/javascripts/admin/templates/plugins-index.hbs b/app/assets/javascripts/admin/templates/plugins-index.hbs index 5236d9d999b..b5928ae1efd 100644 --- a/app/assets/javascripts/admin/templates/plugins-index.hbs +++ b/app/assets/javascripts/admin/templates/plugins-index.hbs @@ -1,9 +1,11 @@ {{#if length}} - {{d-button label="admin.plugins.change_settings" - icon="gear" - class='settings-button pull-right' - action="showSettings"}} + {{#if currentUser.admin}} + {{d-button label="admin.plugins.change_settings" + icon="gear" + class='settings-button pull-right' + action="showSettings"}} + {{/if}}

    {{i18n "admin.plugins.installed"}}

    @@ -41,11 +43,10 @@ {{/if}} - {{#if plugin.enabled_setting}} - + {{#if currentUser.admin}} + {{#if plugin.enabled_setting}} + {{d-button action="showSettings" actionParam=plugin icon="gear" label="admin.plugins.change_settings_short"}} + {{/if}} {{/if}} diff --git a/app/assets/javascripts/admin/templates/reports.hbs b/app/assets/javascripts/admin/templates/reports.hbs index 718a61a2c1d..1f5360a8af0 100644 --- a/app/assets/javascripts/admin/templates/reports.hbs +++ b/app/assets/javascripts/admin/templates/reports.hbs @@ -1,9 +1,12 @@

    {{model.title}}

    -
    +
    {{i18n 'admin.dashboard.reports.start_date'}} {{input type="date" value=startDate}} {{i18n 'admin.dashboard.reports.end_date'}} {{input type="date" value=endDate}} {{combo-box valueAttribute="value" content=categoryOptions value=categoryId}} + {{#if showGroupOptions}} + {{combo-box valueAttribute="value" content=groupOptions value=groupId}} + {{/if}} {{d-button action="refreshReport" class="btn-primary" label="admin.dashboard.reports.refresh_report" icon="refresh"}} {{d-button action="exportCsv" label="admin.export_csv.button_text" icon="download"}}
    diff --git a/app/assets/javascripts/admin/templates/site-settings-category.hbs b/app/assets/javascripts/admin/templates/site-settings-category.hbs index 8cb5aedaa3a..3e8b088f692 100644 --- a/app/assets/javascripts/admin/templates/site-settings-category.hbs +++ b/app/assets/javascripts/admin/templates/site-settings-category.hbs @@ -1,6 +1,6 @@ {{#if filteredContent}}
    - {{#each setting in filteredContent}} + {{#each filteredContent as |setting|}} {{site-setting setting=setting saveAction="saveSetting"}} {{/each}}
    diff --git a/app/assets/javascripts/admin/templates/site-settings.hbs b/app/assets/javascripts/admin/templates/site-settings.hbs index b7f400a2420..d7e157a9291 100644 --- a/app/assets/javascripts/admin/templates/site-settings.hbs +++ b/app/assets/javascripts/admin/templates/site-settings.hbs @@ -6,9 +6,9 @@
    - + {{d-button action="toggleMenu" class="menu-toggle" icon="bars"}} {{text-field value=filter placeholderKey="type_to_filter" class="no-blur"}} - + {{d-button action="clearFilter" label="admin.site_settings.clear_filter"}}
    @@ -19,7 +19,7 @@ {{#link-to 'adminSiteSettingsCategory' category.nameKey class=category.nameKey}} {{category.name}} {{#if filtered}} - ({{category.siteSettings.length}}) + {{#if category.count}}({{category.count}}){{/if}} {{/if}} {{/link-to}} {{/link-to}} diff --git a/app/assets/javascripts/admin/templates/site-text-edit.hbs b/app/assets/javascripts/admin/templates/site-text-edit.hbs index 438887f85fe..5e02eb07316 100644 --- a/app/assets/javascripts/admin/templates/site-text-edit.hbs +++ b/app/assets/javascripts/admin/templates/site-text-edit.hbs @@ -1,26 +1,20 @@ -

    {{model.title}}

    -

    {{model.description}}

    +
    -{{#if model.markdown}} - {{pagedown-editor value=model.value}} -{{/if}} -{{#if model.plainText}} - {{textarea value=model.value class="plain"}} -{{/if}} -{{#if model.html}} - {{ace-editor content=model.value mode="html"}} -{{/if}} -{{#if model.css}} - {{ace-editor content=model.value mode="css"}} -{{/if}} +
    +

    {{siteText.id}}

    +
    -
    - - {{#if saved}}{{i18n 'saved'}}{{/if}} + {{/save-controls}} + + {{#link-to 'adminSiteText.index' class="go-back"}} + {{fa-icon 'arrow-left'}} + {{i18n 'admin.site_text.go_back'}} + {{/link-to}} +
    diff --git a/app/assets/javascripts/admin/templates/site-text-index.hbs b/app/assets/javascripts/admin/templates/site-text-index.hbs index 5a448def37a..7caf9b124e8 100644 --- a/app/assets/javascripts/admin/templates/site-text-index.hbs +++ b/app/assets/javascripts/admin/templates/site-text-index.hbs @@ -1 +1,23 @@ -

    {{i18n 'admin.site_text.none'}}

    +
    +

    {{i18n "admin.site_text.description"}}

    + + {{text-field value=q + placeholderKey="admin.site_text.search" + class="no-blur site-text-search" + autofocus="true" + key-up="search"}} + +
    + {{d-checkbox label="admin.site_text.show_overriden" checked=overridden change="search"}} +
    +
    + +{{#conditional-loading-spinner condition=searching}} + {{#if siteTexts.extras.recommended}} +

    {{i18n "admin.site_text.recommended"}}

    + {{/if}} + + {{#each siteTexts as |siteText|}} + {{site-text-summary siteText=siteText editAction="edit" term=q}} + {{/each}} +{{/conditional-loading-spinner}} diff --git a/app/assets/javascripts/admin/templates/site-text.hbs b/app/assets/javascripts/admin/templates/site-text.hbs index 25924f99e97..e12a542d794 100644 --- a/app/assets/javascripts/admin/templates/site-text.hbs +++ b/app/assets/javascripts/admin/templates/site-text.hbs @@ -1,15 +1,3 @@ -
    -
    -
      - {{#each c in model}} -
    • - {{#link-to 'adminSiteText.edit' c.text_type}}{{c.title}}{{/link-to}} -
    • - {{/each}} -
    -
    - -
    - {{outlet}} -
    +
    + {{outlet}}
    diff --git a/app/assets/javascripts/admin/templates/user-index.hbs b/app/assets/javascripts/admin/templates/user-index.hbs index bdbee2e5368..608d7c38ba8 100644 --- a/app/assets/javascripts/admin/templates/user-index.hbs +++ b/app/assets/javascripts/admin/templates/user-index.hbs @@ -1,11 +1,13 @@
    - {{#if model.active}} + {{#if model.canViewProfile}} {{#link-to 'user' model class="btn"}} {{fa-icon "user"}} {{i18n 'admin.user.show_public_profile'}} {{/link-to}} + {{/if}} + {{#if model.active}} {{#if model.can_impersonate}} - {{i18n 'admin.user.block_explanation'}} - {{/if}} + {{#conditional-loading-spinner size="small" condition=model.blockingUser}} + {{#if model.blocked}} + + {{i18n 'admin.user.block_explanation'}} + {{else}} + + {{i18n 'admin.user.block_explanation'}} + {{/if}} + {{/conditional-loading-spinner}}
    + +
    +
    {{i18n 'admin.user.staged'}}
    +
    {{model.staged}}
    +
    {{i18n 'admin.user.stage_explanation'}}
    +
    @@ -370,15 +386,15 @@
    {{i18n 'created'}}
    -
    {{{model.created_at_age}}}
    +
    {{format-date model.created_at leaveAgo="true"}}
    {{i18n 'admin.users.last_emailed'}}
    -
    {{{model.last_emailed_age}}}
    +
    {{format-date model.last_emailed_at leaveAgo="true"}}
    {{i18n 'last_seen'}}
    -
    {{{model.last_seen_age}}}
    +
    {{format-date model.last_seen_at leaveAgo="true"}}
    {{i18n 'admin.user.like_count'}}
    @@ -434,26 +450,26 @@

    {{i18n 'admin.user.sso.title'}}

    - {{#with model.single_sign_on_record}} + {{#with model.single_sign_on_record as |sso|}}
    {{i18n 'admin.user.sso.external_id'}}
    -
    {{external_id}}
    +
    {{sso.external_id}}
    {{i18n 'admin.user.sso.external_username'}}
    -
    {{external_username}}
    +
    {{sso.external_username}}
    {{i18n 'admin.user.sso.external_name'}}
    -
    {{external_name}}
    +
    {{sso.external_name}}
    {{i18n 'admin.user.sso.external_email'}}
    -
    {{external_email}}
    +
    {{sso.external_email}}
    {{i18n 'admin.user.sso.external_avatar_url'}}
    -
    {{external_avatar_url}}
    +
    {{sso.external_avatar_url}}
    {{/with}}
    diff --git a/app/assets/javascripts/admin/templates/user-tl3-requirements.hbs b/app/assets/javascripts/admin/templates/user-tl3-requirements.hbs index ca4a74e3fe5..d3e8e4edb10 100644 --- a/app/assets/javascripts/admin/templates/user-tl3-requirements.hbs +++ b/app/assets/javascripts/admin/templates/user-tl3-requirements.hbs @@ -2,7 +2,7 @@
    @@ -10,7 +10,7 @@

    {{model.username}} - {{i18n 'admin.user.tl3_requirements.title'}}


    -

    {{i18n 'admin.user.tl3_requirements.table_title'}}

    +

    {{i18n 'admin.user.tl3_requirements.table_title' time_period=model.tl3Requirements.time_period}}

    diff --git a/app/assets/javascripts/admin/templates/user_badges.hbs b/app/assets/javascripts/admin/templates/user_badges.hbs index 281a37e08c6..772360d21a6 100644 --- a/app/assets/javascripts/admin/templates/user_badges.hbs +++ b/app/assets/javascripts/admin/templates/user_badges.hbs @@ -16,7 +16,7 @@
    - {{combo-box valueAttribute="id" value=controller.selectedBadgeId content=controller.grantableBadges nameProperty="displayName"}} + {{combo-box valueAttribute="id" value=controller.selectedBadgeId content=controller.grantableBadges nameProperty="name"}}
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     <%=t 'js.about.stat.all_time' %><%=t 'js.about.stat.last_7_days' %><%=t 'js.about.stat.last_30_days' %>
    <%=t 'js.about.topic_count' %><%= @about.stats[:topic_count] %><%= @about.stats[:topics_7_days] %><%= @about.stats[:topics_30_days] %>
    <%=t 'js.about.post_count' %><%= @about.stats[:post_count] %><%= @about.stats[:posts_7_days] %><%= @about.stats[:posts_30_days] %>
    <%=t 'js.about.user_count' %><%= @about.stats[:user_count] %><%= @about.stats[:users_7_days] %><%= @about.stats[:users_30_days] %>
    <%=t 'js.about.active_user_count' %><%= @about.stats[:active_users_7_days] %><%= @about.stats[:active_users_30_days] %>
    <%=t 'js.about.like_count' %><%= @about.stats[:like_count] %><%= @about.stats[:likes_7_days] %><%= @about.stats[:likes_30_days] %>
    +
    + + +
    +
    \ No newline at end of file diff --git a/app/views/common/_discourse_javascript.html.erb b/app/views/common/_discourse_javascript.html.erb index 0f67c8f1c4f..921ece2c5ce 100644 --- a/app/views/common/_discourse_javascript.html.erb +++ b/app/views/common/_discourse_javascript.html.erb @@ -33,9 +33,21 @@ + <%= script "preload_store" %> <%= script "locales/#{I18n.locale}" %> + <%= script "ember_jquery" %> <%= script "vendor" %> <%= script "application" %> <%- if staff? %> @@ -31,6 +36,7 @@ <%- end %> <%= render_google_universal_analytics_code %> + <%= yield :head %> @@ -45,10 +51,10 @@
    @@ -58,8 +64,6 @@ - - <%- unless customization_disabled? || loading_admin? %> <%= SiteCustomization.custom_header(session[:preview_style], mobile_view? ? :mobile : :desktop) %> <%- end %> diff --git a/app/views/layouts/crawler.html.erb b/app/views/layouts/crawler.html.erb index e68f58beb2a..a2dfcf11a0b 100644 --- a/app/views/layouts/crawler.html.erb +++ b/app/views/layouts/crawler.html.erb @@ -11,7 +11,39 @@ <%= render_google_universal_analytics_code %> <%= yield :head %> @@ -19,7 +51,7 @@ <%= SiteCustomization.custom_header(session[:preview_style], mobile_view? ? :mobile : :desktop) %> <%- end %>
    - "> + ">
    <%= yield %> @@ -27,10 +59,10 @@

    <%= t 'powered_by_html' %>

    diff --git a/app/views/list/list.erb b/app/views/list/list.erb index b9ae8a0868a..23f6f8cc32a 100644 --- a/app/views/list/list.erb +++ b/app/views/list/list.erb @@ -1,3 +1,5 @@ +<%- if include_crawler_content? %> + <% if @category %>

    <% if @category.parent_category %> @@ -23,9 +25,9 @@ <%= page_links(t) %> <% if (!@category || @category.has_children?) && t.category %> - [<%= t.category.name %>] + [<%= t.category.name %>] <% end %> - '>(<%= t.posts_count %>) + '>(<%= t.posts_count %>)

    <% end %>
    @@ -39,6 +41,8 @@
    <% end %> +<%- end %> + <% if @rss %> <% content_for :head do %> <%= auto_discovery_link_tag(:rss, "#{Discourse.base_url}/posts.rss", title: I18n.t("rss_description.posts")) %> @@ -49,15 +53,14 @@ <% if @category %> <% content_for :head do %> <%= auto_discovery_link_tag(:rss, { action: :category_feed }, title: t('rss_topics_in_category', category: @category.name)) %> - <%= crawlable_meta_data(title: @category.name, - description: @category.description) %> + <%= raw crawlable_meta_data(title: @category.name, description: @category.description) %> <% end %> <% end %> <% if @title %> <% content_for :title do %><%= @title %><% end %> <% elsif @category %> - <% content_for :title do %><%=@category.name%> <%=t('topics')%><% end %> + <% content_for :title do %><%= @category.name %><% end %> <% elsif params[:page] %> <% content_for :title do %><%=t 'page_num', num: params[:page].to_i + 1 %><% end %> <% end %> diff --git a/app/views/list/list.rss.erb b/app/views/list/list.rss.erb index b1eb41f1038..7cc954ec2a0 100644 --- a/app/views/list/list.rss.erb +++ b/app/views/list/list.rss.erb @@ -30,7 +30,7 @@ <%= topic.pinned_at ? 'Yes' : 'No' %> <%= topic.closed ? 'Yes' : 'No' %> <%= topic.archived ? 'Yes' : 'No' %> - topic-<%= topic.id %> + <%= Discourse.current_hostname %>-topic-<%= topic.id %> <%= topic.title %> <% end %> diff --git a/app/views/posts/latest.rss.erb b/app/views/posts/latest.rss.erb index f0f452a9072..8f97eff3f00 100644 --- a/app/views/posts/latest.rss.erb +++ b/app/views/posts/latest.rss.erb @@ -7,14 +7,14 @@ <%= @link %> <%= @description %> <% @posts.each do |post| %> - <% next unless post.user && post.topic %> + <% next unless post.user %> <%= post.topic.title %> ]]> ]]> <%= Discourse.base_url + post.url %> <%= post.created_at.rfc2822 %> - post-<%= post.id %> + <%= Discourse.current_hostname %>-post-<%= post.id %> <% end %> diff --git a/app/views/static/login.html.erb b/app/views/static/login.html.erb index 6e840e6e9ab..ed8badab6fb 100644 --- a/app/views/static/login.html.erb +++ b/app/views/static/login.html.erb @@ -1,3 +1,3 @@ <% if SiteSetting.login_required %> - <%= markdown_content(:login_required_welcome_message) %> + <%= PrettyText.cook(I18n.t('login_required.welcome_message', title: SiteSetting.title)).html_safe %> <% end %> diff --git a/app/views/static/signup.html.erb b/app/views/static/signup.html.erb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/app/views/topics/plain.html.erb b/app/views/topics/plain.html.erb index 88385ff7da8..82da8dd745f 100644 --- a/app/views/topics/plain.html.erb +++ b/app/views/topics/plain.html.erb @@ -3,9 +3,7 @@ <%= @topic_view.topic.title %> - <%= crawlable_meta_data(title: @topic_view.title, - description: @topic_view.summary, - image: @topic_view.image_url) %> + <%= raw crawlable_meta_data(title: @topic_view.title, description: @topic_view.summary, image: @topic_view.image_url, read_time: @topic_view.read_time, like_count: @topic_view.like_count) %> <% @topic_view.posts.each do |post| %> diff --git a/app/views/topics/show.html.erb b/app/views/topics/show.html.erb index 9478eefd8fc..010999cc92c 100644 --- a/app/views/topics/show.html.erb +++ b/app/views/topics/show.html.erb @@ -20,6 +20,8 @@ <%= server_plugin_outlet "topic_header" %>
    +<%- if include_crawler_content? %> + <% @topic_view.posts.each do |post| %>
    <% if (u = post.user) %> @@ -54,11 +56,11 @@
    <% end %> +<% end %> + <% content_for :head do %> <%= auto_discovery_link_tag(@topic_view, {action: :feed, slug: @topic_view.topic.slug, topic_id: @topic_view.topic.id}, title: t('rss_posts_in_topic', topic: @topic_view.title), type: 'application/rss+xml') %> - <%= crawlable_meta_data(title: @topic_view.title, - description: @topic_view.summary, - image: @topic_view.image_url) %> + <%= raw crawlable_meta_data(title: @topic_view.title, description: @topic_view.summary, image: @topic_view.image_url, read_time: @topic_view.read_time, like_count: @topic_view.like_count) %> <% end %> <% content_for(:title) { "#{@topic_view.page_title}" } %> diff --git a/app/views/topics/show.rss.erb b/app/views/topics/show.rss.erb index e49890e2d02..aa7d08c4a85 100644 --- a/app/views/topics/show.rss.erb +++ b/app/views/topics/show.rss.erb @@ -30,7 +30,7 @@ ]]> <%= post_url %> <%= post.created_at.rfc2822 %> - post-<%= post.topic_id %>-<%= post.post_number %> + <%= Discourse.current_hostname %>-post-<%= post.topic_id %>-<%= post.post_number %> <%= @topic_view.title %> <% end %> diff --git a/app/views/user_notifications/digest.html.erb b/app/views/user_notifications/digest.html.erb index 2245642c4d2..c9be3362614 100644 --- a/app/views/user_notifications/digest.html.erb +++ b/app/views/user_notifications/digest.html.erb @@ -1,7 +1,7 @@
    - + <%- if logo_url.blank? %> <%= SiteSetting.title %> <%- else %> @@ -11,7 +11,7 @@
    - <%= raw(t 'user_notifications.digest.why', site_link: html_site_link, last_seen_at: @last_seen_at) %> + <%= raw(t 'user_notifications.digest.why', site_link: html_site_link(@anchor_color), last_seen_at: @last_seen_at) %> <%- if @featured_topics.present? %>
    @@ -20,7 +20,7 @@ <%- @featured_topics.each_with_index do |t, i| %> @@ -43,7 +43,7 @@ <%- @new_topics.each do |t| %>
    diff --git a/app/views/users/_auto_redirect_home.html.erb b/app/views/users/_auto_redirect_home.html.erb index b5c9a057e9a..7243a2bbca3 100644 --- a/app/views/users/_auto_redirect_home.html.erb +++ b/app/views/users/_auto_redirect_home.html.erb @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/app/views/users/activate_account.html.erb b/app/views/users/activate_account.html.erb index c0c1ab5287c..40b4c1f9064 100644 --- a/app/views/users/activate_account.html.erb +++ b/app/views/users/activate_account.html.erb @@ -10,6 +10,7 @@
    <%- content_for(:no_ember_head) do %> + <%= script "ember_jquery" %> <%= script "vendor" %> <%- end %> diff --git a/app/views/users/authorize_email.html.erb b/app/views/users/authorize_email.html.erb deleted file mode 100644 index 8eef69bc663..00000000000 --- a/app/views/users/authorize_email.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -
    - <%if flash[:error]%> -
    - <%=flash[:error]%> -
    - <%else%> -

    <%= t 'change_email.confirmed' %>

    -
    - <%= t('change_email.please_continue', site_name: SiteSetting.title) %> - <%= render partial: 'auto_redirect_home' %> - <%end%> -
    \ No newline at end of file diff --git a/app/views/users/omniauth_callbacks/complete.html.erb b/app/views/users/omniauth_callbacks/complete.html.erb index 3107268530e..f2fdcfad86f 100644 --- a/app/views/users/omniauth_callbacks/complete.html.erb +++ b/app/views/users/omniauth_callbacks/complete.html.erb @@ -22,8 +22,8 @@

    <%=t "login.close_window" %>

    diff --git a/app/views/users/password_reset.html.erb b/app/views/users/password_reset.html.erb index c1597a5416f..2371150d553 100644 --- a/app/views/users/password_reset.html.erb +++ b/app/views/users/password_reset.html.erb @@ -37,7 +37,7 @@

    - +

    @@ -48,6 +48,10 @@ <%end%>

    +<%- content_for(:no_ember_head) do %> + <%= script "ember_jquery" %> +<%- end %> + diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 8dfa390743e..2616716c053 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -6,9 +6,9 @@ <% content_for :head do %> <% if @restrict_fields %> - <%= crawlable_meta_data(title: @user.username, image: @user.small_avatar_url) %> + <%= raw crawlable_meta_data(title: @user.username, image: @user.small_avatar_url) %> <% else %> - <%= crawlable_meta_data(title: @user.username, description: @user.user_profile.bio_summary, image: @user.small_avatar_url) %> + <%= raw crawlable_meta_data(title: @user.username, description: @user.user_profile.bio_summary, image: @user.small_avatar_url) %> <% end %> <% end %> diff --git a/app/views/users_email/confirm.html.erb b/app/views/users_email/confirm.html.erb new file mode 100644 index 00000000000..f02bb9fbe9d --- /dev/null +++ b/app/views/users_email/confirm.html.erb @@ -0,0 +1,15 @@ +
    + <% if @update_result == :authorizing_new %> +

    <%= t 'change_email.authorizing_old.title' %>

    +
    +

    <%= t 'change_email.authorizing_old.description' %>

    + <% elsif @update_result == :complete %> +

    <%= t 'change_email.confirmed' %>

    +
    + <%= t('change_email.please_continue', site_name: SiteSetting.title) %> + <% else %> +
    + <%=t 'change_email.error' %> +
    + <% end %> +
    diff --git a/bin/docker/boot_dev b/bin/docker/boot_dev new file mode 100755 index 00000000000..0b3ed1eca23 --- /dev/null +++ b/bin/docker/boot_dev @@ -0,0 +1,14 @@ +#!/bin/bash + +pushd `dirname $0` > /dev/null +SCRIPTPATH=`pwd -P` +popd > /dev/null + + +SOURCE_DIR=`(cd $SCRIPTPATH && cd ../../ && pwd)` +DATA_DIR=$SOURCE_DIR/tmp/postgres + +echo $SOURCE_DIR +echo $DATA_DIR + +docker run -d -p 3000:3000 -v $DATA_DIR:/shared/postgres_data -v $SOURCE_DIR:/src --hostname=discourse_dev --name=discourse_dev --restart=always discourse/dev /sbin/boot diff --git a/bin/docker/bundle b/bin/docker/bundle new file mode 100755 index 00000000000..d304ab47123 --- /dev/null +++ b/bin/docker/bundle @@ -0,0 +1,5 @@ +#!/bin/bash + +PARAMS="$@" +CMD="cd /src && HOME=/home/discourse chpst -u discourse:discourse bundle $PARAMS" +docker exec -it discourse_dev /bin/bash -c "$CMD" diff --git a/bin/docker/psql b/bin/docker/psql new file mode 100755 index 00000000000..6336af07b1b --- /dev/null +++ b/bin/docker/psql @@ -0,0 +1,5 @@ +#!/bin/bash + +PARAMS="$@" +CMD="chpst -u postgres psql $PARAMS" +docker exec -it discourse_dev /bin/bash -c "$CMD" diff --git a/bin/docker/rails b/bin/docker/rails new file mode 100755 index 00000000000..afbda658024 --- /dev/null +++ b/bin/docker/rails @@ -0,0 +1,9 @@ +#!/bin/bash + +PARAMS="$@" +if [[ $# = 1 ]] && [[ "$1" =~ "s" ]]; +then + PARAMS="$PARAMS -b 0.0.0.0" +fi +CMD="cd /src && HOME=/home/discourse RAILS_ENV=${RAILS_ENV:=development} chpst -u discourse:discourse rails $PARAMS" +docker exec -it discourse_dev /bin/bash -c "$CMD" diff --git a/bin/docker/rake b/bin/docker/rake new file mode 100755 index 00000000000..2ecac1b25e4 --- /dev/null +++ b/bin/docker/rake @@ -0,0 +1,5 @@ +#!/bin/bash + +PARAMS="$@" +CMD="cd /src && HOME=/home/discourse RAILS_ENV=${RAILS_ENV:=development} chpst -u discourse:discourse rake $PARAMS" +docker exec -it discourse_dev /bin/bash -c "$CMD" diff --git a/bin/docker/reset_db b/bin/docker/reset_db new file mode 100755 index 00000000000..2d1ae28c06a --- /dev/null +++ b/bin/docker/reset_db @@ -0,0 +1,12 @@ +#!/bin/bash + +pushd `dirname $0` > /dev/null +SCRIPTPATH=`pwd -P` +popd > /dev/null + + +SOURCE_DIR=`(cd $SCRIPTPATH && cd ../../ && pwd)` +DATA_DIR=$SOURCE_DIR/tmp/postgres + + +docker run -it -v $DATA_DIR:/shared/postgres_data samsaffron/discourse_dev:1.0.13 /bin/bash -c "rm -fr /shared/postgres_data/*" diff --git a/bin/docker/shutdown_dev b/bin/docker/shutdown_dev new file mode 100755 index 00000000000..557ccfe9dff --- /dev/null +++ b/bin/docker/shutdown_dev @@ -0,0 +1,3 @@ +#!/bin/bash + +docker rm -f discourse_dev diff --git a/config/application.rb b/config/application.rb index 203442efff2..69a4531dd03 100644 --- a/config/application.rb +++ b/config/application.rb @@ -69,7 +69,9 @@ module Discourse path =~ /assets\/images/ && !%w(.js .css).include?(File.extname(filename)) end] - config.assets.precompile += ['vendor.js', 'common.css', 'desktop.css', 'mobile.css', 'admin.js', 'admin.css', 'shiny/shiny.css', 'preload_store.js', 'browser-update.js', 'embed.css', 'break_string.js'] + config.assets.precompile += ['vendor.js', 'common.css', 'desktop.css', 'mobile.css', + 'admin.js', 'admin.css', 'shiny/shiny.css', 'preload_store.js', + 'browser-update.js', 'embed.css', 'break_string.js', 'ember_jquery.js'] # Precompile all defer Dir.glob("#{config.root}/app/assets/javascripts/defer/*.js").each do |file| @@ -122,10 +124,7 @@ module Discourse # see: http://stackoverflow.com/questions/11894180/how-does-one-correctly-add-custom-sql-dml-in-migrations/11894420#11894420 config.active_record.schema_format = :sql - if Rails.version >= "4.2.0" && Rails.version < "5.0.0" - # Opt-into the default behavior in Rails 5 - config.active_record.raise_in_transactional_callbacks = false - end + config.active_record.raise_in_transactional_callbacks = true # per https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet config.pbkdf2_iterations = 64000 @@ -148,6 +147,7 @@ module Discourse require 'discourse_redis' require 'logster/redis_store' + require 'freedom_patches/redis' # Use redis for our cache config.cache_store = DiscourseRedis.new_redis_store $redis = DiscourseRedis.new diff --git a/config/database.yml b/config/database.yml index 10cd2890999..fb6d923aea2 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,4 +1,5 @@ development: + prepared_statements: false adapter: postgresql database: discourse_development min_messages: warning @@ -25,6 +26,7 @@ test: # profile db is used for benchmarking using the script/bench.rb script profile: + prepared_statements: false adapter: postgresql database: discourse_profile min_messages: warning diff --git a/config/discourse_defaults.conf b/config/discourse_defaults.conf index 3b2ae347d9d..ee87099158d 100644 --- a/config/discourse_defaults.conf +++ b/config/discourse_defaults.conf @@ -39,9 +39,15 @@ db_username = discourse # password used to access the db db_password = -# allow usage of prepared statements, must be disabled for -# pgpool transaction pooling -db_prepared_statements = true +# Disallow prepared statements +# see: https://github.com/rails/rails/issues/21992 +db_prepared_statements = false + +# host address for db replica server +db_replica_host = + +# port running replica db server, defaults to 5432 if not set +db_replica_port = # hostname running the forum hostname = "www.example.com" @@ -89,6 +95,12 @@ redis_host = localhost # redis server port redis_port = 6379 +# redis slave server address +redis_slave_host = + +# redis slave server port +redis_slave_port = 6379 + # redis database redis_db = 0 @@ -123,8 +135,15 @@ new_version_emails = true connection_reaper_age = 30 # run reap check every 30 seconds connection_reaper_interval = 30 +# also reap any connections older than this +connection_reaper_max_age = 600 # set to relative URL (for subdirectory hosting) # IMPORTANT: path must not include a trailing / # EG: /forum relative_url_root = + +# increasing this number will increase redis memory use +# this ensures backlog (ability of channels to catch up are capped) +# message bus default cap is 1000, we are winding it down to 100 +message_bus_max_backlog_size = 100 diff --git a/config/environments/production.rb b/config/environments/production.rb index 013e37f597f..c637fb67b1d 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -10,7 +10,7 @@ Discourse::Application.configure do config.action_controller.perform_caching = true # Disable Rails's static asset server (Apache or nginx will already do this) - config.serve_static_assets = GlobalSetting.serve_static_assets + config.serve_static_files = GlobalSetting.serve_static_assets config.assets.js_compressor = :uglifier diff --git a/config/environments/profile.rb b/config/environments/profile.rb index 1784a23528b..3f672a9c472 100644 --- a/config/environments/profile.rb +++ b/config/environments/profile.rb @@ -13,7 +13,7 @@ Discourse::Application.configure do config.action_controller.perform_caching = true # in profile mode we serve static assets - config.serve_static_assets = true + config.serve_static_files = true # Compress JavaScripts and CSS config.assets.compress = true diff --git a/config/environments/test.rb b/config/environments/test.rb index b885d72ab32..16cab97ce13 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -8,7 +8,7 @@ Discourse::Application.configure do config.cache_classes = true # Configure static asset server for tests with Cache-Control for performance - config.serve_static_assets = true + config.serve_static_files = true # Show full error reports and disable caching config.consider_all_requests_local = true diff --git a/config/initializers/00-rails-master-polyfills.rb b/config/initializers/000-rails-master-polyfills.rb similarity index 100% rename from config/initializers/00-rails-master-polyfills.rb rename to config/initializers/000-rails-master-polyfills.rb diff --git a/config/initializers/01-redis.rb b/config/initializers/001-redis.rb similarity index 100% rename from config/initializers/01-redis.rb rename to config/initializers/001-redis.rb diff --git a/config/initializers/02-freedom_patches.rb b/config/initializers/002-freedom_patches.rb similarity index 100% rename from config/initializers/02-freedom_patches.rb rename to config/initializers/002-freedom_patches.rb diff --git a/config/initializers/03-sql_builder.rb b/config/initializers/003-sql_builder.rb similarity index 100% rename from config/initializers/03-sql_builder.rb rename to config/initializers/003-sql_builder.rb diff --git a/config/initializers/004-message_bus.rb b/config/initializers/004-message_bus.rb new file mode 100644 index 00000000000..41d5386c5f7 --- /dev/null +++ b/config/initializers/004-message_bus.rb @@ -0,0 +1,84 @@ +MessageBus.site_id_lookup do |env=nil| + if env + setup_message_bus_env(env) + env["__mb"][:site_id] + else + RailsMultisite::ConnectionManagement.current_db + end +end + +def setup_message_bus_env(env) + return if env["__mb"] + + host = RailsMultisite::ConnectionManagement.host(env) + RailsMultisite::ConnectionManagement.with_hostname(host) do + user = CurrentUser.lookup_from_env(env) + user_id = user && user.id + is_admin = !!(user && user.admin?) + group_ids = if is_admin + # special rule, admin is allowed access to all groups + Group.pluck(:id) + elsif user + user.groups.pluck('groups.id') + end + + hash = { + extra_headers: + { + "Access-Control-Allow-Origin" => Discourse.base_url_no_prefix, + "Access-Control-Allow-Methods" => "GET, POST", + "Access-Control-Allow-Headers" => "X-SILENCE-LOGGER, X-Shared-Session-Key" + }, + user_id: user_id, + group_ids: group_ids, + is_admin: is_admin, + site_id: RailsMultisite::ConnectionManagement.current_db + + } + env["__mb"] = hash + end + + nil +end + +MessageBus.extra_response_headers_lookup do |env| + setup_message_bus_env(env) + env["__mb"][:extra_headers] +end + +MessageBus.user_id_lookup do |env| + setup_message_bus_env(env) + env["__mb"][:user_id] +end + +MessageBus.group_ids_lookup do |env| + setup_message_bus_env(env) + env["__mb"][:group_ids] +end + +MessageBus.is_admin_lookup do |env| + setup_message_bus_env(env) + env["__mb"][:is_admin] +end + +MessageBus.on_connect do |site_id| + RailsMultisite::ConnectionManagement.establish_connection(db: site_id) +end + +MessageBus.on_disconnect do |site_id| + ActiveRecord::Base.connection_handler.clear_active_connections! +end + +# Point at our redis +MessageBus.redis_config = GlobalSetting.redis_config +MessageBus.reliable_pub_sub.max_backlog_size = GlobalSetting.message_bus_max_backlog_size + +MessageBus.long_polling_enabled = SiteSetting.enable_long_polling +MessageBus.long_polling_interval = SiteSetting.long_polling_interval +MessageBus.cache_assets = !Rails.env.development? +MessageBus.enable_diagnostics + +if Rails.env == "test" || $0 =~ /rake$/ + # disable keepalive in testing + MessageBus.keepalive_interval = -1 +end diff --git a/config/initializers/05-site_settings.rb b/config/initializers/005-site_settings.rb similarity index 100% rename from config/initializers/05-site_settings.rb rename to config/initializers/005-site_settings.rb diff --git a/config/initializers/06-ensure_login_hint.rb b/config/initializers/006-ensure_login_hint.rb similarity index 100% rename from config/initializers/06-ensure_login_hint.rb rename to config/initializers/006-ensure_login_hint.rb diff --git a/config/initializers/06-mini_profiler.rb b/config/initializers/006-mini_profiler.rb similarity index 93% rename from config/initializers/06-mini_profiler.rb rename to config/initializers/006-mini_profiler.rb index 3726cb173b9..9ef0c9ec925 100644 --- a/config/initializers/06-mini_profiler.rb +++ b/config/initializers/006-mini_profiler.rb @@ -27,6 +27,7 @@ if defined?(Rack::MiniProfiler) /assets/, /\/user_avatar\//, /\/letter_avatar\//, + /\/letter_avatar_proxy\//, /\/highlight-js\//, /qunit/, /srv\/status/, @@ -41,11 +42,12 @@ if defined?(Rack::MiniProfiler) /^\/favicon\/proxied/ ] - # For our app, let's just show mini profiler always, polling is chatty so nuke that + # we DO NOT WANT mini-profiler loading on anything but real desktops and laptops + # so let's rule out all handheld, tablet, and mobile devices Rack::MiniProfiler.config.pre_authorize_cb = lambda do |env| path = env['PATH_INFO'] - (env['HTTP_USER_AGENT'] !~ /iPad|iPhone|Nexus 7|Android/) && + (env['HTTP_USER_AGENT'] !~ /iPad|iPhone|Android/) && !skip.any?{|re| re =~ path} end diff --git a/config/initializers/08-rack-cors.rb b/config/initializers/008-rack-cors.rb similarity index 100% rename from config/initializers/08-rack-cors.rb rename to config/initializers/008-rack-cors.rb diff --git a/config/initializers/09-omniauth.rb b/config/initializers/009-omniauth.rb similarity index 75% rename from config/initializers/09-omniauth.rb rename to config/initializers/009-omniauth.rb index 1632ba0250c..90feb34426b 100644 --- a/config/initializers/09-omniauth.rb +++ b/config/initializers/009-omniauth.rb @@ -3,9 +3,12 @@ require "openid_redis_store" # if you need to test this and are having ssl issues see: # http://stackoverflow.com/questions/6756460/openssl-error-using-omniauth-specified-ssl-path-but-didnt-work +# OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE if Rails.env.development? Rails.application.config.middleware.use OmniAuth::Builder do Discourse.authenticators.each do |authenticator| authenticator.register_middleware(self) end end + +OmniAuth.config.logger = Rails.logger diff --git a/config/initializers/10-discourse_iife.rb b/config/initializers/010-discourse_iife.rb similarity index 100% rename from config/initializers/10-discourse_iife.rb rename to config/initializers/010-discourse_iife.rb diff --git a/config/initializers/11-rack-protection.rb b/config/initializers/011-rack-protection.rb similarity index 100% rename from config/initializers/11-rack-protection.rb rename to config/initializers/011-rack-protection.rb diff --git a/config/initializers/04-message_bus.rb b/config/initializers/04-message_bus.rb deleted file mode 100644 index 00bf806d410..00000000000 --- a/config/initializers/04-message_bus.rb +++ /dev/null @@ -1,57 +0,0 @@ -MessageBus.site_id_lookup do - RailsMultisite::ConnectionManagement.current_db -end - -MessageBus.extra_response_headers_lookup do |env| - { - "Access-Control-Allow-Origin" => Discourse.base_url_no_prefix, - "Access-Control-Allow-Methods" => "GET, POST", - "Access-Control-Allow-Headers" => "X-SILENCE-LOGGER, X-Shared-Session-Key" - } -end - -MessageBus.user_id_lookup do |env| - user = CurrentUser.lookup_from_env(env) - user.id if user -end - -MessageBus.group_ids_lookup do |env| - user = CurrentUser.lookup_from_env(env) - if user && user.admin? - # special rule, admin is allowed access to all groups - Group.pluck(:id) - elsif user - user.groups.pluck('groups.id') - end -end - -MessageBus.on_connect do |site_id| - RailsMultisite::ConnectionManagement.establish_connection(db: site_id) -end - -MessageBus.on_disconnect do |site_id| - ActiveRecord::Base.connection_handler.clear_active_connections! -end - -# Point at our redis -MessageBus.redis_config = GlobalSetting.redis_config - -MessageBus.long_polling_enabled = SiteSetting.enable_long_polling -MessageBus.long_polling_interval = SiteSetting.long_polling_interval - -MessageBus.is_admin_lookup do |env| - user = CurrentUser.lookup_from_env(env) - if user && user.admin - true - else - false - end -end - -MessageBus.cache_assets = !Rails.env.development? -MessageBus.enable_diagnostics - -if Rails.env == "test" - # disable keepalive in testing - MessageBus.keepalive_interval = -1 -end diff --git a/config/initializers/50-force_https.rb b/config/initializers/050-force_https.rb similarity index 63% rename from config/initializers/50-force_https.rb rename to config/initializers/050-force_https.rb index 126c8b9d448..0e91da8b24c 100644 --- a/config/initializers/50-force_https.rb +++ b/config/initializers/050-force_https.rb @@ -12,6 +12,3 @@ class Discourse::ForceHttpsMiddleware end -# this code plays up, skip for now -#Rails.configuration.middleware.insert_before MessageBus::Rack::Middleware, Discourse::ForceHttpsMiddleware - diff --git a/config/initializers/99-anon-cache.rb b/config/initializers/099-anon-cache.rb similarity index 100% rename from config/initializers/99-anon-cache.rb rename to config/initializers/099-anon-cache.rb diff --git a/config/initializers/99-drain_pool.rb b/config/initializers/099-drain_pool.rb similarity index 100% rename from config/initializers/99-drain_pool.rb rename to config/initializers/099-drain_pool.rb diff --git a/config/initializers/99-unicorn.rb b/config/initializers/099-unicorn.rb similarity index 100% rename from config/initializers/99-unicorn.rb rename to config/initializers/099-unicorn.rb diff --git a/config/initializers/100-i18n.rb b/config/initializers/100-i18n.rb new file mode 100644 index 00000000000..37a0dd050cc --- /dev/null +++ b/config/initializers/100-i18n.rb @@ -0,0 +1,10 @@ +# order: after 02-freedom_patches.rb + +require 'i18n/backend/discourse_i18n' +I18n.backend = I18n::Backend::DiscourseI18n.new +I18n.config.missing_interpolation_argument_handler = proc { throw(:exception) } +I18n.init_accelerator! + +unless Rails.env.test? + MessageBus.subscribe("/i18n-flush") { I18n.reload! } +end diff --git a/config/initializers/logster.rb b/config/initializers/100-logster.rb similarity index 65% rename from config/initializers/logster.rb rename to config/initializers/100-logster.rb index 2daf7200fe0..e237d6aa75e 100644 --- a/config/initializers/logster.rb +++ b/config/initializers/100-logster.rb @@ -6,6 +6,7 @@ if Rails.env.production? /^PG::Error: ERROR:\s+duplicate key/, /^ActionController::UnknownFormat/, + /^ActionController::UnknownHttpMethod/, /^AbstractController::ActionNotFound/, @@ -55,3 +56,27 @@ Logster.config.current_context = lambda{|env,&blk| Logster.config.subdirectory = "#{GlobalSetting.relative_url_root}/logs" Logster.config.application_version = Discourse.git_version + +store = Logster.store +redis = Logster.store.redis +store.redis_prefix = Proc.new { redis.namespace } +store.redis_raw_connection = redis.without_namespace +severities = [Logger::WARN, Logger::ERROR, Logger::FATAL, Logger::UNKNOWN] + +RailsMultisite::ConnectionManagement.each_connection do + error_rate_per_minute = SiteSetting.alert_admins_if_errors_per_minute rescue 0 + + if (error_rate_per_minute || 0) > 0 + store.register_rate_limit_per_minute(severities, error_rate_per_minute) do |rate| + MessageBus.publish("/logs_error_rate_exceeded", { rate: rate, duration: 'minute' }) + end + end + + error_rate_per_hour = SiteSetting.alert_admins_if_errors_per_hour rescue 0 + + if (error_rate_per_hour || 0) > 0 + store.register_rate_limit_per_hour(severities, error_rate_per_hour) do |rate| + MessageBus.publish("/logs_error_rate_exceeded", { rate: rate, duration: 'hour' }) + end + end +end diff --git a/config/initializers/oj.rb b/config/initializers/100-oj.rb similarity index 100% rename from config/initializers/oj.rb rename to config/initializers/100-oj.rb diff --git a/config/initializers/onebox_options.rb b/config/initializers/100-onebox_options.rb similarity index 100% rename from config/initializers/onebox_options.rb rename to config/initializers/100-onebox_options.rb diff --git a/config/initializers/quiet_logger.rb b/config/initializers/100-quiet_logger.rb similarity index 100% rename from config/initializers/quiet_logger.rb rename to config/initializers/100-quiet_logger.rb diff --git a/config/initializers/rails3_ar_after_commit_tests.rb b/config/initializers/100-rails3_ar_after_commit_tests.rb similarity index 100% rename from config/initializers/rails3_ar_after_commit_tests.rb rename to config/initializers/100-rails3_ar_after_commit_tests.rb diff --git a/config/initializers/secret_token.rb b/config/initializers/100-secret_token.rb similarity index 100% rename from config/initializers/secret_token.rb rename to config/initializers/100-secret_token.rb diff --git a/config/initializers/session_store.rb b/config/initializers/100-session_store.rb similarity index 62% rename from config/initializers/session_store.rb rename to config/initializers/100-session_store.rb index 2a14105c920..e89e764e869 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/100-session_store.rb @@ -1,6 +1,10 @@ # Be sure to restart your server when you modify this file. -Discourse::Application.config.session_store :cookie_store, key: '_forum_session' +Discourse::Application.config.session_store( + :cookie_store, + key: '_forum_session', + path: (Rails.application.config.relative_url_root.nil?) ? '/' : Rails.application.config.relative_url_root +) # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information diff --git a/config/initializers/sidekiq.rb b/config/initializers/100-sidekiq.rb similarity index 99% rename from config/initializers/sidekiq.rb rename to config/initializers/100-sidekiq.rb index bfac8028f19..3940cdd4c8e 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/100-sidekiq.rb @@ -74,5 +74,3 @@ end Sidekiq.error_handlers.clear Sidekiq.error_handlers << SidekiqLogsterReporter.new - - diff --git a/config/initializers/silence_logger.rb b/config/initializers/100-silence_logger.rb similarity index 100% rename from config/initializers/silence_logger.rb rename to config/initializers/100-silence_logger.rb diff --git a/config/initializers/sprockets.rb b/config/initializers/100-sprockets.rb similarity index 100% rename from config/initializers/sprockets.rb rename to config/initializers/100-sprockets.rb diff --git a/config/initializers/strong_parameters.rb b/config/initializers/100-strong_parameters.rb similarity index 100% rename from config/initializers/strong_parameters.rb rename to config/initializers/100-strong_parameters.rb diff --git a/config/initializers/verify_config.rb b/config/initializers/100-verify_config.rb similarity index 100% rename from config/initializers/verify_config.rb rename to config/initializers/100-verify_config.rb diff --git a/config/initializers/watch_for_restart.rb b/config/initializers/100-watch_for_restart.rb similarity index 100% rename from config/initializers/watch_for_restart.rb rename to config/initializers/100-watch_for_restart.rb diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/100-wrap_parameters.rb similarity index 100% rename from config/initializers/wrap_parameters.rb rename to config/initializers/100-wrap_parameters.rb diff --git a/config/initializers/200-message_bus_request_tracker.rb b/config/initializers/200-message_bus_request_tracker.rb new file mode 100644 index 00000000000..203c8d2711d --- /dev/null +++ b/config/initializers/200-message_bus_request_tracker.rb @@ -0,0 +1,13 @@ +# we want MesageBus in the absolute front +# this is important cause the vast majority of web requests go to it +# this allows us to avoid full middleware crawls each time +Rails.configuration.middleware.delete MessageBus::Rack::Middleware +Rails.configuration.middleware.unshift MessageBus::Rack::Middleware + +# no reason to track this in development, that is 300+ redis calls saved per +# page view (we serve all assets out of thin in development) +if Rails.env != 'development' || ENV['TRACK_REQUESTS'] + require 'middleware/request_tracker' + Rails.configuration.middleware.unshift Middleware::RequestTracker +end + diff --git a/config/initializers/99-request_tracker.rb b/config/initializers/99-request_tracker.rb deleted file mode 100644 index 5ba1330e1cd..00000000000 --- a/config/initializers/99-request_tracker.rb +++ /dev/null @@ -1,6 +0,0 @@ -# no reason to track this in development, that is 300+ redis calls saved per -# page view (we serve all assets out of thin in development) -if Rails.env != 'development' || ENV['TRACK_REQUESTS'] - require 'middleware/request_tracker' - Rails.configuration.middleware.unshift Middleware::RequestTracker -end diff --git a/config/initializers/i18n.rb b/config/initializers/i18n.rb deleted file mode 100644 index 43b7299572e..00000000000 --- a/config/initializers/i18n.rb +++ /dev/null @@ -1,37 +0,0 @@ -# order: after 02-freedom_patches.rb - -# Include pluralization module -require 'i18n/backend/pluralization' -I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization) - -# Include fallbacks module -require 'i18n/backend/fallbacks' -I18n.backend.class.send(:include, I18n::Backend::Fallbacks) - -# Configure custom fallback order -class FallbackLocaleList < Hash - def [](locale) - # user locale, site locale, english - # TODO - this can be extended to be per-language for a better user experience - # (e.g. fallback zh_TW to zh_CN / vice versa) - [locale, SiteSetting.default_locale.to_sym, :en].uniq.compact - end - - def ensure_loaded! - self[I18n.locale].each { |l| I18n.ensure_loaded! l } - end -end - -class NoFallbackLocaleList < FallbackLocaleList - def [](locale) - [locale] - end -end - - -if Rails.env.development? - I18n.fallbacks = NoFallbackLocaleList.new -else - I18n.fallbacks = FallbackLocaleList.new - I18n.config.missing_interpolation_argument_handler = proc { throw(:exception) } -end diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb deleted file mode 100644 index 9e8b0131f8f..00000000000 --- a/config/initializers/inflections.rb +++ /dev/null @@ -1,10 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new inflection rules using the following format -# (all these examples are active by default): -# ActiveSupport::Inflector.inflections do |inflect| -# inflect.plural /^(ox)$/i, '\1en' -# inflect.singular /^(ox)en/i, '\1' -# inflect.irregular 'person', 'people' -# inflect.uncountable %w( fish sheep ) -# end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb deleted file mode 100644 index 72aca7e441e..00000000000 --- a/config/initializers/mime_types.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new mime types for use in respond_to blocks: -# Mime::Type.register "text/richtext", :rtf -# Mime::Type.register_alias "text/html", :iphone diff --git a/config/locales/client.ar.yml b/config/locales/client.ar.yml index 63764408b9c..3ba96d67ad0 100644 --- a/config/locales/client.ar.yml +++ b/config/locales/client.ar.yml @@ -22,197 +22,214 @@ ar: few: بايت many: بايت other: بايت - gb: جيجا + gb: جيجا بايت kb: كيلو بايت - mb: ميجا - tb: تيرا + mb: ميجا بايت + tb: تيرا بايت short: - thousands: "ألف{{number}}" - millions: "مليون{{number}}" + thousands: "{{number}} ألف" + millions: "{{number}} مليون" dates: time: "h:mm a" - long_no_year: "MMM D h:mm a" - long_no_year_no_time: "MMM D" - full_no_year_no_time: "MMMM Do" - long_with_year: "MMM D, YYYY h:mm a" - long_with_year_no_time: "MMM D, YYYY" - full_with_year_no_time: "MMM D, YYYY" - long_date_with_year: "MMM D, 'YY LT" - long_date_without_year: "MMM D, LT" - long_date_with_year_without_time: "MMM D, 'YY" - long_date_without_year_with_linebreak: "MMM D
    LT" - long_date_with_year_with_linebreak: "MMM D, 'YY
    LT" + long_no_year: "D MMM h:mm a" + long_no_year_no_time: "D MMM" + full_no_year_no_time: "Do MMMM" + long_with_year: "D MMM، YYYY h:mm a" + long_with_year_no_time: "D MMM، YYYY" + full_with_year_no_time: "D MMM، YYYY" + long_date_with_year: "D MMM، YYYY LT" + long_date_without_year: "D MMM، LT" + long_date_with_year_without_time: "D MMM، YYYY" + long_date_without_year_with_linebreak: "D MMM
    LT" + long_date_with_year_with_linebreak: "D MMM، YYYY
    LT" tiny: - half_a_minute: "< 1m" + half_a_minute: "< 1دق" less_than_x_seconds: - zero: "> %{count}ث" - one: "> ثانية" - two: "> ثانيتان" - few: "> %{count}ث" - many: "> %{count}ث" - other: "%{count} ثانية" + zero: "< %{count}ث" + one: "< %{count}ث" + two: "< %{count}ث" + few: "< %{count}ث" + many: "< %{count}ث" + other: "< %{count}ث" x_seconds: - zero: "%{count} ثانية" - one: "%{count} ثانية" - two: "%{count} ثانية" - few: "%{count} ثانية" - many: "%{count} ثانية" - other: "%{count} ثانية" + zero: "%{count}ث" + one: "%{count}ث" + two: "%{count}ث" + few: "%{count}ث" + many: "%{count}ث" + other: "%{count}ث" less_than_x_minutes: - zero: "< 0 د" - one: "< 1 د" - two: "< 2 د" - few: "< %{count} د" - many: "< %{count} د" - other: "< %{count} د" + zero: "< %{count}دق" + one: "< %{count}دق" + two: "< %{count}دق" + few: "< %{count}دق" + many: "< %{count}دق" + other: "< %{count}دق" x_minutes: - zero: "0 د" - one: "1 د" - two: "2 د" - few: "%{count} د" - many: "%{count} د" - other: "%{count} د" + zero: "%{count}دق" + one: "%{count}دق" + two: "%{count}دق" + few: "%{count}دق" + many: "%{count}دق" + other: "%{count}دق" about_x_hours: - zero: "0 س" - one: "1 س" - two: "2 س" - few: "%{count} س" - many: "%{count} س" - other: "%{count} س" + zero: "%{count}سا" + one: "%{count}سا" + two: "%{count}سا" + few: "%{count}سا" + many: "%{count}سا" + other: "%{count}سا" x_days: - zero: "0 ي" - one: "1 ي" - two: "2 ي" - few: "%{count} ي" - many: "%{count} ي" - other: "%{count} ي" + zero: "%{count}ي" + one: "%{count}ي" + two: "%{count}ي" + few: "%{count}ي" + many: "%{count}ي" + other: "%{count}ي" about_x_years: - zero: "0 ع" - one: "1 ع" - two: "2 ع" - few: "%{count} ع" - many: "%{count} ع" - other: "%{count} ع" + zero: "%{count}س" + one: "%{count}س" + two: "%{count}س" + few: "%{count}س" + many: "%{count}س" + other: "%{count}س" over_x_years: - zero: "> 0 ع" - one: "> 1 ع" - two: "> 2 ع" - few: "> %{count} ع" - many: "> %{count} ع" - other: "> %{count} ع" + zero: "> %{count}س" + one: "> %{count}س" + two: "> %{count}س" + few: "> %{count}س" + many: "> %{count}س" + other: "> %{count}س" almost_x_years: - zero: "0 ع" - one: "1 ع" - two: "2 ع" - few: "%{count} ع" - many: "%{count} ع" - other: "%{count} ع" - date_month: "MMM D" - date_year: "MMM 'YY" + zero: "%{count}س" + one: "%{count}س" + two: "%{count}س" + few: "%{count}س" + many: "%{count}س" + other: "%{count}س" + date_month: "D MMM" + date_year: "MMM YYYY" medium: x_minutes: - zero: "0 دقيقة" + zero: "أقل من دقيقة" one: "دقيقة واحدة" two: "دقيقتان" few: "%{count} دقائق" many: "%{count} دقيقة" other: "%{count} دقيقة" x_hours: - zero: "0 ساعة" + zero: "أقل من ساعة" one: "ساعة واحدة" two: "ساعتان" few: "%{count} ساعات" many: "%{count} ساعة" - other: "%{count} ساعات" + other: "%{count} ساعة" x_days: - zero: "0 يوم" + zero: "أقل من يوم" one: "يوم واحد" two: "يومان" few: "%{count} أيام" - many: "%{count} يومًا" - other: "%{count} أيام" - date_year: "MMM D, 'YY" + many: "%{count} يوما" + other: "%{count} يوم" + date_year: "D MMM، YYYY" medium_with_ago: x_minutes: - zero: "منذ 0 دقيقة" - one: "منذ دقيقة واحدة" - two: "منذ دقيقتين" - few: "منذ %{count} دقائق" - many: "منذ %{count} دقيقة" - other: "منذ %{count} دقيقة" + zero: "قبل أقل من دقيقة" + one: "قبل دقيقة واحدة" + two: "قبل دقيقتين" + few: "قبل %{count} دقائق" + many: "قبل %{count} دقيقة" + other: "قبل %{count} دقيقة" x_hours: - zero: "منذ 0 ساعة" - one: "منذ ساعة واحدة" - two: "منذ ساعتين" - few: "منذ %{count} ساعات" - many: "منذ %{count} ساعة" - other: "منذ %{count} ساعة" + zero: "قبل أقل من ساعة" + one: "قبل ساعة واحدة" + two: "قبل ساعتين" + few: "قبل %{count} ساعات" + many: "قبل %{count} ساعة" + other: "قبل %{count} ساعة" x_days: - zero: "%{count} يوم مضى" - one: "%{count} يوم مضى" - two: "%{count} يوم مضى" - few: "%{count} يوم مضى" - many: "%{count} يوم مضى" - other: "%{count} يوم مضى" + zero: "قبل أقل من يوم" + one: "قبل يوم واحد" + two: "قبل يومين" + few: "قبل %{count} أيام" + many: "قبل %{count} يوما" + other: "قبل %{count} يوما" later: x_days: - zero: "%{count} يوم مضى" - one: "1 يوم مضى" - two: "يومان مضى {count}%" - few: "أيام مضت {count}%" - many: "أيام مضت {count}%" - other: "أيام مضت {count}%" + zero: "بعد أقل من يوم" + one: "بعد يوم واحد" + two: "بعد يومين" + few: "بعد %{count} أيام" + many: "بعد %{count} يوما" + other: "بعد %{count} يوم" x_months: - zero: "بعد أقل من شهر." - one: "بعد شهر." - two: "بعد شهرين." + zero: "بعد أقل من شهر" + one: "بعد شهر واحد" + two: "بعد شهرين" few: "بعد %{count} أشهر" - many: "بعد %{count} شهر." - other: "بعد %{count} شهر." + many: "بعد %{count} شهرا" + other: "بعد %{count} شهر" x_years: - zero: "بعد أقل من سنة." - one: "بعد سنة واحدة." - two: "بعد سنتين." - few: "بعد %{count} سنوات." - many: "بعد %{count} سنوات." - other: "بعد %{count} سنة." + zero: "بعد أقل من سنة" + one: "بعد سنة واحدة" + two: "بعد سنتين" + few: "بعد %{count} سنوات" + many: "بعد %{count} سنة" + other: "بعد %{count} سنة" + previous_month: 'الشهر السابق' + next_month: 'الشهر التالي' share: - topic: 'ضع رابطاً في هذا الموضوع.' + topic: 'شارك رابط هذا الموضوع' post: 'الموضوع رقم %{postNumber}' - close: 'اغلق' - twitter: 'شارك هذا الرابط عن طريق تويتر' - facebook: 'شارك هذا الرابط عن طريق فيس بوك' - google+: 'شارك هذا الرابط عن طريق جوجل+' - email: 'شارك هذا الرابط عن طريق البريد الالكتروني' + close: 'أغلق' + twitter: 'شارك هذا الرابط في تويتر' + facebook: 'شارك هذا الرابط في فيس بوك' + google+: 'شارك هذا الرابط في جوجل+' + email: 'شارك هذا الرابط في بريد إلكتروني' action_codes: - split_topic: "تقسيم هذا الموضوع %{when}" + split_topic: "قسم هذا الموضوع في %{when}" + invited_user: "دعوة %{who} %{when}" + removed_user: "ازالة %{who} %{when}" autoclosed: - enabled: 'أغلق %{when}' - disabled: 'مفتوح %{when}' + enabled: 'أُغلق في %{when}' + disabled: 'فُتح في %{when}' closed: - enabled: 'مغلق %{when}' - disabled: 'مفتوح %{when}' + enabled: 'أغلقه في %{when}' + disabled: 'فتحه في %{when}' archived: - enabled: 'مؤرشف %{when}' - disabled: 'غير مؤرشف %{when}' + enabled: 'أرشفه في %{when}' + disabled: 'أزال أرشفته في %{when}' pinned: - enabled: 'مثبت %{when}' - disabled: 'غير مثبت %{when}' + enabled: 'ثبّته في %{when}' + disabled: 'أزال تثبيته في %{when}' pinned_globally: - enabled: 'مثبت عالمياً %{when}' - disabled: 'غير مثبت %{when}' + enabled: 'ثبّته عموميا في %{when}' + disabled: 'أزال تثبيته في %{when}' visible: enabled: 'مدرج %{when}' disabled: 'غير مدرج %{when}' topic_admin_menu: "عمليات المدير" - emails_are_disabled: "جميع الرسائل الالكترونية تم تعطيلها من قبل المدير , لن يتم ارسال اي بريد الكتروني " - edit: 'عدّل العنوان و التصنيف على هذا الموضوع' - not_implemented: "لم يتم تنفيذ هذه الميزة حتى الآن، نعتذر!" + emails_are_disabled: "جميع الرسائل الإلكترونية المرسلة عطلها المدير , لن يتم إرسال إشعار من أي نوع لبريدك الإلكتروني ." + s3: + regions: + us_east_1: "الولايات المتحدة الشرقيه ( ولايه فيرجينيا )" + us_west_1: "الولايات المتحدة الغربية ( كاليفورنيا )" + us_west_2: "الولايات المتحدة الغربية ( ولاية أوريغون )" + us_gov_west_1: "إستضافة أمازون الحسابية الحكومية (الولايات المتحدة الأمريكية)" + eu_west_1: "الاتحاد الأوروبي ( أيرلندا )" + eu_central_1: "الاتحاد الأوروبي ( فرانكفورت )" + ap_southeast_1: "آسيا والمحيط الهادئ ( سنغافورة )" + ap_southeast_2: "آسيا والمحيط الهادئ ( سيدني )" + ap_northeast_1: "آسيا والمحيط الهادئ ( طوكيو )" + ap_northeast_2: "آسيا والمحيط الهادئ ( سيول )" + sa_east_1: "أمريكا الجنوبية ( ساو باولو )" + edit: 'عدّل عنوان هذا الموضوع وفئته' + not_implemented: "لم تُنجز هذه الميزة بعد، آسفون!" no_value: "لا" yes_value: "نعم" - generic_error: "نعتذر، حدث خطأ." - generic_error_with_reason: "حدث خطأ : %{error}" - sign_up: "إشترك" + generic_error: "آسفون، حدث خطأ ما." + generic_error_with_reason: "حدث خطأ ما: %{error}" + sign_up: "سجّل معنا" log_in: "تسجيل الدخول " age: "العمر" joined: "إنضم" @@ -241,12 +258,14 @@ ar: read_more: 'اقرأ المزيد' more: "المزيد" less: "أقل" - never: "ابداً" - daily: "يومي" - weekly: "اسبوعي" - every_two_weeks: "كل اسبوعين" + never: "مطلقا" + every_30_minutes: "بعد 30 دقيقه" + every_hour: "بعد ساعه" + daily: "يوميا" + weekly: "أسبوعيا" + every_two_weeks: "كل أسبوعين" every_three_days: "كل ثلاثة أيام" - max_of_count: "اقصى {{count}}" + max_of_count: "أقصى عدد هو {{count}}" alternation: "أو" character_count: zero: "0 حرف" @@ -257,6 +276,7 @@ ar: other: "{{count}} حرف" suggested_topics: title: "مواضيع مقترحة" + pm_title: "رسائلة مقترحة " about: simple_title: "نبذة" title: "عن %{title}" @@ -264,82 +284,82 @@ ar: our_admins: "مدراؤنا" our_moderators: "مشرفونا" stat: - all_time: "دائما " + all_time: "يوم التأسيس" last_7_days: "آخر 7 أيام " - last_30_days: "آخر 30 يوم" - like_count: "اعجابات" - topic_count: "مواضيع" - post_count: "مشاركات" - user_count: "مستخدمون جدد" - active_user_count: "مستخدمون نشطون" + last_30_days: "آخر 30 يوما" + like_count: "الإعجابات" + topic_count: "المواضيع" + post_count: "المنشورات" + user_count: "المستخدمون الجدد" + active_user_count: "المستخدمون النشطون" contact: "اتصل بنا" - contact_info: "في حالة حدوث أي مشكلة حرجة أو مسألة عاجلة تؤثر على هذا الموقع، يرجى الاتصال بنا على %{contact_email}." + contact_info: "في حال حدوث مشكلة حرجة أو أمر عاجل يؤثّر على الموقع، من فضلك راسلنا على %{contact_info}." bookmarked: - title: "المفضلة" - clear_bookmarks: "حذف المفضله" + title: "إلى المفضّلة" + clear_bookmarks: "أزل من المفضّلة" help: - bookmark: "انقر هنا لإضافة أول رد في هذا الموضوع الى المفضلة" - unbookmark: "أنقر هنا لحذف كل المفضلة في هذا الموضوع" + bookmark: "انقر لإضافة أول منشور في هذا الموضوع إلى المفضّلة" + unbookmark: "انقر لإزالة كل المفضّلات في هذا الموضوع" bookmarks: - not_logged_in: "نعتذر يجب ان تكون متصلا لكي تقوم بإضافة هدا الموضوع للمفضلة" - created: "لقد نجحت في إضافة الموضوع للمفضلة" - not_bookmarked: "لقد قمت بقراءة هذه المشاركة مسبقاً. اضغط هنا لحفظها." - last_read: "هذه آخر مشاركة تمت قرائتها. اضغط هنا لحفظها." - remove: "المفضلة" - confirm_clear: "هل تود فعلا إزالة كل علامات التفضيل من هذا الموضوع؟" + not_logged_in: "آسفون، عليك تسجيل الدخول لتفضيل المنشورات" + created: "لقد أضفت هذا المنشور إلى المفضّلة" + not_bookmarked: "لقد قرأت هذا المنشور، انقر لإضافته إلى المفضّلة" + last_read: "هذا آخر منشور قرأته، انقر لإضافته إلى المفضّلة" + remove: "أزل من المفضّلة" + confirm_clear: "أتريد حقا إزالة كل ما أضفته إلى المفضّلة في هذا الموضوع؟" topic_count_latest: - zero: "0 مواضيع جديدة أو محدّثة" - one: "موضوع واحد جديد أو محدّث" - two: "موضوعان جديدان أو محدّثان" - few: "{{count}} مواضيع جديدة أو محدّثة" - many: "{{count}} موضوعًا جديدا أو محدّثا" - other: "{{count}} موضوع جديد أو محدّث" + zero: "لا مواضيع جديدة أو محدّثة." + one: "موضوع واحد جديد أو محدّث." + two: "موضوعان جديدان أو محدّثان." + few: "{{count}} مواضيع جديدة أو محدّثة." + many: "{{count}} موضوعا جديدا أو محدّثا." + other: "{{count}} موضوع جديد أو محدّث." topic_count_unread: - zero: "0 مواضيع غير مقروءة" - one: "موضوع واحد غير مقروء" - two: "موضوعان غير مقروءان" - few: "{{count}} مواضيع غير مقروءة" - many: "{{count}} موضوعًا غير مقروء" - other: "{{count}} موضوع غير مقروء" + zero: "لا مواضيع غير مقروءة" + one: "موضوع واحد غير مقروء." + two: "موضوعان غير مقروءان." + few: "{{count}} مواضيع غير مقروءة." + many: "{{count}} موضوعا غير مقروء." + other: "{{count}} موضوع غير مقروء." topic_count_new: - zero: "0 مواضيع جديدة" - one: "موضوع واحد جديد" - two: "موضوعان جديدان" - few: "{{count}} مواضيع جديدة" - many: "{{count}} موضوعًا جديدًا" - other: "{{count}} موضوع جديد" - click_to_show: "إضغط للعرض." + zero: "لا مواضيع جديدة." + one: "موضوع واحد جديد." + two: "موضوعان جديدان." + few: "{{count}} مواضيع جديدة." + many: "{{count}} موضوعا جديدا." + other: "{{count}} موضوع جديد." + click_to_show: "انقر للعرض." preview: "معاينة" - cancel: "الغاء" - save: "حفظ التغييرات" - saving: "يتم الحفظ..." - saved: "تم الحفظ!" - upload: "رفع" - uploading: "يتم الرفع..." - uploading_filename: "تحديث {{filename}}..." - uploaded: "اكتمل الرفع!" - enable: "تمكين" - disable: "تعطيل" + cancel: "ألغ" + save: "احفظ التعديلات" + saving: "يحفظ..." + saved: "حُفظت!" + upload: "ارفع" + uploading: "يرفع..." + uploading_filename: "يرفع {{filename}}..." + uploaded: "رُفع!" + enable: "فعّل" + disable: "عطّل" undo: "تراجع" revert: "عكس" failed: "فشل" switch_to_anon: "وضع التخفي" - switch_from_anon: "خروج مجهول" + switch_from_anon: "اخرج من وضع التخفي" banner: close: "تعطيل البانر" edit: "تحرير هذا البانر" choose_topic: - none_found: "لم يتم العثور على مواضيع." + none_found: "لم يتم العثور على مواضيع ." title: - search: "بحث عن موضوع حسب الاسم، رابط أو رقم التعريف(id) :" + search: "بحث عن موضوع حسب الاسم، رابط أو رقم التعريف (id) :" placeholder: "اكتب عنوان الموضوع هنا" queue: - topic: "الموضوع" + topic: "الموضوع :" approve: 'الموافقة' reject: 'الرفض' - delete_user: 'حذف المستخدم' + delete_user: 'احذف المستخدم' title: "تحتاج موافقة" - none: "لا يوجد مشاركات لمراجعتها" + none: "لا يوجد مشاركات لمراجعتها ." edit: "تعديل" cancel: "إلغاء" view_pending: "عرض المشاركات المعلقة" @@ -351,7 +371,7 @@ ar: many: "هذا الموضوع له كثير من المشاركات بانتظار الموافقة" other: "هذا الموضوع له {{count}} مشاركات بانتظار الموافقة" confirm: "حفظ التعديلات" - delete_prompt: "هل أنت متأكد أنك تريد حذف %{username}؟ هذا سيحذف جميع مشاركاتك ويحظر بريدك الإلكتروني و عنوانك الـIP ." + delete_prompt: "هل أنت متأكد أنك تريد حذف %{username}؟ جميع مشاركته سوف تحذف كذلك و سوف يحظر كل من بريده الإلكتروني و عنوان الـ IP." approval: title: "المشاركات تحتاج موافقة" description: "لقد استلمنا مشاركتك لكنها تحتاج موافقة المشرف قبل ظهورها. الرجاء الانتظار" @@ -382,7 +402,7 @@ ar: title: "الأعضاء" likes_given: "الإعجابات المعطاة" likes_received: "الإعجابات المستلمة" - topics_entered: "مدخل" + topics_entered: "المواضيع المدخلة" topics_entered_long: "المواضيع المدخلة" time_read: "وقت القراءة" topic_count: "المواضيع" @@ -402,6 +422,15 @@ ar: many: "%{count} عضوًا" other: "%{count} عضو" groups: + empty: + posts: "لا يوجد أي منشور لأي عضو من هذه المجموعة ." + members: "لا يوجد أعضاء في هذه المجموعة ." + mentions: "لا يوجد أعضاء في هذه المجموعة ." + messages: "لا توجد رسائل لهذه المجموعة." + topics: "لا يوجد أي منشور لأي عضو من هذه المجموعة ." + add: "اضافة" + selector_placeholder: "اضافة عضو" + owner: "المالك" visible: "المجموعة مرئية عن جميع المستخدمين" title: zero: "مجموعات" @@ -411,17 +440,33 @@ ar: many: "مجموعات" other: "مجموعات" members: "أعضاء " + topics: "ألمواضيع" posts: "مشاركات" + mentions: "إشارات" + messages: "الرسائل" alias_levels: - title: "الذين يمكنهم استخدام هذه المجموعة كاسم مستعار ؟" + title: "من يستطيع أن يشارك في هذه المجموعة ؟" nobody: "لا أحد" - only_admins: "المسؤولين فقط" + only_admins: "المسؤولون فقط" mods_and_admins: "فقط المدراء والمشرفون" members_mods_and_admins: "فقط اعضاء المجموعة والمشرفون والمدراء" everyone: "الكل" trust_levels: title: "مستوى الثقة يمنح تلقائيا للأعضاء عندما يضيفون:" none: "لا شيء" + notifications: + watching: + title: "تحت المتابعة" + description: "سيتم إشعارك بأية رد على هذه الرسالة، وبعدد الردود الجديدة التي ستظهر ." + tracking: + title: "تتبع" + description: "سيتم إشعارك بأية رد على هذا الموضوع، وبعدد الردود الجديدة التي ستظهر." + regular: + title: "معتدل" + description: ".سيتم إشعارك إذا ذكر أحد ما @name أو رد على مشاركاتك" + muted: + title: "مكتوم" + description: "لن يتم إشعارك بأي جديد يخص هذا الموضوع ولن يظهرهذا الموضوع في قائمة المواضيع المنشورة مؤخراً." user_action_groups: '1': "الإعجابات المعطاة" '2': "الإعجابات المستلمة" @@ -431,7 +476,6 @@ ar: '6': "ردود" '7': "إشارات" '9': "إقتباسات" - '10': "تألقت" '11': "التعديلات" '12': "العناصر المرسلة" '13': "البريد الوارد" @@ -441,6 +485,7 @@ ar: all_subcategories: "جميع" no_subcategory: "لا شيء" category: "تصنيف" + category_list: "أعرض قائمة الأقسام." reorder: title: "إعادة ترتيب الفئات" title_long: "إعادة تنظيم قائمة الفئة" @@ -505,49 +550,50 @@ ar: invited_by: "مدعو بواسطة" trust_level: "مستوى الثقة" notifications: "الاشعارات" + statistics: "احصائيات" desktop_notifications: label: "إشعارات سطح المكتب" not_supported: "عذراً , الإشعارات غير مدعومة على هذا المتصفح " perm_default: "تفعيل الإشعارات" perm_denied_btn: "الصلاحيات ممنوعة " - perm_denied_expl: "لقد قمت بإيقاف صلاحية الإشعارات في متصفحك . إستخدم متصفحك لتفعيل التنبيهات و ثم أعد ضغط الزر .\n( سطح المكتب : الأيقونة في أقصى اليسار في شريط العنوان . للهواتف الذكية : في معلومات الموقع Site Info)" + perm_denied_expl: "لقد قمت بالغاء الاشعارات . قم بتفعيل الاشعارات عن طريق اعدادات االمتصفح" disable: "إيقاف الإشعارات " - currently_enabled: "( مفعل مسبقاً )" enable: "تفعيل الإشعارات" - currently_disabled: "( مفعل مسبقاً )" each_browser_note: "ملاحظة : يجب انت تقوم بتغيير هذا الإعداد عند كل مرة تستخدم فيها متصفح جديد ." dismiss_notifications: "جعل الجميع مقروء" dismiss_notifications_tooltip: "جعل جميع اشعارات غيرمقروء الى مقروء" - disable_jump_reply: "لاتذهب الى مشاركة جديدة بعد الرد" - dynamic_favicon: "أعرض عدد الموضوع الجديد / الحديث في أيقونة المتصفح." + disable_jump_reply: "لاتذهب إلى مشاركتي بعد الرد" + dynamic_favicon: "إعرض عدد المواضيع الجديدة والمحدثة في أيقونة المتصفح" edit_history_public: "جعل المستخدمين الاخرين يطلعون على تعديلاتي" external_links_in_new_tab: "إفتح كل الروابط الخارجية في صفحة جديدة" - enable_quoting: "إسمح بإقتباس التعليقات لنصوص البارزة الملقى عليها ضوء" + enable_quoting: "فعل خاصية إقتباس النصوص المظللة" change: "تغيير" - moderator: "{{user}} لديه صلاحية التعديل" + moderator: "{{user}} مشرف" admin: "{{user}} مدير" - moderator_tooltip: "هذا المستخدم لديه صلاحية التعديل" + moderator_tooltip: "هذا المستخدم مشرف" admin_tooltip: "هذا المستخدم مدير" blocked_tooltip: "هذا المستخدم محظور" suspended_notice: "هذا المستخدم موقوف حتى تاريخ {{date}}" suspended_reason: "سبب" github_profile: "Github" - mailing_list_mode: "استقبال بريد الكتروني لكل مشاركة جديدة (بإسثناء لو قمت بكتم الموضوع او التصنيف)" - watched_categories: "متابع" - watched_categories_instructions: "تلقائيا ستقوم بمتابعة جميع المواضيع في هذا التصنيف , وسيتم اشعارك بجميع المشاركات والمواضيع و بعدد المشاركات الجديدة التي ستظهر بجانب الموضوع. " - tracked_categories: "Tracked" - tracked_categories_instructions: "ستتبع بشكل تلقائي جميع المواضيع الجديدة في هذه التصنيفات. عدد المشاركات الجديدة سيظهر بجانب الموضوع." + mailing_list_mode: "استقبال بريد الكتروني لكل مشاركة جديدة (إلا إذا كتمت الموضوع أو التصنيف)" + watched_categories: "مراقبة" + watched_categories_instructions: "ستتم مراقبة جميع المواضيع الجديدة في هذه التصانيف. سيتم اشعارك بجميع المشاركات والمواضيع الجديدة، بالاضافة الى عدد المشاركات الجديدة الذي سيظهر بجانب الموضوع." + tracked_categories: "متابعة" + tracked_categories_instructions: "ستتم متابعة جميع المواضيع الجديدة في هذه التصانيف. عدد المشاركات الجديدة سيظهر بجانب الموضوع." muted_categories: "كتم" - muted_categories_instructions: "تلقائيا ستقوم بمتابعة جميع المواضيع في هذا التصنيف , وسيتم اشعارك لجميع المشاركات والمواضيع وكذلك عداد الغيرمقروء والمشاركات الجديدة" + muted_categories_instructions: "لن يتم إشعارك بأي جديد عن المواضيع الجديدة في هذه التصنيفات، ولن تظهر مواضيع هذه التصنيفات في قائمة المواضيع المنشورة مؤخراً." delete_account: "حذف الحساب" - delete_account_confirm: "هل انت متاكد من انك تريد حذف هذا المستخدم؟ هذا الإجراء دائماً!" - deleted_yourself: "حسابك تم حذفه بنجاح" - delete_yourself_not_allowed: "لايمكنك حذف حسابك لان , تواصل مع المدير ليحذف حسابك " + delete_account_confirm: "هل انت متاكد من انك تريد حذف حسابك نهائيا؟ لايمكن التراجع عن هذا العمل!" + deleted_yourself: "تم حذف حسابك بنجاح" + delete_yourself_not_allowed: "لايمكنك حذف حسابك الان , تواصل مع المدير ليحذف حسابك " unread_message_count: "الرسائل" admin_delete: "حذف" users: "الأعضاء" muted_users: "الأعضاء المكتومون" muted_users_instructions: "كتم جميع التنبيهات من هؤلاء الأعضاء." + muted_topics_link: "عرض المواضيع المكتومة" + automatically_unpin_topics: "قم تلقائيا بازاله العلامات عند الوصول الى نهايه الصفحه" staff_counters: flags_given: "علامات مساعدة" flagged_posts: "# مشاركات" @@ -556,8 +602,15 @@ ar: warnings_received: "تحذيرات" messages: all: "الكل" - mine: "لي" - unread: "غير مقروء" + inbox: "البريد الوارد" + sent: "مرسلة" + archive: "الارشيف" + groups: "مجموعاتي" + bulk_select: "إختيار رسائل" + move_to_inbox: "الذهاب إلى الرسائل الواردة" + move_to_archive: "الارشيف" + failed_to_move: "فشل في نقل الرسائل المحددة (ربما يكون اتصالك ضعيفاً)" + select_all: "إختيار الكل" change_password: success: "(تم ارسال الرسالة)" in_progress: "(يتم ارسال رسالة)" @@ -602,10 +655,14 @@ ar: ok: "سيتم إرسال رسالة على بريدك الإلكتروني لتأكيد الحساب" invalid: "يرجى إدخال بريد الكتروني فعّال." authenticated: "تم توثيق بريدك الإلكتروني بواسطة {{provider}}" + frequency_immediately: "سيتم ارسال رسالة الكترونية فورا في حال أنك لم الرسائل السابقة" frequency: - zero: "سيتم ارسال رسالة الكترونية فورا في حال أنك لم الرسائل السابقة" - one: "سيتم ارسال رسالة الكترونية فقط في حال أننا لم نشاهدك في آخر دقيقة وانك لك تقم بقراءة الرسائل الالكترونية السابقة" - other: "سيتم ارسال رسالة الكترونية في أننا لم نشاهدك خلال {{count}} دقيقة وانك لم تقم بقراءة الرسائل الالكترونية السابقة " + zero: "سنراسلك على بريدك فقط في حال لم تكن متصلا على الموقع في آخر {{count}} دقيقة ." + one: "سنراسلك على بريدك فقط في حال لم تكن متصلا على الموقع في آخر دقيقة ." + two: "سنراسلك على بريدك فقط في حال لم تكن متصلا على الموقع في آخر دقيقتين ." + few: "سنراسلك على بريدك فقط في حال لم تكن متصلا على الموقع في {{count}} دقائق ." + many: "سنراسلك على بريدك فقط في حال لم تكن متصلا على الموقع في {{count}} دقيقة ." + other: "سنراسلك على بريدك فقط في حال لم تكن متصلا على الموقع في {{count}} دقيقة ." name: title: "الاسم" instructions: "اسمك الكامل (اختياري )" @@ -638,22 +695,36 @@ ar: log_out: "تسجيل الخروج" location: "الموقع" card_badge: - title: "بطاقة المستخدم" + title: "وسام بطاقة المستخدم" website: "موقع الكتروني" email_settings: "بريد الكتروني" + like_notification_frequency: + title: "اشعرني عند الاستحسان" + always: "دائما" + first_time_and_daily: "اول مره يتم استحسان المنشور و يوميا " + first_time: "اول مره يتم استحسان المنشور" + never: "ابداً" + email_previous_replies: + title: "تضمين مشاركات سابقة في أسفل البريد المرسل" + unless_emailed: "الا اذا تم ارساله موخراً" + always: "دائماً" + never: "ابداً" email_digests: title: "إرسال رسالة إلكترونية تحتوي على جديد الموقع عندما لا أزور الموقع" + every_30_minutes: "بعد 30 دقيقه" + every_hour: "كل ساعه " daily: "يومي" every_three_days: "كل ثلاثة أيام" weekly: "اسبوعي" every_two_weeks: "كل أسبوعين" + email_in_reply_to: "ارفق مقتبسات الرد على المنشور في رسائل البريد" email_direct: "تلقي رسالة إلكترونية عند اقتباس مشاركة لك أو الرد على عليها أو في حالة ذكر اسمك @username" email_private_messages: "إرسال إشعار بالبريد الإلكتروني عندما يرسل لك شخصاً رسالة خاصة" email_always: "نبهني بوجود رسائل جديدة حتى لو كنت متصل على الموقع ." other_settings: "اخرى" categories_settings: "اقسام" new_topic_duration: - label: " \nإعتبر الوضوع جديد حين" + label: " \nإعتبر المواضيع جديدة في حال" not_viewed: "لم تقم بالاطلاع عليها حتى الآن" last_here: "تم انشائها منذ آخر زيارة لك" after_1_day: "أنشأت في اليوم الماضي" @@ -677,7 +748,13 @@ ar: user: "المستخدمين المدعويين" sent: "تم الإرسال" none: "لا توجد دعوات معلقة لعرضها." - truncated: "اظهار اوائل {{count}} المدعويين" + truncated: + zero: "لا يوجد دعوات لعرضها." + one: "عرض الدعوة الأولى." + two: "عرض الدعوتان الأولتان." + few: "عرض الدعوات الأولية." + many: "عرض الدعوات {{count}} الأولى." + other: "عرض الدعوات {{count}} الأولى." redeemed: "دعوات مستخدمة" redeemed_tab: "محررة" redeemed_tab_with_count: "({{count}}) محررة" @@ -712,6 +789,15 @@ ar: same_as_email: "كلمة المرور مطابقة للبريد الإليكتروني." ok: "كلمة المرور هذة تعتبر جيدة." instructions: "على الاقل %{count} حرف" + summary: + title: "ملخص" + stats: "احصائيات" + top_replies: "أفضل المشاركات" + more_replies: "المزيد من الردود" + top_topics: "افضل المواضيع" + more_topics: "المزيد من المواضيع" + top_badges: "افضل الاوسمه" + more_badges: "المزيد من الاوسمه" associated_accounts: "حساب مرتبط" ip_address: title: "أخر عنوان أيبي" @@ -737,11 +823,13 @@ ar: server: "خطأ في السيرفر" forbidden: "غير مصرح" unknown: "خطأ" + not_found: "الصفحة غير متوفرة" desc: network: "الرجاء التحقق من اتصالك" network_fixed: "يبدوا أنه رجع" server: "رقم الخطأ: {{status}}" forbidden: "ليس لديك الصلاحية" + not_found: "عفوا، حاول التطبيق حمل URL الغير موجودة." unknown: "حدث خطأ ما" buttons: back: "الرجوع" @@ -752,8 +840,9 @@ ar: logout: "تم تسجيل خروجك" refresh: "تحديث" read_only_mode: - enabled: "وضع القراءة فقط مفعل. يمكنك إكمال تصفح الموقع لكن التفاعلات قد لا تعمل." + enabled: "الموقع في وضع القراءه فقط. الرجاء الاستمرار بالتصفح , لكن الردود و الاعجابات و الخصائص الاخرى معطله للان ." login_disabled: "تسجيل الدخول معطل لأن الموقع في خالة القراءة فقط" + logout_disabled: "تسجيل الخروج معطل عندما يكون الموقع في حاله القراءه فقط" too_few_topics_and_posts_notice: "دعونا الحصول على هذه المناقشة بدأت! يوجد حاليا%{currentTopics} / %{requiredTopics} المواضيع و %{currentPosts} / %{requiredPosts} المشاركات. الزوار الجدد بحاجة إلى بعض الأحاديث لقراءة والرد على." too_few_topics_notice: "دعونا الحصول على هذه المناقشة التي! وهناك حاليا %{currentTopics} / %{requiredTopics} المواضيع. الزوار الجديدة بحاجة إلى بعض الأحاديث قراءة والرد عليها." too_few_posts_notice: "دعونا الحصول على هذه المناقشة التي بدأت! يوجد حاليا %{currentPosts} / %{requiredPosts} مشاركات. الزوار الجديدة بحاجة إلى بعض الأحاديث قراءة والرد عليها." @@ -780,22 +869,14 @@ ar: signup_cta: sign_up: "إشترك" hide_session: "ذكرني غدا" - hide_forever: "لا، شكراً" + hide_forever: "لا شكرا" hidden_for_session: "حسنا، أنا اسأل لك غدا. يمكنك دائماً استخدام '\"تسجيل الدخول\"' لإنشاء حساب، أيضا." - intro: "مهلا هناك! : heart_eyes: يبدو أنك تتمتع المناقشة، ولكن لم تقم بالتسجيل للحصول على حساب." - value_prop: "عندما تقوم بإنشاء حساب، نستطيع تتبع بالضبط ما كنت قد قرأت، حيث كنت دائماً تأتي حق العودة حيث تركته. يمكنك أيضا الحصول على الاشعارات، هنا وعبر البريد الإلكتروني، كلما تقدم وظائف جديدة. ويمكنك مثل مشاركات لتبادل الحب.:heartbeat:" - methods: - sso: "التسجيل أمر سهل: كل ما تحتاجه حساب في الموقع الرئيسي." - only_email: "التسجيل أمر سهل: كل ما تحتاجه هو بريد إلكتروني وكلمة مرور." - only_other: "استخدم الخاص بك %{provider} لتسجيل حساب ." - one_and_email: "استخدم الخاص بك %{provider} الحساب, أو البريد الإلكتروني وكلمة المرور، للتسجيل." - multiple_no_email: "التسجيل أمر سهل: استخدام أي موقع لتواصل الاجتماعي %{count} لتسجيل الدخول." - multiple: "التسجيل أمر سهل: استخدام أي موقع لتواصل الاجتماعي لتسجيل الدخول %{count} ، أو البريد الإلكتروني وكلمة المرور." - unknown: "خطأ في الحصول على دعم أساليب تسجيل الدخول" + intro: "لحظة ! :heart_eyes: يبدو أنك مهتم بهذه المناقشة، لكنك لم تقم بالتسجيل للحصول على حساب ." + value_prop: "عندما تنشئ حساب، ننحن نتذكر ما كنت تقرأه بالضبط، و سترجع دائما في المكان الذي تركته، و ستصلك الاشعارات ايضا، هنا و عبر البريد الإلكتروني، في اي وقت ينشأ فيه منشور جديد، و تستطيع أن تُعجب بالمنشورارت لتشارك ما يعجبك :heartbeat:" summary: enabled_description: "أنت تنظر الى ملخص لهذا الموضوع , مشاركات مثيرة للإهتمام بحسب رأي المجتمع" - description: "هناك {{count}} ردود" - description_time: "هناك {{count}} ردود مع تقدير وقت القراءة {{readingTime}} دقائق." + description: "يوجد {{replyCount}} مشاركة." + description_time: "يوجد {{replyCount}} مشاركة, والوقت المقدر للقراءة {{readingTime}} minutes دقيقة." enable: 'لخّص هذا الموضوع' disable: 'عرض جميع المشاركات' deleted_filter: @@ -805,15 +886,15 @@ ar: disable: "عرض المشاركات المحذوفة" private_message_info: title: " رسالة خاصة" - invite: " إستدعي الأخرين" - remove_allowed_user: "هل تريد حقا ازالة {{name}} من الرسائل الخاصة ?" + invite: " إدعو اخرين" + remove_allowed_user: "هل تريد حقا ازالة {{name}} من الرسائل الخاصة ؟" email: 'البريد الإلكتروني' username: 'إسم المستخدم' last_seen: 'شوهدت' created: 'مكتوبة' created_lowercase: 'منشأة' trust_level: 'مستوى التقة' - search_hint: 'اسم مستخدم, بريد الكتروني او ايبي' + search_hint: 'اسم مستخدم او بريد الكتروني او عنوان ايبي' create_account: title: "إنشاء حساب جديد" failed: "حدث خطأ ما, ربما بريدك الالكتروني مسجل مسبقا, جرب رابط نسيان كلمة المرور " @@ -845,10 +926,13 @@ ar: awaiting_approval: "لم يتم الموافقة على حسابك، سيتم إرسال بريد إلكتروني عندما تتم الموافقة." requires_invite: "المعذرة، الوصول لهذا الموقع خاص بالمدعويين فقط." not_activated: "لا يمكنك تسجيل الدخول. لقد سبق و أن أرسلنا بريد إلكتروني إلى {{sentTo}} لتفعيل حسابك. الرجاء اتباع التعليمات المرسلة لتفعيل الحساب." - not_allowed_from_ip_address: "لا يمكنك تستجيل الدخول من خلال هذا العنوان الرقمي - IP." + not_allowed_from_ip_address: "لا يمكنك تسجيل الدخول من خلال هذا العنوان الرقمي - IP." admin_not_allowed_from_ip_address: "لا يمكنك تسجيل الدخول كمدير من خلال هذا العنوان الرقمي - IP." resend_activation_email: "اضغط هنا لإرسال رسالة إلكترونية أخرى لتفعيل الحساب." sent_activation_email_again: "لقد سبق وأن تم إرسال رسالة إلكترونية إلى {{currentEmail}} لتفعيل حسابك. تأكد من مجلد السبام في بريدك." + to_continue: "الرجاء تسجيل الدخول..." + preferences: "يتوجب عليك تسجيل الدخول لتغيير إعداداتك الشخصية." + forgot: "لا أذكر معلومات حسابي" google: title: "مع جوجل" message: "التحقق من خلال حساب جوجل ( الرجاء التأكد من عدم تشغيل مانع الاعلانات المنبثقة في المتصفح)" @@ -858,6 +942,9 @@ ar: twitter: title: "مع تويتر" message: "التحقق من خلال حساب تويتر ( الرجاء التأكد من عدم تشغيل مانع الاعلانات المنبثقة في المتصفح)" + instagram: + title: "عن طريق الانستغرام" + message: "تسجيل الدخول عن طريق الانستغرام (تاكد ان حاجب النوافذ المنبسقه غير مفعل)" facebook: title: "مع الفيسبوك" message: "التحقق من خلال حساب الفيس بوك ( الرجاء التأكد من عدم تشغيل مانع الاعلانات المنبثقة في المتصفح)" @@ -871,8 +958,13 @@ ar: google: "جوجل" twitter: "تويتر" emoji_one: "تعبيرات" + shortcut_modifier_key: + shift: 'العالي' + ctrl: 'التحكم' + alt: 'Alt' composer: - emoji: "تعبيرات: ابتسامة" + emoji: "الرموز التعبيرية :)" + more_emoji: "أكثر..." options: "خيارات" whisper: "همس" add_warning: "هذا تحذير رسمي" @@ -883,14 +975,15 @@ ar: saved_local_draft_tip: "تم الحفظ محلياً" similar_topics: "موضوعك مشابه لـ ..." drafts_offline: "مسودات محفوظة " + group_mentioned: "عند استعمال {{group}}, انت على وشك اشعار {{count}} people." error: title_missing: "العنوان مطلوب" title_too_short: "العنوان يجب أن يكون اكثر {{min}} حرف" title_too_long: "العنوان يجب أن لا يكون أكثر من {{max}} حرف" post_missing: "لا يمكن للمشاركة أن تكون خالية" post_length: "التعليق يجب أن يكون أكثر {{min}} حرف" - try_like: 'هل تجرب زر ؟' - category_missing: "يجب عليك اختيارفئة" + try_like: 'هل جربت زر ؟' + category_missing: "يجب عليك اختيارتصنيف" save_edit: "حفظ التحرير" reply_original: "التعليق على الموضوع الاصلي" reply_here: "الرد هنا" @@ -905,46 +998,48 @@ ar: show_edit_reason: "(اضف سبب التعديل)" reply_placeholder: "أكتب هنا. استخدم Markdown, BBCode, أو HTML للتشكيل. اسحب أو الصق الصور." view_new_post: "الاطلاع على أحدث مشاركاتك" - saving: "يتم الحفظ..." + saving: "جارِ الحفظ" saved: "تم الحفظ" saved_draft: "جاري إضافة المسودة. اضغط للاستئناف" uploading: "يتم الرفع..." - show_preview: 'السابق »' + show_preview: 'أعرض المعاينة »' hide_preview: '« اخف المعاينة' quote_post_title: "اقتبس كامل المشاركة" - bold_title: "قوي" - bold_text: "strong text" - italic_title: "Emphasis" - italic_text: "emphasized text" + bold_title: "عريض" + bold_text: "نص عريض" + italic_title: "مائل" + italic_text: "نص مائل" link_title: "الرابط" link_description: "ادخل وصف الرابط هنا " link_dialog_title: "اضف الرابط" link_optional_text: "عنوان اختياري" - quote_title: "حظر الاقتباس" - quote_text: "حظر الاقتباس" - code_title: "الاطلاع على التنسيق" - code_text: "لإضافة فراغ اول النص عن طريق 4 مسافات" + link_placeholder: "http://example.com \"نص إختياري\"" + quote_title: "اقتباس فقرة" + quote_text: "اقتباس فقرة" + code_title: "المحافظة على التنسيق" + code_text: "اضف 4 مسافات اول السطر قبل النص المنسق" upload_title: "رفع" upload_description: "ادخل وصف الرفع هنا" olist_title: "قائمة مرقمة" ulist_title: "قائمة " list_item: "قائمة العناصر" - heading_title: "اخفاء" - heading_text: "اخفاء" - hr_title: "Horizontal Rule" - undo_title: "تراجع" - redo_title: "تقدم" - help: "مساعدة في الـ Maekdown" - toggler: "اخف او اظهر معلومات الكاتب" + heading_title: "عنوان" + heading_text: "عنوان" + hr_title: "خط افقي" + help: "مساعدة في رموز التنسيق" + toggler: "اخف او اظهر صندوق التحرير" + modal_ok: "موافق" + modal_cancel: "إلغاء" + cant_send_pm: "عذرا ، لا يمكنك ان ترسل رسالة الى %{username} ." admin_options_title: "اختياري اضافة اعدادات الموضوع" auto_close: - label: "اغلاق تلقائي لوقت الموضع" + label: "وقت الإغلاق التلقائي للموضوع" error: "يرجى ادخال قيمة صحيحة" based_on_last_post: "لاتغلق الموضوع حتى تكون آخر مشاركة بهذا القدم " all: examples: 'أدخل رقم الساعة (24) . الوقت (17:30) . او التاريخ (2013-11-22 14:00).' limited: - units: "(# of hours)" + units: "(# من الساعات)" examples: 'أدخل الساعة (24)' notifications: title: "الإشعار عندما يتم ذكر @name , أو الردود على مواضيعك أو مشاركاتك أو الرسالة الخاصة ...إلخ" @@ -952,11 +1047,13 @@ ar: more: "إظهار إشعارات قديمة" total_flagged: "مجموع المشاركات المعلّم عليها" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}}" replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -977,9 +1074,11 @@ ar: invitee_accepted: "قبلت الدعوة بواسطة" moved_post: "مشاركتك نقلت بواسطة" linked: "رابط لمشاركتك" - granted_badge: "تم منح الشارة" + granted_badge: "تم منح الوسام" + group_message_summary: "الرسائل في صندوق رسائل المجموعه" popup: mentioned: '{{username}} أشار لك في "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} ذكرك في "{{topic}}" - {{site_title}}' quoted: '{{username}} نقل لك في "{{topic}}" - {{site_title}}' replied: '{{username}} رد لك في "{{topic}}" - {{site_title}}' posted: '{{username}} شارك في "{{topic}}" - {{site_title}}' @@ -991,9 +1090,9 @@ ar: from_my_computer: "عن طريق جهازي" from_the_web: "عن طريق الويب" remote_tip: "رابط لصورة" - remote_tip_with_attachments: "رابط لصورة أو ملف ({{authorized_extensions}})" + remote_tip_with_attachments: "رابط لصورة أو ملف {{authorized_extensions}}" local_tip: "إختر صور من جهازك ." - local_tip_with_attachments: "اضغط لاختيار صورة أو ملف من جهازك ({{authorized_extensions}})" + local_tip_with_attachments: "اختيار صور او ملفات من جهازك {{authorized_extensions}}" hint: "(تستطيع أيضا أن تسحب و تفلت ملف أو صورة في المحرر لرفعه)" hint_for_supported_browsers: "يمكنك أيضا سحبوإفلات أو لصق الصور إلى المحرر" uploading: "يتم الرفع" @@ -1032,12 +1131,14 @@ ar: current_user: 'الذهاب إلى صفحتك الشخصية' topics: bulk: + unlist_topics: "ازالة المواضيع من القائمة" reset_read: "تصفير القراءات" delete: "المواضيع المحذوفة" - dismiss_posts: "إخفاء المشاركات" - dismiss_posts_tooltip: "تصفير عدادا المواضيع الغير مقروءة مع الاستمرار في إظهارها في قائمة المواضيع الغير مقروءة عند إضافة مشاركات جديدة" - dismiss_topics: "إخفاء المواضيع" - dismiss_topics_tooltip: "توقف عن إظهار هذه المواضيع ضمن قائمة الغير مقروءة عند إضافة مشاركات جديدة لها" + dismiss: "إخفاء" + dismiss_read: "تجاهل المشاركات غير المقروءة" + dismiss_button: "تجاهل..." + dismiss_tooltip: "تجاهل فقط المشاركات الجديدة او توقف عن تتبع المواضيع" + also_dismiss_topics: "التوقف عن متابعه المواضيع حتي لا تظهر كغير مقروء مره اخرى " dismiss_new: "إخفاء الجديد" toggle: "إيقاف/تشغيل الاختيار المتعدد للمواضيع" actions: "عمليات تنفذ دفعة واحدة" @@ -1064,9 +1165,6 @@ ar: category: "لا يوجد مواضيع في التصنيف {{category}}" top: "لا يوجد مواضيع تستحق أن تكون ضمن الأفضل مع الأسف." search: "لا يوجد نتائج للبحث." - educate: - new: '

    مواضيعك الجديدة ستظهر هنا.

    بشكل افتراضي ، كل المواضيع ستعتبر جديدة و تحمل الوسم جديد إذا تمت كتابتها قبل يومين على الأكثر.

    طبعا تقدر تغير هذا من إعداداتك.

    ' - unread: '

    المواضيع الغير مقروءة ستظهر هنا

    افتراضياً, سيتم اعتبارالمواضيع غير مقروءة وتحمل الوسم 1 إذا:

    • كتبت موضوع جديد
    • رددت على موضوع
    • قرأت موضوع لأكثر من 4 دقائق.

    أو إذا قمت باختيار خيار تتبع موضوع أو إضافته للمواضيع المراقبة من خلال لوحة التحكم بالإشعارات.

    تستطيع تغيير الإعدادات من خلال إعداداتك.

    ' bottom: latest: "لا يوجد المزيد من المواضيع الحديثة" hot: "هذه كل المواضيع التي عليها إقبال عالي حتى هذه اللحظة" @@ -1086,6 +1184,12 @@ ar: create: 'موضوع جديد' create_long: 'كتابة موضوع جديد' private_message: 'أرسل رسالة خاصة' + archive_message: + help: 'انقل الرسالة لارشيفك.' + title: 'الارشيف' + move_to_inbox: + title: 'انقل للبريد الوارد.' + help: 'انقل الرسالة مرة آخرى للبريد الوارد.' list: 'المواضيع' new: 'موضوع جديد' unread: 'غير مقروء' @@ -1110,7 +1214,7 @@ ar: login_required: "عليك تسجيل الدخول لمشاهدة الموضوع" server_error: title: "حدث خطأ أثناء عرض الموضوع" - description: "للأسف، لا يمكن عرض الموضوع ، قد يكون بسبب مشكلة في الاتصال. الرجاء المحاولة مرة أخرى، إذا استمرت المشكلة عطنا خبر" + description: "للأسف، لا يمكن عرض الموضوع ، ربما تكون مشكلة في الاتصال. يرجى المحاولة مرة أخرى، إذا استمرت المشكلة يرجى التواصل معنا ." not_found: title: "لم يتم العثور على الموضوع" description: "للأسف، لم نتمكن من إيجاد الموضوع. يمكن تم حذفه من قبل المشرف." @@ -1151,7 +1255,7 @@ ar: read_more_MF: "هناك { UNREAD, plural, =0 {} one { is 1 unread } other { are # unread } } { NEW, plural, =0 {} one { {BOTH, select, true{and } false {is } other{}} 1 new topic} other { {BOTH, select, true{and } false {are } other{}} # new topics} } remaining, or {CATEGORY, select, true {browse other topics in {catLink}} false {{latestLink}} other {}}" browse_all_categories: استعرض جميع التصنيفات view_latest_topics: شاهد آخر المواضيع - suggest_create_topic: ما رأيك لو تكتب موضوع جديد؟ + suggest_create_topic: ما رأيك أن تكتب موضوعاً جديداً ؟ jump_reply_up: الذهاب إلى أول رد jump_reply_down: الذهاب إلى آخر رد deleted: "الموضوع محذوف" @@ -1160,6 +1264,7 @@ ar: auto_close_title: 'إعدادات الإغلاق التلقائي' auto_close_save: "حفظ" auto_close_remove: "لا تغلق هذا الموضوع تلقائياً" + auto_close_immediate: "احر منشور في الموضيع كان قبل %{hours} ساعه , لذلك فان الموضوع يتم اغلاقه حالاَ ." progress: title: حالة الموضوع go_top: "أعلى" @@ -1180,7 +1285,7 @@ ar: '2_8': 'سيصلك إشعارات لأنك اخترت تتبع هذا التصنيف' '2_4': 'سيصلك إشعارات لأنك أضفت مشاركة لهذا الموضوع.' '2_2': 'سيصلك إشعارات لأنك اخترت متابعة الموضوع' - '2': 'سيصلك اشعار بسبب انك قراءة هذا الموضوع.' + '2': 'سيصلك إشعار لأنك قرأت هذا الموضوع.' '1_2': '.سيتم إشعارك إذا ذكر أحد ما @name أو رد على مشاركاتك' '1': '.سيتم إشعارك إذا ذكر أحد ما @name أو رد على مشاركاتك' '0_7': 'لن يصلك أي إشعار يخص هذا التصنيف بناء على طلبك.' @@ -1209,7 +1314,7 @@ ar: description: "لن يتم إشعارك بأي جديد يخص هذه الرسالة الخاصة." muted: title: "مكتوم" - description: "لن يتم إشعارك بأي جديد يخص هذا الموضوع ولن يظهرهذا الموضوع في تبويب المواضيع الغير مقروءة." + description: "لن يتم إشعارك بأي جديد يخص هذا الموضوع ولن يظهرهذا الموضوع في قائمة المواضيع المنشورة مؤخراً." actions: recover: "استرجاع الموضوع" delete: "حذف الموضوع" @@ -1251,25 +1356,32 @@ ar: unpin_until: "ازالة هذا الموضوع من أعلى فئة {{categoryLink}} أو إنتظر حتى %{until} " pin_note: "المستخدمون يستطعون إزالة تثبيت الموضوع بشكل خاص بهم." pin_validation: "التاريخ مطلوب لتثبيت هذا الموضوع." + not_pinned: "ﻻيوجد مواضيع مثبتة في {{categoryLink}}." already_pinned: - zero: "ﻻيوجد مواضيع مثبتة في {{categoryLink}}." - one: "المواضيع المثيتة حالياً في {{categoryLink}} : \n1." - other: "المواضيع المثبتة حالياً في {{categoryLink}} : \n{{count}}." + zero: "المواضيع مثبتة حالياً في {{categoryLink}}: {{count}}" + one: "المواضيع مثبتة حالياً في {{categoryLink}}: 1" + two: "المواضيع مثبتة حالياً في {{categoryLink}}: {{count}}" + few: "المواضيع مثبتة حالياً في {{categoryLink}}: {{count}}" + many: "المواضيع مثبتة حالياً في {{categoryLink}}: {{count}}" + other: "المواضيع مثبتة حالياً في {{categoryLink}}: {{count}}" pin_globally: " جعل هذا الموضوع يظهر في أعلى جميع القوائم الموضوع." confirm_pin_globally: "لديك بالفعل {{count}} الموضوعات معقود على الصعيد العالمي. قد تكون عدة مواضيع معلقة عبئا للمستخدمين الجدد والمجهولين. هل أنت متأكد أنك تريد يعلقون موضوع آخر على الصعيد العالمي؟" unpin_globally: "إزالة هذا الموضوع من أعلى لجميع القوائم الموضوع." unpin_globally_until: "أزل هذا الموضوع من أعلى قوائم الموضوعاتاو إنتظر حتى : %{until}." global_pin_note: "يمكن للمستخدمين بفصل موضوع على حدة لأنفسهم. " + not_pinned_globally: "لا توجد مواضيع مثبته عموما" already_pinned_globally: - zero: "لا توجد مواضيع معقود على الصعيد العالمي." - one: "موضوعات معلقة حاليا على الصعيد العالمي: 1." - other: "موضوعات معلقة حاليا على الصعيد العالمي: {{count}}." + zero: "مواضيع مثبتة حاليا : {{count}}" + one: "مواضيع مثبتة حاليا : 1" + two: "مواضيع مثبتة حاليا : {{count}}" + few: "مواضيع مثبتة حاليا : {{count}}" + many: "مواضيع مثبتة حاليا : {{count}}" + other: "مواضيع مثبتة حاليا : {{count}}" make_banner: "أجعل هذا الموضوع يظهر في الإشعار في أعلى كل الصفحة." remove_banner: "إزالة الإشعار الذي يظهر في اعلى الصفحات" banner_note: "المستخدمون يستطعون إبعاد الشعار بأغلاقه. موضوع واحد فقط يبقى كشعار لأي وقت معطى." - already_banner: - zero: "لا يوجد إشعار للموضوع" - one: "هناك شعار موضوع حاليا" + no_banner_exists: "لا يوجد اشعار للموضوع" + banner_exists: "شعار الموضوع هناك حاليا." inviting: "دعوة..." automatically_add_to_groups_optional: "هذه الدعوة تتضمن صلاحيات الدخول على المجموعات : (اختياري , مدير فقط )" automatically_add_to_groups_required: "هذه الدعوة تتضمن صلاحيات الدخول على هذه المجموعات: (يتطلب , مدير" @@ -1281,12 +1393,13 @@ ar: success: "لقد دعونا ذلك المستخدم للمشاركة في هذه الرسالة." error: "للأسف, حدثت مشكلة في دعوة المستخدم" group_name: "اسم المجموعة" + controls: "خصائص الموضوع" invite_reply: title: 'دعوة' username_placeholder: "اسم المستخدم" action: 'ارسال دعوة' help: 'دعوة المستخدمين لهذا الموضوع عن طرق البريد الإلكتروني أو الأشعارات' - to_forum: "سيتم ارسال رسالة بريد الكتروني ﻷصدقائك للمشاركة في هذا الموضوع , لابتطلب تسجيل الدخول" + to_forum: "سيتم ارسال رسالة بريد الكتروني ﻷصدقائك للمشاركة في الموقع , هذه العملية لا تتطلب تسجيل الدخول ." sso_enabled: "أدخل أسم الشخص الذي ترغب بدعوته لهذا الموضوع" to_topic_blank: "أدخل أسم الشخص أو عنوان بريده الإلكتروني لدعوته لهذا الموضوع" to_topic_email: "لقد ادخلت عنوان البريد إلإلكتروني. سنقوم بإرسال دعوة تسمح لصديقك بالرد حالاً على هذا الموضوع." @@ -1378,12 +1491,12 @@ ar: show_full: "عرض كامل المشاركة" show_hidden: 'عرض المحتوى المخفي.' deleted_by_author: - zero: "(مشاركة كُتبت بواسطة كاتب, سوف تحذف تلقائياً خلال أقل من ساعة مالم يُشار اليها)" - one: "(مشاركة كُتبت بواسطة كاتب, سوف تحذف تلقائياً خلال ساعة مالم يُشار اليها)" - two: "(مشاركة كُتبت بواسطة كاتب, سوف تحذف تلقائياً خلال ساعتين مالم يُشار اليها)" - few: "(مشاركة كُتبت بواسطة كاتب, سوف تحذف تلقائياً خلال %{count} ساعات مالم يُشار اليها)" - many: "(مشاركة كُتبت بواسطة كاتب, سوف تحذف تلقائياً خلال %{count} ساعة مالم يُشار اليها)" - other: "(مشاركة كُتبت بواسطة كاتب, سوف تحذف تلقائياً خلال %{count} ساعة مالم يُشار اليها)" + zero: "(المشاركة سحبت بواسطة الكاتب, سوف تحذف تلقائياً خلال أقل من ساعة مالم يُشار اليها)" + one: "(المشاركة سحبت بواسطة الكاتب, سوف تحذف تلقائياً خلال ساعة مالم يُشار اليها)" + two: "(المشاركة سحبت بواسطة الكاتب, سوف تحذف تلقائياً خلال ساعتين مالم يُشار اليها)" + few: "(المشاركة سحبت بواسطة الكاتب, سوف تحذف تلقائياً خلال %{count} ساعات مالم يُشار اليها)" + many: "(المشاركة سحبت بواسطة الكاتب, سوف تحذف تلقائياً خلال %{count} ساعة مالم يُشار اليها)" + other: "(المشاركة سحبت بواسطة الكاتب, سوف تحذف تلقائياً خلال %{count} ساعة مالم يُشار اليها)" expand_collapse: "عرض/إخفاء" gap: zero: "لا يوجد ردود مخفية." @@ -1415,10 +1528,14 @@ ar: few: "أعجب أشخاص قليلون بهذه المشاركة" many: "أعجب أشخاص كثيرون بهذه المشاركة" other: "{{count}} أشخاص أعجبوا بهذه المشاركة" + has_likes_title_only_you: "أنت أعجبت بهذه المشاركة" has_likes_title_you: zero: "أنت أعجبت بهذه المشاركة" - one: "أنت وشخص أخر أعجبتم بهذه المشاركة" - other: "أنت و {{count}} أشخاص أخرون أعجبتم بهذه المشاركة ." + one: "أنت وشخص أخر أعجبتما بهذه المشاركة" + two: "أنت وشخصان أخران أعجبتم بهذه المشاركة" + few: "أنت و {{count}} أشخاص أخرون أعجبتم بهذه المشاركة ." + many: "أنت و {{count}} شخصا أخرون أعجبتم بهذه المشاركة ." + other: "أنت و {{count}} شخص أخرون أعجبتم بهذه المشاركة ." errors: create: "المعذرة، حدثت مشكلة أثناء إنشاء المشاركة. الرجاء المحاولة مرة أخرى." edit: "المعذرة، حدث خطأ أثناء تحرير مشاركتك. الرجاء المحاولة في وقت لاحق." @@ -1438,12 +1555,12 @@ ar: via_email: "وصلت هذه المشاركة من خلال الإيميل" whisper: "هذه المشاركة همسة خاصة للمشرفين" wiki: - about: "هذه المشاركة عبارة عن ويكي بمعنى أنها متاحة للمستخدمين العاديين لتحريرها ، " + about: "هذه المشاركة تعتبر ويكي." archetypes: save: 'حفظ الخيارات' controls: reply: "كتابة رد على هذه المشاركة" - like: "تمام" + like: "أعجبني" has_liked: "لقد تم تسجيل إعجابك بالمشاركة" undo_like: "التراجع عن الإعجاب بهذه المشاركة" edit: "تحرير المشاركة" @@ -1470,6 +1587,7 @@ ar: revert_to_regular: "حذف اللون الوظيفي" rebake: "إعادة بناء HTML" unhide: "إظهار" + change_owner: "تغيير الملكية" actions: flag: 'التبليغات' defer_flags: @@ -1495,17 +1613,14 @@ ar: like: "التراجع عن الإعجاب" vote: "التراجع عن التصويت" people: - off_topic: "{{icons}} بلغ أن هذا لاعلاقة له بالموضوع" - spam: "{{icons}} بلغ انه هذا هو سبام" - spam_with_url: "{{icons}} بُلغ انه غير مرغوب به" - inappropriate: "{{icons}} بلغ أنه غير لائق" - notify_moderators: "{{icons}} تنبيه المشرف" - notify_moderators_with_url: "{{icons}} نبه المشرف" - notify_user: "{{icons}} رسالة مُرسلة." - notify_user_with_url: "{{icons}} أرسلت message ." - bookmark: "{{icons}} اضف في المفضلة" - like: "{{icons}} استحسان" - vote: "{{icons}} صوت لهذا" + off_topic: "أبلغ أن هذا خارج الموضوع." + spam: "علّم على أنّه سبام" + inappropriate: "ابلغ انه غير ملائم " + notify_moderators: "اشعر المشرفين" + notify_user: "ارسل رساله" + bookmark: "اضف الى المفضله" + like: "استحسان" + vote: "صوت لهذا" by_you: off_topic: "لقد تم الإبلاغ عن الموضوع على أنه ليس في المكان الصحيح" spam: "تم الإبلاغ عن الموضوع على أنه سبام" @@ -1629,10 +1744,6 @@ ar: few: "{{count}} أشخاص صوتوا لهذه المشاركة." many: "{{count}} شخص صوتوا لهذه المشاركة." other: "{{count}} شخص صوتوا لهذه المشاركة." - edits: - one: 1 تعديل - other: "{{count}} تعديل" - zero: لايوجد تعديل delete: confirm: zero: "هل أنت متأكد أنك لا تريد حذف تلك المشاركة؟" @@ -1649,6 +1760,7 @@ ar: last: "آخر تعديل" hide: "اخفاء التعديل" show: "اظهار التعديل" + revert: "العوده الى هذا المراجعه" comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" displays: inline: @@ -1705,7 +1817,7 @@ ar: email_in_disabled: "إضافة مواضيع جديدة من خلال البريد الإلكتروني موقف في الوقت الحالي من خلال إعدادات الموقع. لتفعيل إضافة مواضيع جديدة من خلال البريد الإلكتروني," email_in_disabled_click: 'قم بتفعيل خيار "email in" في الإعدادات' suppress_from_homepage: "كتم هذه الفئة من الصفحة الرئيسية" - allow_badges_label: "السماح بالحصول على الشارات في هذا التصنيف" + allow_badges_label: "السماح بالحصول على الأوسمة في هذا التصنيف" edit_permissions: "تعديل الصلاحيات" add_permission: "اضف صلاحية" this_year: "هذه السنة" @@ -1717,19 +1829,18 @@ ar: notifications: watching: title: "مشاهده " - description: "سوف تشاهد تلقائياً كل المواضيع الجديدة في هذه الفئات. سيتم نتبيهك لكل المشاركات والمواضيع الجديدة, وعدد الردود الجديدة على هذه المواضيع سيكون ظاهراً." + description: "ستتم مراقبة جميع المواضيع الجديدة في هذه التصانيف. سيتم اشعارك بجميع المشاركات الجديدة في كل المواضيع، بالاضافة الى عدد الردود الجديدة الذي سيظهر بجانب الموضوع." tracking: title: "تتبع " - description: "سوف تتابع تلقائياً كل المواضيع في هذه الفئات.وعدد الردود الجديدة على هذه المواضيعسكون ظاهراً." + description: "ستتم متابعة جميع المواضيع الجديدة في هذه التصانيف. سيتم اشعارك اذا ذكر احدهم @اسمك او رد عليك، كذلك عدد المشاركات الجديدة سيظهر بجانب الموضوع." regular: - title: "طبيعي" + title: "منتظم" description: "سوف تُنبه اذا قام أحد بالاشارة لاسمك \"@name\" أو الرد عليك." muted: title: "كتم" - description: "لن يتم إشعارك بأي جديد يخص هذا الموضوع ولن يظهرهذا الموضوع في تبويب المواضيع الغير مقروءة." + description: "لن يتم إشعارك بأي مشاركات جديدة في هذه التصنيفات ولن يتم عرضها في قائمة المواضيع المنشورة مؤخراً." flagging: title: 'شكرا لمساعدتك في إبقاء مجتمعنا نظيفاً.' - private_reminder: 'التبليغات ذات خصوصية، تظهر فقط للمشرفين' action: 'التبليغ عن مشاركة' take_action: "أجراء العمليه " notify_action: 'رسالة' @@ -1741,6 +1852,7 @@ ar: submit_tooltip: "إرسال تبليغ" take_action_tooltip: "الوصول إلى الحد الأعلى للتبليغات دون انتظار تبليغات أكثر من أعضاء الموقع." cant: "المعذرة، لا يمكنك التبليغ عن هذه المشاركة في هذه اللحظة." + notify_staff: 'اشعر الطاقم سرياً' formatted_name: off_topic: "خارج عن الموضوع" inappropriate: "غير لائق" @@ -1757,7 +1869,7 @@ ar: notify_action: "رسالة" topic_map: title: "ملخص الموضوع" - participants_title: "مشاركين مكررين" + participants_title: "مشاركين معتادين" links_title: "روابط شائعة." links_shown: "اظهار {{totalLinks}} روابط..." clicks: @@ -1783,7 +1895,7 @@ ar: help: "هذا الموضوع غير مثبت بالنسبة لك, سيتم عرضه بالترتيب العادي" pinned_globally: title: "تثبيت عام" - help: "هذا الموضوع مثبت بشكل عام, سوف يظهر في المقدمة في جميع القوائم" + help: "هذا الموضوع مثبت بشكل عام, سوف يظهر في مقدمة المواضيع بآخر المشاركات وفي الفئة الخاصة به" pinned: title: "مثبت" help: "هذا الموضوع مثبت لك, سوف يتم عرضه في اول القسم" @@ -1838,9 +1950,13 @@ ar: with_topics: "%{filter} مواضيع" with_category: "%{filter} %{category} مواضيع" latest: - title: - zero: "الأخير" - one: "الآخر (1)" + title: "اخر المواضيع" + title_with_count: + zero: "اخر المواضيع (1)" + one: "اخر المواضيع (1)" + two: "الآخر ({{count}})" + few: "الآخر ({{count}})" + many: "الآخر ({{count}})" other: "الآخر ({{count}})" help: "مواضيع بآخر المشاركات" hot: @@ -1857,22 +1973,38 @@ ar: title_in: "قسم - {{categoryName}}" help: "جميع المواضيع تتبع القسم" unread: - title: - zero: "غير مقروء" - one: "غير مقروء (1)" + title: "غير مقروء" + title_with_count: + zero: "غير مقروء (1)" + one: "غيرمقروء( 1)" + two: "غير مقروء ({{count}})" + few: "غير مقروء {({count}})" + many: "غير مقروء ({{count}})" other: "غير مقروء ({{count}})" help: "مواضيع أنت تشاهدها بمشاركات غير مقروءة " lower_title_with_count: + zero: "1 غير مقررء " one: "1 غير مقروء" + two: "{{count}} غير مقروء " + few: "{{count}} غير مقروء " + many: "{{count}} غير مقروء" other: "{{count}} غير مقروء" new: lower_title_with_count: + zero: "لا جديد" one: "1 جديد" + two: "{{count}} جديد" + few: "{{count}} جديد" + many: "{{count}} جديد" other: "{{count}} جديد" lower_title: "جديد" - title: - zero: "جديد" + title: "جديد" + title_with_count: + zero: "لا جديد" one: "جديد (1)" + two: "جديد ({{count}})" + few: "جديد ({{count}})" + many: "جديد ({{count}})" other: "جديد ({{count}})" help: "مواضيع جديد في الايام السابقة" posted: @@ -1882,9 +2014,13 @@ ar: title: "المفضلة" help: "مواضيع قمت بتفضيلها" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: + zero: "{{categoryName}} (1)" one: "{{categoryName}} (1)" + two: "{{categoryName}} ({{count}})" + few: "{{categoryName}} ({{count}})" + many: "{{categoryName}} ({{count}})" other: "{{categoryName}} ({{count}})" help: "آخر المواضيع في {{categoryName}} قسم" top: @@ -1965,6 +2101,7 @@ ar: refresh_report: "تحديث التقرير " start_date: "تاريخ البدء" end_date: "تاريخ الإنتهاء" + groups: "جميع الفئات" commits: latest_changes: "آخر تغيير: يرجى التحديث" by: "بواسطة" @@ -2010,7 +2147,7 @@ ar: error: "حدث خطأ ما" reply_message: "الرد" no_results: "لا يوجد بلاغات." - topic_flagged: "هذا topic قد عُلِّم." + topic_flagged: "هذا الموضوع قد عُلِّم." visit_topic: "زيارة الموضوع لاتخاذ قرار" was_edited: "تم تعديل المشاركة بعد أول بلاغ" previous_flags_count: "هذه المشاركة قد سبق الإشارة إليها {{count}} مرات." @@ -2065,15 +2202,24 @@ ar: delete_confirm: "حذف هذة المجموعة؟" delete_failed: "لا يمكن حذف هذه المجموعة. اذا كانت هذة المجموعة مجموعة تلقائية, لا يمكن حذفها." delete_member_confirm: "ازالة '%{username}' من '%{group}' المجموعة?" + delete_owner_confirm: "هل تريد إزالة صلاحيات الإدارة من '%{username} ؟" name: "الاسم" add: "اضافة" add_members: "اضافة عضو" custom: "مخصص" + bulk_complete: "تم اضافة المستخدم/المستخدمين الى المجموعة" + bulk: "اضافة زمرة الى مجموعة" + bulk_paste: "اكتب قائمة من اسماء المستخدمين او البريد الالكتروني ، واحد في كل سطر :" + bulk_select: "(اختر مجموعة)" automatic: "تلقائي" automatic_membership_email_domains: "المستخدمين الذين يمتلكون بريد الالكتروني عنوانه مطابق للعنوان الذي في القائمة سيتم تلقائيا اضافتهم للمجموعة." automatic_membership_retroactive: "اضافة الاعضاء الذين يمتكلون عنوان ايميل مطابق للعنوان الموجود في القائمة." default_title: "عنوان افتراضي لكل أعضاء هذه المجموعة." primary_group: "تلقيائاً ضعها كمجموعة أساسية." + group_owners: الملّاك + add_owners: اضف ملّاكً + incoming_email: "تعيين بريد إلكتروني خاص:" + incoming_email_placeholder: "يرجى إدخال بريد الكتروني فعّال." api: generate_master: "Generate Master API Key" none: "There are no active API keys right now" @@ -2087,7 +2233,7 @@ ar: confirm_revoke: "هل أنت متأكد من رغبتك في تعطيل هذا المفتاح؟" info_html: "Your API key will allow you to create and update topics using JSON calls." all_users: "جميع المستخدمين" - note_html: "Keep this key secret, all users that have it may create arbitrary posts as any user." + note_html: "حافظ على سرية هذا المفتاح، اي شخص يحصل عليه يستطيع انشاء مواضيع باسم اي مستخدم اخر" plugins: title: "اضافات" installed: "اضافات مثيته" @@ -2147,11 +2293,11 @@ ar: is_disabled: "Restore is disabled in the site settings." label: "استعادة" title: "اعادة تخزين النسخة الاحتياطية" - confirm: "هل أنت متأكد من رغبتك في اعادة تخزين النسخة الاحتياطية؟" + confirm: "هل انت متاكد انك تريد استعاده هذه النسخه الاحتياطيه؟" rollback: label: "اعادة السنخة السابقة" title: "Rollback the database to previous working state" - confirm: "Are your sure you want to rollback the database to the previous working state?" + confirm: "هل انت متاكد انك تريد اعاده قواعد البيانات الى الحاله السابقه؟" export_csv: user_archive_confirm: "هل أنت متأكد من رغبتك في تحميل جميع مشاركاتك ؟" success: "بدأ التصدير, سيتم إعلامك برسالة عند اكتمال العملية." @@ -2193,7 +2339,7 @@ ar: explain_rescue_preview: "مشاهدة الموقع بالشكل الافتراضي" save: "حفظ" new: "جديد" - new_style: "ثيم جديد" + new_style: "تصميم جديد" import: "استيراد" import_title: "حدد ملف او انسخ نص" delete: "حذف" @@ -2202,6 +2348,14 @@ ar: color: "Color" opacity: "Opacity" copy: "نسخ" + email_templates: + title: "قالب البريد الالكتروني " + subject: "الموضوع" + multiple_subjects: "قالب البريد الإلكتروني هذا لديه موضوعات متعددة." + body: "المحتوى" + none_selected: "اختر قالب بريد الكتروني لتبدا بتعديله " + revert: "اعاده التغيرات " + revert_confirm: "هل انت متاكد من انك تريد اعاده التغيرات؟ " css_html: title: "CSS/HTML" long_title: "CSS and HTML Customizations" @@ -2209,7 +2363,7 @@ ar: title: "اللون" long_title: "نمط الألوان" about: "Modify the colors used on the site without writing CSS. Add a scheme to start." - new_name: "New Color Scheme" + new_name: "نمط ألوان جديد" copy_name_prefix: "نسخة من" delete_confirm: "حذف جميع الالوان؟" undo: "تراجع" @@ -2246,18 +2400,18 @@ ar: love: name: 'إعجاب' description: "لون زر الإعجاب." - wiki: - name: 'ويكي' - description: "اللون الأساسي المستخدم كخلفية لمشاركات الويكي." email: - title: "بريد الكتروني" + title: "رسائل البريد الالكتروني" settings: "اعدادات" - all: "الكل" + templates: "نماذج" + preview_digest: "ملخص المعاينة." sending_test: "إرسال بريد إلكتروني للتجربة..." error: "خطأ - %{server_error}" test_error: "حدث خطأ أثناء إرسال رسالة تجريبية. الرجاء فحص إعدادات البريد الإلكتروني و التأكد من أن الاستضافة لا تمنع مرور البريد الإلكتروني والمحاولة مرة أخرى." sent: "تم الإرسال" skipped: "تم التجاوز" + received: "وارد" + rejected: "مرفوض" sent_at: "أرسلت في" time: "الوقت" user: "المستخدم" @@ -2267,7 +2421,6 @@ ar: send_test: "ارسل رسالة تجربة" sent_test: "اٌرسلت!" delivery_method: "طريقة التسليم" - preview_digest: "معاينة الخلاصة." preview_digest_desc: "معاينة محتوى رسائل البريد الإلكتروني الملخص المرسلة للأعضاء الغير متاحين." refresh: "تحديث" format: "التنسيق" @@ -2276,6 +2429,25 @@ ar: last_seen_user: "آخر مستخدم تواجد:" reply_key: "مفتاح الرد" skipped_reason: "تجاوز السبب" + incoming_emails: + from_address: "من" + to_addresses: "الى" + cc_addresses: "Cc" + subject: "موضوع" + error: "خطأ" + none: "لا يوجد بريد وارد" + modal: + title: "تفاصيل الرسائل الوارده" + error: "خطأ" + subject: "الموضوع" + body: "المحتوى" + rejection_message: "البريد المحظور" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "موضوع..." + error_placeholder: "خطأ" logs: none: "لا يوجد سجلات." filters: @@ -2294,6 +2466,7 @@ ar: ip_address: "IP" topic_id: "رقم معرّف الموضوع" post_id: "رقم المشاركة" + category_id: "معرف الفئة" delete: 'حذف' edit: 'تعديل' save: 'حفظ' @@ -2324,6 +2497,7 @@ ar: change_site_setting: "تغيير اعدادات الموقع" change_site_customization: "تخصيص الموقع" delete_site_customization: "حذف هذا التخصيص؟" + change_site_text: "تغيير نص الموقع." suspend_user: "حظر المستخدم" unsuspend_user: "رفع الحظر " grant_badge: "منح شارة" @@ -2334,6 +2508,16 @@ ar: impersonate: "إنتحال" anonymize_user: "مستخدم مجهول" roll_up: "عناوين IP المتغيرة المحظورة" + change_category_settings: "تغيير إعدادات الفئة" + delete_category: "حذف الفئة" + create_category: "أنشئ فئة" + block_user: "حظر" + unblock_user: "رفع الحظر" + grant_admin: "منح صلاحيات ادارية" + revoke_admin: "سحب الصلاحيات الادارية" + grant_moderation: "عين كمشرف" + revoke_moderation: "سحب صلاحيات المشرف" + backup_operation: "عمليه النسخ الاحتياطي" screened_emails: title: "عناوين بريد إلكتروني محجوبة." description: "عندما تتم محاول انشاء حساب جديد, سيتم التحقق من قائمة البريد الالكتروني وسيتم حظر التسجيل لهذا البريد واتخاذ اي اجراء متبع" @@ -2357,7 +2541,7 @@ ar: do_nothing: "سماح" allow_admin: "سماح المدير" form: - label: "جديد" + label: "جديد:" ip_address: "عناوين الIP" add: "اضافة" filter: "بحث" @@ -2408,9 +2592,9 @@ ar: pending: 'أعضاء بانتظار المراجعة' newuser: 'أعضاء في مستوى الثقة 0 (عضو جديد)' basic: 'أعضاء في مستوى الثقة 1 (عضو أساسي)' - regular: 'أعضاء في مستوى الثقة 2 (منتسب)' - leader: 'أعضاء في مستوى الثقة 3 (منتظم)' - elder: 'أعضاء في مستوى الثقة 4 (قائد)' + member: 'الاعضاء في مستوى الثقة رقم 2 (أعضاء)' + regular: 'الاعضاء في مستوى الثقة رقم 3 (عاديين)' + leader: 'الاعضاء في مستوى الثقة رقم 4 (قادة)' staff: "طاقم" admins: 'مستخدمين مدراء' moderators: 'مراقبين' @@ -2451,6 +2635,7 @@ ar: moderator: "مراقب؟" admin: "مدير؟" blocked: "محظور؟" + staged: "تنظيم؟" show_admin_profile: "مدير" edit_title: "تعديل العنوان" save_title: "حفظ العنوان" @@ -2527,9 +2712,12 @@ ar: deactivate_failed: "حدث خطأ عند تعطيل هذا المستخدم." unblock_failed: 'حدث خطأ عند الغاء حظر هذا المستخدم.' block_failed: 'حدث خطأ عند حظر هذا المستخدم.' + block_confirm: 'هل انت متأكد من حظر هذا المستخدم؟ لن يستطيع انشاء مواضيع او ردود جديدة' + block_accept: 'نعم, حظر هذا المستخدم' deactivate_explanation: "المستخدم الغير نشط يحب أن يتأكد من البريد الالكتروني" suspended_explanation: "المستخدم الموقوف لايملك صلاحية تسجيل الدخول" block_explanation: "المستخدم الموقوف لايستطيع أن يشارك" + stage_explanation: "العضو المنظم يمكنه فقط النشر عن طريق البريد الالكتروني في المواضيع المخصصه ." trust_level_change_failed: "هناك مشكلة في تغيير مستوى ثقة المستخدم " suspend_modal_title: "حظر المستخدم" trust_level_2_users: "أعضاء مستوى الثقة 2." @@ -2540,7 +2728,7 @@ ar: unlock_trust_level: "فتح مستوى الثقة " tl3_requirements: title: "المتطلبات لمستوى الثقة 3." - table_title: "في آخر 100 يوم" + table_title: "في أخر %{time_period} أيام:" value_heading: "تصويت" requirement_heading: "متطلبات" visits: "الزيارات" @@ -2601,8 +2789,15 @@ ar: confirm: 'تأكيد' dropdown: "القائمة المنسدلة" site_text: - none: "اختر نوع المحتوى المراد تعديله" + description: "يمكنك تخصيص اي نص في مدونتك . الرجاء البدء بالبحث في الاسفل:" + search: "ابحث عن النص الذي تريد تعديله" title: 'محتوى النص' + edit: 'تعديل' + revert: "حفظ التعديلات" + revert_confirm: "هل انت متاكد من انك تريد اعاده التغيرات؟ " + go_back: "العودة إلى البحث" + recommended: "نوصيك بتخصيص النص التالي ليلائم احتياجاتك:" + show_overriden: 'اظهر التجاوزات فقط' site_settings: show_overriden: 'تظهر فقط تجاوز' title: 'اعدادات' @@ -2658,14 +2853,14 @@ ar: revoke_confirm: هل أنت متأكد أنك تريد سحب هذه الشارة؟ edit_badges: 'تعديل الشعارات ' grant_badge: منح شارة - granted_badges: شارات ممنوحة. + granted_badges: أوسمة ممنوحة. grant: منحة no_user_badges: "%{name} لم يمنح أي شارة." no_badges: لا يوجد أي شارة يمكن منحها. none_selected: "حدد شارة البدء" allow_title: اسمح للشارة أن تستخدم كعنوان. multiple_grant: 'يمكن منحه عدة مرات. ' - listable: اظهار الشارة على صفحة الشارات العامة + listable: اظهار الوسام على صفحة الأوسمة العامة enabled: تفعيل الشعار icon: أيقونة image: صورة @@ -2673,7 +2868,7 @@ ar: query: علامة استفهام (SQL) target_posts: إستعلام يستهدف المشاركات auto_revoke: إلغاء الاستعلام اليومي - show_posts: عرض مشاركة الشارات الممنوحة على صفحة الشارات. + show_posts: عرض مشاركة الوسام الممنوح على صفحة الوسام. trigger: مطلق trigger_type: none: "تحديث يومي" @@ -2682,18 +2877,22 @@ ar: trust_level_change: "عندما يقوم شخص بتغير مستوى الثقة." user_change: "عندما يتم تعديل عضو أو انشاءه." preview: - link_text: "معاينة الشارات الممنوحة." + link_text: "معاينة الأوسمة الممنوحة." plan_text: "معاينة مع خطة الاستعلام." modal_title: "معاينة علامة استفهام" sql_error_header: "كان هناك خطأ ما في الاستعلام." - error_help: "انظر الرابط التالي للمساعدة بالاستفسارات الشارات." + error_help: "انظر الرابط التالي للمساعدة باستفسارات الوسام." bad_count_warning: header: "تحذير !!" text: "هناك عينات ممنوحة ضائعة. حدث هذا عندما أعادت شارة الإستعلام user IDs أو post IDs التي لم تكن موجودة. هذا ربما بسبب نتيجة غير متوقعة في وقت لاحق - رجائا أنقر مرتين للتأكد من إستعلامك-" + no_grant_count: "لا توجد اوسمه لتمنح " grant_count: - zero: "لا شارات لكي تعيّن." - one: "1 شارة لكي تعين." - other: "%{count} شارات بكي تعين." + zero: "%{count} وساما لتمنح ." + one: "وسام واحد ليتم منحه ." + two: "وسامين ليتم منحهما ." + few: "%{count} أوسمة لتمنح ." + many: "%{count} وساما لتمنح ." + other: "%{count} وساما لتمنح ." sample: "أمثلة:" grant: with: %{أسم المستخدم} @@ -2773,7 +2972,7 @@ ar: title: 'التطبيقات' create: 'c انشاء موضوع جديد' notifications: 'n فتح الإشعارات' - hamburger_menu: '= فتح قائمة hamburger' + hamburger_menu: '= فتح قائمة الموقع' user_profile_menu: 'pأفتح قائمة المستخدم' show_incoming_updated_topics: '. عرض المواضيع المحدثة' search: '/ البحث' @@ -2801,16 +3000,21 @@ ar: mark_tracking: 'm, t تابع الموضوع' mark_watching: 'm, w شاهد الموضوع' badges: - title: شارات - allow_title: "يمكن استخدامه كعنوان" - multiple_grant: "يمكن منحه عدة مرات. " + earned_n_times: + zero: "لم يحصل على هذه الشاره ولا مره" + one: "استحق هذه الشاره مره واحده" + two: "استحق هذه الشاره مرتين" + few: "استحق هذه الشاره %{count} مرات" + many: "استحق هذه الشاره %{count} مرات" + other: "استحق هذه الشاره %{count} مرات" + title: أوسمة badge_count: zero: "%{count} شاره" one: "%{count} شاره" two: "%{count} شاراتين" - few: "%{count} شارات" - many: "%{count} شارات" - other: "%{count} شارات" + few: "%{count} أوسمة" + many: "%{count} أوسمة" + other: "%{count} أوسمة" more_badges: zero: "+%{count} المزيد" one: "+%{count} المزيد" @@ -2825,7 +3029,7 @@ ar: few: "%{count} ممنوحات." many: "%{count} ممنوحات." other: "%{count} ممنوحات." - select_badge_for_title: حدد شعار لإستخدامه كعنوان + select_badge_for_title: حدد وسام لتستخدمه كعنوانك none: "لا شئ" badge_grouping: getting_started: @@ -2838,97 +3042,6 @@ ar: name: الجميع posting: name: نشر - badge: - editor: - name: محرر - description: أول موضوع تم تحريره - basic_user: - name: أساسي - description: منح جميع وظائف المجتمع الأساسية. - member: - name: عضو - description: مُنح دعوات - regular: - name: منتظم - description: منح اعادة تصنيف, اعادة تسمية, اتباع الروابط - leader: - name: قائد - description: منح تحرير عام, تثبيت, اغلاق, ارشفة, تقسيم ودمج - welcome: - name: مرحباً - description: تلقيت إعجاب - autobiographer: - name: الكاتب سيرته بنفسه - description: تصفية عضو ملف التعريفمعلومات - anniversary: - name: ذكرى - description: عضو نشط لمدة عام، شارك مرة واحدة على الأقل - nice_post: - name: مشاركة رائعة - description: 'تلقيت 10 إعجاب لهذه المشاركة . هذا الاشعار يتم إرسالة مرات عديدة ' - good_post: - name: مشاركة جيدة - description: تلقيت 25 إعجاب لهذه المشاركة . هذا الاشعار يتم إرسالة مرات عديدة - great_post: - name: مشاركة ممتازة - description: تلقيت 50 إعجاب لهذه المشاركة . هذا الاشعار يتم إرسالة مرات عديدة - nice_topic: - name: 'موضوع رائع ' - description: تلقيت 10 إعجاب لهذا الموضوع . هذا الاشعار يتم إرسالة مرات عديدة - good_topic: - name: موضوع جيد - description: تلقيت 25 إعجاب لهذا الموضوع . هذا الاشعار يتم إرسالة مرات عديدة - great_topic: - name: موضوع ممتاز - description: 'تلقيت 50 إعجاب لهذا الموضوع . هذا الاشعار يتم إرسالة مرات عديدة ' - nice_share: - name: مشاركة رائعة - description: تم مشاركة رد مع أكثر من 25 زائر - good_share: - name: مشاركة جيدة - description: تم مشاركة رد مع أكثر من 300 زائر - great_share: - name: مشاركة ممتازة - description: تم مشاركة رد مع أكثر من 1000 زائر - first_like: - name: اول اعجاب - description: أعجب في رد - first_flag: - name: اول بلاغ - description: مشاركة مبلغ عنها - promoter: - name: متعهد - description: دعوة مستخدم - campaigner: - name: ناشط - description: تم دعوة 3 أعضاء (مستوى الثقة 1) - champion: - name: بطل - description: تم دعوة 5 أعضاء (مستوى الثقة 2) - first_share: - name: اول مشاركة - description: مشاركة تعليق - first_link: - name: الرابط الأول - description: اضافة رابط لموضوع اخر - first_quote: - name: التعليق الأول - description: إقتباسات - read_guidelines: - name: اقرأ التعليمات - description: اطلع على توجيهات المجتمع - reader: - name: قارئ - description: قراءة أكثر من 100 تعليق في الموضوع - popular_link: - name: رابط مشهور - description: شارك رابط خارجي بـ 50 نقرة على الأقل. - hot_link: - name: الرابط الساخن - description: شارك الرابط الخارجي بـ 300 نقرة على الأقل. - famous_link: - name: رابط مشهور - description: شارك الرابط الخارجي بـ 1000 نقرة على الأقل google_search: |

    ابحث في قوقل

    diff --git a/config/locales/client.bs_BA.yml b/config/locales/client.bs_BA.yml index 2083dcfee35..d25b537c041 100644 --- a/config/locales/client.bs_BA.yml +++ b/config/locales/client.bs_BA.yml @@ -8,6 +8,9 @@ bs_BA: js: number: + format: + separator: "." + delimiter: "," human: storage_units: format: '%n %u' @@ -20,6 +23,9 @@ bs_BA: kb: KB mb: MB tb: TB + short: + thousands: "{{number}} hiljada" + millions: "{{number}} miliona" dates: time: "h:mm a" long_no_year: "MMM D h:mm a" @@ -88,12 +94,12 @@ bs_BA: few: "Prije par godina" other: "%{count} godine/a prije" share: - topic: 'podjeli link ka ovoj temi' - post: 'podjeli link ka ovom postu #%{postNumber}' + topic: 'podijeli link ka ovoj temi' + post: 'podijeli link ka ovom postu #%{postNumber}' close: 'zatvori' - twitter: 'podjeli link na Twitteru' - facebook: 'podjeli link na Facebooku' - google+: 'podjeli link na Google+' + twitter: 'podijeli link na Twitteru' + facebook: 'podijeli link na Facebook-u' + google+: 'podijeli link na Google+' email: 'pošalji ovaj link na email' topic_admin_menu: "topic admin actions" edit: 'izmjeni naslov i kategoriju ove teme' @@ -220,7 +226,6 @@ bs_BA: few: "Ova tema ima {{count}} postova koji čekaju odobrenje" other: "Ova tema ima {{count}} postova koji čekaju odobrenje" confirm: "Sačuvaj promjene" - delete_prompt: "Jeste li sigurni da želite izbrisati %{username}? Ovo će izbrisati sve njihove postove i blokirati njihovu email i IP adresu." approval: title: "Post treba odobrenje" description: "Primili smo Vaš novi post ali on treba biti odobren od strane moderatora prije nego bude javno dostupan. Molimo budite strpljivi." @@ -261,7 +266,6 @@ bs_BA: members: "Članovi" posts: "Postovi" alias_levels: - title: "Who can use this group as an alias?" nobody: "Niko" only_admins: "Samo admini" mods_and_admins: "Samo moderatori i Admini" @@ -276,7 +280,6 @@ bs_BA: '6': "Odgovori" '7': "Spemenute" '9': "Citirane" - '10': "Označene" '11': "Izmjenjene" '12': "Poslato" '13': "Inbox" @@ -332,7 +335,6 @@ bs_BA: watched_categories: "Watched" tracked_categories: "Tracked" muted_categories: "Muted" - muted_categories_instructions: "You will not be notified of anything about new topics in these categories, and they will not appear on your unread tab." delete_account: "Delete My Account" delete_account_confirm: "Are you sure you want to permanently delete your account? This action cannot be undone!" deleted_yourself: "Your account has been deleted successfully." @@ -346,8 +348,6 @@ bs_BA: warnings_received: "warnings" messages: all: "Sve" - mine: "Moje" - unread: "Nepročitane" change_password: success: "(email poslat)" in_progress: "(šaljem email)" @@ -436,7 +436,6 @@ bs_BA: search: "kucaj da potražiš pozivnice..." title: "Pozivnice" user: "Pozvan Korisnik" - truncated: "Showing the first {{count}} invites." redeemed: "Redeemed Invites" redeemed_at: "Redeemed" pending: "Pending Invites" @@ -500,7 +499,6 @@ bs_BA: close: "Zatvori" assets_changed_confirm: "Ovaj sajt je upravo unaprijeđen. Osvježi stranicu za novu verziju?" read_only_mode: - enabled: "An administrator enabled read-only mode. You can continue to browse the site but interactions may not work." login_disabled: "Login is disabled while the site is in read only mode." learn_more: "learn more..." year: 'godina' @@ -516,8 +514,6 @@ bs_BA: last_post: Zadnji post summary: enabled_description: "You're viewing a summary of this topic: the most interesting posts as determined by the community." - description: "There are {{count}} replies." - description_time: "There are {{count}} replies with an estimated read time of {{readingTime}} minutes." enable: 'Summarize This Topic' disable: 'Show All Posts' deleted_filter: @@ -615,7 +611,6 @@ bs_BA: edit_reason_placeholder: "zašto pravite izmjenu?" show_edit_reason: "(dodaj razlog izmjene)" view_new_post: "Pogledaj svoj novi post." - saving: "Čuvam..." saved: "Sačuvano!" saved_draft: "Imate sačuvan post. Kliknite ovdje da nastavite sa izmjenama" uploading: "Uplodujem..." @@ -642,8 +637,6 @@ bs_BA: heading_title: "Naslov" heading_text: "Naslov" hr_title: "Horizontalna Crta" - undo_title: "Poništi" - redo_title: "Povrati" help: "Markdown Editing Help" toggler: "sakrij ili pokaži komposer" admin_options_title: "Optional staff settings for this topic" @@ -664,7 +657,6 @@ bs_BA: mentioned: "@

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -679,7 +671,6 @@ bs_BA: from_my_computer: "Sa mog uređaja" from_the_web: "Sa neta" remote_tip: "link do slike http://primjer.com/slika.jpg" - remote_tip_with_attachments: "link to image or file http://primjer.com/file.ext (allowed extensions: {{authorized_extensions}})." hint: "(možete i mišom prenijeti vaše slike direktno iz vašeg foldera ovdje)" uploading: "Uplodujem" image_link: "link do vaše slike će pokazivati" @@ -699,10 +690,6 @@ bs_BA: bulk: reset_read: "Reset Read" delete: "Delete Topics" - dismiss_posts: "Dismiss Posts" - dismiss_posts_tooltip: "Clear unread counts on these topics but continue to show them on my unread list when new posts are made" - dismiss_topics: "Dismiss Topics" - dismiss_topics_tooltip: "Stop showing these topics in my unread list when new posts are made" dismiss_new: "Dismiss New" toggle: "toggle bulk selection of topics" actions: "Bulk Actions" @@ -719,9 +706,6 @@ bs_BA: hot: "Nema popularnih tema." category: "Nema više tema u {{category}}." top: "Nema više popularnih tema." - educate: - new: '

    Tvoje nepročitane teme se pojavljuju ovdje.

    Nove teme imaju nova indikaciju.

    Možete promjeniti notifikacije preko vaših postavki.

    ' - unread: '

    Tvoje nepročitane teme se pojavljuju ovdje.

    Ako imate nepročitanih postova vidjet ćete njihov broj 1 ako ste:

    • Kreirali tu temu
    • Odgovorili na tu temu
    • Proveli čitajući temu više od 4 minuta

    Ili ako ste na dnu teme označili da motrite i pratite temu.

    Možete promjeniti notifikacije preko vaših postavki.

    ' bottom: latest: "Nema više novih tema." hot: "Nema više popularnih tema." @@ -788,6 +772,8 @@ bs_BA: '2_4': 'Dobijat ćete notifikacije zato što ste ostavili odgovor na ovoj temi.' '2_2': 'Dobijat ćete notifikacije zato što pratite ovu temu.' '2': 'Dobijat ćete notifikacije zato što pročitao ovu temu.' + '1_2': 'Dobiti ćete notifikaciju kada neko spomene tvoje @name ili odgovori na tvoj post.' + '1': 'Dobiti ćete notifikaciju kada neko spomene tvoje @name ili odgovori na tvoj post.' '0_7': 'Ignorišete sve notifikacije u ovoj kategoriji.' '0_2': 'Ignorišete sve notifikacije u ovoj temi.' '0': 'Ignorišete sve notifikacije u ovoj temi.' @@ -799,12 +785,17 @@ bs_BA: title: "Praćenje" tracking: title: "Praćenje" + regular: + title: "Regularan" + description: "Dobiti ćete notifikaciju kada neko spomene tvoje @name ili odgovori na tvoj post." + regular_pm: + title: "Regularan" + description: "Dobiti ćete notifikaciju kada neko spomene tvoje @name ili odgovori na tvoj post." muted_pm: title: "Mutirano" description: "You will never be notified of anything about this private message." muted: title: "Mutirano" - description: "Obaviještenja za ovu temu su isključena i sistem vam neće prikazivati nove postove za ovu temu." actions: recover: "Un-Delete Topic" delete: "Delete Topic" @@ -819,6 +810,9 @@ bs_BA: invisible: "Make Unlisted" visible: "Make Listed" reset_read: "Reset Read Data" + feature: + pin: "Prikači temu" + unpin: "Otkači temu" reply: title: 'Odgovori' help: 'počni sa pisanjem odgovora na ovu temu' @@ -832,6 +826,8 @@ bs_BA: title: 'Opomena' help: 'anonimno prijavi ovu temu ili pošalji privatnu notifikaciju' success_message: 'Uspješno ste opomenuli ovu temu.' + feature_topic: + title: "Istakni ovu temu." inviting: "Inviting..." automatically_add_to_groups_optional: "This invite also includes access to these groups: (optional, admin only)" automatically_add_to_groups_required: "This invite also includes access to these groups: (Required, admin only)" @@ -907,8 +903,6 @@ bs_BA: no_value: "Ne, sačuvaj" yes_value: "Da, otkaži" via_email: "this post arrived via email" - wiki: - about: "this post is a wiki; basic users can edit it" archetypes: save: 'Save Options' controls: @@ -950,17 +944,6 @@ bs_BA: bookmark: "Otkaži bookmark" like: "Otkaži lajk" vote: "Otkaži glas" - people: - off_topic: "{{icons}} označio ka ne-relevatno" - spam: "{{icons}} označio kao spam" - inappropriate: "{{icons}} flagged this as inappropriate" - notify_moderators: "{{icons}} notified moderators" - notify_moderators_with_url: "{{icons}} notified moderators" - notify_user: "{{icons}} sent a private message" - notify_user_with_url: "{{icons}} sent a private message" - bookmark: "{{icons}} bookmarked this" - like: "{{icons}} lajkovali ovo" - vote: "{{icons}} glasali za ovo" by_you: off_topic: "You flagged this as off-topic" spam: "Opomenuo si ovo kao spam" @@ -970,10 +953,6 @@ bs_BA: bookmark: "You bookmarked this post" like: "Lajkovao si ovo" vote: "Glasao si za ovaj post" - edits: - one: 1 edit - other: "{{count}} edits" - zero: no edits revisions: controls: first: "First revision" @@ -1045,10 +1024,10 @@ bs_BA: tracking: title: "Praćenje" regular: - title: "Regularno" + title: "Regularan" + description: "Dobiti ćete notifikaciju kada neko spomene tvoje @name ili odgovori na tvoj post." muted: title: "Mutirano" - description: "You will not be notified of anything about new topics in these categories, and they will not appear on your unread tab." flagging: title: 'Zašto prijavljujete ovaj post?' action: 'Opomeni Post' @@ -1087,7 +1066,6 @@ bs_BA: help: "This topic is unpinned; it will display in default order" pinned_globally: title: "Zakačena Globalno" - help: "Ova tema je zakačena globalno; biće na vrhu svih listi" pinned: title: "Zakačena" help: "Ova tema je zakačena; biće na vrhu svoje kategorije" @@ -1130,32 +1108,14 @@ bs_BA: title_in: "Kategorija - {{categoryName}}" help: "sve teme grupisane po kategoriji" unread: - title: - zero: "Nepročitane" - one: "Nepročitane (1)" - other: "Nepročitane ({{count}})" help: "teme koje trenutno pratite i motrite sa nepročitanim postovima" - lower_title_with_count: - one: "1 nepročitana" - other: "{{count}} nepročitanih" new: - lower_title_with_count: - one: "1 nova" - other: "{{count}} novih" lower_title: "nova" - title: - zero: "Nove Teme" - one: "Nova Tema (1)" - other: "Nove Teme ({{count}})" help: "teme kreirane u zadnjih nekoliko dana" posted: title: "Moji Odgovori" help: "teme u kojima imate postove" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" - other: "{{categoryName}} ({{count}})" help: "zadnje teme u {{categoryName}} kategoriji" top: title: "Popularne" @@ -1329,10 +1289,8 @@ bs_BA: restore: is_disabled: "Restore is disabled in the site settings." title: "Restore the backup" - confirm: "Are your sure you want to restore this backup?" rollback: title: "Rollback the database to previous working state" - confirm: "Are your sure you want to rollback the database to the previous working state?" export_csv: success: "Export has been initiated, you will be notified shortly with progress." failed: "Export failed. Please check the logs." @@ -1402,13 +1360,9 @@ bs_BA: love: name: 'love' description: "The like button's color." - wiki: - name: 'wiki' - description: "Base color used for the background of wiki posts." email: - title: "Email" settings: "Settings" - all: "All" + preview_digest: "Pregled Sajta" sending_test: "Sending test Email..." test_error: "There was a problem sending the test email. Please double-check your mail settings, verify that your host is not blocking mail connections, and try again." sent: "Sent" @@ -1422,7 +1376,6 @@ bs_BA: send_test: "Send Test Email" sent_test: "sent!" delivery_method: "Delivery Method" - preview_digest: "Pregled Sajta" refresh: "Refresh" format: "Format" html: "html" @@ -1531,9 +1484,6 @@ bs_BA: pending: 'Users Pending Review' newuser: 'Users at Trust Level 0 (New User)' basic: 'Users at Trust Level 1 (Basic User)' - regular: 'Users at Trust Level 2 (Member)' - leader: 'Users at Trust Level 3 (Regular)' - elder: 'Users at Trust Level 4 (Leader)' admins: 'Admin Users' moderators: 'Moderators' blocked: 'Blocked Users' @@ -1621,7 +1571,6 @@ bs_BA: unlock_trust_level: "Unlock Trust Level" tl3_requirements: title: "Requirements for Trust Level 3" - table_title: "In the last 100 days:" value_heading: "Value" requirement_heading: "Requirement" visits: "Visits" @@ -1676,7 +1625,6 @@ bs_BA: text: 'Text Field' confirm: 'Confirmation' site_text: - none: "Choose a type of content to begin editing." title: 'Text Content' site_settings: show_overriden: 'Only show overridden' @@ -1755,10 +1703,6 @@ bs_BA: bad_count_warning: header: "WARNING!" text: "There are missing grant samples. This happens when the badge query returns user IDs or post IDs that do not exist. This may cause unexpected results later on - please double-check your query." - grant_count: - zero: "No badges to be assigned." - one: "1 badge to be assigned." - other: "%{count} badges to be assigned." sample: "Sample:" grant: with: %{username} @@ -1813,8 +1757,6 @@ bs_BA: mark_watching: 'm, w Motri temu' badges: title: Bedževi - allow_title: "allow badge as title?" - multiple_grant: "awarded multiple times?" select_badge_for_title: Izaveri bedž za svoj naslov none: "" badge_grouping: @@ -1828,78 +1770,3 @@ bs_BA: name: Drugi posting: name: Postiranje - badge: - editor: - name: Urednik - description: Prvi post izmjenjen - basic_user: - name: Osnovni - description: Odobrene sve osnovne funkcije foruma - member: - name: Član - description: Odobrene pozivnice - regular: - name: Regularan - description: Granted recategorize, rename, followed links and lounge - leader: - name: Vođa - description: Granted global edit, pin, close, archive, split and merge - welcome: - name: Dobrodošao - description: Dobio Lajk - autobiographer: - name: Autobiografičar - description: Popunio biografiju na svom profilu - anniversary: - name: Godišnjica - description: Aktivan član godinu dana, pisao najmanje jednom - nice_post: - name: Dobar Post - description: Dobio 10 lajkova na postu. Ovaj se bedž može dobiti više puta - good_post: - name: Odličan Post - description: Dobio 25 lajkova na postu. Ovaj se bedž može dobiti više puta - great_post: - name: Super Post - description: Dobio 50 lajkova na postu. Ovaj se bedž može dobiti više puta - nice_topic: - name: Dobra Tema - description: Dobio 10 lajkova na postu. Ovaj se bedž može dobiti više puta - good_topic: - name: Odlična Tema - description: Dobio 25 lajkova na postu. Ovaj se bedž može dobiti više puta - great_topic: - name: Super Tema - description: Dobio 50 lajkova na postu. Ovaj se bedž može dobiti više puta - nice_share: - name: Dobar Share - description: Podijelio je post sa više od 25 posjetilaca - good_share: - name: Good Share - description: Shared a post with 300 unique visitors - great_share: - name: Great Share - description: Shared a post with 1000 unique visitors - first_like: - name: Prvi Lajk - description: Lajkovao post - first_flag: - name: Prva Opomena - description: Opomenuo post - champion: - description: Pozvao 5 članova (trust level 2) - first_share: - name: Prvi Share - description: Podijelio post - first_link: - name: Prvi Link - description: Dodao interni link na drugu temu - first_quote: - name: Prvo Citiranje - description: Citirao korisnika - read_guidelines: - name: Pročitao Pravila - description: Pročitao naša pravila - reader: - name: Čitač - description: Pročitao post na temi sa više od 100 postova diff --git a/config/locales/client.cs.yml b/config/locales/client.cs.yml index 7699af6fb59..91496b3f03c 100644 --- a/config/locales/client.cs.yml +++ b/config/locales/client.cs.yml @@ -127,6 +127,26 @@ cs: facebook: 'sdílet odkaz na Facebooku' google+: 'sdílet odkaz na Google+' email: 'odeslat odkaz emailem' + action_codes: + split_topic: "rozděl toto téma %{when}" + autoclosed: + enabled: 'uzavřeno %{when}' + disabled: 'otevřeno %{when}' + closed: + enabled: 'uzavřeno %{when}' + disabled: 'otevřeno %{when}' + archived: + enabled: 'archivováno %{when}' + disabled: 'odarchivováno %{when}' + pinned: + enabled: 'připnuto %{when}' + disabled: 'odepnuto %{when}' + pinned_globally: + enabled: 'globálně přinuto %{when}' + disabled: 'odepnuto %{when}' + visible: + enabled: 'uvedeno %{when}' + disabled: 'neuvedeno %{when}' topic_admin_menu: "akce administrátora tématu" emails_are_disabled: "Všechny odchozí emaily byly administrátorem vypnuty. Žádné odchozí emaily nebudou odeslány." edit: 'upravit název a kategorii příspěvku' @@ -142,6 +162,7 @@ cs: admin_title: "Administrace" flags_title: "Nahlášení" show_more: "zobrazit více" + show_help: "volby" links: "Odkazy" links_lowercase: one: "odkaz" @@ -223,6 +244,7 @@ cs: saved: "Uloženo!" upload: "Obrázek" uploading: "Nahrávám..." + uploading_filename: "Nahrávání {{filename}}..." uploaded: "Nahráno!" enable: "Zapnout" disable: "Vypnout" @@ -230,6 +252,7 @@ cs: revert: "Vrátit" failed: "Selhání" switch_to_anon: "Anonymní mód" + switch_from_anon: "Opustit Anonymní" banner: close: "Odmítnout tento banner." edit: "Editujte tento banner >>" @@ -253,7 +276,6 @@ cs: few: "Toto téma má {{count}} příspěvky, které čekají na schválení." other: "Toto téma má {{count}} příspěvků, které čekají na schválení." confirm: "Uložit změny" - delete_prompt: "Jsi si jistý, že chceš smazat %{username}? Smažou se všechny jeho příspěvky, zablokuje se jeho email a IP adresa," approval: title: "Příspěvek potřebuje schválení" description: "Obdrželi jsme váš příspěvek, ale musí být před zveřejněním schválen moderátorem. Buďte trpěliví." @@ -298,6 +320,9 @@ cs: few: "%{count} uživatelé" other: "%{count} uživatelů" groups: + add: "Přidat" + selector_placeholder: "Přidat členy" + owner: "Vlastník" visible: "Skupina je viditelná pro všechny uživatele" title: one: "skupina" @@ -306,12 +331,15 @@ cs: members: "Členové" posts: "Odpovědi" alias_levels: - title: "Kdo může zmínit tuto skupinu jako @skupina?" + title: "Kdo může do této skupiny psát zprávy a @zmiňovat ji?" nobody: "Nikdo" only_admins: "Pouze správci" mods_and_admins: "Pouze moderátoři a správci" members_mods_and_admins: "Pouze členové skupiny, moderátoři a správci" everyone: "Kdokoliv" + trust_levels: + title: "Automaticky přidělená úroveň důvěryhodnosti členům když jsou přidáni: " + none: "Žádná" user_action_groups: '1': "Rozdaných 'líbí se'" '2': "Obdržených 'líbí se'" @@ -321,7 +349,6 @@ cs: '6': "Odezva" '7': "Zmínění" '9': "Citace" - '10': "Oblíbené" '11': "Editace" '12': "Odeslané zprávy" '13': "Přijaté zprávy" @@ -331,6 +358,14 @@ cs: all_subcategories: "vše" no_subcategory: "žádné" category: "Kategorie" + reorder: + title: "Přeřadit kategorie" + title_long: "Přeorganizovat seznam kategorií" + fix_order: "Zafixovat umístění" + fix_order_tooltip: "Ne všechny kategorie mají jedinečné číslo umístěni, což může způsobovat nečekané následky." + save: "Uložit pořadí" + apply_all: "Použít" + position: "Umístění" posts: "Příspěvky" topics: "Témata" latest: "Aktuální" @@ -362,6 +397,8 @@ cs: topics_entered: "témat zadáno" post_count: "počet příspěvků" confirm_delete_other_accounts: "Určitě chcete smazat tyto účty?" + user_fields: + none: "(zvolit možnost)" user: said: "{{username}}:" profile: "Profil" @@ -373,11 +410,20 @@ cs: private_messages: "Zprávy" activity_stream: "Aktivita" preferences: "Nastavení" + expand_profile: "Rozšířit" bookmarks: "Záložky" bio: "O mně" invited_by: "Pozvánka od" trust_level: "Důvěryhodnost" notifications: "Oznámení" + desktop_notifications: + label: "Upozornění na desktopu" + not_supported: "Tento prohlížeč nepodporuje upozornění. Omlouváme se." + perm_default: "Vypnout upozornění." + perm_denied_btn: "Povolení zamítnuto" + disable: "Vypnout upozornění" + enable: "Povolit upozornění" + each_browser_note: "Poznámka: Musíš změnit tuto volbu v každém prohlížeči, který používáš." dismiss_notifications: "Označ vše jako přečtené" dismiss_notifications_tooltip: "Označit všechny nepřečtené notifikace jako přečtené" disable_jump_reply: "Po odpovědi nepřeskakovat na nový příspěvek" @@ -390,6 +436,7 @@ cs: admin: "{{user}} je administrátor" moderator_tooltip: "Tento uživatel je moderátor" admin_tooltip: "Tento uživatel je admi" + blocked_tooltip: "Tento uživatel je zablokován." suspended_notice: "Uživatel je suspendován do {{date}}." suspended_reason: "Důvod: " github_profile: "Github" @@ -399,7 +446,7 @@ cs: tracked_categories: "Sledované" tracked_categories_instructions: "Všechna nová témata v této kategorii budou automaticky hlídaná. Počet nových příspěvků se zobrazí vedle tématu." muted_categories: "Ztišené" - muted_categories_instructions: "Nebudete upozorněni na žádná nová témata v těchto kategoriích a ani se nebudou zobrazovat jako nepřečtené." + muted_categories_instructions: "Budeš přijímat upornění na nová témata v těchto kategoriích a ty se neobjeví v aktuálních." delete_account: "Smazat můj účet" delete_account_confirm: "Jste si jisti, že chcete trvale odstranit svůj účet? Tuto akci nelze vrátit zpět!" deleted_yourself: "Váš účet byl úspěšně odstraněn." @@ -409,6 +456,7 @@ cs: users: "Uživatelé" muted_users: "Ztišení" muted_users_instructions: "Umlčet všechny notifikace od těchto uživatelů." + muted_topics_link: "Ukázat utlumená témata" staff_counters: flags_given: "užitečná nahlášení" flagged_posts: "nahlášených příspěvků" @@ -417,8 +465,7 @@ cs: warnings_received: "varování" messages: all: "Všechny" - mine: "Moje" - unread: "Nepřečtené" + groups: "Moje skupiny" change_password: success: "(email odeslán)" in_progress: "(odesílám)" @@ -450,6 +497,7 @@ cs: upload_title: "Nahrát obrázek" upload_picture: "Nahrát obrázek" image_is_not_a_square: "Varování: Ořízli jsme váš avatar; šířka a délka nebyla stejná." + cache_notice: "Úspěšně jsi si vyměnil profilovou fotku, ale chvíli může trvat, než se zobrazí kvůli ukládání v mezipaměti prohlížeče. " change_profile_background: title: "Pozadí profilu" instructions: "Pozadí profilu je zarovnáno doprostřed a má výchozí šířku 850px." @@ -462,10 +510,11 @@ cs: ok: "Pro potvrzení vám pošleme email." invalid: "Zadejte prosím správnou emailovou adresu" authenticated: "Vaše emailová adresa byla autorizována přes službu {{provider}}." + frequency_immediately: "Pokud jste obsah dosud nečetli, pošleme vám ho ihned emailem." frequency: - zero: "Pokud jste obsah dosud nečetli, pošleme vám ho ihned emailem." - one: "Pošleme vám email, pokud jste tu nebyli poslední minutu." - other: "Email vám zašleme pouze pokud nejste v posledních {{count}} minutách." + one: "Email vám zašleme pouze pokud jste se neukázali během poslední minuty." + few: "Email vám zašleme pouze pokud jste se neukázali během posledních {{count}} minut." + other: "Email vám zašleme pouze pokud jste se neukázali během posledních {{count}} minut." name: title: "Jméno" instructions: "Celé jméno (volitelně)" @@ -509,26 +558,45 @@ cs: every_two_weeks: "každé dva týdny" email_direct: "Zašli mi email, pokud mě někde cituje, odpoví na můj příspěvek, zmíní mé @jméno nebo mě pozve do tématu." email_private_messages: "Zašli mi email, pokud mi někdo pošle zprávu." + email_always: "Zašli mi upozornění emailem i když jsem aktivní na fóru" other_settings: "Ostatní" categories_settings: "Kategorie" new_topic_duration: label: "Považovat témata za nová, pokud" not_viewed: "jsem je dosud neviděl." last_here: "byla vytvořena od mé poslední návštěvy." + after_1_day: "vytvořeno během posledního dne" + after_2_days: "vytvořeno během posledních 2 dnů" + after_1_week: "vytvořeno během posledního týdne" + after_2_weeks: "vytvořeno během posledních 2 týdnů" auto_track_topics: "Automaticky sledovat témata, která navštívím" auto_track_options: never: "nikdy" immediately: "ihned" + after_30_seconds: "po 30 sekundách" + after_1_minute: "po 1 minutě" + after_2_minutes: "po 2 minutách" + after_3_minutes: "po 3 minutách" + after_4_minutes: "po 4 minutách" + after_5_minutes: "po 5 minutách" + after_10_minutes: "po 10 minutách" invited: search: "pište pro hledání v pozvánkách..." title: "Pozvánky" user: "Pozvaný uživatel" - truncated: "Showing the first {{count}} invites." + sent: "Odeslané" + none: "Nemáte žádně nevyřízené pozvánky na zobrazení." + truncated: + one: "Zobrazena první pozvánka." + few: "Zobrazeno prvních {{count}} pozvánek." + other: "Zobrazeno prvních {{count}} pozvánek." redeemed: "Uplatněné pozvánky" redeemed_tab: "Uplatněno" + redeemed_tab_with_count: "Vyřízeno ({{count}})" redeemed_at: "Uplatněno" pending: "Nevyřízené pozvánky" pending_tab: "Čeká na schválení" + pending_tab_with_count: "Nevyřízeno ({{count}})" topics_entered: "Zobrazil témat" posts_read_count: "Přečteno příspěvků" expired: "Poznávka je už prošlá." @@ -540,6 +608,8 @@ cs: days_visited: "Přítomen dnů" account_age_days: "Stáří účtu ve dnech" create: "Poslat pozvánku" + generate_link: "Zkopírovat odkaz na pozvánku" + generated_link_message: '

    Odkaz na poznámku byl úspěšně vygenerován!

    Odkaz na pozvánku je platný jen pro tuto e-mailovou adresu: %{invitedEmail}

    ' bulk_invite: none: "Zatím jste nikoho nepozval. Můžete poslat individuální pozvánku nebo pozvat skupinu lidí naráz pomocí nahrání souboru." text: "Hromadné pozvání s pomocí souboru" @@ -579,11 +649,13 @@ cs: server: "Chyba serveru" forbidden: "Přístup zamítnut" unknown: "Chyba" + not_found: "Stránka nenalezena" desc: network: "Prosím zkontrolujte své připojení." network_fixed: "Looks like it's back." server: "Kód chyby: {{status}}" forbidden: "Nemáte povolení to spatřit." + not_found: "Jejda, aplikace zkusila načíst neexistující URL." unknown: "Něco se pokazilo." buttons: back: "Zpět" @@ -594,7 +666,6 @@ cs: logout: "Byli jste odhlášeni." refresh: "Obnovit" read_only_mode: - enabled: "Stranka je nastavena jen pro čtení. Můžete pokračovat v prohlížení ale interakce nemusí fungovat." login_disabled: "Přihlášení je zakázáno jelikož fórum je v režimu jen pro čtení." learn_more: "více informací..." year: 'rok' @@ -613,10 +684,15 @@ cs: one: odpověď few: odpovědi other: odpovědí + signup_cta: + sign_up: "Registrovat se" + hide_session: "Připomenout mi zítra" + hide_forever: "děkuji, ne" + hidden_for_session: "Dobrá, zeptám se tě zítra. Pro založení účtu můžeš také vždy použít 'Přihlásit se'." + intro: "Nazdar! :heart_eyes: Vypadá to, že si užíváš diskuzi, ale zatím jsi si nezaložil účet." + value_prop: "Pokud si založíš účet, budeme si přesně pomatovat, co jsi četly, takže se vždycky vrátíš do bodu, odkud jsi odešel. Také budeš dostávat upozornění, zde a přes e-mail, kdykoli přibydou nově příspěvky. A můžeš přidávat 'to se mi líbí' a šířit tak lásku. :heartbeat:" summary: enabled_description: "Čtete shrnutí tohoto tématu: nejzajímavější příspěvky podle komunity." - description: "Obsahuje {{count}} odpovědí." - description_time: "Obsahuje {{count}} odpovědí o odhadovaném času čtení {{readingTime}} minut." enable: 'Přepnout na "nejlepší příspěvky"' disable: 'Přepnout na normální zobrazení' deleted_filter: @@ -670,6 +746,9 @@ cs: admin_not_allowed_from_ip_address: "Z této IP adresy se nemůžete přihlásit jako administrátor." resend_activation_email: "Klikněte sem pro zaslání aktivačního emailu." sent_activation_email_again: "Zaslali jsme vám další aktivační email na {{currentEmail}}. Může trvat několik minut, než vám dorazí. Zkontrolujte také vaši složku s nevyžádanou pošlou." + to_continue: "Přihlaš se, prosím" + preferences: "Pro to, aby jsi mohl měnit své uživatelské nastavení, se musíš přihlásit." + forgot: "Nevybavuju si podrobnosti svého účtu" google: title: "přes Google" message: "Autorizuji přes Google (ujistěte se, že nemáte zablokovaná popup okna)" @@ -692,15 +771,23 @@ cs: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + more_emoji: "více..." + options: "Možnosti" + whisper: "šeptat" add_warning: "Toto je oficiální varování." + toggle_whisper: "Přepnout šeptání" posting_not_on_topic: "Rozepsali jste odpověď na téma \"{{title}}\", ale nyní máte otevřené jiné téma." saving_draft_tip: "ukládá se..." saved_draft_tip: "uloženo" saved_local_draft_tip: "uloženo lokálně" similar_topics: "Podobná témata" drafts_offline: "koncepty offline" + group_mentioned: "Použitím {{group}} upozorníš {{count}} lidí." error: title_missing: "Název musí být vyplněn" title_too_short: "Název musí být dlouhý alespoň {{min}} znaků" @@ -721,8 +808,9 @@ cs: title_placeholder: "O čem je ve zkratce tato diskuze?" edit_reason_placeholder: "proč byla nutná úprava?" show_edit_reason: "(přidat důvod úpravy)" + reply_placeholder: "Piš tady. Pro formátování používej Markdown, BBCode nebo HTML. Přetáhni nebo vlož obrázky." view_new_post: "Zobrazit váš nový příspěvek." - saving: "Ukládám..." + saving: "Ukládám" saved: "Uloženo!" saved_draft: "Máte rozepsaný příspěvek. Klikněte pro obnovení." uploading: "Nahrávám..." @@ -737,6 +825,7 @@ cs: link_description: "sem vložte popis odkazu" link_dialog_title: "Vložit odkaz" link_optional_text: "volitelný popis" + link_placeholder: "http://example.com \"nepovinný text\"" quote_title: "Bloková citace" quote_text: "Bloková citace" code_title: "Ukázka kódu" @@ -749,10 +838,11 @@ cs: heading_title: "Nadpis" heading_text: "Nadpis" hr_title: "Horizontální oddělovač" - undo_title: "Zpět" - redo_title: "Opakovat" help: "Nápověda pro Markdown" toggler: "zobrazit nebo skrýt editor příspěvku" + modal_ok: "OK" + modal_cancel: "Zrušit" + cant_send_pm: "Bohužel, nemůžete poslat zprávu uživateli %{username}." admin_options_title: "Volitelné administrační nastavení tématu" auto_close: label: "Automaticky zavřít téma za:" @@ -769,9 +859,9 @@ cs: more: "zobrazit starší oznámení" total_flagged: "celkem nahlášeno příspěvků" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -781,6 +871,20 @@ cs: moved_post: "

    {{username}} přesunul {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Získáno '{{description}}'

    " + alt: + mentioned: "Zmíněno" + quoted: "Citováno" + replied: "Odpověděl" + posted: "Příspěvek od" + edited: "Editovat váš příspěvek od" + liked: "Líbil se tvůj příspěvek" + private_message: "Soukromá zpráva od" + invited_to_private_message: "Pozván k soukromé zprávě od" + invited_to_topic: "Pozván k tématu od" + invitee_accepted: "Pozvánka přijata od" + moved_post: "Tvůj příspěvek přesunul" + linked: "Odkaz na tvůj příspěvek" + granted_badge: "Odznak přidělen" popup: mentioned: '{{username}} vás zmínil v "{{topic}}" - {{site_title}}' quoted: '{{username}} vás citoval v "{{topic}}" - {{site_title}}' @@ -794,14 +898,30 @@ cs: from_my_computer: "Z mého zařízení" from_the_web: "Z webu" remote_tip: "odkaz na obrázek" - remote_tip_with_attachments: "odkaz na obrázek nebo osubor ({{authorized_extensions}})" + remote_tip_with_attachments: "odkaz na obrázek nebo soubor {{authorized_extensions}}" + local_tip: "vyber obrázky z tvého zařízení" + local_tip_with_attachments: "vyber obrázky nebo soubory ze svého zařízení {{authorized_extensions}}" hint: "(můžete také rovnou soubor do editoru přetáhnout)" + hint_for_supported_browsers: "také můžeš obrázky do editoru přetáhnout nebo vložit" uploading: "Nahrávám" select_file: "Vyberte soubor" image_link: "adresa na kterou má váš obrázek odkazovat" search: + sort_by: "Seřadil" + relevance: "Relevance" + latest_post: "Poslední příspěvek" + most_viewed: "Nejzobrazovanější" + most_liked: "Nejoblíbenější" + select_all: "Vybrat vše" + clear_all: "Vymazat vše" + result_count: + one: "1 výsledek pro \"{{term}}\"" + few: "{{count}} výsledků pro \"{{term}}\"" + other: "{{count}} výsledků pro \"{{term}}\"" title: "vyhledávat témata, příspěvky, uživatele nebo kategorie" no_results: "Nenalezeny žádné výsledky." + no_more_results: "Nenalezeny žádné další výsledky." + search_help: Pomoc s hledáním searching: "Hledám ..." post_format: "#{{post_number}} od {{username}}" context: @@ -809,17 +929,21 @@ cs: category: "Vyhledat v kategorii „{{category}}“" topic: "Vyhledat v tomto tématu" private_messages: "Hledat ve zprávách" + hamburger_menu: "jít na jiný seznam témat nebo kategorii" + new_item: "nové" go_back: 'jít zpět' not_logged_in_user: 'stránka uživatele s přehledem o aktuální činnosti a nastavení' current_user: 'jít na vaši uživatelskou stránku' topics: bulk: + unlist_topics: "Odebrat témata ze seznamu" reset_read: "reset přečteného" delete: "Smazat témata" - dismiss_posts: "Odbýt příspěvky" - dismiss_posts_tooltip: "Smazat počet nepřečtených příspěvků v tématu ale na seznamu je dál zobrazovat jako nepřečtené" - dismiss_topics: "Odbýt témata" - dismiss_topics_tooltip: "Nezobrazovat tato témata jako nepřečtená při novém příspěvku" + dismiss: "Odbýt" + dismiss_read: "Odbýt všechna nepřečtená" + dismiss_button: "Odbýt..." + dismiss_tooltip: "Odbýt jen nové příspěvka nebo přestat sledovat témata" + also_dismiss_topics: "Přestat sledovat tyto témata, takže se mi znovu nezobrazí jako nepřečtená" dismiss_new: "Odbýt nová" toggle: "hromadný výběr témat" actions: "Hromadné akce" @@ -843,9 +967,6 @@ cs: category: "V kategorii {{category}} nejsou žádná témata." top: "Nejsou tu žádná populární témata." search: "There are no search results." - educate: - new: '

    Zde se zobrazují nová témata.

    Podle výchozího nastavení jsou za nová témata považována ta, která byla vytvořena v posledních 2 dnech.

    U těch se ukáže ukazatel Nové.

    Můžete to změnit ve vašem nastavení.

    ' - unread: '

    Zde se zobrazují vaše nepřečtená témata.

    Podle výchozího nastavení jsou za nepřečtená témata, ukterých se zobrazuje počet nepřečtení 1, považována ta, která jste:

    • Vytvořil toto téma
    • Odpovědětl v tématu
    • Četl téma více než 4 minuty

    Nebo pokud jste nastavil téma jako Hlídané či Sledované pomocí nabídky na spodku každého tématu.

    You can change this in your preferences.

    ' bottom: latest: "Nejsou tu žádná další témata z poslední doby." hot: "Nejsou tu žádná další populární témata k přečtení." @@ -858,6 +979,9 @@ cs: bookmarks: "Žádná další oblíbená témata nejsou k dispozici." search: "There are no more search results." topic: + unsubscribe: + stop_notifications: "Budete dostávat méně upozornění pro {{title}}" + change_notification_state: "Váš momentální stav oznámení je" filter_to: "{{post_count}} příspěvků v tématu" create: 'Nové téma' create_long: 'Vytvořit nové téma' @@ -956,15 +1080,17 @@ cs: title: "Sledované" description: "U tohoto tématu se zobrazí počet nových příspěvků. Budete upozorněni, pokud někdo zmíní vaše @jméno nebo odpoví na váš příspěvek." regular: + title: "Normální" description: "Budete informováni pokud někdo zmíní vaše @jméno nebo odpoví na váš příspěvek." regular_pm: + title: "Normální" description: "Budete informováni pokud někdo zmíní vaše @jméno nebo odpoví na váš příspěvek." muted_pm: title: "Ztišení" description: "Nikdy nedostanete oznámení týkající se čehokoliv v této zprávě." muted: title: "Ztišené" - description: "nebudete dostávat žádná oznámení k tomuto tématu a ani se nebude zobrazovat v seznamu nepřečtených témat." + description: "Nikdy nedostanete nic ohledně tohoto tématu a nezobrazí se v aktuálních." actions: recover: "Vrátit téma" delete: "Odstranit téma" @@ -1000,26 +1126,28 @@ cs: success_message: 'Téma úspěšně nahlášeno.' feature_topic: title: "Povýšit téma" + pin: "Zobrazit toto téma na vrcholu kategorie {{categoryLink}} dokud" confirm_pin: "Již máte {{count}} připevněných příspěvků. Příliš mnoho připevněných příspěvků může zatěžovat nové nebo anonymní uživatele. Určitě chcete připevnit další téma v této kategorii?" unpin: "Odstranit toto téma z vrcholu {{categoryLink}} kategorie." + unpin_until: "Odstranit toto téma z vrcholu kategorie {{categoryLink}}, nebo počkat dokud %{until}" pin_note: "Uživatelé mohou odepnout téma sami pro sebe." - already_pinned: - zero: "V {{categoryLink}} nejsou žádná připevněná témata." - one: "V současnosti připevněná téma v {{categoryLink}}: 1." - other: "V současnosti připevněná téma v {{categoryLink}}: {{count}}." + pin_validation: "Pro připíchnutí tohoto tématu je třeba datum." + not_pinned: "V kategorii {{categoryLink}} nejsou žádná připnutá témata." + pin_globally: "Zobrazit toto téma na vrcholu seznamu všech témat dokud" confirm_pin_globally: "Již máte {{count}} globálně připevněných příspěvků. Příliš mnoho připevněných příspěvků může zatěžovat nové nebo anonymní uživatele. Určitě chcete připevnit další téma globálně?" unpin_globally: "Odstranit toto téma z vrcholu všech seznamů s tématy." + unpin_globally_until: "Odstranit toto téma z vrcholu seznamu všech témat nebo počat dokud %{until}." global_pin_note: "Uživatelé mohou odepnout téma sami pro sebe." + not_pinned_globally: "Nemáte žádná globálně připevněná témata." already_pinned_globally: - zero: "Nemáte žádná globálně připevněná témata." - one: "V současnosti globálně připevněná témata: 1." - other: "V současnosti globálně připevněná témata: {{count}}." + one: "V současnosti globálně připevněná témata: 1" + few: "V současnosti globálně připevněná témata: {{count}}" + other: "V současnosti globálně připevněná témata: {{count}}" make_banner: "Udělat z tohoto tématu banner, který se zobrazí na vrcholu všech stránek." remove_banner: "Odstranit banner, který se zobrazuje na vrcholu všech stránek." banner_note: "Uživatelé mohou odmítnout banner jeho zavřením. V jeden moment může být pouze jedno téma jako banner." - already_banner: - zero: "Žádné téma není jako banner." - one: "V současnosti je zde zakázané téma." + no_banner_exists: "Žádné téma není jako banner." + banner_exists: "V současnosti je zde téma jako banner." inviting: "Odesílám pozvánku..." automatically_add_to_groups_optional: "Tato pozvánka obsahuje také přístup do této skupiny: (volitelné, pouze administrátor)" automatically_add_to_groups_required: "Tato pozvánka obsahuje také přístup do těchto skupin: (Vyžadováno, pouze administrátor)" @@ -1081,6 +1209,12 @@ cs: few: "Vyberte prosím nového autora {{count}} příspěvků od {{old_user}}." other: "Vyberte prosím nového autora {{count}} příspěvků od {{old_user}}." instructions_warn: "Poznámka: Žádná upozornění na tento příspěvek nebudou zpětně přenesena na nového uživatele.
    Varování: V současné chvíli, žádná data svázaná s příspěvkem nebudou přenesena na nového uživatele. Používejte opatrně." + change_timestamp: + title: "Změnit časovou značku" + action: "změnit časovou značku" + invalid_timestamp: "Časová značka nemůže být v budoucnosti." + error: "Nastala chyba při změně časové značky tématu." + instructions: "Zvol novou časovou značku tématu, prosím. Příspěvky v tématu se aktualizují tak aby měly stejný rozdíl v čase." multi_select: select: 'vybrat' selected: 'vybráno ({{count}})' @@ -1094,6 +1228,8 @@ cs: few: Máte označeny {{count}} příspěvky. other: Máte označeno {{count}} příspěvků. post: + reply: " {{replyAvatar}} {{usernameLink}}" + reply_topic: " {{link}}" quote_reply: "odpověď s citací" edit: "Editujete {{link}} {{replyAvatar}} {{username}}" edit_reason: "Důvod: " @@ -1127,9 +1263,10 @@ cs: one: "1 člověku se líbí tento příspěvek" few: "{{count}} lidem se líbí tento příspěvek" other: "{{count}} lidem se líbí tento příspěvek" + has_likes_title_only_you: "tento příspěvek se mi líbí" has_likes_title_you: - zero: "tento příspěvek se mi líbí" - one: "vám a 1 další osobě se tento příspěvek líbí" + one: "vám a 1 dalšímu člověku se tento příspěvek líbí" + few: "vám a {{count}} dalším lidem se tento příspěvek líbí" other: "vám a {{count}} dalším lidem se tento příspěvek líbí" errors: create: "Bohužel nastala chyba při vytváření příspěvku. Prosím zkuste to znovu." @@ -1148,8 +1285,7 @@ cs: no_value: "Nezahazovat" yes_value: "Ano, zahodit" via_email: "tento příspěvek byl přijat přes email" - wiki: - about: "tento příspěvek je wiki; běžní uživatelé jej mohou editovat" + whisper: "tento příspěvek je soukromé šeptání pro moderátory" archetypes: save: 'Uložit nastavení' controls: @@ -1178,6 +1314,7 @@ cs: revert_to_regular: "Odstraňte Staff Color" rebake: "Obnovit HTML" unhide: "Odkrýt" + change_owner: "Změna autora" actions: flag: 'Nahlásit' defer_flags: @@ -1199,18 +1336,6 @@ cs: bookmark: "Odebrat ze záložek" like: "Už se mi to nelíbí" vote: "Zrušit hlas" - people: - off_topic: "{{icons}} označili tento příspěvek jako off-topic" - spam: "{{icons}} označili tento příspěvek jako spam" - spam_with_url: "{{icons}} označení jako spam" - inappropriate: "{{icons}} označili tento příspěvek jako nevhodný" - notify_moderators: "{{icons}} nahlásili tento příspěvek" - notify_moderators_with_url: "{{icons}} nahlásili tento příspěvek" - notify_user: "{{icons}} poslal zprávu" - notify_user_with_url: "{{icons}} poslal zprávu" - bookmark: "{{icons}} si přidali příspěvek do záložek" - like: "{{icons}} se líbí tento příspěvek" - vote: "{{icons}} hlasovali pro tento příspěvek" by_you: off_topic: "Označili jste tento příspěvek jako off-topic" spam: "Označili jste tento příspěvek jako spam" @@ -1286,10 +1411,6 @@ cs: one: "1 člověk hlasoval pro tento příspěvek" few: "{{count}} lidé hlasovali pro tento příspěvek" other: "{{count}} lidí hlasovalo pro tento příspěvek" - edits: - one: 1 úprava - other: "{{count}} úprav" - zero: žádné úpravy delete: confirm: one: "Opravdu chcete odstranit tento příspěvek?" @@ -1327,6 +1448,7 @@ cs: topic_template: "Šablona tématu" delete: 'Smazat kategorii' create: 'Nová kategorie' + create_long: 'Vytvořit novou kategorii' save: 'Uložit kategorii' slug: 'Odkaz kategorie' slug_placeholder: '(Dobrovolné) podtržená URL' @@ -1356,6 +1478,7 @@ cs: email_in_allow_strangers: "Přijímat emaily i od neregistrovaných uživatelů" email_in_disabled: "Přidávání nových témat před email je zakázáno v Nastavení fóra. K povolení nových témat přes email," email_in_disabled_click: 'povolit nastavení "email in"' + suppress_from_homepage: "Potlač tuto kategorii na domovské stránce." allow_badges_label: "Povolit používání odznaků v této kategorii" edit_permissions: "Upravit oprávnění" add_permission: "Přidat oprávnění" @@ -1368,19 +1491,18 @@ cs: notifications: watching: title: "Hlídání" - description: "Všechna nová témata v této kategorii budou automaticky Sledovaná. Na všechny nové příspěvky a témata budete upozorněni. Navíc ve výpisu uvidíte počet nepřečtených příspěvků." + description: "Budete automaticky sledovat všechna nová témata v těchto kategoriích. Budete dostávat upozornění na všechny nové příspěvky ve všech tématech a zobrazí se počet nových odpovědí." tracking: title: "Sledování" - description: "Všechna nová témata v této kategorii budou automaticky Hlídaná. Počet nových příspěvků se zobrazí vedle tématu." + description: "Budete automaticky sledovat všechna nová témata v těchto kategorích. Budete dostávat upozornění pokud vám někdo odpoví, nebo zmíní vaše @jméno a zobrazí se počet nových odpovědí. " regular: title: "Normální" description: "Budete informováni pokud někdo zmíní vaše @jméno nebo odpoví na váš příspěvek." muted: title: "Ztišený" - description: "Nebudete upozorněni na žádná nová témata v těchto kategoriích a ani se nebudou zobrazovat jako nepřečtené." + description: "Nikdy nebudete dostávat upozornění na nová témata v těchto kategoriích a neobjeví se v aktuálních." flagging: title: 'Děkujeme, že pomáháte udržovat komunitu zdvořilou!' - private_reminder: 'nahlášení jsou soukromá, viditelná pouze pro správce' action: 'Nahlásit příspěvek' take_action: "Zakročit" notify_action: 'Zpráva' @@ -1390,6 +1512,7 @@ cs: ip_address_missing: "(N/A)" hidden_email_address: "(skrytý)" submit_tooltip: "Podat soukromé nahlášení" + take_action_tooltip: "Ihned dosáhni vlaječky prahu, než aby jsi čekal na více komunitních vlaječek" cant: "Bohužel nyní nemůžete tento příspěvek nahlásit." formatted_name: off_topic: "Je to mimo téma." @@ -1423,12 +1546,14 @@ cs: help: "toto téma je uzavřené; další odpovědi nejsou přijímány" archived: help: "toto téma je archivováno; je zmraženo a nelze ho již měnit" + locked_and_archived: + help: "Toto téma je uzavřené a archivované; další odpovědi nejsou přijímány a změny nejsou možné" unpinned: title: "Nepřipnuté" help: "Pro vás toto téma není připnuté; bude se zobrazovat v běžném pořadí" pinned_globally: title: "Připnuté globálně" - help: "Toto téma je připnuto globálně, zobrazí se na vršku všech seznamů" + help: "Toto téma je připnuté; bude se zobrazovat na vrcholu aktuálních a ve své kategorii" pinned: title: "Připnuto" help: "Pro vás je toto téma připnuté; bude se zobrazovat na vrcholu seznamu ve své kategorii" @@ -1474,10 +1599,11 @@ cs: with_topics: "%{filter} témata" with_category: "%{filter} %{category} témata" latest: - title: - zero: "Aktuální" - one: "Aktuální (1)" - other: "Aktuální ({{count}})" + title: "Nejaktuálnější" + title_with_count: + one: "Nedávné (1)" + few: "Nedávná ({{count}})" + other: "Nedávná ({{count}})" help: "nejaktuálnější témata" hot: title: "Populární" @@ -1493,22 +1619,26 @@ cs: title_in: "Kategorie - {{categoryName}}" help: "všechna témata seskupená podle kategorie" unread: - title: - zero: "Nepřečtená" - one: "Nepřečtená (1)" + title: "Nepřečtená" + title_with_count: + one: "Nepřečtená ({{1}})" + few: "Nepřečtená ({{count}})" other: "Nepřečtená ({{count}})" help: "témata. která sledujete nebo hlídáte, s nepřečtenými příspěvky" lower_title_with_count: - one: "1 nepřečtený" + one: "{{count}} nepřečtené" + few: "{{count}} nepřečtených" other: "{{count}} nepřečtených" new: lower_title_with_count: - one: "1 nový" - other: "{{count}} nové" + one: "{{count}} nové" + few: "{{count}} nových" + other: "{{count}} nových" lower_title: "nové" - title: - zero: "Nová" - one: "Nová (1)" + title: "Nová" + title_with_count: + one: "Nové" + few: "Nová ({{count}})" other: "Nová ({{count}})" help: "témata vytvořená za posledních několik dní" posted: @@ -1518,9 +1648,10 @@ cs: title: "Záložky" help: "témata, do kterých jste si vložili záložku" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" + title: "{{categoryName}}" + title_with_count: + one: "{{categoryName}} ({{count}})" + few: "{{categoryName}} ({{count}})" other: "{{categoryName}} ({{count}})" help: "populární témata v kategorii {{categoryName}}" top: @@ -1530,6 +1661,8 @@ cs: title: "Za celou dobu" yearly: title: "Ročně" + quarterly: + title: "Čtvrtletně" monthly: title: "Měsíčně" weekly: @@ -1538,6 +1671,7 @@ cs: title: "Denně" all_time: "Za celou dobu" this_year: "Rok" + this_quarter: "Čtvrtletí" this_month: "Měsíc" this_week: "Týden" today: "Dnes" @@ -1683,15 +1817,24 @@ cs: delete_confirm: "Smazat toto skupiny?" delete_failed: "Unable to delete group. If this is an automatic group, it cannot be destroyed." delete_member_confirm: "Odstranit '%{username}' ze '%{group}' skupiny?" + delete_owner_confirm: "Odstranit vlastnickou výsadu od '%{username}'?" name: "Jméno" add: "Přidat" add_members: "Přidat členy" custom: "Přizpůsobené" + bulk_complete: "Uživatelé byli přidáni do skupiny." + bulk: "Hromadné přidání do skupiny" + bulk_paste: "Vlož seznam uživatelských jmen a e-mailů, jeden záznam na řádek" + bulk_select: "(vyber skupinu)" automatic: "Automatické" automatic_membership_email_domains: "Uživatelé zaregistrovaní s emailem jehož doména se přesně shoduje s jednou z tohoto seznamu budou automaticky přidáni to této skupiny:" automatic_membership_retroactive: "Aplikovat stejné doménové pravidlo na už existující uživatele" default_title: "Výchozí popis pro všechny uživatele této skupiny" primary_group: "Automaticky nastavit jako hlavní skupinu" + group_owners: Vlastníci + add_owners: Přidat vlastníky + incoming_email: "Vlastní příchozí emailová adresa" + incoming_email_placeholder: "zadej emailovou adresu" api: generate_master: "Vygenerovat Master API Key" none: "Nejsou tu žádné aktivní API klíče." @@ -1765,11 +1908,9 @@ cs: is_disabled: "Restore is disabled in the site settings." label: "Obnovit" title: "Restore the backup" - confirm: "Are your sure you want to restore this backup?" rollback: label: "Rollback" title: "Rollback the database to previous working state" - confirm: "Are your sure you want to rollback the database to the previous working state?" export_csv: user_archive_confirm: "Jste si jistí, že chcete stáhnout všechny své příspěvky?" success: "Export byl spuštěn. O dokončení celého procesu budete informování pomocí zprávy." @@ -1815,19 +1956,30 @@ cs: import_title: "Vyberte soubor nebo vložte text" delete: "Smazat" delete_confirm: "Smazat toto přizpůsobení?" + about: "Změn CSS styly a hlavičky HTML na stránkách. Přidej přizpůsobení na začátek." color: "Barva" opacity: "Neprůhlednost" copy: "Kopírovat" + email_templates: + title: "Šablona emailu" + subject: "Předmět" + multiple_subjects: "Tato šablona emailu má více předmětů." + body: "Tělo" + none_selected: "Pro začátek editace zvolte šablonu emailu." + revert: "Vrátit změny" + revert_confirm: "Opravdu chcete vrátit změny?" css_html: title: "CSS/HTML" long_title: "Přizpůsobení CSS a HTML" colors: title: "Barvy" long_title: "Barevná schémata" + about: "Změn barvy použité na stránkách bez psaní CSS. Přidej schéma na začátek." new_name: "Nové barevné schéma" copy_name_prefix: "Kopie" delete_confirm: "Chcete smazat toto barevné schéma?" undo: "zpět" + undo_title: "Vrať svoje změny této barvy od doby kdy byla posledně uložena." revert: "vrátit" revert_title: "Vrátit tuto barvu na výchozí barevné schéma Discourse." primary: @@ -1847,25 +1999,25 @@ cs: description: "Barva pozadí záhlaví stránky." header_primary: name: "primární záhlaví" + description: "Text a ikony v záhlaví stránky." highlight: name: 'zvýraznit' + description: 'Barva pozadí zvýrazněných prvků stránky, například příspěvků a témat.' danger: name: 'nebezpečí' + description: 'Barva zvýraznění pro akce jako mazání příspěvků a témat.' success: name: 'úspěch' description: 'Používá se pro indikaci úspěšné akce.' love: name: 'láska' description: "Barva tlačítka Like." - wiki: - name: 'wiki' - description: "Základní barva použita pro pozadí wiki článků." email: - title: "Email" settings: "Nastavení" - all: "Všechny emaily" + preview_digest: "Náhled souhrnu" sending_test: "Zkušební email se odesílá..." error: "CHYBA - %{server_error}" + test_error: "Nastal problém při odesílání testovacího emailu. Zkontroluj si, prosím, své mailové nastavení, ověř, že hosting neblokuje mailové spojení a zkus to znova." sent: "Odeslané" skipped: "Přeskočené" sent_at: "Odesláno" @@ -1877,7 +2029,7 @@ cs: send_test: "Odešli testovací email" sent_test: "odesláno!" delivery_method: "Způsob doručení" - preview_digest: "Náhled souhrnu" + preview_digest_desc: "Zobraz náhled mailů se souhrnem posílaným neaktivním uživatelúm." refresh: "Aktualizovat" format: "Formát" html: "html" @@ -1903,6 +2055,7 @@ cs: ip_address: "IP" topic_id: "ID tématu" post_id: "ID příspěvku" + category_id: "ID kategorie" delete: 'Smazat' edit: 'Upravit' save: 'Uložit' @@ -1942,6 +2095,9 @@ cs: delete_post: "smazat příspěvek" impersonate: "vydávat se za uživatele" anonymize_user: "anonymní uživatel" + change_category_settings: "změnit nastavení kategorie" + delete_category: "smazat kategorii" + create_category: "vytvořit kategorii" screened_emails: title: "Filtrované emaily" description: "Při registraci nového účtu budou konzultovány následujíci adresy. Při shodě bude registrace zablokována, nebo bude provedena jiná akce." @@ -1971,6 +2127,7 @@ cs: impersonate: title: "Přihlásit se jako" not_found: "Tento uživatel nebyl nalezen." + invalid: "Bohužel, za tohoto uživatele se nemůžete vydávat." users: title: 'Uživatelé' create: 'Přidat administrátora' @@ -2002,9 +2159,9 @@ cs: pending: 'Uživatelé čekající na schválení' newuser: 'Uživatelé s věrohodností 0 (Nový uživatel)' basic: 'Uživatelé s věrohodností 1 (Základní uživatel)' - regular: 'Uživatelé s věrohodností 2 (Člen)' - leader: 'Uživatelé s věrohodností 3 (Pravidelný uživatel)' - elder: 'Uživatelé s věrohodností 4 (Vedoucí)' + member: 'Uživatelé s věrohodností 2 (Člen)' + regular: 'Uživatelé s věrohodností 3 (Pravidelný uživatel)' + leader: 'Uživatelé s věrohodností 4 (Vedoucí)' staff: "Štáb" admins: 'Admininstrátoři' moderators: 'Moderátoři' @@ -2119,7 +2276,6 @@ cs: unlock_trust_level: "Odemknout úroveň důvěryhodnosti" tl3_requirements: title: "Požadavky pro důvěryhodnost 3" - table_title: "Za posledních 100 dní:" value_heading: "Hodnota" requirement_heading: "Požadavek" visits: "Návštěv" @@ -2162,6 +2318,7 @@ cs: delete: "Smazat" cancel: "Zrušit" delete_confirm: "Určitě chcete smazat toto rozšíření?" + options: "Možnosti" required: title: "Povinné pro registraci?" enabled: "povinné" @@ -2177,9 +2334,17 @@ cs: field_types: text: 'Text Field' confirm: 'Potvrzení' + dropdown: "Menu" site_text: - none: "Vyberte obsah který chcete upravit." + description: "Můžete uzpůsobit jakýkoli text na fóru. Začnětj s vyhledáváním níže, prosím:" + search: "Hledat text, který byste chtěli upravit" title: 'Texty' + edit: 'upravit' + revert: "Vrátit změny" + revert_confirm: "Opravdu chcete vrátit změny?" + go_back: "Zpět na hledání" + recommended: "Doporučujeme uzpůsobit následující text tak, aby vám vyhovoval:" + show_overriden: 'Zobrazit pouze změněná nastavení' site_settings: show_overriden: 'Zobrazit pouze změněná nastavení' title: 'Nastavení' @@ -2209,6 +2374,7 @@ cs: backups: "Zálohy" login: "Login" plugins: "Pluginy" + user_preferences: "Uživatelká nastavení" badges: title: Odznaky new_badge: Nový odznak @@ -2219,6 +2385,8 @@ cs: description: Popis badge_type: Typ odznaku badge_grouping: Skupina + badge_groupings: + modal_title: Sdružování odznaků granted_by: Uděleno granted_at: Uděleno v reason_help: (Odkaz na příspěvek nebo téma) @@ -2252,13 +2420,17 @@ cs: trust_level_change: "Když uživatel změní důvěryhodnost" user_change: "Když je uživatel upraven nebo vytvořen" preview: + link_text: "Náhled udělených odznaků" + plan_text: "Náhled s plánem dotazu" + modal_title: "Náhled dotazu na odznak" sql_error_header: "Bohužel, nastala chyba s dotazem." error_help: "Prohlédněte si následující odkazy, které vám zodpoví dotazy o odznacích." bad_count_warning: header: "VAROVÁNÍ!" + no_grant_count: "Žádné odznaky k udělení." grant_count: - zero: "Žádné odznaky k udělení." one: "1 odznak k udělení." + few: "%{count} odznaků k udělení." other: "%{count} odznaků k udělení." sample: "Příklad:" grant: @@ -2273,6 +2445,38 @@ cs: name: "Název" image: "Obrázek" delete_confirm: "Určitě chcete smazat :%{name}: emoji?" + embedding: + get_started: "Pokud chceš zabudovat Discourse do jiných stránek, začni s přidáním hostu." + confirm_delete: "Opravdu chcete smazat tento host?" + sample: "Abyste vytvořili a zabudovali témata z discourse, použijte následující HTML kód na vašem webu. Nahraď REPLACE_ME celkovým URL stránky, do které je zabudováváš." + title: "Zabudování" + host: "Povolené hosty" + edit: "upravit" + category: "Příspěvek do kategorie" + add_host: "Přidat host" + settings: "Nastavení zabudování" + feed_settings: "Nastavení odebírání" + crawling_settings: "Nastavení procházení" + embed_by_username: "Uživatelské jméno pro vytvářéní témat" + embed_post_limit: "Maximální počet příspěvků k zabudování" + embed_truncate: "Useknout zabudované příspěvky" + feed_polling_enabled: "Importovat příspěvky pomocí RSS/ATOM" + save: "Uložit nastavení zabudování" + permalink: + title: "Trvalé odkazy" + url: "URL" + topic_id: "ID tématu" + topic_title: "Téma" + post_id: "ID příspěvku" + post_title: "Příspěvek" + category_id: "ID kategorie" + category_title: "Kategorie" + external_url: "Externí URL" + delete_confirm: Opravdu chcete smazat tento trvalý odkaz? + form: + label: "Nové:" + add: "Přidat" + filter: "Hledat (URL nebo externí URL)" lightbox: download: "download" search_help: @@ -2288,6 +2492,8 @@ cs: categories: 'g, c Kategorie' top: 'g, t Nahoru' bookmarks: 'g, b Záložky' + profile: 'g, p Profil' + messages: 'g, m Zprávy' navigation: title: 'Navigation' jump: '# Jdi na příspěvek #' @@ -2299,12 +2505,14 @@ cs: title: 'Application' create: 'c Create a new topic' notifications: 'n Open notifications' + hamburger_menu: '= Otevře hamburgerové menu' user_profile_menu: 'p Otevře uživatelské menu' show_incoming_updated_topics: '. Ukáže aktualizovaná témata' search: '/ Search' help: '? Otevře seznam klávesových zkratek' dismiss_new_posts: 'x, r Dismiss New/Posts' dismiss_topics: 'x, t Dismiss Topics' + log_out: 'shift+z shift+z Odhlásit se' actions: title: 'Actions' bookmark_topic: 'f Toggle bookmark topic' @@ -2326,8 +2534,6 @@ cs: mark_watching: 'm, w Watch topic' badges: title: Odznaky - allow_title: "může být použito jako titul" - multiple_grant: "může být přiděleno několikrát" badge_count: one: "1 odznak" few: "%{count} odznaky" @@ -2353,75 +2559,3 @@ cs: name: Ostatní posting: name: Přispívání - badge: - editor: - name: Editor - description: První úprava příspěvku. - basic_user: - name: Základní - description: Granted all essential community functions - member: - name: Člen - description: Povoleny pozvánky - regular: - name: Normální - leader: - name: Vůdce - description: Povoleno globální editování, připínání, zavírání, archivace, rozdělení a spojení - welcome: - name: Vítejte - description: Obdrženo líbí se mi - autobiographer: - name: Autor vlastního životopisu - description: Vypněné informace v profilu. - anniversary: - name: Výročí - description: Aktivním členem přes rok, přispěl alespoň jednou - nice_post: - name: Zdařilý příspěvek - description: Obdrženo 10 líbí se na příspěvku. Tento odznak můžete získat opakovaně - good_post: - name: Dobrý příspěvek - description: Obdrženo 25 líbí se na příspěvku. Tento odznak můžete získat opakovaně - great_post: - name: Výborný příspěvek - description: Obdrženo 50 líbí se na příspěvku. Tento odznak můžete získat opakovaně - nice_topic: - name: Zdařilé téma - description: Obdrženo 10 líbí se v tématu. Tento odznak můžete získat opakovaně - good_topic: - name: Dobré téma - description: Obdrženo 25 líbí se v tématu. Tento odznak můžete získat opakovaně - great_topic: - name: Výborné téma - description: Obdrženo 50 líbí se v tématu. Tento odznak můžete získat opakovaně - nice_share: - name: Zdařilé sdílení - description: Sdílení příspěvku s 25 unikátními návštěvníky - good_share: - name: Dobré sdílení - description: Sdílení příspěvku s 300 unikátními návštěvníky - great_share: - name: Výborné sdílení - description: Sdílení příspěvku s 1000 unikátními návštěvníky - first_like: - name: První lajk - description: Líbil se příspěvek - first_flag: - name: První nahlášení - description: Nahlášen příspěvek - first_share: - name: První sdílení - description: Sdílený příspěvek - first_link: - name: První odkaz - description: Vložen interní odkaz na jiné téma - first_quote: - name: První citace - description: Citovat uživatele - read_guidelines: - name: Přečíst pokyny - description: Přečíst komunitní pokyny - reader: - name: Čtenář - description: Přečíst každý příspěvek v tématu s více než 100 příspěvky diff --git a/config/locales/client.da.yml b/config/locales/client.da.yml index 8b0887269ce..893867d73d5 100644 --- a/config/locales/client.da.yml +++ b/config/locales/client.da.yml @@ -100,6 +100,8 @@ da: x_years: one: "1 år senere" other: "%{count} år senere" + previous_month: 'Forrige måned' + next_month: 'Næste måned' share: topic: 'del et link til dette emne' post: 'indlæg #%{postNumber}' @@ -109,6 +111,9 @@ da: google+: 'del dette link på Google+' email: 'send dette link i en e-mail' action_codes: + split_topic: "delte dette emne op %{when}" + invited_user: "Inviterede %{who} %{when}" + removed_user: "fjernede %{who} %{when}" autoclosed: enabled: 'lukket %{when}' disabled: 'åbnet %{when}' @@ -117,6 +122,16 @@ da: disabled: 'åbnet %{when}' archived: enabled: 'arkiveret %{when}' + disabled: 'dearkiveret %{when}' + pinned: + enabled: 'fastgjort %{when}' + disabled: 'frigjort %{when}' + pinned_globally: + enabled: 'fastgjort globalt %{when}' + disabled: 'frigjort %{when}' + visible: + enabled: 'listet %{when}' + disabled: 'aflistet %{when}' topic_admin_menu: "administrationshandlinger på emne" emails_are_disabled: "Alle udgående emails er blevet deaktiveret globalt af en administrator. Ingen emailnotifikationer af nogen slags vil blive sendt." edit: 'redigér titel og kategori for dette emne' @@ -151,6 +166,8 @@ da: more: "Mere" less: "Mindre" never: "aldrig" + every_30_minutes: "hvert 30. minut" + every_hour: "hver time" daily: "dagligt" weekly: "ugentligt" every_two_weeks: "hver anden uge" @@ -162,6 +179,7 @@ da: other: "{{count}} tegn" suggested_topics: title: "Foreslåede emner" + pm_title: "Foreslåede beskeder" about: simple_title: "Om" title: "Om %{title}" @@ -178,7 +196,7 @@ da: user_count: "Nye brugere" active_user_count: "Aktive brugere" contact: "Kontakt os" - contact_info: "I tilfælde af kritiske situationer eller vigtige spørgsmål angående denne side, kontakt os venligst på %{contact_emal}." + contact_info: "I tilfælde af kritiske situationer eller vigtige spørgsmål angående denne side, kontakt os venligst på %{contact_info}." bookmarked: title: "Bogmærke" clear_bookmarks: "Ryd Bogmærker" @@ -209,6 +227,7 @@ da: saved: "Gemt!" upload: "Upload" uploading: "Uploader…" + uploading_filename: "Uploader {{filename}}..." uploaded: "Uploadet!" enable: "Aktiver" disable: "Deaktiver" @@ -216,6 +235,7 @@ da: revert: "Gendan" failed: "Fejlet" switch_to_anon: "Anonym tilstand" + switch_from_anon: "Afbryd anonym tilstand" banner: close: "Afvis denne banner." edit: "Rediger dette banner >>" @@ -238,7 +258,7 @@ da: one: "Det emne har 1 indlæg der afventer godkendelse" other: "Dette emne har {{count}} indlæg der afventer godkendelse" confirm: "Gem ændringer" - delete_prompt: "Er du sikker på, at du vil slette %{username}? Alle brugerens indlæg bliver slettet og email og IP-adresse bliver blokeret." + delete_prompt: "Er du sikker på at du vil slette %{username}? Det fjerner alle indlæg og blokerer email og IP-adresse." approval: title: "Indlæg afventer godkendelse" description: "Vi har modtaget dit indlæg, men det skal først godkendes af en moderator. Hav venligst tålmodighed." @@ -265,8 +285,8 @@ da: title: "Brugere" likes_given: "Givet" likes_received: "Modtaget" - topics_entered: "Indtastet" - topics_entered_long: "Emner indtastet" + topics_entered: "Besøgte" + topics_entered_long: "Emner besøgt" time_read: "Læsetid" topic_count: "Emner" topic_count_long: "Emner oprettet" @@ -281,21 +301,47 @@ da: one: "1 bruger" other: "%{count} brugere" groups: + empty: + posts: "Der er ingen indlæg af medlemmer af denne gruppe." + members: "Der er ingen medlemmer i denne gruppe." + mentions: "Denne gruppe er ikke nævnt." + messages: "Der er ingen besked til denne gruppe." + topics: "Der er intet emne af medlemmer af denne gruppe." + add: "Tilføj" + selector_placeholder: "Tilføj medlemmer" + owner: "ejer" visible: "Gruppen er synlige for alle brugere" title: one: "gruppe" other: "grupper" members: "Medlemmer" + topics: "Emner" posts: "Indlæg" + mentions: "Omtaler" + messages: "Beskeder" alias_levels: - title: "Hvem kan bruge denne gruppe som et alias?" + title: "Hvem kan sende beskeder til og @nævne denne gruppe?" nobody: "Ingen" only_admins: "Kun administratore" mods_and_admins: "Kun moderatore og administratore" members_mods_and_admins: "Kun gruppe medlemmer, moderatore og administratore" everyone: "Alle" trust_levels: + title: "Tillidsniveau der automatisk tildeles medlemmer når de oprettes:" none: "Ingen" + notifications: + watching: + title: "Kigger" + description: "Du får beskeder om hvert nyt indlæg i hver besked og antallet af nye svar bliver vist." + tracking: + title: "Følger" + description: "Du får besked hvis nogen nævner dit @navn eller svarer dig og antallet af nye svar bliver vist." + regular: + title: "Normal" + description: "Du får besked hvis nogen nævner dit @navn " + muted: + title: "Tavs" + description: "Du får aldrig beskeder om nye emner i denne gruppe." user_action_groups: '1': "Likes givet" '2': "Likes modtaget" @@ -305,7 +351,6 @@ da: '6': "Svar" '7': "Referencer" '9': "Citater" - '10': "Favoritter" '11': "Ændringer" '12': "Sendte indlæg" '13': "Indbakke" @@ -315,8 +360,15 @@ da: all_subcategories: "Alle" no_subcategory: "ingen" category: "Kategori" + category_list: "Vis liste over kategorier" reorder: + title: "Ret kategoriernes rækkefølge " + title_long: "Omorganiser listen over kategorier" + fix_order: "Lås placeringer" + fix_order_tooltip: "Ikke alle kategorier har et unikt positionsnummer, hvilket kan give uventede resultater." + save: "Gem rækkefølge" apply_all: "Anvend" + position: "Position" posts: "Indlæg" topics: "Emner" latest: "Seneste" @@ -343,7 +395,7 @@ da: username: "brugernavn" trust_level: "TL" read_time: "læse tid" - topics_entered: "emner indtastet" + topics_entered: "emner besøgt" post_count: "# indlæg" confirm_delete_other_accounts: "Er du sikker på, at du vil slette disse kontoer?" user_fields: @@ -365,16 +417,18 @@ da: invited_by: "Inviteret af" trust_level: "Tillidsniveau" notifications: "Underretninger" + statistics: "Statistik" desktop_notifications: + label: "Desktop-notifikationer" + not_supported: "Notifikationer understøttes ikke af denne browser. Beklager." + perm_default: "Slå notifikationer til" perm_denied_btn: "Tilladelse nægtet" - perm_denied_expl: "Du har ikke givet tilladelse til meddelelser. Brug din browser til at aktivere meddelelser og klik derefter på knappen, når du er færdig. (Computer: Ikonet længst til venstre i adresselinjen. Mobil: 'Site info'.)" - disable: "Deaktiver meddelelser" - currently_enabled: "(slået til)" - enable: "Aktiver meddelelser" - currently_disabled: "(slået fra)" + perm_denied_expl: "Du nægtede adgang for notifikationer. Tillad notifikationer via indstillingerne i din browser." + disable: "Deaktiver notifikationer" + enable: "Aktiver notifikationer" each_browser_note: "Bemærk: Du skal ændre indstillingen i alle dine browsere." dismiss_notifications: "Marker alle som læst" - dismiss_notifications_tooltip: "Marker alle ulæste meddelelser som læst" + dismiss_notifications_tooltip: "Marker alle ulæste notifikationer som læst" disable_jump_reply: "Ikke hop til mit indlæg efter jeg svarer" dynamic_favicon: "Vis nyt / opdateret emnetal på browserikon" edit_history_public: "Lad andre brugere se mine tidligere revisioner" @@ -383,7 +437,7 @@ da: change: "skift" moderator: "{{user}} er moderator" admin: "{{user}} er admin" - moderator_tooltip: "Dette bruger er moderator" + moderator_tooltip: "Denne bruger er moderator" admin_tooltip: "Denne bruger er administrator" blocked_tooltip: "Brugeren er blokeret" suspended_notice: "Denne bruger er suspenderet indtil {{date}}." @@ -395,7 +449,7 @@ da: tracked_categories: "Fulgt" tracked_categories_instructions: "Du vil automatisk følge alle nye emner i disse kategorier. En optælling af nye indlæg vises ved emnet." muted_categories: "Ignoreret" - muted_categories_instructions: "Du ignorerer automatisk alle emner i disse kategorier" + muted_categories_instructions: "Du får ikke beskeder om nye emner i disse kategorier og de fremstår ikke i seneste." delete_account: "Slet min konto" delete_account_confirm: "Er du sikker på du vil slette din konto permanent? Dette kan ikke fortrydes!" deleted_yourself: "Din konto er nu slettet." @@ -405,6 +459,7 @@ da: users: "Brugere" muted_users: "Ignoreret" muted_users_instructions: "Undertryk alle notifikationer fra disse brugere." + muted_topics_link: "Vis mute emner" staff_counters: flags_given: "hjælpsomme markeringer" flagged_posts: "markerede indlæg" @@ -413,8 +468,15 @@ da: warnings_received: "advarsler" messages: all: "Alle" - mine: "Mine" - unread: "Ulæste" + inbox: "Indbakke" + sent: "Sendt" + archive: "Arkiv" + groups: "Mine grupper" + bulk_select: "Vælg beskeder" + move_to_inbox: "Flyt til Indbakke" + move_to_archive: "Arkiv" + failed_to_move: "Kunne ikke flytte valgt beskeder (måske problemer med netværket)" + select_all: "Vælg alle" change_password: success: "(e-mail sendt)" in_progress: "(sender e-mail)" @@ -459,10 +521,10 @@ da: ok: "Vi vil sende dig en bekræftelses email" invalid: "Indtast venligst en gyldig email adresse" authenticated: "Din email er blevet bekræftet af {{provider}}" + frequency_immediately: "Vi sender dig en email med det samme, hvis du ikke har læst den ting vi emailer dig om." frequency: - zero: "Vi vil straks sende dig en e-mail, hvis du ikke har læst det vi sender dig en e-mail omkring." - one: "Vi vil kun sende dig en email, hvis vi ikke har set dig det sidste minut." - other: "Vi vil kun sende dig en email, hvis vi ikke har set dig de sidste {{count}} minutter." + one: "Vi sender dig kun email, hvis vi ikke har set dig i det seneste minut." + other: "Vi sender dig kun email. hvis vi ikke har set dig i de sidste {{count}} minutter." name: title: "Navn" instructions: "Dit fulde navn (valgfrit)" @@ -498,12 +560,27 @@ da: title: "Brugerkort-Badge" website: "Site" email_settings: "E-mail" + like_notification_frequency: + title: "Giv besked når liked" + always: "Altid" + first_time_and_daily: "Første gang et indlæg likes og dagligt" + first_time: "Første gang et indlæg likes" + never: "Aldrig" + email_previous_replies: + title: "Inkluder tidligere svar i bunden af emails" + unless_emailed: "medmindre tidligere sendt" + always: "altid" + never: "aldrig" email_digests: title: "Når jeg ikke besøger her, send mig en email med nyheder." + every_30_minutes: "hvert 30. minut" + every_hour: "hver time" daily: "dagligt" every_three_days: "hver tredje dag" weekly: "ugenligt" every_two_weeks: "hver anden uge" + include_tl0_in_digests: "Inkluder indlæg fra nye brugere i opsummerings-mails" + email_in_reply_to: "Inkluder et uddrag af svaret indlæg i emails" email_direct: "Send mig en email når nogen citerer mig, svarer på mit indlæg, nævner mit @brugernavn eller inviterer mig til et emne" email_private_messages: "Send mig en email når nogen sender mig en besked" email_always: "Send mig email-notifikationer, selv når jeg er aktiv på websitet" @@ -534,12 +611,16 @@ da: user: "Inviteret bruger" sent: "Sendt" none: "Der er ingen afventende invitationer." - truncated: "Viser de første {{count}} invitationer." + truncated: + one: "Viser den første invitation." + other: "Viser de første {{count}} invitationer." redeemed: "Brugte invitationer" redeemed_tab: "Indløst" + redeemed_tab_with_count: "Indløst ({{count}})" redeemed_at: "Invitation brugt" pending: "Udestående invitationer" pending_tab: "Afventende" + pending_tab_with_count: "Ventende ({{count}})" topics_entered: "Emner åbnet" posts_read_count: "Indlæg læst" expired: "Denne invitation er forældet" @@ -552,6 +633,7 @@ da: account_age_days: "Kontoens alder i dage" create: "Send en invitation" generate_link: "Kopier invitations-link" + generated_link_message: '

    Invitationslink genereret!

    Invitationslinket er kun gyldigt for denne email-adresse: %{invitedEmail}

    ' bulk_invite: none: "Du har ikke inviteret nogen her endnu. Du kan sende individuelle invitationer eller invitere en masse mennesker på én gang ved at uploade en samlet liste over invitationer." text: "Masse invitering fra en fil" @@ -566,6 +648,15 @@ da: same_as_email: "Dit password er det samme som din email adresse." ok: "Din adgangskode ser fin ud." instructions: "Mindst %{count} tegn" + summary: + title: "Resume" + stats: "Statistik" + top_replies: "Top svar" + more_replies: "Flere svar" + top_topics: "Top emner" + more_topics: "Flere emner" + top_badges: "Top badges" + more_badges: "Flere badges" associated_accounts: "Logins" ip_address: title: "Sidste IP-adresse" @@ -591,11 +682,13 @@ da: server: "Server fejl" forbidden: "Adgang nægtet" unknown: "Fejl" + not_found: "Side ikke fundet" desc: network: "Tjek din internetforbindelse." network_fixed: "Det ser ud som om den er tilbage." server: "Fejlkode: {{status}}" forbidden: "Du har ikke tilladelser til at se det" + not_found: "Ups, programmet forsøgte at indlæse en URL der ikke eksisterer." unknown: "Noget gik galt." buttons: back: "Gå tilbage" @@ -606,8 +699,15 @@ da: logout: "Du er blevet logget ud." refresh: "Opdater" read_only_mode: - enabled: "Skrivebeskyttet tilstand er aktiv. Du kan fortsætte med at læse indlæg, men du kan ikke ændre noget." + enabled: "Dette website kan kun læses lige nu. Fortsæt endelig med at kigge, men der kan ikke svares, likes eller andet indtil videre." login_disabled: "Log in er deaktiveret midlertidigt, da forummet er i \"kun læsnings\" tilstand." + logout_disabled: "Log ud er deaktivere mens websitet kun kan læses." + too_few_topics_and_posts_notice: "Lad os få startet denne diskussion! Der er i øjeblikket %{currentTopics} / %{requiredTopics} emner og %{currentPosts} / %{requiredPosts} indlæg. Nye besøgende har brug for samtaler at læse og svare på." + too_few_topics_notice: "Lad os få startet denne diskussion ! Der er i øjeblikket %{currentTopics} / %{requiredTopics} emner. Nye besøgende har brug for samtaler at læse og svare på." + too_few_posts_notice: "Lad os få startet denne diskussion ! Der er i øjeblikket %{currentPosts} / %{requiredPosts} indlæg. Nye besøgende har brug for samtaler at læse og svare på." + logs_error_rate_notice: + reached: "%{timestamp}: Aktuelle mængde på %{rate} har nået websitets begrænsning på %{siteSettingRate}." + exceeded: "%{timestamp}: Aktuelle mængde på %{rate} har overskredet websitets begrænsning på %{siteSettingRate}." learn_more: "Læs mere…" year: 'år' year_desc: 'Indlæg oprettet i de seneste 365 dage' @@ -624,10 +724,17 @@ da: replies_lowercase: one: svar other: svar + signup_cta: + sign_up: "Tilmeld dig" + hide_session: "Mind mig om det i morgen" + hide_forever: "nej tak" + hidden_for_session: "OK, jeg spørger dig i morgen. Du kan også altid bruge \"Log på\" til at oprette en konto." + intro: "Hejsa! :heart_eyes: Det ser ud til, at du følger godt med i samtalerne, men du har endnu ikke oprettet en konto." + value_prop: "Når du opretter en konto, så kan vi huske hvad du har læst, så du altid kan fortsætte, hvor du er kommet til. Du får også notifikationer - her og på email - når nye interessante indlæg postes. Og du kan like indlæg og dele begejstringen. :heartbeat:" summary: enabled_description: "Du ser et sammendrag af dette emne: kun de mest interessante indlæg som andre finder interresante." - description: "Der er {{count}} svar." - description_time: "Der er {{count}} svar og det vil tage ca. {{readingTime}} minutter at læse." + description: "Der er {{replyCount}} svar." + description_time: "Der er {{replyCount}} svar med en estimeret læsetid på {{readingTime}} minutter." enable: 'Opsummér dette emne' disable: 'Vis alle indlæg' deleted_filter: @@ -681,6 +788,9 @@ da: admin_not_allowed_from_ip_address: "Du kan ikke logge på som administrator fra denne IP adresse." resend_activation_email: "Klik her for at sende aktiverings-e-mail’en igen." sent_activation_email_again: "Vi har sendt endnu en aktiverings-e-mail til dig på {{currentEmail}}. Det kan tage nogen få minutter før den når frem; kontrollér også din spam-mappe." + to_continue: "Log venligst ind" + preferences: "Du skal være logget ind for at ændre præferencer." + forgot: "Jeg kan ikke huske min kontos detaljer" google: title: "med Google" message: "Logger ind med Google (kontrollér at pop-op-blokering ikke er aktiv)" @@ -690,6 +800,9 @@ da: twitter: title: "med Twitter" message: "Logger ind med Twitter (kontrollér at pop-op-blokering ikke er aktiv)" + instagram: + title: "med Instagram" + message: "Validering med Instagram (vær sikker på at pop-up blokering ikke er slået til)" facebook: title: "med Facebook" message: "Logger ind med Facebook (kontrollér at pop-op-blokering ikke er aktiv)" @@ -703,15 +816,24 @@ da: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Skift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "mere..." + options: "Indstillinger" + whisper: "hvisken" add_warning: "Dette er en officiel advarsel." + toggle_whisper: "Slå hvisken til/fra" posting_not_on_topic: "Hvilket emne vil du svare på?" saving_draft_tip: "gemmer..." saved_draft_tip: "gemt" saved_local_draft_tip: "gemt lokalt" similar_topics: "Dit emne minder om…" drafts_offline: "kladder offline" + group_mentioned: "Ved at bruge {{group}} informerer du {{count}} personer." error: title_missing: "Titlen er påkrævet" title_too_short: "Titlen skal være på mindst {{min}} tegn" @@ -732,8 +854,9 @@ da: title_placeholder: "Hvad handler diskussionen om i korte træk?" edit_reason_placeholder: "hvorfor redigerer du?" show_edit_reason: "(tilføj en begrundelse for ændringen)" + reply_placeholder: "Skriv her. Brug Markdown, BBCode eller HTML til at formattere. Træk eller indsæt billeder." view_new_post: "Se dit nye indlæg." - saving: "Gemmer…" + saving: "Gemmer." saved: "Gemt!" saved_draft: "Kladde i gang. Vælg for at fortsætte med den." uploading: "Uploader…" @@ -748,6 +871,7 @@ da: link_description: "skriv linkets beskrivelse her" link_dialog_title: "Indsæt link" link_optional_text: "evt. titel" + link_placeholder: "http://example.com \"valgfri tekst\"" quote_title: "Citatblok" quote_text: "Citatblok" code_title: "Præformateret tekst" @@ -760,10 +884,11 @@ da: heading_title: "Overskrift" heading_text: "Overskrift" hr_title: "Vandret streg" - undo_title: "Fortryd" - redo_title: "Gentag" help: "Hjælp til Markdown-redigering" toggler: "skjul eller vis editor-panelet" + modal_ok: "OK" + modal_cancel: "Annuller" + cant_send_pm: "Beklager, du kan ikke sende en besked til %{username}." admin_options_title: "Valgfrie staff-indstillinger for dette emne" auto_close: label: "Tidspunkt for automatisk lukning af emne:" @@ -775,16 +900,18 @@ da: units: "(# timer)" examples: 'Indtast antal timer (24).' notifications: - title: "notifikation ved @navns nævnelse, svar til dine indlæg og emner, beskeder, mv." + title: "notifikationer ved @navns nævnelse, svar på dine indlæg og emner, beskeder, mv." none: "Ikke i stand til at indlæse notifikationer for tiden." more: "se ældre notifikationer" total_flagged: "total markerede indlæg" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -792,8 +919,27 @@ da: moved_post: "

    {{username}} moved {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Du blev tildelt '{{description}}'

    " + group_message_summary: + one: "

    {{count}} besked i din {{group_name}} inbox

    " + other: "

    {{count}} beskeder i din {{group_name}} inbox

    " + alt: + mentioned: "Nævnt af" + quoted: "Citeret af" + replied: "Svaret" + posted: "Indlæg af" + edited: "Rediger dit indlæg af" + liked: "Likede dit indlæg" + private_message: "Privat besked fra" + invited_to_private_message: "Inviteret til en privat besked fra" + invited_to_topic: "Inviteret til et indlæg fra" + invitee_accepted: "Invitation accepteret af" + moved_post: "Dit indlæg blev flyttet af" + linked: "Link til dit indlæg" + granted_badge: "Badge tildelt" + group_message_summary: "Besker i gruppens indbakke" popup: mentioned: '{{username}} nævnte dig i "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} nævnte dig i "{{topic}}" - {{site_title}}' quoted: '{{username}} citerede dig i "{{topic}}" - {{site_title}}' replied: '{{username}} svarede dig i "{{topic}}" - {{site_title}}' posted: '{{username}} skrev i "{{topic}}" - {{site_title}}' @@ -805,14 +951,25 @@ da: from_my_computer: "Fra min computer" from_the_web: "Fra nettet" remote_tip: "link til billede" - remote_tip_with_attachments: "link til billede eller fil ({{authorized_extensions}})" + remote_tip_with_attachments: "link til billede eller fil {{authorized_extensions}}" local_tip: "vælg billeder fra din enhed" - local_tip_with_attachments: "vælg billeder eller filer fra din enhed ({{authorized_extensions}})" + local_tip_with_attachments: "vælg billeder eller filer fra din enhed {{authorized_extensions}}" hint: "(du kan også trække og slippe ind i editoren for at uploade dem)" + hint_for_supported_browsers: "du kan også bruge træk-og-slip eller indsætte billeder i editoren" uploading: "Uploader billede" select_file: "Vælg fil" image_link: "link som dit billede vil pege på" search: + sort_by: "Sorter efter" + relevance: "Relevans" + latest_post: "Seneste indlæg" + most_viewed: "Mest sete" + most_liked: "Mest likede" + select_all: "Vælg alle" + clear_all: "Ryd alle" + result_count: + one: "1 resultat for \"{{term}}\"" + other: "{{count}} reultater for \"{{term}}\"" title: "søg efter emner, indlæg, brugere eller kategorier" no_results: "Ingen resultater fundet." no_more_results: "Ikke flere resultater." @@ -825,17 +982,20 @@ da: topic: "Søg i dette emne" private_messages: "Søg i beskeder" hamburger_menu: "gå til en anden emneliste eller kategori" + new_item: "ny" go_back: 'gå tilbage' not_logged_in_user: 'bruger side, med oversigt over aktivitet og indstillinger' current_user: 'gå til brugerside' topics: bulk: + unlist_topics: "Fjern emner fra liste" reset_read: "Nulstil \"læst\"" delete: "Slet emner" - dismiss_posts: "Afvis indlæg" - dismiss_posts_tooltip: "Nulstil \"ulæste\" på disse emner, men fortsæt med at vise dem på min \"ulæste\" liste når der kommer nye indlæg" - dismiss_topics: "Afvist Emner" - dismiss_topics_tooltip: "Stop med at vide disse emner i min \"ulæste\" liste når der kommer nye indlæg" + dismiss: "Afvis" + dismiss_read: "Afvis alle ulæste" + dismiss_button: "Afvis..." + dismiss_tooltip: "Afvis kun nye indlæg eller stop med at følge emner" + also_dismiss_topics: "Stop med at følge disse emner så de aldrig mere kommer op som ulæste igen" dismiss_new: "Afvis nye" toggle: "vælg flere emner af gangen" actions: "Handlinger på flere indlæg" @@ -858,9 +1018,6 @@ da: category: "Der er ingen emner i kategorien {{category}}." top: "Der er ingen top emner" search: "Der er ingen søgeresultater." - educate: - new: '

    Dine nye emner vises her.

    Som standard, betragtes emner som nye og vil vise en ny indikator hvis de er lavet inden for de sidste 2 dage.

    Du kan skifte dette i dine instillinger.

    ' - unread: '

    Dine ulæste emner vises her.

    Som standard, betragtes emner som ulæste og vil vise en ulæst-tæller 1 hvis du:

    • Lavede emnet
    • Svarede på emnet
    • læste emnet i mere end 4 min.

    Eller hvis du udtrykkeligt har sat emnet til Sporet eller Overvåget via notifikations kontrollen i budnen af hvert emne.

    Du kan ændre dette i dine instillinger.

    ' bottom: latest: "Der er ikke flere populære emner." hot: "There are no more hot topics." @@ -873,10 +1030,19 @@ da: bookmarks: "Der er ikke flere bogmærkede emner." search: "Der er ikke flere søgeresultater." topic: + unsubscribe: + stop_notifications: "Du vil nu modtage færre notifikationer for {{title}}" + change_notification_state: "Din nuværende notifikationstilstand er" filter_to: "Vis {{post_count}} indlæg i emnet" create: 'Nyt emne' create_long: 'Opret et nyt emne i debatten' private_message: 'Start en besked' + archive_message: + help: 'Flyt beskeder til dit arkiv' + title: 'Arkiv' + move_to_inbox: + title: 'Flyt til Indbakke' + help: 'Flyt beskeder tilbage til Indbakke' list: 'Emner' new: 'nyt emne' unread: 'ulæste' @@ -927,6 +1093,7 @@ da: auto_close_title: 'Indstillinger for automatisk lukning' auto_close_save: "Gem" auto_close_remove: "Luk ikke dette emne automatisk" + auto_close_immediate: "Seneste indlæg i emnet er allerede %{hours} timer gammelt så emnet bliver lukket med det samme." progress: title: emnestatus go_top: "top" @@ -976,7 +1143,7 @@ da: description: "Du vil aldrig få notifikationer om denne besked." muted: title: "Stille!" - description: "du får ikke besked om nogen hændelser i dette emne, og det vil ikke fremgå af din liste over ulæste emner." + description: "Du vil aldrig få beskeder om noget i indlæggene og de vil ikke vises i seneste." actions: recover: "Gendan emne" delete: "Slet emne" @@ -1012,26 +1179,30 @@ da: success_message: 'Du har nu rapporteret dette emne til administrator.' feature_topic: title: "Fremhæv dette emne" + pin: "Fastgør dette emne til toppen af kategorien {{categoryLink}} indtil" confirm_pin: "Du har allerede {{count}} fastgjorte emner. Fastgjorte emner kan være irriterende for nye og anonyme brugere. Er du sikker på du vil fastgøre et nyt emne i denne kategori?" unpin: "Fjern dette emne fra starten af listen i {{categoryLink}} kategorien." + unpin_until: "Fjern dette emne fra toppen af kategorien {{categoryLink}} eller vent til %{until}." pin_note: "Brugere kan unpinne emnet individuelt." + pin_validation: "Der skal angives en dato for at fastgøre dette emne" + not_pinned: "Der er ingen fastgjorte emner i {{categoryLink}}." already_pinned: - zero: "Der er ingen fastgjorte emner i {{categoryLink}}." - one: "Emner fastgjorte i {{categoryLink}}: 1." - other: "Fastgjorte emner i {{categoryLink}}: {{count}}." + one: "Emner fastgjort i {{categoryLink}}: 1" + other: "Emner fastgjort i {{categoryLink}}: {{count}}" + pin_globally: "Fastgør dette emne til toppen af alle emnelister indtil" confirm_pin_globally: "Du har allerede {{count}} globalt fastgjorte emner. For mange fastgjorte emner kan være irriterende for nye og anonyme brugere. Er du sikker på du vil fastgøre et emne mere globalt?" unpin_globally: "Fjern dette emne fra toppen af alle emne lister." + unpin_globally_until: "Fjern dette emne fra toppen af alle emnelister eller vent til %{until}." global_pin_note: "Brugere kan unpinne emnet individuelt." + not_pinned_globally: "Der er ingen globalt fastgjorte emner." already_pinned_globally: - zero: "Der er ingen globalt fastgjorte emner." - one: "Globalt fastgjorte emner: 1." - other: "Emner fastgjort globalt: {{count}}." + one: "Globalt fastgjorte emner: 1" + other: "Globalt fastgjorte emner: {{count}}" make_banner: "Gør dette emne til en banner, der kommer til at stå i toppen på alle sider." remove_banner: "Fjern banneret, der står på toppen af alle sider." banner_note: "Brugere kan fjernet banneret ved at lukke det. Kun én banner kan være aktiv ad gangen." - already_banner: - zero: "Der er intet banner emne." - one: "Der er allerede et banner emne." + no_banner_exists: "Der er ikke noget banner-emne." + banner_exists: "Der er aktuelt et banner-emne." inviting: "Inviterer…" automatically_add_to_groups_optional: "Denne invitation giver også adgang til disse grupper: (valgfrit, kun for administrator)" automatically_add_to_groups_required: "Denne invitation giver også adgang til disse grupper: (Påkrævet, kun for administrator)" @@ -1043,6 +1214,7 @@ da: success: "Vi har inviteret denne bruger til at være med i denne besked." error: "Beklager, der skete en fejl, da vi forsøgte at invitere brugeren." group_name: "gruppe navn" + controls: "Emnestyring" invite_reply: title: 'Invitér' username_placeholder: "brugernavn" @@ -1089,6 +1261,12 @@ da: one: "Vælg den nye ejer af indlægget, oprindeligt skrevet af {{old_user}}." other: "Vælg den nye ejer af {{count}} indlæg, oprindeligt skrevet af {{old_user}}." instructions_warn: "Bemærk at tidligere notifikationer på dette emne vil ikke blive overført til den nye bruger.\n
    Advarsel: På nuværende tidspunkt, vil ingen data der er afhængig af dette indlæg blive overført til den nye bruger. Brug forsigtigt." + change_timestamp: + title: "Ret tidsstempel" + action: "ret tidsstempel" + invalid_timestamp: "Tidsstempel kan ikke være i fremtiden" + error: "Der opstod en fejl under rettelsen af tidsstemplet for dette emne." + instructions: "Vælg venligst det nye tidsstempel for dette emne. Indlæg under emnet vil blive opdateret så de har samme tidsforskel." multi_select: select: 'vælg' selected: 'valgt ({{count}})' @@ -1101,6 +1279,8 @@ da: one: Du har valgt 1 indlæg. other: Du har valgt {{count}} indlæg. post: + reply: " {{replyAvatar}} {{usernameLink}}" + reply_topic: " {{link}}" quote_reply: "citér svar" edit: "Redigerer {{link}} {{replyAvatar}} {{username}}" edit_reason: "Reason: " @@ -1129,10 +1309,10 @@ da: has_likes_title: one: "1 likede dette indlæg" other: "{{count}} likede dette indlæg" + has_likes_title_only_you: "du likede dette indlæg" has_likes_title_you: - zero: "du likede dette indlæg" one: "du og 1 anden likede dette indlæg" - other: "Du og {{count}} andre likede dette indlæg" + other: "du og {{count}} andre likede dette indlæg" errors: create: "Beklager, der opstod en fejl under oprettelsen af dit indlæg. Prøv venligst igen." edit: "Beklager, der opstrod en fejl under redigeringen af dit indlæg. Prøv venligst igen." @@ -1150,10 +1330,12 @@ da: no_value: "Nej" yes_value: "Ja" via_email: "dette indlæg blev oprettet via email" + whisper: "dette indlæg er en privat hvisken for moderatorer" wiki: - about: "dette indlæg er en wiki; almindelige brugere kan redigere den" + about: "dette indlæg er en wiki" archetypes: save: 'Gem indstillinger' + few_likes_left: "Tak fordi du liker! Du har kun få likes tilbage i dag." controls: reply: "begynd at skrive et svar på dette indlæg" like: "like dette indlæg" @@ -1179,6 +1361,7 @@ da: revert_to_regular: "Fjern Personale farve" rebake: "Gendan HTML" unhide: "Vis" + change_owner: "Skift ejerskab" actions: flag: 'Flag' defer_flags: @@ -1200,17 +1383,14 @@ da: like: "Undo like" vote: "Undo vote" people: - off_topic: "{{icons}} markerede dette som urelevant for emnet" - spam: "{{icons}} markerede dette som spam" - spam_with_url: "{{icons}} markerede dette som spam" - inappropriate: "{{icons}} markerede dette som upassende" - notify_moderators: "{{icons}} underrettede moderatorer" - notify_moderators_with_url: "{{icons}} underrettede moderatorer" - notify_user: "{{icons}} har sendt en besked" - notify_user_with_url: "{{icons}} sendte en besked" - bookmark: "{{icons}} bogmærker" - like: "{{icons}} likes" - vote: "{{icons}} stemmer" + off_topic: "markerede dette som off-topic" + spam: "markerede dette som spam" + inappropriate: "markerede dette som upassende" + notify_moderators: "informerede moderatorer" + notify_user: "sendte en besked" + bookmark: "bogmærkede dette" + like: "likede dette" + vote: "stemte for dette" by_you: off_topic: "Du flagede dette som off-topic" spam: "Du flagede dette som spam" @@ -1270,10 +1450,6 @@ da: vote: one: "1 person stemte for dette indlæg" other: "{{count}} personer stemte for dette indlæg" - edits: - one: én ændring - other: "{{count}} ændringer" - zero: ingen ændringer delete: confirm: one: "Er du sikker på, at du vil slette indlægget?" @@ -1286,6 +1462,7 @@ da: last: "Sidste udgave" hide: "Skjul udgave" show: "Vis udgave" + revert: "Gå tilbage til denne udgave" comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" displays: inline: @@ -1310,6 +1487,7 @@ da: topic_template: "Skabelon for emne" delete: 'Slet kategori' create: 'Ny kategori' + create_long: 'Opret en ny kategori' save: 'Gem kategori' slug: 'Kategori simpelt navn' slug_placeholder: '(Valgfri) gennemstregede-ord for URL' @@ -1332,6 +1510,7 @@ da: change_in_category_topic: "besøg kategoriemnet for at redigere beskrivelsen" already_used: 'This color has been used by another category' security: "Sikkerhed" + special_warning: "Advarsel: Denne kategori er forud-seedet og sikkerhedsindstillingerne kan ikke redigeres. Hvis du ikke ønsker at bruge denne kategori, bør du slette den snarere end at genbruge den til et andet formål." images: "Billeder" auto_close_label: "Luk automatisk emner efter:" auto_close_units: "timer" @@ -1339,6 +1518,7 @@ da: email_in_allow_strangers: "Accepter emails fra ikke oprettede brugere" email_in_disabled: "Nye emner via email er deaktiveret i Site opsætning. For at aktivere oprettelse af nye emner via email," email_in_disabled_click: 'aktiver "email ind" indstilligen.' + suppress_from_homepage: "Undertryk denne kategori fra hjemmesiden" allow_badges_label: "Tillad af badges bliver tildelt i denne kategori" edit_permissions: "Redigér tilladelser" add_permission: "Tilføj tilladelse" @@ -1350,20 +1530,19 @@ da: parent: "Overordnet kategori" notifications: watching: - title: "Kigger" - description: "Du overvåger automatisk alle emner i disse kategorier. Du vil få en notifikation ved alle nye indlæg og emner, og antallet af nye svar vil stå ved siden af emnerne." + title: "Overvåger" + description: "Du overvåger automatisk alle emner i disse kategorier. Du vil få en notifikation ved alle nye indlæg i alle emner, og antallet af nye svar vil blive vist." tracking: title: "Følger" - description: "Du vil automatisk følge alle nye emner i disse kategorier. En optælling af nye svar vises ved emnerne." + description: "Du følger automatisk alle nye emner i disse kategorier. Du vil blive underrettet hvis nogen nævner dit navn eller svarer dig, og antallet af nye svar vil blive vist." regular: - title: "Standard" + title: "Normal" description: "Du vil modtage en notifikation, hvis nogen nævner dit @name eller svarer dig." muted: title: "Ignoreret" - description: "Du ignorerer automatisk alle emner i disse kategorier. De vil heller ikke stå i sin \"ulæste\" indikation." + description: "Du vil aldrig få besked om noget om nye emner i kategorierne og de vises heller ikke i seneste." flagging: title: 'Tak fordi du hjælper med at holde vores forum civiliseret!' - private_reminder: 'flag er private, de er kun

    synlige for personalet' action: 'Flag indlæg' take_action: "Reagér" notify_action: 'Besked' @@ -1375,6 +1554,7 @@ da: submit_tooltip: "Send privat markeringen" take_action_tooltip: "Nå til markerings niveauer med det samme, i stedet for at vente på flere markeringer fra fælleskabet" cant: "Beklager, du kan i øjeblikket ikke flage dette indlæg." + notify_staff: 'Informer staff privat' formatted_name: off_topic: "Det holder sig ikke til emnet" inappropriate: "Det er upassende" @@ -1406,12 +1586,14 @@ da: help: "emnet er låst; det modtager ikke flere svar" archived: help: "emnet er arkiveret; det er frosset og kan ikke ændres" + locked_and_archived: + help: "Dette emne er lukket og arkiveret; der kan ikke længere postes nye indlæg, og emner kan ikke ændres." unpinned: title: "Ikke fastgjort" help: "Dette emne er ikke fastgjort for dig; det vil blive vist i den normale rækkefølge" pinned_globally: title: "Fastgjort globalt" - help: "Dette emne er fastgjort globalt; det vil blive vist øverst på alle lister" + help: "Dette emne er globalt fastgjort; det vises i toppen af seneste og i dets kategori" pinned: title: "Fastgjort" help: "Dette emne er fastgjort for dig; det vil blive vist i toppen af dets kategori" @@ -1454,9 +1636,9 @@ da: with_topics: "%{filter} emner" with_category: "%{filter} %{category} emner" latest: - title: - zero: "Seneste" - one: "Senest (1)" + title: "Seneste" + title_with_count: + one: "Seneste (1)" other: "Seneste ({{count}})" help: "de seneste emner" hot: @@ -1473,10 +1655,10 @@ da: title_in: "Kategori - {{categoryName}}" help: "alle emner grupperet efter kategori" unread: - title: - zero: "Ulæste" + title: "Ulæst" + title_with_count: one: "Ulæst (1)" - other: "Ulæst ({{count}})" + other: "Ulæste ({{count}})" help: "emner du følger med i lige nu med ulæste indlæg" lower_title_with_count: one: "1 ulæst" @@ -1484,11 +1666,11 @@ da: new: lower_title_with_count: one: "1 ny" - other: "{{count}} nye indlæg" + other: "{{count}} nye" lower_title: "Ny" - title: - zero: "Nye" - one: "Ny (1)" + title: "Nye" + title_with_count: + one: "Nye (1)" other: "Nye ({{count}})" help: "Emner oprettet i de seneste par dage" posted: @@ -1498,8 +1680,8 @@ da: title: "Bogmærker" help: "emner du har bogmærket" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "populære emner i kategorien {{categoryName}}" @@ -1581,6 +1763,7 @@ da: refresh_report: "Genopfrisk rapporten" start_date: "Start dato" end_date: "Slut dato" + groups: "Alle grupper" commits: latest_changes: "Seneste ændringer: opdatér ofte!" by: "af" @@ -1661,15 +1844,24 @@ da: delete_confirm: "Slet denne gruppe?" delete_failed: "Kan ikke slette gruppen. Hvis dette er en automatisk gruppe, kan den ikke ødelægges." delete_member_confirm: "Fjern '%{username}' fra gruppen '%{group}'?" + delete_owner_confirm: "Fjern ejer-privilegier for '%{username}'?" name: "Navn" add: "Tilføj" add_members: "Tilføj medlemmer" custom: "Brugerdefineret" + bulk_complete: "Brugerne er tilføjet gruppen." + bulk: "Tilføj mange brugere til gruppe" + bulk_paste: "Indsæt en liste brugerne eller emails, én per linje:" + bulk_select: "(vælg en gruppe)" automatic: "Automatisk" automatic_membership_email_domains: "Brugere der registrerer med et email domæne der præcist matcher et på denne liste, vil automatisk blive tilføjet til denne gruppe:" automatic_membership_retroactive: "Brug denne email domæne regel til at tilføje brugere der allerede er registrerede brugere" default_title: "Standard titel for alle brugere i denne gruppe" primary_group: "Sæt automatisk som primær gruppe" + group_owners: Ejere + add_owners: Tilføj ejere + incoming_email: "Brugerdefineret indkommende email" + incoming_email_placeholder: "indtast email" api: generate_master: "Generér API-nøgle" none: "Der er ingen aktive API-nøgler i øjeblikket." @@ -1743,11 +1935,9 @@ da: is_disabled: "Gendan er deaktiveret i forum indstillingerne." label: "Genetabler" title: "Gendan backuppen" - confirm: "Er du sikker på du vil gendanne fra denne backup?" rollback: label: "Rul tilbage" title: "Rul databasen tilbage til et tidspunkt hvor tingene virkede" - confirm: "Er du sikker på du vil rulle databasen tilbage?" export_csv: user_archive_confirm: "Er du sikker på du vil downloade dine indlæg?" success: "Eksport er startet, du vil blive notificeret via en besked når denne proces er færdig." @@ -1772,6 +1962,7 @@ da: header: "Header" top: "Top" footer: "Bund" + embedded_css: "Indlejret CSS" head_tag: text: "" title: "HTML som indsættes før -tagget" @@ -1797,6 +1988,14 @@ da: color: "Farve" opacity: "Gennemsigtighed" copy: "Kopier" + email_templates: + title: "Email-skabeloner" + subject: "Emne" + multiple_subjects: "Email-skabelonen har flere emner." + body: "Indhold" + none_selected: "Vælg en email-skabelon for at begynde at redigere." + revert: "Rul ændringer tilbage" + revert_confirm: "Er du sikker på, at du vil rulle ændringerne tilbage?" css_html: title: "CSS, HTML" long_title: "CSS og HTML tilpasninger" @@ -1841,18 +2040,18 @@ da: love: name: 'kærlighed' description: "Like knappens farve." - wiki: - name: 'wiki' - description: "Basis farven der bruges som baggrund i wiki posts." email: - title: "E-mail" + title: "Emails" settings: "Indstillinger" - all: "Alle" + templates: "Skabeloner" + preview_digest: "Forhåndsvisning af sammendrag" sending_test: "Sender test email..." error: "ERROR - %{server_error}" test_error: "Der opstod et problem med at sende test emailen. Dobbelt check dine email indstillinger, verificer at din server ikke blokerer email forbindelser og prøv så igen." sent: "Sendt" skipped: "Droppet" + received: "Modtaget" + rejected: "Afvist" sent_at: "Sendt" time: "Tidspunkt" user: "Bruger" @@ -1862,7 +2061,7 @@ da: send_test: "send test-e-mail" sent_test: "sednt!" delivery_method: "Leveringsmetode" - preview_digest: "Forhåndsvisning af sammendrag" + preview_digest_desc: "Forhåndsvis indholdet af de opsamlings-emails der sendes til inaktive brugere" refresh: "Opdatér" format: "Format" html: "html" @@ -1870,6 +2069,22 @@ da: last_seen_user: "Sidst sete bruge:" reply_key: "Svarnøgle" skipped_reason: "Begrundelse" + incoming_emails: + from_address: "Fra" + to_addresses: "Til" + cc_addresses: "Cc" + subject: "Emne" + error: "Fejl" + none: "Ingen indkommende emails fundet" + modal: + error: "Fejl" + subject: "Emne" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Emne..." + error_placeholder: "Fejl" logs: none: "Ingen logs fundet" filters: @@ -1888,6 +2103,7 @@ da: ip_address: "IP" topic_id: "Emne ID" post_id: "Indlægs ID" + category_id: "Kategori-id" delete: 'Slet' edit: 'Redigér' save: 'Gem' @@ -1918,6 +2134,7 @@ da: change_site_setting: "skift indstillinger for site" change_site_customization: "skift tilpasning af site" delete_site_customization: "slet tilpasning af site" + change_site_text: "skift tekst for site" suspend_user: "suspendér user" unsuspend_user: "ophæv suspendering af bruger" grant_badge: "tildel badge" @@ -1927,6 +2144,16 @@ da: delete_post: "slet indlæg" impersonate: "Udgiv dig for bruger" anonymize_user: "anonymiser bruger" + roll_up: "rul IP-blokke op" + change_category_settings: "ret kategori-indstillinger" + delete_category: "slet kategori" + create_category: "opret kategori" + block_user: "bloker bruger" + unblock_user: "fjern blokering af bruger" + grant_admin: "tildel admin" + revoke_admin: "fjern admin" + grant_moderation: "tildel moderation" + revoke_moderation: "fjern moderation" screened_emails: title: "Blokerede e-mails" description: "Følgende e-mail-adresser kontrolleres når nogen prøver at oprette en konto, og oprettelsen vil enten blive blokeret, eller der vil blive foretaget en anden handling." @@ -1993,9 +2220,9 @@ da: pending: 'Brugere som afvanter godkendelse' newuser: 'Brugere på tillidsniveau 0 (Ny bruger)' basic: 'Brugere på tillidsniveau 1 (Basisbruger)' - regular: 'Brugere på tillidsniveau 2 (bruger)' - leader: 'Brugere på tillidsniveau 3 (Ekspertbruger)' - elder: 'Brugere på tillidsniveau 4 (Advanceret bruger)' + member: 'Bruger på tillidsniveau 2 (Medlem)' + regular: 'Bruger på tillidsniveau 3 (Regulær)' + leader: 'Bruger på tillidsniveau 4 (Leder)' staff: "Personale" admins: 'Admin-brugere' moderators: 'Moderatorer' @@ -2092,6 +2319,8 @@ da: deactivate_failed: "Der opstod et problem ved deaktivering af brugeren." unblock_failed: 'Der opstod et problem ved ophævelsen af brugerens blokering.' block_failed: 'Der opstod et problem ved blokering af brugeren.' + block_confirm: 'Er du sikker på, at du vil blokere brugeren? Bruger kan ikke længere oprette emner eller indlæg.' + block_accept: 'Ja, bloker brugeren' deactivate_explanation: "En deaktiveret bruger skal genvalidere deres e-mail." suspended_explanation: "En suspenderet bruger kan ikke logge ind." block_explanation: "En blokeret bruger kan ikke oprette indlæg eller starte emner." @@ -2105,7 +2334,7 @@ da: unlock_trust_level: "Lås tillidsniveau op" tl3_requirements: title: "Krav for fortrolighedsniveau 3" - table_title: "For de sidste 100 dage:" + table_title: "I de sidste %{time_period} dage:" value_heading: "værdi" requirement_heading: "Obligatoriske" visits: "Besøg" @@ -2164,9 +2393,17 @@ da: field_types: text: 'Tekstfelt' confirm: 'Bekræft' + dropdown: "Rulleboks" site_text: - none: "Vælg en indholdstype for at begynde at redigere." + description: "Du kan ændre alt tekst på dette forum. Start med at søge herunder:" + search: "Søg efter teksten du gerne vil rette" title: 'Tekstindhold' + edit: 'ret' + revert: "Rul ændringer tilbage" + revert_confirm: "Er du sikker på, at du vil rulle ændringerne tilbage?" + go_back: "Tilbage til søgning" + recommended: "Vi anbefaler ændringer i følgende tekst:" + show_overriden: 'Vis kun tilsidesatte' site_settings: show_overriden: 'Vis kun tilsidesatte' title: 'Indstillinger' @@ -2175,7 +2412,7 @@ da: no_results: "Ingen resultater fundet." clear_filter: "Ryd" add_url: "tilføj URL" - add_host: "tilføj host" + add_host: "tilføj server" categories: all_results: 'Alle' required: 'Obligatoriske' @@ -2197,6 +2434,7 @@ da: backups: "Backups" login: "Brugernavn" plugins: "Plugins" + user_preferences: "Brugerpræferencer" badges: title: Badges new_badge: Nyt Badge @@ -2205,6 +2443,7 @@ da: badge: Badge display_name: Vist navn description: Beskrivelse + long_description: Lang beskrivelse badge_type: Badge Type badge_grouping: Gruppe badge_groupings: @@ -2253,10 +2492,10 @@ da: bad_count_warning: header: "ADVARSEL!" text: "Der mangler tildelinger. Dette sker når en SQL query returnerer bruger ID'er eller indlægs IS'er der ikke eksisterer. Dette kan give uventede resultater senere - vær venlig at dobbelt checke din SQL query." + no_grant_count: "Ingen badges til tildeling." grant_count: - zero: "Ingen badges at tildele." - one: "1 badge at tildele." - other: "%{count} badgesat tildele." + one: "1 badge til tildeling." + other: "%{count} badges til tildeling." sample: "Eksempel:" grant: with: %{username} @@ -2271,8 +2510,28 @@ da: image: "Billede" delete_confirm: "Er du sikker på du vil slette emotikonnet: %{name} ?" embedding: + get_started: "Hvis du vil indlejre Discourse på et andet website, skal du starte med at tilføje dets server." + confirm_delete: "Er du sikker på at du vil slette denne server?" + sample: "Tilføj denne HTML til dit site for at oprette og indlejre emner fra discourse. Erstat REPLACE_ME med den kanoniske URL for den side du indlejrer den på," + title: "Indlejring" + host: "Tilladte servere" + edit: "redigér" + category: "Opret i kategorien" + add_host: "Tilføj server" + settings: "Indlejrings-indstillinger" + feed_settings: "Feed-indstillinger" + feed_description: "Hvis du angiver et RSS/ATOM-feed for dit site, kan det forbedre Discourses mulighed for at importere dit indhold." + crawling_settings: "Robot-indstillinger" + crawling_description: "Når Discourse opretter emner for dine indlæg, og der ikke er noget RSS/ATOM-feed, vil den forsøge at parse dit indhold ud fra din HTML. Det kan nogengange være en udfordring at udtrække dit indhold, så vi giver mulighed for at specificere CSS-regler for at gøre udtræk lettere." + embed_by_username: "Brugernavn for oprettelse af emne" + embed_post_limit: "Maksimalt antal indlæg der kan indlejres." + embed_username_key_from_feed: "Nøgle til at udtrække discourse-brugernavn fra feed" + embed_truncate: "Beskær de indlejrede indlæg" + embed_whitelist_selector: "CSS-selektorer for elementer der er tilladte i indlejringer" + embed_blacklist_selector: "CSS-selektorer for elementer der fjernes fra indlejringer" feed_polling_enabled: "Importer indlæg via RSS/ATOM" feed_polling_url: "URL på RSS/ATOM feed der skal kravles" + save: "Gem indlejrings-indstillinger" permalink: title: "Permalinks" url: "URL" @@ -2303,6 +2562,8 @@ da: categories: 'g, c Kategorier' top: 'g, t Top' bookmarks: 'g, b Bogmærker' + profile: 'g, p Profil' + messages: 'g, m Beskeder' navigation: title: 'Navigation' jump: '# Gå til indlæg #' @@ -2321,6 +2582,7 @@ da: help: '? Åben keyboard hjælp' dismiss_new_posts: 'x, r Afvis alle Nye/Indlæg' dismiss_topics: 'x, t Afvis emner' + log_out: 'shift+z shift+z Log ud' actions: title: 'Handlinger' bookmark_topic: 'f Sæt bogmærke i emne' @@ -2341,9 +2603,14 @@ da: mark_tracking: 'm, t Følg emne' mark_watching: 'm, w Iagtag emne' badges: + earned_n_times: + one: "Fortjente dette badge 1 gang" + other: "Fortjente dette badge %{count} gange." + granted_on: "Tildelt %{date}" + others_count: "Andre med dette badge (%{count})" title: Badges - allow_title: "kan bruges som titel" - multiple_grant: "kan gives flere gange" + allow_title: "tilgængelig titel" + multiple_grant: "tildelt flere gange" badge_count: one: "1 Badge" other: "%{count} Badges" @@ -2366,91 +2633,12 @@ da: name: Andre posting: name: Indlæg - badge: - editor: - name: Redigering - description: Første indlæg redigering - basic_user: - name: Basic - description: Givet alle vigtige fællesskab funktioner - member: - name: Medlem - description: Givet invitationer - regular: - name: Stamgæst - description: Givet re-kategoristering, omdøbning, følge links og loungen - leader: - name: Leder - description: Givet global redigering, fastgøring, lukning, arkivering, del og sammensæt - welcome: - name: Velkommen - description: Modtaget et like - autobiographer: - name: Selvbiografi - description: Har udfyldt sin profil information - anniversary: - name: Jubilæum - description: Aktivt medlem i et år, som har skrevet mindst en gang - nice_post: - name: Fint indlæg - description: Har modtaget 10 "likes" på et indlæg. Denne badge kan modtages flere gange. - good_post: - name: Godt indlæg - description: Har modtaget 25 "likes" på et indlæg. Denne badge kan modtages flere gange. - great_post: - name: Rigtig godt indlæg - description: Har modtaget 50 "likes" på et indlæg. Denne badge kan modtages flere gange. - nice_topic: - name: Godt emne - description: Har modtaget 10 "likes" på et emne. Denne badge kan modtages flere gange. - good_topic: - name: Godt emne - description: Har modtaget 25 "likes" på et emne. Denne badge kan modtages flere gange. - great_topic: - name: Fantastisk emne - description: Har modtaget 50 "likes" på et emne. Denne badge kan modtages flere gange. - nice_share: - name: God deling - description: Delt et emne med 25 unikke besøgende - good_share: - name: God deling - description: Delt et indlæg med 300 unikke besøgende - great_share: - name: Fantastisk deling - description: Delt et indlæg med 1000 unikke besøgende - first_like: - name: Første like - description: Har liked et indlæg - first_flag: - name: Første markering - description: Markeret et indlæg - promoter: - name: Promoter - description: Inviterede en bruger - campaigner: - name: Kampagnechef - description: Inviterede 3 brugere (tillidsniveau 1) - champion: - name: Mester - description: Inviterede 5 medlemmer (tillidsniveau 2) - first_share: - name: Første deling - description: Delt et indlæg - first_link: - name: Første link - description: Internt link til et andet emne tilføjet - first_quote: - name: Første citering - description: Citeret en bruger - read_guidelines: - name: Læst retningslinierne - description: Har læst retningslinierne for forummet - reader: - name: Læser - description: Har læst hver eneste indlæg i et emne med mere end 100 posts - popular_link: - name: Populært link - description: Postede et eksternt link med mindst 50 klik - hot_link: - name: Hot link - description: Postede et eksternt link med mindst 300 klik + google_search: | +

    Søg med Google

    +

    + + + + + +

    diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml index 5a57b229696..ccd97821743 100644 --- a/config/locales/client.de.yml +++ b/config/locales/client.de.yml @@ -100,6 +100,8 @@ de: x_years: one: "ein Jahr später" other: "%{count} Jahre später" + previous_month: 'Vormonat' + next_month: 'Nächster Monat' share: topic: 'Teile einen Link zu diesem Thema' post: 'Beitrag #%{postNumber}' @@ -110,6 +112,8 @@ de: email: 'diesen Link per E-Mail senden' action_codes: split_topic: "Thema aufgeteilt, %{when}" + invited_user: "%{who} eingeladen, %{when}" + removed_user: "%{who} entfernt, %{when}" autoclosed: enabled: 'geschlossen, %{when}' disabled: 'geöffnet, %{when}' @@ -130,6 +134,19 @@ de: disabled: 'unsichtbar gemacht, {when}' topic_admin_menu: "Thema administrieren" emails_are_disabled: "Die ausgehende E-Mail-Kommunikation wurde von einem Administrator global deaktiviert. Es werden keinerlei Benachrichtigungen per E-Mail verschickt." + s3: + regions: + us_east_1: "USA Ost (Nord-Virginia)" + us_west_1: "USA West (Nordkalifornien)" + us_west_2: "USA West (Oregon)" + us_gov_west_1: "AWS GovCloud (USA)" + eu_west_1: "EU (Irland)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asien-Pazifik (Singapur)" + ap_southeast_2: "Asien-Pazifik (Sydney)" + ap_northeast_1: "Asien-Pazifik (Tokio)" + ap_northeast_2: "Asien-Pazifik (Seoul)" + sa_east_1: "Südamerika (São Paulo)" edit: 'Titel und Kategorie dieses Themas ändern' not_implemented: "Entschuldige, diese Funktion wurde noch nicht implementiert!" no_value: "Nein" @@ -162,6 +179,8 @@ de: more: "Mehr" less: "Weniger" never: "nie" + every_30_minutes: "alle 30 Minuten" + every_hour: "jede Stunde" daily: "täglich" weekly: "wöchentlich" every_two_weeks: "jede zweite Woche" @@ -173,6 +192,7 @@ de: other: "{{count}} Zeichen" suggested_topics: title: "Vorgeschlagene Themen" + pm_title: "Vorgeschlagene Nachrichten" about: simple_title: "Über uns" title: "Über %{title}" @@ -251,7 +271,7 @@ de: one: "Dieses Thema hat einen Beitrag, der genehmigt werden muss" other: "Dieses Thema hat {{count}} Beiträge, die genehmigt werden müssen" confirm: "Änderungen speichern" - delete_prompt: "Bist du sicher, dass du %{username} löschen möchtest? Es werden alle Beiträge des Benutzers gelöscht und dessen E-Mail- und IP-Adresse geblockt." + delete_prompt: "Möchtest du wirklich %{username} löschen? Damit werden alle Beiträge des Benutzers entfernt und dessen E-Mail- und IP-Adresse geblockt." approval: title: "Beitrag muss genehmigt werden" description: "Wir haben deinen neuen Beitrag erhalten. Dieser muss allerdings zunächst durch einen Moderator freigeschaltet werden. Bitte habe etwas Geduld. " @@ -294,21 +314,47 @@ de: one: "1 Benutzer" other: "%{count} Benutzer" groups: + empty: + posts: "Es gibt keinen Beitrag von Mitgliedern dieser Gruppe." + members: "Diese Gruppe hat keine Mitglieder." + mentions: "Diese Gruppe wurde nicht erwähnt." + messages: "Es gibt keine Nachrichten für diese Gruppe." + topics: "Es gibt kein Thema von Mitgliedern dieser Gruppe." + add: "Hinzufügen" + selector_placeholder: "Mitglieder hinzufügen" + owner: "Eigentümer" visible: "Gruppe ist für alle Benutzer sichtbar" title: one: "Gruppe" other: "Gruppen" members: "Mitglieder" + topics: "Themen" posts: "Beiträge" + mentions: "Erwähnungen" + messages: "Nachrichten" alias_levels: - title: "Wer kann diese Gruppe als Alias verwenden?" + title: "Wer kann diese Gruppe kontaktieren und per @Gruppenname erwähnen?" nobody: "Niemand" only_admins: "Nur Administratoren" mods_and_admins: "Nur Moderatoren und Administratoren" members_mods_and_admins: "Nur Gruppenmitglieder, Moderatoren und Administratoren" everyone: "Jeder" trust_levels: + title: "Vertrauensstufe, die neuen Mitgliedern automatisch verliehen wird:" none: "keine" + notifications: + watching: + title: "Beobachten" + description: "Du wirst über jeden neuen Beitrag in jeder Nachricht benachrichtigt und die Anzahl neuer Antworten wird angezeigt." + tracking: + title: "Verfolgen" + description: "Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet, und die Anzahl neuer Antworten wird angezeigt." + regular: + title: "Normal" + description: "Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet." + muted: + title: "Stummgeschaltet" + description: "Du erhältst keine Benachrichtigungen über neue Themen in dieser Gruppe." user_action_groups: '1': "Abgegebene Likes" '2': "Erhaltene Likes" @@ -318,7 +364,6 @@ de: '6': "Antworten" '7': "Erwähnungen" '9': "Zitate" - '10': "Favoriten" '11': "Änderungen" '12': "Gesendete Objekte" '13': "Posteingang" @@ -328,7 +373,12 @@ de: all_subcategories: "alle" no_subcategory: "keine" category: "Kategorie" + category_list: "Kategorieliste anzeigen" reorder: + title: "Kategorien neu sortieren" + title_long: "Neustrukturierung der Kategorieliste" + fix_order: "Positionen korrigieren" + fix_order_tooltip: "Nicht alle Kategorien haben eine eindeutige Positionsnummer, was zu unerwarteten Ergebnissen führen kann." save: "Reihenfolge speichern" apply_all: "Anwenden" position: "Position" @@ -380,15 +430,15 @@ de: invited_by: "Eingeladen von" trust_level: "Vertrauensstufe" notifications: "Benachrichtigungen" + statistics: "Statistiken" desktop_notifications: label: "Desktop-Benachrichtigungen" not_supported: "Dieser Browser unterstützt leider keine Benachrichtigungen." perm_default: "Benachrichtigungen einschalten" perm_denied_btn: "Zugriff verweigert" + perm_denied_expl: "Du hast das Anzeigen von Benachrichtigungen verboten. Aktiviere die Benachrichtigungen über deine Browser-Einstellungen." disable: "Benachrichtigungen deaktivieren" - currently_enabled: "(derzeit aktiviert)" enable: "Benachrichtigungen aktivieren" - currently_disabled: "(derzeit deaktiviert)" each_browser_note: "Hinweis: Du musst diese Einstellung in jedem von dir verwendeten Browser ändern." dismiss_notifications: "Alle als gelesen markieren" dismiss_notifications_tooltip: "Alle ungelesenen Benachrichtigungen als gelesen markieren" @@ -412,7 +462,7 @@ de: tracked_categories: "Verfolgt" tracked_categories_instructions: "Du wirst automatisch allen neuen Themen in diesen Kategorien folgen. Die Anzahl der neuen Antworten wird bei den betroffenen Themen angezeigt." muted_categories: "Stummgeschaltet" - muted_categories_instructions: "Du erhältst keine Benachrichtigungen über neue Themen in diesen Kategorien und sie werden nicht in deiner Liste ungelesener Themen aufscheinen." + muted_categories_instructions: "Du erhältst keine Benachrichtigungen über neue Themen in dieser Kategorie und die Themen werden auch nicht in der Liste der aktuellen Themen erscheinen." delete_account: "Lösche mein Benutzerkonto" delete_account_confirm: "Möchtest du wirklich dein Benutzerkonto permanent löschen? Diese Aktion kann nicht rückgängig gemacht werden!" deleted_yourself: "Dein Benutzerkonto wurde erfolgreich gelöscht." @@ -422,6 +472,8 @@ de: users: "Benutzer" muted_users: "Stummgeschaltet" muted_users_instructions: "Alle Benachrichtigungen von diesem Benutzer unterdrücken." + muted_topics_link: "Zeige stummgeschaltete Themen" + automatically_unpin_topics: "Angeheftete Themen automatisch loslösen, wenn ich deren letzten Beitrag gelesen habe." staff_counters: flags_given: "hilfreiche Meldungen" flagged_posts: "gemeldete Beiträge" @@ -430,8 +482,15 @@ de: warnings_received: "Warnungen" messages: all: "Alle" - mine: "Meine" - unread: "Ungelesen" + inbox: "Posteingang" + sent: "Gesendet" + archive: "Archiv" + groups: "Meine Gruppen" + bulk_select: "Nachrichten auswählen" + move_to_inbox: "In Posteingang verschieben" + move_to_archive: "Archivieren" + failed_to_move: "Die ausgewählten Nachrichten konnten nicht verschoben werden. Vielleicht gibt es ein Netzwerkproblem." + select_all: "Alle auswählen" change_password: success: "(E-Mail gesendet)" in_progress: "(E-Mail wird gesendet)" @@ -476,8 +535,8 @@ de: ok: "Wir senden dir zur Bestätigung eine E-Mail" invalid: "Bitte gib eine gültige E-Mail-Adresse ein" authenticated: "Deine E-Mail-Adresse wurde von {{provider}} bestätigt" + frequency_immediately: "Wir werden dir sofort eine E-Mail senden, wenn du die betroffenen Inhalte noch nicht gelesen hast." frequency: - zero: "Wir werden dir sofort eine E-Mail senden, wenn du die betroffenen Inhalte noch nicht gelesen hast." one: "Wir werden dir nur dann eine E-Mail senden, wenn wir dich nicht innerhalb der letzten Minute gesehen haben." other: "Wir werden dir nur dann eine E-Mail senden, wenn wir dich nicht innerhalb der letzten {{count}} Minuten gesehen haben." name: @@ -515,17 +574,35 @@ de: title: "Benutzerkarten-Abzeichen" website: "Website" email_settings: "E-Mail" + like_notification_frequency: + title: "Benachrichtigung für erhaltene Likes anzeigen" + always: "immer" + first_time_and_daily: "erster Like eines Beitrags und täglich" + first_time: "nur erster Like eines Beitrags" + never: "nie" + email_previous_replies: + title: "Füge vorherige Beiträge ans Ende von E-Mails an" + unless_emailed: "sofern noch nicht gesendet" + always: "immer" + never: "nie" email_digests: title: "Sende eine E-Mail mit Neuigkeiten, wenn ich länger nicht hier bin:" + every_30_minutes: "alle 30 Minuten" + every_hour: "stündlich" daily: "täglich" every_three_days: "alle drei Tage" weekly: "wöchentlich" every_two_weeks: "jede zweite Woche" + include_tl0_in_digests: "Beiträge von neuen Benutzern in E-Mail mit Neuigkeiten einfügen" + email_in_reply_to: "Einen Auszug aus dem beantworteten Beitrag in E-Mails einfügen." email_direct: "Sende mir eine E-Mail, wenn mich jemand zitiert, auf meine Beiträge antwortet, meinen @Namen erwähnt oder mich zu einem Thema einlädt." email_private_messages: "Sende mir eine E-Mail, wenn mir jemand eine Nachricht sendet." email_always: "Benachrichtige mich per E-Mail auch während ich auf dieser Website aktiv bin" other_settings: "Andere" categories_settings: "Kategorien" + enable_mailing_list: + one: "Bist du dir sicher, dass du jeden neuen Post per E-Mail erhalten willst?" + other: "Bist du dir sicher, dass du jeden neuen Post per E-Mail erhalten willst?

    Du wirst ungefähr {{count}} E-Mails pro Tag erhalten." new_topic_duration: label: "Themen als neu ansehen, wenn" not_viewed: "ich diese noch nicht betrachtet habe" @@ -536,7 +613,7 @@ de: after_2_weeks: "in den letzten 2 Wochen erstellt" auto_track_topics: "Betrachteten Themen automatisch folgen" auto_track_options: - never: "niemals" + never: "nie" immediately: "sofort" after_30_seconds: "nach 30 Sekunden" after_1_minute: "nach 1 Minute" @@ -546,11 +623,14 @@ de: after_5_minutes: "nach 5 Minuten" after_10_minutes: "nach 10 Minuten" invited: - search: "schreib zum Suchen nach Einladungen..." + search: "zum Suchen nach Einladungen hier eingeben..." title: "Einladungen" user: "Eingeladener Benutzer" sent: "Gesendet" - truncated: "Zeige die ersten {{count}} Einladungen." + none: "Es gibt keine ausstehenden Einladungen." + truncated: + one: "Zeige die erste Einladung." + other: "Zeige die ersten {{count}} Einladungen." redeemed: "Angenommene Einladungen" redeemed_tab: "Angenommen" redeemed_tab_with_count: "Angenommen ({{count}})" @@ -569,6 +649,8 @@ de: days_visited: "Besuchstage" account_age_days: "Konto-Alter in Tagen" create: "Einladung versenden" + generate_link: "Einladungslink kopieren" + generated_link_message: '

    Einladungslink erfolgreich generiert!

    Der Einladungslink ist nur für folgende E-Mail-Adresse gültig: %{invitedEmail}

    ' bulk_invite: none: "Du hast noch niemanden hierher eingeladen. Du kannst individuelle Einladungen verschicken oder eine Masseneinladung an eine Gruppe von Leuten verschicken indem du eine Datei für Masseneinladung hochlädst." text: "Masseneinladung aus Datei" @@ -583,6 +665,37 @@ de: same_as_email: "Dein Passwort entspricht deiner E-Mail-Adresse." ok: "Dein Passwort sieht in Ordnung aus." instructions: "Mindestens %{count} Zeichen." + summary: + title: "Übersicht" + stats: "Statistiken" + time_read: "Lesezeit" + topic_count: + one: "Thema erstellt" + other: "Themen erstellt" + post_count: + one: "Beitrag erstellt" + other: "Beiträge erstellt" + likes_given: + one: "Like gegeben" + other: "Likes gegeben" + likes_received: + one: "Like bekommen" + other: "Likes bekommen" + days_visited: + one: "Tag vorbeigekommen" + other: "Tage vorbeigekommen" + posts_read: + one: "Beitrag gelesen" + other: "Beiträge gelesen" + top_replies: "Die besten Beiträge" + no_replies: "Noch keine Antworten." + more_replies: "weitere Beiträge" + top_topics: "Die besten Themen" + no_topics: "Noch keine Themen." + more_topics: "weitere Themen" + top_badges: "Die besten Abzeichen" + no_badges: "Noch keine Abzeichen." + more_badges: "weitere Abzeichen" associated_accounts: "Anmeldeinformationen" ip_address: title: "Letzte IP-Adresse" @@ -608,11 +721,13 @@ de: server: "Server-Fehler" forbidden: "Zugriff verweigert" unknown: "Fehler" + not_found: "Seite nicht gefunden" desc: network: "Bitte überprüfe deine Netzwerkverbindung." network_fixed: "Sieht aus, als wäre es wieder da." server: "Fehlercode: {{status}}" forbidden: "Du darfst das nicht ansehen." + not_found: "Hoppla! Die Anwendung hat versucht eine URL zu laden, die nicht existiert." unknown: "Etwas ist schief gelaufen." buttons: back: "Zurück" @@ -623,8 +738,18 @@ de: logout: "Du wurdest abgemeldet." refresh: "Aktualisieren" read_only_mode: - enabled: "Der Nur-Lesen-Modus ist aktiviert. Du kannst die Website weiter durchsuchen und lesen. Einige Funktionen werden jedoch wahrscheinlich nicht funktionieren." + enabled: "Diese Seite ist im Nur-Lesen Modus. Du kannst weiterhin die Seite lesen, aber antworten, liken und andere Aktionen sind deaktiviert." login_disabled: "Die Anmeldung ist deaktiviert während sich die Website im Nur-Lesen-Modus befindet." + logout_disabled: "Die Abmeldung ist deaktiviert während sich die Website im Nur-Lesen-Modus befindet." + too_few_topics_and_posts_notice: "Lass' die Diskussionen starten! Es existieren bisher %{currentTopics} von %{requiredTopics} benötigten Themen und %{currentPosts} von %{requiredPosts} benötigten Beiträgen. Neue Besucher benötigen bestehende Konversationen, die sie lesen und auf die sie antworten können." + too_few_topics_notice: "Lass' die Diskussionen starten! Es existieren bisher %{currentTopics} von %{requiredTopics} benötigten Themen. Neue Besucher benötigen bestehende Konversationen, die sie lesen und auf die sie antworten können." + too_few_posts_notice: "Lass' die Diskussionen starten! Es existieren bisher %{currentPosts} von %{requiredPosts} benötigten Beiträgen. Neue Besucher benötigen bestehende Konversationen, die sie lesen und auf die sie antworten können." + logs_error_rate_notice: + reached: "%{timestamp}: Aktuelle Rate von %{rate} hat die Begrenzung von %{siteSettingRate} in den Website-Einstellungen erreicht." + exceeded: "%{timestamp}: Aktuelle Rate von %{rate} hat die Begrenzung von %{siteSettingRate} in den Website-Einstellungen überschritten." + rate: + one: "1 Fehler/%{duration}" + other: "%{count} Fehler/%{duration}" learn_more: "mehr erfahren..." year: 'Jahr' year_desc: 'Themen, die in den letzten 365 Tagen erstellt wurden' @@ -644,22 +769,14 @@ de: signup_cta: sign_up: "Registrieren" hide_session: "Erinnere mich morgen" - hide_forever: "Nein danke!" - hidden_for_session: "In Ordnung, ich frag dich morgen wieder. Du kannst dir auch jederzeit mit „Anmelden“ ein Benutzerkonto erstellen." + hide_forever: "Nein danke" + hidden_for_session: "In Ordnung, ich frag dich morgen wieder. Du kannst dir auch jederzeit unter „Anmelden“ ein Benutzerkonto erstellen." intro: "Hallo! :heart_eyes: Es sieht so aus, als würde dir die Diskussion gefallen. Du hast aber noch kein Benutzerkonto." value_prop: "Wenn du ein Benutzerkonto anlegst, merken wir uns, was du gelesen hast, damit du immer dort fortsetzten kannst, wo du aufgehört hast. Du kannst auch Benachrichtigungen – hier oder per E-Mail – erhalten, wenn neue Beiträge verfasst werden. Beiträge, die dir gefallen, kannst du mit einem Like versehen und diese Freude mit allen teilen. :heartbeat:" - methods: - sso: "Die Registrierung ist einfach: Alles was du brauchst, ist ein Benutzerkonto auf der Hauptseite." - only_email: "Die Registrierung ist einfach: Alles was du brauchst, ist eine E-Mail-Adresse und ein Passwort." - only_other: "Benutze dein %{provider} Benutzerkonto, um dich zu registrieren." - one_and_email: "Benutze dein %{provider} Benutzerkonto oder eine E-Mail-Adresse und ein Passwort, um dich zu registrieren." - multiple_no_email: "Die Registrierung ist einfach: Benutze eine unserer %{count} sozialen Anmelde-Methoden." - multiple: "Die Registrierung ist einfach: Benutze eine unserer %{count} sozialen Anmelde-Methoden oder eine E-Mail-Adresse und ein Passwort." - unknown: "Fehler beim Ermitteln der unterstützten Anmelde-Methoden" summary: enabled_description: "Du siehst gerade eine Zusammenfassung des Themas: die interessantesten Beiträge, die von der Community bestimmt wurden." - description: "Es gibt {{count}} Antworten." - description_time: "Es gibt {{count}} Antworten mit einer geschätzten Lesezeit von {{readingTime}} Minuten." + description: "Es gibt {{replyCount}} Antworten." + description_time: "Es gibt {{replyCount}} Antworten mit einer geschätzten Lesezeit von {{readingTime}} Minuten." enable: 'Zusammenfassung vom Thema erstellen' disable: 'Alle Beiträge anzeigen' deleted_filter: @@ -713,6 +830,9 @@ de: admin_not_allowed_from_ip_address: "Von dieser IP-Adresse darfst du dich nicht als Administrator anmelden." resend_activation_email: "Klicke hier, um eine neue Aktivierungsmail zu schicken." sent_activation_email_again: "Wir haben dir eine weitere E-Mail zur Aktivierung an {{currentEmail}} geschickt. Es könnte ein paar Minuten dauern, bis diese ankommt; sieh auch im Spam-Ordner nach." + to_continue: "Melde dich bitte an" + preferences: "Du musst angemeldet sein, um deine Benutzereinstellungen bearbeiten zu können." + forgot: "Ich kann mich nicht an meine Zugangsdaten erinnern" google: title: "mit Google" message: "Authentifiziere mit Google (stelle sicher, dass keine Pop-up-Blocker aktiviert sind)" @@ -722,6 +842,9 @@ de: twitter: title: "mit Twitter" message: "Authentifiziere mit Twitter (stelle sicher, dass keine Pop-up-Blocker aktiviert sind)" + instagram: + title: "mit Instagram" + message: "Authentifiziere mit Instagram (stelle sicher, dass keine Pop-up-Blocker aktiviert sind)" facebook: title: "mit Facebook" message: "Authentifiziere mit Facebook (stelle sicher, dass keine Pop-up-Blocker aktiviert sind)" @@ -735,8 +858,13 @@ de: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Umschalt' + ctrl: 'Strg' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "mehr..." options: "Optionen" whisper: "flüstern" add_warning: "Dies ist eine offizielle Warnung." @@ -747,6 +875,7 @@ de: saved_local_draft_tip: "lokal gespeichert" similar_topics: "Dein Thema hat Ähnlichkeit mit..." drafts_offline: "Entwürfe offline" + group_mentioned: "Durch Verwendung von {{group}} werden {{count}} Personen benachrichtigt." error: title_missing: "Titel ist erforderlich" title_too_short: "Titel muss mindestens {{min}} Zeichen lang sein" @@ -767,9 +896,9 @@ de: title_placeholder: "Um was geht es in dieser Diskussion? Schreib einen kurzen Satz." edit_reason_placeholder: "Warum bearbeitest du?" show_edit_reason: "(Bearbeitungsgrund hinzufügen)" - reply_placeholder: "Schreibe hier. Verwende Markdown, BBCode oder HTML zur Formatierung. Füge Bilder ein oder ziehe sie herein." + reply_placeholder: "Schreib hier. Verwende Markdown, BBCode oder HTML zur Formatierung. Füge Bilder ein oder ziehe sie herein." view_new_post: "Sieh deinen neuen Beitrag an." - saving: "Speichere..." + saving: "Wird gespeichert" saved: "Gespeichert!" saved_draft: "Ein Beitrag ist in Arbeit. Zum Fortsetzen hier klicken." uploading: "Wird hochgeladen..." @@ -784,6 +913,7 @@ de: link_description: "gib hier eine Link-Beschreibung ein" link_dialog_title: "Hyperlink einfügen" link_optional_text: "Optionaler Titel" + link_placeholder: "http://example.com \"Optionaler Text\"" quote_title: "Zitat" quote_text: "Zitat" code_title: "Vorformatierter Text" @@ -796,10 +926,11 @@ de: heading_title: "Überschrift" heading_text: "Überschrift" hr_title: "Horizontale Linie" - undo_title: "Rückgängig machen" - redo_title: "Wiederholen" help: "Hilfe zur Markdown-Formatierung" toggler: "Eingabebereich aus- oder einblenden" + modal_ok: "OK" + modal_cancel: "Abbrechen" + cant_send_pm: "Entschuldige, aber du kannst keine Nachricht an %{username} senden." admin_options_title: "Optionale Mitarbeiter-Einstellungen für dieses Thema" auto_close: label: "Zeitpunkt der automatischen Schließung:" @@ -816,11 +947,16 @@ de: more: "ältere Benachrichtigungen anzeigen" total_flagged: "Anzahl der gemeldeten Beiträge" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " + liked_many: + one: "

    {{username}}, {{username2}} und 1 anderer {{description}}

    " + other: "

    {{username}}, {{username2}} und {{count}} andere {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -828,6 +964,9 @@ de: moved_post: "

    {{username}} hat {{description}} verschoben

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Abzeichen '{{description}}' erhalten

    " + group_message_summary: + one: "

    Eine Nachricht in deinem {{group_name}} Postfach

    " + other: "

    {{count}} Nachrichten in deinem {{group_name}} Postfach

    " alt: mentioned: "Erwähnt von" quoted: "Zitiert von" @@ -837,8 +976,15 @@ de: liked: "Gefällt dein Beitrag" private_message: "Nachricht von" invited_to_private_message: "Zu Unterhaltung eingeladen von" + invited_to_topic: "Zu Thema eingeladen von" + invitee_accepted: "Einladung angenommen von" + moved_post: "Dein Beitrag wurde verschoben von" + linked: "Link zu deinem Beitrag" + granted_badge: "Abzeichen erhalten" + group_message_summary: "Nachrichten im Gruppenpostfach" popup: mentioned: '{{username}} hat dich in "{{topic}}" - {{site_title}} erwähnt' + group_mentioned: '{{username}} hat dich in "{{topic}}" - {{site_title}} erwähnt' quoted: '{{username}} hat dich in "{{topic}}" - {{site_title}} zitiert' replied: '{{username}} hat dir in "{{topic}}" - {{site_title}} geantwortet' posted: '{{username}} hat in "{{topic}}" - {{site_title}} einen Beitrag verfasst' @@ -850,9 +996,9 @@ de: from_my_computer: "Von meinem Gerät" from_the_web: "Aus dem Web" remote_tip: "Link zu Bild" - remote_tip_with_attachments: "Link zu Bild oder Datei ({{authorized_extensions}})" + remote_tip_with_attachments: "Link zu Bild oder Datei {{authorized_extensions}}" local_tip: "wähle auf deinem Gerät gespeicherte Bilder aus" - local_tip_with_attachments: "wähle auf deinem Gerät gespeicherte Bilder oder Dateien aus ({{authorized_extensions}})" + local_tip_with_attachments: "Wähle Bilder oder Dateien von deinem Gerät aus {{authorized_extensions}}" hint: "(du kannst Dateien auch in den Editor ziehen, um diese hochzuladen)" hint_for_supported_browsers: "du kannst Bilder auch in den Editor ziehen oder diese aus der Zwischenablage einfügen" uploading: "Wird hochgeladen" @@ -861,7 +1007,7 @@ de: search: sort_by: "Sortieren nach" relevance: "Relevanz" - latest_post: "letztem Beitrag" + latest_post: "letzter Beitrag" most_viewed: "Anzahl der Aufrufe" most_liked: "Anzahl der Likes" select_all: "Alle auswählen" @@ -880,18 +1026,21 @@ de: category: "Kategorie „{{category}}“ durchsuchen" topic: "Dieses Thema durchsuchen" private_messages: "Nachrichten durchsuchen" + hamburger_menu: "zu einer anderen Themenliste oder Kategorie wechseln" new_item: "neu" go_back: 'zurückgehen' not_logged_in_user: 'Benutzerseite mit einer Zusammenfassung der Benutzeraktivitäten und Einstellungen' current_user: 'zu deiner Benutzerseite gehen' topics: bulk: + unlist_topics: "Themen unsichtbar machen" reset_read: "Gelesene zurücksetzen" delete: "Themen löschen" - dismiss_posts: "Beiträge ignorieren" - dismiss_posts_tooltip: "Neue Beiträge in diesen Themen ignorieren. Die Themen aber später wieder als ungelesen anzeigen, sobald neue Beiträge verfasst werden." - dismiss_topics: "Themen ignorieren" - dismiss_topics_tooltip: "Diese Themen ignorieren und nicht mehr als ungelesen anzeigen, selbst wenn neue Beiträge verfasst werden." + dismiss: "Ignorieren" + dismiss_read: "Blende alle ungelesenen Beiträge aus" + dismiss_button: "Ignorieren..." + dismiss_tooltip: "Nur die neuen Beiträge ignorieren oder Themen nicht mehr verfolgen" + also_dismiss_topics: "Diese Themen nicht mehr verfolgen, sodass mir diese nicht mehr als ungelesen angezeigt werden" dismiss_new: "Neue Themen ignorieren" toggle: "zu Massenoperationen auf Themen umschalten" actions: "Massenoperationen" @@ -914,11 +1063,6 @@ de: category: "Es gibt keine Themen in {{category}}." top: "Es gibt keine Top-Themen." search: "Es wurden keine Suchergebnisse gefunden." - educate: - new: '

    Hier werden neue Themen angezeigt.

    Standardmäßig werden jene Themen als neu angesehen und mit dem neu Indikator versehen, die in den letzten 2 Tagen erstellt wurden.

    Du kannst das in deinen Einstellungen ändern.

    ' - unread: '

    Hier werden deine ungelesenen Themen angezeigt.

    Die Anzahl der ungelesenen Beiträge wird als 1 neben den Themen angezeigt.
    - - Standardmäßig werden Themen als ungelesen angesehen, wenn du:

    • das Thema erstellt hast
    • auf das Thema geantwortet hast
    • das Thema länger als 4 Minuten gelesen hast

    Außerdem werden jene Themen berücksichtigt, die du in den Benachrichtigungseinstellungen am Ende eines jeden Themas ausdrücklich auf Beobachten oder Verfolgen gesetzt hast.

    Du kannst das in deinen Einstellungen ändern.

    ' bottom: latest: "Das waren die aktuellen Themen." hot: "Das waren alle beliebten Themen." @@ -938,6 +1082,12 @@ de: create: 'Neues Thema' create_long: 'Ein neues Thema erstellen' private_message: 'Eine Unterhaltung beginnen' + archive_message: + help: 'Nachricht ins Archiv verschieben' + title: 'Archivieren' + move_to_inbox: + title: 'In Posteingang verschieben' + help: 'Nachricht in den Posteingang zurück verschieben' list: 'Themen' new: 'neues Thema' unread: 'ungelesen' @@ -988,6 +1138,7 @@ de: auto_close_title: 'Automatisches Schließen' auto_close_save: "Speichern" auto_close_remove: "Dieses Thema nicht automatisch schließen" + auto_close_immediate: "Der letzte Beitrag in diesem Thema ist bereits %{hours} Stunden alt. Das Thema wird daher sofort geschlossen." progress: title: Themen-Fortschritt go_top: "Anfang" @@ -1009,8 +1160,8 @@ de: '2_4': 'Du wirst Benachrichtigungen erhalten, weil du eine Antwort zu diesem Thema verfasst hast.' '2_2': 'Du wirst Benachrichtigungen erhalten, weil du dieses Thema verfolgst.' '2': 'Du wirst Benachrichtigungen erhalten, weil du dieses Thema gelesen hast.' - '1_2': 'Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder dir antwortet.' - '1': 'Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder dir antwortet.' + '1_2': 'Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet.' + '1': 'Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet.' '0_7': 'Du ignorierst alle Benachrichtigungen dieser Kategorie.' '0_2': 'Du ignorierst alle Benachrichtigungen dieses Themas.' '0': 'Du ignorierst alle Benachrichtigungen dieses Themas.' @@ -1022,22 +1173,22 @@ de: description: "Du wirst über jeden neuen Beitrag in diesem Thema benachrichtigt und die Anzahl der neuen Antworten wird angezeigt." tracking_pm: title: "Verfolgen" - description: "Die Anzahl der neuen Antworten wird bei dieser Unterhaltung angezeigt. Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder dir antwortet." + description: "Die Anzahl der neuen Antworten wird bei dieser Unterhaltung angezeigt. Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deine Nachricht antwortet." tracking: title: "Verfolgen" - description: "Die Anzahl der neuen Antworten wird bei diesem Thema angezeigt. Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder dir antwortet." + description: "Die Anzahl der neuen Antworten wird bei diesem Thema angezeigt. Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet." regular: title: "Normal" - description: "Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder dir antwortet." + description: "Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet." regular_pm: title: "Normal" - description: "Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder dir antwortet." + description: "Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deine Nachricht antwortet." muted_pm: title: "Stummgeschaltet" description: "Du erhältst keine Benachrichtigungen im Zusammenhang mit dieser Unterhaltung." muted: title: "Stummgeschaltet" - description: "Du erhältst keine Benachrichtigungen über dieses Thema und es wird nicht in deiner Liste ungelesener Themen aufscheinen." + description: "Du erhältst keine Benachrichtigungen über neue Aktivitäten in diesem Thema und es wird auch nicht mehr in der Liste der letzten Beiträge erscheinen." actions: recover: "Löschen rückgängig machen" delete: "Thema löschen" @@ -1078,8 +1229,9 @@ de: unpin: "Dieses Thema vom Anfang der {{categoryLink}} Kategorie loslösen." unpin_until: "Dieses Thema vom Anfang der {{categoryLink}} Kategorie loslösen oder bis %{until} warten." pin_note: "Benutzer können das Thema für sich selbst loslösen." + pin_validation: "Ein Datum wird benötigt um diesen Beitrag zu fixieren." + not_pinned: "Es sind in {{categoryLink}} keine Themen angeheftet." already_pinned: - zero: "Es sind in {{categoryLink}} keine Themen angeheftet." one: "Momentan in {{categoryLink}} angeheftete Themen: 1" other: "Momentan in {{categoryLink}} angeheftete Themen: {{count}}" pin_globally: "Dieses Thema am Anfang aller Themenlisten anzeigen bis" @@ -1087,16 +1239,15 @@ de: unpin_globally: "Dieses Thema vom Anfang aller Themenlisten loslösen." unpin_globally_until: "Dieses Thema vom Anfang aller Themenlisten loslösen oder bis %{until} warten." global_pin_note: "Benutzer können das Thema für sich selbst loslösen." + not_pinned_globally: "Es sind keine Themen global angeheftet." already_pinned_globally: - zero: "Es sind keine Themen global angeheftet." one: "Momentan global angeheftete Themen: 1" other: "Momentan global angeheftete Themen: {{count}}" make_banner: "Macht das Thema zu einem Ankündigungsbanner, welcher am Anfang aller Seiten angezeigt wird." remove_banner: "Entfernt das Ankündigungsbanner vom Anfang aller Seiten." banner_note: "Benutzer können das Ankündigungsbanner schließen und so für sich selbst dauerhaft ausblenden. Es kann zu jeder Zeit höchstens ein Thema ein Banner sein." - already_banner: - zero: "Es gibt kein Ankündigungsbanner." - one: "Es gibt bereits ein anderes Ankündigungsbanner." + no_banner_exists: "Es gibt kein Ankündigungsbanner." + banner_exists: "Es gibt bereits ein anderes Ankündigungsbanner." inviting: "Einladungen werden gesendet..." automatically_add_to_groups_optional: "Diese Einladung beinhaltet auch Zugang zu den folgenden Gruppen: (optional, nur Admin)" automatically_add_to_groups_required: "Diese Einladung beinhaltet auch Zugang zu folgenden Gruppen: (erforderlich, nur Admin)" @@ -1108,6 +1259,7 @@ de: success: "Wir haben den Benutzer gebeten, sich an dieser Unterhaltung zu beteiligen." error: "Entschuldige, es gab einen Fehler beim Einladen des Benutzers." group_name: "Gruppenname" + controls: "Weitere Aktionen" invite_reply: title: 'Einladen' username_placeholder: "Benutzername" @@ -1202,8 +1354,8 @@ de: has_likes_title: one: "dieser Beitrag gefällt 1 Person" other: "dieser Beitrag gefällt {{count}} Personen" + has_likes_title_only_you: "dir gefällt dieser Beitrag" has_likes_title_you: - zero: "dir gefällt dieser Beitrag" one: "dir und einer weiteren Person gefällt dieser Beitrag" other: "dir und {{count}} weiteren Personen gefällt dieser Beitrag" errors: @@ -1223,8 +1375,9 @@ de: no_value: "Nein, beibehalten" yes_value: "Ja, verwerfen" via_email: "dieser Beitrag ist per E-Mail eingetroffen" + whisper: "Dieser Beitrag ist Privat für Moderatoren." wiki: - about: "dieser Beitrag ist ein Wiki; Anwärter können diesen bearbeiten" + about: "dieser Beitrag ist ein Wiki" archetypes: save: 'Speicheroptionen' controls: @@ -1252,6 +1405,7 @@ de: revert_to_regular: "Mitarbeiter-Einfärbung entfernen" rebake: "HTML erneuern" unhide: "Einblenden" + change_owner: "Eigentümer ändern" actions: flag: 'Melden' defer_flags: @@ -1273,17 +1427,7 @@ de: like: "Gefällt mir nicht mehr" vote: "Stimme widerrufen" people: - off_topic: "{{icons}} haben das als „am Thema vorbei“ gemeldet" - spam: "{{icons}} haben das als Spam gemeldet" - spam_with_url: "{{icons}} haben das als Spam gemeldet" - inappropriate: "{{icons}} haben das als unangemessen gemeldet" - notify_moderators: "{{icons}} haben das den Moderatoren gemeldet" - notify_moderators_with_url: "{{icons}} haben das den Moderatoren gemeldet" - notify_user: "{{icons}} hat eine Nachricht gesendet" - notify_user_with_url: "{{icons}} hat eine Nachricht gesendet" - bookmark: "{{icons}} haben das als Lesezeichen" - like: "{{icons}} gefällt dieser Beitrag" - vote: "{{icons}} haben dafür gestimmt" + spam: "Melde es als Spam" by_you: off_topic: "Du hast das als „am Thema vorbei“ gemeldet" spam: "Du hast das als Spam gemeldet" @@ -1343,10 +1487,6 @@ de: vote: one: "Eine Person hat für diesen Beitrag gestimmt" other: "{{count}} Personen haben für diesen Beitrag gestimmt" - edits: - one: 1 Bearbeitung - other: "{{count}} Bearbeitungen" - zero: keine Bearbeitungen delete: confirm: one: "Möchtest du wirklich diesen Beitrag löschen?" @@ -1383,6 +1523,7 @@ de: topic_template: "Themenvorlage" delete: 'Kategorie löschen' create: 'Neue Kategorie' + create_long: 'Eine neue Kategorie erstellen' save: 'Kategorie speichern' slug: 'Sprechender Name für URL' slug_placeholder: '(Optional) mit Bindestrich getrennte Wörter für URL' @@ -1405,6 +1546,7 @@ de: change_in_category_topic: "Beschreibung bearbeiten" already_used: 'Diese Farbe wird bereits für eine andere Kategorie verwendet' security: "Sicherheit" + special_warning: "Warnung: Diese Kategorie is eine pre-seeded Kategorie und die Sicherheitseinstellungen können nicht bearbeitet werden. Wenn du wünschst nicht diese Kategorie zu benutzen dann lösche sie anstatt sie zu wiederverwenden" images: "Bilder" auto_close_label: "Themen automatisch schließen nach:" auto_close_units: "Stunden" @@ -1412,6 +1554,7 @@ de: email_in_allow_strangers: "Akzeptiere E-Mails von nicht registrierten, anonymen Benutzern" email_in_disabled: "Das Erstellen von neuen Themen per E-Mail ist in den Website-Einstellungen deaktiviert. Um das Erstellen von neuen Themen per E-Mail zu erlauben," email_in_disabled_click: 'aktiviere die Einstellung „email in“.' + suppress_from_homepage: "Löse diese Kategorie von der Webseite." allow_badges_label: "Erlaube das Verleihen von Abzeichen in dieser Kategorie" edit_permissions: "Berechtigungen bearbeiten" add_permission: "Berechtigung hinzufügen" @@ -1424,19 +1567,18 @@ de: notifications: watching: title: "Beobachten" - description: "Du wirst automatisch alle neuen Themen in dieser Kategorie beobachten und über alle neuen Beiträge und Themen benachrichtigt werden. Die Anzahl der neuen Antworten wird bei den betroffenen Themen angezeigt." + description: "Du wirst automatisch alle neuen Themen in diesen Kategorien beobachten. Du wirst über jeden neuen Beitrag in jedem Thema benachrichtigt und die Anzahl neuer Antworten wird angezeigt." tracking: title: "Verfolgen" - description: "Du wirst automatisch allen neuen Themen in dieser Kategorie folgen. Die Anzahl der neuen Antworten wird bei den betroffenen Themen angezeigt." + description: "Du wirst automatisch allen neuen Themen in diesen Kategorien folgen. Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet, und die Anzahl neuer Antworten wird angezeigt." regular: title: "Normal" - description: "Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder dir antwortet." + description: "Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet." muted: title: "Stummgeschaltet" - description: "Du erhältst keine Benachrichtigungen über neue Themen in dieser Kategorie und die Themen werden nicht in deiner Liste ungelesener Themen aufscheinen." + description: "Du erhältst nie mehr Benachrichtigungen über neue Themen in dieser Kategorie und die Themen werden auch nicht in der Liste der letzten Themen erscheinen." flagging: title: 'Danke für deine Mithilfe!' - private_reminder: 'Meldungen sind vertraulich und nur für Mitarbeiter sichtbar' action: 'Beitrag melden' take_action: "Reagieren" notify_action: 'Nachricht' @@ -1479,12 +1621,14 @@ de: help: "Dieses Thema ist geschlossen. Das Antworten ist nicht mehr möglich." archived: help: "Dieses Thema ist archiviert; es ist eingefroren und kann nicht mehr geändert werden" + locked_and_archived: + help: "Dieses Thema ist geschlossen. Das Antworten oder das Bearbeiten ist nicht mehr möglich." unpinned: title: "Losgelöst" help: "Dieses Thema ist für dich losgelöst; es wird in der normalen Reihenfolge angezeigt" pinned_globally: title: "Global angeheftet" - help: "Dieses Thema ist global angeheftet; es wird immer am Anfang aller Listen auftauchen" + help: "Dieses Thema ist global angeheftet; es wird immer am Anfang der Liste der letzten Beiträgen und in seiner Kategorie auftauchen" pinned: title: "Angeheftet" help: "Dieses Thema ist für dich angeheftet; es wird immer am Anfang seiner Kategorie auftauchen" @@ -1523,8 +1667,8 @@ de: with_topics: "%{filter}e Themen" with_category: "%{filter}e Themen in %{category}" latest: - title: - zero: "Aktuell" + title: "Aktuell" + title_with_count: one: "Aktuell (1)" other: "Aktuell ({{count}})" help: "die zuletzt geänderten Themen" @@ -1542,8 +1686,8 @@ de: title_in: "Kategorie - {{categoryName}}" help: "alle Themen, gruppiert nach Kategorie" unread: - title: - zero: "Ungelesen" + title: "Ungelesen" + title_with_count: one: "Ungelesen (1)" other: "Ungelesen ({{count}})" help: "Themen mit ungelesenen Beiträgen, die du derzeit beobachtest oder verfolgst" @@ -1555,8 +1699,8 @@ de: one: "1 neues" other: "{{count}} neue" lower_title: "neu" - title: - zero: "Neu" + title: "Neu" + title_with_count: one: "Neu (1)" other: "Neu ({{count}})" help: "Themen, die in den letzten paar Tagen erstellt wurden" @@ -1567,8 +1711,8 @@ de: title: "Lesezeichen" help: "Themen, in denen du ein Lesezeichen gesetzt hast" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "aktuelle Themen in der Kategorie {{categoryName}}" @@ -1650,6 +1794,7 @@ de: refresh_report: "Bericht aktualisieren" start_date: "Startdatum" end_date: "Enddatum" + groups: "Alle Gruppen" commits: latest_changes: "Letzte Änderungen: bitte häufig updaten!" by: "von" @@ -1730,15 +1875,24 @@ de: delete_confirm: "Diese Gruppe löschen?" delete_failed: "Gruppe konnte nicht gelöscht werden. Wenn dies eine automatische Gruppe ist, kann sie nicht gelöscht werden." delete_member_confirm: "'%{username}' aus der Gruppe '%{group}' entfernen?" + delete_owner_confirm: "Eigentümerrechte für '%{username}' entfernen?" name: "Name" add: "Hinzufügen" add_members: "Mitglieder hinzufügen" custom: "Benutzerdefiniert" + bulk_complete: "Die Benutzer wurden der Gruppe hinzugefügt." + bulk: "Mehrere der Gruppe hinzufügen" + bulk_paste: "Füge eine Liste an Benutzernamen oder E-Mail-Adressen ein (ein Eintrag je Zeile):" + bulk_select: "(wähle eine Gruppe aus)" automatic: "Automatisch" automatic_membership_email_domains: "Benutzer, deren E-Mail-Domain mit einem der folgenden Listeneinträge genau übereinstimmt, werden automatisch zu dieser Gruppe hinzugefügt:" automatic_membership_retroactive: "Diese Regel auch auf existierende Benutzer anwenden, um diese zur Gruppe hinzuzufügen." default_title: "Standardtitel für alle Benutzer in dieser Gruppe" primary_group: "Automatisch als primäre Gruppe festlegen" + group_owners: Eigentümer + add_owners: Eigentümer hinzufügen + incoming_email: "Benutzerdefinierte Adresse für eingehende E-Mails" + incoming_email_placeholder: "E-Mail-Adresse eingeben" api: generate_master: "Master API Key erzeugen" none: "Es gibt momentan keine aktiven API-Keys" @@ -1812,11 +1966,10 @@ de: is_disabled: "Wiederherstellung ist in den Website-Einstellungen deaktiviert." label: "Wiederherstellen" title: "Das Backup wiederherstellen" - confirm: "Möchtest du wirklich dieses Backup wiederherstellen?" + confirm: "Bist du sicher, dass du dieses Backup wiederherstellen möchtest?" rollback: label: "Zurücksetzen" title: "Die Datenbank auf den letzten funktionierenden Zustand zurücksetzen" - confirm: "Möchtest du wirklich die Datenbank auf den letzten funktionierenden Stand zurücksetzen?" export_csv: user_archive_confirm: "Möchtest du wirklich deine Beiträge herunterladen?" success: "Der Export wurde gestartet. Du erhältst eine Nachricht, sobald der Vorgang abgeschlossen ist." @@ -1836,7 +1989,7 @@ de: button_title: "Einladungen versenden" customize: title: "Anpassen" - long_title: "Website-Anpassungen" + long_title: "Anpassungen" css: "CSS" header: "Kopfbereich" top: "Anfang" @@ -1867,6 +2020,14 @@ de: color: "Farbe" opacity: "Transparenz" copy: "Kopieren" + email_templates: + title: "E-Mail-Vorlagen" + subject: "Betreff" + multiple_subjects: "Diese E-Mail-Vorlage enthält mehrere Betreffzeilen." + body: "Nachrichtentext" + none_selected: "Wähle eine E-Mail-Vorlage aus, um diese zu bearbeiten." + revert: "Änderungen verwerfen" + revert_confirm: "Möchtest du wirklich deine Änderungen verwerfen?" css_html: title: "CSS/HTML" long_title: "CSS und HTML Anpassungen" @@ -1911,18 +2072,18 @@ de: love: name: 'Liebe' description: "Die Farbe des Like-Buttons." - wiki: - name: 'Wiki' - description: "Die Standardfarbe wird als Hintergrundfarbe für Wiki-Beiträge genutzt." email: - title: "E-Mail" + title: "E-Mails" settings: "Einstellungen" - all: "Alle" + templates: "Vorlagen" + preview_digest: "Vorschau auf Neuigkeiten anzeigen" sending_test: "Versende Test-E-Mail..." error: "FEHLER - %{server_error}" test_error: "Es gab ein Problem beim Senden der Test-E-Mail. Bitte überprüfe nochmals deine E-Mail-Einstellungen, stelle sicher dass dein Anbieter keine E-Mail-Verbindungen blockiert und probiere es erneut." sent: "Gesendet" skipped: "Übersprungen" + received: "Empfangen" + rejected: "Abgelehnt" sent_at: "Gesendet am" time: "Zeit" user: "Benutzer" @@ -1932,14 +2093,32 @@ de: send_test: "Test-E-Mail senden" sent_test: "Gesendet!" delivery_method: "Versandmethode" - preview_digest: "Vorschau auf Neuigkeiten anzeigen" + preview_digest_desc: "Vorschau der Neuigkeiten, die als E-Mail an inaktive Nutzer gesendet werden." refresh: "Aktualisieren" format: "Format" html: "HTML" text: "Text" - last_seen_user: "Letzter Benutzer:" + last_seen_user: "Benutzer zuletzt gesehen:" reply_key: "Antwort-Schlüssel" skipped_reason: "Grund des Überspringens" + incoming_emails: + from_address: "Von" + to_addresses: "An" + cc_addresses: "Cc" + subject: "Betreff" + error: "Fehler" + none: "Keine eingehenden E-Mails gefunden." + modal: + title: "Details der eingehenden E-Mail" + error: "Fehler" + subject: "Betreff" + body: "Nachrichtentext" + filters: + from_placeholder: "von@example.com" + to_placeholder: "an@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Betreff..." + error_placeholder: "Fehler" logs: none: "Keine Protokolleinträge gefunden." filters: @@ -1958,6 +2137,7 @@ de: ip_address: "IP" topic_id: "Themen-ID" post_id: "Beitrags-ID" + category_id: "Kategorie-ID" delete: 'Löschen' edit: 'Bearbeiten' save: 'Speichern' @@ -1985,9 +2165,10 @@ de: delete_user: "Benutzer löschen" change_trust_level: "Vertrauensstufe ändern" change_username: "Benutzernamen ändern" - change_site_setting: "Website-Einstellungen ändern" - change_site_customization: "Website-Anpassungen ändern" - delete_site_customization: "Website-Anpassungen löschen" + change_site_setting: "Einstellungen ändern" + change_site_customization: "Anpassungen ändern" + delete_site_customization: "Anpassungen löschen" + change_site_text: "Text ändern" suspend_user: "Benutzer sperren" unsuspend_user: "Benutzer entsperren" grant_badge: "Abzeichen verleihen" @@ -1998,6 +2179,16 @@ de: impersonate: "Nutzersicht" anonymize_user: "Benutzer anonymisieren" roll_up: "IP-Adressen zusammenfassen" + change_category_settings: "Kategorieeinstellungen ändern" + delete_category: "Kategorie löschen" + create_category: "Kategorie erstellen" + block_user: "Benutzer blockieren" + unblock_user: "Blockierung von Benutzer aufheben" + grant_admin: "Administration gewähren" + revoke_admin: "Administration entziehen" + grant_moderation: "Moderation gewähren" + revoke_moderation: "Moderation entziehen" + backup_operation: "Backup läuft" screened_emails: title: "Gefilterte E-Mails" description: "Wenn jemand ein Konto erstellt, werden die folgenden E-Mail-Adressen überprüft und es wird die Anmeldung blockiert oder eine andere Aktion ausgeführt." @@ -2064,9 +2255,9 @@ de: pending: 'Benutzer mit ausstehender Genehmigung' newuser: 'Benutzer mit Vertrauensstufe 0 (Neuer Benutzer)' basic: 'Benutzer mit Vertrauensstufe 1 (Anwärter)' - regular: 'Benutzer mit Vertrauensstufe 2 (Mitglied)' - leader: 'Benutzer mit Vertrauensstufe 3 (Stammgast)' - elder: 'Benutzer mit Vertrauensstufe 4 (Anführer)' + member: 'Benutzer mit Vertrauensstufe 2 (Mitglied)' + regular: 'Benutzer mit Vertrauensstufe 3 (Stammgast)' + leader: 'Benutzer mit Vertrauensstufe 4 (Anführer)' staff: "Mitarbeiter" admins: 'Administratoren' moderators: 'Moderatoren' @@ -2099,6 +2290,7 @@ de: moderator: "Moderator?" admin: "Administrator?" blocked: "Geblockt?" + staged: "Vorbereitet?" show_admin_profile: "Administration" edit_title: "Titel bearbeiten" save_title: "Titel speichern" @@ -2163,9 +2355,12 @@ de: deactivate_failed: "Beim Deaktivieren des Benutzers ist ein Fehler aufgetreten." unblock_failed: 'Beim Aufheben der Blockierung des Benutzers ist ein Fehler aufgetreten.' block_failed: 'Beim Blocken des Benutzers ist ein Fehler aufgetreten.' + block_confirm: 'Bust du sicher, dass du diesen Benutzer blockieren willst? Sie werden keine Möglichkeit mehr haben, Themen oder Beiträge zu erstellen.' + block_accept: 'Ja, diesen Benutzer blockieren.' deactivate_explanation: "Ein deaktivierter Benutzer muss seine E-Mail-Adresse erneut bestätigen." suspended_explanation: "Ein gesperrter Benutzer kann sich nicht anmelden." block_explanation: "Ein geblockter Benutzer kann keine Themen erstellen oder Beiträge veröffentlichen." + stage_explanation: "Ein vorbereiteter Nutzer kann nur via E-Mail zu bestimmten Themen beitragen." trust_level_change_failed: "Beim Wechsel der Vertrauensstufe ist ein Fehler aufgetreten." suspend_modal_title: "Benutzer sperren" trust_level_2_users: "Benutzer mit Vertrauensstufe 2" @@ -2176,7 +2371,7 @@ de: unlock_trust_level: "Vertrauensstufe entsperren" tl3_requirements: title: "Anforderungen für Vertrauensstufe 3" - table_title: "In den letzten 100 Tagen:" + table_title: "In den letzten %{time_period} Tagen:" value_heading: "Wert" requirement_heading: "Anforderung" visits: "Aufrufe" @@ -2237,10 +2432,17 @@ de: confirm: 'Bestätigung' dropdown: "Dropdown-Liste" site_text: - none: "Wähle einen Inhaltstyp, um mit dem Bearbeiten zu beginnen." + description: "Du kannst jeden Text deines Forums anpassen. Benutze dazu die Suche:" + search: "Suche nach dem Text, den du bearbeiten möchtest" title: 'Textinhalt' + edit: 'bearbeiten' + revert: "Änderungen verwerfen" + revert_confirm: "Möchtest du wirklich deine Änderungen verwerfen?" + go_back: "Zurück zur Suche" + recommended: "Wir empfehlen, dass du den folgenden Text an deine Bedürfnisse anpasst:" + show_overriden: 'Nur geänderte Texte anzeigen' site_settings: - show_overriden: 'Zeige nur geänderte Einstellungen' + show_overriden: 'Nur geänderte Einstellungen anzeigen' title: 'Einstellungen' reset: 'zurücksetzen' none: 'keine' @@ -2326,8 +2528,8 @@ de: bad_count_warning: header: "WARNUNG!" text: "Es fehlen Beispieldaten. Das passiert, wenn die Abzeichen-Abfrage IDs von Benutzern oder Beiträgen liefert, die nicht existieren. Das kann in weiterer Folge zu unerwarteten Ergebnissen führen. Bitte überprüfe nochmals deine Abfrage." + no_grant_count: "Es werden keine Abzeichen verliehen." grant_count: - zero: "Es wird kein Abzeichen verliehen." one: "Es wird 1 Abzeichen verliehen." other: "Es werden %{count} Abzeichen verliehen." sample: "Beispiel:" @@ -2344,14 +2546,25 @@ de: image: "Bild" delete_confirm: "Möchtest du wirklich das :%{name}: Emoji löschen?" embedding: + get_started: "Wenn du Discourse in einer anderen Website einbetten möchtest, beginne mit dem hinzufügen des host. " confirm_delete: "Möchtest du wirklich diesen Host löschen?" + sample: "Benutze den folgenden HTML code für deine Seite um discourse Beiträge zu erstellen und einzubetten. Ersetze ERSETZE_MICH mit der URL der Seite in die du sie einbetten möchtest." title: "Einbettung" host: "Erlaubte Hosts" edit: "bearbeiten" + category: "In Kategorie Beitrag schreiben" add_host: "Host hinzufügen" settings: "Einbettungseinstellungen" feed_settings: "Feed-Einstellungen" + feed_description: "Wenn man RSS/ATOM Feeds für eine Webseite zur Verfügung stellt, können sich die Möglichkeiten des Imports verbessern. " crawling_settings: "Crawler-Einstellungen" + crawling_description: "Wenn Discourse Themen für deine Beiträge erstellt wird es falls kein RSS/ATOM-Feed verfügbar ist versuchen, den Inhalt aus dem HTML-Code zu extrahieren. Dies ist teilweise schwierig, weshalb hier CSS-Regeln angegeben werden können, die die Extraktion erleichtern." + embed_by_username: "Benutzername für Beitragserstellung" + embed_post_limit: "Maximale Anzahl der Beiträge, welche eingebettet werden" + embed_username_key_from_feed: "Schlüssel, um Discourse-Benutzernamen aus Feed zu ermitteln." + embed_truncate: "Kürze die eingebetteten Beiträge" + embed_whitelist_selector: "CSS Selektor für Elemente, die in Einbettungen erlaubt sind." + embed_blacklist_selector: "CSS Selektor für Elemente, die in Einbettungen entfernt werden." feed_polling_enabled: "Beiträge über RSS/ATOM importieren" feed_polling_url: "URL des RSS/ATOM Feeds für den Import" save: "Einbettungseinstellungen speichern" @@ -2426,9 +2639,10 @@ de: mark_tracking: 'm, t Thema verfolgen' mark_watching: 'm, w Thema beobachten' badges: + earned_n_times: + one: "Einmal dieses Abzeichen erhalten" + other: "%{count} mal dieses Abzeichen erhalten" title: Abzeichen - allow_title: "kann als Titel verwendet werden" - multiple_grant: "kann mehrfach verliehen werden" badge_count: one: "1 Abzeichen" other: "%{count} Abzeichen" @@ -2451,97 +2665,6 @@ de: name: Andere posting: name: Beiträge - badge: - editor: - name: Bearbeiter - description: Hat den ersten Beitrag bearbeitet - basic_user: - name: Anwärter - description: Ermöglicht das Nutzen alle wesentlichen Community-Funktionen - member: - name: Mitglied - description: Ermöglicht Einladungen - regular: - name: Stammgast - description: Ermöglicht das Verschieben und Umbenennen von Themen, die Veröffentlichung von verfolgbaren Links und den Zugang zur Lounge - leader: - name: Anführer - description: Ermöglicht das Bearbeiten aller Beiträge und das Anheften, Schließen, Archivieren, Aufteilen und Zusammenfügen von Themen - welcome: - name: Willkommen - description: Hat ein Like erhalten - autobiographer: - name: Autobiograf - description: Hat Benutzerprofil ausgefüllt - anniversary: - name: Jubiläum - description: Aktives Mitglied für ein Jahr und hat mindestens einen Beitrag verfasst - nice_post: - name: Schöner Beitrag - description: Hat 10 Likes für einen Beitrag erhalten. Dieses Abzeichen kann mehrfach verliehen werden. - good_post: - name: Guter Beitrag - description: Hat 25 Likes für einen Beitrag erhalten. Dieses Abzeichen kann mehrfach verliehen werden. - great_post: - name: Großartiger Beitrag - description: Hat 50 Likes für einen Beitrag erhalten. Dieses Abzeichen kann mehrfach verliehen werden. - nice_topic: - name: Schönes Thema - description: Hat 10 Likes für ein Thema erhalten. Dieses Abzeichen kann mehrfach verliehen werden. - good_topic: - name: Gutes Thema - description: Hat 25 Likes für ein Thema erhalten. Dieses Abzeichen kann mehrfach verliehen werden. - great_topic: - name: Großartiges Thema - description: Hat 50 Likes für ein Thema erhalten. Dieses Abzeichen kann mehrfach verliehen werden. - nice_share: - name: Schöne Weitergabe - description: Hat einen Beitrag mit 25 Besuchern geteilt - good_share: - name: Gute Weitergabe - description: Hat einen Beitrag mit 300 Besuchern geteilt - great_share: - name: Großartige Weitergabe - description: Hat einen Beitrag mit 1000 Besuchern geteilt - first_like: - name: Erster Like - description: Hat Gefallen an einem Beitrag gefunden - first_flag: - name: Erste Meldung - description: Hat einen Beitrag gemeldet - promoter: - name: Befürworter - description: Hat einen Benutzer eingeladen - campaigner: - name: Aktivist - description: Hat 3 Anwärter (Vertrauensstufe 1) eingeladen - champion: - name: Verfechter - description: Hat 5 Mitglieder (Vertrauensstufe 2) eingeladen - first_share: - name: Erste Weitergabe - description: Hat einen Beitrag geteilt - first_link: - name: Erster Link - description: Hat einen internen Link auf einen anderen Beitrag hinzugefügt - first_quote: - name: Erstes Zitat - description: Hat einen Benutzer zitiert - read_guidelines: - name: Richtlinien gelesen - description: Hat die Community-Richtlinien gelesen - reader: - name: Leser - description: Hat in einem Thema mit mehr als 100 Beiträgen jeden Beitrag gelesen - popular_link: - name: Beliebter Link - description: Hat einen externen Link veröffentlicht, der mindestens 50 Klicks erhalten hat. - hot_link: - name: Angesagter Link - description: Hat einen externen Link veröffentlicht, der mindestens 300 Klicks erhalten hat. - famous_link: - name: Berühmter Link - description: Hat einen externen Link veröffentlicht, der mindestens 1000 Klicks erhalten hat. google_search: |

    Mit Google suchen

    diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 4dd0b0cf5c7..f3c5ca3f2fd 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1,9 +1,9 @@ # encoding: utf-8 +# # This file contains content for the client portion of Discourse, sent out # to the Javascript app. # -# To work with us on translations, see: -# https://www.transifex.com/projects/p/discourse-org/ +# To work with us on translations, see: https://www.transifex.com/projects/p/discourse-org/ # # This is a "source" file, which is used by Transifex to get translations for other languages. # After this file is changed, it needs to be pushed by a maintainer to Transifex: @@ -12,8 +12,7 @@ # # Read more here: https://meta.discourse.org/t/contribute-a-translation-to-discourse/14882 # -# To validate this YAML file after you change it, please paste it into -# http://yamllint.com/ +# To validate this YAML file after you change it, please paste it into http://yamllint.com/ en: js: @@ -110,6 +109,8 @@ en: x_years: one: "1 year later" other: "%{count} years later" + previous_month: 'Previous Month' + next_month: 'Next Month' share: topic: 'share a link to this topic' post: 'post #%{postNumber}' @@ -121,6 +122,8 @@ en: action_codes: split_topic: "split this topic %{when}" + invited_user: "invited %{who} %{when}" + removed_user: "removed %{who} %{when}" autoclosed: enabled: 'closed %{when}' disabled: 'opened %{when}' @@ -144,6 +147,20 @@ en: emails_are_disabled: "All outgoing email has been globally disabled by an administrator. No email notifications of any kind will be sent." + s3: + regions: + us_east_1: "US East (N. Virginia)" + us_west_1: "US West (N. California)" + us_west_2: "US West (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "EU (Ireland)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asia Pacific (Singapore)" + ap_southeast_2: "Asia Pacific (Sydney)" + ap_northeast_1: "Asia Pacific (Tokyo)" + ap_northeast_2: "Asia Pacific (Seoul)" + sa_east_1: "South America (Sao Paulo)" + edit: 'edit the title and category of this topic' not_implemented: "That feature hasn't been implemented yet, sorry!" no_value: "No" @@ -153,7 +170,6 @@ en: sign_up: "Sign Up" log_in: "Log In" age: "Age" - last_post: "Last Post" joined: "Joined" admin_title: "Admin" flags_title: "Flags" @@ -177,6 +193,8 @@ en: more: "More" less: "Less" never: "never" + every_30_minutes: "every 30 minutes" + every_hour: "every hour" daily: "daily" weekly: "weekly" every_two_weeks: "every two weeks" @@ -189,6 +207,7 @@ en: suggested_topics: title: "Suggested Topics" + pm_title: "Suggested Messages" about: simple_title: "About" @@ -282,7 +301,7 @@ en: other: "This topic has {{count}} posts awaiting approval" confirm: "Save Changes" - delete_prompt: "Are you sure you want to delete %{username}? This will remove all of their posts and block their email and ip address." + delete_prompt: "Are you sure you want to delete %{username}? This will remove all of their posts and block their email and IP address." approval: title: "Post Needs Approval" @@ -331,14 +350,26 @@ en: other: "%{count} users" groups: + empty: + posts: "There is no post by members of this group." + members: "There is no member in this group." + mentions: "There is no mention of this group." + messages: "There is no message for this group." + topics: "There is no topic by members of this group." + add: "Add" + selector_placeholder: "Add members" + owner: "owner" visible: "Group is visible to all users" title: one: "group" other: "groups" members: "Members" + topics: "Topics" posts: "Posts" + mentions: "Mentions" + messages: "Messages" alias_levels: - title: "Who can use this group as an alias?" + title: "Who can message and @mention this group?" nobody: "Nobody" only_admins: "Only admins" mods_and_admins: "Only moderators and Admins" @@ -347,6 +378,19 @@ en: trust_levels: title: "Trust level automatically granted to members when they're added:" none: "None" + notifications: + watching: + title: "Watching" + description: "You will be notified of every new post in every message, and a count of new replies will be shown." + tracking: + title: "Tracking" + description: "You will be notified if someone mentions your @name or replies to you, and a count of new replies will be shown." + regular: + title: "Normal" + description: "You will be notified if someone mentions your @name or replies to you." + muted: + title: "Muted" + description: "You will never be notified of anything about new topics in this group." user_action_groups: "1": "Likes Given" @@ -357,7 +401,6 @@ en: "6": "Responses" "7": "Mentions" "9": "Quotes" - "10": "Starred" "11": "Edits" "12": "Sent Items" "13": "Inbox" @@ -368,6 +411,7 @@ en: all_subcategories: "all" no_subcategory: "none" category: "Category" + category_list: "Display category list" reorder: title: "Reorder Categories" title_long: "Reorganize the category list" @@ -427,16 +471,17 @@ en: invited_by: "Invited By" trust_level: "Trust Level" notifications: "Notifications" + statistics: "Stats" desktop_notifications: label: "Desktop Notifications" not_supported: "Notifications are not supported on this browser. Sorry." perm_default: "Turn On Notifications" perm_denied_btn: "Permission Denied" - perm_denied_expl: "You have denied permission for notifications. Use your browser to enable notifications, then click the button when done. (Desktop: The leftmost icon in the address bar. Mobile: 'Site Info'.)" + perm_denied_expl: "You denied permission for notifications. Allow notifications via your browser settings." disable: "Disable Notifications" - currently_enabled: "(currently enabled)" + currently_enabled: "" enable: "Enable Notifications" - currently_disabled: "(currently disabled)" + currently_disabled: "" each_browser_note: "Note: You have to change this setting on every browser you use." dismiss_notifications: "Mark all as Read" dismiss_notifications_tooltip: "Mark all unread notifications as read" @@ -460,7 +505,7 @@ en: tracked_categories: "Tracked" tracked_categories_instructions: "You will automatically track all new topics in these categories. A count of new posts will appear next to the topic." muted_categories: "Muted" - muted_categories_instructions: "You will not be notified of anything about new topics in these categories, and they will not appear on your unread tab." + muted_categories_instructions: "You will not be notified of anything about new topics in these categories, and they will not appear in latest." delete_account: "Delete My Account" delete_account_confirm: "Are you sure you want to permanently delete your account? This action cannot be undone!" deleted_yourself: "Your account has been deleted successfully." @@ -470,6 +515,8 @@ en: users: "Users" muted_users: "Muted" muted_users_instructions: "Suppress all notifications from these users." + muted_topics_link: "Show muted topics" + automatically_unpin_topics: "Automatically unpin topics when I reach the bottom." staff_counters: flags_given: "helpful flags" @@ -480,8 +527,15 @@ en: messages: all: "All" - mine: "Mine" - unread: "Unread" + inbox: "Inbox" + sent: "Sent" + archive: "Archive" + groups: "My Groups" + bulk_select: "Select messages" + move_to_inbox: "Move to Inbox" + move_to_archive: "Archive" + failed_to_move: "Failed to move selected messages (perhaps your network is down)" + select_all: "Select All" change_password: success: "(email sent)" @@ -534,8 +588,8 @@ en: ok: "We will email you to confirm" invalid: "Please enter a valid email address" authenticated: "Your email has been authenticated by {{provider}}" + frequency_immediately: "We'll email you immediately if you haven't read the thing we're emailing you about." frequency: - zero: "We'll email you immediately if you haven't read the thing we're emailing you about." one: "We'll only email you if we haven't seen you in the last minute." other: "We'll only email you if we haven't seen you in the last {{count}} minutes." @@ -578,13 +632,28 @@ en: website: "Web Site" email_settings: "Email" + like_notification_frequency: + title: "Notify when liked" + always: "Always" + first_time_and_daily: "First time a post is liked and daily" + first_time: "First time a post is liked" + never: "Never" + email_previous_replies: + title: "Include previous replies at the bottom of emails" + unless_emailed: "unless previously sent" + always: "always" + never: "never" email_digests: title: "When I don't visit here, send an email digest of what's new:" + every_30_minutes: "every 30 minutes" + every_hour: "hourly" daily: "daily" every_three_days: "every three days" weekly: "weekly" every_two_weeks: "every two weeks" + include_tl0_in_digests: "Include posts from new users in digest emails" + email_in_reply_to: "Include an excerpt of replied to post in emails" email_direct: "Send me an email when someone quotes me, replies to my post, mentions my @username, or invites me to a topic" email_private_messages: "Send me an email when someone messages me" email_always: "Send me email notifications even when I am active on the site" @@ -592,6 +661,10 @@ en: other_settings: "Other" categories_settings: "Categories" + enable_mailing_list: + one: "Are you sure you want to be emailed for every new post?" + other: "Are you sure you want to be emailed for every new post?

    This will result in approximately {{count}} emails per day." + new_topic_duration: label: "Consider topics new when" not_viewed: "I haven't viewed them yet" @@ -619,7 +692,9 @@ en: user: "Invited User" sent: "Sent" none: "There are no pending invites to display." - truncated: "Showing the first {{count}} invites." + truncated: + one: "Showing the first invite." + other: "Showing the first {{count}} invites." redeemed: "Redeemed Invites" redeemed_tab: "Redeemed" redeemed_tab_with_count: "Redeemed ({{count}})" @@ -656,6 +731,39 @@ en: ok: "Your password looks good." instructions: "At least %{count} characters." + summary: + title: "Summary" + stats: "Stats" + time_read: "read time" + topic_count: + one: "topic created" + other: "topics created" + post_count: + one: "post created" + other: "posts created" + likes_given: + one: "like given" + other: "likes given" + likes_received: + one: "like received" + other: "likes received" + days_visited: + one: "day visited" + other: "days visited" + posts_read: + one: "post read" + other: "posts read" + top_replies: "Top Replies" + no_replies: "No replies yet." + more_replies: "More Replies" + top_topics: "Top Topics" + no_topics: "No topics yet." + more_topics: "More Topics" + top_badges: "Top Badges" + no_badges: "No badges yet." + more_badges: "More Badges" + + associated_accounts: "Logins" ip_address: title: "Last IP Address" @@ -701,11 +809,18 @@ en: logout: "You were logged out." refresh: "Refresh" read_only_mode: - enabled: "Read-only mode is enabled. You can continue to browse the site but interactions may not work." + enabled: "This site is in read only mode. Please continue to browse, but replying, likes, and other actions are disabled for now." login_disabled: "Login is disabled while the site is in read only mode." + logout_disabled: "Logout is disabled while the site is in read only mode." too_few_topics_and_posts_notice: "Let's get this discussion started! There are currently %{currentTopics} / %{requiredTopics} topics and %{currentPosts} / %{requiredPosts} posts. New visitors need some conversations to read and respond to." too_few_topics_notice: "Let's get this discussion started! There are currently %{currentTopics} / %{requiredTopics} topics. New visitors need some conversations to read and respond to." too_few_posts_notice: "Let's get this discussion started! There are currently %{currentPosts} / %{requiredPosts} posts. New visitors need some conversations to read and respond to." + logs_error_rate_notice: + reached: "%{timestamp}: Current rate of %{rate} has reached site settings's limit of %{siteSettingRate}." + exceeded: "%{timestamp}: Current rate of %{rate} has exceeded site settings's limit of %{siteSettingRate}." + rate: + one: "1 error/%{duration}" + other: "%{count} errors/%{duration}" learn_more: "learn more..." @@ -733,19 +848,11 @@ en: hidden_for_session: "OK, I'll ask you tomorrow. You can always use 'Log In' to create an account, too." intro: "Hey there! :heart_eyes: Looks like you're enjoying the discussion, but you're not signed up for an account." value_prop: "When you create an account, we remember exactly what you've read, so you always come right back where you left off. You also get notifications, here and via email, whenever new posts are made. And you can like posts to share the love. :heartbeat:" - methods: - sso: "Signing up is easy: all you need is an account on the main site." - only_email: "Signing up is easy: all you need is an email and password." - only_other: "Use your %{provider} account to sign up." - one_and_email: "Use your %{provider} account, or an email and password, to sign up." - multiple_no_email: "Signing up is easy: use any of our %{count} social logins." - multiple: "Signing up is easy: use any of our %{count} social logins, or an email and password." - unknown: "error getting supported login methods" summary: enabled_description: "You're viewing a summary of this topic: the most interesting posts as determined by the community." - description: "There are {{count}} replies." - description_time: "There are {{count}} replies with an estimated read time of {{readingTime}} minutes." + description: "There are {{replyCount}} replies." + description_time: "There are {{replyCount}} replies with an estimated read time of {{readingTime}} minutes." enable: 'Summarize This Topic' disable: 'Show All Posts' @@ -805,6 +912,9 @@ en: admin_not_allowed_from_ip_address: "You can't log in as admin from that IP address." resend_activation_email: "Click here to send the activation email again." sent_activation_email_again: "We sent another activation email to you at {{currentEmail}}. It might take a few minutes for it to arrive; be sure to check your spam folder." + to_continue: "Please Log In" + preferences: "You need to be logged in to change your user preferences." + forgot: "I don't recall my account details" google: title: "with Google" message: "Authenticating with Google (make sure pop up blockers are not enabled)" @@ -814,6 +924,9 @@ en: twitter: title: "with Twitter" message: "Authenticating with Twitter (make sure pop up blockers are not enabled)" + instagram: + title: "with Instagram" + message: "Authenticating with Instagram (make sure pop up blockers are not enabled)" facebook: title: "with Facebook" message: "Authenticating with Facebook (make sure pop up blockers are not enabled)" @@ -829,8 +942,14 @@ en: twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' + composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "more..." options: "Options" whisper: "whisper" @@ -843,6 +962,8 @@ en: similar_topics: "Your topic is similar to..." drafts_offline: "drafts offline" + group_mentioned: "By using {{group}}, you are about to notify {{count}} people." + error: title_missing: "Title is required" title_too_short: "Title must be at least {{min}} characters" @@ -867,7 +988,7 @@ en: show_edit_reason: "(add edit reason)" reply_placeholder: "Type here. Use Markdown, BBCode, or HTML to format. Drag or paste images." view_new_post: "View your new post." - saving: "Saving..." + saving: "Saving" saved: "Saved!" saved_draft: "Post draft in progress. Select to resume." uploading: "Uploading..." @@ -883,6 +1004,7 @@ en: link_description: "enter link description here" link_dialog_title: "Insert Hyperlink" link_optional_text: "optional title" + link_placeholder: "http://example.com \"optional text\"" quote_title: "Blockquote" quote_text: "Blockquote" code_title: "Preformatted text" @@ -895,10 +1017,11 @@ en: heading_title: "Heading" heading_text: "Heading" hr_title: "Horizontal Rule" - undo_title: "Undo" - redo_title: "Redo" help: "Markdown Editing Help" toggler: "hide or show the composer panel" + modal_ok: "OK" + modal_cancel: "Cancel" + cant_send_pm: "Sorry, you can't send a message to %{username}." admin_options_title: "Optional staff settings for this topic" auto_close: @@ -918,11 +1041,16 @@ en: more: "view older notifications" total_flagged: "total flagged posts" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " + liked_many: + one: "

    {{username}}, {{username2}} and 1 other {{description}}

    " + other: "

    {{username}}, {{username2}} and {{count}} others {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -931,6 +1059,10 @@ en: linked: "

    {{username}} {{description}}

    " granted_badge: "

    Earned '{{description}}'

    " + group_message_summary: + one: "

    {{count}} message in your {{group_name}} inbox

    " + other: "

    {{count}} messages in your {{group_name}} inbox

    " + alt: mentioned: "Mentioned by" quoted: "Quoted by" @@ -945,9 +1077,11 @@ en: moved_post: "Your post was moved by" linked: "Link to your post" granted_badge: "Badge granted" + group_message_summary: "Messages in group inbox" popup: mentioned: '{{username}} mentioned you in "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} mentioned you in "{{topic}}" - {{site_title}}' quoted: '{{username}} quoted you in "{{topic}}" - {{site_title}}' replied: '{{username}} replied to you in "{{topic}}" - {{site_title}}' posted: '{{username}} posted in "{{topic}}" - {{site_title}}' @@ -960,9 +1094,9 @@ en: from_my_computer: "From my device" from_the_web: "From the web" remote_tip: "link to image" - remote_tip_with_attachments: "link to image or file ({{authorized_extensions}})" + remote_tip_with_attachments: "link to image or file {{authorized_extensions}}" local_tip: "select images from your device" - local_tip_with_attachments: "select images or files from your device ({{authorized_extensions}})" + local_tip_with_attachments: "select images or files from your device {{authorized_extensions}}" hint: "(you can also drag & drop into the editor to upload them)" hint_for_supported_browsers: "you can also drag and drop or paste images into the editor" uploading: "Uploading" @@ -1001,12 +1135,14 @@ en: topics: bulk: + unlist_topics: "Unlist Topics" reset_read: "Reset Read" delete: "Delete Topics" - dismiss_posts: "Dismiss Posts" - dismiss_posts_tooltip: "Clear unread counts on these topics but continue to show them on my unread list when new posts are made" - dismiss_topics: "Dismiss Topics" - dismiss_topics_tooltip: "Stop showing these topics in my unread list when new posts are made" + dismiss: "Dismiss" + dismiss_read: "Dismiss all unread" + dismiss_button: "Dismiss…" + dismiss_tooltip: "Dismiss just new posts or stop tracking topics" + also_dismiss_topics: "Stop tracking these topics so they never show up as unread for me again" dismiss_new: "Dismiss New" toggle: "toggle bulk selection of topics" actions: "Bulk Actions" @@ -1031,8 +1167,8 @@ en: top: "There are no top topics." search: "There are no search results." educate: - new: '

    Your new topics appear here.

    By default, topics are considered new and will show a new indicator if they were created in the last 2 days.

    You can change this in your preferences.

    ' - unread: '

    Your unread topics appear here.

    By default, topics are considered unread and will show unread counts 1 if you:

    • Created the topic
    • Replied to the topic
    • Read the topic for more than 4 minutes

    Or if you have explicitly set the topic to Tracked or Watched via the notification control at the bottom of each topic.

    You can change this in your preferences.

    ' + new: '

    Your new topics appear here.

    By default, topics are considered new and will show a new indicator if they were created in the last 2 days.

    Visit your preferences to change this.

    ' + unread: '

    Your unread topics appear here.

    By default, topics are considered unread and will show unread counts 1 if you:

    • Created the topic
    • Replied to the topic
    • Read the topic for more than 4 minutes

    Or if you have explicitly set the topic to Tracked or Watched via the notification control at the bottom of each topic.

    Visit your preferences to change this.

    ' bottom: latest: "There are no more latest topics." hot: "There are no more hot topics." @@ -1053,6 +1189,12 @@ en: create: 'New Topic' create_long: 'Create a new Topic' private_message: 'Start a message' + archive_message: + help: 'Move message to your archive' + title: 'Archive' + move_to_inbox: + title: 'Move to Inbox' + help: 'Move message back to Inbox' list: 'Topics' new: 'new topic' unread: 'unread' @@ -1121,6 +1263,7 @@ en: auto_close_title: 'Auto-Close Settings' auto_close_save: "Save" auto_close_remove: "Don't Auto-Close This Topic" + auto_close_immediate: "The last post in the topic is already %{hours} hours old, so the topic will be closed immediately." progress: title: topic progress @@ -1172,7 +1315,7 @@ en: description: "You will never be notified of anything about this message." muted: title: "Muted" - description: "You will never be notified of anything about this topic, and it will not appear on your unread tab." + description: "You will never be notified of anything about this topic, and it will not appear in latest." actions: recover: "Un-Delete Topic" @@ -1221,25 +1364,24 @@ en: unpin_until: "Remove this topic from the top of the {{categoryLink}} category or wait until %{until}." pin_note: "Users can unpin the topic individually for themselves." pin_validation: "A date is required to pin this topic." + not_pinned: "There are no topics pinned in {{categoryLink}}." already_pinned: - zero: "There are no topics pinned in {{categoryLink}}." - one: "Topics currently pinned in {{categoryLink}}: 1." - other: "Topics currently pinned in {{categoryLink}}: {{count}}." + one: "Topics currently pinned in {{categoryLink}}: 1" + other: "Topics currently pinned in {{categoryLink}}: {{count}}" pin_globally: "Make this topic appear at the top of all topic lists until" confirm_pin_globally: "You already have {{count}} globally pinned topics. Too many pinned topics may be a burden for new and anonymous users. Are you sure you want to pin another topic globally?" unpin_globally: "Remove this topic from the top of all topic lists." unpin_globally_until: "Remove this topic from the top of all topic lists or wait until %{until}." global_pin_note: "Users can unpin the topic individually for themselves." + not_pinned_globally: "There are no topics pinned globally." already_pinned_globally: - zero: "There are no topics pinned globally." - one: "Topics currently pinned globally: 1." - other: "Topics currently pinned globally: {{count}}." + one: "Topics currently pinned globally: 1" + other: "Topics currently pinned globally: {{count}}" make_banner: "Make this topic into a banner that appears at the top of all pages." remove_banner: "Remove the banner that appears at the top of all pages." banner_note: "Users can dismiss the banner by closing it. Only one topic can be bannered at any given time." - already_banner: - zero: "There is no banner topic." - one: "There is currently a banner topic." + no_banner_exists: "There is no banner topic." + banner_exists: "There is currently a banner topic." inviting: "Inviting..." automatically_add_to_groups_optional: "This invite also includes access to these groups: (optional, admin only)" @@ -1254,6 +1396,8 @@ en: error: "Sorry, there was an error inviting that user." group_name: "group name" + controls: "Topic Controls" + invite_reply: title: 'Invite' username_placeholder: "username" @@ -1360,8 +1504,8 @@ en: one: "1 person liked this post" other: "{{count}} people liked this post" + has_likes_title_only_you: "you liked this post" has_likes_title_you: - zero: "you liked this post" one: "you and 1 other person liked this post" other: "you and {{count}} other people liked this post" @@ -1387,11 +1531,13 @@ en: whisper: "this post is a private whisper for moderators" wiki: - about: "this post is a wiki; basic users can edit it" + about: "this post is a wiki" archetypes: save: 'Save Options' + few_likes_left: "Thanks for sharing the love! You only have a few likes left for today." + controls: reply: "begin composing a reply to this post" like: "like this post" @@ -1417,6 +1563,7 @@ en: revert_to_regular: "Remove Staff Color" rebake: "Rebuild HTML" unhide: "Unhide" + change_owner: "Change Ownership" actions: flag: 'Flag' @@ -1439,17 +1586,14 @@ en: like: "Undo like" vote: "Undo vote" people: - off_topic: "{{icons}} flagged this as off-topic" - spam: "{{icons}} flagged this as spam" - spam_with_url: "{{icons}} flagged this as spam" - inappropriate: "{{icons}} flagged this as inappropriate" - notify_moderators: "{{icons}} notified moderators" - notify_moderators_with_url: "{{icons}} notified moderators" - notify_user: "{{icons}} sent a message" - notify_user_with_url: "{{icons}} sent a message" - bookmark: "{{icons}} bookmarked this" - like: "{{icons}} liked this" - vote: "{{icons}} voted for this" + off_topic: "flagged this as off-topic" + spam: "flagged this as spam" + inappropriate: "flagged this as inappropriate" + notify_moderators: "notified moderators" + notify_user: "sent a message" + bookmark: "bookmarked this" + like: "liked this" + vote: "voted for this" by_you: off_topic: "You flagged this as off-topic" spam: "You flagged this as spam" @@ -1510,11 +1654,6 @@ en: one: "1 person voted for this post" other: "{{count}} people voted for this post" - edits: - one: 1 edit - other: "{{count}} edits" - zero: no edits - delete: confirm: one: "Are you sure you want to delete that post?" @@ -1528,6 +1667,7 @@ en: last: "Last revision" hide: "Hide revision" show: "Show revision" + revert: "Revert to this revision" comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" displays: inline: @@ -1595,8 +1735,6 @@ en: position_disabled_click: 'enable the "fixed category positions" setting.' parent: "Parent Category" notifications: - title: '' - reasons: watching: title: "Watching" description: "You will automatically watch all new topics in these categories. You will be notified of every new post in every topic, and a count of new replies will be shown." @@ -1608,11 +1746,10 @@ en: description: "You will be notified if someone mentions your @name or replies to you." muted: title: "Muted" - description: "You will never be notified of anything about new topics in these categories, and they will not appear on your unread tab." + description: "You will never be notified of anything about new topics in these categories, and they will not appear in latest." flagging: title: 'Thanks for helping to keep our community civil!' - private_reminder: 'flags are private, only visible to staff' action: 'Flag Post' take_action: "Take Action" notify_action: 'Message' @@ -1624,6 +1761,7 @@ en: submit_tooltip: "Submit the private flag" take_action_tooltip: "Reach the flag threshold immediately, rather than waiting for more community flags" cant: "Sorry, you can't flag this post at this time." + notify_staff: 'Notify staff privately' formatted_name: off_topic: "It's Off-Topic" inappropriate: "It's Inappropriate" @@ -1665,7 +1803,7 @@ en: help: "This topic is unpinned for you; it will display in regular order" pinned_globally: title: "Pinned Globally" - help: "This topic is pinned globally; it will display at the top of all lists" + help: "This topic is pinned globally; it will display at the top of latest and its category" pinned: title: "Pinned" help: "This topic is pinned for you; it will display at the top of its category" @@ -1712,8 +1850,8 @@ en: with_topics: "%{filter} topics" with_category: "%{filter} %{category} topics" latest: - title: - zero: "Latest" + title: "Latest" + title_with_count: one: "Latest (1)" other: "Latest ({{count}})" help: "topics with recent posts" @@ -1731,23 +1869,21 @@ en: title_in: "Category - {{categoryName}}" help: "all topics grouped by category" unread: - title: - zero: "Unread" + title: "Unread" + title_with_count: one: "Unread (1)" other: "Unread ({{count}})" help: "topics you are currently watching or tracking with unread posts" lower_title_with_count: - zero: "" one: "1 unread" other: "{{count}} unread" new: lower_title_with_count: - zero: "" one: "1 new" other: "{{count}} new" lower_title: "new" - title: - zero: "New" + title: "New" + title_with_count: one: "New (1)" other: "New ({{count}})" help: "topics created in the last few days" @@ -1758,8 +1894,8 @@ en: title: "Bookmarks" help: "topics you have bookmarked" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "latest topics in the {{categoryName}} category" @@ -1848,6 +1984,7 @@ en: refresh_report: "Refresh Report" start_date: "Start Date" end_date: "End Date" + groups: "All groups" commits: latest_changes: "Latest changes: please update often!" @@ -1935,15 +2072,25 @@ en: delete_confirm: "Delete this group?" delete_failed: "Unable to delete group. If this is an automatic group, it cannot be destroyed." delete_member_confirm: "Remove '%{username}' from the '%{group}' group?" + delete_owner_confirm: "Remove owner privilege for '%{username}'?" name: "Name" add: "Add" add_members: "Add members" custom: "Custom" + bulk_complete: "The users have been added to the group." + bulk: "Bulk Add to Group" + bulk_paste: "Paste a list of usernames or emails, one per line:" + bulk_select: "(select a group)" automatic: "Automatic" automatic_membership_email_domains: "Users who register with an email domain that exactly matches one in this list will be automatically added to this group:" automatic_membership_retroactive: "Apply the same email domain rule to add existing registered users" default_title: "Default title for all users in this group" primary_group: "Automatically set as primary group" + group_owners: Owners + add_owners: Add owners + incoming_email: "Custom incoming email address" + incoming_email_placeholder: "enter email address" + api: generate_master: "Generate Master API Key" @@ -2020,11 +2167,11 @@ en: is_disabled: "Restore is disabled in the site settings." label: "Restore" title: "Restore the backup" - confirm: "Are your sure you want to restore this backup?" + confirm: "Are you sure you want to restore this backup?" rollback: label: "Rollback" title: "Rollback the database to previous working state" - confirm: "Are your sure you want to rollback the database to the previous working state?" + confirm: "Are you sure you want to rollback the database to the previous working state?" export_csv: user_archive_confirm: "Are you sure you want to download your posts?" @@ -2078,6 +2225,15 @@ en: color: "Color" opacity: "Opacity" copy: "Copy" + email_templates: + title: "Email Templates" + subject: "Subject" + multiple_subjects: "This email template has multiple subjects." + body: "Body" + none_selected: "Select an email template to begin editing." + revert: "Revert Changes" + revert_confirm: "Are you sure you want to revert your changes?" + css_html: title: "CSS/HTML" long_title: "CSS and HTML Customizations" @@ -2122,20 +2278,19 @@ en: love: name: 'love' description: "The like button's color." - wiki: - name: 'wiki' - description: "Base color used for the background of wiki posts." - email: - title: "Email" + title: "Emails" settings: "Settings" - all: "All" + templates: "Templates" + preview_digest: "Preview Digest" sending_test: "Sending test Email..." error: "ERROR - %{server_error}" test_error: "There was a problem sending the test email. Please double-check your mail settings, verify that your host is not blocking mail connections, and try again." sent: "Sent" skipped: "Skipped" + received: "Received" + rejected: "Rejected" sent_at: "Sent At" time: "Time" user: "User" @@ -2145,7 +2300,6 @@ en: send_test: "Send Test Email" sent_test: "sent!" delivery_method: "Delivery Method" - preview_digest: "Preview Digest" preview_digest_desc: "Preview the content of the digest emails sent to inactive users." refresh: "Refresh" format: "Format" @@ -2154,6 +2308,26 @@ en: last_seen_user: "Last Seen User:" reply_key: "Reply Key" skipped_reason: "Skip Reason" + incoming_emails: + from_address: "From" + to_addresses: "To" + cc_addresses: "Cc" + subject: "Subject" + error: "Error" + none: "No incoming emails found." + modal: + title: "Incoming Email Details" + error: "Error" + headers: "Headers" + subject: "Subject" + body: "Body" + rejection_message: "Rejection Mail" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Subject..." + error_placeholder: "Error" logs: none: "No logs found." filters: @@ -2173,6 +2347,7 @@ en: ip_address: "IP" topic_id: "Topic ID" post_id: "Post ID" + category_id: "Category ID" delete: 'Delete' edit: 'Edit' save: 'Save' @@ -2203,6 +2378,7 @@ en: change_site_setting: "change site setting" change_site_customization: "change site customization" delete_site_customization: "delete site customization" + change_site_text: "change site text" suspend_user: "suspend user" unsuspend_user: "unsuspend user" grant_badge: "grant badge" @@ -2213,6 +2389,16 @@ en: impersonate: "impersonate" anonymize_user: "anonymize user" roll_up: "roll up IP blocks" + change_category_settings: "change category settings" + delete_category: "delete category" + create_category: "create category" + block_user: "block user" + unblock_user: "unblock user" + grant_admin: "grant admin" + revoke_admin: "revoke admin" + grant_moderation: "grant moderation" + revoke_moderation: "revoke moderation" + backup_operation: "backup operation" screened_emails: title: "Screened Emails" description: "When someone tries to create a new account, the following email addresses will be checked and the registration will be blocked, or some other action performed." @@ -2281,9 +2467,9 @@ en: pending: 'Users Pending Review' newuser: 'Users at Trust Level 0 (New User)' basic: 'Users at Trust Level 1 (Basic User)' - regular: 'Users at Trust Level 2 (Member)' - leader: 'Users at Trust Level 3 (Regular)' - elder: 'Users at Trust Level 4 (Leader)' + member: 'Users at Trust Level 2 (Member)' + regular: 'Users at Trust Level 3 (Regular)' + leader: 'Users at Trust Level 4 (Leader)' staff: "Staff" admins: 'Admin Users' moderators: 'Moderators' @@ -2317,6 +2503,7 @@ en: moderator: "Moderator?" admin: "Admin?" blocked: "Blocked?" + staged: "Staged?" show_admin_profile: "Admin" edit_title: "Edit Title" save_title: "Save Title" @@ -2381,9 +2568,12 @@ en: deactivate_failed: "There was a problem deactivating the user." unblock_failed: 'There was a problem unblocking the user.' block_failed: 'There was a problem blocking the user.' + block_confirm: 'Are you sure you want to block this user? They will not be able to create any new topics or posts.' + block_accept: 'Yes, block this user' deactivate_explanation: "A deactivated user must re-validate their email." suspended_explanation: "A suspended user can't log in." block_explanation: "A blocked user can't post or start topics." + stage_explanation: "A staged user can only post via email in specific topics." trust_level_change_failed: "There was a problem changing the user's trust level." suspend_modal_title: "Suspend User" trust_level_2_users: "Trust Level 2 Users" @@ -2394,7 +2584,7 @@ en: unlock_trust_level: "Unlock Trust Level" tl3_requirements: title: "Requirements for Trust Level 3" - table_title: "In the last 100 days:" + table_title: "In the last %{time_period} days:" value_heading: "Value" requirement_heading: "Requirement" visits: "Visits" @@ -2458,8 +2648,15 @@ en: dropdown: "Dropdown" site_text: - none: "Choose a type of content to begin editing." + description: "You can customize any of the text on your forum. Please start by searching below:" + search: "Search for the text you'd like to edit" title: 'Text Content' + edit: 'edit' + revert: "Revert Changes" + revert_confirm: "Are you sure you want to revert your changes?" + go_back: "Back to Search" + recommended: "We recommend customizing the following text to suit your needs:" + show_overriden: 'Only show overridden' site_settings: show_overriden: 'Only show overridden' @@ -2501,6 +2698,7 @@ en: badge: Badge display_name: Display Name description: Description + long_description: Long Description badge_type: Badge Type badge_grouping: Group badge_groupings: @@ -2549,8 +2747,8 @@ en: bad_count_warning: header: "WARNING!" text: "There are missing grant samples. This happens when the badge query returns user IDs or post IDs that do not exist. This may cause unexpected results later on - please double-check your query." + no_grant_count: "No badges to be assigned." grant_count: - zero: "No badges to be assigned." one: "1 badge to be assigned." other: "%{count} badges to be assigned." sample: "Sample:" @@ -2668,9 +2866,14 @@ en: mark_watching: 'm, w Watch topic' badges: + earned_n_times: + one: "Earned this badge 1 time" + other: "Earned this badge %{count} times" + granted_on: "Granted %{date}" + others_count: "Others with this badge (%{count})" title: Badges - allow_title: "can be used as a title" - multiple_grant: "can be awarded multiple times" + allow_title: "available title" + multiple_grant: "awarded multiple times" badge_count: one: "1 Badge" other: "%{count} Badges" @@ -2693,97 +2896,6 @@ en: name: Other posting: name: Posting - badge: - editor: - name: Editor - description: First post edit - basic_user: - name: Basic - description: Granted all essential community functions - member: - name: Member - description: Granted invitations - regular: - name: Regular - description: Granted recategorize, rename, followed links and lounge - leader: - name: Leader - description: Granted global edit, pin, close, archive, split and merge - welcome: - name: Welcome - description: Received a like - autobiographer: - name: Autobiographer - description: Filled user profile information - anniversary: - name: Anniversary - description: Active member for a year, posted at least once - nice_post: - name: Nice Post - description: Received 10 likes on a post. This badge can be granted multiple times - good_post: - name: Good Post - description: Received 25 likes on a post. This badge can be granted multiple times - great_post: - name: Great Post - description: Received 50 likes on a post. This badge can be granted multiple times - nice_topic: - name: Nice Topic - description: Received 10 likes on a topic. This badge can be granted multiple times - good_topic: - name: Good Topic - description: Received 25 likes on a topic. This badge can be granted multiple times - great_topic: - name: Great Topic - description: Received 50 likes on a topic. This badge can be granted multiple times - nice_share: - name: Nice Share - description: Shared a post with 25 unique visitors - good_share: - name: Good Share - description: Shared a post with 300 unique visitors - great_share: - name: Great Share - description: Shared a post with 1000 unique visitors - first_like: - name: First Like - description: Liked a post - first_flag: - name: First Flag - description: Flagged a post - promoter: - name: Promoter - description: Invited a user - campaigner: - name: Campaigner - description: Invited 3 basic users (trust level 1) - champion: - name: Champion - description: Invited 5 members (trust level 2) - first_share: - name: First Share - description: Shared a post - first_link: - name: First Link - description: Added an internal link to another topic - first_quote: - name: First Quote - description: Quoted a user - read_guidelines: - name: Read Guidelines - description: Read the community guidelines - reader: - name: Reader - description: Read every post in a topic with more than 100 posts - popular_link: - name: Popular Link - description: Posted an external link with at least 50 clicks - hot_link: - name: Hot Link - description: Posted an external link with at least 300 clicks - famous_link: - name: Famous Link - description: Posted an external link with at least 1000 clicks google_search: |

    Search with Google

    diff --git a/config/locales/client.es.yml b/config/locales/client.es.yml index 4b1f09b9f3b..dab1a1b20d4 100644 --- a/config/locales/client.es.yml +++ b/config/locales/client.es.yml @@ -100,6 +100,8 @@ es: x_years: one: "%{count} año después" other: "%{count} años después" + previous_month: 'Anterior mes' + next_month: 'Próximo mes' share: topic: 'comparte un enlace a este tema' post: 'post #%{postNumber}' @@ -110,6 +112,8 @@ es: email: 'comparte este enlace por email' action_codes: split_topic: "separó este tema %{when}" + invited_user: "invitó a %{who} %{when}" + removed_user: "eliminó a %{who} %{when}" autoclosed: enabled: 'cerrado %{when}' disabled: 'abierto %{when}' @@ -127,9 +131,22 @@ es: disabled: 'sin destacar %{when}' visible: enabled: 'listado %{when}' - disabled: 'sin listar %{when}' + disabled: 'quitado de la lista, invisible %{when}' topic_admin_menu: "acciones de administrador para el tema" emails_are_disabled: "Todos los emails salientes han sido desactivados por un administrador. No se enviará ninguna notificación por email." + s3: + regions: + us_east_1: "US East (N. Virginia)" + us_west_1: "US West (N. California)" + us_west_2: "US West (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "UE (Irlanda)" + eu_central_1: "UE (Frankfurt)" + ap_southeast_1: "Asia Pacific (Singapur)" + ap_southeast_2: "Asia Pacific (Sydney)" + ap_northeast_1: "Asia Pacific (Tokyo)" + ap_northeast_2: "Asia Pacific (Seúl)" + sa_east_1: "Sudamérica (São Paulo)" edit: 'editar el título y la categoría de este tema' not_implemented: "Esta característica no ha sido implementada aún, ¡lo sentimos!" no_value: "No" @@ -162,6 +179,8 @@ es: more: "Más" less: "Menos" never: "nunca" + every_30_minutes: "cada 30 minutos" + every_hour: "cada hora" daily: "cada día" weekly: "cada semana" every_two_weeks: "cada dos semanas" @@ -173,6 +192,7 @@ es: other: "{{count}} caracteres" suggested_topics: title: "Temas Sugeridos" + pm_title: "Mensajes sugeridos" about: simple_title: "Acerca de" title: "Sobre %{title}" @@ -251,7 +271,7 @@ es: one: "Este tema tiene 1 post esperando aprobación" other: "Este tema tiene {{count}} posts esperando aprobación" confirm: "Guardar Cambios" - delete_prompt: "¿Seguro que quieres eliminar a %{username}? Esto eliminará todos sus posts y bloqueará su email y dirección IP." + delete_prompt: "¿Seguro que quieres eliminar a %{username}? Se eliminarán todos sus posts y se bloqueará su email y dirección IP." approval: title: "El Post Necesita Aprobación" description: "Hemos recibido tu nuevo post pero necesita ser aprobado por un moderador antes de aparecer. Por favor, ten paciencia." @@ -294,14 +314,26 @@ es: one: "1 usuario" other: "%{count} usuarios" groups: + empty: + posts: "No hay mensajes publicados por los miembros de este grupo." + members: "Este grupo no tiene miembros." + mentions: "No hay menciones de este grupo." + messages: "No hay mensajes para este grupo." + topics: "No hay temas de miembros de este grupo." + add: "Añadir" + selector_placeholder: "Añadir miembros" + owner: "propietario" visible: "El grupo es visible para todos los usuarios" title: one: "grupo" other: "grupos" members: "Miembros" + topics: "Temas" posts: "Posts" + mentions: "Menciones" + messages: "Mensajes" alias_levels: - title: "¿Quién puede usar este grupo como un alias?" + title: "¿Quién puede emviar mensajes y @mencionar a este grupo?" nobody: "Nadie" only_admins: "Solo administradores" mods_and_admins: "Solo moderadores y administradores" @@ -310,6 +342,19 @@ es: trust_levels: title: "Nivel de confianza entregado automáticamente a miembros cuando son añadidos:" none: "Ninguno" + notifications: + watching: + title: "Vigilando" + description: "e te notificará de cada nuevo post en este mensaje y se mostrará un contador de nuevos posts." + tracking: + title: "Siguiendo" + description: "Se te notificará si alguien menciona tu @nombre o te responde, y un contador de nuevos mensajes será mostrado." + regular: + title: "Normal" + description: "Se te notificará si alguien menciona tu @nombre o te responde." + muted: + title: "Silenciado" + description: "Nunca se te notificará de nada sobre temas en este grupo." user_action_groups: '1': "'Me gusta' Dados" '2': "'Me gusta' Recibidos" @@ -319,16 +364,16 @@ es: '6': "Respuestas" '7': "Menciones" '9': "Citas" - '10': "Favoritos" '11': "Ediciones" '12': "Elementos Enviados" '13': "Bandeja de entrada" '14': "Pendiente" categories: - all: "Todas las categorías" + all: "Categorías" all_subcategories: "todas" no_subcategory: "ninguna" category: "Categoría" + category_list: "Mostrar lista de categorías" reorder: title: "Reorganizar Categorías" title_long: "Reorganizar la lista de categorías" @@ -385,16 +430,15 @@ es: invited_by: "Invitado Por" trust_level: "Nivel de Confianza" notifications: "Notificaciones" + statistics: "Estadísticas" desktop_notifications: label: "Notificaciones de escritorio" not_supported: "Las notificaciones no están disponibles en este navegador. Lo sentimos." perm_default: "Activar notificaciones" perm_denied_btn: "Permiso denegado" - perm_denied_expl: "Has denegado el permiso para las notificaciones. Usa tu navegador para activarlas, después haz clic en el botón cuando esté hecho. (En escritorio: el icono a la izquierda de la barra de direcciones. En móvil: 'info del sitio'.)" + perm_denied_expl: "Has denegado los permisos para las notificaciones en tu navegador web. Configura tu navegador para permitir notificaciones. " disable: "Desactivar notificaciones" - currently_enabled: "(activadas actualmente)" enable: "Activar notificaciones" - currently_disabled: "(desactivadas actualmente)" each_browser_note: "Nota: Tendrás que cambiar esta opción para cada navegador que uses." dismiss_notifications: "Marcador todos como leídos" dismiss_notifications_tooltip: "Marcar todas las notificaciones no leídas como leídas" @@ -418,7 +462,7 @@ es: tracked_categories: "Siguiendo" tracked_categories_instructions: "Seguirás automáticamente todos los nuevos temas en estas categorías. Se añadirá un contador de posts nuevos y sin leer al lado del tema." muted_categories: "Silenciado" - muted_categories_instructions: "No será notificado de nuevos temas en estas categorías, y no aparecerán en la sección de \"no leídos\"." + muted_categories_instructions: "No serás notificado de ningún tema en estas categorías, y no aparecerán en la página de mensajes recientes." delete_account: "Borrar Mi Cuenta" delete_account_confirm: "¿Estás seguro que quieres borrar permanentemente tu cuenta? ¡Esta acción no puede ser revertida!" deleted_yourself: "Tu cuenta ha sido borrada exitosamente." @@ -428,6 +472,8 @@ es: users: "Usuarios" muted_users: "Silenciados" muted_users_instructions: "Omite todas las notificaciones de estos usuarios." + muted_topics_link: "Mostrar temas silenciados" + automatically_unpin_topics: "Dejar de destacar temas automáticamente cuando los leo por completo." staff_counters: flags_given: "reportes útiles" flagged_posts: "posts reportados" @@ -436,8 +482,15 @@ es: warnings_received: "avisos" messages: all: "Todos" - mine: "Míos" - unread: "No leídos" + inbox: "Bandeja de entrada" + sent: "Enviados" + archive: "Archivo" + groups: "Mis grupos" + bulk_select: "Mensajes seleccionados" + move_to_inbox: "Mover a la bandeja de entrada" + move_to_archive: "Archivar" + failed_to_move: "No se han podido mover los mensajes seleccionados (puede haber problemas de conexión)" + select_all: "Seleccionar todo" change_password: success: "(e-mail enviado)" in_progress: "(enviando e-mail)" @@ -482,8 +535,8 @@ es: ok: "Te enviaremos un email para confirmar" invalid: "Por favor, introduce una dirección de correo válida" authenticated: "Tu dirección de correo ha sido autenticada por {{provider}}" + frequency_immediately: "Te enviaremos un email inmediatamente si no has leído aquello que vamos a enviarte." frequency: - zero: "Te enviaremos un email inmediatamente si no has leído aquello que vamos a enviarte." one: "Sólo te enviaremos emails si no te hemos visto en el último minuto." other: "Sólo te enviaremos si no te hemos visto en los últimos {{count}} minutos." name: @@ -521,12 +574,27 @@ es: title: "Distintivo de Tarjeta de Usuario" website: "Sitio Web" email_settings: "E-mail" + like_notification_frequency: + title: "Notificar cuando me dan Me gusta" + always: "Con cada Me gusta que reciban mis posts" + first_time_and_daily: "Al primer Me gusta que reciben mis posts y luego diariamente si reciben más" + first_time: "Al primer Me gusta que reciben mi posts" + never: "Nunca" + email_previous_replies: + title: "Incluir respuestas previas al pie de los emails" + unless_emailed: "a menos que se hayan enviado previamente" + always: "siempre" + never: "nunca" email_digests: title: "Cuando no visite la página, enviarme un correo con las últimas novedades." + every_30_minutes: "cada 30 minutos" + every_hour: "cada hora" daily: "diariamente" every_three_days: "cada tres días" weekly: "semanalmente" every_two_weeks: "cada dos semanas" + include_tl0_in_digests: "Incluir posts de nuevos usuarios en los resúmenes por email" + email_in_reply_to: "Incluir un extracto del post al que se responde en los emails" email_direct: "Envíame un email cuando alguien me cite, responda a mis posts, mencione mi @usuario o me invite a un tema" email_private_messages: "Notifícame por email cuando alguien me envíe un mensaje" email_always: "Quiero recibir notificaciones por email incluso cuando esté de forma activa por el sitio" @@ -557,7 +625,9 @@ es: user: "Invitar Usuario" sent: "Enviadas" none: "No hay ninguna invitación pendiente que mostrar." - truncated: "Mostrando las primeras {{count}} invitaciones." + truncated: + one: "Mostrando la primera invitación." + other: "Mostrando las primeras {{count}} invitaciones." redeemed: "Invitaciones aceptadas" redeemed_tab: "Usado" redeemed_tab_with_count: "Aceptadas ({{count}})" @@ -592,6 +662,15 @@ es: same_as_email: "Tu contraseña es la misma que tu dirección de correo electrónico." ok: "Tu contraseña es válida." instructions: "Debe contener al menos %{count} caracteres." + summary: + title: "Resumen" + stats: "Estadísticas" + top_replies: "Respuestas top" + more_replies: "Más respuestas" + top_topics: "Temas top" + more_topics: "Más temas" + top_badges: "Distintivos top" + more_badges: "Más distintivos" associated_accounts: "Inicios de sesión" ip_address: title: "Última dirección IP" @@ -617,11 +696,13 @@ es: server: "Error del Servidor" forbidden: "Acceso Denegado" unknown: "Error" + not_found: "Página no encontrada" desc: network: "Por favor revisa tu conexión." network_fixed: "Parece que ha vuelto." server: "Código de error: {{status}}" forbidden: "No estás permitido para ver eso." + not_found: "¡Ups! la aplicación intentó cargar una URL inexistente." unknown: "Algo salió mal." buttons: back: "Volver Atrás" @@ -632,11 +713,18 @@ es: logout: "Has cerrado sesión." refresh: "Actualizar" read_only_mode: - enabled: "Modo solo-lectura activado. Puedes continuar navegando por el sitio pero las interacciones podrían no funcionar." + enabled: "Este sitio está en modo solo-lectura. Puedes continuar navegando pero algunas acciones como responder o dar \"me gusta\" no están disponibles por ahora." login_disabled: "Iniciar sesión está desactivado mientras el foro esté en modo solo lectura." + logout_disabled: "Cerrar sesión está desactivado mientras el sitio se encuentre en modo de sólo lectura." too_few_topics_and_posts_notice: "¡Vamos a dar por comenzada la comunidad! Hay %{currentTopics} / %{requiredTopics} temas y %{currentPosts} / %{requiredPosts} mensajes. Los nuevos visitantes necesitan algo que leer y a lo que responder." too_few_topics_notice: "¡Vamos a dar por comenzada la comunidad! Hay %{currentTopics} / %{requiredTopics} temas. Los nuevos visitantes necesitan algo que leer y a lo que responder." too_few_posts_notice: "¡Vamos a dar por empezada la comunidad! Hay %{currentPosts} / %{requiredPosts} mensajes. Los nuevos visitantes necesitan algo que leer y a lo que responder." + logs_error_rate_notice: + reached: "%{timestamp}: La tasa actual del %{rate} ha alcanzado el límite establecido en las opciones del sitio en el %{siteSettingRate}." + exceeded: "%{timestamp}: La tasa actual del %{rate} ha excedido el límite establecido en las opciones del sitio en el %{siteSettingRate}." + rate: + one: "1 error/%{duration}" + other: "%{count} errores/%{duration}" learn_more: "saber más..." year: 'año' year_desc: 'temas creados en los últimos 365 días' @@ -656,22 +744,14 @@ es: signup_cta: sign_up: "Registrarse" hide_session: "Recordar mañana" - hide_forever: "No gracias" + hide_forever: "no, gracias" hidden_for_session: "Vale, te preguntaremos mañana. Recuerda que también puedes usar el botón 'Iniciar sesión' para crear una cuenta en cualquier momento." intro: "¡Hola! :heart_eyes: Parece que estás interesado en las cosas que nuestros usuarios publican, pero no tienes una cuenta registrada." - value_prop: "Si estás registrado, podemos saber exactamente lo que has leído, para que siempre puedas retomar la lectura donde la dejaste. También puedes recibir notificaciones, por aquí o por email, cuando se publiquen nuevos mensajes. Ah, ¡y puedes darle a Me gusta a los mensajes! :heartbeat:" - methods: - sso: "Registrarse es gratis: sólo necesitas una cuenta de la web principal." - only_email: "Registrarse es fácil: sólo necesitas un email y una contraseña." - only_other: "Usa tu cuenta de %{provider} para registrarte." - one_and_email: "Usa tu cuenta de %{provider} para registrarte, o un correo y una contraseña." - multiple_no_email: "Registrarse es fácil: usa cualquiera de nuestras %{count} integraciones con redes sociales." - multiple: "Registrarse es fácil: usa cualquiera de nuestras %{count} integraciones con redes sociales, o un email y una contraseña." - unknown: "error al obtener los métodos de inicio de sesión disponible" + value_prop: "Cuando te registras, recordamos lo que has leído, para que puedas volver justo donde estabas leyendo. También recibes notificaciones, por aquí y por email, cuando se publican nuevos mensajes. ¡También puedes darle a Me gusta a los mensajes! :heartbeat:" summary: enabled_description: "Estás viendo un resumen de este tema: los posts más interesantes determinados por la comunidad." - description: "Hay {{count}} respuestas." - description_time: "Hay {{count}} respuestas con un tiempo de lectura estimado de {{readingTime}} minutos." + description: "Hay {{replyCount}} respuestas." + description_time: "Hay {{replyCount}} respuestas con un tiempo de lectura estimado de {{readingTime}} minutos." enable: 'Resumir este Tema' disable: 'Ver Todos los Posts' deleted_filter: @@ -725,6 +805,9 @@ es: admin_not_allowed_from_ip_address: "No puedes iniciar sesión como admin desde esta dirección IP." resend_activation_email: "Has clic aquí para enviar el email de activación nuevamente." sent_activation_email_again: "Te hemos enviado otro e-mail de activación a {{currentemail}}. Podría tardar algunos minutos en llegar; asegúrate de revisar tu carpeta de spam." + to_continue: "Por favor, inicia sesión" + preferences: "Debes tener una sesión iniciada para cambiar tus preferencias de usuario." + forgot: "No me acuerdo de los detalles de mi cuenta." google: title: "con Google" message: "Autenticando con Google (asegúrate de desactivar cualquier bloqueador de pop ups)" @@ -734,6 +817,9 @@ es: twitter: title: "con Twitter" message: "Autenticando con Twitter (asegúrate de desactivar cualquier bloqueador de pop ups)" + instagram: + title: "con Instagram" + message: "Autenticando con Instagram (asegúrate que los bloqueadores de pop up no están activados)" facebook: title: "con Facebook" message: "Autenticando con Facebook (asegúrate de desactivar cualquier bloqueador de pop ups)" @@ -747,8 +833,13 @@ es: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "más..." options: "Opciones" whisper: "susurrar" add_warning: "Ésta es una advertencia oficial." @@ -759,6 +850,7 @@ es: saved_local_draft_tip: "guardado localmente" similar_topics: "Tu tema es similar a..." drafts_offline: "borradores offline" + group_mentioned: "Al usar {{group}}, estás a punto de notificar a {{count}} personas." error: title_missing: "Es necesario un título" title_too_short: "El título debe ser por lo menos de {{min}} caracteres." @@ -781,7 +873,7 @@ es: show_edit_reason: "(añadir motivo de edición)" reply_placeholder: "Escribe aquí. Usa Markdown, BBCode o HTML para darle formato. Arrastra o pega imágenes." view_new_post: "Ver tu nuevo post." - saving: "Guardando..." + saving: "Guardando" saved: "¡Guardado!" saved_draft: "Borrador en progreso. Selecciona para continuar." uploading: "Subiendo..." @@ -796,6 +888,7 @@ es: link_description: "introduzca descripción del enlace aquí" link_dialog_title: "Insertar Enlace" link_optional_text: "título opcional" + link_placeholder: "http://ejemplo.com \"texto opcional\"" quote_title: "Cita" quote_text: "Cita" code_title: "Texto preformateado" @@ -808,10 +901,11 @@ es: heading_title: "Encabezado" heading_text: "Encabezado" hr_title: "Linea Horizontal" - undo_title: "Deshacer" - redo_title: "Rehacer" help: "Ayuda de Edición con Markdown" toggler: "ocultar o mostrar el panel de edición" + modal_ok: "OK" + modal_cancel: "Cancelar" + cant_send_pm: "Lo sentimos, no puedes enviar un mensaje a %{username}." admin_options_title: "Opciones de moderación para este tema" auto_close: label: "Tiempo para cierre automático del tema" @@ -828,11 +922,16 @@ es: more: "ver notificaciones antiguas" total_flagged: "total de posts reportados" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " + liked_many: + one: "

    {{username}}, {{username2}} y otro {{description}}

    " + other: "

    {{username}}, {{username2}} y {{count}} otros {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -840,6 +939,9 @@ es: moved_post: "

    {{username}} movió {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Se te ha concedido '{{description}}'

    " + group_message_summary: + one: "

    {{count}} mensaje en la bandeja del grupo {{group_name}}

    " + other: "

    {{count}} mensajes en la bandeja del grupo {{group_name}}

    " alt: mentioned: "Mencionado por" quoted: "Citado por" @@ -854,8 +956,10 @@ es: moved_post: "Tu post fue eliminado por" linked: "Enlace a tu post" granted_badge: "Distintivo concedido" + group_message_summary: "Mensajes en la bandeja del grupo" popup: mentioned: '{{username}} te mencionó en "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} te ha mencionado en "{{topic}}" - {{site_title}}' quoted: '{{username}} te citó en "{{topic}}" - {{site_title}}' replied: '{{username}} te respondió en "{{topic}}" - {{site_title}}' posted: '{{username}} publicó en "{{topic}}" - {{site_title}}' @@ -867,9 +971,9 @@ es: from_my_computer: "Desde mi dispositivo" from_the_web: "Desde la web" remote_tip: "enlace a la imagen" - remote_tip_with_attachments: "enlace a la imagen o al archivo ({{authorized_extensions}})" + remote_tip_with_attachments: "enlace a imagen o archivo {{authorized_extensions}}" local_tip: "selecciona las imágenes desde tu dispositivo" - local_tip_with_attachments: "selecciona imágenes o archivos desde tu dispositivo ({{authorized_extensions}})" + local_tip_with_attachments: "selecciona imágenes o archivos desde tu dispositivo {{authorized_extensions}}" hint: "(también puedes arrastrarlos al editor para subirlos)" hint_for_supported_browsers: "puedes también arrastrar o pegar imágenes en el editor" uploading: "Subiendo" @@ -904,12 +1008,14 @@ es: current_user: 'ir a tu página de usuario' topics: bulk: + unlist_topics: "Hacer invisibles" reset_read: "Restablecer leídos" delete: "Eliminar temas" - dismiss_posts: "Ignorar publicaciones" - dismiss_posts_tooltip: "Limpiar contadores de 'no leídos' en estos temas pero continuar mostrándolos en mi lista de 'no leídos' cuando se hacen nuevas publicaciones" - dismiss_topics: "Descartar Temas" - dismiss_topics_tooltip: "Dejar de mostrar estos temas en mi lista de 'no leídos' cuando se hacen nuevas publicaciones" + dismiss: "Descartar" + dismiss_read: "Descartar todos los temas sin leer" + dismiss_button: "Descartar..." + dismiss_tooltip: "Descartar solo los nuevos posts o dejar de seguir los temas" + also_dismiss_topics: "Parar de seguir estos temas para que no aparezcan más en mis mensajes no leídos" dismiss_new: "Ignorar nuevos" toggle: "activar selección de temas en bloque" actions: "Acciones en bloque" @@ -927,17 +1033,17 @@ es: read: "Todavía no has leído ningún tema." posted: "Todavía no has publicado en ningún tema." latest: "No hay temas recientes. Qué pena..." - hot: "No hay temas calientes nuevos." + hot: "No hay temas candentes nuevos." bookmarks: "No tienes temas guardados en marcadores todavía." category: "No hay temas en la categoría {{category}}." top: "No hay temas en el top más vistos." search: "No hay resultados de búsqueda." educate: - new: '

    Tus nuevos temas aparecerán aquí.

    Por defecto, los temas son considerados nuevos y mostrarán un indicador: nuevo si son creados en los 2 últimos días.

    Puedes cambiar esto en tus preferencias.

    ' - unread: '

    Tus temas sin leer aparecerán aquí.

    Por defecto, los temas son considerados no leídos y mostrán contadores de post sin leer 1 si:

    • Creaste el tema
    • Respondiste al tema
    • Leíste el tema durante más de 4 minutos

    O si has establecido específicamente el tema a Seguir o Vigilar en el control de notificaciones al pie de cada tema.

    Puedes cambiar esto en tus preferencias.

    ' + new: '

    Tus temas nuevos aparecen aquí.

    Por defecto, los temas se consideran nuevos y mostrarán un indicador nuevo si fueron creados en los últimos 2 días.

    Dirígite a preferencias para cambiar esto.

    ' + unread: '

    Tus temas sin leer aparecen aquí.

    Por defecto, los temas son considerados sin leer y mostrarán contadores de posts sin leer 1 si:

    • Creaste el tema
    • Respondiste al tema
    • Leíste el tema por más de 4 minutos

    O si has establecido específicamente el tema como Siguiendo o Vigilando a través del control de notificaciones al pie de cada tema.

    Visita tus preferencias para cambiar esto.

    ' bottom: latest: "No hay más temas recientes para leer." - hot: "No hay más temas calientes." + hot: "No hay más temas candentes." posted: "No hay más temas publicados." read: "No hay más temas leídos." new: "No hay más nuevos temas." @@ -954,9 +1060,15 @@ es: create: 'Crear tema' create_long: 'Crear un nuevo tema' private_message: 'Empezar un mensaje' + archive_message: + help: 'Archivar mensaje' + title: 'Archivar' + move_to_inbox: + title: 'Mover a la bandeja de entrada' + help: 'Restaurar mensaje a la bandeja de entrada' list: 'Temas' new: 'nuevo tema' - unread: 'No leídos' + unread: 'sin leer' new_topics: one: '1 tema nuevo' other: '{{count}} temas nuevos' @@ -1004,6 +1116,7 @@ es: auto_close_title: 'Configuración de auto-cerrado' auto_close_save: "Guardar" auto_close_remove: "No Auto-Cerrar Este Tema" + auto_close_immediate: "El último mensaje tiene %{hours} horas de antigüedad, por lo que será cerrado inmediatamente." progress: title: avances go_top: "arriba" @@ -1053,7 +1166,7 @@ es: description: "Nunca se te notificará nada sobre este hilo de mensajes." muted: title: "Silenciar" - description: "Nunca recibirás notificaciones sobre este tema y no aparecerá en tu pestaña de no leídos." + description: "No serás notificado de algo relacionado con este tema, y no aparecerá en la página de mensajes recientes." actions: recover: "Deshacer borrar tema" delete: "Eliminar tema" @@ -1095,25 +1208,24 @@ es: unpin_until: "Quitar este tema del top de la categoría {{categoryLink}} o esperar al %{until}." pin_note: "Los usuarios pueden desanclar el tema de forma individual por sí mismos." pin_validation: "Es obligatorio especificar una fecha para destacar este tema." + not_pinned: "No hay temas destacados en {{categoryLink}}." already_pinned: - zero: "No hay temas destacados en {{categoryLink}}." - one: "Temas anclados actualmente en {{categoryLink}}: 1." - other: "Temas anclados actualmente en {{categoryLink}}: {{count}}." + one: "Hay un tema destacado actualmente en {{categoryLink}}. " + other: "Temas destacados actualmente en {{categoryLink}}: {{count}}" pin_globally: "Hacer que este tema aparezca en el top de todas las listas de temas hasta" confirm_pin_globally: "Hay ya {{count}} temas destacados globalmente. Que haya demasiados temas destacados puede resultar engorroso para los usuarios nuevos y anónimos. ¿Seguro que quieres destacar otro tema de forma global?" unpin_globally: "Eliminar este tema de la parte superior de todas las listas de temas." unpin_globally_until: "Quitar este tema del top de todas las listas de temas o esperar al %{until}." global_pin_note: "Los usuarios pueden desanclar el tema de forma individual por sí mismos." + not_pinned_globally: "No hay temas destacados globalmente." already_pinned_globally: - zero: "No hay temas destacados globalmente." - one: "Temas anclados actualmente de forma global: 1." - other: "Temas destacados de forma global: {{count}}." + one: "Actualmente hay 1 tema destacado globalmente." + other: "Temas destacados globalmente: {{count}}" make_banner: "Hacer de este tema una pancarta que aparece en la parte superior de todas las páginas." remove_banner: "Retire la pancarta que aparece en la parte superior de todas las páginas." banner_note: "Los usuarios pueden descartar la pancarta cerrándola. Sólo un tema puede ser una pancarta en cualquier momento dado." - already_banner: - zero: "No hay tema de encabezado (banner)." - one: "Actualmente hay un tema de encabezado (banner)." + no_banner_exists: "No hay tema de encabezado (banner)." + banner_exists: "Actualmente hay un tema de encabezado (banner)." inviting: "Invitando..." automatically_add_to_groups_optional: "Esta invitación incluye además acceso a estos grupos: (opcional, solo administradores)" automatically_add_to_groups_required: "Esta invitación incluye además acceso a estos grupos: (Requerido, solo administradores)" @@ -1125,6 +1237,7 @@ es: success: "Hemos invitado a ese usuario a participar en este hilo de mensajes." error: "Lo sentimos, hubo un error al invitar a ese usuario." group_name: "nombre del grupo" + controls: "Controles del tema" invite_reply: title: 'Invitar' username_placeholder: "nombre de usuario" @@ -1219,10 +1332,10 @@ es: has_likes_title: one: "1 persona le ha dado Me gusta a este post" other: "{{count}} personas le han dado Me gusta a este post" + has_likes_title_only_you: "te ha gustado este mensaje" has_likes_title_you: - zero: "le has dado Me gusta a este post" - one: "tú y 1 persona más habéis dado Me gusta a este post" - other: "tú y {{count}} personas más habéis dado Me gust a a este post" + one: "A tí y a una persona le ha gustado este mensaje" + other: "A tí y a otros {{count}} les han gustado este mensaje" errors: create: "Lo sentimos, hubo un error al crear tu post. Por favor, inténtalo de nuevo." edit: "Lo sentimos, hubo un error al editar tu post. Por favor, inténtalo de nuevo." @@ -1242,9 +1355,10 @@ es: via_email: "este post llegó por email" whisper: "esto post es un susurro privado para moderadores" wiki: - about: "Este post es tipo wiki, cualquier usuario registrado puede editarlo" + about: "este post es tipo wiki" archetypes: save: 'Guardar opciones' + few_likes_left: "¡Gracias por compartir tu afecto! Te quedan solo unos pocos me gusta para hoy." controls: reply: "componer una respuesta para este post" like: "me gusta este post" @@ -1270,6 +1384,7 @@ es: revert_to_regular: "Eliminar el formato de post de staff" rebake: "Reconstruir HTML" unhide: "Deshacer ocultar" + change_owner: "Cambiar dueño" actions: flag: 'Reportar' defer_flags: @@ -1291,17 +1406,14 @@ es: like: "Deshacer Me gusta" vote: "Deshacer voto" people: - off_topic: "{{icons}} reportó esto como off-topic" - spam: "{{icons}} reportó esto como spam" - spam_with_url: "{{icons}} reportó esto como spam" - inappropriate: "{{icons}} flagged reportó esto como inapropiado" - notify_moderators: "{{icons}} ha notificado a los moderadores" - notify_moderators_with_url: "{{icons}} moderadores notificados" - notify_user: "{{icons}} ha enviado un mensaje" - notify_user_with_url: "{{icons}} ha enviado un mensaje" - bookmark: "{{icons}} ha marcado esto" - like: "{{icons}} les gusta esto" - vote: "{{icons}} ha votado esto" + off_topic: "reportó esto como off-topic" + spam: "reportó esto como spam" + inappropriate: "reportó esto como inapropiado" + notify_moderators: "notificó a moderadores" + notify_user: "envió un mensaje" + bookmark: "guardó esto en marcadores" + like: "le gustó esto" + vote: "votó por esto" by_you: off_topic: "Has reportado esto como off-topic" spam: "Has reportado esto como Spam" @@ -1361,10 +1473,6 @@ es: vote: one: "Una persona ha votado este post" other: "{{count}} personas votaron este post" - edits: - one: 1 edición - other: "{{count}} ediciones" - zero: sin ediciones delete: confirm: one: "¿Seguro que quieres eliminar ese post?" @@ -1377,6 +1485,7 @@ es: last: "Última revisión" hide: "Ocultar revisión." show: "Mostrar revisión." + revert: "Volver a esta revisión" comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" displays: inline: @@ -1391,7 +1500,7 @@ es: category: can: 'puede… ' none: '(sin categoría)' - all: 'Todas las categorías' + all: 'Categorías' choose: 'Seleccionar una categoría…' edit: 'editar' edit_long: "Editar" @@ -1445,19 +1554,18 @@ es: notifications: watching: title: "Vigilar" - description: "Seguirás automáticamente todos los nuevos temas en estas categorías. Se te notificará de cada nuevo post y tema, y además, se añadirá un contador de posts nuevos y sin leer al lado del tema." + description: "Vigilarás automáticamente todos los nuevos temas en estas categorías. Serás notificado por cada nuevo mensaje en cada tema, y verás una cuenta de las nuevas respuestas." tracking: title: "Seguir" - description: "Seguirás automáticamente todos los nuevos temas en estas categorías. Se añadirá un contador de posts nuevos y sin leer al lado del tema." + description: "Seguirás automáticamente todos los nuevos temas en estas categorías. Serás notificado si alguien menciona tu @nombre o te responde, y verás una cuenta de las nuevas respuestas." regular: title: "Normal" description: "Se te notificará solo si alguien menciona tu @nombre o te responde a un post." muted: title: "Silenciadas" - description: "No se te notificará de nuevos temas en estas categorías y no aparecerán en la pestaña de no leídos." + description: "No serás notificado de ningún tema en estas categorías, y no aparecerán en la página de mensajes recientes." flagging: title: '¡Gracias por ayudar a mantener una comunidad civilizada!' - private_reminder: 'los reportes son privados, son visibles únicamente por los administradores' action: 'Reportar post' take_action: "Tomar medidas" notify_action: 'Mensaje' @@ -1469,6 +1577,7 @@ es: submit_tooltip: "Enviar el reporte privado" take_action_tooltip: "Alcanzar el umbral de reportes inmediatamente, en vez de esperar a más reportes de la comunidad" cant: "Lo sentimos, no puedes reportar este post en este momento." + notify_staff: 'Notificar a los administradores de forma privada' formatted_name: off_topic: "Está fuera de lugar" inappropriate: "Es inapropiado" @@ -1507,7 +1616,7 @@ es: help: "Este tema se ha dejado de destacar para ti; en tu listado de temas se mostrará en orden normal" pinned_globally: title: "Destacado globalmente" - help: "Este tema ha sido destacado globalmente, se mostrará en la parte superior de todas las listas" + help: "Este tema ha sido destacado globalmente, se mostrará en la parte superior de la página de mensajes recientes y de su categoría." pinned: title: "Destacado" help: "Este tema ha sido destacado para ti; se mostrará en la parte superior de su categoría" @@ -1550,14 +1659,14 @@ es: with_topics: "%{filter} temas" with_category: "Foro de %{category} - %{filter}" latest: - title: - zero: "Recientes" - one: "Recientes (1)" + title: "Recientes" + title_with_count: + one: "Reciente (1)" other: "Recientes ({{count}})" help: "temas con posts recientes" hot: - title: "Popular" - help: "una selección de los temas más populares" + title: "Candente" + help: "una selección de los temas más candentes" read: title: "Leídos" help: "temas que ya has leído" @@ -1569,22 +1678,22 @@ es: title_in: "Categoría - {{categoryName}}" help: "todos los temas agrupados por categoría" unread: - title: - zero: "No leídos" - one: "No leído (1)" - other: "No leídos ({{count}})" + title: "Sin leer" + title_with_count: + one: "Sin leer (1)" + other: "Sin leer ({{count}})" help: "temas que estás vigilando o siguiendo actualmente con posts no leídos" lower_title_with_count: - one: "1 no leído" + one: "{{count}} sin leer" other: "{{count}} sin leer" new: lower_title_with_count: - one: "1 nuevo" - other: "{{count}} nuevos" + one: "1 tema nuevo" + other: "{{count}} temas nuevos" lower_title: "nuevo" - title: - zero: "Nuevos" - one: "Nuevo (1)" + title: "Nuevo" + title_with_count: + one: "Nuevos ({{count}})" other: "Nuevos ({{count}})" help: "temas publicados en los últimos días" posted: @@ -1594,8 +1703,8 @@ es: title: "Marcadores" help: "temas que has guardado en marcadores" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "temas recientes en la categoría {{categoryName}}" @@ -1677,6 +1786,7 @@ es: refresh_report: "Actualizar reporte" start_date: "Desde fecha" end_date: "Hasta fecha" + groups: "Todos los grupos" commits: latest_changes: "Cambios recientes: ¡actualiza a menudo!" by: "por" @@ -1757,15 +1867,24 @@ es: delete_confirm: "Borrar este grupo?" delete_failed: "No se pudo borrar el grupo. Si este es un grupo automático, no se puede destruir." delete_member_confirm: "¿Eliminar a '%{username}' del grupo '%{group}'?" + delete_owner_confirm: "¿Quitar privilegios de propietario para '%{username}'?" name: "Nombre" add: "Añadir" add_members: "Añadir miembros" custom: "Personalizado" + bulk_complete: "Los usuarios han sido añadidos al grupo." + bulk: "Añadir al grupo en masa" + bulk_paste: "Pega una lista de nombres de usuario o emails, uno por línea:" + bulk_select: "(selecciona un grupo)" automatic: "Automático" automatic_membership_email_domains: "Los usuarios que se registren con un dominio de e-mail que esté en esta lista serán automáticamente añadidos a este grupo:" automatic_membership_retroactive: "Aplicar la misma regla de dominio de email para usuarios registrados existentes " default_title: "Título por defecto para todos los miembros en este grupo" primary_group: "Establecer como grupo primario automáticamente" + group_owners: Propietarios + add_owners: Añadir propietarios + incoming_email: "Correos electrónicos entrantes personalizados" + incoming_email_placeholder: "introducir dirección de emai" api: generate_master: "Generar clave maestra de API" none: "No hay ninguna clave de API activa en este momento." @@ -1839,11 +1958,11 @@ es: is_disabled: "Restaurar está deshabilitado en la configuración del sitio." label: "Restaurar" title: "Restaurar la copia de seguridad" - confirm: "¿Estás seguro que quieres restaurar esta copia de seguridad?" + confirm: "¿Seguro que quieres restaurar esta copia de seguridad?" rollback: label: "Revertir" title: "Regresar la base de datos al estado funcional anterior" - confirm: "¿Estás seguro que quieres regresar la base de datos al estado funcional anterior?" + confirm: "¿Seguro que quieres retornar la base de datos al estado funcional previo?" export_csv: user_archive_confirm: "¿Seguro que quieres descargar todos tus posts?" success: "Exportación iniciada, se te notificará a través de un mensaje cuando el proceso se haya completado." @@ -1894,6 +2013,14 @@ es: color: "Color" opacity: "Opacidad" copy: "Copiar" + email_templates: + title: "Diseño del email" + subject: "Título del email" + multiple_subjects: "Esta plantilla de email tiene múltiples asuntos." + body: "Cuerpo del email" + none_selected: "Selecciona un 'diseño de email' para comenzar a editar" + revert: "Revertir los cambios" + revert_confirm: "¿Estás seguro de querer revertir los cambios?" css_html: title: "CSS/HTML" long_title: "Personalizaciones CSS y HTML" @@ -1938,18 +2065,18 @@ es: love: name: 'me gusta' description: "El color del botón de \"me gusta\"" - wiki: - name: 'wiki' - description: "Color base usado para el fondo en los posts del wiki." email: - title: "Email" + title: "Emails" settings: "Ajustes" - all: "Todos" + templates: "Plantillas" + preview_digest: "Vista previa de Resumen" sending_test: "Enviando e-mail de prueba..." error: "ERROR - %{server_error}" test_error: "Hubo un error al enviar el email de prueba. Por favor, revisa la configuración de correo, verifica que tu servicio de alojamiento no esté bloqueando los puertos de conexión de correo, y prueba de nuevo." sent: "Enviado" skipped: "Omitidos" + received: "Recibidos" + rejected: "Rechazados" sent_at: "Enviado a" time: "Fecha" user: "Usuario" @@ -1959,7 +2086,6 @@ es: send_test: "Enviar email de prueba" sent_test: "enviado!" delivery_method: "Método de entrega" - preview_digest: "Vista previa de Resumen" preview_digest_desc: "Previsualiza el contenido del email de resumen enviado a usuarios inactivos." refresh: "Actualizar" format: "Formato" @@ -1968,6 +2094,25 @@ es: last_seen_user: "Último usuario visto:" reply_key: "Clave de respuesta" skipped_reason: "Saltar motivo" + incoming_emails: + from_address: "De" + to_addresses: "Para" + cc_addresses: "Cc" + subject: "Asunto" + error: "Error" + none: "No se encontraron emails entrantes." + modal: + title: "Detalles de emails entrantes" + error: "Error" + subject: "Asunto" + body: "Cuerpo" + rejection_message: "Correo de rechazo" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Asunto..." + error_placeholder: "Error" logs: none: "No se han encontrado registros." filters: @@ -1986,6 +2131,7 @@ es: ip_address: "IP" topic_id: "ID del Tema" post_id: "ID del Post" + category_id: "ID de la categoría" delete: 'Eliminar' edit: 'Editar' save: 'Guardar' @@ -2016,6 +2162,7 @@ es: change_site_setting: "cambiar configuración del sitio" change_site_customization: "cambiar customización del sitio" delete_site_customization: "borrar customización del sitio" + change_site_text: "cambiar textos" suspend_user: "suspender usuario" unsuspend_user: "desbloquear usuario" grant_badge: "conceder distintivo" @@ -2026,6 +2173,16 @@ es: impersonate: "impersonar" anonymize_user: "anonimizar usuario" roll_up: "agrupar bloqueos de IP" + change_category_settings: "cambiar opciones de categoría" + delete_category: "eliminar categoría" + create_category: "crear categoría" + block_user: "bloquear usuario" + unblock_user: "desbloquear usuario" + grant_admin: "conceder administración" + revoke_admin: "revocar administración" + grant_moderation: "conceder moderación" + revoke_moderation: "revocar moderación" + backup_operation: "operación de copia de seguridad de respaldo" screened_emails: title: "Correos bloqueados" description: "Cuando alguien trata de crear una cuenta nueva, los siguientes correos serán revisados y el registro será bloqueado, o alguna otra acción será realizada." @@ -2092,9 +2249,9 @@ es: pending: 'Usuarios pendientes de revisión' newuser: 'Usuarios con nivel de confianza 0 (Nuevo)' basic: 'Usuarios con nivel de confianza 1 (Básico)' - regular: 'Usuarios con Nivel de confianza 2 (Miembro)' - leader: 'Usuarios con Nivel de confianza 3 (Habitual)' - elder: 'Usuarios con Nivel de confianza 4 (Líder)' + member: 'Usuarios en nivel de confianza 2 (Miembro)' + regular: 'Usuarios en nivel de confianza 3 (Habitual)' + leader: 'Usuarios en nivel de confianza 4 (Líder)' staff: "Staff" admins: 'Administradores' moderators: 'Moderadores' @@ -2127,6 +2284,7 @@ es: moderator: "¿Moderador?" admin: "¿Administrador?" blocked: "¿Bloqueado?" + staged: "¿Provisional?" show_admin_profile: "Administrador" edit_title: "Editar título" save_title: "Guardar título" @@ -2191,9 +2349,12 @@ es: deactivate_failed: "Ha habido un problema desactivando el usuario." unblock_failed: 'Ha habido un problema desbloqueando el usuario.' block_failed: 'Ha habido un problema bloqueando el usuario.' + block_confirm: '¿Seguro que quieres bloquear a este usuario? No podrá crear nuevos temas ni publicar posts.' + block_accept: 'Sí, bloquear este usuario' deactivate_explanation: "Un usuario desactivado debe rehabilitar su dirección de correo." suspended_explanation: "Un usuario suspendido no puede ingresar al sitio." block_explanation: "Un usuario bloqueado no puede publicar posts ni crear temas." + stage_explanation: "Un usuario provisional sólo puede publicar por email en temas específicos." trust_level_change_failed: "Ha habido un problema cambiando el nivel de confianza del usuario." suspend_modal_title: "Suspender Usuario" trust_level_2_users: "Usuarios del nivel de Confianza 2" @@ -2204,7 +2365,7 @@ es: unlock_trust_level: "Desbloquear Nivel de Confianza" tl3_requirements: title: "Requerimientos para el nivel de confianza 3" - table_title: "En los últimos 100 días:" + table_title: "En los últimos %{time_period} días:" value_heading: "Valor" requirement_heading: "Requerimiento" visits: "Visitas" @@ -2265,8 +2426,15 @@ es: confirm: 'Confirmación' dropdown: "Lista" site_text: - none: "Elige un tipo de contenido para empezar a editar." + description: "Puedes personalizar cualquier texto de tu foro. Empieza por buscar debajo:" + search: "Busca el texto que te gustaría editar" title: 'Contenido de Texto' + edit: 'editar' + revert: "Deshacer cambios" + revert_confirm: "¿Estás seguro de que quieres deshacer tus cambios?" + go_back: "Volver a la búsqueda" + recommended: "Recomendamos personalizar los siguientes textos para que se ajusten a tus necesidades:" + show_overriden: 'Sólo mostrar textos editados' site_settings: show_overriden: 'Sólo mostrar lo personalizado' title: 'Ajustes del sitio' @@ -2306,6 +2474,7 @@ es: badge: Distintivo display_name: Nombre a mostrar description: Descripción + long_description: Descripción completa badge_type: Tipo de distintivo badge_grouping: Grupo badge_groupings: @@ -2354,9 +2523,9 @@ es: bad_count_warning: header: "¡ADVERTENCIA!" text: "Faltan algunas muestras a la hora de conceder el distintivo. Esto ocurre cuando la query del distintivo devuelve IDs de usuarios o de posts que no existen. Esto podría causar resultados inesperados más tarde - por favor, revisa de nuevo tu query." + no_grant_count: "No hay distintivos para asignar." grant_count: - zero: "No hay distintivos para asignar." - one: "1 distintivo para conceder." + one: "%{count} distintivos para conceder." other: "%{count} distintivos para conceder." sample: "Ejemplo:" grant: @@ -2465,9 +2634,14 @@ es: mark_tracking: 'm, t Seguir tema' mark_watching: 'm, w Vigilar Tema' badges: + earned_n_times: + one: "Ganó este distintivo 1 vez" + other: "Ganó este distintivo %{count} veces" + granted_on: "Concedido el %{date}" + others_count: "Otras personas con este distintivo (%{count})" title: Distintivos - allow_title: "puede ser utilizado como título" - multiple_grant: "puede ser otorgado varias veces" + allow_title: "título disponible" + multiple_grant: "puede ser concedido varias veces" badge_count: one: "1 distintivo" other: "%{count} distintivos" @@ -2490,97 +2664,6 @@ es: name: Miscelánea posting: name: Escritura - badge: - editor: - name: Editor - description: Editó un post por primera vez - basic_user: - name: Básico - description: Dispone de todas las funciones esenciales de la comunidad - member: - name: Miembro - description: Se le conceden invitaciones - regular: - name: Habitual - description: Se le concede el poder recategorizar, renombrar, publicar enlacer sin el tag no-follow y acceso a sala vip - leader: - name: Líder - description: Se le concede el poder editar, destacar, cerrar, archivar, dividir y combinar temas globalmente - welcome: - name: ¡Bienvenido/a! - description: Recibió un "me gusta" - autobiographer: - name: Autobiógrafo - description: Detalló información en su perfil de usuario - anniversary: - name: Aniversario - description: Miembro activo desde hace un año y ha publicado al menos una vez - nice_post: - name: Buen post - description: Recibió 10 "me gusta" en un post. Este distintivo puede ser concedido varias veces - good_post: - name: Gran post - description: Recibió 25 "me gusta" en un post. Este distintivo puede ser concedido varias veces - great_post: - name: Excelente post - description: Recibió 50 "me gusta" en un post. Este distintivo puede ser concedido varias veces - nice_topic: - name: Buen tema - description: Recibió 10 "me gusta" en un tema. Este distintivo puede ser concedido varias veces - good_topic: - name: Gran tema - description: Recibió 25 "me gusta" en un tema. Este distintivo puede ser concedido varias veces - great_topic: - name: Excelente tema - description: Recibió 50 "me gusta" en un tema. Este distintivo puede ser concedido varias veces - nice_share: - name: Buena contribución - description: Compartió un post con 25 visitantes únicos - good_share: - name: Gran contribución - description: Compartió un post con 300 visitantes únicos - great_share: - name: Excelente contribución - description: Compartió un post con 1000 visitantes únicos - first_like: - name: Primer "me gusta" - description: Le dio a "me gusta" a un post - first_flag: - name: Primer reporte - description: Reportó un post - promoter: - name: Promotor - description: Invitó a un usuario - campaigner: - name: Partidiario - description: Invitó a 3 usuarios básicos (nivel de confianza 1) - champion: - name: Campeón - description: Invitó a 5 miembros (nivel de confianza 2) - first_share: - name: Primer Compartido - description: Compartió un post - first_link: - name: Primer Enlace - description: Añadió un enlace interno a otro tema - first_quote: - name: Primera Cita - description: Citó a un usuario - read_guidelines: - name: Directrices leídas - description: Leyó las directrices de la comunidad - reader: - name: Lector - description: Leyó todos los posts en un tema con más de 100 - popular_link: - name: Enlace Popular - description: Publicó un enlace externo con al menos 50 clicks - hot_link: - name: Enlace Candente - description: Publicó un enlace externo con al menos 300 clicks - famous_link: - name: Enlace Famoso - description: Publicó un enlace externo con al menos 1000 clicks google_search: |

    Buscar con Google

    diff --git a/config/locales/client.fa_IR.yml b/config/locales/client.fa_IR.yml index 337852a60ec..d88193c39c1 100644 --- a/config/locales/client.fa_IR.yml +++ b/config/locales/client.fa_IR.yml @@ -81,6 +81,8 @@ fa_IR: other: "%{count} ماه بعد" x_years: other: "%{count} سال بعد" + previous_month: 'ماه پیشین' + next_month: 'ماه بعد' share: topic: 'پیوندی به این موضوع را به اشتراک بگذارید' post: 'ارسال #%{postNumber}' @@ -89,6 +91,26 @@ fa_IR: facebook: 'این پیوند را در فیسبوک به اشتراک بگذارید.' google+: 'این پیوند را در Google+‎ به اشتراک بگذارید.' email: 'این پیوند را با ایمیل بفرستید' + action_codes: + split_topic: "این مبحث را جدا کنید %{when}" + autoclosed: + enabled: 'بسته شد %{when}' + disabled: 'باز شد %{when}' + closed: + enabled: 'بسته شد %{when}' + disabled: 'باز شد %{when}' + archived: + enabled: 'بایگانی شد %{when}' + disabled: 'از بایگانی درآمد %{when}' + pinned: + enabled: 'سنجاق شد %{when}' + disabled: 'از سنجاق خارج شد %{when}' + pinned_globally: + enabled: 'به صورت سراسری سنجاق شد %{when}' + disabled: 'از سنجاق خارج شد %{when}' + visible: + enabled: 'فهرست شد %{when}' + disabled: 'از فهرست پاک شد %{when}' topic_admin_menu: "اقدامات مدیریت موضوع" emails_are_disabled: "تمام ایمیل های خروجی بصورت کلی توسط مدیر قطع شده است. هیچگونه ایمیل اگاه سازی ارسال نخواهد شد." edit: 'سرنویس و دستهٔ این موضوع را ویرایش کنید' @@ -104,6 +126,7 @@ fa_IR: admin_title: "مدیر" flags_title: "پرچم‌ها" show_more: "بیش‌تر نشان بده" + show_help: "گزینه ها" links: "پیوندها" links_lowercase: other: "پیوندها" @@ -175,6 +198,7 @@ fa_IR: saved: "ذخیره شد!" upload: "بارگذاری" uploading: "در حال بارگذاری..." + uploading_filename: "بارگذاری {{filename}}..." uploaded: "بارگذاری شد!" enable: "فعال کردن" disable: "ازکاراندازی" @@ -182,6 +206,7 @@ fa_IR: revert: "برگشت" failed: "ناموفق" switch_to_anon: "حالت ناشناس " + switch_from_anon: "از حالت ناشناس خارج شدن" banner: close: "این سردر را رد بده." edit: "این بنر را ویرایش کنید >>" @@ -203,7 +228,6 @@ fa_IR: has_pending_posts: other: "این عنوان دارای {{count}} نوشته‌ی در انتظار تایید است" confirm: "ذخیره سازی تغییرها" - delete_prompt: "آیا مطمئن هستی از پاک کردن این %{username}? این باعث پاک شدن تمام پست ها و منجر به بلاک شدن ایمیل و IP می شود." approval: title: "نوشته نیاز به تایید دارد" description: "ما نوشته شما را دریافت کرده ایم ولی نیاز به تایید آن توسط یکی از مدیران است قبل از اینکه نمایش داده شود. لطفا صبر داشته باشید." @@ -244,18 +268,43 @@ fa_IR: total_rows: other: "%{count} کاربران" groups: + empty: + posts: "در این گروه هیچ پستی توسط کاربران " + members: "هیچ عضوی در این گروه وجود ندارد." + mentions: "هیچ کجا به این گروه اشاره‌ای نشده است." + messages: "پیامی در این گروه وجود ندارد." + topics: "در این گروه هیچ موضوعی توسط کاربران ارسال نشده." + add: "افزودن" + selector_placeholder: "افزودن عضو" + owner: "مالک" visible: "همهٔ کاربران گروه را می‌بینند" title: other: "گروه‌ها" members: "اعضا" posts: "نوشته ها" alias_levels: - title: "چه کسی می تواند این گروه به عنوان یک نام مستعار استفاده کند؟" + title: "چه کسی میتواند پیام بفرستد و به این گروه @اشاره کند؟" nobody: "هیچ‌کس" only_admins: "تنها مدیران" mods_and_admins: "فقط گردانندگان و ادمین ها" members_mods_and_admins: "تنها کاربران گروه، مدیران ومدیران کل" everyone: "هرکس" + trust_levels: + title: "سطح اعتماد به صورت خودکار به اعضاء داده میشود وقتی که آن ها اضافه میشوند:" + none: "هیچ کدام" + notifications: + watching: + title: "در حال مشاهده" + description: "در صورت ارسال شدن پست جدید در هر پیام یک اعلان برای شما ارسال می‌شود و تعداد پاسخ‌های جدید نمایش داده می‌شود." + tracking: + title: "ردگیری" + description: "در صورت اشاره شدن به @نام شما توسط اشخاص دیگر و یا دریافت پاسخ، اعلانی برای شما ارسال می‌شود و تعداد پاسخ‌های جدید نمایش داده می‌شود." + regular: + title: "معمولی" + description: "در صورتی که به @نام شما اشاره شود و یا پاسخی دریافت کنید اعلانی برای شما ارسال می‌شود." + muted: + title: "بی صدا شد" + description: "با ارسال شدن موضوعات جدید در این گروه شما اعلانی دریافت نمی‌کنید." user_action_groups: '1': "پسندهای داده شده" '2': "پسندهای دریافت شده" @@ -265,7 +314,6 @@ fa_IR: '6': "واکنش" '7': "اشاره‌ها" '9': "نقل‌قول‌ها" - '10': "ستاره‌دار" '11': "ویرایش‌ها" '12': "ارسال موارد" '13': "صندوق دریافت" @@ -275,6 +323,15 @@ fa_IR: all_subcategories: "همه" no_subcategory: "هیچی" category: "دسته بندی" + category_list: "نمایش لیست دسته‌بندی" + reorder: + title: "دوباره مرتب کردن دسته بندی ها" + title_long: "سازماندهی مجدد فهرست دسته بندی ها" + fix_order: "اصلاح موقعیت ها" + fix_order_tooltip: "همه دسته بندی ها یک شماره موقعیت مخصوص ندارند, که ممکن است باعث نتایج غیر منتظره شود." + save: "ذخیره ترتیب" + apply_all: "اعمال کردن" + position: "موقعیت" posts: "نوشته ها" topics: "موضوعات" latest: "آخرین" @@ -302,6 +359,8 @@ fa_IR: topics_entered: "موضوعات وارد شده" post_count: "# نوشته ها" confirm_delete_other_accounts: "آیا مطمئن هستید که می خواهید این حساب کاربری را حذف نمایید؟" + user_fields: + none: "(یک گزینه انتخاب کنید)" user: said: "{{username}}:" profile: "نمایه" @@ -313,11 +372,21 @@ fa_IR: private_messages: "پیام‌ها" activity_stream: "فعالیت" preferences: "تنظیمات" + expand_profile: "باز کردن" bookmarks: "نشانک‌ها" bio: "درباره من" invited_by: "فراخوان از سوی" trust_level: "سطح اعتماد" notifications: "آگاه‌سازی‌ها" + statistics: "وضعیت" + desktop_notifications: + label: "اعلانات دسکتاپ" + not_supported: "اعلانات بر روی این مرورگر پشتیبانی نمیشوند. با عرض پوزش." + perm_default: "فعال کردن اعلانات" + perm_denied_btn: "دسترسی رد شد" + disable: "غیرفعال کردن اعلانات" + enable: "فعال کردن اعلانات" + each_browser_note: "نکته: شما باید این تنظیمات را در هر مرورگری که استفاده میکنید تغییر دهید." dismiss_notifications: "علامت گذاری همه به عنوان خوانده شده" dismiss_notifications_tooltip: "علامت گذاری همه اطلاعیه های خوانده نشده به عنوان خوانده شده" disable_jump_reply: "بعد از پاسخ من به پست من پرش نکن" @@ -330,6 +399,7 @@ fa_IR: admin: "{{user}} یک مدیر کل است" moderator_tooltip: "این کاربر یک مدیر است" admin_tooltip: "این کاربر یک ادمین است" + blocked_tooltip: "این کاربر مسدود شده است" suspended_notice: "این کاربر تا {{date}} در وضعیت معلق است." suspended_reason: "دلیل: " github_profile: "Github" @@ -339,7 +409,7 @@ fa_IR: tracked_categories: "پی‌گیری شده" tracked_categories_instructions: "شما به صورت خودکار تمام عناوین جدید در این دسته را پیگیری خواهید کرد. تعداد نوشته های جدید در کنار عنواین نمایش داده می‌شود." muted_categories: "بی صدا شد" - muted_categories_instructions: "از هر آن‌چه درباره موضوعات تازه در این دسته‌ بندی ها روی دهد، شما آگاه نخواهید شد و در تب نخواندهٔ‌ شما نمایش داده نمی‌شوند." + muted_categories_instructions: "شما از هیچ چیز مباحث جدید این دسته بندی ها آگاه نمیشوید, و آن ها در آخرین ها نمایش داده نمیشوند." delete_account: "حساب من را پاک کن" delete_account_confirm: "آیا مطمئنید که می‌خواهید شناسه‌تان را برای همیشه پاک کنید؟ برگشتی در کار نیست!" deleted_yourself: "حساب‌ کاربری شما با موفقیت حذف شد." @@ -349,6 +419,7 @@ fa_IR: users: "کاربران" muted_users: "بی صدا شده" muted_users_instructions: "متفوقف کردن تمام اطلاعیه ها از طرف این کاربران." + muted_topics_link: "نمایش مباحث قطع شده" staff_counters: flags_given: "پرچم گذاری های مفید" flagged_posts: "نوشته های پرچم گذاری شده" @@ -357,8 +428,14 @@ fa_IR: warnings_received: "هشدارها" messages: all: "همه" - mine: "خودم" - unread: "خوانده‌ نشده‌" + inbox: "صندوق دریافت" + sent: "ارسال شد" + archive: "بایگانی" + groups: "گروه های من" + bulk_select: "انتخاب پیام‌ها" + move_to_inbox: "انتقال به صندوق دریافت" + failed_to_move: "انتقال پیام‌های انتخاب شده با اشکال مواجه شد (شاید اتصال شما در دسترس نیست)" + select_all: "انتخاب همه" change_password: success: "(ایمیل ارسال شد)" in_progress: "(فرستادن ایمیل)" @@ -390,6 +467,7 @@ fa_IR: upload_title: "تصویرتان را بار بگذارید" upload_picture: "بارگذاری تصویر" image_is_not_a_square: "اخطار: ما تصویر شما بریدیم; طول و عرض برابر نبود." + cache_notice: "شما با موفقیت تصویر پروفایل خود را تغییر دادید اما به دلیل ذخیره سازی مرورگر ممکن است کمی زمان ببرد." change_profile_background: title: "پس‌زمینه نمایه" instructions: "تصاویر پس‌زمینه نمایه‌ها در مرکز قرار میگیرند و به صورت پیش‌فرض طول 850px دارند." @@ -402,10 +480,9 @@ fa_IR: ok: "ایمیلی برای تایید برایتان می‌فرستیم" invalid: "لطفا یک آدرس ایمیل معتبر وارد کنید" authenticated: "ایمیل شما تصدیق شد توسط {{provider}}" + frequency_immediately: "ما بلافاصله برای شما ایمیل میفرستیم اگر نخوانده باشید چیزی را که ما درباره آن برای شما ایمیل میفرستیم." frequency: - zero: "ما برای شما سریعا ایمیلی می فرستیم در صورتی که چیزهای فرستاده شده در ایمیل را نخوانده باشید" - one: "ما در صورتی به شما ایمیل می زنیم که شما را تا آخرین لحظه ندیده باشیم" - other: "ما در صورتی به شما ایمیل می زنیم که شما را تا دقیقه {{count}} ندیده باشیم " + other: "ما فقط در صورتی برای شما ایمیل میفرستیم که شما را در {{count}} دقیقه آخر ندیده باشیم." name: title: "نام" instructions: "نام کامل (اختیاری)" @@ -456,20 +533,36 @@ fa_IR: label: "موضوعات را جدید در نظر بگیر وقتی" not_viewed: "من هنوز آن ها را ندیدم" last_here: "آخرین باری که اینجا بودم ساخته شده‌اند" + after_1_day: "ایجاد شده در روز گذشته" + after_2_days: "ایجاد شده در 2 روز گذشته" + after_1_week: "ایجاد شده در هفته گذشته" + after_2_weeks: "ایجاد شده در 2 هفته گذشته" auto_track_topics: "دنبال کردن خودکار موضوعاتی که وارد می‌شوم" auto_track_options: never: "هرگز" immediately: "فورا" + after_30_seconds: "پس از 30 ثانیه" + after_1_minute: "پس از 1 دقیقه" + after_2_minutes: "پس از 2 دقیقه" + after_3_minutes: "پس از 3 دقیقه" + after_4_minutes: "پس از 4 دقیقه" + after_5_minutes: "پس از 5 دقیقه" + after_10_minutes: "پس از 10 دقیقه" invited: search: "بنویسید تا فراخوانه‌ها را جستجو کنید..." title: "فراخوانه‌ها" user: "کاربر فراخوانده شده" - truncated: "نمایش {{count}} فراخوانهٔ نخست" + sent: "فرستاده شده" + none: "هیچ دعوت در انتظاری برای نمایش موجود نیست." + truncated: + other: "نمایش اولین {{count}} دعوت." redeemed: "آزاد سازی دعوتنامه" redeemed_tab: "آزاد شده" + redeemed_tab_with_count: "تایید شده ({{count}})" redeemed_at: "آزاد سازی" pending: "دعوت های بی‌پاسخ" pending_tab: "در انتظار" + pending_tab_with_count: "در حال انتظار ({{count}})" topics_entered: "موضوعات بازدید شد" posts_read_count: "خواندن نوشته ها" expired: "این دعوت منقضی شده است." @@ -481,6 +574,8 @@ fa_IR: days_visited: "روز های بازدید شده" account_age_days: "عمر حساب بر اساس روز" create: "فرستادن یک دعوتنامه" + generate_link: "کپی لینک دعوت" + generated_link_message: '

    لینک دعوت با موفقیت تولید شد!

    لینک دعوت فقط برای این ایمیل آدرس معتبر است: %{invitedEmail}

    ' bulk_invite: none: "شما هنوز کسی را اینجا دعوت نکرده اید. می توانید بصورت تکی یا گروهی یکجا دعوتنامه را بفرستید از طریق بارگذار فراخوانه فله ای ." text: "دعوت گروهی از طریق فایل" @@ -520,11 +615,13 @@ fa_IR: server: "خطای سرور" forbidden: "دسترسی قطع شده است" unknown: "خطا" + not_found: "صفحه پیدا نشد" desc: network: "ارتباط اینترنتی‌تان را بررسی کنید." network_fixed: "به نظر می رسد اون برگشت." server: "کد خطا : {{status}}" forbidden: "شما اجازه دیدن آن را ندارید." + not_found: "اوه, برنامه سعی کرد پیوندی را که وجود ندارد باز کند." unknown: "اشتباهی روی داد." buttons: back: "برگشت" @@ -535,8 +632,10 @@ fa_IR: logout: "شما از سایت خارج شده اید" refresh: "تازه کردن" read_only_mode: - enabled: "حالت فقط خواندن را فعال است. می توانید به جستجو در وب سایت ادامه دهید ولی ممکن است تعاملات کار نکند." login_disabled: "ورود به سیستم غیر فعال شده همزمان با اینکه سایت در حال فقط خواندنی است." + too_few_topics_and_posts_notice: "بیا این بحث را شروع کنیم! در حال حاضر این %{currentTopics} / %{requiredTopics} مبحث ها و %{currentPosts} / %{requiredPosts} ارسال ها وجود دارد. بازدید کنندگان تازه وارد نیاز دارند به گفتگو هایی برای خواندن و پاسخ دادن." + too_few_topics_notice: "بیا این بحث را شروع کنیم! در حال حاضر این %{currentTopics} / %{requiredTopics} مباحث وجود دارد. بازدیدکنندگان تازه وارد نیاز دارند به گفتگوهایی برای خواندن و پاسخ دادن." + too_few_posts_notice: "بیا این بحث را شروع کنیم! در حال حاضر این %{currentPosts} / %{requiredPosts} ارسال ها وجود دارد. بازدیدکنندگان تازه وارد نیاز دارند به گفتگوهایی برای خواندن و پاسخ دادن." learn_more: "بیشتر بدانید..." year: 'سال' year_desc: 'موضوعاتی که در 365 روز گذشته باز شده‌اند' @@ -552,10 +651,15 @@ fa_IR: last_reply_lowercase: آخرین پاسخ replies_lowercase: other: 'پاسخ ها ' + signup_cta: + sign_up: "ثبت نام" + hide_session: "فردا به من یادآوری کن" + hide_forever: "نه ممنون" + hidden_for_session: "باشه, فردا از شما سئوال میکنم. شما همیشه میتوانید از 'ورود' نیز برای ساخت حساب کاربری استفاده کنید." + intro: "سلام! :heart_eyes: به نظر میاد شما از بحث لذت میبرید, اما شما هنوز برای یک حساب کاربری ثبت نام نکرده اید." + value_prop: "وقتی که شما یک حساب کابری ایجاد میکنید, ما به خاطر میسپاریم که شما دقیقا در حال خواندن چه چیزی بودید, بنابراین شما همیشه برمی گردید از جایی که خواندن را رها کردید. همچنین شما اعلانات را دریافت میکنید, اینجا و از طریق ایمیل, هر زمان که ارسال جدیدی فرستاده شود. و شما میتوانید ارسال ها را پسند کنید تا در محبت آن سهیم باشید. :heartbeat:" summary: enabled_description: "شما خلاصه ای از این موضوع را می بینید: بالاترین‌ نوشته های انتخاب شده توسط انجمن." - description: "{{count}} پاسخ" - description_time: "وجود دارد {{count}} پاسخ ها برا اساس زمان خواندن{{readingTime}} دقیقه." enable: 'خلاصه این موضوع' disable: 'نمایش همه نوشته‌ها' deleted_filter: @@ -609,6 +713,9 @@ fa_IR: admin_not_allowed_from_ip_address: "شما نمی تواند با این اپی آدرس وارد کنترل پنل ادمین شوید." resend_activation_email: "برای فرستادن دوبارهٔ رایانامهٔ‌فعال‌سازی، اینجا را بفشارید." sent_activation_email_again: "رایانامهٔ‌ فعال‌سازی دیگری را برایتان به نشانی {{currentEmail}} فرستادیم. چند دقیقه‌ای طول می‌کشد تا برسد. مطمئن شوید که پوشهٔ هرزنامه را بررسی می‌کنید." + to_continue: "لطفا وارد شوید" + preferences: "شما باید وارد شوید تا بتوانید تنظیمات کاربری خود را تغییر بدهید." + forgot: "من اطلاعات حساب کاربری خود را فراموش کردم" google: title: "با Google" message: "اعتبارسنجی با گوگل (مطمئن شوید که بازدارنده‌های pop up فعال نباشند)" @@ -631,15 +738,23 @@ fa_IR: google: "گوگل" twitter: "تویتر" emoji_one: "یک شکلک" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "شکلک :smile:" + more_emoji: "بیشتر..." + options: "گزینه ها" + whisper: "نجوا" add_warning: "این یک هشدار رسمی است." + toggle_whisper: "تغییر وضعیت نجوا" posting_not_on_topic: "به کدام موضوع می‌خواهید پاسخ دهید؟" saving_draft_tip: "در حال ذخیره سازی ..." saved_draft_tip: "اندوخته شد" saved_local_draft_tip: "ذخیره سازی به صورت محلی" similar_topics: "موضوع شما شبیه است به..." drafts_offline: "پیش نویس آنلاین" + group_mentioned: "با استفاده از {{group}}, شما اگاه میکنید {{count}} اشخاص." error: title_missing: "سرنویس الزامی است" title_too_short: "سرنویس دست‌کم باید {{min}} نویسه باشد" @@ -660,8 +775,9 @@ fa_IR: title_placeholder: "در یک جملهٔ‌ کوتاه، این موضوع در چه موردی است؟" edit_reason_placeholder: "چرا ویرایش می‌کنید؟" show_edit_reason: "(افزودن دلیل ویرایش)" + reply_placeholder: "اینجا بنویسید. از Markdown, BBCode و یا HTML برای شکل دادن استفاده کنید. عکس ها را بکشید و یا کپی کنید." view_new_post: "نوشته تازه‌تان را ببینید." - saving: "در حال ذخیره سازی..." + saving: "در حال ذخیره سازی" saved: "اندوخته شد!" saved_draft: "در حال حاضر پیشنویس وجود دارد . برای از سر گیری انتخاب نمایید." uploading: "بارگذاری..." @@ -676,6 +792,7 @@ fa_IR: link_description: "توضیحات لینک را اینجا وارد کنید." link_dialog_title: "لینک را درج کنید" link_optional_text: "سرنویس اختیاری" + link_placeholder: "\"متن دلخواه\" http://example.com" quote_title: "نقل قول" quote_text: "نقل قول" code_title: "نوشته تنظیم نشده" @@ -688,10 +805,11 @@ fa_IR: heading_title: "عنوان" heading_text: "عنوان" hr_title: "خط کش افقی" - undo_title: "برگردانی" - redo_title: "دوباره‌گردانی" help: "راهنمای ویرایش با Markdown" toggler: "مخفی یا نشان دادن پنل نوشتن" + modal_ok: "باشه" + modal_cancel: "لغو کردن" + cant_send_pm: "متاسفانه , شما نمیتوانید پیام بفرستید به %{username}." admin_options_title: "تنظیمات اختیاری مدیران برای این موضوع" auto_close: label: "بستن خودکار موضوع در زمان :" @@ -708,9 +826,9 @@ fa_IR: more: "دیدن آگاه‌سازی‌های پیشن" total_flagged: "همهٔ نوشته‌های پرچم خورده" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -720,8 +838,23 @@ fa_IR: moved_post: "

    {{username}} moved {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Earned '{{description}}'

    " + alt: + mentioned: "اشاره شده توسط" + quoted: "نقل قول شده توسط" + replied: "پاسخ داده شد" + posted: "ارسال شد توسط" + edited: "ویرایش پست شما توسط" + liked: "ارسال شما را پسندید" + private_message: "پیام خصوصی از جانب" + invited_to_private_message: "دعوت شد به یک پیام خصوصی از جانب" + invited_to_topic: "دعوت شد به یک مبحث از جانب" + invitee_accepted: "دعوت قبول شد توسط" + moved_post: "ارسال شما انتقال داده شد توسط" + linked: "پیوند به ارسال شما" + granted_badge: "مدال اعطاء شد" popup: mentioned: '{{username}} mentioned you in "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} به شما در "{{topic}}" - {{site_title}} اشاره نمود' quoted: '{{username}} quoted you in "{{topic}}" - {{site_title}}' replied: '{{username}} replied to you in "{{topic}}" - {{site_title}}' posted: '{{username}} posted in "{{topic}}" - {{site_title}}' @@ -733,14 +866,24 @@ fa_IR: from_my_computer: "از دستگاه من" from_the_web: "از وب" remote_tip: "لینک به تصویر" - remote_tip_with_attachments: "لطفا لینک تصویر یا فایل ({{authorized_extensions}})" + remote_tip_with_attachments: "پیوند به عکس یا فایل {{authorized_extensions}}" local_tip: "عکس ها را از روی سیستم خود انتخاب کنید" - local_tip_with_attachments: "عکس ها را از روی سیستم خود انتخاب کنید ({{authorized_extensions}})" + local_tip_with_attachments: "عکس ها یا فایل ها را از دستگاه خود انتخاب کنید {{authorized_extensions}}" hint: "(برای آپلود می توانید فایل را کیشده و در ویرایشگر رها کنید)" + hint_for_supported_browsers: "شما همچنین میتوانید عکس ها را به داخل ویرایشگر بکشید و رها کنید یا کپی کنید" uploading: "در حال بروز رسانی " select_file: "انتخاب فایل" image_link: "به لینک تصویر خود اشاره کنید" search: + sort_by: "مرتب سازی بر اساس" + relevance: "ارتباطات" + latest_post: "آخرین ارسال" + most_viewed: "بیشترین بازدید شده" + most_liked: "بیشترین پسندیده شده" + select_all: "انتخاب همه" + clear_all: "پاک کردن همه" + result_count: + other: "{{count}} نتایج \"{{term}}\"" title: "جستجوی موضوعات، نوشته ها، کاربران یا دسته‌ بندی ها" no_results: "چیزی یافت نشد." no_more_results: "نتایجی بیشتری یافت نشد." @@ -752,17 +895,21 @@ fa_IR: category: "جستجوی دستهٔ «{{category}}»" topic: "جستجوی این موضوع" private_messages: "جستجوی پیام" + hamburger_menu: "به فهرست مبحث یا دسته بندی دیگر بروید" + new_item: "تازه" go_back: 'برگردید' not_logged_in_user: 'صفحه کاربر با خلاصه ای از فعالیت های و تنظیمات' current_user: 'به نمایه‌تان بروید' topics: bulk: + unlist_topics: "از فهرست خارج کردن مباحث" reset_read: "تنظیم مجدد خوانده شد" delete: "حذف موضوعات" - dismiss_posts: "بستن نوشته ها" - dismiss_posts_tooltip: "پاک کردن شمارش خوانده نشده های این موضوع اما همچنان در لیست خوانده نشده های من آنها را نمایش بده زمانی که پست جدید ساخته شد" - dismiss_topics: "بستن موضوعات" - dismiss_topics_tooltip: "نشان دادن این تاپیک را از لیست خوانده نشده متوقف کن وقتی پست های جدید بوجود آمد" + dismiss: "پنهان کردن" + dismiss_read: "پنهان کردن تمامی خوانده نشده ها" + dismiss_button: "پنهان کردن..." + dismiss_tooltip: "فقط پنهان کردن ارسال های تازه یا متوقف کردن پیگیری مباحث" + also_dismiss_topics: "توقف پیگیری این مباحث پس آن ها دیگر هرگز به عنوان خوانده نشده دوباره برای من نمایش داده نمیشوند" dismiss_new: "بستن جدید" toggle: "ضامن انتخاب یکباره موضوعات" actions: "عملیات یکجا" @@ -784,9 +931,6 @@ fa_IR: category: "هیچ موضوعاتی در {{category}} نیست." top: "موضوع برتر وجود ندارد." search: " هیچ نتیجه جستجویی وجود ندارد." - educate: - new: '

    موضوعات جدید در اینجا قرار می گیرند.

    به طور پیش فرض، موضوعات جدید در نظر گرفته خواهند شد و نشان داده می شوند جدید شاخص اگر آنها در 2 روز گذشته ایجاد شده باشند

    شما می توانید این را برای خود تغییر دهید تنظیمات.

    ' - unread: '

    موضوعات خوانده نشده شما در اینجا قرار می گیرند.

    به طور پیش فرض، موضوعات خوانده نشده در نظر گرفته خواهند شد و شمارش خوانده نشده ها نشان داده می شود 1 اگر شما:

    • موضوع ایجاد کرده اید
    • به موضوع پاسخ داده اید
    • خواندن موضوع در بیش از 4 دقیقه

    و یا اگر شما به صراحت مجموعه ای از موضوع مورد ردیابی و یا تماشا از طریق کنترل اطلاع رسانی در پایین هر موضوع انتخاب کرده اید.

    شما می توانید این را تغییر دهید. تنظیمات.

    ' bottom: latest: "موضوع تازهٔ دیگری نیست." hot: "موضوع داغ دیگری نیست." @@ -799,6 +943,9 @@ fa_IR: bookmarks: "موضوعات نشانک‌گذاری شده‌ی دیگری وجود ندارد." search: "نتیجه جستجوی دیگری وجود ندارد" topic: + unsubscribe: + stop_notifications: "حالا شما اعلانات کمتری برای {{title}} دریافت میکنید" + change_notification_state: "وضعیت فعلی اعلانات شما این هست" filter_to: "نوشته در موضوع {{post_count}} " create: 'موضوع جدید' create_long: 'ساخت یک موضوع جدید' @@ -847,6 +994,7 @@ fa_IR: auto_close_title: 'تنضیمات قفل خوکار' auto_close_save: "‌ذخیره" auto_close_remove: "این موضوع را خوکار قفل نکن" + auto_close_immediate: "زمان ارسال آخرین پست در موضوع برای %{hours} ساعت پیش است، بنابر این موضوع بلافاصله بسته می‌شود." progress: title: نوشته ی در حال اجرا go_top: "بالا" @@ -886,15 +1034,17 @@ fa_IR: title: "ردگیری" description: "تعداد پاسخ‌های جدید برای این عنوان نمایش داده خواهد شد. در صورتی که فردی با @name به شما اشاره کند یا به شما پاسخی دهد، به شما اطلاع رسانی خواهد شد." regular: + title: "معمولی" description: "در صورتی که فردی با @name به شما اشاره کند یا به شما پاسخی دهد به شما اطلاع داده خواهد شد." regular_pm: + title: "معمولی" description: "در صورتی که فردی با @name به شما اشاره کند یا به شما پاسخی دهد به شما اطلاع داده خواهد شد." muted_pm: title: "بی صدا شد" description: " در باره این پیام هرگز به شما اطلاع رسانی نخواهید شد" muted: title: "بی صدا شد" - description: "درباره این موضوع به شما هرگز اطلاع رسانی نخواهد شد٬ و در کنار جستار شمار خوانده نشده ها پدیدار نمی شود" + description: "شما هرگز از چیزی درباره این مبحث آگاه نمیشوید, و آن در آخرین ها نمایش داده نخواهد شد." actions: recover: "بازیابی موضوع" delete: "پاک کردن موضوع" @@ -930,26 +1080,28 @@ fa_IR: success_message: 'شما باموفقیت این موضوع را پرچم زدید' feature_topic: title: " ویژگی های این موضوع" + pin: "این مبحث را در بالای {{categoryLink}} دسته بندی نمایش بده تا وقتی که" confirm_pin: "شما قبلا این {{count}} موضوع را سنجاق کردید. تعداد زیاد موضوع های سنجاق شده شاید برای کاربران جدید یا ناشناس بار سنگینی ایجاد کند. آیا شما اطمینان دارید از سنجاق کردن یک موضوع دیگر در این دسته بندی ؟" unpin: "این موضوع را از لیست بالاترین‌ های دسته بندی {{categoryLink}} حذف کن" + unpin_until: "این مبحث از بالای {{categoryLink}} دسته بندی حذف شود یا منتظر بمانید تا وقتی که %{until}." pin_note: "کاربران می توانند موضوع را بصورت جداگانه برای خود از سنجاق در بیاورند" + pin_validation: "برای سنجاق کردن این مبحث نیاز به یک تاریخ معین است." + not_pinned: "هیچ مبحثی در {{categoryLink}} سنجاق نشده." already_pinned: - zero: "دیگر هیچ موضوعات سنجاق شده وجود ندارد در {{categoryLink}}." - one: "موضوعات در حال حاضر سنجاق شده اند {{categoryLink}}: 1." - other: "موضوعات در حال حاضر سنجاق شده اند {{categoryLink}}: {{count}}." + other: "مباحثی که در حال حاضر سنجاق شده اند در {{categoryLink}}: {{count}}" + pin_globally: "نمایش این مبحث در بالای فهرست همه مباحث تا وقتی که" confirm_pin_globally: "شما قبلا این موضوع {{count}} را بصورت سراسری سنجاق زده اید. تعداد زیاد موضوع های سنجاق شده برای کاربران جدید و ناشناس می تواند سخت باشد. آیا از سنجاق کردن موضوع ها بصورت سراری اطمینان دارید ؟ " unpin_globally: "حذف این موضوع از بالای همه لیست موضوعات." + unpin_globally_until: "حذف این مبحث از بالای لیست همه مباحث یا صبر کردن تا %{until}." global_pin_note: "کاربران می توانند موضوع را بصورت جداگانه برای خود از سنجاق در بیاورند" + not_pinned_globally: "هیچ مبحثی به صورت سراسری سنجاق نشده." already_pinned_globally: - zero: "هیچ موضوعی که به صورت سرسری سنجاق شده باشد وجود ندارد." - one: "موضوعات در سطح سراسری سنجاق شده است: 1." - other: "موضوعات در سطح سراسری سنجاق شده است: {{count}}." + other: "مباحثی که در حال حاضر به صورت سراسری سنجاق شده اند: {{count}}" make_banner: "این موضوع را در وارد بنر کن که در تمام صفحات در بالای صفحه نشان داده شود" remove_banner: "حذف بنری که از بالای تمام صفحات نمایش داده می شود. " banner_note: "کاربران می توانند بنر را با بستن آنها رد کنند. فقط یک موضوع را می توان بنر کرد در هرزمان داده شده ای. " - already_banner: - zero: "هیچ موضوع سرصفحه ای وجود ندارد" - one: "در حال حاضر یک موضوع بنر is وجود دارد." + no_banner_exists: "هیچ مبحث سرصفحه ای وجود ندارد." + banner_exists: "یک مبحث سرصفحه ای هست در حال حاضر." inviting: "فراخوانی..." automatically_add_to_groups_optional: "این دعوتنامه دارای دسترسی به این گروه ها است : (اختیاری٬ فقط ادمین)" automatically_add_to_groups_required: "این دعوتنامه دارای دسترسی به این گروه ها است : (Required, admin only)" @@ -961,6 +1113,7 @@ fa_IR: success: "ما آن کاربر را برای شرکت در این پیام دعوت کردیم." error: "با معذرت٬ یک خطا برای دعوت آن کاربر وجود داشت" group_name: "نام گروه" + controls: "مدیریت مبحث" invite_reply: title: 'دعوتنامه ' username_placeholder: "نام کاربری" @@ -1003,6 +1156,12 @@ fa_IR: instructions: other: "لطفا مالک جدید را برای این {{count}} نوشته انتخاب کنید با {{old_user}}." instructions_warn: "نکته٬ هر گونه آگاه سازی برای این پست همانند سابق برای کاربر جدید فرستاده نمی شود. .
    اخطار: در حال حاضر٬‌ هیچگونه اطلاعات قبلی به کاربر جدید فرستاده نشده. با احتیاط استفاده شود. " + change_timestamp: + title: "تغییر برچسب زمان" + action: "تغییر برچسب زمان" + invalid_timestamp: "برچسب زمان نمیتواند در آینده باشد." + error: "یک ایراد برای تغییر برچسب زمان مبحث وجود دارد." + instructions: "لطفا یک برچسب زمان جدید برای مبحث انتخاب کنید. ارسال های مبحث برای داشتن یک اختلاف زمانی واحد به روز میشوند." multi_select: select: 'انتخاب' selected: 'انتخاب شده ({{count}}) ' @@ -1014,6 +1173,8 @@ fa_IR: description: other: شما تعداد {{count}} نوشته انتخاب کرده اید post: + reply: " {{replyAvatar}} {{usernameLink}}" + reply_topic: " {{link}}" quote_reply: "پاسخ با نقل قول" edit: "در حال ویرایش {{link}} {{replyAvatar}} {{username}}" edit_reason: "دلیل:" @@ -1037,10 +1198,9 @@ fa_IR: other: "{{count}} لایک" has_likes_title: other: "{{count}} کاربر این مورد را پسندیده اند" + has_likes_title_only_you: "شما این ارسال را پسندیده اید" has_likes_title_you: - zero: "شما این نوشته را پسندیده اید" - one: "شما و یک کاربر دیگر این مورد را پسندیده اید" - other: "شما و {{count}} کاربر دیگر این مورد را پسندیده اید" + other: "شما و {{count}} شخص دیگر این ارسال را پسندیده اید" errors: create: "متأسفیم، در فرستادن نوشته شما خطایی روی داد. لطفاً دوباره تلاش کنید." edit: "متأسفیم، در ویرایش نوشته شما خطایی روی داد. لطفاً دوباره تلاش کنید." @@ -1058,8 +1218,7 @@ fa_IR: no_value: "خیر، نگه دار" yes_value: "بله، رها کن" via_email: "این نوشته از طریق ایمیل ارسال شده است" - wiki: - about: "این یک نوشته ویکی است;کاربران عادی می توانند آن را ویرایش نماییند" + whisper: "این ارسال نجوای خصوصی برای مدیران است" archetypes: save: ' ذخیره تنظیمات' controls: @@ -1086,6 +1245,7 @@ fa_IR: revert_to_regular: "حذف زنگ مدیر" rebake: "باز سازی اچ تی ام ال" unhide: "آشکار کردن" + change_owner: "تغییر مالکیت" actions: flag: 'پرچم' defer_flags: @@ -1105,18 +1265,6 @@ fa_IR: bookmark: "برداشتن نشانک" like: "خنثی سازی لایک" vote: "خنثی سازی امتیاز" - people: - off_topic: "{{icons}} برای این مورد پرچم آف-‌تاپیک زد" - spam: "{{icons}} برای این مورد پرچم هرزنامه زد" - spam_with_url: "{{icons}} پرچم گذاری شداین یک هرزنامه است" - inappropriate: "{{icons}} با پرچم گزاری این مورد را نامناسب بدان" - notify_moderators: "{{icons}} مدیران را آگاه کرد" - notify_moderators_with_url: "{{icons}} مدیران را آگاه کرد" - notify_user: "{{icons}} ارسال یک پیام خصوصی" - notify_user_with_url: "{{icons}} ارسال پیام خصوصی" - bookmark: "{{icons}} این را نشانه‌گذاری کرد" - like: "{{icons}} این مورد را پسندید" - vote: "{{icons}} رأی داد به این " by_you: off_topic: "شما برای این مورد پرچم آف-تاپیک زدید" spam: "شما برای این مورد پرچم هرزنامه زدید" @@ -1160,10 +1308,6 @@ fa_IR: other: "{{count}} کاربر این مورد را پسند کردند" vote: other: "{{count}} کاربران به این نوشته رأی دادند" - edits: - one: ۱ ویرایش - other: "{{count}} ویرایش" - zero: هیچ ویرایشی delete: confirm: other: "آیا مطمئنید که می‌خواهید همهٔ آن نوشته ها را پاک کنید؟" @@ -1199,6 +1343,7 @@ fa_IR: topic_template: "قالب موضوع" delete: 'پاک کردن دسته' create: 'دسته بندی جدید' + create_long: 'ساختن یک دسته بندی جدید' save: 'ذخیره سازی دسته بندی' slug: 'Slug دسته بندی' slug_placeholder: '(اختیاری) dash-کلمه برای url' @@ -1221,6 +1366,7 @@ fa_IR: change_in_category_topic: "ویرایش توضیحات" already_used: 'این رنگ توسط یک دسته بندی دیگر گزیده شده است' security: "امنیت" + special_warning: "اخطار: این دسته بندی یک دسته بندی پیش کشت است و تنظیمات امینتی آن قابل تغییر نیست. اگر شما نمیخواهید از این دسته بندی استفاده کنید, به جای تغییر کاربرد حذفش کنید." images: "تصاویر" auto_close_label: "بسته شدن خودکار موضوعات پس از:" auto_close_units: "ساعت ها" @@ -1228,6 +1374,7 @@ fa_IR: email_in_allow_strangers: "تایید ایمیل ها از کاربران ناشناس بدون حساب کاربری" email_in_disabled: "ارسال پست با ایمیل در تنظیمات سایت غیر فعال است. برای فعال سازی موضوعات جدید را با ایمیل ارسال کنید, " email_in_disabled_click: 'فعال کردن تنظیمات "email in".' + suppress_from_homepage: "برداشتن این دسته بندی از صفحه اصلی." allow_badges_label: "امکان اهداء مدال در این دسته بندی را بده" edit_permissions: "ویرایش پروانه‌ها" add_permission: "افزودن پروانه" @@ -1240,19 +1387,18 @@ fa_IR: notifications: watching: title: "در حال تماشا" - description: "شما به صورت خودکار تمام عناوین این دسته‌ها را مشاهده‌ خواهید کرد. به شما تمام عناوین و نوشته‌‌های جدید اطلاع رسانی خواهد شد، و تعداد نوشته‌های جدید هر عنوان در کنار آن نمایش داده می‌شود." + description: "شما به صورت خودکار تمامی مباحث تازه در این دسته بندی ها را نگاه میکنید. اگر ارسال تازه ای در هرکدام از مباحث فرستاده شد شما مطلع میشود, و همچنین تعدادی از پاسخ های تازه نیز نمایش داده میشوند." tracking: title: "پیگیری" - description: "شما به صورت خودکار تمام عناوین جدید در این دسته‌ها را پیگیری خواهید کرد. تعداد نوشته های جدید در کنار عنواین نمایش داده می‌شود." + description: "شما به صورت خودکار تمامی مبحث های تازه در این دسته بندی ها را دنبال میکنید, و اگر کسی @اسم شما را بیاورد و یا به شما پاسخ دهد به شما اطلاع داده خواهد شد, و همچنین تعدادی از پاسخ های تازه نیز نمایش داده میشوند." regular: - title: "منظم" + title: "معمولی" description: "در صورتی که فردی با @name به شما اشاره کند یا به شما پاسخی دهد به شما اطلاع داده خواهد شد." muted: title: "بی صدا شد" - description: "به شما همه چیز در رابطه با این دسته بندی اطلاع داده خواهد شد ، و آن ها در تب خوانده نشده پدیدار نمی شوند" + description: "شما هیچ وقت از مبحث های تازه در این دسته بندی ها مطلع نمیشوید, و آن ها در آخرین ها نمایش داده نمیشوند." flagging: title: 'تشکر برای کمک به نگه داشتن جامعه ما بصورت مدنی !' - private_reminder: 'پرچم های خصوصی, فقط قابل مشاهده برای مدیران' action: 'پرچم‌گذاری نوشته' take_action: "اقدام" notify_action: 'پیام' @@ -1294,12 +1440,14 @@ fa_IR: help: "این موضوع بسته شده؛ پاسخ‌های تازه اینجا پذیرفته نمی‌شوند" archived: help: "این موضوع بایگانی شده؛ یخ زده و نمی‌تواند تغییر کند." + locked_and_archived: + help: "این مبحث بسته و آرشیو شده; دیگر پاسخ های تازه قبول نمیکند و قابل تغییر هم نیست" unpinned: title: "خارج کردن از سنجاق" help: "این موضوع برای شما شنجاق نشده است، آن طور منظم نمایش داده خواهد شد" pinned_globally: title: "به صورت سراسری سنجاق شد" - help: "این موضوع بصورت سراسری سنجاق شده است، آن بالای تمامی موضوعات نمایش داده خواهد شد" + help: "این مبحث بصورت سراسری سنجاق شده; در بالای آخرین ها و دسته بندی ها نمایش داده میشود" pinned: title: "سنجاق شد" help: "این موضوع برای شما سنجاق شده است، آن طور منظم در بالای دسته بندی نمایش داده خواهد شد." @@ -1339,10 +1487,9 @@ fa_IR: with_topics: "%{filter} موضوعات" with_category: "%{filter} %{category} موضوعات" latest: - title: - zero: "جدیدترین" - one: "جدیدترین(1)" - other: "جدیدترین ({{count}})" + title: "آخرین" + title_with_count: + other: "آخرین ({{count}})" help: "موضوعات با نوشته های تازه" hot: title: "داغ" @@ -1358,22 +1505,18 @@ fa_IR: title_in: "دسته بندی - {{categoryName}}" help: "همهٔ موضوعات در دسته‌ بندی ها جای گرفتند" unread: - title: - zero: "خوانده‌ نشده‌" - one: "خوانده‌ نشده‌ (۱)" + title: "خوانده‌ نشده‌" + title_with_count: other: "خوانده‌ نشده‌ ({{count}})" help: "موضوعاتی که در حال حاضر مشاهده می کنید یا دنبال می کنید با نوشته های خوانده نشده" lower_title_with_count: - one: "1 خوانده نشده" other: "{{count}} خوانده نشده" new: lower_title_with_count: - one: "۱ تازه" other: "{{count}} تازه" lower_title: "جدید" - title: - zero: "جدید" - one: "جدید (1)" + title: "جدید" + title_with_count: other: "جدید ({{count}})" help: "موضوعات ایجاد شده در چند روز گذشته" posted: @@ -1383,9 +1526,8 @@ fa_IR: title: "نشانک ها" help: "موضوعاتی که نشانک‌گذاری کرده‌اید." category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (۱)" + title: "{{categoryName}}" + title_with_count: other: "{{categoryName}} ({{count}})" help: "موضوعات تازه در دستهٔ {{categoryName}}" top: @@ -1395,6 +1537,8 @@ fa_IR: title: "تمام وقت" yearly: title: "سالیانه " + quarterly: + title: "بطور چهارگانه" monthly: title: "ماهیانه " weekly: @@ -1403,6 +1547,7 @@ fa_IR: title: "روزانه" all_time: "تمام وقت" this_year: "سال" + this_quarter: "ربع" this_month: "ماه" this_week: "هفته" today: "امروز" @@ -1538,15 +1683,24 @@ fa_IR: delete_confirm: "حفظ کردن این گروه؟" delete_failed: "قادر به حذف گروه نیستیم. اگر این یک گروه خودکار است، نمی توان آن را از بین برد." delete_member_confirm: "حذف کردن '%{username}' از '%{group}' گروه؟" + delete_owner_confirm: "حذف حق مالکیت برای '%{username}'؟" name: "نام" add: "اضافه کردن" add_members: "اضافه کردن عضو" custom: "دلخواه" + bulk_complete: "کاربران به گروه اضافه شدند." + bulk: "اضافه کردن تعداد زیادی به گروه" + bulk_paste: "یک لیست از نام های کاربری و یا ایمیل ها وارد کنید, در هر خط فقط یکی:" + bulk_select: "(یک گروه انتخاب کنید)" automatic: "خودکار" automatic_membership_email_domains: " کاربرانی که با ایمیل دامنه ثبت نام کرده اند،دقیقا شبیه دامنه های لیست، بصورت خودکار به این گروه اضافه می شوند :" automatic_membership_retroactive: "درخواست همان قاعده دامنه ایمیل برای اضافه کردن برای کاربران ثبت نام کرده" default_title: "عنوان را پیش فرض کن برای تمام اعضا در این گروه" primary_group: "بطور خودکار به گروه اصلی تبدیل شد" + group_owners: مالکین + add_owners: افزودن مالک + incoming_email: "آدرس ایمیل های دریافتی سفارشی" + incoming_email_placeholder: "آدرس ایمیل را وارد کنید" api: generate_master: "ایجاد کلید اصلی API" none: "هم اکنون هیچ کلید API فعالی وجود ندارد" @@ -1620,11 +1774,9 @@ fa_IR: is_disabled: "بازگردانی در تنظیمات سایت از کار انداخته شده است." label: "بازیابی" title: "بازیابی پشتیبان" - confirm: "آیا مطمئنید که می‌خواهید پشتیبان را برگردانید؟" rollback: label: "عقبگرد" title: "عقب گرد پایگاه داده به حالت کار قبلی" - confirm: "آیا مطمئن هستید به بازگشت به حالت کار قبلی پایگاه داده ؟" export_csv: user_archive_confirm: "آیا مطمئنید که می‌خواهید نوشته‌هایتان را دانلود کنید؟" success: "فرایند برون ریزی، به شما از طریق پیام اطلاع رسانی خواهد شد وقتی این فرایند تکمیل شود." @@ -1649,6 +1801,7 @@ fa_IR: header: "سردر" top: "بالا" footer: "پانوشته " + embedded_css: "CSS جاساز شده" head_tag: text: "" title: "HTML هایی که قرار داده شده قبل از تگ " @@ -1674,6 +1827,14 @@ fa_IR: color: "رنگ" opacity: "تاری" copy: "کپی" + email_templates: + title: "قالب های ایمیل" + subject: "عنوان" + multiple_subjects: "این قالب ایمیل دارای چندین عنوان است." + body: "بدنه" + none_selected: "یک قالب ایمیل برای شروع ویرایش انتخاب کنید." + revert: "باطل کردن تغییرات" + revert_confirm: "آیا مطمئن هستید که میخواهید تنظیمات را باطل کنید؟" css_html: title: "CSS/HTML" long_title: "شخصی‌سازی CSS و HTML" @@ -1718,13 +1879,9 @@ fa_IR: love: name: 'دوست داشتن' description: "رنگ دکمه های لایک" - wiki: - name: 'ویکی' - description: "رنگ پایه استفاده شده برای پس زمینه نوشته ها ی ویکی ." email: - title: "ایمیل " settings: "تنظیمات" - all: "همه" + preview_digest: "پیشنمایش خلاصه" sending_test: "فرستادن ایمیل آزمایشی..." error: "خطا - %{server_error}" test_error: "در ارسال ایمیل آزمایشی مشکلی وجود داشته است. لطفاً مجدداً تنظیمات ایمیل خود را بررسی کنید، از این که هاستتان اتصالات ایمیل را مسدود نکرده اطمینان حاصل کرده و مجدداً تلاش کنید." @@ -1739,7 +1896,7 @@ fa_IR: send_test: "ارسال ایمیل آزمایشی" sent_test: "فرستاده شد!" delivery_method: "روش تحویل" - preview_digest: "پیشنمایش خلاصه" + preview_digest_desc: "پیش نمایش محتوای خلاصه ایمیل های ارسال شده به کاربران غیر فعال." refresh: "تازه‌سازی" format: "قالب" html: "html" @@ -1765,6 +1922,7 @@ fa_IR: ip_address: "IP" topic_id: " ID موضوع" post_id: "ID نوشته" + category_id: "شناسه دسته بندی" delete: 'حذف' edit: 'ویرایش‌' save: 'ذخیره ' @@ -1795,6 +1953,7 @@ fa_IR: change_site_setting: "تغییر تنظیمات سایت" change_site_customization: "تغییر سفارشی‌سازی سایت" delete_site_customization: "پاک‌کردن سفارشی‌سازی سایت" + change_site_text: "تغییر نوشته سایت" suspend_user: "کاربر تعلیق شده" unsuspend_user: "کابر تعلیق نشده" grant_badge: "اعطای مدال" @@ -1805,6 +1964,9 @@ fa_IR: impersonate: "جعل هویت کردن" anonymize_user: "کاربر ناشناس" roll_up: "آدرس‌های IP بلاک شده را جمع کنید" + change_category_settings: "تغییر تنظیمات دسته بندی" + delete_category: "حذف دسته بندی" + create_category: "ساخت دسته بندی" screened_emails: title: "ایمیل ها نمایش داده شده" description: "وقتی کسی سعی می کند یک حساب جدید ایجاد کند، از آدرس ایمیل زیر بررسی و ثبت نام مسدود خواهد شد، و یا برخی از اقدام های دیگر انجام می شود." @@ -1869,9 +2031,9 @@ fa_IR: pending: 'کاربران در انتظار بررسی' newuser: 'کاربران در سطح اعتماد 0 (کاربران جدید)' basic: 'کاربران در سطح اعتماد 1 (کاربر اصلی)' - regular: 'کاربران در سطح اعتماد 2 (عضو رسمی)' - leader: 'کاربران در سطح اعتماد 3 (منظم)' - elder: 'کاربران در سطح اعتماد 4 (رهبر)' + member: 'کاربران در سطح اعتماد 2 (عضو)' + regular: 'کاربران در سطح اعتماد 3 (عادی)' + leader: 'کاربران در سطح اعتماد 4 (رهبر)' staff: "مدیر" admins: 'کاربران مدیر' moderators: 'مدیران' @@ -1976,7 +2138,7 @@ fa_IR: unlock_trust_level: "باز کردن سطح اعتماد" tl3_requirements: title: "شرایط لازم برای سطح اعتماد 3." - table_title: "در ۱۰۰ روز اخیر:" + table_title: "در %{time_period} روز گذشته:" value_heading: "مقدار" requirement_heading: "نیازمندی‌ها" visits: "بازدیدها" @@ -2019,6 +2181,7 @@ fa_IR: delete: "حذف" cancel: "لغو کردن" delete_confirm: "آیا برای حذف این فیلد کاربری مطمئن هستید ؟" + options: "گزینه ها" required: title: "مورد نیاز در ثبت نام؟" enabled: "مورد نیاز " @@ -2034,9 +2197,17 @@ fa_IR: field_types: text: 'فیلد متن' confirm: 'تاییدیه' + dropdown: "کرکره ای" site_text: - none: "یک دسته‌ از محتویات را برای آغاز ویرایش انتخاب کنید." + description: "شما میتوانید در انجمن خود همه متن ها را شخصی سازی کنید, لطفا با جستجو کردن متن زیر شروع کنید:" + search: "جستجو برای متنی که میخواهید ویرایش کنید" title: 'محتویات متن' + edit: 'ویرایش' + revert: "باطل کردن تغییرات" + revert_confirm: "آیا مطمئن هستید که میخواهید تغییرات را باطل کنید؟" + go_back: "بازگشت به جستجو" + recommended: "ما پیشنهاد میکنیم این متن را بر اساس نیاز های خود ویرایش کنید:" + show_overriden: 'تنها بازنویسی‌شده‌ها را نمایش بده' site_settings: show_overriden: 'تنها بازنویسی‌شده‌ها را نمایش بده' title: 'تنظیمات' @@ -2067,6 +2238,7 @@ fa_IR: backups: "پشتیبان‌ها" login: "ورود" plugins: "افزونه ها" + user_preferences: "تنظیمات کاربری" badges: title: مدال ها new_badge: مدال جدید @@ -2123,10 +2295,9 @@ fa_IR: bad_count_warning: header: "هشدار!" text: "نمونه اعطای گم شده وجود دارد. این اتفاق زمانی می افتد که پرس و جوuser IDs یا post IDs که وجود ندارد را برمی گرداند. این ممکن است باعث خیلی از نتایج غیر منتظره بعد از آن شود - لطفا دوباره بررسی کنید." + no_grant_count: "هیچ مدالی برای اختصاص دادن وجود ندارد." grant_count: - zero: "هیچ مدالی برای اختصاص دادن وجود ندارد" - one: "1 مدال اختصاص داده شد." - other: "٪ {COUNT} مدال ها اختصاص داده شد" + other: "%{count} مدالهایی که قرار است اختصاص داده شود." sample: "نمونه:" grant: with: %{username} @@ -2140,6 +2311,29 @@ fa_IR: name: "نام" image: "تصویر" delete_confirm: "آیا مطمئنید که می‌خواهید شکلک :{name}%: را پاک کنید؟" + embedding: + get_started: "اگر مایل هستید که Discourse را بر روی یک وبسایت دیگر جاساز کنید, با اضافه کردن میزبان یا همان هاست آن وبسایت شروع کنید." + confirm_delete: "آیا مطمئن هستید که میخواهید آن میزبان را حذف کنید؟" + sample: "از این کد HTML در سایت خود استفاده کنید تا بتوانید مبحث های Discourse ایجاد کنید یا جاساز کنید, این کد REPLACE_ME را به URL استاندارد صفحه ای که بر روی آن جاسازی میکنید تغییر دهید." + title: "جاسازی" + host: "میزبان های مجاز" + edit: "ویرایش" + category: "ارسال به دسته بندی" + add_host: "اضافه کردن میزبان" + settings: "تنظیمات جاسازی" + feed_settings: "تنظیمات فید" + feed_description: "اضافه کردن یک RSS/ATOM فید به وبسایت باعث افزایش قابلیت Discourse برای وارد کردن محتوای شما میشود." + crawling_settings: "تنظیمات خزنده" + crawling_description: "وقتی که Discourse مبحث هایی برای ارسال های شما ایجاد میکند, اگر هیچ RSS/ATOM فیدی موجود نبود سعی میکند که محتوای شما را از HTML تان تجزیه کند. گاهی اوقات استخراج محتوای شما سخت است, برای همین ما قابلیت تعیین قوانین CSS را میدهیم که استخراج را آسان تر میکند." + embed_by_username: "نام کاربری برای ساخت مبحث" + embed_post_limit: "حداکثر تعداد پست هایی که میتوان جاساز کرد" + embed_username_key_from_feed: "کلیدی برای کشیدن نام کاربری Discourse از فید" + embed_truncate: "کوتاه کردن نوشته های جاسازی شده" + embed_whitelist_selector: "CSS انتخاب کننده برای المان هایی که اجازه دارند جاسازی شوند" + embed_blacklist_selector: "انتخاب کننده CSS برای المان هایی که از جاسازی پاک شده اند" + feed_polling_enabled: "وارد کردن پست ها توسط RSS/ATOM" + feed_polling_url: " لینک RSS/ATOM فید برای خزیدن" + save: "ذخیره تنظیمات کدهای جاساز" permalink: title: " پیوند دائمی" url: "آدرس" @@ -2170,6 +2364,8 @@ fa_IR: categories: 'g, c دسته بندی ها' top: 'g, t بالا ترین' bookmarks: 'g, h نشانک‌ها' + profile: 'g, p پروفایل' + messages: 'g, m پیام ها' navigation: title: 'راهبری' jump: '# رفتن به نوشته #' @@ -2181,12 +2377,14 @@ fa_IR: title: 'نرم‌افزار' create: 'c ساختن یک موضوع جدید' notifications: 'n باز کردن آگاه‌سازی‌ها' + hamburger_menu: '= باز کردن منوی همبرگری' user_profile_menu: 'p باز کردن منوی کاربران' show_incoming_updated_topics: '. نمایش موضوعات بروز شده' search: '/ جستجو' help: '? باز کردن راهنمای کیبورد' dismiss_new_posts: 'x, rبستن جدید/نوشته ها ' dismiss_topics: 'x, t بستن موضوعات' + log_out: 'shift+z shift+z خروج' actions: title: 'اقدامات' bookmark_topic: 'f تعویض نشانک موضوع' @@ -2208,8 +2406,6 @@ fa_IR: mark_watching: 'm, w مشاهده موضوع' badges: title: مدال‌ها - allow_title: "می تواند برای یک عنوان استفاده شود" - multiple_grant: "می توان چندین بار اهدا کرد" badge_count: other: "%{count} مدال" more_badges: @@ -2229,87 +2425,19 @@ fa_IR: name: دیگر posting: name: در حال نوشتن - badge: - editor: - name: ویرایشگر - description: نخستین ویرایش نوشته - basic_user: - name: اساسی - description: اعطا کردن تمام عملکرد های ضروری برای انجمن - member: - name: عضو - description: اعطا کردن دعوت نامه - regular: - name: منظم - description: a> دعوت نامه تغییر دسته بندی، تغییر نام دهید، به دنبال کردن لینک ها و سالن - leader: - name: رهبر - description: 'اعطا کردن + google_search: | +

    جستجو با گوگل

    - ویرایش سراسری، پین، بستن، بایگانی، تقسیم و ادغام' - welcome: - name: خوش آمدید - description: ' یک پسند دریافت شد' - autobiographer: - name: نویسندهء شرح حال - description: فیلد کاربر نمایه اطلاعات - anniversary: - name: سالگرد - description: عضو فعال به مدت یک سال،ارسال شده حداقل یک بار - nice_post: - name: نوشته‌ی دلپذیر - description: دریافت 10 پسند در یک نوشته. این نشان را می توان چندین بار اعطا کرد - good_post: - name: نوشته‌ی خوب - description: دریافت 25 پسند در یک نوشته. این نشان را می توان چندین بار اعطا کرد - great_post: - name: نوشته‌ی عالی - description: دریافت 50 پسند در یک نوشته. این نشان را می توان چندین بار اعطا کرد - nice_topic: - name: موضوع دلپذیر - description: دریافت 10 پسند در یک موضوع. این نشان را می توان چندین بار اعطا کرد - good_topic: - name: موضوع خوب - description: دریافت 25 پسند در یک موضوع. این نشان را می توان چندین بار اعطا کرد - great_topic: - name: موضوع عالی - description: دریافت 50 پسند در یک موضوع. این نشان را می توان چندین بار اعطا کرد - nice_share: - name: ا‌شتراک‌گذاری خوب - description: اشتراک گذاری نوشته با 25 بازدید کننده منحصر به فرد - good_share: - name: اشتراک‌گذاری خوب - description: اشتراک گذاری نوشته با 300 بازدید کننده منحصر به فرد - great_share: - name: اشتراک‌گذاری عالی - description: اشتراک گذاری نوشته با 1000 بازدید کننده منحصر به فرد - first_like: - name: نخستین پسند - description: نوشته ای را پسندید - first_flag: - name: پرچم نخست - description: نوشته را پرچم زد - promoter: - name: ترویج دهنده - description: دعوت کننده یک کاربر - campaigner: - name: فعال - description: دعوت کننده سه کاربر معمولی (سطح اعتماد ۱) - champion: - name: قهرمان - description: دعوت کننده پنج کاربر عضو (سطح اعتماد ۲) - first_share: - name: نخستین اشتراک‌گذاری - description: نوشته ای به اشتراک گذاشته شده - first_link: - name: پیوند نخست - description: لینک های داخلی اضافه شده به دیگر موضوعات - first_quote: - name: نقل‌قول نخست - description: نقل قول یک کاربر - read_guidelines: - name: خواندن دستورالعمل ها - description: خواندن دستورالعمل های انجمن - reader: - name: خواننده - description: مطالعه تمام نوشته‌هایی در یک موضوع که بیش از 100 نوشته دارد. +

    + +

    + +

    diff --git a/config/locales/client.fi.yml b/config/locales/client.fi.yml index cb443816532..08f13c39dd7 100644 --- a/config/locales/client.fi.yml +++ b/config/locales/client.fi.yml @@ -100,6 +100,8 @@ fi: x_years: one: "1 vuosi myöhemmin" other: "%{count} vuotta myöhemmin" + previous_month: 'Edellinen kuukausi' + next_month: 'Seuraava kuukausi' share: topic: 'jaa linkki tähän ketjuun' post: '%{postNumber}. viesti' @@ -109,6 +111,9 @@ fi: google+: 'jaa tämä linkki Google+:ssa' email: 'lähetä tämä linkki sähköpostissa' action_codes: + split_topic: "pilkkoi tämän ketjun %{when}" + invited_user: "kutsui käyttäjän %{who} %{when}" + removed_user: "poisti käyttäjän %{who} %{when}" autoclosed: enabled: 'sulki %{when}' disabled: 'avasi %{when}' @@ -129,20 +134,33 @@ fi: disabled: 'poisti listauksista %{when}' topic_admin_menu: "ketjun ylläpitotoimet" emails_are_disabled: "Ylläpitäjä on estänyt kaiken lähtevän sähköpostiliikenteen. Mitään sähköposti-ilmoituksia ei lähetetä." - edit: 'muokkaa tämän ketjun otsikkoa ja aluetta' + s3: + regions: + us_east_1: "itäinen USA (Pohjois-Virginia)" + us_west_1: "Läntinen USA (Pohjois-Kalifornia)" + us_west_2: "Läntinen USA (Oregon)" + us_gov_west_1: "AWS GovCloud (USA)" + eu_west_1: "EU (Irlanti)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Aasia ja Tyynimeri (Singapore)" + ap_southeast_2: "Aasia ja Tyynimeri (Sydney)" + ap_northeast_1: "Aasia ja Tyynimeri (Tokio)" + ap_northeast_2: "Aasia ja Tyynimeri (Soul)" + sa_east_1: "Etelä-Amerikka (Sao Paulo)" + edit: 'muokkaa ketjun otsikkoa ja aluetta' not_implemented: "Tätä toimintoa ei ole vielä toteutettu, pahoittelut!" no_value: "Ei" yes_value: "Kyllä" generic_error: "On tapahtunut virhe." generic_error_with_reason: "Tapahtui virhe: %{error}" sign_up: "Luo tili" - log_in: "Kirjaudu sisään" + log_in: "Kirjaudu" age: "Ikä" joined: "Liittynyt" admin_title: "Ylläpito" flags_title: "Liput" show_more: "näytä lisää" - show_help: "astukset" + show_help: "ohjeet" links: "Linkit" links_lowercase: one: "linkki" @@ -161,6 +179,8 @@ fi: more: "Lisää" less: "Vähemmän" never: "ei koskaan" + every_30_minutes: "puolen tunnin välein" + every_hour: "tunnin välein" daily: "päivittäin" weekly: "viikottain" every_two_weeks: "kahden viikon välein" @@ -172,6 +192,7 @@ fi: other: "{{count}} merkkiä" suggested_topics: title: "Suositellut ketjut" + pm_title: "Suositellut viestit" about: simple_title: "Tietoja" title: "Tietoja sivustosta %{title}" @@ -197,7 +218,7 @@ fi: unbookmark: "Klikkaa poistaaksesi kaikki tämän ketjun kirjanmerkit" bookmarks: not_logged_in: "pahoittelut, sinun täytyy kirjautua sisään voidaksesi lisätä viestin kirjanmerkin" - created: "olet lisännyt tämän viestin kirjainmerkkeihisi" + created: "olet lisännyt tämän viestin kirjanmerkkeihisi" not_bookmarked: "olet lukenut tämän viestin, klikkaa lisätäksesi sen kirjanmerkkeihisi" last_read: "tämä on viimeisin viesti jonka olet lukenut, klikkaa lisätäksesi sen kirjanmerkkeihisi" remove: "Poista kirjanmerkki" @@ -227,9 +248,10 @@ fi: revert: "Palauta" failed: "Epäonnistui" switch_to_anon: "Anonyymi tila" + switch_from_anon: "Poistu anonyymitilasta" banner: close: "Sulje tämä banneri." - edit: "Muokkaa tätä banneria >>" + edit: "Muokkaa banneria >>" choose_topic: none_found: "Yhtään ketjua ei löydetty." title: @@ -249,7 +271,7 @@ fi: one: "1 viesti ketjussa odottaa hyväksyntää" other: "{{count}} viestiä ketjussa odottaa hyväksyntää" confirm: "Tallenna muutokset" - delete_prompt: "Haluatko varmasti poistaa käyttäjän %{username}? Kaikki käyttäjän kirjoittamat viestit poistetaan ja tämän sähköposti- sekä IP-osoitteille asetetaan esto." + delete_prompt: "Haluatko todella poistaa käyttäjän %{username}? Kaikki hänen kirjoittamansa viestit poistetaan. Lisäksi hänen sähköposti- ja IP-osoitteillensa laitetaan esto." approval: title: "Viesti odottaa hyväksyntää" description: "Olemme vastaanottaneet viestisi, mutta se täytyy vielä hyväksyä ennen, kuin se näytetään sivustolla. Ole kärsivällinen." @@ -264,9 +286,9 @@ fi: you_replied_to_post: "Sinä vastasit {{post_number}}" user_replied_to_topic: "{{user}} vastasi ketjuun" you_replied_to_topic: "Sinä vastasit ketjuun" - user_mentioned_user: "{{user}} mainitsi {{another_user}}" + user_mentioned_user: "{{user}} mainitsi käyttäjän {{another_user}}" user_mentioned_you: "{{user}} mainitsi sinut" - you_mentioned_user: "Sinä mainitsit {{another_user}}" + you_mentioned_user: "Sinä mainitsit käyttäjän {{another_user}}" posted_by_user: "Kirjoittaja {{user}}" posted_by_you: "Kirjoittaja sinä" sent_by_user: "Lähettäjä {{user}}" @@ -292,14 +314,26 @@ fi: one: "1 käyttäjä" other: "%{count} käyttäjää" groups: + empty: + posts: "Ryhmän jäsenet eivät ole kirjoittaneet viestejä." + members: "Kukaan ei kuulu tähän ryhmään." + mentions: "Ryhmää ei ole mainittu." + messages: "Tällä ryhmällä ei ole yksityistä ketjua." + topics: "Ryhmän jäsenet eivät ole aloittaneet ketjuja." + add: "Lisää" + selector_placeholder: "Lisää jäseniä" + owner: "omistaja" visible: "Ryhmä näkyy kaikille käyttäjille" title: one: "ryhmä" other: "ryhmät" members: "Jäsenet" + topics: "Ketjut" posts: "Viestit" + mentions: "Viittaukset" + messages: "Viestit" alias_levels: - title: "Kuka voi käyttää tätä ryhmää aliaksena?" + title: "Ketkä voivat lähettää viestejä tälle ryhmälle tai @viitata siihen?" nobody: "Ei kukaan" only_admins: "Vain ylläpitäjät" mods_and_admins: "Vain ylläpitäjät ja valvojat" @@ -308,6 +342,19 @@ fi: trust_levels: title: "Luottamustaso, joka annetaan automaattisesti lisättäessä tähän ryhmään:" none: "Ei mitään" + notifications: + watching: + title: "Tarkkaillut" + description: "Saat ilmoituksen uusista viesteistä jokaisessa viestiketjussa, ja uusien vastausten lukumäärä näytetään." + tracking: + title: "Seurannassa" + description: "Saat ilmoituksen, jos joku mainitsee @nimesi tai vastaa sinulle, ja uusien vastausten lukumäärä näytetään." + regular: + title: "Tavallinen" + description: "Saat ilmoituksen, jos joku mainitsee @nimesi tai vastaa sinulle." + muted: + title: "Vaimennetut" + description: "Et saa ilmoituksia uusista ketjuista tässä ryhmässä." user_action_groups: '1': "Annetut tykkäykset" '2': "Saadut tykkäykset" @@ -317,7 +364,6 @@ fi: '6': "Vastaukset" '7': "Viittaukset" '9': "Lainaukset" - '10': "Tähdelliset" '11': "Muokkaukset" '12': "Lähetetyt" '13': "Postilaatikko" @@ -325,8 +371,9 @@ fi: categories: all: "kaikki alueet" all_subcategories: "kaikki" - no_subcategory: "alueettomat" + no_subcategory: "vain pääalue" category: "Alue" + category_list: "Näytä alueet" reorder: title: "Järjestä alueet uudelleen" title_long: "Järjestä alueiden lista uudelleen" @@ -340,7 +387,7 @@ fi: latest: "Tuoreimmat" latest_by: "tuorein" toggle_ordering: "vaihda järjestystä" - subcategories: "Sisemmät alueet" + subcategories: "Tytäralueet" topic_stats: "Uusien ketjujen lukumäärä." topic_stat_sentence: one: "%{count} uusi ketju viimeisen %{unit} aikana." @@ -383,16 +430,15 @@ fi: invited_by: "Kutsuja" trust_level: "Luottamustaso" notifications: "Ilmoitukset" + statistics: "Tilastot" desktop_notifications: label: "Työpöytäilmoitukset" - not_supported: "Tämä selainen ei tue ilmoituksia, pahoittelut." + not_supported: "Tämä selain ei tue ilmoituksia, pahoittelut." perm_default: "Näytä ilmoituksia" perm_denied_btn: "Ei oikeuksia" - perm_denied_expl: "Olet kieltänyt ilmoitusten näyttämisen. Salli ilmoitusten näyttäminen selaimen asetuksista ja klikkaa sen jälkeen painiketta. (Työpöytä: vasemmanpuoleisin kuvake osoiterivillä. Mobiili: 'Sivun tiedot'.)" + perm_denied_expl: "Olet kieltänyt ilmoitukset. Salli ilmoitukset selaimesi asetuksista." disable: "Poista ilmoitukset käytöstä" - currently_enabled: "(nyt käytössä)" enable: "Näytä ilmoituksia" - currently_disabled: "(pois käytöstä)" each_browser_note: "Huom: Sinun täytyy vaihtaa tämä asetus kaikissa selaimista, joita käytät." dismiss_notifications: "Merkitse kaikki luetuiksi" dismiss_notifications_tooltip: "Merkitse kaikki lukemattomat ilmoitukset luetuiksi" @@ -416,7 +462,7 @@ fi: tracked_categories: "Seuratut" tracked_categories_instructions: "Näiden alueiden kaikki uudet ketjut asetetaan automaattisesti seurantaan. Uusien viestien lukumäärä näytetään ketjun otsikon vieressä." muted_categories: "Vaimennetut" - muted_categories_instructions: "Et saa imoituksia uusista viesteistä näillä alueilla, eivätkä ne näy Lukemattomat-välilehdellä." + muted_categories_instructions: "Et saa imoituksia uusista viesteistä näillä alueilla, eivätkä ne näy tuoreimmissa." delete_account: "Poista tilini" delete_account_confirm: "Oletko varma, että haluat lopullisesti poistaa käyttäjätilisi? Tätä toimintoa ei voi perua!" deleted_yourself: "Käyttäjätilisi on poistettu." @@ -426,16 +472,25 @@ fi: users: "Käyttäjät" muted_users: "Vaimennetut" muted_users_instructions: "Älä näytä ilmoituksia näiltä käyttäjiltä" + muted_topics_link: "Näytä vaimennetut ketjut" + automatically_unpin_topics: "Poista kiinnitetyn ketjun kiinnitys automaattisesti, selattuani sen loppuun." staff_counters: - flags_given: "hyödyllisiä lippuja" + flags_given: "hyödyllistä liputusta" flagged_posts: "liputettuja viestejä" - deleted_posts: "poistettuja viestejä" + deleted_posts: "poistettua viestiä" suspensions: "hyllytyksiä" warnings_received: "varoituksia" messages: all: "Kaikki" - mine: "Omat" - unread: "Lukemattomat" + inbox: "Saapuneet" + sent: "Lähetetyt" + archive: "Arkisto" + groups: "Omat ryhmäni" + bulk_select: "Valitse viestejä" + move_to_inbox: "Siirrä saapuneisiin" + move_to_archive: "Arkisto" + failed_to_move: "Viestien siirto epäonnistui (vika saattaa olla internetyhteydessäsi)" + select_all: "Valitse kaikki" change_password: success: "(sähköposti lähetetty)" in_progress: "(lähettää sähköpostia)" @@ -480,9 +535,9 @@ fi: ok: "Lähetämme sinulle sähköpostin varmistukseksi." invalid: "Ole hyvä ja anna toimiva sähköpostiosoite" authenticated: "{{provider}} on todentanut sähköpostiosoitteesi" + frequency_immediately: "Saat sähköpostia välittömästi, jollet ole jo lukenut asiaa, jota sähköpostiviesti koskee." frequency: - zero: "Lähetämme sähköpostia heti, jos et ole lukenut sähköpostin aihetta." - one: "Lähetämme sähköpostia vain, jos emme ole nähneet sinua edellisen minuutin aikana." + one: "Lähetämme sähköpostia vain, jos emme ole nähneet sinua edellisen minuutin aikana." other: "Lähetämme sähköpostia vain, jos emme ole nähneet sinua edellisen {{count}} minuutin aikana." name: title: "Nimi" @@ -519,12 +574,27 @@ fi: title: "Käyttäjäkortin tunnus" website: "Nettisivu" email_settings: "Sähköposti" + like_notification_frequency: + title: "Ilmoita, kun viestistäni tykätään" + always: "Aina" + first_time_and_daily: "Ensimmäistä kertaa ja päivittäin" + first_time: "Ensimmäistä kertaa" + never: "Ei koskaan" + email_previous_replies: + title: "Liitä aiemmat vastaukset mukaan sähköpostin alaosaan" + unless_emailed: "ellei aiemmin lähetetty" + always: "aina" + never: "ei koskaan" email_digests: title: "Lähetä tiivistelmä uusista viesteistä sähköpostilla, jos en käy sivustolla " + every_30_minutes: "puolen tunnin välein" + every_hour: "tunneittain" daily: "päivittäin" every_three_days: "joka kolmas päivä" weekly: "viikottain" every_two_weeks: "joka toinen viikko" + include_tl0_in_digests: "Sisällytä uusien käyttäjien viestit sähköpostitiivistelmiin oletuksena." + email_in_reply_to: "Liitä sähköpostiin lyhennelmä viestistä, johon vastataan" email_direct: "Lähetä minulle sähköposti, jos joku lainaa viestiäni, vastaa viestiini, viittaa @nimeeni, tai kutsuu minut viestiketjuun" email_private_messages: "Lähetä minulle sähköposti, kun joku lähettää minulle viestin" email_always: "Lähetä sähköposti-ilmoitukset, vaikka olen aktiivinen palstalla." @@ -555,7 +625,9 @@ fi: user: "Kutsuttu käyttäjä" sent: "Lähetetty" none: "Avoimia kutsuja ei ole." - truncated: "Näytetään ensimmäiset {{count}} kutsua." + truncated: + one: "Näytetään ensimmäinen kutsu." + other: "Näytetään ensimmäiset {{count}} kutsua." redeemed: "Hyväksytyt kutsut" redeemed_tab: "Hyväksytyt" redeemed_tab_with_count: "Hyväksytyt ({{count}})" @@ -590,6 +662,15 @@ fi: same_as_email: "Salasanasi on sama kuin sähköpostisi." ok: "Salasana vaikuttaa hyvältä." instructions: "Vähintään %{count} merkkiä." + summary: + title: "Yhteenveto" + stats: "Tilastot" + top_replies: "Parhaat viestit" + more_replies: "Lisää viestejä" + top_topics: "Parhaat ketjut" + more_topics: "Lisää ketjuja" + top_badges: "Parhaat arvomerkit" + more_badges: "Lisää arvomerkkejä" associated_accounts: "Kirjautumiset" ip_address: title: "Viimeinen IP-osoite" @@ -615,11 +696,13 @@ fi: server: "Palvelinvirhe" forbidden: "Pääsy estetty" unknown: "Virhe" + not_found: "Sivua ei löytynyt" desc: network: "Tarkasta internetyhteytesi." network_fixed: "Näyttäisi palanneen takaisin." server: "Virhekoodi: {{status}}" forbidden: "Sinulla ei ole oikeutta katsoa tätä." + not_found: "Hups, ohjelma yritti ladata osoitteen, jota ei ole olemassa" unknown: "Jotain meni pieleen." buttons: back: "Mene takaisin" @@ -630,8 +713,12 @@ fi: logout: "Sinut kirjattiin ulos." refresh: "Lataa sivu uudelleen" read_only_mode: - enabled: "Olet Vain luku -tilassa. Voit jatkaa selaamista, muttet välttämättä pysty vaikuttamaan sisältöön." - login_disabled: "Kirjautuminen ei ole käytössä sivuston ollessa vain luku -tilassa." + enabled: "Sivusto on vain luku -tilassa. Voit jatkaa selailua, mutta vastaaminen, tykkääminen ja muita toimintoja on toistaiseksi poissa käytöstä." + login_disabled: "Et voi kirjautua sisään, kun sivusto on vain luku -tilassa." + logout_disabled: "Et voi kirjautua ulos, kun sivusto on vain luku -tilassa." + too_few_topics_and_posts_notice: "Laitetaanpa keskustelu alulle! Tällä hetkellä palstalla on %{currentTopics} / %{requiredTopics} ketjua ja %{currentPosts} / %{requiredPosts} viestiä. Uudet kävijät tarvitsevat keskusteluita, joita lukea ja joihin vastata." + too_few_topics_notice: "Laitetaanpa keskustelu alulle! Tällä hetkellä palstalla on %{currentTopics} / %{requiredTopics} ketjua. Uudet kävijät tarvitsevat keskusteluita, joita lukea ja joihin vastata." + too_few_posts_notice: "Laitetaanpa keskustelu alulle! Tällä hetkellä palstalla on %{currentPosts} / %{requiredPosts} viestiä. Uudet kävijät tarvitsevat keskusteluita, joita lukea ja joihin vastata." learn_more: "opi lisää..." year: 'vuosi' year_desc: 'viimeisen 365 päivän aikana luodut ketjut' @@ -648,10 +735,17 @@ fi: replies_lowercase: one: vastaus other: vastauksia + signup_cta: + sign_up: "Luo tili" + hide_session: "Muistuta huomenna" + hide_forever: "ei kiitos" + hidden_for_session: "OK, kysyn huomenna uudestaan. Voit aina myös käyttää 'Kirjaudu sisään' -linkkiä luodaksesi tilin." + intro: "Hei siellä! :heart_eyes: Vaikuttaa siltä, että olet pitänyt keskusteluista, mutta et ole luonut omaa tiliä." + value_prop: "Kun luot tilin, muistamme mitä olet lukenut, jotta voit aina palata keskusteluissa takaisin oikeaan kohtaan. Saat myös ilmoituksia, täällä tai sähköpostilla, kun uusia viestejä kirjoitetaan. Voit myös tykätä viesteistä. :heartbeat:" summary: enabled_description: "Tarkastelet tiivistelmää tästä ketjusta, sen mielenkiintoisimpia viestejä käyttäjien toiminnan perusteella." - description: "Tässä kejussa on {{count}} viestiä." - description_time: "Ketjussa on {{count}} viestiä, joiden arvioitu lukemisaika on {{readingTime}} minuuttia." + description: "Vastauksia on {{replyCount}} kpl." + description_time: "Vastauksia on {{replyCount}}. Niiden lukemiseen menee arviolta {{readingTime}} minuuttia." enable: 'Näytä ketjun tiivistelmä' disable: 'Näytä kaikki viestit' deleted_filter: @@ -685,7 +779,7 @@ fi: complete_username_not_found: "Käyttäjänimeä %{username} ei ole rekisteröity" complete_email_not_found: "Sähköpostiosoitetta %{email} vastaavaa tiliä ei ole" login: - title: "Kirjaudu sisään" + title: "Kirjaudu" username: "Käyttäjä" password: "Salasana" email_placeholder: "sähköposti tai käyttäjätunnus" @@ -705,6 +799,9 @@ fi: admin_not_allowed_from_ip_address: "Et voi kirjautua ylläpitäjänä tästä IP-osoitteesta." resend_activation_email: "Klikkaa tästä lähettääksesi vahvistusviestin uudelleen." sent_activation_email_again: "Lähetimme uuden vahvistusviestin sinulle osoitteeseen {{sentTo}}. Viestin saapumisessa voi kestää muutama minuutti, muista tarkastaa myös roskapostikansio." + to_continue: "Ole hyvä ja kirjaudu sisään" + preferences: "Sinun täytyy olla kirjautuneena sisään muokataksesi tilisi asetuksia" + forgot: "En muista käyttäjätilini tietoja" google: title: "Googlella" message: "Todennetaan Googlen kautta (varmista, että ponnahdusikkunoiden esto ei ole päällä)" @@ -714,6 +811,9 @@ fi: twitter: title: "Twitterillä" message: "Todennetaan Twitterin kautta (varmista, että ponnahdusikkunoiden esto ei ole päällä)" + instagram: + title: "Instagramilla" + message: "Todennetaan Instagramin kautta (varmista, että ponnahdusikkunoiden esto ei ole päällä)" facebook: title: "Facebookilla" message: "Todennetaan Facebookin kautta (varmista, että ponnahdusikkunoiden esto ei ole päällä)" @@ -727,15 +827,24 @@ fi: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "lisää..." + options: "Asetukset" + whisper: "kuiskaus" add_warning: "Tämä on virallinen varoitus." + toggle_whisper: "Vaihda kuiskaus" posting_not_on_topic: "Mihin ketjuun haluat vastata?" saving_draft_tip: "tallennetaan..." saved_draft_tip: "tallennettu" saved_local_draft_tip: "tallennettu omalla koneella" similar_topics: "Tämä ketju vaikuttaa samalta kuin.." drafts_offline: "offline luonnokset" + group_mentioned: "Jos viittaat ryhmään {{group}}, {{count}} käyttäjää saa ilmoituksen." error: title_missing: "Otsikko on pakollinen" title_too_short: "Otsikon täytyy olla vähintään {{min}} merkkiä pitkä" @@ -758,7 +867,7 @@ fi: show_edit_reason: "(lisää syy muokkaukselle)" reply_placeholder: "Kirjoita tähän. Käytä Markdownia, BBCodea tai HTML:ää muotoiluun. Raahaa tai liitä kuvia." view_new_post: "Katsele uutta viestiäsi." - saving: "Tallennetaan..." + saving: "Tallennetaan" saved: "Tallennettu!" saved_draft: "Viestiluonnos kesken. Klikkaa tähän jatkaaksesi." uploading: "Lähettää..." @@ -773,6 +882,7 @@ fi: link_description: "kirjoita linkin kuvaus tähän" link_dialog_title: "Lisää linkki" link_optional_text: "vaihtoehtoinen kuvaus" + link_placeholder: "http://esimerkki.fi \"valinnainen teksti\"" quote_title: "Lainaus" quote_text: "Lainaus" code_title: "Teksti ilman muotoiluja" @@ -785,10 +895,11 @@ fi: heading_title: "Otsikko" heading_text: "Otsikko" hr_title: "Vaakaviiva" - undo_title: "Peru" - redo_title: "Tee uudestaan" help: "Markdown apu" toggler: "näytä tai piilota kirjoitusalue" + modal_ok: "OK" + modal_cancel: "Peruuta" + cant_send_pm: "Et voi lähettää viestiä käyttäjälle %{username}." admin_options_title: "Tämän ketjun vain henkilökunnalle näytettävät asetukset" auto_close: label: "Sulje ketju automaattisesti tämän ajan jälkeen:" @@ -805,11 +916,16 @@ fi: more: "vanhat ilmoitukset" total_flagged: "yhteensä liputettuja viestejä" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " + liked_many: + one: "

    {{username}}, {{username2}} ja 1 muu {{description}}

    " + other: "

    {{username}}, {{username2}} ja {{count}} muuta {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -817,6 +933,9 @@ fi: moved_post: "

    {{username}} siirsi {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Ansaitsit '{{description}}'

    " + group_message_summary: + one: "

    {{count}} viesti ryhmän {{group_name}} saapuneissa

    " + other: "

    {{count}} viestiä ryhmän {{group_name}} saapuneissa

    " alt: mentioned: "Viittaaja" quoted: "Lainaaja" @@ -831,28 +950,40 @@ fi: moved_post: "Viestisi siirsi" linked: "Linkki viestiisi" granted_badge: "Arvomerkki myönnetty" + group_message_summary: "Viestejä ryhmän saapuneissa viesteissä." popup: mentioned: '{{username}} mainitsi sinut ketjussa "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} mainitsi sinut ketjussa "{{topic}}" - {{site_title}}' quoted: '{{username}} lainasi sinua ketjussa "{{topic}}" - {{site_title}}' replied: '{{username}} vastasi sinulle ketjussa "{{topic}}" - {{site_title}}' posted: '{{username}} vastasi ketjuun "{{topic}}" - {{site_title}}' private_message: '{{username}} lähetti sinulle yksityisviestin ketjussa "{{topic}}" - {{site_title}}' - linked: '{{username}} linkitti viestiisi aiheesta "{{topic}}" - {{site_title}}' + linked: '{{username}} linkitti viestiisi ketjusta "{{topic}}" - {{site_title}}' upload_selector: title: "Lisää kuva" - title_with_attachments: "Lisää kuva tai tidosto" + title_with_attachments: "Lisää kuva tai tiedosto" from_my_computer: "Tästä laitteesta" from_the_web: "Netistä" remote_tip: "linkki kuvaan" - remote_tip_with_attachments: "linkki kuvaan tai tiedostoon ({{authorized_extensions}})" + remote_tip_with_attachments: "linkki kuvaan tai tiedostoon {{authorized_extensions}}" local_tip: "valitse kuvia laitteeltasi" - local_tip_with_attachments: "valitse kuvia tai tiedostoja laitteeltasi ({{authorized_extensions}})" + local_tip_with_attachments: "valitse kuvia tai tiedostoja laitteeltasi {{authorized_extensions}}" hint: "(voit myös raahata ne editoriin ladataksesi ne sivustolle)" hint_for_supported_browsers: "voit myös raahata tai liittää kuvia editoriin" uploading: "Lähettää" select_file: "Valitse tiedosto" image_link: "linkki, johon kuvasi osoittaa" search: + sort_by: "Järjestä" + relevance: "Osuvuus" + latest_post: "Uusin viesti" + most_viewed: "Katselluin" + most_liked: "Tykätyin" + select_all: "Valitse kaikki" + clear_all: "Tyhjennä kaikki" + result_count: + one: "1 tulos haulle \"{{term}}\"" + other: "{{count}} tulosta haulle \"{{term}}\"" title: "etsi ketjuja, viestejä, käyttäjiä tai alueita" no_results: "Ei tuloksia." no_more_results: "Enempää tuloksia ei löytynyt." @@ -864,17 +995,21 @@ fi: category: "Etsi alueelta \"{{category}}\"" topic: "Etsi tästä ketjusta" private_messages: "Etsi viesteistä" + hamburger_menu: "siirry toiseen ketjuun tai alueelle" + new_item: "uusi" go_back: 'mene takaisin' not_logged_in_user: 'käyttäjäsivu, jossa on tiivistelmä käyttäjän viimeaikaisesta toiminnasta sekä käyttäjäasetukset' current_user: 'siirry omalle käyttäjäsivullesi' topics: bulk: + unlist_topics: "Poista ketjuja listauksista" reset_read: "Palauta lukutila" delete: "Poista ketjut" - dismiss_posts: "Unohda viestit" - dismiss_posts_tooltip: "Tyhjennä nyt ilmoitukset lukemattomista viesteistä näiden ketjujen osalta, mutta näytä ilmoitukset uudestaan, kun ketjuihin kirjoitetaan uusia viestejä." - dismiss_topics: "Unohda ketjut" - dismiss_topics_tooltip: "Lakkaa pysyvästi näyttämästä ilmoituksia uusista viesteistä näissä ketjuissa." + dismiss: "Unohda" + dismiss_read: "Unohda kaikki lukemattomat" + dismiss_button: "Unohda..." + dismiss_tooltip: "Unohda uudet viestit tai lopeta ketjujen seuraaminen" + also_dismiss_topics: "Älä seuraa näitä ketjuja enää - ne eivät jatkossa näy Lukemattomat-välilehdellä" dismiss_new: "Unohda uudet" toggle: "Vaihda useamman ketjun valintaa" actions: "Massatoiminnot" @@ -891,15 +1026,15 @@ fi: new: "Sinulla ei ole uusia ketjuja." read: "Et ole lukenut vielä yhtään yhtään ketjua." posted: "Et ole kirjoittanut vielä yhteenkään ketjuun." - latest: "Tuoreimpia ketjuja ei ole. Ompa harmi." + latest: "Tuoreimpia ketjuja ei ole. Onpa harmi." hot: "Kuumia ketjuja ei ole." bookmarks: "Et ole vielä merkinnyt kirjanmerkkejä." category: "Alueella {{category}} ei ole ketjua." top: "Huippuketjuja ei ole." search: "Hakutuloksia ei löytynyt." educate: - new: '

    Uudet ketjut ilmestyvät tähän.

    Oletuksena, ketjut tulkitaan uusiksi ja niiden yhteydessä näytetäänuusi-merkki, kun ne on luotu edellisen kahden päivän aikana.

    Voit muuttaa tätä käyttäjäasetuksistasi.

    ' - unread: '

    Lukemattomat viestit ilmestyvät tähän.

    Oletuksena, ketjut tulkitaan lukemattomiksi ja niiden yhteydessä näytetään 1 jos olet:

    • luonut ketjun
    • vastannut ketjuun
    • lukenut ketjua enemmän, kuin 4 minuuttia

    tai, jos olet erikseen merkannut ketjun seurantaan tai tarkkailuun ketjun lopusta löytyvästä painikkeesta.

    Voit muuttaa tätä käyttäjäasetuksistasi.

    ' + new: '

    Uuden ketjut näytetään tässä.

    Ketjut tulkitaan uusiksi ja niiden yhteydessä näytetään uusi-merkki, kun ne on luotu edellisen kahden päivän aikana.

    Voit muuttaa tätä käyttäjäasetuksistasi.

    ' + unread: '

    Lukemattomia viestejä sisältävät ketjut näytetään tässä.

    Ketjun yhteydessä näytetään lukemattomien viestien lukumäärä 1 jos olet:

    • luonut ketjun
    • vastannut ketjuun
    • lukenut ketjua pidempään, kuin 4 minuuttia

    tai, jos olet erikseen merkannut ketjun seurattavaksi tai tarkkailtavaksi ketjun lopusta löytyvästä painikkeesta.

    Voit muuttaa tätä käyttäjäasetuksistasi.

    ' bottom: latest: "Tuoreimpia ketjuja ei ole enempää." hot: "Kuumia ketjuja ei ole enempää." @@ -919,6 +1054,12 @@ fi: create: 'Uusi ketju' create_long: 'Luo uusi ketju' private_message: 'Luo viesti' + archive_message: + help: 'Siirrä viesti arkistoosi' + title: 'Arkistoi' + move_to_inbox: + title: 'Siirrä saapuneisiin' + help: 'Siirrä takaisin saapuneisiin.' list: 'Ketjut' new: 'uusi ketju' unread: 'lukemattomat' @@ -935,7 +1076,7 @@ fi: login_required: "Sinun täytyy kirjautua sisään nähdäksesi tämän ketjun." server_error: title: "Ketjun lataaminen epäonnistui" - description: "Pahoittelut, ketjun lataaminen epäonnistui. Kyse saattaa olla yhteysongelmsta. Kokeile sivun lataamista uudestaan ja jos ongelma jatkuu, ota yhteyttä." + description: "Pahoittelut, ketjun lataaminen epäonnistui. Kyse saattaa olla yhteysongelmasta. Kokeile sivun lataamista uudestaan ja jos ongelma jatkuu, ota yhteyttä." not_found: title: "Ketjua ei löytynyt" description: "Pahoittelut, ketjua ei löytynyt. Ehkäpä valvoja on siirtänyt sen muualle?" @@ -957,7 +1098,7 @@ fi: toggle_information: "näytä/kätke ketjun tiedot" read_more_in_category: "Haluatko lukea lisää? Selaa muita ketjuja alueella {{catLink}} tai {{latestLink}}." read_more: "Haluatko lukea lisää? {{catLink}} tai {{latestLink}}." - read_more_MF: "Sinulla on { UNREAD, plural, =0 {} one { 1 lukematon } other { # lukematonta } } { NEW, plural, =0 {} one { {BOTH, select, true{ja } false { } other{}} 1 uusi ketju} other { {BOTH, select, true{ja } false { } other{}} # uutta kejua} } jäljellä, voit myös {CATEGORY, select, true {selata muita ketjuja alueella {catLink}} false {{latestLink}} other {}}" + read_more_MF: "Sinulla on { UNREAD, plural, =0 {} one { 1 lukematon } other { # lukematonta } } { NEW, plural, =0 {} one { {BOTH, select, true{ja } false { } other{}} 1 uusi ketju} other { {BOTH, select, true{ja } false { } other{}} # uutta ketjua} } jäljellä, voit myös {CATEGORY, select, true {selata muita ketjuja alueella {catLink}} false {{latestLink}} other {}}" browse_all_categories: Selaa keskustelualueita view_latest_topics: katsele tuoreimpia ketjuja suggest_create_topic: Jospa aloittaisit uuden ketjun? @@ -969,6 +1110,7 @@ fi: auto_close_title: 'Automaattisen sulkemisen asetukset' auto_close_save: "Tallenna" auto_close_remove: "Älä sulje tätä ketjua automaattisesti" + auto_close_immediate: "Viimeisin viesti tässä ketjussa on jo %{hours} tuntia vanha, joten ketju suljetaan heti." progress: title: ketjun edistyminen go_top: "alkuun" @@ -987,7 +1129,7 @@ fi: '3_1': 'Saat ilmoituksia, koska loit tämän ketjun.' '3': 'Saat ilmoituksia, koska olet asettanut ketjun tarkkailuun.' '2_8': 'Saat ilmoituksia, koska olet asettanut tämän alueen seurantaan.' - '2_4': 'Saat ilmoituksia, koska olet kirjoittanut ketjuun viestin.' + '2_4': 'Saat ilmoituksia, koska olet kirjoittanut ketjuun.' '2_2': 'Saat ilmoituksia, koska olet asettanut ketjun seurantaan.' '2': 'Saat ilmoituksia, koska luet tätä ketjua.' '1_2': 'Saat ilmoituksen jos joku mainitsee @nimesi tai vastaa sinulle.' @@ -1018,7 +1160,7 @@ fi: description: "Et saa mitään ilmoituksia tästä keskustelusta." muted: title: "Vaimenna" - description: "Et saa ilmoituksia mistään tässä ketjussa eikä se näy lukemattomat-välilehdessä." + description: "Et saa ilmoituksia mistään tässä ketjussa, eikä se näy tuoreimmissa." actions: recover: "Peru ketjun poisto" delete: "Poista ketju" @@ -1059,25 +1201,25 @@ fi: unpin: "Älä enää pidä tätä ketjua {{categoryLink}}-aluen ylimmäisenä." unpin_until: "Poista nyt tämän ketjun kiinnitys alueen {{categoryLink}} ylimmäisenä, tai odota kunnes %{until}." pin_note: "Käyttäjät voivat poistaa ketjun kiinnityksen itseltään." + pin_validation: "Päivämäärä vaaditaan kiinnittämään tämä ketju" + not_pinned: "Alueella {{categoryLink}} ei ole kiinnitettyjä ketjuja." already_pinned: - zero: "Alueella {{categoryLink}} ei ole kiinnitettyjä ketjuja." - one: "Kiinnitettyjä ketjuja alueella {{categoryLink}}: 1." - other: "Kiinnitettyjä ketjuja alueella {{categoryLink}}: {{count}}." + one: "Kiinnitettyjä ketjuja alueella {{categoryLink}}: 1" + other: "Alueelle {{categoryLink}} kiinnitettyjä ketjuja: {{count}}" pin_globally: "Kiinnitä tämä ketju kaikkien alueiden ylimmäiseksi, kunnes" confirm_pin_globally: "Olet kiinnittänyt jo {{count}} ketjua kaikille alueille. Liian monta kiinnitettyä ketjua voi olla liian suuri taakka uusille ja kirjautumattomille käyttäjille. Oletko varma, että haluat kiinnittä vielä uuden ketjun kaikille alueille?" unpin_globally: "Älä enää pidä tätä ketjua kaikkien alueiden ylimmäisenä." unpin_globally_until: "Poista nyt tämän ketjun kiinnitys kaikkien alueiden ylimmäisenä, tai odota kunnes %{until}." global_pin_note: "Käyttäjät voivat poistaa ketjun kiinnityksen itseltään." + not_pinned_globally: "Yhtään ketjua ei ole kiinnitetty koko palstalle." already_pinned_globally: - zero: "Mitään ketjuja ei ole kiinnitetty kaikille alueille." - one: "Kaikille alueille kiinnitettyjen ketjujen lukumäärä: 1." - other: "Kaikille alueille kiinnitettyjen ketjujen lukumäärä: {{count}}." + one: "Koko palstalle kiinnitettyjä ketjuja: 1" + other: "Koko palstalle kiinnitettyjä ketjuja: {{count}}" make_banner: "Tee tästä ketjusta banneri, joka näytetään kaikkien sivujen ylimmäisenä." remove_banner: "Poista banneri, joka näytetään kaikkien sivujen ylimmäisenä." banner_note: "Käyttäjät voivat piilottaa bannerin sulkemalla sen. Vain yksi ketju kerrallaan voi olla banneri." - already_banner: - zero: "Banneriketjua ei ole." - one: "Banneri ketju on käytössä." + no_banner_exists: "Banneriketjua ei ole määritelty." + banner_exists: "Banneriketju on määritelty." inviting: "Kutsutaan..." automatically_add_to_groups_optional: "Tämä kutsu sisältää automaattisesti pääsyn ryhmiin: (valinnainen, vain ylläpitäjille)" automatically_add_to_groups_required: "Tämä kutsu sisältää automaattisesti pääsyn ryhmiin: (Vaaditaan, vain ylläpitäjille)" @@ -1089,6 +1231,7 @@ fi: success: "Käyttäjä on kutsuttu osallistumaan tähän yksityiseen keskusteluun." error: "Pahoittelut, kutsuttaessa tapahtui virhe." group_name: "ryhmän nimi" + controls: "Ketjun hallinta" invite_reply: title: 'Kutsu' username_placeholder: "käyttäjätunnus" @@ -1135,6 +1278,12 @@ fi: one: "Valitse uusi omistaja viestille käyttäjältä {{old_user}}." other: "Valitse uusi omistaja {{count}} viestille käyttäjältä {{old_user}}." instructions_warn: "Huomaa, että viestin ilmoitukset eivät siirry uudelle käyttäjälle automaattisesti.
    Varoitus: Tällä hetkellä mikään viestikohtainen data ei siirry uudelle käyttäjälle. Käytä varoen." + change_timestamp: + title: "Muuta aikaleimaa" + action: "muuta aikaleimaa" + invalid_timestamp: "Aikaleima ei voi olla tulevaisuudessa." + error: "Ketjun aikaleiman vaihtamisessa tapahtui virhe" + instructions: "Ole hyvä ja valitse ketjulle uusi aikaleima. Ketjun viestit päivitetään samalla aikaerolla." multi_select: select: 'valitse' selected: 'valittuna ({{count}})' @@ -1177,10 +1326,10 @@ fi: has_likes_title: one: "1 käyttäjä tykkäsi tästä viestistä" other: "{{count}} käyttäjää tykkäsi tästä viestistä" + has_likes_title_only_you: "tykkäsit tästä viestistä" has_likes_title_you: - zero: "sinä tykkäsit tästä viestistä" - one: "sinä ja 1 muu tykkäsitte tästä viestistä" - other: "Sinä ja {{count}} muuta tykkäsivät tästä viestistä" + one: "Sinä ja yksi toinen tykkäsi tästä viestistä" + other: "Sinä ja {{count}} muuta tykkäsi tästä viestistä" errors: create: "Pahoittelut, viestin luonti ei onnistunut. Ole hyvä ja yritä uudelleen." edit: "Pahoittelut, viestin muokkaus ei onnistunut. Ole hyvä ja yritä uudelleen." @@ -1198,10 +1347,12 @@ fi: no_value: "Ei, säilytä" yes_value: "Kyllä, hylkää" via_email: "tämä viesti lähetettiin sähköpostitse" + whisper: "tämä viesti on yksityinen kuiskaus valvojille" wiki: - about: "tämä viesti on wiki; peruskäyttäjät voivat muokata sitä" + about: "tämä viesti on wiki" archetypes: save: 'Tallennusasetukset' + few_likes_left: "Kiitos hyvän mielen levittämisestä! Sinulla on enää muutama tykkäys jäljellä tälle päivälle." controls: reply: "aloita vastaamaan tähän viestiin" like: "tykkää viestistä" @@ -1227,6 +1378,7 @@ fi: revert_to_regular: "Poista henkilökunnan taustaväri" rebake: "Tee HTML uudelleen" unhide: "Poista piilotus" + change_owner: "Vaihda omistajuutta" actions: flag: 'Liputa' defer_flags: @@ -1248,17 +1400,14 @@ fi: like: "Peru tykkäys" vote: "Peru ääni" people: - off_topic: "{{icons}} liputtivat tämän asiaan kuulumattomaksi" - spam: "{{icons}} liputtivat tämän roskapostiksi" - spam_with_url: "{{icons}} liputtivat tämän roskapostiksi" - inappropriate: "{{icons}} liputtivat tämän asiattomaksi" - notify_moderators: "{{icons}} ilmoittivat valvojille" - notify_moderators_with_url: "{{icons}} ilmoittivat valvojille" - notify_user: "{{icons}} lähetti viestin" - notify_user_with_url: "{{icons}} lähetti viestin" - bookmark: "{{icons}} lisäsivät tämän kirjanmerkkeihinsä" - like: "{{icons}} tykkäsivät tästä" - vote: "{{icons}} äänestivät tätä" + off_topic: "liputti tämän asiaan kuulumattomaksi" + spam: "liputti tämän roskapostiksi" + inappropriate: "liputti tämän asiattomaksi" + notify_moderators: "ilmoitti valvojille" + notify_user: "lähetti viestin" + bookmark: "lisäsi tämän kirjanmerkkeihin" + like: "tykkäsi tästä" + vote: "äänesti tätä" by_you: off_topic: "Liputit tämän asiaankuulumattomaksi" spam: "Liputit tämän roskapostiksi" @@ -1318,10 +1467,6 @@ fi: vote: one: "yksi käyttäjä äänesti tätä viestiä" other: "{{count}} käyttäjää äänesti tätä viestiä" - edits: - one: 1 muokkaus - other: "{{count}} muokkausta" - zero: ei muokkauksia delete: confirm: one: "Oletko varma, että haluat poistaa tämän viestin?" @@ -1334,6 +1479,7 @@ fi: last: "Viimeinen revisio" hide: "Piilota revisio" show: "Näytä revisio" + revert: "Palaa tähän revisioon" comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" displays: inline: @@ -1358,7 +1504,8 @@ fi: topic_template: "Ketjun sapluuna" delete: 'Poista alue' create: 'Uusi alue' - save: 'Tallenna alue' + create_long: 'Luo uusi alue' + save: 'Tallenna' slug: 'Alueen lyhenne' slug_placeholder: '(Valinnainen) url-lyhenne' creation_error: Alueen luonnissa tapahtui virhe. @@ -1368,7 +1515,7 @@ fi: topic: "alueen kuvausketju" logo: "Alueen logo" background_image: "Alueen taustakuva" - badge_colors: "Alueiden tunnusten värit" + badge_colors: "Alueen tunnusvärit" background_color: "Taustaväri" foreground_color: "Edustan väri" name_placeholder: "Yksi tai kaksi sanaa enimmillään" @@ -1380,6 +1527,7 @@ fi: change_in_category_topic: "Muokkaa kuvausta" already_used: 'Tämä väri on jo käytössä toisella alueella' security: "Turvallisuus" + special_warning: "Varoitus: Tämä alue on esituotettu ja sen turvallisuusasetuksia ei voi muuttaa. Jos et halua käyttää sitä, poista se sen sijaan." images: "Kuvat" auto_close_label: "Sulje ketjut automaattisesti tämän ajan jälkeen:" auto_close_units: "tuntia" @@ -1387,11 +1535,12 @@ fi: email_in_allow_strangers: "Hyväksy viestejä anonyymeiltä käyttäjiltä joilla ei ole tiliä" email_in_disabled: "Uusien ketjujen luominen sähköpostitse on otettu pois käytöstä sivuston asetuksissa. Salliaksesi uusien ketjujen luomisen sähköpostilla, " email_in_disabled_click: 'ota käyttöön "email in" asetus.' + suppress_from_homepage: "Vaimenna tämä ketju kotisivulta." allow_badges_label: "Salli arvomerkkien myöntäminen tältä alueelta" edit_permissions: "Muokkaa oikeuksia" add_permission: "Lisää oikeus" this_year: "tänä vuonna" - position: "asema" + position: "arvo" default_position: "Oletuspaikka" position_disabled: "Alueet näytetään aktiivisuusjärjestyksessä. Muokataksesi järjestystä," position_disabled_click: 'ota käyttöön "pysyvä aluejärjestys" asetuksista.' @@ -1399,19 +1548,18 @@ fi: notifications: watching: title: "Tarkkaile" - description: "Näiden alueiden kaikki uudet ketjut asetetaan automaattisesti tarkkailuun. Saat ilmoituksen kaikista uusista viesteistä ja ketjuista ja uusien viestien lukumäärä näytetään ketjun otsikon vieressä." + description: "Tarkkailet automaattisesti kaikkia uusia ketjuja näillä alueilla. Saat ilmoituksen jokaisesta uudesta viestistä jokaisessa ketjussa ja uusien vastausten lukumäärä näytetään. " tracking: title: "Seuraa" - description: "Näiden alueiden kaikki uudet ketjut asetetaan automaattisesti seurantaan. Uusien viestien lukumäärä näytetään ketjun otsikon vieressä." + description: "Seuraat automaattisesti kaikkia uusia ketjuja näillä alueilla. Saat ilmoituksen, jos joku mainitsee @nimesi tai vastaa sinulle ja uusien vastauksien lukumäärä näytetään." regular: title: "Tavallinen" description: "Saat ilmoituksen jos joku mainitsee @nimesi tai vastaa sinulle." muted: title: "Vaimennettu" - description: "Et saa imoituksia uusista viesteistä näillä alueilla, eivätkä ne näy Lukemattomat-välilehdellä" + description: "Et saa ilmoituksia uusista ketjuista näillä alueilla, eivätkä ne näy tuoreimmissa." flagging: title: 'Kiitos avustasi yhteisön hyväksi!' - private_reminder: 'liput ovat yksityisiä, ne näkyvät ainoastaan henkilökunnalle' action: 'Liputa viesti' take_action: "Ryhdy toimiin" notify_action: 'Viesti' @@ -1423,6 +1571,7 @@ fi: submit_tooltip: "Toimita lippu" take_action_tooltip: "Saavuta liputusraja välittömästi, ennemmin kuin odota muidenkin käyttäjien liputuksia." cant: "Pahoittelut, et pysty liputtamaan tätä viestiä tällä hetkellä." + notify_staff: 'Ilmoita ylläpidolle yksityisesti' formatted_name: off_topic: "Se on asiaankuulumaton" inappropriate: "Se on asiaton" @@ -1454,12 +1603,14 @@ fi: help: "Tämä ketju on suljettu; siihen ei voi enää vastata." archived: help: "Tämä ketju on arkistoitu; se on jäädytetty eikä sitä voi muuttaa" + locked_and_archived: + help: "Tämä ketju on suljettu ja arkistoitu, sihen ei voi enää vastata eikä sitä muuttaa" unpinned: title: "Kiinnitys poistettu" help: "Ketjun kiinnitys on poistettu sinulta; se näytetään tavallisessa järjestyksessä." pinned_globally: title: "Kiinnitetty koko palstalle" - help: "Tämä ketju on nyt kiinnitetty koko palstalle; se näytetään kaikkien listausten ylimpänä" + help: "Tämä ketju on kiinnitetty koko palstalle; se näytetään tuoreimpien ja oman alueensa ylimpänä" pinned: title: "Kiinnitetty" help: "Tämä ketju on kiinnitetty sinulle; se näytetään alueensa ensimmäisenä" @@ -1469,10 +1620,10 @@ fi: posts_lowercase: "viestejä" posts_long: "tässä ketjussa on {{number}} viestiä" posts_likes_MF: | - Tässä ketjussa on {count, plural, one {1 vastaus, jolla on} other {# vastausta, joilla on}} {ratio, select, - low {suuri määrä tykkäyksiä suhteessa viestien määrään} - med {erittäin suuri määrä tykkäyksiä suhteessa viestien määrään} - high {äärimmäisen suuri määrä tykkäyksiä suhteessa viestien määrään} + Tässä ketjussa on {count, plural, one {1 vastaus} other {# vastausta}} {ratio, select, + low {, joilla on suuri määrä tykkäyksiä suhteessa viestien määrään} + med {, joilla on erittäin suuri määrä tykkäyksiä suhteessa viestien määrään} + high {, joilla on äärimmäisen suuri määrä tykkäyksiä suhteessa viestien määrään} other {}} original_post: "Aloitusviesti" views: "Katselut" @@ -1502,9 +1653,9 @@ fi: with_topics: "%{filter} ketjut" with_category: "%{filter} %{category} ketjut" latest: - title: - zero: "Tuoreimmat" - one: "Tuoreimmat (1)" + title: "Tuoreimmat" + title_with_count: + one: "Tuorein (1)" other: "Tuoreimmat ({{count}})" help: "ketjut, joissa on viimeaikaisia viestejä" hot: @@ -1521,23 +1672,23 @@ fi: title_in: "Alue - {{categoryName}}" help: "kaikki ketjut alueen mukaan järjestettynä" unread: - title: - zero: "Lukemattomat" - one: "Lukemattomat (1)" - other: "Lukemattomat ({{count}})" + title: "Lukemattomat" + title_with_count: + one: "Lukematta (1)" + other: "Lukematta ({{count}})" help: "ketjut, joita seuraat tai tarkkailet tällä hetkellä ja joissa on lukemattomia viestejä" lower_title_with_count: - one: "1 lukematon" - other: "{{count}} lukematonta" + one: "1 lukematta" + other: "{{count}} lukematta" new: lower_title_with_count: one: "1 uusi" other: "{{count}} uutta" lower_title: "uusi" - title: - zero: "Uudet" - one: "Uudet (1)" - other: "Uudet ({{count}})" + title: "Uudet" + title_with_count: + one: "Uusia (1)" + other: "Uusia ({{count}})" help: "viime päivinä luodut ketjut" posted: title: "Viestini" @@ -1546,8 +1697,8 @@ fi: title: "Kirjanmerkit" help: "ketjut, jotka olet merkinnyt kirjanmerkillä" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "Tuoreimmat alueella {{categoryName}}" @@ -1629,6 +1780,7 @@ fi: refresh_report: "Päivitä raportti" start_date: "Alkupäivämäärä" end_date: "Loppupäivämäärä" + groups: "Kaikki ryhmät" commits: latest_changes: "Viimeisimmät muutokset: päivitä usein!" by: "käyttäjältä" @@ -1709,15 +1861,24 @@ fi: delete_confirm: "Poista tämä ryhmä?" delete_failed: "Ryhmän poistaminen ei onnistu. Jos tämä on automaattinen ryhmä, sitä ei voi poistaa." delete_member_confirm: "Poista '%{username}' ryhmästä '%{group}'?" + delete_owner_confirm: "Poista omistajan etuudet käyttäjältä '%{username}'?" name: "Nimi" add: "Lisää" add_members: "Lisää jäseniä" custom: "Mukautetut" + bulk_complete: "Käyttäjät on lisätty ryhmään." + bulk: "Lisää ryhmään useita" + bulk_paste: "Liitä lista käyttäjänimistä tai sähköpostiosoitteista, yksi per rivi:" + bulk_select: "(valitse ryhmä)" automatic: "Automaattiset" automatic_membership_email_domains: "Käyttäjät, jotka luovat tunnuksen sähköpostiosoitteella, jonka verkkotunnus on tällä listalla, lisätään tähän ryhmään:" automatic_membership_retroactive: "Lisää jo olemassa olevat käyttäjät käyttäen samaa sääntöä verkkotunnuksista" default_title: "Tämä ryhmän jäsenten oletustitteli" primary_group: "Aseta automaattisesti ensisijaiseksi ryhmäksi" + group_owners: Omistajat + add_owners: Lisää omistajia + incoming_email: "Saapuvan sähköpostin osoite" + incoming_email_placeholder: "aseta sähköpostiosoite" api: generate_master: "Luo rajapinnan pääavain" none: "Aktiivisia API avaimia ei ole määritelty." @@ -1846,6 +2007,14 @@ fi: color: "Väri" opacity: "Läpinäkyvyys" copy: "Kopioi" + email_templates: + title: "Sähköpostipohjat" + subject: "Otsikko" + multiple_subjects: "Tällä sähköpostiluonnoksella on useita vastaanottajia." + body: "Leipäteksti" + none_selected: "Aloita muokkaaminen valitsemalla sähköpostiluonnos." + revert: "Peru muutokset" + revert_confirm: "Haluatko varmasti peruuttaa muutokset?" css_html: title: "CSS/HTML" long_title: "CSS ja HTML Kustomoinnit" @@ -1890,18 +2059,18 @@ fi: love: name: 'tykkäys' description: "Tykkäyspainikkeen väri." - wiki: - name: 'wiki' - description: "Wiki-viestien taustaväri." email: - title: "Sähköposti" + title: "Sähköpostit" settings: "Asetukset" - all: "Kaikki" + templates: "Viestipohjat" + preview_digest: "Esikatsele tiivistelmä" sending_test: "Lähetetään testisähköpostia..." error: "VIRHE - %{server_error}" test_error: "Testisähköpostin lähettäminen ei onnistunut. Tarkista uudelleen sähköpostiasetukset, varmista, että palveluntarjoajasi ei estä sähköpostiyhteyksiä ja kokeile sitten uudestaan." sent: "Lähetetty" skipped: "Jätetty väliin" + received: "Vastaanotetut" + rejected: "Hylätyt" sent_at: "Lähetetty" time: "Aika" user: "Käyttäjä" @@ -1911,7 +2080,7 @@ fi: send_test: "Lähetä testisähköposti" sent_test: "lähetetty!" delivery_method: "Lähetystapa" - preview_digest: "Esikatsele tiivistelmä" + preview_digest_desc: "Esikatsele inaktiivisille käyttäjille lähetettyjen tiivistelmäsähköpostien sisältöä." refresh: "Päivitä" format: "Muotoilu" html: "html" @@ -1919,6 +2088,25 @@ fi: last_seen_user: "Käyttäjän edellinen kirjautuminen:" reply_key: "Vastausavain" skipped_reason: "Syy väliinjättämiselle" + incoming_emails: + from_address: "Lähettäjä" + to_addresses: "Vastaanottaja" + cc_addresses: "Kopio" + subject: "Otsikko" + error: "Virhe" + none: "Uusia sähköpostiviestejä ei löydetty." + modal: + title: "Saapuvan sähköpostin tiedot" + error: "Virhe" + subject: "Otsikko" + body: "Leipäteksti" + rejection_message: "Hylkäysviesti" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Otsikko..." + error_placeholder: "Virhe" logs: none: "Lokeja ei löytynyt." filters: @@ -1937,6 +2125,7 @@ fi: ip_address: "IP-osoite" topic_id: "Ketjun ID" post_id: "Viestin ID" + category_id: "Alueen ID" delete: 'Poista' edit: 'Muokkaa' save: 'Tallenna' @@ -1967,6 +2156,7 @@ fi: change_site_setting: "muuta sivuston asetusta" change_site_customization: "vaihda sivuston mukautusta" delete_site_customization: "poista sivuston mukautus" + change_site_text: "muutos sivuston teksteissä" suspend_user: "hyllytä käyttäjä" unsuspend_user: "poista hyllytys" grant_badge: "myönnä arvomerkki" @@ -1977,6 +2167,16 @@ fi: impersonate: "esiinny käyttäjänä" anonymize_user: "anonymisoi käyttäjä" roll_up: "Kääri IP estot" + change_category_settings: "muuta alueen asetuksia" + delete_category: "poista alue" + create_category: "luo alue" + block_user: "estä käyttäjä" + unblock_user: "poista esto" + grant_admin: "myönnä ylläpitäjän oikeudet" + revoke_admin: "peru ylläpitäjän oikeudet" + grant_moderation: "myönnä valvojan oikeudet" + revoke_moderation: "peru valvojan oikeudet" + backup_operation: "varmuuskopiointi" screened_emails: title: "Seulottavat sähköpostiosoitteet" description: "Uuden käyttäjätunnuksen luonnin yhteydessä annettua sähköpostiosoitetta verrataan alla olevaan listaan ja tarvittaessa tunnuksen luonti joko estetään tai suoritetaan muita toimenpiteitä." @@ -2043,9 +2243,9 @@ fi: pending: 'Hyväksymistä odottavat käyttäjät' newuser: 'Luottamustason 0 käyttäjät (Tulokas)' basic: 'Luottamustason 1 käyttäjät (Haastaja)' - regular: 'Käyttäjät luottamustasolla 2 (Konkari)' - leader: 'Käyttäjät luottamustasolla 3 (Mestari)' - elder: 'Käyttäjät luottamustasolla 4 (Johtaja)' + member: 'Luottamustason 2 käyttäjät (Konkari)' + regular: 'Luottamustason 3 käyttäjät (Mestari)' + leader: 'Luottamustason 4 käyttäjät (Johtaja)' staff: "Henkilökunta" admins: 'Ylläpitäjät' moderators: 'Valvojat' @@ -2078,6 +2278,7 @@ fi: moderator: "Valvoja?" admin: "Ylläpitäjä?" blocked: "Estetty?" + staged: "Luotu?" show_admin_profile: "Ylläpito" edit_title: "Muokkaa nimikettä" save_title: "Tallenna nimike" @@ -2142,9 +2343,12 @@ fi: deactivate_failed: "Käyttäjätilin poistaminen käytöstä ei onnistunut." unblock_failed: 'Käyttäjätilin eston poistaminen ei onnistunut.' block_failed: 'Käyttäjätilin estäminen ei onnistunut.' + block_confirm: 'Oletko varma, että haluat estää tämän käyttäjän? He eivät voi luoda uusia aiheita tai viestejä.' + block_accept: 'Kyllä, estä tämä käyttäjä' deactivate_explanation: "Käytöstä poistetun käyttäjän täytyy uudelleen vahvistaa sähköpostiosoitteensa." suspended_explanation: "Hyllytetty käyttäjä ei voi kirjautua sisään." block_explanation: "Estetty käyttäjä ei voi luoda viestejä tai ketjuja." + stage_explanation: "Automaattisesti luotu käyttäjä voi vastata sähköpostilla vain erikseen määritettyihin ketjuihin." trust_level_change_failed: "Käyttäjän luottamustason vaihtamisessa tapahtui virhe." suspend_modal_title: "Hyllytä käyttäjä" trust_level_2_users: "Käyttäjät luottamustasolla 2" @@ -2155,7 +2359,7 @@ fi: unlock_trust_level: "Avaa luottamustason lukitus" tl3_requirements: title: "Vaatimukset luottamustasolle 3." - table_title: "Edellisen 100 päivän aikana:" + table_title: "Edellisen %{time_period} päivän aikana:" value_heading: "Arvo" requirement_heading: "Vaatimus" visits: "Vierailua" @@ -2216,8 +2420,15 @@ fi: confirm: 'Vahvistus' dropdown: "Alasvetovalikko" site_text: - none: "Valitse sisällön tyyppi aloittaaksesi muokkaamisen." + description: "Omalla palstallasi voit muokata mitä tahansa tekstisisältöä. Käytä alla sijaitsevaa hakutoimintoa:" + search: "Hae tekstinpätkää, jota haluaisit muokata" title: 'Tekstit' + edit: 'muokkaa' + revert: "Kumoa muutokset" + revert_confirm: "Oletko varma, että haluat kumota tekemäsi muutokset?" + go_back: "Takaisin hakuun" + recommended: "On suositeltavaa muokata seuraavaa tekstiä tarpeidesi mukaan:" + show_overriden: 'Näytä vain muokatut' site_settings: show_overriden: 'Näytä vain muokatut' title: 'Asetukset' @@ -2248,6 +2459,7 @@ fi: backups: "Varmuuskopiot" login: "Kirjautuminen" plugins: "Lisäosat" + user_preferences: "Käyttäjäasetukset" badges: title: Arvomerkit new_badge: Uusi arvomerkki @@ -2256,6 +2468,7 @@ fi: badge: Arvomerkki display_name: Nimi description: Kuvaus + long_description: Pitkä kuvaus badge_type: Arvomerkin tyyppi badge_grouping: Ryhmä badge_groupings: @@ -2304,10 +2517,10 @@ fi: bad_count_warning: header: "VAROITUS!" text: "Myöntöjen näytteitä puuttuu. Tämä tapahtuu, kun arvomerkin kysely palauttaa käyttäjä ID:n tai viestin ID:n jota ei ole olemassa. Tämä voi johtaa odottamattomiin seurauksiin myöhemmin - tarkista kysely uudestaan." + no_grant_count: "Ei arvomerkkejä myönnettäväksi" grant_count: - zero: "Ei arvomerkkejä myönnettävänä." - one: "1 arvomerkki myönnettävänä." - other: "%{count} arvomerkkiä myönnettävänä." + one: "1 arvomerkkiä odottaa myöntämistä." + other: "%{count} arvomerkkiä odottaa myöntämistä." sample: "Esimerkki:" grant: with: %{username} @@ -2321,6 +2534,29 @@ fi: name: "Nimi" image: "Kuva" delete_confirm: "Oletko varma, että haluat poistaa emojin :%{name}:?" + embedding: + get_started: "Jos haluat upottaa Discoursen toiselle sivustolle, aloita lisäämällä isäntä." + confirm_delete: "Oletko varma, että haluat poistaa tämän isännän?" + sample: "Käytä alla olevaa HTML-koodia sivustollasi luodaksesi ja upottaaksesi discourse ketjuja. Korvaa REPLACE_ME upotettavan sivun kanonisella URL-osoitteella." + title: "Upottaminen" + host: "Sallitut isännät" + edit: "muokkaa" + category: "Julkaise alueelle" + add_host: "Lisää isäntä" + settings: "Upotuksen asetukset" + feed_settings: "Syötteen asetukset" + feed_description: "Tarjoamalla RSS/ATOM syötteen sivustollesi, voit lisätä Discoursen kykyä tuoda sisältöä." + crawling_settings: "Crawlerin asetukset" + crawling_description: "Kun Discourse luo ketjuja kirjoituksistasi, se yrittää jäsentää kirjoitustesi sisältöä HTML:stä, jos RSS/ATOM syötettä ei ole tarjolla, Joskus kirjoitusten sisällön poimiminen on haastavaa, joten tarjoamme mahdollisuuden määrittää CSS sääntöjä sen helpottamiseksi." + embed_by_username: "Käyttäjänimi ketjun luomiseksi" + embed_post_limit: "Upotettavien viestien maksimimäärä" + embed_username_key_from_feed: "Avain, jolla erotetaan Discourse-käyttäjänimi syötteestä" + embed_truncate: "Typistä upotetut viestit" + embed_whitelist_selector: "CSS valitsin elementeille, jotka sallitaan upotetuissa viesteissä" + embed_blacklist_selector: "CSS valitstin elementeille, jotka poistetaan upotetuista viesteistä" + feed_polling_enabled: "Tuo kirjoitukset RSS/ATOM syötteen avulla" + feed_polling_url: "RSS/ATOM syötteen URL" + save: "Tallenna upotusasetukset" permalink: title: "Ikilinkit" url: "URL" @@ -2339,7 +2575,7 @@ fi: lightbox: download: "lataa" search_help: - title: 'Etsi ohjetta' + title: 'Haun ohje' keyboard_shortcuts_help: title: 'Näppäinoikotiet' jump_to: @@ -2351,23 +2587,27 @@ fi: categories: 'g, c Alueet' top: 'g, t Huiput' bookmarks: 'g, b Kirjanmerkit' + profile: 'g, p Profiili' + messages: 'g, m Viestit' navigation: title: 'Navigointi' jump: '# Siirry viestiin #' back: 'u Takaisin' up_down: 'k/j Siirrä valintaa ↑ ↓' open: 'o tai Enter Avaa valittu ketju' - next_prev: 'shift+j/shift+k Seuraava/edellinen osio' + next_prev: 'shift+j/shift+k Seuraava/edellinen näkymä' application: title: 'Ohjelmisto' create: 'c Luo uusi ketju' notifications: 'n Avaa ilmoitukset' + hamburger_menu: '= Avaa valikko' user_profile_menu: 'p Avaa käyttäjätilin valikko' show_incoming_updated_topics: '. Näytä päivittyneet ketjut' search: '/ Etsi' help: '? Avaa näppäinoikoteiden apu' dismiss_new_posts: 'x, r Unohda uudet/viestit' dismiss_topics: 'x, t Unohda ketjut' + log_out: 'shift+z shift+z Kirjaudu ulos' actions: title: 'Toiminnot' bookmark_topic: 'f Vaihda kirjanmerkkeihin tai pois' @@ -2388,9 +2628,14 @@ fi: mark_tracking: 'm, t Seuraa ketjua' mark_watching: 'm, w Tarkkaile ketjua' badges: + earned_n_times: + one: "Ansaitsi tämän arvomerkin yhden kerran" + other: "Ansaitsi tämän arvomerkin %{count} kertaa" + granted_on: "Myönnetty %{date}" + others_count: "Muita, joilla on tämä arvomerkki (%{count})" title: Arvomerkit - allow_title: "voidaan käyttää tittelinä" - multiple_grant: "voidaan myöntää useita kertoja" + allow_title: "sallittu titteli" + multiple_grant: "myönnettävissä useaan kertaan" badge_count: one: "1 Arvomerkki" other: "%{count} Arvomerkkiä" @@ -2413,85 +2658,12 @@ fi: name: Muut posting: name: Kirjoittaminen - badge: - editor: - name: Muokkaaja - description: Ensimmäinen muokkaus - basic_user: - name: Haastaja - description: Myönnetty oikeudet tärkeimpiin toimintoihin - member: - name: Konkari - description: Myönnetty oikeus kutsua käyttäjiä - regular: - name: Mestari - description: Myönnetty oikeus siirtää ja nimetä uudelleen ketjuja, linkkien seuraaminen ja Lounge - leader: - name: Johtaja - description: Myönnetty ketjujen globaali muokkaus, kiinnitys, sulkeminen, arkistointi, jakaminen ja yhdistäminen - welcome: - name: Tervetuloa - description: Sai tykkäyksen - autobiographer: - name: Muistelmien kirjoittaja - description: Täytti käyttäjätiedot - anniversary: - name: Vuosipäivä - description: Ollut vuoden aktiivinen jäsen, kirjoittanut vähintään kerran - nice_post: - name: Kiva viesti - description: Sai 10 tykkäystä viestistä. Tämä arvomerkki voidaan myöntää useita kertoja - good_post: - name: Hyvä viesti - description: Sai 25 tykkäystä viestistä. Tämä arvomerkki voidaan myöntää useita kertoja - great_post: - name: Mahtava viesti - description: Sai 50 tykkäystä viestistä. Tämä arvomerkki voidaan myöntää useita kertoja - nice_topic: - name: Kiva ketju - description: Sai 10 tykkäystä ketjusta. Tämä arvomerkki voidaan myöntää useita kertoja - good_topic: - name: Hyvä ketju - description: Sai 25 tykkäystä ketjusta. Tämä arvomerkki voidaan myöntää useita kertoja - great_topic: - name: Mahtava ketju - description: Sai 50 tykkäystä ketjusta. Tämä arvomerkki voidaan myöntää useita kertoja - nice_share: - name: Kiva jako - description: Jakoi viestin, joka sai 25 uniikkia kävijää - good_share: - name: Hyvä jako - description: Jakoi viestin, joka sai 300 uniikkia kävijää - great_share: - name: Mahtava jako - description: Jakoi viestin, joka sai 1000 uniikkia kävijää - first_like: - name: Ensimmäinen tykkäys - description: Tykkäsi viestistä - first_flag: - name: Ensimmäinen liputus - description: Liputti viestin - promoter: - name: Myöntäjä - description: Kutsui käyttäjän - campaigner: - name: Kampanjoija - description: Kutsui 3 haastajaa (luottamustaso 1) - champion: - name: Kampanjapäällikkö - description: Kutsui 5 konkaria (luottamustaso 2) - first_share: - name: Ensimmäinen jakaminen - description: Jakoi viestin - first_link: - name: Ensimmäinen linkki - description: Lisäsi viestiin linkin toiseen ketjuun - first_quote: - name: Ensimmäinen lainaus - description: Lainasi toista käyttäjää - read_guidelines: - name: Luki ohjeet - description: Luki sivuston ohjeet - reader: - name: Lukija - description: Luki kaikki viestit ketjusta, jossa on yli 100 viestiä + google_search: | +

    Etsi Googlella

    +

    +

    +

    diff --git a/config/locales/client.fr.yml b/config/locales/client.fr.yml index f6b80ec36e5..faa544d11dc 100644 --- a/config/locales/client.fr.yml +++ b/config/locales/client.fr.yml @@ -100,6 +100,8 @@ fr: x_years: one: "1 année plus tard" other: "%{count} années plus tard" + previous_month: 'Mois précédent' + next_month: 'Mois suivant' share: topic: 'partager ce sujet' post: 'message #%{postNumber}' @@ -109,6 +111,9 @@ fr: google+: 'partager ce lien sur Google+' email: 'envoyer ce lien dans un courriel' action_codes: + split_topic: "a scindé ce sujet %{when}" + invited_user: "a invité %{who} %{when}" + removed_user: "a retiré %{who} %{when}" autoclosed: enabled: 'fermé %{when}' disabled: 'ouvert %{when}' @@ -129,6 +134,19 @@ fr: disabled: 'délisté %{when}' topic_admin_menu: "actions administrateur pour ce sujet" emails_are_disabled: "Le courriel sortant a été désactivé par un administrateur. Aucune notification courriel ne sera envoyée." + s3: + regions: + us_east_1: "US Est (N. Virginia)" + us_west_1: "US Ouest (N. California)" + us_west_2: "US Ouest (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "EU (Irlande)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asia Pacific (Singapore)" + ap_southeast_2: "Asia Pacific (Sydney)" + ap_northeast_1: "Asia Pacific (Tokyo)" + ap_northeast_2: "Asia Pacific (Seoul)" + sa_east_1: "South America (Sao Paulo)" edit: 'éditer le titre et la catégorie de ce sujet' not_implemented: "Cette fonctionnalité n'a pas encore été implémentée, désolé." no_value: "Non" @@ -161,6 +179,8 @@ fr: more: "Plus" less: "Moins" never: "jamais" + every_30_minutes: "toutes les 30 minutes" + every_hour: "chaque heure" daily: "quotidiennes" weekly: "hebdomadaires" every_two_weeks: "bi-mensuelles" @@ -172,6 +192,7 @@ fr: other: "{{count}} caractères" suggested_topics: title: "Sujets similaires" + pm_title: "Messages Proposés" about: simple_title: "A propos" title: "A propos de %{title}" @@ -219,7 +240,7 @@ fr: saved: "Sauvegardé !" upload: "Envoyer" uploading: "Envoi en cours..." - uploading_filename: "Téléversement de {{filename}}..." + uploading_filename: "Téléchargement de {{filename}}..." uploaded: "Envoyé !" enable: "Activer" disable: "Désactiver" @@ -227,6 +248,7 @@ fr: revert: "Rétablir" failed: "Echec" switch_to_anon: "Mode anonyme" + switch_from_anon: "Quitter le mode anonyme" banner: close: "Ignorer cette bannière." edit: "Éditer cette bannière >>" @@ -292,22 +314,47 @@ fr: one: "1 utilisateur" other: "%{count} utilisateurs" groups: + empty: + posts: "Il n'y a aucun message de la part des membres de ce groupe." + members: "Il n'y a aucun membre dans ce groupe." + mentions: "Il n'y a aucune mention de ce groupe." + messages: "Il n'y a aucun message pour ce groupe." + topics: "Il n'y a aucun sujet de la part des membres de ce groupe." + add: "Ajouter" + selector_placeholder: "Ajouter des membres" + owner: "propriétaire" visible: "Ce groupe est visible par tous les utilisateurs" title: one: "groupe" other: "groupes" members: "Membres" + topics: "Sujets" posts: "Messages" + mentions: "Mentions" + messages: "Messages" alias_levels: - title: "Qui peut utiliser ce groupe comme d'un alias pour les mentions ?" + title: "Qui peut envoyer un message et @notifier ce groupe ?" nobody: "Personne" only_admins: "Seulement les administrateurs " mods_and_admins: "Seulement les modérateurs et les administrateurs " members_mods_and_admins: "Seulement les membres du groupe, les modérateurs et les administrateurs " everyone: "Tout le monde" trust_levels: - title: "Niveau de confiance automatiquement attribué lorsque les membres sont ajoutés à :" + title: "Niveau de confiance automatiquement attribué lorsque les membres sont ajoutés :" none: "Aucun" + notifications: + watching: + title: "Surveiller" + description: "Vous serez notifié de chaque nouvelle réponse dans chaque message, et le nombre de nouvelles réponses sera affiché." + tracking: + title: "Suivre" + description: "Vous serez notifié si quelqu'un mentionne votre @pseudo ou vous répond, et le nombre de nouvelles réponses sera affiché." + regular: + title: "Normal" + description: "Vous serez notifié si quelqu'un mentionne votre @pseudo ou vous répond." + muted: + title: "Silencieux" + description: "Nous ne serez jamais notifié de quoi que ce soit à propos des nouveaux sujets dans ce groupe." user_action_groups: '1': "J'aime donnés" '2': "J'aime reçus" @@ -317,7 +364,6 @@ fr: '6': "Réponses" '7': "Mentions" '9': "Citations" - '10': "Favoris" '11': "Editions" '12': "Eléments envoyés" '13': "Boîte de réception" @@ -327,9 +373,11 @@ fr: all_subcategories: "toutes" no_subcategory: "aucune" category: "Catégorie" + category_list: "Afficher la liste des catégories" reorder: title: "Réordonner les catégories" title_long: "Réorganiser la liste des catégories" + fix_order: "Corriger les positions" fix_order_tooltip: "Toutes les catégories n'ont pas une position unique. Cela peut provoquer des résultats non souhaités." save: "Enregistrer l'ordre" apply_all: "Appliquer" @@ -337,7 +385,7 @@ fr: posts: "Messages" topics: "Sujets" latest: "Récents" - latest_by: "dernièr sujet de" + latest_by: "dernier sujet de" toggle_ordering: "modifier le mode du tri" subcategories: "Sous-catégories" topic_stats: "Le nombre de nouveaux sujets." @@ -382,16 +430,15 @@ fr: invited_by: "Invité par" trust_level: "Niveau de confiance" notifications: "Notifications" + statistics: "Stats" desktop_notifications: label: "Notifications de bureau" not_supported: "Les notifications ne sont pas supportées avec ce navigateur. Désolé." perm_default: "Activer les notifications" perm_denied_btn: "Permission Refusée" - perm_denied_expl: "Vous avez refusé la permission pour les notifications. Utilisez votre navigateur pour activer les notifications, puis appuyez sur le bouton une fois terminé. (Bureau : L'icône la plus à gauche dans la barre d'adresse. Mobile : 'Info Site'.)" + perm_denied_expl: "Vous n'avez pas autorisé les notifications. Autorisez-les depuis les paramètres de votre navigateur." disable: "Désactiver les notifications" - currently_enabled: "(activé actuellement)" enable: "Activer les notifications" - currently_disabled: "(désactivé actuellement)" each_browser_note: "Note : Vous devez changer ce paramètre sur chaque navigateur que vous utilisez." dismiss_notifications: "Marquer tout comme lu" dismiss_notifications_tooltip: "Marquer comme lues toutes les notifications non lues" @@ -415,7 +462,7 @@ fr: tracked_categories: "Suivies" tracked_categories_instructions: "Vous allez suivre automatiquement tous les nouveaux sujets dans ces catégories. Le nombre de nouveaux messages apparaîtra à côté du sujet." muted_categories: "Désactivés" - muted_categories_instructions: "Vous ne recevrez aucune notification concernant les nouveaux sujets de ces catégories, et ils n'apparaitront pas dans votre onglet non lu." + muted_categories_instructions: "Vous ne serez notifié de rien concernant les nouveaux sujets dans ces catégories, et elles n'apparaîtront pas dans les dernières catégories." delete_account: "Supprimer mon compte" delete_account_confirm: "Êtes-vous sûr de vouloir supprimer définitivement votre compte ? Cette action ne peut être annulée !" deleted_yourself: "Votre compte a été supprimé avec succès." @@ -425,6 +472,8 @@ fr: users: "Utilisateurs" muted_users: "Silencieux" muted_users_instructions: "Cacher toutes les notifications de ces utilisateurs." + muted_topics_link: "Afficher les sujets en sourdine" + automatically_unpin_topics: "Desépingler automatiquement quand j'arrive à la fin." staff_counters: flags_given: "signalements utiles" flagged_posts: "messages signalés" @@ -433,8 +482,15 @@ fr: warnings_received: "avertissements" messages: all: "Tous" - mine: "Envoyés" - unread: "Non lus" + inbox: "Boîte de réception" + sent: "Envoyé" + archive: "Archiver" + groups: "Mes groupes" + bulk_select: "Sélection des messages" + move_to_inbox: "Déplacer dans la boîte de réception" + move_to_archive: "Archiver" + failed_to_move: "Impossible de déplacer les messages sélectionnés (peut-être que votre connexion est coupée)" + select_all: "Sélectionner tout" change_password: success: "(courriel envoyé)" in_progress: "(courriel en cours d'envoi)" @@ -479,8 +535,8 @@ fr: ok: "On vous enverra un courriel pour confirmer" invalid: "Merci d'entrer une adresse de courriel valide" authenticated: "Votre adresse de courriel a été authentifiée par {{provider}}" + frequency_immediately: "Nous vous enverrons un courriel immédiatement si vous n'avez pas lu le contenu en question." frequency: - zero: "Nous vous enverrons un courriel immédiatement si vous n'avez déjà lu le contenu en question." one: "Nous vous enverrons des courriels seulement si nous ne vous avons pas vu sur le site dans la dernière minute." other: "Nous vous enverrons des courriels seulement si nous ne vous avons pas vu sur le site dans les dernières {{count}} minutes." name: @@ -518,12 +574,26 @@ fr: title: "Badge pour la carte de l'utilisateur" website: "Site internet" email_settings: "Courriel" + like_notification_frequency: + title: "Notifier lors d'un J'aime" + always: "Toujours" + first_time_and_daily: "La première fois qu'un message est aimé, et quotidiennement" + first_time: "La première fois qu'un message est aimé" + never: "Jamais" + email_previous_replies: + title: "Inclure les réponses précédentes en bas des courriels" + unless_emailed: "sauf si déjà envoyé" + always: "toujours" + never: "jamais" email_digests: title: "Quand je ne visite pas ce site, m'envoyer un résumé des nouveautés par courriel:" + every_30_minutes: "toutes les 30 minutes" + every_hour: "toutes les heures" daily: "quotidien" every_three_days: "tous les trois jours" weekly: "hebdomadaire" every_two_weeks: "toutes les deux semaines" + email_in_reply_to: "Inclure un extrait du message auquel il a été répondu dans les courriels" email_direct: "M'envoyer un courriel quand quelqu'un me cite, répond à mon message ou mentionne mon @pseudo ou m'invite à rejoindre un sujet" email_private_messages: "M'envoyer un courriel quand quelqu'un m'envoie un message privé" email_always: "Recevoir des notifications par email même lorsque je suis actif sur le site" @@ -554,7 +624,9 @@ fr: user: "Utilisateurs" sent: "Envoyé" none: "Il n'y a plus d'invitation en attente à afficher." - truncated: "Affichage des {{count}} premières invitations." + truncated: + one: "Afficher la première invitation." + other: "Afficher les {{count}} premières invitations." redeemed: "Invitations acceptées" redeemed_tab: "Utilisés" redeemed_tab_with_count: "Invitations acceptées ({{count}})" @@ -589,6 +661,15 @@ fr: same_as_email: "Votre mot de passe est le même que votre adresse mail." ok: "Votre mot de passe semble correct." instructions: "Au moins %{count} caractères." + summary: + title: "Résumé" + stats: "Statistiques" + top_replies: "Réponses les plus référencés" + more_replies: "Plus de réponses" + top_topics: "Sujets les plus référencés" + more_topics: "Plus de sujets" + top_badges: "Badges les plus accordés" + more_badges: "Plus de badges" associated_accounts: "Connexions" ip_address: title: "Dernières adresses IP" @@ -614,11 +695,13 @@ fr: server: "Erreur serveur" forbidden: "Accès refusé" unknown: "Erreur" + not_found: "Page introuvable" desc: network: "Veuillez vérifier votre connexion." network_fixed: "On dirait que c'est revenu." server: "Code d'erreur: {{status}}" forbidden: "Vous n'êtes pas autorisé à voir cela." + not_found: "Oups, l'application a essayé de charger une URL qui n'existe pas." unknown: "Une erreur est survenue." buttons: back: "Retour" @@ -629,8 +712,12 @@ fr: logout: "Vous avez été déconnecté" refresh: "Rafraîchir" read_only_mode: - enabled: "Le mode lecture seule est activé. Vous pouvez continuer à naviguer sur le site, mais ne pouvez pas prendre part aux discussions." + enabled: "Le site est en mode lecture seule. Vous pouvez continer à naviguer, mais les réponses, J'aime et autre interactions sont désactivées pour l'instant." login_disabled: "Impossible de se connecté quand le site est en mode lecture seule." + logout_disabled: "Impossible de se deconnecter quand le site est en mode lecture seule." + too_few_topics_and_posts_notice: "Démarrons cette discussion! Il y a actuellement %{currentTopics} / %{requiredTopics} sujets et %{currentPosts} / %{requiredPosts} messages. Les nouveaux visiteurs ont besoin de quelques conversations pour lire et répondre." + too_few_topics_notice: "Démarrons cette discussion ! Il y a actuellement %{currentTopics} / %{requiredTopics} sujets. Les nouveaux visiteurs ont besoin de quelques conversations à lire et répondre." + too_few_posts_notice: "Démarrons cette discussion ! Il y a actuellement %{currentPosts} / %{requiredPosts} messages. Les nouveaux visiteurs ont besoin de quelques conversations à lire et répondre." learn_more: "en savoir plus…" year: 'an' year_desc: 'sujets créés durant les 365 derniers jours' @@ -647,10 +734,17 @@ fr: replies_lowercase: one: réponse other: réponses + signup_cta: + sign_up: "S'inscrire" + hide_session: "Me le rappeler demain." + hide_forever: "non merci" + hidden_for_session: "Très bien, je vous proposerai demain. Vous pouvez toujours cliquer sur 'Se connecter' pour créer un compte." + intro: "Bonjour! :heart_eyes: Vous semblez apprécier la discussion, mais n'avez pas encore créé de compte." + value_prop: "Quand vous créez votre compte, nous stockons ce que vous avez lu pour vous positionner systématiquement sur le bon emplacement à votre retour. Vous avez également des notifications, ici et par courriel, quand de nouveaux messages sont postés. Et vous pouvez aimer les messages pour partager vos coups de cœurs. :heartbeat:" summary: enabled_description: "Vous visualisez un résumé de ce sujet : les messages importants choisis par la communauté." - description: "Il y a {{count}} réponses." - description_time: "Il y a {{count}} réponses avec un temps estimé de lecture de {{readingTime}} minutes." + description: "Il y a {{replyCount}} réponses." + description_time: "Il y a {{replyCount}} réponses avec un temps estimé de lecture de {{readingTime}} minutes." enable: 'Résumer ce sujet' disable: 'Afficher tous les messages' deleted_filter: @@ -704,6 +798,9 @@ fr: admin_not_allowed_from_ip_address: "Vous ne pouvez pas vous connecter comme administrateur depuis cette adresse IP." resend_activation_email: "Cliquez ici pour envoyer à nouveau le courriel d'activation." sent_activation_email_again: "Nous venons d'envoyer un nouveau courriel d'activation à {{currentEmail}}. Il peut prendre quelques minutes à arriver; n'oubliez pas de vérifier votre répertoire spam." + to_continue: "Veuillez vous connecter" + preferences: "Vous devez être connecté pour modifier vos préférences utilisateur." + forgot: "J'ai oublié les détails de mon compte" google: title: "via Google" message: "Authentification via Google (assurez-vous que les popups ne soient pas bloquées)" @@ -713,6 +810,9 @@ fr: twitter: title: "via Twitter" message: "Authentification via Twitter (assurez-vous que les popups ne soient pas bloquées)" + instagram: + title: "avec Instagram" + message: "Authentification via Instagtram (assurez-vous que les popups ne soient pas bloquées)" facebook: title: "via Facebook" message: "Authentification via Facebook (assurez-vous que les popups ne soient pas bloquées)" @@ -726,15 +826,24 @@ fr: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "plus..." + options: "Options" + whisper: "murmure" add_warning: "Ceci est un avertissement officiel." + toggle_whisper: "Activer/Désactiver Whisper" posting_not_on_topic: "À quel sujet voulez-vous répondre ?" saving_draft_tip: "sauvegarde en cours..." saved_draft_tip: "sauvegardé" saved_local_draft_tip: "sauvegardé en local" similar_topics: "Votre message est similaire à..." drafts_offline: "sauvegardé hors ligne" + group_mentioned: "En utilisant {{group}}, vous allez notifier {{count}} personnes." error: title_missing: "Le titre est obligatoire." title_too_short: "Le titre doit avoir au moins {{min}} caractères" @@ -757,7 +866,7 @@ fr: show_edit_reason: "(ajouter la raison de l'édition)" reply_placeholder: "Écrivez ici. Utilisez Markdown, BBCode, ou HTML pour formatter. Glissez ou collez des images." view_new_post: "Voir votre nouveau message." - saving: "Sauvegarde…" + saving: "Sauvegarde" saved: "Sauvegardé !" saved_draft: "Vous avez un message brouillon en cours. Sélectionner cette barre pour reprendre son édition." uploading: "Envoi en cours…" @@ -772,6 +881,7 @@ fr: link_description: "saisir ici la description du lien" link_dialog_title: "Insérez le lien" link_optional_text: "titre optionnel" + link_placeholder: "http://exemple.fr \"texte facultatif\"" quote_title: "Citation" quote_text: "Citation" code_title: "Texte préformaté" @@ -784,10 +894,11 @@ fr: heading_title: "Titre" heading_text: "Titre" hr_title: "Barre horizontale" - undo_title: "Annuler" - redo_title: "Refaire" help: "Aide Markdown" toggler: "Afficher ou cacher le composer" + modal_ok: "OK" + modal_cancel: "Annuler" + cant_send_pm: "Désolé, vous ne pouvez pas envoyer de message à l'utilisateur %{username}." admin_options_title: "Paramètres optionnels pour ce sujet" auto_close: label: "Heure de fermeture automatique de ce sujet :" @@ -804,11 +915,16 @@ fr: more: "voir les anciennes notifications" total_flagged: "Nombre total de messages signalés" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " + liked_many: + one: "

    {{username}}, {{username2}} et 1 autre {{description}}

    " + other: "

    {{username}}, {{username2}} et {{count}} autres {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -816,6 +932,9 @@ fr: moved_post: "

    {{username}} a déplacé {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Vous avez gagné {{description}}

    " + group_message_summary: + one: "

    {{count}} message dans votre boite de réception {{group_name}}

    " + other: "

    {{count}} messages dans votre boite de réception {{group_name}}

    " alt: mentioned: "Mentionné par" quoted: "Cité par" @@ -830,8 +949,10 @@ fr: moved_post: "Votre message a été déplacé par" linked: "Lien vers votre message" granted_badge: "Badge attribué" + group_message_summary: "Messages dans la boite de réception de groupe." popup: mentioned: '{{username}} vous a mentionné dans «{{topic}}» - {{site_title}}' + group_mentioned: '{{username}} vous a mentionné dans «{{topic}}» - {{site_title}}' quoted: '{{username}} vous a cité dans «{{topic}}» - {{site_title}}' replied: '{{username}} vous a répondu dans «{{topic}}» - {{site_title}}' posted: '{{username}} a posté dans «{{topic}}» - {{site_title}}' @@ -843,17 +964,25 @@ fr: from_my_computer: "Depuis mon appareil" from_the_web: "Depuis le web" remote_tip: "lien vers l'image" - remote_tip_with_attachments: "lien vers l'image ou le fichier ({{authorized_extensions}})" + remote_tip_with_attachments: "lien vers l'image ou le fichier {{authorized_extensions}}" local_tip: "sélectionnez des images depuis votre appareil" - local_tip_with_attachments: "sélectionnez des images depuis votre appareil ({{authorized_extensions}})" + local_tip_with_attachments: "sélectionnez des images ou des fichiers depuis votre appareil {{authorized_extensions}}" hint: "(vous pouvez également faire un glisser-déposer dans l'éditeur pour les télécharger)" hint_for_supported_browsers: "vous pouvez aussi glisser/déposer ou coller des images dans l'éditeur" uploading: "Fichier en cours d'envoi" select_file: "Sélectionner Fichier" image_link: "lien vers lequel pointe l'image" search: - select_all: "Tout sélectionner" - clear_all: "Tout supprimer" + sort_by: "Trier par" + relevance: "Pertinence" + latest_post: "Dernier Message" + most_viewed: "Plus Vu" + most_liked: "Plus Aimé" + select_all: "Sélectionner tout" + clear_all: "Désélectionner tout" + result_count: + one: "1 résultat pour \"{{term}}\"" + other: "{{count}} résultats pour \"{{term}}\"" title: "Rechercher les sujets, messages, utilisateurs ou catégories" no_results: "Aucun résultat." no_more_results: "Pas davantage de résultats." @@ -872,12 +1001,14 @@ fr: current_user: 'voir la page de l''utilisateur' topics: bulk: + unlist_topics: "Ne plus lister les sujets" reset_read: "Réinitialiser la lecture" delete: "Supprimer les sujets" - dismiss_posts: "Ignorer les messages" - dismiss_posts_tooltip: "Marquer comme lus ces sujets mais continuer de les afficher dans ma liste de sujets non-lus si de nouveaux messages apparaissent." - dismiss_topics: "Ignorer les sujets" - dismiss_topics_tooltip: "Marquer tous les sujets comme lus et ne plus les afficher dans ma liste de sujet non-lus si de nouveaux messages apparaissent." + dismiss: "Ignorer" + dismiss_read: "Ignorer tous les sujets non-lus" + dismiss_button: "Ignorer..." + dismiss_tooltip: "Ignorer les nouveaux messages ou arrêter des suivre les sujets" + also_dismiss_topics: "Arrêter de suivre ces sujets, ils ne s'afficheront donc plus en \"non lu\" pour moi" dismiss_new: "Ignorer Nouveaux" toggle: "activer la sélection multiple des sujets" actions: "Actions sur sélection multiple" @@ -901,12 +1032,8 @@ fr: top: "Il n'y a pas de meilleurs sujets." search: "Votre recherche ne retourne aucun résultat." educate: - new: '

    Vos nouveaux sujets apparaissent ici

    Par défaut, les sujets sont considérés comme nouveau et affiche l''indicateur nouveau lorsqu''ils ont été crées dans les deux derniers jours.

    - - Vous pouvez modifier cela dans vos préférences.

    ' - unread: '

    Vos sujets non-lus apparaissent ici

    Par défaut, les sujets sont considérés comme non-lus et affichent le nombre de messages non-lus 1 sont ceux:

    - -
    • Que vous avez crées
    • Auxquels vous avez répondu
    • Que vous avez lu plus de 4 minutes

    Ou que vous avez explicitement suivis ou surveillés

    Vous pouvez modifier cela dans vos préférences.

    ' + new: '

    Vos nouveaux sujets apparaissent ici

    Par défaut, les sujets sont considérés comme nouveaux et affichent l''indicateur nouveau lorsqu''ils ont été créés depuis moins de 2 jours.

    Vous pouvez modifier cela dans vos préférences.

    ' + unread: '

    Vos sujets non-lus apparaissent ici

    Par défaut, les sujets sont considérés comme non-lus et affichent le nombre de messages non-lus 1 sont ceux:

    • Que vous avez crées
    • Auxquels vous avez répondu
    • Que vous avez lu plus de 4 minutes

    Ou que vous avez explicitement suivis ou surveillés

    Vous pouvez modifier cela dans vos préférences.

    ' bottom: latest: "Il n'y a plus de sujet à lire." hot: "Il n'y a plus de sujet populaire à lire." @@ -926,6 +1053,12 @@ fr: create: 'Créer votre sujet' create_long: 'Créer un nouveau sujet' private_message: 'Écrire un message' + archive_message: + help: 'Transférer message dans votre archive' + title: 'Archiver' + move_to_inbox: + title: 'Déplacer dans la boîte de réception' + help: 'Redéplacer dans la boîte de réception' list: 'Sujets' new: 'nouveau sujet' unread: 'non-lus' @@ -976,6 +1109,7 @@ fr: auto_close_title: 'Paramètres de fermeture automatique' auto_close_save: "Sauvegarder" auto_close_remove: "Ne pas fermer automatiquement ce sujet" + auto_close_immediate: "Le dernier message dans ce sujet a déjà %{hours} heures, alors le sujet sera fermé immédiatement." progress: title: progression dans le sujet go_top: "haut" @@ -1025,7 +1159,7 @@ fr: description: "Vous ne serez jamais averti de quoi que ce soit à propos de ce message." muted: title: "Silencieux" - description: "Vous ne serez jamais informé de quoi que ce soit à propos de ce sujet, et il n'apparaîtra pas dans votre onglet non lu." + description: "Vous ne serez jamais notifié de rien concernant ce sujet, et il n'apparaîtra pas des les derniers sujets." actions: recover: "Annuler Suppression Sujet" delete: "Supprimer Sujet" @@ -1067,25 +1201,24 @@ fr: unpin_until: "Enlever ce sujet du haut de la catégorie {{categoryLink}} ou attendre jusqu'à %{until}." pin_note: "Les utilisateurs peuvent enlever l'épingle de ce sujet eux-mêmes." pin_validation: "Une date est requise pour épingler ce sujet." + not_pinned: "Aucun sujet actuellement épinglé dans {{categoryLink}}." already_pinned: - zero: "Aucun sujet actuellement épinglé dans {{categoryLink}}." - one: "Sujets actuellement épinglés dans {{categoryLink}}: 1." - other: "Sujets actuellement épinglés dans {{categoryLink}}: {{count}}." + one: "Sujets actuellement épinglés dans {{categoryLink}}: 1" + other: "Sujets actuellement épinglés dans {{categoryLink}}: {{count}}" pin_globally: "Faire apparaître ce sujet en haut de toutes les listes de sujet jusqu'à " confirm_pin_globally: "Vous avez déjà {{count}} sujets épinglés globalement. S'il y a trop de sujets épinglés cela peut être lourd pour les nouveaux utilisateurs et les utilisateurs anonymes. Êtes-vous sûr de vouloir rajouter une sujet épinglé globalement?" unpin_globally: "Enlever ce sujet du haut de toutes les listes de sujet." unpin_globally_until: "Enlever ce sujet du haut de toutes les listes de sujet ou attendre jusqu'à %{until}." global_pin_note: "Les utilisateurs peuvent enlever l'épingle du sujet individuellement." + not_pinned_globally: "Aucun sujet épinglé globalement." already_pinned_globally: - zero: "Aucun sujet épinglé globalement." - one: "Sujets actuellement épinglés globalement : 1." - other: "Sujets actuellement épinglés globalement : {{count}}." + one: "Sujets actuellement épinglés globalement : 1" + other: "Sujets actuellement épinglés globalement : {{count}}" make_banner: "Transformer ce sujet en gros titre qui apparaît en haut de chaque page." remove_banner: "Enlever le gros titre qui apparaît en haut de chaque page." banner_note: "Les utilisateurs peuvent fermer le gros titre. Seul un sujet peut être mis en gros titre à la fois." - already_banner: - zero: "Il n'y a pas actuellement de sujet en gros titre." - one: "Il y a actuellement un sujet en gros titre." + no_banner_exists: "Il n'y a pas actuellement de sujet en gros titre." + banner_exists: "Il y a actuellement un sujet en gros titre." inviting: "Invitation en cours…" automatically_add_to_groups_optional: "Cette invitation inclus l'accès à ces groupes: (optionnel, administrateur uniquement)" automatically_add_to_groups_required: "Cette invitation inclus l'accès à ces groupes: (Requis, administrateur uniquement)" @@ -1097,6 +1230,7 @@ fr: success: "Nous avons invité cet utilisateur à participer à cette discussion." error: "Désolé, il y a eu une erreur lors de l'invitation de cet utilisateur." group_name: "nom du groupe" + controls: "Actions sur le sujet" invite_reply: title: 'Inviter' username_placeholder: "pseudo" @@ -1191,8 +1325,8 @@ fr: has_likes_title: one: "1 personne a aimé ce message" other: "{{count}} personnes ont aimé ce message" + has_likes_title_only_you: "vous avez aimé ce message" has_likes_title_you: - zero: "vous avez aimé ce message" one: "vous et 1 autre personne ont aimé ce message" other: "vous et {{count}} autres personnes ont aimé ce message" errors: @@ -1212,8 +1346,9 @@ fr: no_value: "Non, le conserver" yes_value: "Oui, abandonner" via_email: "message depuis un courriel" + whisper: "ce message est un murmure privé pour les modérateurs" wiki: - about: "ce message est en mode wiki; les utilisateurs de base peuvent le modifier" + about: "ce message est un wiki" archetypes: save: 'Sauvegarder les options' controls: @@ -1241,6 +1376,7 @@ fr: revert_to_regular: "Retirer la couleur modérateur" rebake: "Reconstruire l'HTML" unhide: "Ré-afficher" + change_owner: "Modifier la propriété" actions: flag: 'Signaler' defer_flags: @@ -1262,17 +1398,14 @@ fr: like: "Annuler j'aime" vote: "Retirer votre vote" people: - off_topic: "{{icons}} l'ont signalé comme étant hors-sujet" - spam: "{{icons}} l'ont signalé comme étant du spam" - spam_with_url: "{{icons}} signalé ceci comme spam" - inappropriate: "{{icons}} l'ont signalé comme inapproprié" - notify_moderators: "{{icons}} l'ont signalé pour modération" - notify_moderators_with_url: "{{icons}} l'ont signalé pour modération" - notify_user: "{{icons}} a envoyé un message" - notify_user_with_url: "{{icons}} a envoyé un message" - bookmark: "{{icons}} l'ont ajouté à leurs signets" - like: "{{icons}} l'ont aimé" - vote: "{{icons}} ont voté pour" + off_topic: "signalé comme hors-sujet." + spam: "signalé comme spam" + inappropriate: "signalé comme inapproprié" + notify_moderators: "signalé aux modérateurs" + notify_user: "a envoyé un message" + bookmark: "ajouté aux signets" + like: "a aimé ceci" + vote: "a voté pour ce message" by_you: off_topic: "Vous l'avez signalé comme étant hors-sujet" spam: "Vous l'avez signalé comme étant du spam" @@ -1332,10 +1465,6 @@ fr: vote: one: "1 personne a voté pour ce message" other: "{{count}} personnes ont voté pour ce message" - edits: - one: une édition - other: "{{count}} éditions" - zero: pas d'édition delete: confirm: one: "Êtes-vous sûr de vouloir supprimer ce message ?" @@ -1348,6 +1477,7 @@ fr: last: "Dernière révision" hide: "Masquer la révision" show: "Afficher la révision" + revert: "Revenir à cette révision" comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" displays: inline: @@ -1395,6 +1525,7 @@ fr: change_in_category_topic: "Éditer la description" already_used: 'Cette couleur est déjà utilisée par une autre catégorie' security: "Sécurité" + special_warning: "Avertissement : cette catégorie est une catégorie pré-remplie et les réglages de sécurité ne peuvent pas être modifiés. Si vous ne souhaitez pas utiliser cette catégorie, supprimez-là au lieu de détourner sa fonction." images: "Images" auto_close_label: "Fermer automatiquement après :" auto_close_units: "heures" @@ -1402,7 +1533,7 @@ fr: email_in_allow_strangers: "Accepter les courriels d'utilisateurs anonymes sans compte" email_in_disabled: "La possibilité de créer des nouveaux sujets via courriel est désactivé dans les Paramètres. Pour l'activer," email_in_disabled_click: 'activer le paramètre "email in".' - suppress_from_homepage: "Supprimer cette catégorie de la page d'accueil" + suppress_from_homepage: "Retirer cette catégorie de la page d'accueil" allow_badges_label: "Autoriser les badges à être accordé dans cette catégorie" edit_permissions: "Éditer les permissions" add_permission: "Ajouter une Permission" @@ -1415,19 +1546,18 @@ fr: notifications: watching: title: "S'abonner" - description: "Vous surveillerez automatiquement les nouveaux sujets dans ces catégories. Vous serez notifié de tous les nouveaux messages et sujets, et le nombre de nouvelles réponses apparaîtra pour ces sujets." + description: "Vous surveillerez automatiquement tous les nouveaux sujets dans ces catégories. Vous serez averti pour tout nouveau message dans chaque sujet, et le nombre de nouvelles réponses sera affiché." tracking: title: "Suivi" - description: "Vous suivrez automatiquement tous les nouveaux sujets dans ces catégories. Le nombre de nouvelles réponses apparaîtra pour ces sujets." + description: "Vous surveillerez automatiquement tous les nouveaux sujets dans ces catégories. Vous serez averti si quelqu'un mentionne votre @pseudo ou vous répond, et le nombre de nouvelles réponses sera affiché." regular: title: "Normal" description: "Vous serez notifié si quelqu'un mentionne votre @pseudo ou vous répond." muted: title: "Silencieux" - description: "Vous ne recevrez aucune notification sur les sujets de ces catégories, et ils n'apparaîtront pas dans votre onglet \"non-lus\"." + description: "Vous ne serez jamais notifié de rien concernant les nouveaux sujets dans ces catégories, et elles n'apparaîtront pas dans les dernières catégories." flagging: title: 'Merci de nous aider à garder notre communauté aimable !' - private_reminder: 'les signalements sont privés, seulement visible aux modérateurs' action: 'Signaler ce message' take_action: "Signaler" notify_action: 'Message' @@ -1439,6 +1569,7 @@ fr: submit_tooltip: "Soumettre le signalement privé" take_action_tooltip: "Atteindre le seuil de signalement immédiatement, plutôt que d'attendre plus de signalement de la communauté." cant: "Désolé, vous ne pouvez pas signaler ce message pour le moment" + notify_staff: 'Notifier les responsables de manière privée' formatted_name: off_topic: "C'est hors-sujet" inappropriate: "C'est inapproprié" @@ -1477,7 +1608,7 @@ fr: help: "Ce sujet est désépinglé pour vous; il sera affiché dans l'ordre par défaut" pinned_globally: title: "Épingler globalement" - help: "Ce sujet est épinglé globalement; il s'affichera en haut de toutes les listes de sujets" + help: "Ce sujet est épinglé globalement; il apparaîtra en premier dans la liste des derniers sujets et dans sa catégorie" pinned: title: "Épingler" help: "Ce sujet est épinglé pour vous; il s'affichera en haut de sa catégorie" @@ -1520,9 +1651,9 @@ fr: with_topics: "Sujets %{filter}" with_category: "Sujets %{filter} sur %{category}" latest: - title: - zero: "Récents" - one: "Récent (1)" + title: "Récents" + title_with_count: + one: "Récent ({{count}})" other: "Récents ({{count}})" help: "sujets avec des messages récents" hot: @@ -1539,10 +1670,10 @@ fr: title_in: "Catégorie - {{categoryName}}" help: "tous les sujets regroupés par catégorie" unread: - title: - zero: "Non lus" - one: "Non lus (1)" - other: "Non lus ({{count}})" + title: "Non lus" + title_with_count: + one: "1 non-lu" + other: " ({{count}}) non-lus" help: "sujets que vous suivez ou suivez attentivement actuiellement avec des messages non lus" lower_title_with_count: one: "1 non-lu" @@ -1552,10 +1683,10 @@ fr: one: "1 nouveau" other: "{{count}} nouveaux" lower_title: "nouveau" - title: - zero: "Nouveau" + title: "Nouveaux" + title_with_count: one: "Nouveau (1)" - other: "Nouveau ({{count}})" + other: "Nouveaux ({{count}})" help: "sujets créés dans les derniers jours" posted: title: "Mes Messages" @@ -1564,8 +1695,8 @@ fr: title: "Signets" help: "sujets ajoutés à vos signets" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "derniers sujets dans la catégorie {{categoryName}}" @@ -1647,6 +1778,7 @@ fr: refresh_report: "Actualiser le rapport" start_date: "Date de début" end_date: "Date de fin" + groups: "Tous les groupes" commits: latest_changes: "Dernières modifications: merci de mettre à jour régulièrement!" by: "par" @@ -1657,7 +1789,7 @@ fr: agree: "Accepter" agree_title: "Confirme que le signalement est correct et valide." agree_flag_modal_title: "Accepter et..." - agree_flag_hide_post: "Accepter (caché le message + envoi d'un MP)" + agree_flag_hide_post: "Accepter (cacher le message + envoi d'un MP)" agree_flag_hide_post_title: "Masquer ce message et envoyer automatiquement un message à l'utilisateur afin qu'il le modifie rapidement" agree_flag_restore_post: "Accepter (restauré le message)" agree_flag_restore_post_title: "Restaurer ce message" @@ -1727,15 +1859,24 @@ fr: delete_confirm: "Supprimer ce groupe ?" delete_failed: "Impossible de supprimer le groupe. Si c'est un groupe automatique il ne peut être détruit." delete_member_confirm: "Enlever '%{username}' du groupe '%{group}'?" + delete_owner_confirm: "Retirer les privilèges de propriétaire pour '%{username}' ?" name: "Nom" add: "Ajouter" add_members: "Ajouter des membres" custom: "Personnaliser" + bulk_complete: "Les utilisateurs ont été ajoutés au groupe" + bulk: "Ajouter au groupe en masse" + bulk_paste: "Coller une liste de pseudo ou courriel, un par ligne :" + bulk_select: "(sélectionner un groupe)" automatic: "Automatique" automatic_membership_email_domains: "Les utilisateurs qui s'enregistrent avec un domaine courriel qui correspond exactement à un élément de cette liste seront automatiquement ajoutés à ce groupe:" automatic_membership_retroactive: "Appliquer la même règle de domaine courriel pour les utilisateurs existants" default_title: "Titre par défaut pour tous les utilisateurs de ce groupe" primary_group: "Définir comme groupe primaire automatiquement" + group_owners: Propriétaires + add_owners: Ajouter des propriétaires + incoming_email: "Adresse e-mail d'expédition personnalisée" + incoming_email_placeholder: "Entrer une adresse e-mail" api: generate_master: "Générer une clé Maître pour l'API" none: "Il n'y a pas de clés API actives en ce moment." @@ -1813,7 +1954,7 @@ fr: rollback: label: "Revenir en arrière" title: "Restaurer (RollBack) la base de données à l'état de travail précédent" - confirm: "Êtes-vous sûr de vouloir restaurer (rollback) la base de données à l'état de fonctionnement précédent?" + confirm: "Êtes-vous sûr de vouloir restaurer la base de données à l'état de fonctionnement précédent?" export_csv: user_archive_confirm: "Êtes-vous sûr de vouloir télécharger vos messages?" success: "L'exportation a été initialisé. Vous serez averti par message lorsque le traitement sera terminé." @@ -1864,6 +2005,14 @@ fr: color: "Couleur" opacity: "Opacité" copy: "Copier" + email_templates: + title: "Modèle de courriel" + subject: "Objet" + multiple_subjects: "Ce modèle d'e-mail a plusieurs objets." + body: "Corps" + none_selected: "Choisissez un modèle de courriel pour commencer l'édition" + revert: "Annuler les changements" + revert_confirm: "Êtes-vous sur de vouloir annuler vos changements ?" css_html: title: "CSS/HTML" long_title: "Personnalisation du CSS et HTML" @@ -1908,18 +2057,18 @@ fr: love: name: 'aimer' description: "La couleur du bouton \"J'aime\"." - wiki: - name: 'wiki' - description: "Couleur de base utilisée pour le fond des messages de type wiki." email: - title: "Courriel" + title: "Courriels" settings: "Paramètrage" - all: "Tous" + templates: "Modèles" + preview_digest: "Prévisualisation du courriel" sending_test: "Envoi en cours du courriel de test..." error: "ERREUR - %{server_error}" test_error: "Il y a eu un problème avec l'envoi du courriel de test. Veuillez vérifier vos paramètres, que votre hébergeur ne bloque pas les connections aux courriels, et réessayer." sent: "Envoyés" skipped: "Ignorés" + received: "Reçus" + rejected: "Rejetés" sent_at: "Envoyer à" time: "Heure" user: "Utilisateur" @@ -1929,7 +2078,6 @@ fr: send_test: "Envoyer un courriel de test" sent_test: "Envoyé !" delivery_method: "Méthode d'envoi" - preview_digest: "Prévisualisation du courriel" preview_digest_desc: "Prévisualiser le contenu des courriels hebdomadaires sommaires envoyés aux utilisateurs inactifs." refresh: "Rafraîchir" format: "Format" @@ -1938,6 +2086,25 @@ fr: last_seen_user: "Dernière utilisateur vu :" reply_key: "Répondre" skipped_reason: "Passer Raison" + incoming_emails: + from_address: "De" + to_addresses: "A" + cc_addresses: "Cc" + subject: "Objet" + error: "Erreur" + none: "Aucun courriel reçu." + modal: + title: "Détails du courriel entrant" + error: "Erreur" + subject: "Subject" + body: "Body" + rejection_message: "Courriel de refus" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Objet..." + error_placeholder: "Erreur" logs: none: "Pas de journaux trouvés." filters: @@ -1956,6 +2123,7 @@ fr: ip_address: "IP" topic_id: "Identifiant du sujet" post_id: "Identifiant du message" + category_id: "ID catégorie" delete: 'Supprimer' edit: 'Éditer' save: 'Sauvegarder' @@ -1986,6 +2154,7 @@ fr: change_site_setting: "modifier les paramètres du site" change_site_customization: "modifier la personnalisation du site" delete_site_customization: "supprimer la personnalisation du site" + change_site_text: "modifier le texte du site" suspend_user: "suspendre l'utilisateur" unsuspend_user: "retirer la suspension de l'utilisateur" grant_badge: "décerné le badge" @@ -1996,6 +2165,16 @@ fr: impersonate: "incarner" anonymize_user: "rendre l'utilisateur anonyme" roll_up: "consolider des blocs d'IP" + change_category_settings: "modifier les paramètres de la catégorie" + delete_category: "supprimer la catégorie" + create_category: "créer une catégorie" + block_user: "bloquer l'utilisateur" + unblock_user: "débloquer l'utilisateur" + grant_admin: "Accorder les droits d'admin" + revoke_admin: "Révoquer les droits d'admin" + grant_moderation: "Accorder les droits de modération" + revoke_moderation: "Révoquer les droits de modération" + backup_operation: "sauvegarde" screened_emails: title: "Courriels affichés" description: "Lorsque quelqu'un essaye de créé un nouveau compte, les adresses de courriel suivantes seront vérifiées et l'inscription sera bloquée, ou une autre action sera réalisée." @@ -2008,7 +2187,7 @@ fr: url: "URL" domain: "Domaine" screened_ips: - title: "IP Suivies" + title: "IP surveillés" description: 'Adresses IP qui sont surveillés. Utiliser "Autoriser" pour ajouter les adresses IP à la liste blanche.' delete_confirm: "Êtes-vous sûr de vouloir supprimer la règle pour %{ip_address} ?" roll_up_confirm: "Êtes-vous certain de vouloir consolider les adresses IP interdites sous forme de plages de sous réseaux ?" @@ -2062,9 +2241,9 @@ fr: pending: 'Utilisateur en attente' newuser: 'Utilisateurs au niveau de confiance 0 (Nouveaux utilisateurs)' basic: 'Utilisateurs au niveau de confiance 1 (Utilisateurs de base)' - regular: 'Utilisateurs de niveau 2 (Membre)' - leader: 'Utilisateurs de niveau 3 (Habitué)' - elder: 'Utilisateurs de niveau 4 (Meneur)' + member: 'Utilisateurs au Niveau de confiance 2 (Membre)' + regular: 'Utilisateurs au Niveau de confiance 3 (Habitué)' + leader: 'Utilisateurs au Niveau de confiance 4 (Meneur)' staff: "Membres de l'équipe des responables" admins: 'Administrateurs' moderators: 'Modérateurs' @@ -2097,6 +2276,7 @@ fr: moderator: "Modérateur ?" admin: "Admin ?" blocked: "Bloqué ?" + staged: "En attente?" show_admin_profile: "Admin" edit_title: "Modifier le titre" save_title: "Sauvegarder le titre" @@ -2161,9 +2341,12 @@ fr: deactivate_failed: "Il y a eu un problème lors de la désactivation du compte." unblock_failed: 'Problème rencontré lors du déblocage de l''utilisateur.' block_failed: 'Problème rencontré lors du blocage de l''utilisateur.' + block_confirm: 'Êtes-vous sûr de vouloir bloquer cet utilisateur? Ils ne pourront plus créer de sujet ou message.' + block_accept: 'Oui, bloquer cet utilisateur' deactivate_explanation: "Un utilisateur désactivé doit revalider son adresse de courriel." suspended_explanation: "Un utilisateur suspendu ne peut pas se connecter." block_explanation: "Un utilisateur bloqué ne peut pas écrire de message, ni créer de sujet." + stage_explanation: "Un utilisateur en attente ne peut envoyer des messages que par courriel et sur des sujets spécifiques." trust_level_change_failed: "Il y a eu un problème lors de la modification du niveau de confiance de l'utilisateur." suspend_modal_title: "Suspendre l'utilisateur" trust_level_2_users: "Utilisateurs de niveau de confiance 2" @@ -2174,7 +2357,7 @@ fr: unlock_trust_level: "Déverrouiller le niveau de confiance" tl3_requirements: title: "Pré-requis pour le niveau de confiance 3" - table_title: "Les 100 derniers jours :" + table_title: "Dans les %{time_period} derniers jours:" value_heading: "Valeur" requirement_heading: "Pré-requis" visits: "Visites" @@ -2235,8 +2418,15 @@ fr: confirm: 'Confirmation' dropdown: "Menu déroulant" site_text: - none: "Choisissez un type de contenu pour commencer l'édition." + description: "Vous pouvez personnaliser n'importe quel libellé dans votre forum. Commencez en utilisant la recherche ci-dessous :" + search: "Cherchez le texte que vous souhaitez modifier" title: 'Contenu' + edit: 'modifier' + revert: "Annuler les changements" + revert_confirm: "Êtes-vous sur de vouloir annuler vos changements ?" + go_back: "Retour à la recherche" + recommended: "Nous vous recommandons de personnaliser le texte suivant selon vos besoins :" + show_overriden: 'Ne montrer que ce qui a été personnalisé' site_settings: show_overriden: 'Ne montrer que ce qui a été changé' title: 'Paramètres' @@ -2324,10 +2514,10 @@ fr: bad_count_warning: header: "ATTENTION !" text: "Certains badges n'ont pas été décernés. Ceci se produit lorsque la requête du badge retourne des identifiants d'utilisateurs ou de messages qui n’existent plus. Cela peut produire des résultats non attendus - veuillez vérifier votre requête." + no_grant_count: "Aucun badge à assigner." grant_count: - zero: "Aucun badge à décerner." - one: "1 badge à décerner." - other: "%{count} badges à décerner." + one: "1 badge à assigner." + other: "%{count} badges à assigner." sample: "Exemple :" grant: with: %{username} @@ -2435,9 +2625,10 @@ fr: mark_tracking: 'm, t Marquer le sujet comme suivi' mark_watching: 'm, w Marquer le sujet comme surveillé' badges: + earned_n_times: + one: "A reçu ce badge 1 fois" + other: "A reçu ce badge %{count} fois" title: Badges - allow_title: "peut être utilisé comme votre titre" - multiple_grant: "peut être décerné plusieurs fois" badge_count: one: "1 badge" other: "%{count} badges" @@ -2460,97 +2651,6 @@ fr: name: Autre posting: name: Message - badge: - editor: - name: Editeur - description: A modifié un message pour la première fois - basic_user: - name: Actif - description: Toutes les fonctions communautaires essentielles sont accessibles - member: - name: Membre - description: Accorde les invitations. - regular: - name: Habitué - description: La re-catégorisation, le renommage, le suivi de lien et le salon sont accessibles - leader: - name: Meneur - description: L'édition, l'épinglage, la fermeture, l'archivage, la séparation et la fusion sont accessibles - welcome: - name: Bienvenue - description: A reçu un j'aime. - autobiographer: - name: Autobiographe - description: A rempli les informations de son profil - anniversary: - name: Jubilaire - description: Membres actif depuis un an, avec au moins un message - nice_post: - name: Joli message - description: A reçu 10 j'aime sur un message. Ce badge peut être décerné plusieurs fois - good_post: - name: Excellent message - description: A reçu 25 j'aime sur un message. Ce badge peut être décerné plusieurs fois - great_post: - name: Bon message - description: A reçu 50 j'aime sur un message. Ce badge peut être décerné plusieurs fois - nice_topic: - name: Sujet intéressant - description: A reçu 10 J'aime sur un sujet. Ce badge peut être décerné plusieurs fois - good_topic: - name: Bon sujet - description: A reçu 25 J'aime sur un sujet. Ce badge peut être décerné plusieurs fois - great_topic: - name: Super sujet - description: A reçu 50 J'aime sur un sujet. Ce badge peut être décerné plusieurs fois - nice_share: - name: Partage sympa - description: Message partagé avec 25 visiteurs uniques - good_share: - name: Bon partage - description: Message partagé avec 300 visiteurs uniques - great_share: - name: Super Partage - description: Message partagé avec 1000 visiteurs uniques - first_like: - name: Premier j'aime - description: A aimé un message - first_flag: - name: Premier signalement - description: A signalé un message - promoter: - name: Ambassadeur - description: A invité un utilisateur - campaigner: - name: Militant - description: A invité 3 utilisateurs basiques (Niveau de confiance 1) - champion: - name: Champion - description: A invité 5 membres (Niveau de confiance 2) - first_share: - name: Premier partage - description: A partagé un message - first_link: - name: Premier lien - description: A ajouté un lien interne vers un autre sujet - first_quote: - name: Première citation - description: A cité un utilisateur - read_guidelines: - name: Règlement lu - description: A lu le règlement de la communauté - reader: - name: Lecteur - description: A lu tous les messages d'un sujet contenant plus de 100 messages - popular_link: - name: Lien populaire - description: A posté un lien externe avec au moins 50 clics - hot_link: - name: Lien tendance - description: A posté un lien externe avec au moins 300 clics - famous_link: - name: Lien célèbre - description: A posté un lien externe avec au moins 1000 clics google_search: |

    Rechercher avec Google

    diff --git a/config/locales/client.gl.yml b/config/locales/client.gl.yml new file mode 100644 index 00000000000..97df985aed1 --- /dev/null +++ b/config/locales/client.gl.yml @@ -0,0 +1,2662 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +gl: + js: + number: + format: + separator: "." + delimiter: "," + human: + storage_units: + format: '%n %u' + units: + byte: + one: Byte + other: Bytes + gb: GB + kb: KB + mb: MB + tb: TB + short: + thousands: "{{number}}k" + millions: "{{number}}M" + dates: + time: "h:mm a" + long_no_year: "D MMM h:mm a" + long_no_year_no_time: "D MMM" + full_no_year_no_time: "D MMMM" + long_with_year: "D MMM, YYYY h:mm a" + long_with_year_no_time: "D MMM, YYYY" + full_with_year_no_time: "D MMMM, YYYY" + long_date_with_year: "D MMM, 'YY LT" + long_date_without_year: "D MMM, LT" + long_date_with_year_without_time: "D MMM, 'YY" + long_date_without_year_with_linebreak: "D MMM
    LT" + long_date_with_year_with_linebreak: "D MMM, 'YY
    LT" + tiny: + half_a_minute: "< 1m" + less_than_x_seconds: + one: "< 1s" + other: "< %{count}s" + x_seconds: + one: "1s" + other: "%{count}s" + less_than_x_minutes: + one: "< 1m" + other: "< %{count}m" + x_minutes: + one: "1m" + other: "%{count}m" + about_x_hours: + one: "1h" + other: "%{count}h" + x_days: + one: "1d" + other: "%{count}d" + about_x_years: + one: "1ano" + other: "%{count}anos" + over_x_years: + one: "> 1ano" + other: "> %{count}anos" + almost_x_years: + one: "1ano" + other: "%{count}anos" + date_month: "D MMM" + date_year: "MMM 'YY" + medium: + x_minutes: + one: "1 min" + other: "%{count} mins" + x_hours: + one: "1 hora" + other: "%{count} horas" + x_days: + one: "1 día" + other: "%{count} días" + date_year: "D MMM, 'YY" + medium_with_ago: + x_minutes: + one: "Hai 1 min." + other: "Hai %{count} min." + x_hours: + one: "Hai 1 hora" + other: "Hai %{count} horas" + x_days: + one: "Hai 1 día" + other: "Hai %{count} días" + later: + x_days: + one: "1 día despois" + other: "%{count} días despois" + x_months: + one: "1 mes despois" + other: "%{count} meses despois" + x_years: + one: "1 anos despois" + other: "%{count} anos despois" + previous_month: 'Mes anterior' + next_month: 'Mes seguinte' + share: + topic: 'compartir unha ligazón a este tema' + post: 'publicación %{postNumber}' + close: 'pechar' + twitter: 'compartir esta ligazón no Twitter' + facebook: 'compartir esta ligazón no Facebook' + google+: 'compartir esta ligazón no Google+' + email: 'enviar esta ligazón nun correo electrónico' + action_codes: + split_topic: "este tema dividiuse o %{when}" + invited_user: "convidou a %{who} %{when}" + removed_user: "eliminou a %{who} %{when}" + autoclosed: + enabled: 'pechado o %{when}' + disabled: 'aberto o %{when}' + closed: + enabled: 'pechado o %{when}' + disabled: 'aberto o %{when}' + archived: + enabled: 'arquivado o %{when}' + disabled: 'desarquivado o %{when}' + pinned: + enabled: 'pegado o %{when}' + disabled: 'despegado o %{when}' + pinned_globally: + enabled: 'pegado globalmente o %{when}' + disabled: 'despegado o %{when}' + visible: + enabled: 'listado o %{when}' + disabled: 'retirado da lista o %{when}' + topic_admin_menu: "accións do administrador de temas" + emails_are_disabled: "Todos os correos electrónicos saíntes foron desactivados globalmente por un administrador. Non se enviará ningún tipo de notificación por correo electrónico." + s3: + regions: + us_east_1: "EE.UU. Leste (N. Virxinia)" + us_west_1: "EE.UU. Oeste (N. California)" + us_west_2: "EE.UU. Oeste (Oregón)" + us_gov_west_1: "AWS GovCloud (EE.UU)" + eu_west_1: "EU (Irlanda)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asia Pacífico (Singapur)" + ap_southeast_2: "Asia Pacífico (Sidney)" + ap_northeast_1: "Asia Pacífico (Tokio)" + ap_northeast_2: "Asia Pacífico (Seúl)" + sa_east_1: "América do Sur (São Paulo)" + edit: 'editar o título e a categoría deste tema' + not_implemented: "Sentímolo pero esta funcionalidade non se implementou aínda." + no_value: "Non" + yes_value: "Si" + generic_error: "Sentímolo pero produciuse un erro." + generic_error_with_reason: "Produciuse un erro: %{error}" + sign_up: "Crear unha conta" + log_in: "Iniciar sesión" + age: "Idade" + joined: "Inscrito" + admin_title: "Admin" + flags_title: "Denuncias" + show_more: "amosar máis" + show_help: "opcións" + links: "Ligazóns" + links_lowercase: + one: "ligazón" + other: "ligazóns" + faq: "FAQ" + guidelines: "Directrices" + privacy_policy: "Normas de confidencialidade" + privacy: "Confidencialidade" + terms_of_service: "Termos do servizo" + mobile_view: "Visualización móbil" + desktop_view: "Visualización en escritorio" + you: "Ti" + or: "ou" + now: "agora mesmiño" + read_more: 'ler máis' + more: "Máis" + less: "Menos" + never: "nunca" + every_30_minutes: "cada 30 minutos" + every_hour: "cada hora" + daily: "diariamente" + weekly: "semanalmente" + every_two_weeks: "cada dúas semanas" + every_three_days: "cada tres días" + max_of_count: "máx. de {{count}}" + alternation: "ou" + character_count: + one: "{{count}} carácter" + other: "{{count}} caracteres" + suggested_topics: + title: "Temas suxeridos" + pm_title: "Mensaxes suxeridas" + about: + simple_title: "Verbo de" + title: "Verbo de %{title}" + stats: "Estatísticas do sitio" + our_admins: "Administradores" + our_moderators: "Os moderadores" + stat: + all_time: "De sempre" + last_7_days: "Últimos 7 días" + last_30_days: "Últimos 30 días" + like_count: "Gústames" + topic_count: "Temas" + post_count: "Publicacións" + user_count: "Novos usuarios" + active_user_count: "Usuarios activos" + contact: "Contacta connosco" + contact_info: "No caso dunha incidencia crítica ou asunto urxente que afecte este sitio, contacta connosco en %{contact_info}." + bookmarked: + title: "Marcador" + clear_bookmarks: "Limpar marcadores" + help: + bookmark: "Preme para engadir aos marcadores a publicación inicial deste tema" + unbookmark: "Preme para retirar todos os marcadores deste tema" + bookmarks: + not_logged_in: "cómpre que teñas a sesión iniciada para engadir unha publicación aos marcadores" + created: "engadiches aos marcadores esta publicación" + not_bookmarked: "Acabas de ler esta publicación; preme para engadila aos marcadores" + last_read: "esta é a última publicación lida por ti; preme para engadila aos marcadores" + remove: "Eliminar marcador" + confirm_clear: "Confirmas o borrado de todos os marcadores deste tema?" + topic_count_latest: + one: "{{count}} tema novo ou actualizado." + other: "{{count}} temas novos ou actualizados." + topic_count_unread: + one: "{{count}} tópico sen ler." + other: "{{count}} temas sen ler." + topic_count_new: + one: "{{count}} tópico novo" + other: "{{count}} temas novos" + click_to_show: "Preme para amosar." + preview: "previsualizar" + cancel: "cancelar" + save: "Gardar cambios" + saving: "Gardando...." + saved: "Gardado!" + upload: "Actualizar" + uploading: "Actualizando..." + uploading_filename: "Actualizando {{filename}}..." + uploaded: "Actualizado!" + enable: "Activar" + disable: "Desactivar" + undo: "Desfacer" + revert: "Reverter" + failed: "Fallou" + switch_to_anon: "Modo anónimo" + switch_from_anon: "Saír do Modo anónimo" + banner: + close: "Desbotar este báner." + edit: "Editar este báner »" + choose_topic: + none_found: "Non se atoparon temas." + title: + search: "Buscar un tema polo nome, URL ou ID:" + placeholder: "escribe o título do tema aquí" + queue: + topic: "Tema:" + approve: 'Aprobar' + reject: 'Rexeitar' + delete_user: 'Eliminar usuario' + title: "Cómpre aprobación" + none: "Non hai publicacións para revisar." + edit: "Editar" + cancel: "Cancelar" + view_pending: "ver as publicacións pendentes" + has_pending_posts: + one: "Este tema ten {{count}} publicación agardando aprobación" + other: "Este tema ten {{count}} publicacións agardando aprobación." + confirm: "Gardar os cambios" + delete_prompt: "Confirmas a eliminación de %{username}? Eliminaranse todas as súas publicacións e bloquearase o seu correo electrónico e enderezo IP." + approval: + title: "A publicación necesita aprobación" + description: "Recibimos a túa nova publicación pero cómpre que sexa aprobada por un moderador antes de aparecer. Ten paciencia." + pending_posts: + one: "Tes {{count}} publicación pendente." + other: "Tes {{count}} publicacións pendentes." + ok: "De acordo" + user_action: + user_posted_topic: "{{user}} publicou o tema" + you_posted_topic: "Ti publicaches o tema" + user_replied_to_post: "{{user}} respondeu a {{post_number}}" + you_replied_to_post: "Ti respondiches a {{post_number}}" + user_replied_to_topic: "{{user}} respondeu ao tema " + you_replied_to_topic: "Ti respondiches ao tema " + user_mentioned_user: "{{user}} citou a {{another_user}}" + user_mentioned_you: "{{user}} citou a , vaia, a ti." + you_mentioned_user: "Ti citaches a {{another_user}}" + posted_by_user: "Publicado por {{user}}" + posted_by_you: "Publicado por ti" + sent_by_user: "Enviado por {{user}}" + sent_by_you: "Enviado por , vaia, ti mesmo." + directory: + filter_name: "filtrar por nome de usuario" + title: "Usuarios" + likes_given: "Dados" + likes_received: "Recibidos" + topics_entered: "Introducidos" + topics_entered_long: "Temas introducidos" + time_read: "Tempo de lectura" + topic_count: "Temas" + topic_count_long: "Temas creados" + post_count: "Respostas" + post_count_long: "Respostas publicadas" + no_results: "Non se atoparon resultados." + days_visited: "Visitas" + days_visited_long: "Días visitados" + posts_read: "Lidas" + posts_read_long: "Publicacións lidas" + total_rows: + one: "Un usuario" + other: "%{count} usuarios" + groups: + empty: + posts: "Non hai publicacións de membros deste grupo." + members: "Non hai ningún membro neste grupo." + mentions: "Non hai ningunha mención deste grupo." + messages: "Non hai ningunha mensaxe para este grupo." + topics: "Non hai temas por membros deste grupo." + add: "Engadir" + selector_placeholder: "Engadir membros" + owner: "propietario" + visible: "O grupo é visíbel para todos os usuarios." + title: + one: "grupo" + other: "grupos" + members: "Membros" + topics: "Temas" + posts: "Publicacións" + mentions: "Mencións" + messages: "Mensaxes" + alias_levels: + title: "Quen pode enviar mensaxes e @mención a este grupo?" + nobody: "Ninguén" + only_admins: "Só administradores" + mods_and_admins: "Só moderadores e administradores" + members_mods_and_admins: "Só membros do grupo, moderadores e administradores" + everyone: "Todos" + trust_levels: + title: "Nivel de confianza automático concedido aos membros cando son engadidos:" + none: "Ningún" + notifications: + watching: + title: "Ver" + description: "Notificaráseche cada publicación nova en cada mensaxe e amosarase o número de novas respostas." + tracking: + title: "Seguimento" + description: "Notificaráseche se alguén menciona o teu @nome ou che responde e tamén aparecerá o número de novas respostas." + regular: + title: "Normal" + description: "Notificaráseche se alguén menciona o teu @nome ou che responde." + muted: + title: "Silenciado" + description: "Non recibirás notificacións de nada relacionado con novos temas neste grupo." + user_action_groups: + '1': "Gústames dados" + '2': "Gústames recibidos" + '3': "Marcadores" + '4': "Temas" + '5': "Respostas" + '6': "Respostas" + '7': "Mencións" + '9': "CItas" + '11': "Edicións" + '12': "Enviar elementos" + '13': "Caixa de entrada" + '14': "Pendente" + categories: + all: "todas as categorías" + all_subcategories: "todas" + no_subcategory: "ningunha" + category: "Categoría" + category_list: "Amosar a lista de categorías" + reorder: + title: "Reordenar as categorías" + title_long: "Reorganizar a lista de categorías" + fix_order: "Fixar as posicións" + fix_order_tooltip: "Non todas as categorías teñen un número de posición único, e iso pode causar resultados inesperados." + save: "Gardar orde" + apply_all: "Aplicar" + position: "Posición" + posts: "Publicacións" + topics: "Temas" + latest: "Últimos" + latest_by: "últimos de" + toggle_ordering: "trocar o control de ordenación" + subcategories: "Subcategorías" + topic_stats: "Número de temas novos." + topic_stat_sentence: + one: "%{count} tema novo nos últimos %{unit}." + other: "%{count} temas novos nos últimos %{unit}." + post_stats: "O número de publicacións novas." + post_stat_sentence: + one: "%{count} nova publicación no último %{unit}." + other: "%{count} novas publicacións nos últimos %{unit}." + ip_lookup: + title: Busca do enderezo IP + hostname: Nome do servidor + location: Localización + location_not_found: (descoñecido) + organisation: Organización + phone: Teléfono + other_accounts: "Outras contas co mesmo enderezo IP:" + delete_other_accounts: "Eliminar %{count}" + username: "nome do usuario" + trust_level: "NdeC" + read_time: "tempo de lectura" + topics_entered: "temas introducidos" + post_count: "# publicacións" + confirm_delete_other_accounts: "Confirma que quere eliminar estas contas?" + user_fields: + none: "(seleccione unha opción)" + user: + said: "{{username}}:" + profile: "Perfil" + mute: "Silenciar" + edit: "Editar preferencias" + download_archive: "Descargar as miñas publicacións" + new_private_message: "Nova mensaxe" + private_message: "Mensaxe" + private_messages: "Mensaxes" + activity_stream: "Actividade" + preferences: "Preferencias" + expand_profile: "Expandir" + bookmarks: "Marcadores" + bio: "Verbo de min" + invited_by: "Convidado por" + trust_level: "Nivel de confianza" + notifications: "Notificacións" + statistics: "Estatísticas" + desktop_notifications: + label: "Notificacións en escritorio" + not_supported: "Este navegador non admite notificacións. Desculpe." + perm_default: "Acender notificacións" + perm_denied_btn: "Permiso denegado" + perm_denied_expl: "Denegaches o permiso para notificacións no teu navegador. Modifica os axustes para recibir notificacións no teu navegador." + disable: "Desactivar as notificacións" + enable: "Activar as notificacións" + each_browser_note: "Nota: Tes que cambiar este axuste en cadanseu navegador que utilices." + dismiss_notifications: "Marcar todas como lidas" + dismiss_notifications_tooltip: "Marcar todas notificacións sen ler como lidas" + disable_jump_reply: "Non saltar á miña publicación despois de que responda" + dynamic_favicon: "Amosar o número de temas novos / actualizados na icona do navegador" + edit_history_public: "Permitirlles a outros usuarios ver as revisións das miñas publicacións" + external_links_in_new_tab: "Abrir todas as ligazóns externas nunha nova lapela" + enable_quoting: "Activar as comiñas de resposta para o texto realzado" + change: "cambiar" + moderator: "{{user}} é moderador" + admin: "{{user}} é administrador" + moderator_tooltip: "Este usuario é un moderador" + admin_tooltip: "Este usuario é un administrador" + blocked_tooltip: "Este usuario está bloqueado" + suspended_notice: "Este usuario está suspendido até o {{date}}." + suspended_reason: "Razón:" + github_profile: "Github" + mailing_list_mode: "Enviar un correo por cada nova publicación (a non ser que eu silencie o tema ou categoría)" + watched_categories: "Visto" + watched_categories_instructions: "Mirarás automaticamente todos os temas novos nestas categorías. Notificaránseche todas as novas publicacións e temas, e o número de novas publicacións aparecerá tamén preto do tema." + tracked_categories: "Seguido" + tracked_categories_instructions: "Seguirás automaticamente todos os temas novos nestas categorías. Un número de novas publicacións aparecerá preto do tema." + muted_categories: "Silenciado" + muted_categories_instructions: "Non se che notificará nada sobre os temas novos nestas categorías e non aparecerán na lista de últimos." + delete_account: "Eliminar a miña conta" + delete_account_confirm: "Confirmas que queres eliminar definitivamente a túa conta? Esta acción non se pode desfacer!" + deleted_yourself: "A túa conta acaba de ser eliminada completamente." + delete_yourself_not_allowed: "Non podes eliminar a túa conta neste intre. Contacta cun administrador para que este a elimine por ti. " + unread_message_count: "Mensaxes" + admin_delete: "Eliminar" + users: "Usuarios" + muted_users: "Silenciado" + muted_users_instructions: "Suprimir todas as notificacións destes usuarios." + muted_topics_link: "Amosar os temas silenciados" + automatically_unpin_topics: "Despegar os temas automaticamente cando eu chegue á banda inferior." + staff_counters: + flags_given: "denuncias útiles" + flagged_posts: "publicacións denunciadas" + deleted_posts: "publicacións eliminadas" + suspensions: "suspensións" + warnings_received: "advertencias" + messages: + all: "Todas" + inbox: "Caixa de entrada" + sent: "Enviados" + archive: "Arquivo" + groups: "Os meus grupos" + bulk_select: "Seleccionar mensaxes" + move_to_inbox: "Mover á caixa de entrada" + move_to_archive: "Arquivo" + failed_to_move: "Produciuse un fallo ao mover as mensaxes seleccionadas (quizais a rede está caída)" + select_all: "Seleccionar todo" + change_password: + success: "(correo enviado)" + in_progress: "(enviando o correo)" + error: "(erro)" + action: "Enviar correo para restabelecer o contrasinal" + set_password: "Estabelecer o contrasinal" + change_about: + title: "Cambiar «Verbo de min»" + error: "Produciuse un erro ao cambiar este valor." + change_username: + title: "Cambiar o nome do usuario" + confirm: "Se cambias o nome de usuario, todas as citas anteriores das túas publicacións e as mencións ao teu @nome romperanse. Estás totalmente seguro?" + taken: "Sentímolo pero este nome xa está en uso." + error: "Produciuse un erro cambiando o teu nome de usuario." + invalid: "Este usuario é incorrecto. Só pode contar números e letras." + change_email: + title: "Cambiar o correo electrónico" + taken: "Sentímolo pero este correo non está dispoñíbel." + error: "Produciuse un erro cambiando o correo electrónico. Quizais ese enderezo xa está en uso." + success: "Enviamos un correo electrónico a ese enderezo. Sigue as instrucións de confirmación." + change_avatar: + title: "Cambia a foto do perfil" + gravatar: "Gravatar, baseado en" + gravatar_title: "Cambia o avatar no sitio web de Gravatar" + refresh_gravatar_title: "Actualiza o teu Gravatar" + letter_based: "Imaxe do perfil asignada polo sistema" + uploaded_avatar: "Imaxe personalizada" + uploaded_avatar_empty: "Engadir unha imaxe personalizada" + upload_title: "Envía a túa imaxe" + upload_picture: "Enviar imaxe" + image_is_not_a_square: "Aviso: recortamos a túa imaxe; a largura e a altura eran distintas." + cache_notice: "Cambiaches correctamente a túa imaxe do perfil pero quizais tarde un chisco en aparecer debido á xestión da caché do navegador." + change_profile_background: + title: "Fondo do perfil" + instructions: "Os fondos dos perfís centraranse e terán unha largura predeterminada de 850px." + change_card_background: + title: "Fondo das fichas dos usuarios" + instructions: "As imaxes dos fondos centraranse e terán unha largura predeterminada de 590px." + email: + title: "Correo electrónico" + instructions: "Non se verá nunca en público" + ok: "Enviarémosche un correo electrónico para confirmar" + invalid: "Introduce un enderezo de correo electrónico correcto" + authenticated: "O teu enderezo de correo electrónico foi autenticado por {{provider}}" + frequency_immediately: "Enviarémosche un correo-e axiña se non liches sobre o que che estamos a enviar." + frequency: + one: "Só che eviaremos un correo-e se non te vimos no último minuto." + other: "Só che eviaremos un correo-e se non te vimos nos últimos {{count}} minutos." + name: + title: "Nome" + instructions: "Nome completo (opcional)" + instructions_required: "Nome completo" + too_short: "O nome é curto de mais" + ok: "O nome parece correcto" + username: + title: "Nome do usuario" + instructions: "Único, sen espazos, curto" + short_instructions: "A xente pode mencionarte como @{{username}}" + available: "O nome de usuario está dispoñíbel" + global_match: "O correo electrónico correspóndese co nome do usuario rexistrado" + global_mismatch: "Xa rexistrado. Tentar {{suggestion}}?" + not_available: "Non dispoñíbel. Tentar {{suggestion}}?" + too_short: "O nome do usuario é curto de máis" + too_long: "O nome do usuario é longo de máis" + checking: "Comprobando a dispoñibilidade do nome do usuario..." + enter_email: 'Atopouse o nome do usuario; introduce o correo electrónico' + prefilled: "O correo electrónico coincide co nome do usuario rexistrado" + locale: + title: "Idioma da interface" + instructions: "Idioma da interface do usuario. Cambiará cando actualices a páxina." + default: "(predeterminado)" + password_confirmation: + title: "O contrasinal outra vez" + last_posted: "Última publicación" + last_emailed: "Últimos envíos por correo-e" + last_seen: "Visto" + created: "Inscrito" + log_out: "Saír da sesión" + location: "Localización" + card_badge: + title: "Insignia na ficha do usuario" + website: "Sitio web" + email_settings: "Correo electrónico" + like_notification_frequency: + title: "Notificar cando reciba gústames" + always: "Sempre" + first_time_and_daily: "A primeira vez que unha publicación reciba un gústame e diariamente" + first_time: "A primeira vez que unha publicación lle gusta a alguén" + never: "Nunca" + email_previous_replies: + title: "Incluír as respostas previas no final dos correos electrónicos" + unless_emailed: "excepto os enviados anteriormente" + always: "sempre" + never: "nunca" + email_digests: + title: "Cando non veña por aquí, enviarme un compendio das novidade por correo-e:" + every_30_minutes: "cada 30 minutos" + every_hour: "cada hora" + daily: "diariamente" + every_three_days: "cada tres días" + weekly: "semanalmente" + every_two_weeks: "cada dúas semanas" + email_in_reply_to: "Incluír nos correos un extracto das respostas á publicación" + email_direct: "Enviarme un correo electrónico cando alguén me cite, responda a unha das miñas publicacións, mencione o meu @nome_do_usuario ou me convide a un tema." + email_private_messages: "Enviar correo electrónico cando alguén me mande unha mensaxe" + email_always: "Enviádeme notificación por correo-e incluso cando estea activo no sitio" + other_settings: "Outro" + categories_settings: "Categorías" + new_topic_duration: + label: "Considerar novos temas cando" + not_viewed: "Aínda non os vin" + last_here: "creados desde a última vez que estiven aquí" + after_1_day: "creados no último día" + after_2_days: "creados nos últimos 2 días" + after_1_week: "creados na última semana" + after_2_weeks: "creados nas última 2 semanas" + auto_track_topics: "Facer seguimento automático dos temas nos que entro" + auto_track_options: + never: "nunca" + immediately: "inmediatamente" + after_30_seconds: "despois de 30 segundos " + after_1_minute: "despois de 1 minuto" + after_2_minutes: "despois de 2 minutos" + after_3_minutes: "despois de 3 minutos" + after_4_minutes: "despois de 4 minutos" + after_5_minutes: "despois de 5 minutos" + after_10_minutes: "despois de 10 minutos" + invited: + search: "escribir para buscar convites..." + title: "Convites" + user: "Usuario convidado" + sent: "Enviado" + none: "Non hai convites pendentes de ver." + truncated: + one: "Amosando o primeiro convite." + other: "Amosando os primeiros {{count}} convites." + redeemed: "Convites utilizados" + redeemed_tab: "Utilizados" + redeemed_tab_with_count: "Utilizados ({{count}})" + redeemed_at: "Utilizados" + pending: "Convites pendentes" + pending_tab: "Pendente" + pending_tab_with_count: "Pendentes ({{count}})" + topics_entered: "Temas vistos" + posts_read_count: "Publicacións lidas" + expired: "Este convite caducou." + rescind: "Eliminar" + rescinded: "Convite eliminado" + reinvite: "Reenviar convite" + reinvited: "Convite reenviado" + time_read: "Tempo de lectura" + days_visited: "Días visitado" + account_age_days: "Tempo da conta en días" + create: "Enviar un convite" + generate_link: "Copiar a ligazón do convite" + generated_link_message: '

    A ligazón do convite xerouse correctamente.

    A ligazón do convite só é válida para este enderezo de correo-e: %{invitedEmail}

    ' + bulk_invite: + none: "Aínda non convidaches a ninguén. Podes enviar convites individuais ou en grupo se subes un ficheiro para convites múltiples." + text: "Convidar en grupo desde un ficheiro" + uploading: "Enviando..." + success: "O ficheiro enviouse correctamente, notificaráseche por mensaxe cando remate o proceso." + error: "Produciuse un erro ao subir «{{filename}}»: {{message}}" + password: + title: "Contrasinal" + too_short: "O teu contrasinal é demasiado curto." + common: "O contrasinal é demasiado habitual." + same_as_username: "O contrasinal é igual ao nome do usuario." + same_as_email: "O contrasinal é igual ao correo electrónico." + ok: "O contrasinal semella bo." + instructions: "Como mínimo %{count} caracteres." + summary: + title: "Resumo" + stats: "Estatísticas" + top_replies: "Respostas destacadas" + more_replies: "Máis respostas" + top_topics: "Temas destacados" + more_topics: "Máis temas" + top_badges: "Insignias principais" + more_badges: "Máis insignias" + associated_accounts: "Accesos" + ip_address: + title: "Último enderezo IP" + registration_ip_address: + title: "Rexistro de enderezos IP" + avatar: + title: "Imaxe do perfil" + header_title: "perfil, mensaxes, marcadores e preferencias" + title: + title: "Título" + filters: + all: "Todas" + stream: + posted_by: "Publicado por" + sent_by: "Enviado por" + private_message: "mensaxe" + the_topic: "o tema" + loading: "Cargando..." + errors: + prev_page: "ao tentar cargar" + reasons: + network: "Erro de rede" + server: "Erro do servidor" + forbidden: "Acceso denegado" + unknown: "Erro" + not_found: "Páxina non atopada" + desc: + network: "Por favor, comproba a conexión." + network_fixed: "Parece que xa estamos de volta." + server: "Código do erro: {{status}}" + forbidden: "Non tes permiso para ver isto" + not_found: "Vaites, o aplicativo tentou cargar unha URL inexistente." + unknown: "Algo foi mal." + buttons: + back: "Volver" + again: "Tentar de novo" + fixed: "Cargar páxina" + close: "Pechar" + assets_changed_confirm: "Este sitio acaba de actualizarse. Queres recargar a páxina para ter a última versión?" + logout: "Fuches desconectado." + refresh: "Actualizar" + read_only_mode: + enabled: "Este sitio está en modo só-lectura. Continúe navegando pero responder, gustar e outras accións estarán desactivadas polo de agora." + login_disabled: "Cando o sitio está no modo de só-lectura, desactívase o inicio de sesión." + logout_disabled: "O peche de sesión desactívase mentres o sitio está en modo de só lectura." + too_few_topics_and_posts_notice: "Comecemos a discusión! Hai actualmente %{currentTopics} / %{requiredTopics} temas e %{currentPosts} / %{requiredPosts} publicacións. Os novos visitantes precisan algunhas conversas par ler e participar." + too_few_topics_notice: "Comecemos a discusión! Hai actualmente %{currentTopics} / %{requiredTopics} temas. Os novos visitantes precisan algunhas conversas par ler e participar." + too_few_posts_notice: "Comecemos a discusión! Hai actualmente %{currentPosts} / %{requiredPosts} publicacións. Os novos visitantes precisan algunhas conversas par ler e participar." + learn_more: "saber máis..." + year: 'ano' + year_desc: 'temas creados nos últimos 365 días' + month: 'mes' + month_desc: 'temas creados nos últimos 30 días' + week: 'semana' + week_desc: 'temas creados nos últimos 7 días' + day: 'día' + first_post: Publicación inicial + mute: Silenciar + unmute: Non silenciar + last_post: Última publicación + last_reply_lowercase: última resposta + replies_lowercase: + one: resposta + other: respostas + signup_cta: + sign_up: "Rexistrarse" + hide_session: "Lembrarmo mañá" + hide_forever: "non grazas" + hidden_for_session: "De acordo, preguntareicho mañá. Tamén podes usar «Iniciar sesión» para crear unha conta." + intro: "Ei! :heart_eyes: Semella que gozas coa discusión pero non abriches ningunha conta." + value_prop: "Cando creas unha conta, lembramos exactamente o que liches. Deste xeito sempre volves exactamente onde o deixaches. Podes recibir notificación aquí e vía correo electrónico sempre que se fagan publicacións. E podes darlle a Gústame nas publicacións para compartir o cariño. :heartbeat: " + summary: + enabled_description: "Estás vendo un resumo deste tema: as publicacións máis interesantes determinadas pola comunidade" + description: "Hai {{replyCount}} respostas." + description_time: "Hai {{replyCount}} respostas cun tempo estimado de lectura de {{readingTime}} minutos." + enable: 'Resumir este tema' + disable: 'Amosar todas as publicacións' + deleted_filter: + enabled_description: "Este tema contén publicacións eliminadas, que se ocultaron." + disabled_description: "Móstranse as publicacións eliminadas do tema." + enable: "Ocultar publicacións eliminadas" + disable: "Amosar as publicacións eliminadas" + private_message_info: + title: "Mensaxe" + invite: "Convidar a outros..." + remove_allowed_user: "Confirmas a eliminación de {{name}} desta mensaxe?" + email: 'Correo electrónico' + username: 'Nome do usuario' + last_seen: 'Visto' + created: 'Creado' + created_lowercase: 'creado' + trust_level: 'Nivel de confianza' + search_hint: 'nome do usuario, correo-e ou enderezo IP' + create_account: + title: "Crear unha conta nova" + failed: "Algo foi mal, quizais este correo electrónico xa está rexistrado, tenta coa ligazón de «Esquecín o contrasinal»." + forgot_password: + title: "Contrasinal restabelecido" + action: "Esquecín o contrasinal" + invite: "Introduce o nome do usuario ou correo electrónico, e enviaráseche un correo para restabelecer o contrasinal" + reset: "Restabelecer contrasinal" + complete_username: "Se unha conta corresponde ao nome de usuario %{username}, deberas recibir en breve un correo-e coas instrucións sobre como restabelecer o teu contrasinal." + complete_email: "Se unha conta coincide con %{email}, deberías recibir en breve un correo-e con instrucións sobre como restabelecer o teu contrasinal." + complete_username_found: "Atopamos unha conta co mesmo nome de usuario %{username}, deberas recibir en breve un correo-e coas instrucións sobre como restabelecer o teu contrasinal." + complete_email_found: "Atopamos unha conta que coincide con %{email}, deberas recibir en breve unha mensaxe coas instrucións sobre como restabelecer o contrasinal." + complete_username_not_found: "Ningunha conta coincide co nome do usuario %{username}" + complete_email_not_found: "Ningunha conta coincide co %{email}" + login: + title: "Iniciar sesión" + username: "Usuario" + password: "Contrasinal" + email_placeholder: "correo electrónico ou nome de usuario" + caps_lock_warning: " Bloqueo de maiúsculas activado" + error: "Erro descoñecido" + rate_limit: "Por favor, agarda antes de tentalo outra vez." + blank_username_or_password: "Introduce o teu correo electrónico ou nome de usuario e o contrasinal." + reset_password: 'Restabelecer contrasinal' + logging_in: "Iniciando sesión..." + or: "ou" + authenticating: "Autenticando..." + awaiting_confirmation: "A túa conta está pendente de se activar, emprega a ligazón de contrasinal esquecido para emitir outro correo de activación." + awaiting_approval: "A túa conta non foi aínda aprobada polos membros do equipo. Enviaráseche unha mensaxe cando así for." + requires_invite: "Sentímolo pero o acceso a este foro é unicamente por convite." + not_activated: "Non podes acceder aínda. Antes debemos enviarche unha mensaxe a {{sentTo}}. Por favor, sigue as instrucións desta mensaxe para activar a túa conta." + not_allowed_from_ip_address: "Non podes acceder desde este enderezo IP." + admin_not_allowed_from_ip_address: "Non podes acceder como administrador desde este enderezo IP." + resend_activation_email: "Preme aquí para enviar outro correo de activación." + sent_activation_email_again: "Enviamos outro correo-e de activación a {{currentEmail}}. Pode tardar uns minutos en chegar; asegúrate de revisar o cartafol do spam." + to_continue: "Por favor, inicia sesión" + preferences: "Precisas iniciar sesión para cambiar as túas preferencias de usuario." + forgot: "Non lembro os detalles da miña conta" + google: + title: "co Google" + message: "Autenticación mediante Google (asegúrate de ter desactivado o bloqueador de xanelas emerxentes)" + google_oauth2: + title: "co Google" + message: "Autenticación mediante Google (asegúrate de ter desactivado o bloqueador de xanelas emerxentes)" + twitter: + title: "co Twitter" + message: "Autenticación mediante Twitter (asegúrate de ter desactivado o bloqueador de xanelas emerxentes)" + instagram: + title: "con Instagram" + message: "Autenticación con Instagram (asegúrate que os bloqueadores de publicidade estean desactivados)" + facebook: + title: "co Facebook" + message: "Autenticación mediante Facebook (asegúrate de ter desactivado o bloqueador de xanelas emerxentes)" + yahoo: + title: "co Yahoo" + message: "Autenticación mediante Yahoo (asegúrate de ter desactivado o bloqueador de xanelas emerxentes)" + github: + title: "co GitHub" + message: "Autenticación mediante Github (asegúrate de ter desactivado o bloqueador de xanelas emerxentes)" + apple_international: "Apple/Internacional" + google: "Google" + twitter: "Twitter" + emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Maiús.' + ctrl: 'Ctrl' + alt: 'Alt' + composer: + emoji: "Emoji :)" + more_emoji: "máis..." + options: "Opcións" + whisper: "bisbar" + add_warning: "Este é un aviso oficial." + toggle_whisper: "Cambiar Bisbar" + posting_not_on_topic: "A que tema queres responder?" + saving_draft_tip: "gardando..." + saved_draft_tip: "gardado" + saved_local_draft_tip: "gardado localmente" + similar_topics: "O teu tema é semellante a..." + drafts_offline: "borradores sen conexión" + group_mentioned: "Usando {{group}}, vas enviar a notificación a {{count}} persoas." + error: + title_missing: "O título é obrigatorio" + title_too_short: "O título debe ter alomenos {{min}} caracteres" + title_too_long: "O título non debe ter máis de {{max}} caracteres" + post_missing: "A publicación non pode estar baleira" + post_length: "A publicación debe ter alomenos {{min}} caracteres" + try_like: 'Probaches o botón ?' + category_missing: "Debes seleccionar unha categoría" + save_edit: "Gardar a edición" + reply_original: "Responder no tema orixinal" + reply_here: "Responder aquí" + reply: "Responder" + cancel: "Cancelar" + create_topic: "Crear tema" + create_pm: "Mensaxe" + title: "Ou preme Ctrl+Intro" + users_placeholder: "Engadir un usuario" + title_placeholder: "Sobre que trata a discusión nunha soa frase?" + edit_reason_placeholder: "por que estás editando?" + show_edit_reason: "(engadir unha razón para editar)" + reply_placeholder: "Escribe aquí. Usa Markdown, BBCode ou HTML para formatar. Arrastra ou pega imaxes." + view_new_post: "Ver a nova publicación." + saving: "Gardando" + saved: "Gardado!" + saved_draft: "A publicación do borrador está en proceso. Selecciona continuar." + uploading: "Enviando..." + show_preview: 'amosar visualización »' + hide_preview: '« ocultar previsualización' + quote_post_title: "Citar a publicación enteira" + bold_title: "Grosa" + bold_text: "Texto groso" + italic_title: "Resalte" + italic_text: "texto resaltado" + link_title: "Hiperligazón" + link_description: "introducir a descrición da ligazón aquí" + link_dialog_title: "Inserir hiperligazón" + link_optional_text: "título opcional" + link_placeholder: "http://exemplo.com \"texto opcional\"" + quote_title: "Citación" + quote_text: "Citación" + code_title: "Texto preformatado" + code_text: "Texto preformatado cun sangrado de 4 espazos" + upload_title: "Enviar" + upload_description: "introducir a descrición do envío aquí" + olist_title: "Lista numerada" + ulist_title: "Lista con símbolos" + list_item: "Elemento da lista" + heading_title: "Cabeceira" + heading_text: "Cabeceira" + hr_title: "Regra horizontal" + help: "Axuda para edición con Markdown" + toggler: "agochar ou amosar o panel de composición" + modal_ok: "De acordo" + modal_cancel: "Cancelar" + cant_send_pm: "Sentímolo pero non podes enviar unha mensaxe a %{username}." + admin_options_title: "Axustes do equipo para este tema" + auto_close: + label: "Tempo para o peche automático deste tema:" + error: "Introduce un valor correcto." + based_on_last_post: "Non pechar até que a última publicación do tema teña alomenos este tempo." + all: + examples: 'Introducir o número de horas (24), hora absoluta (17:30) ou a marca data/hora (2013-11-22 14:00).' + limited: + units: "(# de horas)" + examples: 'Introducir o número de horas (24).' + notifications: + title: "notificacións das mencións ao teu @nome, respostas ás túas publicacións e temas, mensaxes, etc" + none: "Non é posíbel cargar as notificacións neste intre" + more: "ver notifiacións anteriores" + total_flagged: "total de publicacións denunciadas" + mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " + quoted: "

    {{username}} {{description}}

    " + replied: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " + edited: "

    {{username}} {{description}}

    " + liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " + liked_many: + one: "

    {{username}}, {{username2}} and 1 máis {{description}}

    " + other: "

    {{username}}, {{username2}} e {{count}} máis {{description}}

    " + private_message: "

    {{username}} {{description}}

    " + invited_to_private_message: "

    {{username}} {{description}}

    " + invited_to_topic: "

    {{username}} {{description}}

    " + invitee_accepted: "

    {{username}} aceptou o teu convite

    " + moved_post: "

    {{username}} moveu {{description}}

    " + linked: "

    {{username}} {{description}}

    " + granted_badge: "

    Obtiveches «{{description}}»

    " + group_message_summary: + one: "

    {{count}} mensaxe na caixa do correo de {{group_name}}

    " + other: "

    {{count}} mensaxes na caixa do correo de {{group_name}}

    " + alt: + mentioned: "Mencionado por" + quoted: "Citado por" + replied: "Respondido" + posted: "Publicado por" + edited: "A túa publicación ediotuna" + liked: "Gustoulles a túa publicación" + private_message: "Mensaxe privada de" + invited_to_private_message: "Convidado a unha mensaxe privada de" + invited_to_topic: "Convidado a un tema de" + invitee_accepted: "Convite aceptado por" + moved_post: "A túa publicación foi movida por" + linked: "Ligazón á túa publicación" + granted_badge: "Insignias concedidas" + group_message_summary: "Mensaxes na caixa do grupo" + popup: + mentioned: '{{username}} mencionoute en "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} mencionoute en "{{topic}}" - {{site_title}}' + quoted: '{{username}} citoute en "{{topic}}" - {{site_title}}' + replied: '{{username}} respondeute en "{{topic}}" - {{site_title}}' + posted: '{{username}} publicou en "{{topic}}" - {{site_title}}' + private_message: '{{username}} enviouche unha mensaxe privada en "{{topic}}" - {{site_title}}' + linked: '{{username}} ligou a túa publicación desde "{{topic}}" - {{site_title}}' + upload_selector: + title: "Engadir unha imaxe" + title_with_attachments: "Engadir imaxe ou ficheiro" + from_my_computer: "Desde o meu dispositivo" + from_the_web: "Desde a web" + remote_tip: "ligazón á imaxe" + remote_tip_with_attachments: "ligazón á imaxe ou ficheiro {{authorized_extensions}}" + local_tip: "seleccionar imaxes do teu dispositivo" + local_tip_with_attachments: "selecciona imaxes ou ficheiros do teu dispositivo {{authorized_extensions}}" + hint: "(tamén podes arrastrar e soltar no editor para envialos)" + hint_for_supported_browsers: "tamén podes arrastrar e soltar ou pegar imaxes no editor" + uploading: "Enviando" + select_file: "Seleccionar ficheiro" + image_link: "ligazón onde levará a túa imaxe" + search: + sort_by: "Ordenar por" + relevance: "Relevancia" + latest_post: "Últimas publicacións" + most_viewed: "Máis vistos" + most_liked: "Con máis Gústames" + select_all: "Seleccionar todo" + clear_all: "Borrar todo" + result_count: + one: "Un resultado para \"{{term}}\"" + other: "{{count}} resultados para \"{{term}}\"" + title: "buscar temas, publicacións, usuarios ou categorías" + no_results: "Non se atoparon resultados." + no_more_results: "Non se atoparon máis resultados." + search_help: Buscar axuda + searching: "Buscando..." + post_format: "#{{post_number}} de {{username}}" + context: + user: "Buscar publicacións de @{{username}}" + category: "Buscar na categoría \"{{category}}\"" + topic: "Buscar neste tema" + private_messages: "Buscar mensaxes" + hamburger_menu: "ir a outra lista de temas ou categoría" + new_item: "novo" + go_back: 'volver' + not_logged_in_user: 'páxina do usuario cun resumo das actividades e preferencias actuais' + current_user: 'ir á túa páxina do usuario' + topics: + bulk: + unlist_topics: "Retirar temas da lista" + reset_read: "Restabelecer Lidos" + delete: "Eliminar temas" + dismiss: "Desbotar" + dismiss_read: "Desbotar os non lidos" + dismiss_button: "Desbotar..." + dismiss_tooltip: "Desbotar só as publicacións novas ou deixar de seguir temas" + also_dismiss_topics: "Deter o seguimento destes temas para que non se me amosen como non lidos" + dismiss_new: "Desbotar novas" + toggle: "cambiar a selección en bloque dos temas" + actions: "Accións en bloque" + change_category: "Cambiar categoría" + close_topics: "Pechar temas" + archive_topics: "Arquivar temas" + notification_level: "Cambiar o nivel de notificación" + choose_new_category: "Seleccionar a nova categoría dos temas:" + selected: + one: "Seleccionaches un tema." + other: "Seleccionaches {{count}} temas." + none: + unread: "Non tes temas sen ler." + new: "Non tes novos temas." + read: "Aínda non liches ningún tema." + posted: "Aínda non publicaches en ningún tema." + latest: "Non hai últimos temas. Triste." + hot: "Non hai temas quentes." + bookmarks: "Aínda non marcaches este tema." + category: "Non hai temas en {{category}}." + top: "Non hai temas destacados." + search: "Non hai resultados da busca." + educate: + new: '

    Aquí aparecen os teus temas novos.

    De xeito predeterminado, os temas considéranse novos e amosan un indicador novo se se crearon nos últimos dous días.

    Podes ir ás preferencias para cambiar este axuste.

    ' + unread: '

    Os teus temas sen ler aparecen aquí.

    De xeito predeterminado, os temas considéranse sen ler e amosarase o número dos non lidos. 1 se ti:

    • Creaches o tema
    • Respondiches o tema
    • Liches o tema durante máis de catro minutos

    Ou estabeleciches o tema para ser Seguido ou Visto no control de notificacións na banda inferior de cada tema.

    Vai ás túas preferencias se queres cambiar isto.

    ' + bottom: + latest: "Non hai máis últimos temas." + hot: "Non hai máis temas quentes." + posted: "Non hai máis temas publicados." + read: "Non hai máis temas lidos." + new: "Non hai máis temas novos." + unread: "Non hai máis temas sen ler." + category: "Non hai máis temas en {{category}}." + top: "Non hai máis temas destacados." + bookmarks: "Non hai máis temas marcados." + search: "Non hai máis resultados da busca." + topic: + unsubscribe: + stop_notifications: "Agora recibirás menos notificacións sobre {{title}}" + change_notification_state: "O estado actual das túas notificacións é" + filter_to: "{{post_count}} publicacións no tema" + create: 'Novo tema' + create_long: 'Crear un novo tema' + private_message: 'Iniciar unha mensaxe' + archive_message: + help: 'Mover mensaxes ao arquivo' + title: 'Arquivo' + move_to_inbox: + title: 'Mover á caixa de entrada' + help: 'Mover mensaxes á caixa de entrada' + list: 'Temas' + new: 'novo tema' + unread: 'sen ler' + new_topics: + one: 'Un tema novo' + other: '{{count}} temas novos' + unread_topics: + one: 'Un tema sen ler' + other: '{{count}} temas sen ler' + title: 'Tema' + invalid_access: + title: "O tema é privado" + description: "Sentímolo pero non tes acceso a este tema." + login_required: "Debes iniciar sesión para ver este tema." + server_error: + title: "A carga do tema fallou" + description: "Sentímolo pero non podemos cargar este tema, posibelmente debido a problemas de conexión. Ténato de novo e se o problema continúa fáinolo saber." + not_found: + title: "Non foi posíbel atopar o tema" + description: "Sentímolo pero non foi posíbel atopar este tema. Quizais foi eliminado por un moderador." + total_unread_posts: + one: "Tes unha publicación sen ler neste tema" + other: "Tes {{count}} publicacións sen ler neste tema" + unread_posts: + one: "Tes unha publicación antiga sen ler neste tema" + other: "Tes {{count}} publicacións antigas sen ler neste tema" + new_posts: + one: "hai unha nova publicación neste tema desde a túa última lectura" + other: "hai {{count}} novas publicacións neste tema desde a túa última lectura" + likes: + one: "hai un gústame neste tema" + other: "hai {{count}} gústames neste tema" + back_to_list: "Volver á lista de temas" + options: "Opcións de temas" + show_links: "amosar as ligazóns cara este tema" + toggle_information: "cambiar detalles do tema" + read_more_in_category: "Queres ler máis? explora outros temas en {{catLink}} ou {{latestLink}}." + read_more: "Queres ler máis? {{catLink}} ou {{latestLink}}." + read_more_MF: "Hai { UNREAD, plural, =0 {} one { 1 sen ler } other { # sen ler } } { NEW, plural, =0 {} one { {BOTH, select, true{e} false { } other{}} 1 novo topic} other { {BOTH, select, true{e} false { } other{}} # novos topics} } restantes, ou {CATEGORY, select, true {explora outros temas en {catLink}} false {{latestLink}} other {}}" + browse_all_categories: Explorar todas as categorías + view_latest_topics: ver últimos temas + suggest_create_topic: Porque non crear un tema? + jump_reply_up: ir a unha resposta anterior + jump_reply_down: ir a unha resposta posterior + deleted: "Eliminouse o tema" + auto_close_notice: "Este tema pechará automaticamente en %{timeLeft}." + auto_close_notice_based_on_last_post: "Este tema pechará %{duration} despois da última resposta." + auto_close_title: 'Axustes do peche automático' + auto_close_save: "Gardar" + auto_close_remove: "arriba" + auto_close_immediate: "A última publicación deste tema xa ten %{hours} horas. O tema pecharase inmediatamente." + progress: + title: progreso do tema + go_top: "principio" + go_bottom: "final" + go: "ir" + jump_bottom: "ir á última publicación" + jump_bottom_with_number: "ir á publicación %{post_number}" + total: publicacións totais + current: publicación actual + position: "publicación %{current} de %{total}" + notifications: + reasons: + '3_6': 'Recibirás notificacións porque estás vendo esta categoría.' + '3_5': 'Recibirás notificacións porque comezaches a ver este tema automaticamente.' + '3_2': 'Recibirás notificacións porque estás vendo este tema.' + '3_1': 'Recibirás notificacións por ser o creador deste tema.' + '3': 'Recibirás notificacións porque estás vendo este tema.' + '2_8': 'Recibirás notificacións porque segues esta categoría.' + '2_4': 'Recibirás notificacións porque publicaches unha resposta neste tema.' + '2_2': 'Recibirás notificacións porque segues este tema.' + '2': 'Recibirás notificacións porque liches este tema.' + '1_2': 'Notificarémosche se alguén menciona o teu @nome ou che responde.' + '1': 'Notificarémosche se alguén menciona o teu @nome ou che responde.' + '0_7': 'Estás ignorando todas as notificacións desta categoría.' + '0_2': 'Estás ignorando todas as notificacións deste tema.' + '0': 'Estás ignorando todas as notificacións deste tema.' + watching_pm: + title: "Ver" + description: "Recibirás notificacións de cada resposta a esta mensaxe e aparecerá o número de novas respostas." + watching: + title: "Ver" + description: "Notificaránseche as respostas recibidas neste tema e amosarase o número de novas respostas." + tracking_pm: + title: "Seguimento" + description: "Amosarase o número de novas respostas desta mensaxe. Notificaránseche as mencións ao teu @name ou cando alguén che responda." + tracking: + title: "Seguimento" + description: "Amosarase o número de novas respostas para este tema. Notificaránseche as mencións ao teu @name ou cando alguén che responda." + regular: + title: "Normal" + description: "Notificarémosche se alguén menciona o teu @nome ou che responde." + regular_pm: + title: "Normal" + description: "Notificarémosche se alguén menciona o teu @nome ou che responde." + muted_pm: + title: "Silenciado" + description: "Non recibirás ningunha notificación sobre esta mensaxe." + muted: + title: "Silenciado" + description: "Non se che notificará nada sobre este tema e non aparecerá no listado de últimos." + actions: + recover: "Recuperar tema" + delete: "Eliminar tema" + open: "Abrir tema" + close: "Pechar tema" + multi_select: "Seleccionar publicacións..." + auto_close: "Pechar automaticamente..." + pin: "Pegar tema..." + unpin: "Despegar tema..." + unarchive: "Desarquivar tema" + archive: "Arquivar tema" + invisible: "Retirar da lista" + visible: "Engadir á lista" + reset_read: "Restabelecer datos de lecturas" + feature: + pin: "Pegar tema" + unpin: "Despegar tema" + pin_globally: "Pegar tema globalmente" + make_banner: "Tema do báner" + remove_banner: "Eliminar o tema do báner" + reply: + title: 'Responder' + help: 'responder a este tema' + clear_pin: + title: "Borrar o estado Pegar" + help: "Borra o estado Pegado deste tema para que non apareza na banda superior da lista de temas." + share: + title: 'Compartir' + help: 'compartir unha ligazón a este tema' + flag_topic: + title: 'Denunciar' + help: 'denunciar privadamente este tema para revisalo ou enviar unha notificación privada sobre el' + success_message: 'Denunciaches o tema correctamente.' + feature_topic: + title: "Destacar este tema" + pin: "Facer que este tema apareza no alto da categoría {{categoryLink}} até" + confirm_pin: "Xa tes {{count}} temas pegados. Demasiados temas pegados pode resultar pesado para usuarios novos e anónimos. Confirmas que queres pegar outro tema nesta categoría?" + unpin: "Eliminar este tema da banda superior da categoría {{categoryLink}}." + unpin_until: "Retirar este tema do alto da {{categoryLink}} ou agardar até %{until}." + pin_note: "Os usuarios poden despegar o tema por si mesmos." + pin_validation: "Requírese unha data para pegar este tema." + not_pinned: "Non hai temas pegados en {{categoryLink}}." + already_pinned: + one: "Temas pegados actualmente en {{categoryLink}}: 1" + other: "Temas pegados actualmente en {{categoryLink}}: {{count}}" + pin_globally: "Facer que este tema apareza no alto de todas as listas de temas até" + confirm_pin_globally: "Xa tes {{count}} temas pegados globalmente. Demasiados temas pegados pode resultar pesado para usuarios novos e anónimos. Confirmas que queres pegar outro tema globalmente?" + unpin_globally: "Eliminar este tema da banda superior de todas as listas de temas." + unpin_globally_until: "Eliminar este tema do alto de todas as listas de temas ou agardar até %{until}." + global_pin_note: "Os usuarios poden despegar o tema por si mesmos." + not_pinned_globally: "Non hai temas pegados globalmente." + already_pinned_globally: + one: "Temas pegados globalmente neste intre: 1" + other: "Temas pegados globalmente neste intre: {{count}}" + make_banner: "Facer deste tema un báner que apareza na banda superior de todas as páxinas." + remove_banner: "Eliminar o báner que aparece na banda superior de todas as páxinas." + banner_note: "Os usuarios poden desbotar un báner se o pechan. Unicamente pode haber un tema que sexa un báner ao mesmo tempo." + no_banner_exists: "Non hai tema para o báner." + banner_exists: "Hai actualmente un tema para o báner." + inviting: "Convidando..." + automatically_add_to_groups_optional: "Este convite tamén inclúe o acceso a estes grupos: (opcional, só administradores)" + automatically_add_to_groups_required: "Este convite tamén inclúe o acceso a estes grupos: (Obrigatorio, só administradores)" + invite_private: + title: 'Convidar á mensaxe' + email_or_username: "Nome do usuario ou correo-e do convidado" + email_or_username_placeholder: "correo electrónico e nome do usuario" + action: "Convidar" + success: "Convidamos este usuario a participar nesta mensaxe." + error: "Sentímolo pero houbo un erro convidando este usuario." + group_name: "nome do grupo" + controls: "Controis do tema" + invite_reply: + title: 'Convidar' + username_placeholder: "nome do usuario" + action: 'Enviar convite' + help: 'convidar a outros a este tema por correo electrónico ou notificacións' + to_forum: "Enviaremos un correo electrónico permitindo ao teu amigo que se una inmediatamente ao premer nunha ligazón. Non require iniciar sesión." + sso_enabled: "Introduce o nome do usuario da persoa que desexas convidar a este tema." + to_topic_blank: "Introduce o nome do usuario ou o correo electrónico da persoa que desexas convidar a este tema." + to_topic_email: "Introduciches un enderezo de correo-e. Enviarémosche un convite que permitirá os teus amigos responder inmediatamente a este tema." + to_topic_username: "Introduciches un nome de usuario. Enviarémoslle unha notificación cunha ligazón convidándoo a este tema." + to_username: "Introduce o nome do usuario da persoa que desexas convidar. Enviarémoslle unha notificación cunha ligazón convidándoa a este tema." + email_placeholder: 'name@example.com' + success_email: "Enviamos un convite a {{emailOrUsername}}. Notificarémosche cando utilice a invitación. Mira a lapela de convites na túa páxina de usuario para facer un seguimento das túas invitacións." + success_username: "Convidamos este usuario a participar neste tema." + error: "Sentímolo, non foi posíbel convidar esta persoa. Quizais xa foi convidada? (os convites teñen un límite)" + login_reply: 'Inicia sesión para responder' + filters: + n_posts: + one: "Unha publicación" + other: "{{count}} publicacións" + cancel: "Eliminar filtro" + split_topic: + title: "Mover ao tema novo" + action: "mover ao tema novo" + topic_name: "Nome do tema novo" + error: "Produciuse un erro movendo as publicacións ao novo tema." + instructions: + one: "Vas crear un novo tema e enchelo coa publicación que seleccionaches." + other: "Vas crear un novo tema e enchelo coas {{count}} publicacións que seleccionaches." + merge_topic: + title: "Mover a un tema existente" + action: "mover a un tema existente" + error: "Produciuse un erro movendo publicacións nese tema." + instructions: + one: "Selecciona o tema ao que queres mover esta publicación." + other: "Selecciona o tema ao que queres mover estas {{count}} publicacións." + change_owner: + title: "Cambiar propietario das publicacións" + action: "cambiar propiedade" + error: "Produciuse un erro cambiando a propiedade das publicacións." + label: "Novo propietario das publicacións" + placeholder: "nome do usuario do novo propietario" + instructions: + one: "Selecciona o novo propietario da publicación de {{old_user}}." + other: "Selecciona o novo propietario das {{count}} publicacións de {{old_user}}." + instructions_warn: "Decátate que ningunha notificación sobre esta publicación se transferirá retroactivamente ao novo usuario.
    Aviso: actualmente, non se transfire ao novo usuario ningún dato relacionado cunha publicación. Usa isto con tino." + change_timestamp: + title: "Cambiar a marca data/hora" + action: "cambiar a marca data/hora" + invalid_timestamp: "A marca data/hora non pode ser no futuro." + error: "Produciuse un erro cambiando a marca data/hora do tema." + instructions: "Selecciona a marca data/hora para o tema. As publicacións do tema actualizaranse para ter a mesma diferenza de tempo." + multi_select: + select: 'seleccionar' + selected: 'seleccionados ({{count}})' + select_replies: 'seleccionar +respostas' + delete: eliminar seleccionados + cancel: 'cancelar selección ' + select_all: seleccionar todo + deselect_all: deseleccionar todo + description: + one: Seleccionaches unha publicación. + other: Seleccionaches {{count}} publicacións. + post: + reply: " {{replyAvatar}} {{usernameLink}}" + reply_topic: " {{link}}" + quote_reply: "citar resposta" + edit: "Editando {{link}} {{replyAvatar}} {{username}}" + edit_reason: "Razón:" + post_number: "publicación {{number}}" + last_edited_on: "última edición da publicación" + reply_as_new_topic: "Responder como tema ligado" + continue_discussion: "Continuar a discusión de {{postLink}}:" + follow_quote: "ir á publicación citada" + show_full: "Amosar a publicación completa" + show_hidden: 'Ver o contido oculto.' + deleted_by_author: + one: "(as publicacións retiradas polo autor serán automaticamente eliminadas en %{count} hora, excepto que fosen denunciadas)" + other: "(as publicacións retiradas polo autor serán automaticamente eliminadas en %{count} horas, excepto que fosen denunciadas)" + expand_collapse: "ampliar/reducir" + gap: + one: "ver unha resposta oculta" + other: "ver {{count}} respostas ocultas" + more_links: "{{count}} máis..." + unread: "Publicación sen ler" + has_replies: + one: "{{count}} resposta" + other: "{{count}} respostas" + has_likes: + one: "{{count}} gústame" + other: "{{count}} gústames" + has_likes_title: + one: "A unha persoa gustoulle esta publicación" + other: "A {{count}} persoas gustoulles esta publicación" + has_likes_title_only_you: "gustouche esta publicación" + has_likes_title_you: + one: "A ti e a outro máis gustouvos esta publicación" + other: "A ti e a {{count}} persoas máis gustouvos esta publicación" + errors: + create: "Sentímolo pero produciuse un erro creando a publicación. Téntao de novo." + edit: "Sentímolo pero produciuse un erro editando a publicación. Téntao de novo." + upload: "Sentímolo pero produciuse un erro enviando a publicación. Téntao de novo." + attachment_too_large: "Sentímolo pero o ficheiro é demasiado grande (o tamaño máximo son {{max_size_kb}}kb)." + file_too_large: "Sentímolo pero o ficheiro é demasiado grande (o tamaño máximo son {{max_size_kb}}kb)" + too_many_uploads: "Sentímolo pero só podes enviar un ficheiro de cada vez." + too_many_dragged_and_dropped_files: "Sentímolo pero só podes arrastrar e soltar até 10 ficheiros dunha vez." + upload_not_authorized: "Sentímolo pero o ficheiro que tentas enviar non está autorizado (extensións autorizadas: {{authorized_extensions}})." + image_upload_not_allowed_for_new_user: "Sentímolo pero os novos usuarios non poden subir imaxes." + attachment_upload_not_allowed_for_new_user: "Sentímolo pero os novos usuarios non poden subir anexos." + attachment_download_requires_login: "Sentímolo pero debes iniciar sesión para descargar anexos." + abandon: + confirm: "Confirmas o abandono da túa publicación?" + no_value: "Non, seguir" + yes_value: "Si, abandonar" + via_email: "esta publicación chegou por correo-e" + whisper: "este é un bisbar privado para moderadores" + wiki: + about: "esta publicación é unha wiki" + archetypes: + save: 'Gardar opcións' + controls: + reply: "escribir unha resposta a esta publicación" + like: "gústame esta publicación" + has_liked: "gustouche esta publicación" + undo_like: "desfacer o gústame" + edit: "editar publicación" + edit_anonymous: "Sentímolo pero debes iniciar sesión para editar esta publicación." + flag: "denunciar privadamente esta publicación ou enviar unha notificación privada sobre ela" + delete: "eliminar publicación" + undelete: "recuperar publicación" + share: "compartir ligazón á publicación" + more: "Máis" + delete_replies: + confirm: + one: "Tamén desexas eliminar a resposta directa desta publicación?" + other: "Tamén desexas eliminar as {{count}} respostas directas desta publicación?" + yes_value: "Si, eliminar tamén as respostas" + no_value: "Non, só esta publicación" + admin: "accións admin. nas publicacións" + wiki: "Crear wiki" + unwiki: "Eliminar wiki" + convert_to_moderator: "Engadir cor do Equipo" + revert_to_regular: "Eliminar cor do Equipo" + rebake: "Reconstruír HTML" + unhide: "Non ocultar" + change_owner: "Cambiar propietario" + actions: + flag: 'Denunciar' + defer_flags: + one: "Pospor denuncia" + other: "Pospor denuncias" + it_too: + off_topic: "Denuncialo tamén" + spam: "Denuncialo tamén" + inappropriate: "Denuncialo tamén" + custom_flag: "Denuncialo tamén" + bookmark: "Marcalo tamén" + like: "Gústame tamén" + vote: "Votalo tamén" + undo: + off_topic: "Desfacer denuncia" + spam: "Desfacer denuncia" + inappropriate: "Desfacer denuncia" + bookmark: "Desfacer marcador" + like: "Desfacer o gústame" + vote: "Desfacer voto" + people: + off_topic: "notificado como sen relación co tema" + spam: "denunciou isto como spam" + inappropriate: "denunciou isto como inapropiado" + notify_moderators: "moderadores notificados" + notify_user: "enviou unha mensaxe" + bookmark: "marcou isto" + like: "gustou disto" + vote: "votou por isto" + by_you: + off_topic: "Informaches disto como non relacionado" + spam: "Denunciaches isto como spam" + inappropriate: "Denunciaches isto como inapropiado" + notify_moderators: "Denunciaches isto para moderación" + notify_user: "Enviaches unha mensaxe a este usuario" + bookmark: "Marcaches esta publicación" + like: "Gustouche isto" + vote: "Votaches esta publicación" + by_you_and_others: + off_topic: + one: "Ti e outro máis informastes disto como non relacionado" + other: "Ti e {{count}} máis informastes disto como non relacionado" + spam: + one: "Ti e outro máis denunciastes isto como spam" + other: "Ti e {{count}} máis denunciastes isto com spam" + inappropriate: + one: "Ti e outro máis denunciastes isto como inapropiado" + other: "Ti e {{count}} máis denunciastes isto como inapropiado" + notify_moderators: + one: "Ti e outro máis denunciastes isto para moderación" + other: "Ti e {{count}} máis denunciastes isto para moderación" + notify_user: + one: "Ti e unha persoa máis enviastes unha mensaxe a este usuario" + other: "Ti e {{count}} persoas máis enviastes unha mensaxe a este usuario" + bookmark: + one: "Ti e outra persoa marcastes esta publicación" + other: "Ti e {{count}} persoas máis marcastes esta publicación" + like: + one: "A ti e a un máis gustouvos isto" + other: "A ti e a {{count}} máis gustouvos isto" + vote: + one: "Ti e outra persoa votastes esta publicación" + other: "Ti e {{count}} persoas máis votastes esta publicación" + by_others: + off_topic: + one: "Unha persoa marcou isto como non relacionado" + other: "{{count}} persoas informaron disto como non relacionado" + spam: + one: "Unha persoa marcou isto como spam" + other: "{{count}} persoas denunciaron isto como spam" + inappropriate: + one: "Unha persoa denunciou isto como inapropiado" + other: "{{count}} persoas denunciaron isto como inapropiado" + notify_moderators: + one: "Unha persoa denunciou isto para moderación" + other: "{{count}} persoas denunciaron isto para moderación" + notify_user: + one: "Unha persoa enviou unha mensaxe a este usuario" + other: "{{count}} persoas enviaron unha mensaxe a este usuario" + bookmark: + one: "Unha persoa marcou esta publicación" + other: "{{count}} persoas marcaron esta publicación" + like: + one: "A unha persoa gustoulle isto" + other: "A {{count}} persoas gustoulles isto" + vote: + one: "Unha persoa votou por esta publicación" + other: "{{count}} persoas votaron por esta publicación" + delete: + confirm: + one: "Confirmas a eliminación desta publicación?" + other: "Confirmas a eliminación de todas estas publicacións?" + revisions: + controls: + first: "Primeira revisión" + previous: "Revisión anterior" + next: "Revisión seguinte" + last: "Última revisión" + hide: "Ocultar revisión" + show: "Amosar revisión" + revert: "Reverter a esta revisión" + comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" + displays: + inline: + title: "Amosar o resultado coas adicións e eliminacións inseridas" + button: ' HTML' + side_by_side: + title: "Amosar o resultado coas diferenzas comparadas" + button: ' HTML' + side_by_side_markdown: + title: "Amosar a fonte crúa coas diferenzas comparadas" + button: ' Crúa' + category: + can: 'podes… ' + none: '(sen categoría)' + all: 'Todas as categorías' + choose: 'Seleccionar unha categoría…' + edit: 'editar' + edit_long: "Editar" + view: 'Ver os Temas na Categoría' + general: 'Xeral' + settings: 'Axustes' + topic_template: "Modelo para o tema" + delete: 'Eliminar categoría' + create: 'Nova categoría' + create_long: 'Crear unha nova categoría' + save: 'Gardar categoría' + slug: '«Slug» da Categoría' + slug_placeholder: 'Inserir guións entre palabras para url (opcional) ' + creation_error: Produciuse un erro durante a creación desta categoría. + save_error: Produciuse un erro gardando a categoría. + name: "Nome da categoría" + description: "Descrición" + topic: "tema da categoría" + logo: "Logotipo da categoría" + background_image: "Imaxe do fondo da categoría" + badge_colors: "Cores das insignias" + background_color: "Cor do fondo" + foreground_color: "Cor do primeiro plano" + name_placeholder: "Dúas palabras como máximo" + color_placeholder: "Calquera cor web" + delete_confirm: "Confirmas a eliminación desta categoría?" + delete_error: "Produciuse un erro elimando esta categoría." + list: "Listar categorías" + no_description: "Engade unha descrición a esta categoría." + change_in_category_topic: "Editar a descrición" + already_used: 'Esta cor usouna outra categoría' + security: "Seguranza" + special_warning: "Aviso: esta categoría ten axustes predeterminados e as opcións de seguranza non se poden modificar. Se non queres usala, elimínaa no canto de reciclala." + images: "Imaxes" + auto_close_label: "Pechar automaticamente os temas despois de:" + auto_close_units: "horas" + email_in: "Personalizar enderezos de correos-e entrantes:" + email_in_allow_strangers: "Aceptar correos-e de usuarios anónimos sen contas" + email_in_disabled: "A publicación de novos temas vía correo-e está desactivada nos axustes do sitio. Para activala," + email_in_disabled_click: 'activar o axuste «email in».' + suppress_from_homepage: "Retirar esta categoría da páxina de inicio." + allow_badges_label: "Permitir adxudicar insignias nesta categoría" + edit_permissions: "Editar permisos" + add_permission: "Engadir permisos" + this_year: "este ano" + position: "posición" + default_position: "Posición predeterminada" + position_disabled: "As categorías amosaranse en orde de actividade. Para controlar a orde das categorías nas listas." + position_disabled_click: 'activar o axuste «fixed category positions».' + parent: "Categoría pai" + notifications: + watching: + title: "Ver" + description: "Verás automaticamente todos os novos temas destas categorías. Notificaránseche as novas publicacións de cada tema e amosaráseche o número de novas respostas." + tracking: + title: "Seguimento" + description: "Seguirás automaticamente todos os novos temas destas categorías. Notificaránseche ás mencións ao teu @name e as respostas que recibas, e amosaráseche o número de novas respostas." + regular: + title: "Normal" + description: "Notificarémosche se alguén menciona o teu @nome ou che responde." + muted: + title: "Silenciado" + description: "Non se che notificarán novos temas nestas categorías e non aparecerán nos Últimos." + flagging: + title: 'Grazas por axudar a manter a nosa comunidade.' + action: 'Denunciar publicación' + take_action: "Tomar medidas" + notify_action: 'Mensaxe' + delete_spammer: "Eliminar spammer" + delete_confirm: "Vas borrar %{posts} publicacións e %{topics} temas deste usuario, eliminar a súa conta, bloquear o rexistro desde os seus enderezos IP %{ip_address} e engadir o seu correo-e %{email} a unha lista de bloqueos permanentes. Confirmas que este usuario é un spammer?" + yes_delete_spammer: "Si, eliminar o spammer" + ip_address_missing: "(N/D)" + hidden_email_address: "(oculto)" + submit_tooltip: "Enviar a denuncia privada" + take_action_tooltip: "Alcanzar o limiar de denuncias inmediatamente no canto de agardar por máis denuncias da comunidade" + cant: "Sentímolo pero non podes denunciar esta publicación neste intre." + notify_staff: 'Notificar ao equipo privadamente' + formatted_name: + off_topic: "Non está relacionado" + inappropriate: "É inapropiado" + spam: "É spam" + custom_placeholder_notify_user: "Se específico, construtivo e sempre amábel." + custom_placeholder_notify_moderators: "Especifícanos sobre o que estás preocupado e proporciónanos ligazóns relevantes e exemplos cando sexa posíbel." + custom_message: + at_least: "introduce cando menos {{n}} caracteres" + more: "{{n}} restantes..." + left: "{{n}} restantes" + flagging_topic: + title: "Grazas por axudar a manter a nosa comunidade." + action: "Denunciar tema" + notify_action: "Mensaxe" + topic_map: + title: "Resumo do tema" + participants_title: "Publicadores frecuentes" + links_title: "Ligazóns populares" + links_shown: "amosar as {{totalLinks}} ligazóns..." + clicks: + one: "Un clic" + other: "%{count} clics" + topic_statuses: + warning: + help: "Este é un aviso oficial." + bookmarked: + help: "Marcaches este tema" + locked: + help: "Este tema está pechado, xa non acepta respostas" + archived: + help: "Este tema está arquivado; está conxelado e non se pode cambiar" + locked_and_archived: + help: "Este tema está pechado e arquivado; xa non acepta novas respostas e non se pode cambiar" + unpinned: + title: "Despegado" + help: "Este tema está despegado para vostede; presentarase na orde normal" + pinned_globally: + title: "Pegado globalmente" + help: "Este tema pegouse globalmente; presentarase na banda superior dos máis recentes e na súa categoría" + pinned: + title: "Pegado" + help: "Este tema pegouse globalmente; presentarase na banda superior da súa categoría" + invisible: + help: "Este tema non está listado. Non se presentará nas listas de temas e só estará accesíbel vía ligazón directa" + posts: "Publicacións" + posts_lowercase: "publicacións" + posts_long: "hai {{number}} publicacións neste tema" + posts_likes_MF: | + Este tema ten {count, plural, one {1 resposta} other {# respostas}} {ratio, select, + low {cun alto índice de gústames} + med {cun moi alto índice de gústames} + high {cun extremadamente alto índice de gústames} + other {}} + original_post: "Publicación orixinal" + views: "Vistas" + views_lowercase: + one: "vista" + other: "vistas" + replies: "Respostas" + views_long: "este tema visitouse {{number}} veces" + activity: "Actividade" + likes: "Gústames" + likes_lowercase: + one: "gústame" + other: "gústames" + likes_long: "hai {{number}} gústames neste tema" + users: "Usuarios" + users_lowercase: + one: "usuario" + other: "usuarios" + category_title: "Categoría" + history: "Historial" + changed_by: "por {{author}}" + raw_email: + title: "Fonte do correo" + not_available: "Non dispoñíbel." + categories_list: "Lista de categorías" + filters: + with_topics: "%{filter} temas" + with_category: "Temas de %{filter} %{category}" + latest: + title: "Últimos" + title_with_count: + one: "Último (1)" + other: "({{count}}) últimos" + help: "temas con publicacións recentes" + hot: + title: "Quentes" + help: "unha selección dos temas máis quentes" + read: + title: "Lidos" + help: "temas que liches, partindo da última lectura" + search: + title: "Buscar" + help: "buscar todos os temas" + categories: + title: "Categorías" + title_in: "Categoría - {{categoryName}}" + help: "todos os temas agrupados por categoría" + unread: + title: "Sen ler" + title_with_count: + one: "Un sen ler" + other: "({{count}}) sen ler" + help: "temas con publicacións sen ler que estás vendo ou seguindo" + lower_title_with_count: + one: "Unha sen ler" + other: "{{count}} sen ler" + new: + lower_title_with_count: + one: "Un novo" + other: "{{count}} novos" + lower_title: "novo" + title: "Novo" + title_with_count: + one: "Un novo" + other: "({{count}}) novos" + help: "temas creados nos últimos días" + posted: + title: "As miñas publicacións" + help: "temas nos que publicaches" + bookmarks: + title: "Marcadores" + help: "temas que marcaches" + category: + title: "{{categoryName}}" + title_with_count: + one: "{{categoryName}} (1)" + other: "{{categoryName}} ({{count}})" + help: "últimos temas na categoría {{categoryName}}" + top: + title: "Banda superior" + help: "os temas máis activos no último ano, mes, semana ou día" + all: + title: "De sempre" + yearly: + title: "Anual" + quarterly: + title: "Trimestral" + monthly: + title: "Mensual" + weekly: + title: "Semanal" + daily: + title: "Diario" + all_time: "De sempre" + this_year: "Ano" + this_quarter: "Trimestre" + this_month: "Mes" + this_week: "Semana" + today: "Hoxe" + other_periods: "ver arriba" + browser_update: 'Desgraciadamente, o navegador é demasiado vello para funcionar nesta web. Anóvao.' + permission_types: + full: "Crear / Responder / Ver" + create_post: "Responder / Ver" + readonly: "Ver" + admin_js: + type_to_filter: "escribe para filtrar..." + admin: + title: 'Administrador de Discourse' + moderator: 'Moderador' + dashboard: + title: "Panel" + last_updated: "Última actualización de Panel:" + version: "Versión" + up_to_date: "Estás actualizado." + critical_available: "Está dispoñíbel unha actualización crítica." + updates_available: "Hai actualizacións dispoñíbeis." + please_upgrade: "Por favor actualiza." + no_check_performed: "Non se efectuou unha busca de actualizacións. Asegúrate de que sidekiq está executándose." + stale_data: "Non se efectuou unha busca de actualizacións ultimamente. Asegúrate de que sidekiq está executándose." + version_check_pending: "Parece que actualizaches recentemente. Caralludo!" + installed_version: "Instalado" + latest_version: "Últimos" + problems_found: "Atopáronse algúns problemas coa instalación do Discourse." + last_checked: "Última comprobación" + refresh_problems: "Actualizar" + no_problems: "Non se atoparon problemas." + moderators: 'Moderadores:' + admins: 'Administradores:' + blocked: 'Bloqueados:' + suspended: 'Suspendidos:' + private_messages_short: "Mensaxes" + private_messages_title: "Mensaxes" + mobile_title: "Móbil" + space_free: "{{size}} libres" + uploads: "subidas" + backups: "copias de seguranza" + traffic_short: "Tráfico" + traffic: "Peticións web de aplicativos" + page_views: "Peticións API" + page_views_short: "Peticións API" + show_traffic_report: "Amosar o informe detallado do tráfico" + reports: + today: "Hoxe" + yesterday: "Onte" + last_7_days: "Últimos 7 días" + last_30_days: "Últimos 30 días" + all_time: "De sempre" + 7_days_ago: "Hai 7 días" + 30_days_ago: "Hai 30 días" + all: "Todas" + view_table: "táboa" + view_chart: "gráfica de barras" + refresh_report: "Actualiza informe" + start_date: "Data de inicio" + end_date: "Data de remate" + groups: "Todos os grupos" + commits: + latest_changes: "Últimos cambios: por favor, actualiza a miúdo." + by: "por" + flags: + title: "Denuncias" + old: "Antigo" + active: "Activo" + agree: "Aceptar" + agree_title: "Confirmar esta denuncia como válida" + agree_flag_modal_title: "Aceptar e..." + agree_flag_hide_post: "Aceptar (ocultar publicación + enviar msx. privada)" + agree_flag_hide_post_title: "Ocultar esta publicación e enviar automaticamente unha mensaxe ao usuario para que a edite axiña" + agree_flag_restore_post: "Aceptar (restabelecer publicación)" + agree_flag_restore_post_title: "Restabelecer esta publicación" + agree_flag: "Aceptar denuncia" + agree_flag_title: "Aceptar a denuncia e manter a publicación sen cambios" + defer_flag: "Pospor" + defer_flag_title: "Eliminar esta denuncia; non precisa medidas neste momento." + delete: "Eliminar" + delete_title: "Eliminar a publicación á que se refire esta denuncia." + delete_post_defer_flag: "Eliminar publicación e pospor a denuncia" + delete_post_defer_flag_title: "Eliminar publicación. Se é a inicial, eliminar tamén o tema" + delete_post_agree_flag: "Eliminar a publicación e aceptar a denuncia" + delete_post_agree_flag_title: "Eliminar publicación. Se é a inicial, eliminar tamén o tema." + delete_flag_modal_title: "Eliminar e..." + delete_spammer: "Eliminar spammer" + delete_spammer_title: "Eliminar o usuario e todas as súas publicacións e temas." + disagree_flag_unhide_post: "En desacordo (amosar publicación)" + disagree_flag_unhide_post_title: "Eliminar as denuncias desta publicación e facela visíbel de novo" + disagree_flag: "Non aceptar" + disagree_flag_title: "Denegar esta denuncia por incorrecta" + clear_topic_flags: "Feito" + clear_topic_flags_title: "Este tema investigouse e as incidencias arranxáronse. Preme Feito para eliminar as denuncias." + more: "(máis respostas...)" + dispositions: + agreed: "aceptar" + disagreed: "non aceptar" + deferred: "posposta" + flagged_by: "Denunciado por" + resolved_by: "Arranxado por" + took_action: "Tomadas medidas" + system: "Sistema" + error: "Algo foi mal" + reply_message: "Responder" + no_results: "Non hai denuncias" + topic_flagged: "Este tema foi denunciado." + visit_topic: "Visite o tema para actuar" + was_edited: "A publicación editouse despois da primeira denuncia" + previous_flags_count: "Esta publicación xa se denunciou {{count}} veces." + summary: + action_type_3: + one: "sen relación" + other: "sen relación x{{count}}" + action_type_4: + one: "inapropiado" + other: "inapropiados x{{count}}" + action_type_6: + one: "personalizar" + other: "personalizar x{{count}}" + action_type_7: + one: "personalizar" + other: "personalizar x{{count}}" + action_type_8: + one: "spam" + other: "spam x{{count}}" + groups: + primary: "Grupo primario" + no_primary: "(non hai un grupo primario)" + title: "Grupos" + edit: "Editar grupos" + refresh: "Actualizar" + new: "Novo" + selector_placeholder: "escribe o nome do usuario" + name_placeholder: "Nome do grupo sen espazos, como na regra do nome do usuario" + about: "Edita aquí a túa pertenza a un grupo e nomes" + group_members: "Membros do grupo" + delete: "Eliminar" + delete_confirm: "Eliminar este grupo?" + delete_failed: "Non é posíbel eliminar o grupo. Se este é un grupo automático, non se pode destruír." + delete_member_confirm: "Queres eliminar a «%{username}» do grupo «%{group}»?" + delete_owner_confirm: "Eliminar os privilexios de usuario de «%{username}»?" + name: "Nome" + add: "Engadir" + add_members: "Engadir membros" + custom: "Personalizar" + bulk_complete: "Engadíronse os usuarios ao grupo." + bulk: "Engadir ao grupo en bloque" + bulk_paste: "Pegar unha lista de nomes de usuario ou correos-e, un por liña:" + bulk_select: "(seleccionar un grupo)" + automatic: "Automático" + automatic_membership_email_domains: "Os usuarios que se rexistraron cun dominio de correo electrónico que coincida exactamente con algún da lista engadiranse automaticamente a este grupo:" + automatic_membership_retroactive: "Aplicar a regra do mesmo dominio de correo electrónico para engadir os usuarios rexistrados." + default_title: "Título predeterminado para os usuarios deste grupo" + primary_group: "Estabelecer automaticamente como grupo primario" + group_owners: Propietarios + add_owners: Engadir propietarios + incoming_email: "Personalizar enderezos de correo-e entrantes" + incoming_email_placeholder: "introducir enderezos de correo-e" + api: + generate_master: "Xerar unha chave maestra da API" + none: "Non hai chaves activas da API agora mesmo." + user: "Usuario" + title: "API" + key: "Chave da API" + generate: "Xerar" + regenerate: "Rexenerar" + revoke: "Revogar" + confirm_regen: "Confirmas a substitución da chave da API por unha nova?" + confirm_revoke: "Confirmas a revogación desta chave?" + info_html: "A chave da API permitirache crear e actualizar temas usando chamadas JSON." + all_users: "Todos os usuarios" + note_html: "Manter esta chave en secreto, todos os usuarios que a teñan poderían crear e publicar co nome da calquera usuario." + plugins: + title: "Plugins" + installed: "Plugins instalados" + name: "Nome" + none_installed: "Non tes ningún plugin instalado." + version: "Versión" + enabled: "Activado?" + is_enabled: "S" + not_enabled: "N" + change_settings: "Cambiar axustes" + change_settings_short: "Axustes" + howto: "Como podo instalar un plugin?" + backups: + title: "Copias de seguranza" + menu: + backups: "Copias de seguranza" + logs: "Rexistros" + none: "Non hai copia de seguranza dispoñíbel" + read_only: + enable: + title: "Activar o modo de só-lectura" + label: "Activar modo de só-lectura" + confirm: "Confirmas a activación do modo de só-lectura?" + disable: + title: "Desactivar o modo de só-lectura" + label: "Desactivar modo de só-lectura" + logs: + none: "Aínda non hai rexistros..." + columns: + filename: "Nome do ficheiro" + size: "Tamaño" + upload: + label: "Enviar" + title: "Subir unha copia de seguranza a esta instancia" + uploading: "Enviando..." + success: "«{{filename}}» subiuse correctamente." + error: "Produciuse un erro durante o envío de «{{filename}}»: {{message}}" + operations: + is_running: "Estase executando unha operación..." + failed: "Produciuse un fallo {{operation}} . Revisa os rexistros." + cancel: + label: "Cancelar" + title: "Cancelar a operación actual" + confirm: "Confirmas a cancelación da operación actual?" + backup: + label: "Copia de seguranza" + title: "Crear unha copia de seguranza" + confirm: "Confirmas a execución dunha nova copia de seguranza?" + without_uploads: "Si (non incluír ficheiros)" + download: + label: "Descargar" + title: "Descargar a copia de seguranza" + destroy: + title: "Eliminar a copia de seguranza" + confirm: "Confirmas a destrución desta copia de seguranza?" + restore: + is_disabled: "«Restabelecer» está desactivado nos axustes do sitio." + label: "Restabelecer" + title: "Restabelecer a copia de seguranza" + confirm: "Confirmas a restauración desta copia de seguranza?" + rollback: + label: "Reverter" + title: "Reverter a base de datos ao estado de funcionamento anterior" + confirm: "Confirmas a reversión da base de datos ao estado de funcionamento anterior?" + export_csv: + user_archive_confirm: "Confirmas a descarga das túas publicacións?" + success: "Iniciouse a exportación, notificarémosche cunha mensaxe o remate do proceso." + failed: "Produciuse un fallo na exportación. Comproba os rexistros." + rate_limit_error: "Só se poden descargar as publicacións unha vez por día. Téntao de novo mañá." + button_text: "Exportar" + button_title: + user: "Exportar a lista completa de usuarios en formato CSV." + staff_action: "Exportar o rexistro con todas as accións do equipo en formato CSV." + screened_email: "Exportar a lista de correos-e controlados en formato CSV." + screened_ip: "Exportar a lista de IP controladas en formato CSV." + screened_url: "Exportar a lista de URL controladas en formato CSV." + export_json: + button_text: "Exportar" + invite: + button_text: "Enviar convites" + button_title: "Enviar convites" + customize: + title: "Personalizar" + long_title: "Personalización do sitio" + css: "CSS" + header: "Cabeceira" + top: "Banda superior" + footer: "Pé de páxina" + embedded_css: "CSS encaixado" + head_tag: + text: "" + title: "HTML que se inserirá antes da etiqueta " + body_tag: + text: "" + title: "HTML que se inserirá antes da etiqueta " + override_default: "Non incluír folla de estilo estándar" + enabled: "Activado?" + preview: "previsualizar" + undo_preview: "eliminar previsualización" + rescue_preview: "estilo predeterminado" + explain_preview: "Ver o sitio con esta folla de estilo personalizada" + explain_undo_preview: "Volver á folla de estilo personalizada activada actualmente" + explain_rescue_preview: "Ver o sitio coa folla de estilo predeterminada" + save: "Gardar" + new: "Novo" + new_style: "Novo estilo" + import: "Importar" + import_title: "Seleccionar un ficheiro ou pegar un texto" + delete: "Eliminar" + delete_confirm: "Queres eliminar esta personalización?" + about: "Modificar as follas de estilo CSS e as cabeceiras HTML do sitio. Engadir unha personalización para comezar." + color: "Cor" + opacity: "Opacidade" + copy: "Copiar" + email_templates: + title: "Modelos de correo-e" + subject: "Asunto" + multiple_subjects: "Este modelo de correo-e ten varios asuntos." + body: "Corpo" + none_selected: "Selecciona un modelo de correo-e para comezar a edición." + revert: "Reverter os cambios" + revert_confirm: "Confirmas a reversión dos cambios?" + css_html: + title: "CSS/HTML" + long_title: "Personalizacións do CSS e do HTML" + colors: + title: "Cores" + long_title: "Esquemas de cor" + about: "Modifica as cores usadas no sitio sen ter que escribir en CSS. Engade un esquema para comezar." + new_name: "Novo esquema de cores" + copy_name_prefix: "Copiar de" + delete_confirm: "Queres eliminar este esquema de cor?" + undo: "desfacer" + undo_title: "Desfai os teus cambio nesta cor desde a última vez que a gardaches." + revert: "reverter" + revert_title: "Restabelecer o esquema de cor ao predeterminado de Discourse." + primary: + name: 'primario' + description: 'Principalmente texto, iconas e bordos.' + secondary: + name: 'secundario' + description: 'Cor principal do fondo e cor do texto dalgúns botóns.' + tertiary: + name: 'terciario' + description: 'Ligazóns, algúns botóns, notificacións e cor de resalte.' + quaternary: + name: "cuaternario" + description: "Ligazóns de navegación" + header_background: + name: "Fondo da cabeceira" + description: "Cor do fondo na cabeceira do sitio." + header_primary: + name: "cabeceira primaria" + description: "Texto e iconas na cabeceira do sitio." + highlight: + name: 'resaltes' + description: 'Cor do fondo dos elementos resaltados da páxina, como publicacións e temas.' + danger: + name: 'perigo' + description: 'Cor de resalte para accións como eliminar publicacións e temas.' + success: + name: 'correcto' + description: 'Usado para indicar que unha acción se realizou correctamente.' + love: + name: 'gústame' + description: "Cor do botón Gústame." + email: + title: "Correos electrónicos" + settings: "Axustes" + templates: "Modelos" + preview_digest: "Previsualización do compendio" + sending_test: "Enviando correo-e de proba..." + error: "ERRO - %{server_error}" + test_error: "Produciuse un problema enviando o correo-e de proba. Revisa os teus axustes de correo electrónico, comproba que o teu host non está bloqueando as conexións de correo e téntao de novo." + sent: "Enviado" + skipped: "Saltado" + received: "Recibidos" + rejected: "Rexeitado" + sent_at: "Enviado ás" + time: "Hora" + user: "Usuario" + email_type: "Tipo de correo-e" + to_address: "Ao enderezo" + test_email_address: "enderezo de correo-e de proba" + send_test: "Enviar correo-e de proba" + sent_test: "enviado!" + delivery_method: "Metodo de entrega" + preview_digest_desc: "Previsualiza o contido dos correos-e compendio enviados a usuarios inactivos." + refresh: "Actualizar" + format: "Formato" + html: "html" + text: "texto" + last_seen_user: "Último usuario visto:" + reply_key: "Tecla para responder" + skipped_reason: "Saltar razón" + incoming_emails: + from_address: "De" + to_addresses: "A" + cc_addresses: "Cc" + subject: "Asunto" + error: "Erro" + none: "Non se atoparon correos entrantes." + modal: + title: "Detalles dos correos-e entrantes" + error: "Erro" + subject: "Asunto" + body: "Corpo" + rejection_message: "Correo-e de rexeitamento" + filters: + from_placeholder: "de@exemplo.com" + to_placeholder: "a@exemplo.com" + cc_placeholder: "cc@exemplo.com" + subject_placeholder: "Asunto..." + error_placeholder: "Erro" + logs: + none: "Non se atoparon rexistros." + filters: + title: "Filtro" + user_placeholder: "nome de usuario" + address_placeholder: "nome@exemplo.com" + type_placeholder: "compendio, rexistro..." + reply_key_placeholder: "tecla para responder" + skipped_reason_placeholder: "razón" + logs: + title: "Rexistros" + action: "Acción" + created_at: "Creado" + last_match_at: "Último resultado" + match_count: "Resultados" + ip_address: "IP" + topic_id: "ID do tema" + post_id: "ID da publicación" + category_id: "ID da categoría" + delete: 'Eliminar' + edit: 'Editar' + save: 'Gardar' + screened_actions: + block: "bloquear" + do_nothing: "non facer nada" + staff_actions: + title: "Accións do equipo" + instructions: "Premer nos nomes dos usuarios e nas accións para filtrar a lista. Premer nas imaxes dos perfís para ir ás páxinas dos usuarios." + clear_filters: "Amosar todo" + staff_user: "Usuario do equipo" + target_user: "Usuario obxectivo" + subject: "Asunto" + when: "Cando" + context: "Contexto" + details: "Detalles" + previous_value: "Anterior" + new_value: "Novo" + diff: "Diferenzas" + show: "Amosar" + modal_title: "Detalles" + no_previous: "Non hai ningún valor previo." + deleted: "Non hai ningún valor. O rexistro foi eliminado." + actions: + delete_user: "eliminar usuario" + change_trust_level: "cambiar nivel de confianza" + change_username: "cambiar nome do usuario" + change_site_setting: "cambiar axuste do sitio" + change_site_customization: "cambiar a personalización do sitio" + delete_site_customization: "eliminar a personalización do sitio" + change_site_text: "cambiar o texto do sitio" + suspend_user: "suspender usuario" + unsuspend_user: "non suspender usuario" + grant_badge: "conceder insignia" + revoke_badge: "revogar insignia" + check_email: "comprobar correo-e" + delete_topic: "eliminar tema" + delete_post: "eliminar publicación" + impersonate: "suplantar" + anonymize_user: "facer o usuario anónimo" + roll_up: "encartar os bloques de IP" + change_category_settings: "cambiar axustes da categoría" + delete_category: "eliminar categoría" + create_category: "crear categoría" + block_user: "bloquear usuario" + unblock_user: "desbloquear usuario" + grant_admin: "conceder administración" + revoke_admin: "revogar administración" + grant_moderation: "conceder moderación" + revoke_moderation: "revogar moderación" + backup_operation: "operación de copia de seguranza" + screened_emails: + title: "Correos-e controlados" + description: "Cando alguén tente crear unha nova conta, comprobaranse os seguintes enderezos de correo electrónico e bloquearase o rexistro ou se tomará outra medida." + email: "Enderezo de correo-e" + actions: + allow: "Permitir" + screened_urls: + title: "URL controladas" + description: "As URL listadas aquí usáronse en publicacións de usuarios que foron identificados como spammers." + url: "URL" + domain: "Dominio" + screened_ips: + title: "IP controladas" + description: 'Enderezos IP observados. Usa «Permitir» para engadilos á lista branca.' + delete_confirm: "Confirmas a eliminación da regra para %{ip_address}?" + roll_up_confirm: "Confirmas que queres agrupar en subredes os enderezos IP controlados comunmente?" + rolled_up_some_subnets: "Agrupáronse correctamente en subredes as entradas de IP para bloquear: %{subnets}." + rolled_up_no_subnet: "Non hai nada que agrupar." + actions: + block: "Bloquear" + do_nothing: "Permitir" + allow_admin: "Permitir administrador" + form: + label: "Novo:" + ip_address: "Enderezo IP" + add: "Engadir" + filter: "Buscar" + roll_up: + text: "Agrupar" + title: "Crea unha nova subrede de entradas para bloquear se hai cando menos «min_ban_entries_for_roll_up» entradas." + logster: + title: "Rexistros de erros" + impersonate: + title: "Suplantar" + help: "Usar esta ferramenta para suplantar unha conta de usuario co obxecto de detectar e corrixir erros. Deberás saír da sesión ao rematar." + not_found: "Non é posíbel atopar o usuario." + invalid: "Sentímolo pero non podes suplantar este usuario." + users: + title: 'Usuarios' + create: 'Engadir usuario administrador' + last_emailed: "Últimos envíos por correo-e" + not_found: "Sentímolo pero o nome do usuario non existe no sistema." + id_not_found: "Sentímolo pero o usuario non existe no sistema." + active: "Activo" + show_emails: "Amosar correos-e" + nav: + new: "Novo" + active: "Activo" + pending: "Pendente" + staff: 'Equipo' + suspended: 'Suspendido' + blocked: 'Bloqueado' + suspect: 'Sospeitoso' + approved: "Aprobado?" + approved_selected: + one: "aprobar usuario" + other: "aprobar os ({{count}}) usuarios" + reject_selected: + one: "rexeitar usuario" + other: "rexeitar os ({{count}}) usuarios" + titles: + active: 'Usuarios activos' + new: 'Novos usuarios' + pending: 'Usuarios pendentes de revisión' + newuser: 'Usuarios cun nivel de confianza 0 (novo usuario)' + basic: 'Usuarios cun nivel de confianza 1 (usuario básico)' + member: 'Usuarios cun nivel de confianza 2 (membro)' + regular: 'Usuarios cun nivel de confianza 3 (normal)' + leader: 'Usuarios cun nivel de confianza 4 (líder)' + staff: "Equipo" + admins: 'Usuarios administradores' + moderators: 'Moderadores' + blocked: 'Usuarios bloqueados' + suspended: 'Usuarios suspendidos' + suspect: 'Usuarios sospeitosos' + reject_successful: + one: "Rexeitouse un usuario correctamente." + other: "Rexeitáronse %{count} usuarios correctamente." + reject_failures: + one: "Produciuse un fallo rexeitando o usuario." + other: "Produciuse un fallo rexeitando os %{count} usuarios." + not_verified: "Sen verificar" + check_email: + title: "Amosar o enderezo de correo-e deste usuario" + text: "Amosar" + user: + suspend_failed: "Algo fallou rexeitando este usuario {{error}}" + unsuspend_failed: "Algo foi mal levantando a suspensión deste usuario {{error}}" + suspend_duration: "Canto tempo estará suspendido o usuario?" + suspend_duration_units: "(días)" + suspend_reason_label: "Cal é o motivo da suspensión? Este texto será visíbel para todo o mundo na páxina do perfil deste usuario e amosaráselle ao usuario cando tente iniciar sesión. Procura ser breve." + suspend_reason: "Razón" + suspended_by: "Suspendido por" + delete_all_posts: "Eliminar todas as publicacións" + delete_all_posts_confirm: "Confirmas a eliminación de %{posts} publicacións e %{topics} temas?" + suspend: "Suspender" + unsuspend: "Non suspender" + suspended: "Suspendido?" + moderator: "Moderador?" + admin: "Administrador?" + blocked: "Bloqueado?" + staged: "Transitorio?" + show_admin_profile: "Administración" + edit_title: "Editar título" + save_title: "Gardar título" + refresh_browsers: "Forzar a actualización do navegador" + refresh_browsers_message: "Mensaxe enviada a todos os clientes." + show_public_profile: "Amosar o perfil público" + impersonate: 'Suplantar' + ip_lookup: "Busca de IP" + log_out: "Saír da sesión" + logged_out: "O usuario foi desconectado en todos os dispositivos" + revoke_admin: 'Revogar administrador' + grant_admin: 'Facer administrador' + revoke_moderation: 'Revogar moderación' + grant_moderation: 'Conceder moderación' + unblock: 'Desbloquear' + block: 'Bloquear' + reputation: Reputación + permissions: Permisos + activity: Actividade + like_count: Gústames dados / Recibidos + last_100_days: 'nos últimos 100 días' + private_topics_count: Temas privados + posts_read_count: Publicacións lidas + post_count: Publicacións creadas + topics_entered: Temas vistos + flags_given_count: Denuncias dadas + flags_received_count: Denuncias recibidas + warnings_received_count: Avisos recibidos + flags_given_received_count: 'Denuncias dadas / Recibidas' + approve: 'Aprobar' + approved_by: "aprobado por" + approve_success: "Usuario aprobado, enviouse un correo-e coas instrucións de activación." + approve_bulk_success: "Todos os usuarios seleccionados foron aprobados e notificados." + time_read: "Tempo de lectura" + anonymize: "Facer o usuario anónimo" + anonymize_confirm: "Confirmas que desexas converter esta conta en anónima? Cambiaranse o nome do usuario e o correo electrónico e restabelecerase toda a información do perfil." + anonymize_yes: "Si, converter a conta en anónima" + anonymize_failed: "Produciuse un problema convertendo a conta en anónima." + delete: "Eliminar usuario" + delete_forbidden_because_staff: "Non é posíbel eliminiar os administradores e moderadores." + delete_posts_forbidden_because_staff: "Non é posíbel eliminar todas as publicacións dos administradores ou moderadores." + delete_forbidden: + one: "Non é posíbel eliminar usuarios se teñen publicacións. Elimina as publicacións antes de eliminar o usuario (non é posíbel eliminar publicacións de máis de %{count} día)" + other: "Non é posíbel eliminar usuarios se teñen publicacións. Elimina as publicacións antes de eliminar o usuario (non é posíbel eliminar publicacións de máis de %{count} días)" + cant_delete_all_posts: + one: "Non é posíbel eliminar todas as publicacións. Algunhas teñen máis de %{count} día. (o axuste delete_user_max_post_age.)" + other: "Non é posíbel eliminar todas as publicacións. Algunhas teñen máis de %{count} días. (o axuste delete_user_max_post_age.)" + cant_delete_all_too_many_posts: + one: "Non é posíbel eliminar todas as publicacións porque o usuario ten máis dunha publicación. (delete_all_posts_max)" + other: "Non é posíbel eliminar todas as publicacións porque o usuario ten máis de %{count} publicacións. (delete_all_posts_max)" + delete_confirm: "CONFIRMAS a eliminación deste usuario? Non se poderá desfacer!" + delete_and_block: "Eliminar e bloquear este correo-e e enderezo IP" + delete_dont_block: "Só eliminar" + deleted: "Eliminouse o usuario." + delete_failed: "Produciuse un erro eliminando este usuario. Asegúrate que se eliminan todas as publicacións antes de tentar eliminar o usuario." + send_activation_email: "Enviar correo-e de activación" + activation_email_sent: "Enviouse un correo electrónico de activación." + send_activation_email_failed: "Produciuse un problema enviando outro correo-e de activación. %{error}" + activate: "Activar conta" + activate_failed: "Produciuse un problema activando o usuario." + deactivate_account: "Desactivar a conta" + deactivate_failed: "Produciuse un problema desactivando o usuario." + unblock_failed: 'Produciuse un problema desbloqueando o usuario.' + block_failed: 'Produciuse un problema bloqueando o usuario.' + block_confirm: 'Confirmas o bloqueo deste usuario? Non poderá crear máis temas nin publicacións.' + block_accept: 'Si, bloquealo' + deactivate_explanation: "Un usuario desactivado debe revalidar o seu correo-e." + suspended_explanation: "Un usuario suspendido non pode iniciar sesión." + block_explanation: "Un usuario bloquedo non pode publicar nin iniciar temas." + stage_explanation: "Un usuario transitorio só pode publicar por correo electrónico en temas específicos." + trust_level_change_failed: "Produciuse un problema cambiando o nivel de confianza do usuario." + suspend_modal_title: "Suspender usuario" + trust_level_2_users: "Usuarios con nivel 2 de confianza" + trust_level_3_requirements: "Requirimentos para o nivel de confianza 3" + trust_level_locked_tip: "o nivel de confianza está bloqueado, o sistema non promocionará nin rebaixará o usuario" + trust_level_unlocked_tip: "o nivel de confianza está desbloqueado, o sistema pode promocionar ou rebaixar o usuario" + lock_trust_level: "Bloquear o nivel de confianza" + unlock_trust_level: "Desbloquear o nivel de confianza" + tl3_requirements: + title: "Requerimentos para o nivel 3 de confianza" + table_title: "Nos últimos %{time_period} días:" + value_heading: "Valor" + requirement_heading: "Requirimento" + visits: "Visitas" + days: "días" + topics_replied_to: "Temas os que respondeu" + topics_viewed: "Temas vistos" + topics_viewed_all_time: "Temas vistos (todo o tempo)" + posts_read: "Publicacións lidas" + posts_read_all_time: "Publicacións lidas (todo o tempo)" + flagged_posts: "Publicacións denunciadas" + flagged_by_users: "Usuarios que denunciaron" + likes_given: "Gústames dados" + likes_received: "Gústames recibidos" + likes_received_days: "Gústames recibidos: por días" + likes_received_users: "Gústames recibidos: usuarios" + qualifies: "Cumpre os requisitos para o nivel de confianza 3." + does_not_qualify: "Non cumpre os requisitos para o nivel de confianza 3." + will_be_promoted: "Será promocionado pronto." + will_be_demoted: "Será rebaixado pronto." + on_grace_period: "Actualmente ne periodo de graza da promoción, non será rebaixado" + locked_will_not_be_promoted: "Nivel de confianza bloqueado. Non se promocionará nunca." + locked_will_not_be_demoted: "Nivel de confianza bloqueado. Non será rebaixado nunca." + sso: + title: "Inicio de sesión simple" + external_id: "ID externo" + external_username: "Nome do usuario" + external_name: "Nome" + external_email: "Correo electrónico" + external_avatar_url: "URL da imaxe do perfil" + user_fields: + title: "Campos do usuario" + help: "Engade campos que os usuarios poidan encher." + create: "Crear un campo de usuario" + untitled: "Sen título" + name: "Nome do campo" + type: "TIpo de campo" + description: "Descrición do campo" + save: "Gardar" + edit: "Editar" + delete: "Eliminar" + cancel: "Cancelar" + delete_confirm: "Confirmas a eliminación deste campo do usuario?" + options: "Opcións" + required: + title: "Requirido para rexistrarse?" + enabled: "obrigatorio" + disabled: "non obrigatorio" + editable: + title: "Editábel despois do rexistro?" + enabled: "editábel" + disabled: "non editábel" + show_on_profile: + title: "Amosar no perfil público?" + enabled: "amosado no perfil" + disabled: "non amosado no perfil" + field_types: + text: 'Campo de texto' + confirm: 'Confirmación' + dropdown: "Despregábel" + site_text: + description: "Podes personalizar calquera texto do teu foro. Comeza por buscar debaixo:" + search: "Busca o texto que queres editar" + title: 'Contido do texto' + edit: 'editar' + revert: "Reverter os cambios" + revert_confirm: "Confirmas a reversión dos cambios?" + go_back: "Volver á busca" + recommended: "Recomendamos personalizar o seguinte texto para axeitalo ás túas necesidades:" + show_overriden: 'Amosar só os cambios' + site_settings: + show_overriden: 'Amosar só os cambios' + title: 'Axustes' + reset: 'restabelecer' + none: 'ningunha' + no_results: "Non se atoparon resultados." + clear_filter: "Borrar" + add_url: "engadir URL" + add_host: "engadir host" + categories: + all_results: 'Todas' + required: 'Obrigatorio' + basic: 'Configuración básica' + users: 'Usuarios' + posting: 'Publicación' + email: 'Correo electrónico' + files: 'Ficheiros' + trust: 'Niveis de confianza' + security: 'Seguranza' + onebox: "Onebox" + seo: 'SEO' + spam: 'Spam' + rate_limits: 'Límites de frecuencia' + developer: 'Desenvolvedor' + embedding: "Encaixado" + legal: "Legal" + uncategorized: 'Outro' + backups: "Copias de seguranza" + login: "Iniciar sesión" + plugins: "Plugins" + user_preferences: "Preferencias do usuario" + badges: + title: Insignias + new_badge: Nova insignia + new: Novo + name: Nome + badge: Insignia + display_name: Nome público + description: Descrición + badge_type: Tipo de insignia + badge_grouping: Grupo + badge_groupings: + modal_title: Grupos de insignias + granted_by: Concedido por + granted_at: Concedido + reason_help: (Ligazón a unha publicación ou tema) + save: Gardar + delete: Eliminar + delete_confirm: Confirmas a eliminación desta insignia? + revoke: Revogar + reason: Razón + expand: Expandir … + revoke_confirm: Confirmas a revogación desta insignia? + edit_badges: Editar insignias + grant_badge: Conceder insignia + granted_badges: Insignias concedidas + grant: Conceder + no_user_badges: "A %{name} non se lle concedeu ningunha insignia." + no_badges: Non hai insignias para conceder. + none_selected: "Selecciona unha insignia para comezar" + allow_title: Permitir que se use a insignia como un título + multiple_grant: Pode concederse múltiples veces + listable: Amosar a insignia na páxina de insignias públicas + enabled: Activar insignia + icon: Icona + image: Imaxe + icon_help: "Usar a clase Font Awesome ou unha URL a unha imaxe" + query: Consulta sobre insignia (SQL) + target_posts: Consulta dirixida a mensaxes + auto_revoke: Executar a consulta de revogación diariamente + show_posts: Amosar a publicación concedendo a insignia na páxina das insignias + trigger: Activador + trigger_type: + none: "Actualizar diariamente" + post_action: "Cando un usuario actúa sobre unha publicación" + post_revision: "Cando un usuario edita ou crea unha publicación" + trust_level_change: "Cando un usuario cambia o nivel de confianza" + user_change: "Cando se crea ou edita un usuario" + preview: + link_text: "Previsualizar as insignias concedidas" + plan_text: "Vista previa do plan da consulta" + modal_title: "Previsualizar a consulta de insignias" + sql_error_header: "Produciuse un erro coa consulta." + error_help: "Busca axuda nas seguintes ligazóns sobre consultas de insignias." + bad_count_warning: + header: "AVISO" + text: "Faltan algunhas mostras para a concesión da insignia. Isto acontece cando a consulta sobre insignias devolve unha ID do usuario, ou de publicacións que non existen. Pode causar resultados inesperados posteriormente. Revisa outra vez a solicitude." + no_grant_count: "Non hai insignias para asignar." + grant_count: + one: "1 insignia para asignar." + other: "%{count} insignias para asignar." + sample: "Mostra:" + grant: + with: %{username} + with_post: %{username} para publicación en %{link} + with_post_time: %{username} para publicación en %{link} o %{time} + with_time: %{username} o %{time} + emoji: + title: "Emoji" + help: "Engade novo emoji que estará dispoñíbel para todos. (Suxestión: arrastra e solta múltiples ficheiros dunha vez)" + add: "Engadir novo Emoji" + name: "Nome" + image: "Imaxe" + delete_confirm: "Confirmas a eliminación do emoji :%{name}:?" + embedding: + get_started: "Se queres encaixar o Discourse noutro sitio web, comeza engadindo o seu host." + confirm_delete: "Confirmas a eliminación deste host?" + sample: "Usa o seguinte código HTML no teu sitio para crear e encaixar temas do Discourse. Substitúe REPLACE_ME pola URL canónica da páxina que recibe o encaixado. " + title: "Encaixado" + host: "Hosts permitidos" + edit: "editar" + category: "Publicación a categoría" + add_host: "Engadir host" + settings: "Axustes para o encaixado" + feed_settings: "Axustes das fontes" + feed_description: "Dotar dunha fonte RSS/ATOM o teu sitio pode mellorar a capacidade de Discourse para importar o teu contido." + crawling_settings: "Axustes do extractor" + crawling_description: "Cando o Discourse crea temas para as túas publicacións, se non existe unha fonte RSS/ATOM, tentará analizar o contido do teu HTML. Ás veces pode ser difícil extraer o contido, por iso damos a posibilidade de especificar as regras do CSS para facilitar a extracción." + embed_by_username: "Nome do usuario para crear o tema" + embed_post_limit: "Número máximo de publicacións a encaixar" + embed_username_key_from_feed: "Clave para extraer da fonte o nome do usuario do discourse" + embed_truncate: "Truncar as publicacións encaixadas" + embed_whitelist_selector: "Selector CSS de elementos permitidos nos encaixados" + embed_blacklist_selector: "Selector CSS para elementos retirados nos encaixados" + feed_polling_enabled: "Importar publicacións vía RSS/ATOM" + feed_polling_url: "URL da fonte RSS/ATOM para facer a extracción" + save: "Gardar axustes de encaixado" + permalink: + title: "Ligazóns permanentes" + url: "URL" + topic_id: "ID do tema" + topic_title: "Tema" + post_id: "ID da publicación" + post_title: "Publicación" + category_id: "ID da categoría" + category_title: "Categoría" + external_url: "URL externa" + delete_confirm: Confirmas a eliminación desta ligazón permanente? + form: + label: "Novo:" + add: "Engadir" + filter: "Buscar (URLou URL externa)" + lightbox: + download: "descargar" + search_help: + title: 'Buscar axuda' + keyboard_shortcuts_help: + title: 'Atallos do teclado' + jump_to: + title: 'Ir a' + home: 'g, h Inicio' + latest: 'g, l Último' + new: 'g, n Novo' + unread: 'g, u Sen ler' + categories: 'g, c Categorías' + top: 'g, t Arriba' + bookmarks: 'g, b Marcadores' + profile: 'g, p Perfil' + messages: 'g, m Mensaxes' + navigation: + title: 'Navegación' + jump: '# Ir á publicación #' + back: 'u Volver' + up_down: 'k/j Mover selección ↑ ↓' + open: 'o ou Intro Abrir tema seleccionado' + next_prev: 'maiús.+j/maiús.+k Sección Seguinte/Anterior' + application: + title: 'Aplicativo' + create: 'c Crear un novo tema' + notifications: 'n Abrir notificacións' + hamburger_menu: '= Abrir o menú hamburguesa' + user_profile_menu: 'p Abrir o menú do usuario' + show_incoming_updated_topics: '. Amosar temas actualizados' + search: '/ Buscar' + help: '? Abrir a axuda do teclado' + dismiss_new_posts: 'x, r Desbotar Novas/Publicacións' + dismiss_topics: 'x, t Desbotar temas' + log_out: 'maiús.+z maiús.+z Saír da sesión' + actions: + title: 'Accións' + bookmark_topic: 'f Cambiar marcar tema' + pin_unpin_topic: 'Maiús+p Pegar/Despegar tema' + share_topic: 'maiús.+s Compartir tema' + share_post: 's Compartir publicación' + reply_as_new_topic: 't Responder como tema ligado' + reply_topic: 'maiús.+r Responder o tema' + reply_post: 'r Responder a publicación' + quote_post: 'q Citar publicación' + like: 'l Gústame a publicación' + flag: '! Denunciar publicación' + bookmark: 'b Marcar publicación' + edit: 'e Editar publicación' + delete: 'd Eliminar publicación' + mark_muted: 'm, m Silenciar tema' + mark_regular: 'm, r Tema normal (predeterminado)' + mark_tracking: 'm, t Seguir tema' + mark_watching: 'm, w Ver tema' + badges: + earned_n_times: + one: "Conseguiu esta insignia unha vez" + other: "Conseguiu esta insignia %{count} veces" + title: Insignias + badge_count: + one: "1 insignia" + other: "%{count} insignias" + more_badges: + one: "1 máis" + other: "%{count} máis" + granted: + one: "1 concedido" + other: "%{count} concedidos" + select_badge_for_title: Selecciona insignia para usar como o teu título + none: "" + badge_grouping: + getting_started: + name: Comezar + community: + name: Comunidade + trust_level: + name: Nivel de confianza + other: + name: Outro + posting: + name: Publicación + google_search: | +

    Buscar no Google

    +

    +

    +

    diff --git a/config/locales/client.he.yml b/config/locales/client.he.yml index 3f931cf4d0d..8572aba7dc3 100644 --- a/config/locales/client.he.yml +++ b/config/locales/client.he.yml @@ -101,7 +101,7 @@ he: one: "אחרי שנה אחת" other: "אחרי {{count}}% שנים" share: - topic: 'שתפו קישור לנושא זה' + topic: 'שתפו קישור לפוסט זה' post: 'פרסום #%{postNumber}' close: 'סגור' twitter: 'שתפו קישור זה בטוויטר' @@ -109,6 +109,9 @@ he: google+: 'שתף קישור זה בגוגל+' email: 'שלח קישור בדוא"ל' action_codes: + split_topic: "פצל את הפוסט %{when}" + invited_user: "%{who} הוזמנ/ה ב-%{when}" + removed_user: "%{who} הוסר/ה ב-%{when}" autoclosed: enabled: 'סגר %{when}' disabled: 'פתח %{when}' @@ -127,9 +130,21 @@ he: visible: enabled: 'נכנס לרשימה %{when}' disabled: 'הוצא מהרשימה %{when}' - topic_admin_menu: "פעולות ניהול לנושא" + topic_admin_menu: "פעולות ניהול לפוסט" emails_are_disabled: "כל הדוא\"ל היוצא נוטרל באופן גורף על ידי מנהל אתר. שום הודעת דוא\"ל, מכל סוג שהוא, תשלח." - edit: 'ערוך את הכותרת והקטגוריה של הנושא' + s3: + regions: + us_east_1: "מזרח ארה\"ב (צפון וירג'יניה)" + us_west_1: "מערב ארה\"ב (צפון קליפורניה)" + us_west_2: "מערב ארה\"ב (ארגון)" + eu_west_1: "האיחוד האירופי (אירלנד)" + eu_central_1: "האיחוד האירופי (פרנקפורט)" + ap_southeast_1: "אסיה הפסיפית (סינגפור)" + ap_southeast_2: "אסיה הפסיפית (סידני)" + ap_northeast_1: "אסיה הפסיפית (טוקיו)" + ap_northeast_2: "אסיה הפסיפית (סיאול)" + sa_east_1: "דרום אמריקה (סאו פאולו)" + edit: 'ערוך את הכותרת והקטגוריה של הפוסט' not_implemented: "סליחה, תכונה זו עדיין לא מומשה!" no_value: "לא" yes_value: "כן" @@ -171,7 +186,7 @@ he: one: "תו אחד" other: "{{count}} תווים" suggested_topics: - title: "נושאים מוצעים" + title: "פוסטים מוצעים" about: simple_title: "אודות" title: "אודות %{title}" @@ -183,7 +198,7 @@ he: last_7_days: "7 הימים האחרונים" last_30_days: "ב-30 הימים האחרונים" like_count: "לייקים" - topic_count: "נושאים" + topic_count: "פוסטים" post_count: "פרסומים" user_count: "חדשים" active_user_count: "משתמשים פעילים" @@ -193,24 +208,24 @@ he: title: "סימניה" clear_bookmarks: "ניקוי סימניות" help: - bookmark: "הקליקו כדי ליצור סימניה לפרסום הראשון בנושא זה" - unbookmark: "הקליקו להסרת כל הסימניות בנושא זה" + bookmark: "הקליקו כדי ליצור סימניה לפרסום הראשון בפוסט זה" + unbookmark: "הקליקו להסרת כל הסימניות בפוסט זה" bookmarks: not_logged_in: "סליחה, עליך להיות מחובר כדי להוסיף פוסט למועדפים" created: "סימנת הודעה זו כמועדפת" not_bookmarked: "קראת הודעה זו, לחץ להוספה למועדפים" last_read: "זו ההודעה האחרונה שקראת, לחץ להוספה למועדפים" remove: "הסר מהמועדפים" - confirm_clear: "האם את/ה בטוחים שאתם מעוניינים לנקות את כל הסימניות מנושא זה?" + confirm_clear: "האם את/ה בטוחים שאתם מעוניינים לנקות את כל הסימניות מפוסט זה?" topic_count_latest: - one: "נושא חדש או עדכון {{count}} ." - other: "{{count}} נושאים חדשים או עדכונים." + one: "פוסט חדש או עדכון {{count}} ." + other: "{{count}} פוסטים חדשים או עדכונים." topic_count_unread: one: "נושא שלא נקרא {{count}}." - other: "{{count}} נושאים שלא נקראו." + other: "{{count}} פוסטים שלא נקראו." topic_count_new: - one: "נושא {{count}} חדש." - other: "{{count}} נושאים חדשים." + one: "פוסט {{count}} חדש." + other: "{{count}} פוסטים חדשים." click_to_show: "הקליקו כדי להציג." preview: "תצוגה מקדימה" cancel: "ביטול" @@ -227,16 +242,17 @@ he: revert: "לחזור" failed: "נכשל" switch_to_anon: "מצב אנונימי" + switch_from_anon: "צא ממצב אנונימי" banner: close: "שחרור באנר זה." edit: "ערוך את הבאנר" choose_topic: - none_found: "לא נמצאו נושאים." + none_found: "לא נמצאו פוסטים." title: - search: "חפש נושא לפי שם, כתובת או מזהה:" - placeholder: "הקלד את כותרת הנושא כאן" + search: "חפש פוסט לפי שם, כתובת או מזהה:" + placeholder: "הקלד את כותרת הפוסט כאן" queue: - topic: "נושא:" + topic: "פוסט:" approve: 'לאשר' reject: 'לדחות' delete_user: 'מחק משתמש' @@ -247,9 +263,8 @@ he: view_pending: "הצג הודעות ממתינות" has_pending_posts: one: " בנושא זה ישנה הודעה אחת הממתינה לאישור" - other: "בנושא זה ישנם {{count}} הודעות הממתינות לאישור" + other: "בפוסט זה ישנם {{count}} הודעות הממתינות לאישור" confirm: "שמור שינויים" - delete_prompt: "אתה בטוח שאתה רוצה למחוק את המשתמש %{username}? פעולה זו תמחק את כל ההודעות , תחסום את הדואר האלקטרוני וכתובת ה-IP של המשתמש." approval: title: "ההודעה זקוקה לאישור" description: "קיבלנו את הודעתך אך נדרש אישור של מנחה לפני שההודעה תוצג, אנא המתן בסבלנות." @@ -258,12 +273,12 @@ he: other: "יש לך {{count}} הודעות ממתינות." ok: "אשר" user_action: - user_posted_topic: "{{user}} פרסם את הנושא" - you_posted_topic: "את/ה פרסמת את הנושא" + user_posted_topic: "{{user}} פרסם את הפוסט" + you_posted_topic: "את/ה פרסמת את הפוסט" user_replied_to_post: "{{user}} הגיב ל: {{post_number}}" you_replied_to_post: "את/ה הגבת ל: {{post_number}}" - user_replied_to_topic: "{{user}} הגיב לנושא הזה" - you_replied_to_topic: "את/ה הגבת לנושא הזה" + user_replied_to_topic: "{{user}} הגיב לפוסט הזה" + you_replied_to_topic: "את/ה הגבת לפוסט הזה" user_mentioned_user: "{{user}} הזכיר את {{another_user}}" user_mentioned_you: "{{user}} הזכיר אותך" you_mentioned_user: "את/ה הזכרת את {{another_user}}" @@ -277,10 +292,10 @@ he: likes_given: "ניתנ/ו" likes_received: "התקבל/ו" topics_entered: "כניסות" - topics_entered_long: "נושאים אליהם נכנסת" + topics_entered_long: "פוסטים אליהם נכנסת" time_read: "זמן קריאה" - topic_count: "נושאים" - topic_count_long: "נושאים שנוצרו" + topic_count: "פוסטים" + topic_count_long: "פוסטים שנוצרו" post_count: "תגובות" post_count_long: "תגובות שפורסמו" no_results: "לא נמצאו תוצאות" @@ -292,6 +307,15 @@ he: one: "משתמש/ת 1" other: "%{count} משתמשים" groups: + empty: + posts: "אין פרסום של חברים בקבוצה זו" + members: "אין חברים בקבוצה זו." + mentions: "אין אזכורים של קבוצה זו." + messages: "אין מסרים לקבוצה זו." + topics: "אין נושא מטעם חברים בקבוצה זו." + add: "הוספה" + selector_placeholder: "הוספת חברים וחברות" + owner: "מנהל" visible: "הקבוצה זמינה לכל המשתמשים" title: one: "קבוצה" @@ -299,7 +323,7 @@ he: members: "חברים" posts: "הודעות" alias_levels: - title: "מי יכול להשתמש בקבוצה זו ככינוי?" + title: "מי יכול/ה לשלוח מסרים ו@לאזכר בקבוצה זו?" nobody: "אף אחד" only_admins: "רק מנהלים" mods_and_admins: "רק מנחים ומנהלים" @@ -308,16 +332,21 @@ he: trust_levels: title: "רמת אמון הניתנת אוטומטית למשתמשים כשהם נוספים:" none: "ללא" + notifications: + watching: + title: "במעקב" + description: "תקבל/י הודעה על כל פרסום במסגרת כל מסר, וסך התשובות יוצג." + tracking: + title: "במעקב" user_action_groups: '1': "לייקים שניתנו" '2': "לייקים שהתקבלו" '3': "מועדפים" - '4': "נושאים" + '4': "פוסטים" '5': "תשובות" '6': "תגובות" '7': "אזכורים" '9': "ציטוטים" - '10': "כוכבים" '11': "עריכות" '12': "פריטים שנשלחו" '13': "דואר נכנס" @@ -336,15 +365,15 @@ he: apply_all: "הפעל" position: "מיקום" posts: "פרסומים" - topics: "נושאים" + topics: "פוסטים" latest: "לאחרונה" latest_by: "לאחרונה על ידי" toggle_ordering: "שנה בקר סדר" subcategories: "תתי קטגוריות" - topic_stats: "מספר הנושאים החדשים." + topic_stats: "מספר הפוסטים החדשים." topic_stat_sentence: - one: "נושא חדש אחד ב-%{unit}." - other: "%{count} נושאים חדשים ב-%{unit}." + one: "פוסט חדש אחד ב-%{unit}." + other: "%{count} פוסטים חדשים ב-%{unit}." post_stats: "מספר ההודעות החדשות." post_stat_sentence: one: "הודעה חדשה אחת ב-%{unit}." @@ -361,11 +390,11 @@ he: username: "שם משתמש" trust_level: "TL" read_time: "זמן צפייה" - topics_entered: "כניסה לנושאים" + topics_entered: "כניסה לפוסטים" post_count: "# פרסומים" confirm_delete_other_accounts: "אתה בטוח שברצונך למחוק חשבונות אלו?" user_fields: - none: "(בחר נושא)" + none: "(בחר אפשרות)" user: said: "{{username}}:" profile: "פרופיל" @@ -388,16 +417,13 @@ he: not_supported: "התראות לא נתמכות בדפדפן זה. מצטערים." perm_default: "הדלק התראות" perm_denied_btn: "הרשאות נדחו" - perm_denied_expl: "נטרלת הראשות עבור התראות. השתמש בדפדפן שלך לאפשר התראות, לאחר מכן לחץ על הכפתור. " disable: "כבה התראות" - currently_enabled: "(כרגע מאופשר)" enable: "אפשר התראות" - currently_disabled: "(כרגע לא מאופשר)" each_browser_note: "הערה: עליך לשנות הגדרה זו עבור כל דפדפן בנפרד." dismiss_notifications: "סימון הכל כנקרא" dismiss_notifications_tooltip: "סימון כל ההתראות שלא נקראו כהתראות שנקראו" disable_jump_reply: "אל תקפצו לפרסומים שלי לאחר שאני משיב/ה" - dynamic_favicon: "הצג את מספר נושאים חדשים/מעודכנים על האייקון של הדפדפן" + dynamic_favicon: "הצג את מספר פוסטים חדשים/מעודכנים על האייקון של הדפדפן" edit_history_public: "אפשרו למשתמשים אחרים לראות את תיקוני הפרסומים שלי" external_links_in_new_tab: "פתח את כל הקישורים החיצוניים בעמוד חדש" enable_quoting: "אפשרו תגובת ציטוט לטקסט מסומן" @@ -410,13 +436,12 @@ he: suspended_notice: "המשתמש הזה מושעה עד לתאריך: {{date}}." suspended_reason: "הסיבה: " github_profile: "גיטהאב" - mailing_list_mode: "שלחו לי דוא\"ל על כל פרסום חדש (אלא אם אשתיק את המעקב אחר הנושא או הקטגוריה)" + mailing_list_mode: "שלחו לי דוא\"ל על כל פרסום חדש (אלא אם אשתיק את המעקב אחר הפוסט או הקטגוריה)" watched_categories: "עוקב" - watched_categories_instructions: "תעקבו באופן אוטומטי אחרי כל הנושאים החדשים בקטגוריות אלה. תקבלו התראה על כל פרסום ונושא חדש." + watched_categories_instructions: "תעקבו באופן אוטומטי אחרי כל הפוסטים החדשים בקטגוריות אלה. תקבלו התראה על כל פרסום ופוסט חדש." tracked_categories: "רגיל+" - tracked_categories_instructions: "בקטגוריות אלה סך הפרסומים החדשים שלא נקראו יופיע לצד שם הנושא." + tracked_categories_instructions: "בקטגוריות אלה סך הפרסומים החדשים שלא נקראו יופיע לצד שם הפוסט." muted_categories: "מושתק" - muted_categories_instructions: "לא תקבלו התראות על נושאים חדשים בקטגוריות אלו, והם לא יופיעו בעמוד הלא נקראו שלך." delete_account: "מחק את החשבון שלי" delete_account_confirm: "אתה בטוח שברצונך למחוק את החשבון? לא ניתן לבטל פעולה זו!" deleted_yourself: "חשבונך נמחק בהצלחה." @@ -426,6 +451,7 @@ he: users: "משתמשים" muted_users: "מושתק" muted_users_instructions: "להשבית כל התראה ממשתמשים אלו" + muted_topics_link: "הצג פוסטים שהוסתרו" staff_counters: flags_given: "סימונים שעוזרים" flagged_posts: "הודעות מסומנות" @@ -434,8 +460,6 @@ he: warnings_received: "אזהרות" messages: all: "הכל" - mine: "שלי" - unread: "לא נקראו" change_password: success: "(דואר אלקטרוני נשלח)" in_progress: "(שולח דואר אלקטרוני)" @@ -480,10 +504,6 @@ he: ok: "נשלח לך דואר אלקטרוני לאישור" invalid: "בבקשה הכנס כתובת דואר אלקטרוני חוקית" authenticated: "כתובת הדואר האלקטרוני שלך אושרה על ידי {{provider}}" - frequency: - zero: "נעדכן אותך מיד בדוא\"ל אם לא קראת את הדבר שעליו אנחנו שולחים אליך דוא\"ל." - one: "נשלח לך דוא\"ל אם לא ראינו אותך כאן בדקה האחרונה." - other: "נשלח לך דוא\"ל אם לא ראינו אותך כאן ב-{{count}} הדקות האחרונות." name: title: "שם" instructions: "שמך המלא (רשות)" @@ -525,20 +545,20 @@ he: every_three_days: "כל שלושה ימים" weekly: "שבועית" every_two_weeks: "כל שבועיים" - email_direct: "שלחו לי דוא\"ל כשמישהו/י מצטטים אותי, מגיבם לפרסום שלי, מזכירים את @שם_המשתמש/ת שלי, או מזמינים אותי לנושא" + email_direct: "שלחו לי דוא\"ל כשמישהו/י מצטטים אותי, מגיבם לפרסום שלי, מזכירים את @שם_המשתמש/ת שלי, או מזמינים אותי לפוסט" email_private_messages: "שלחו לי דוא\"ל כשמישהו/י שולחים לי מסר" email_always: "שלח לי נוטיפקציות מייל גם כשאני פעיל/ה באתר. " other_settings: "אחר" categories_settings: "קטגוריות" new_topic_duration: - label: "נושא יחשב כנושא חדש כאשר" + label: "פוסט יחשב כפוסט חדש כאשר" not_viewed: "עוד לא ראיתי אותם" last_here: "נוצרו מאז הביקור האחרון שלי כאן" after_1_day: "נוצר ביום האחרון" after_2_days: "נוצר במהלך היומיים האחרונים" after_1_week: "נוצר במהלך השבוע האחרון" after_2_weeks: "נוצר בשבועיים האחרונים" - auto_track_topics: "מעקב אוטומטי נושאים אליהם נכנסתי" + auto_track_topics: "מעקב אוטומטי פוסטים אליהם נכנסתי" auto_track_options: never: "אף פעם" immediately: "מיידי" @@ -555,7 +575,9 @@ he: user: "משתמש/ת שהוזמנו" sent: "נשלח" none: "אין הזמנות ממתינות להציג" - truncated: "מראה את {{count}} ההזמנות הראשונות." + truncated: + one: "מראה את ההזמנה הראשונה." + other: "מראה את {{count}} ההזמנות הראשונות." redeemed: "הזמנות נוצלו" redeemed_tab: "נענו" redeemed_tab_with_count: "נוצלו ({{count}})" @@ -563,7 +585,7 @@ he: pending: "הזמנות ממתינות" pending_tab: "ממתין" pending_tab_with_count: "ממתינות ({{count}})" - topics_entered: "נושאים נצפו" + topics_entered: "פוסטים נצפו" posts_read_count: "הודעות נקראו" expired: "פג תוקף ההזמנה." rescind: "הסרה" @@ -606,7 +628,7 @@ he: posted_by: "פורסם על ידי" sent_by: "נשלח על ידי" private_message: "הודעה" - the_topic: "הנושא" + the_topic: "הפוסט" loading: "טוען..." errors: prev_page: "בזמן הניסיון לטעון" @@ -615,11 +637,13 @@ he: server: "שגיאת שרת" forbidden: "תקלת גישה" unknown: "תקלה" + not_found: "העמוד אותו אתה מחפש לא נמצא" desc: network: "אנא בדקו את החיבור שלכם" network_fixed: "נראה שזה חזר לעבוד." server: "קוד שגיאה: {{status}}" forbidden: "אינך רשא/ית לצפות בזה." + not_found: "אופס, ניסינו לטעון עמוד שאיננו קיים." unknown: "משהו השתבש." buttons: back: "חזרה" @@ -630,15 +654,17 @@ he: logout: "נותקת מהמערכת" refresh: "רענן" read_only_mode: - enabled: "מופעל מצב קריאה בלבד. אפשר להמשיך לגלוש באתר, אך חלק מהפעולות עלולות לא לעבוד." login_disabled: "התחברות אינה מתאפשרת כשהאתר במצב קריאה בלבד." + too_few_topics_and_posts_notice: "בוא נתחיל את הדיון הזה! יש כרגע %{currentTopics} / %{requiredTopics} נושאים ו-%{currentPosts} / %{requiredPosts} הודעות. אורחים חדשים צריכים כמה דיונים לקרוא ולהגיב אליהם." + too_few_topics_notice: "בוא נתחיל את הדיון הזה! יש כרגע %{currentTopics} / %{requiredTopics} נושאים. אורחים חדשים צריכים כמה דיונים לקרוא ולהגיב אליהם." + too_few_posts_notice: "בוא נתחיל את הדיון הזה! יש כרגע %{currentPosts} / %{requiredPosts} הודעות. אורחים חדשים צריכים כמה דיונים לקרוא ולהגיב אליהם." learn_more: "למד עוד..." year: 'שנה' - year_desc: 'נושאים שפורסמו ב-365 הימים האחרונים' + year_desc: 'פוסטים שפורסמו ב-365 הימים האחרונים' month: 'חודש' - month_desc: 'נושאים שפורסמו ב-30 הימים האחרונים' + month_desc: 'פוסטים שפורסמו ב-30 הימים האחרונים' week: 'שבוע' - week_desc: 'נושאים שפורסמו ב-7 הימים האחרונים' + week_desc: 'פוסטים שפורסמו ב-7 הימים האחרונים' day: 'יום' first_post: הודעה ראשונה mute: השתק @@ -648,15 +674,20 @@ he: replies_lowercase: one: תגובה other: תגובות + signup_cta: + sign_up: "הרשמה" + hide_session: "הזכר לי מחר" + hide_forever: "לא תודה" + hidden_for_session: "אוקי, אשאל אותך מחר. אתה גם תמיד יכול להשתמש ב'התחבר' כדי ליצור משתמש." + intro: "שלום לך :heart_eyes: זה נראה כאילו אתה נהנה מקריאה אבל אתה לא רשום." + value_prop: "כשאתה נרשם, אנחנו זוכרים בדיוק מה קראת כך כשאתה חוזר אתה ממשיך בדיוק מאיפה שהפסקת. בנוסף אתה תקבל התראות דרך האתר ודרך הדואר האלקטרוני שלך כשפוסטים חדשים נוצרים ועוד משהו, אתה יכול לעשות לייק לפוסטים שאהבת. :heartbeat:" summary: - enabled_description: "אתם צופים בסיכום נושא זה: הפרסומים המעניינים ביותר כפי שסומנו על ידי הקהילה." - description: "ישנן {{count}} תגובות" - description_time: "ישנן {{count}} תגובות, עם הערכת זמן קריאה של כ- {{readingTime}} דקות ." - enable: 'סכם נושא זה' + enabled_description: "אתם צופים בסיכום פוסט זה: הפרסומים המעניינים ביותר כפי שסומנו על ידי הקהילה." + enable: 'סכם פוסט זה' disable: 'הצג את כל ההודעות' deleted_filter: - enabled_description: "נושא זה מכיל פרסומים שנמחקו ולכן אינם מוצגים." - disabled_description: "פרסומים שנמחקו בנושא זה מוצגים כעת." + enabled_description: "פוסט זה מכיל פרסומים שנמחקו ולכן אינם מוצגים." + disabled_description: "פרסומים שנמחקו בפוסט זה מוצגים כעת." enable: "הסתר פרסומים שנמחקו" disable: "הצגת פרסומים שנמחקו" private_message_info: @@ -705,6 +736,9 @@ he: admin_not_allowed_from_ip_address: "אינך יכול/ה להתחבר כמנהל מערכת מכתובת IP זו." resend_activation_email: "יש ללחוץ כאן לשליחת דואר אלקטרוני חוזר להפעלת החשבון." sent_activation_email_again: "שלחנו לך הודעת דואר אלקטרוני נוספת להפעלת החשבון לכתובת {{currentEmail}}. זה יכול לקחת כמה דקות עד שיגיע, לא לשכוח לבדוק את תיבת דואר הזבל." + to_continue: "התחברו בבקשה" + preferences: "אתם צריכים להיות מחוברים כדי לשנות את העדפות המשתמש שלכם." + forgot: "אין לי את פרטי החשבון שלי" google: title: "עם גוגל" message: "התחברות עם גוגל (יש לוודא שחוסם חלונות קופצים אינו פעיל)" @@ -727,14 +761,21 @@ he: google: "גוגל" twitter: "טוויטר" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + more_emoji: "עוד..." + options: "אפשרויות" + whisper: "לחישה" add_warning: "זוהי התראה רשמית." - posting_not_on_topic: "לאיזה נושא רצית להגיב?" + toggle_whisper: "הפעלת Whisper" + posting_not_on_topic: "לאיזה פוסט רצית להגיב?" saving_draft_tip: "שמירה..." saved_draft_tip: "נשמר" saved_local_draft_tip: "נשמר מקומית" - similar_topics: "הנושא שלך דומה ל..." + similar_topics: "הפוסט שלך דומה ל..." drafts_offline: "טיוטות מנותקות" error: title_missing: "יש להזין כותרת." @@ -745,11 +786,11 @@ he: try_like: 'האם ניסית את כפתור ה-' category_missing: "עליך לבחור קטגוריה." save_edit: "שמירת עריכה" - reply_original: "תגובה לנושא המקורי" + reply_original: "תגובה לפוסט המקורי" reply_here: "תגובה כאן" reply: "תגובה" cancel: "ביטול" - create_topic: "יצירת נושא" + create_topic: "יצירת פוסט" create_pm: "הודעה" title: "או לחץ Ctrl+Enter" users_placeholder: "הוספת משתמש" @@ -758,7 +799,7 @@ he: show_edit_reason: "(הוספת סיבת עריכה)" reply_placeholder: "הקלד כאן. השתמש ב Markdown, BBCode או HTML לערוך. גרור או הדבק תמונות." view_new_post: "הצגת את ההודעה החדשה שלך." - saving: "שומר..." + saving: "שומר" saved: "נשמר!" saved_draft: "טיוטאת פרסום בתהליך, לחצו כדי להמשיך." uploading: "מעלה..." @@ -773,6 +814,7 @@ he: link_description: "הזן תיאור קישור כאן" link_dialog_title: "הזן קישור" link_optional_text: "כותרת אופציונלית" + link_placeholder: "http://example.com \"טקסט אופציונלי\"" quote_title: "ציטוט" quote_text: "ציטוט" code_title: "טקסט מעוצב" @@ -785,29 +827,29 @@ he: heading_title: "כותרת" heading_text: "כותרת" hr_title: "קו אופקי" - undo_title: "בטל" - redo_title: "חזור" help: "עזרה על כתיבה ב-Markdown" toggler: "הסתר או הצג את פאנל העריכה" - admin_options_title: "אפשרויות צוות אופציונליות לנושא זה" + modal_ok: "אישור" + modal_cancel: "ביטול" + cant_send_pm: "מצטערים, אינכם יכולים לשלוח הודעה ל %{username}." + admin_options_title: "אפשרויות צוות אופציונליות לפוסט זה" auto_close: - label: "מועד סגירה אוטומטית של נושא:" + label: "מועד סגירה אוטומטית של פוסט:" error: "הזינו בבקשה ערך תקין." - based_on_last_post: "לא לסגור עד שהפרסום האחרון בנושא זה יהיה לפחות בגיל זה." + based_on_last_post: "לא לסגור עד שהפרסום האחרון בפוסט זה יהיה לפחות בגיל זה." all: examples: 'הזינו מספר שעות (24), שעה מדוייקת (17:30) או חותמת זמן (2013-11-22 14:00).' limited: units: "(# מספר שעות)" examples: 'הזינו מספר שעות (24).' notifications: - title: "התראות אודות אזכור @שם, תגובות לפרסומים ולנושאים שלך, הודעות וכו'" + title: "התראות אודות אזכור @שם, תגובות לפרסומים ולפוסטים שלך, הודעות וכו'" none: "לא ניתן לטעון כעת התראות." more: "הצגת התראות ישנות יותר" - total_flagged: "סך הכל נושאים מדוגללים" + total_flagged: "סך הכל פוסטים מדוגללים" mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -826,7 +868,7 @@ he: liked: "אהב את הפרסום שלך" private_message: "הודעה פרטית מ" invited_to_private_message: "הזמנה להודעה פרטית מ" - invited_to_topic: "הוזמנת לנושא חדש מ" + invited_to_topic: "הוזמנת לפוסט חדש מ" invitee_accepted: "הזמנה התקבלה על ידי" moved_post: "הפרסום שלך הוזז על ידי" linked: "קישור לפרסום שלך" @@ -844,18 +886,25 @@ he: from_my_computer: "מהמחשב שלי" from_the_web: "מהאינטרנט" remote_tip: "קישור לתמונה" - remote_tip_with_attachments: "קישור לתמונה או קובץ ({{authorized_extensions}})" + remote_tip_with_attachments: "קישור לתמונה או לקובץ {{authorized_extensions}}" local_tip: "בחר תמונות ממכשירך" - local_tip_with_attachments: "בחר תמונות או קבצים ממכשירך ({{authorized_extensions}})" hint: "(ניתן גם לגרור לעורך להעלאה)" hint_for_supported_browsers: "תוכלו גם לגרור או להדביק תמונות לעורך" uploading: "מעלה" select_file: "בחר קובץ" image_link: "קישור לתמונה יצביע ל" search: + sort_by: "מיון על פי" + relevance: "רלוונטיות" + latest_post: "הפוסטים האחרונים" + most_viewed: "הנצפה ביותר" + most_liked: "האהובים ביותר" select_all: "בחר הכל" clear_all: "נקה הכל" - title: "חיפוש נושאים, פרסומים, משתמשים או קטגוריות" + result_count: + one: "תוצאה אחת ל \"{{term}}\"" + other: "{{count}} תוצאות ל \"{{term}}\"" + title: "חיפוש פוסטים, פרסומים, משתמשים או קטגוריות" no_results: "אין תוצאות." no_more_results: "לא נמצאו עוד תוצאות." search_help: עזרה בחיפוש @@ -864,29 +913,30 @@ he: context: user: "חיפוש פרסומים לפי @{{username}}" category: "חיפוש בקטגוריה \"{{category}}\"" - topic: "חפשו בנושא זה" + topic: "חפשו בפוסט זה" private_messages: "חיפוש הודעות" - hamburger_menu: "עבור לרשימת נושאים אחרת או קטגוריה" + hamburger_menu: "עבור לרשימת פוסטים אחרת או קטגוריה" new_item: "חדש" go_back: 'חזור אחורה' not_logged_in_user: 'עמוד משתמש עם סיכום פעילות נוכחית והעדפות' current_user: 'לך לעמוד המשתמש שלך' topics: bulk: + unlist_topics: "הסרת נושאים" reset_read: "איפוס נקראו" - delete: "מחיקת נושאים" - dismiss_posts: "ביטול פרסומים" - dismiss_posts_tooltip: "ניקוי ספירת הלא-נקראים בנושאים אלו, תווך המשך הצגתם ברשימת הלא נקראים כאשר נוספים פרסומים חדשים" - dismiss_topics: "דחיית נושאים" - dismiss_topics_tooltip: "הפסקת הצגת נושאים אלו ברשימת הלא-נקראו האישית כאשר נוספים פרסומים חדשים" + delete: "מחיקת פוסטים" + dismiss: "ביטול" + dismiss_read: "Dismiss all unread" + dismiss_button: "ביטול..." + dismiss_tooltip: "ביטול הצגת פוסטים חדשים או מעקב אחר נושאים" dismiss_new: "שחרור חדשים" - toggle: "החלף קבוצה מסומנת של נושאים" + toggle: "החלף קבוצה מסומנת של פוסטים" actions: "מקבץ פעולות" change_category: "שינוי קטגוריה" - close_topics: "סגירת נושאים" - archive_topics: "ארכיון הנושאים" + close_topics: "סגירת פוסטים" + archive_topics: "ארכיון הפוסטים" notification_level: "שינוי רמת התראה" - choose_new_category: "בחרו את הקטגוריה עבור הנושאים:" + choose_new_category: "בחרו את הקטגוריה עבור הפוסטים:" selected: one: "בחרת נושא אחד." other: "בחרת {{count}} נושאים." @@ -895,86 +945,83 @@ he: new: "אין לך נושאים חדשים." read: "עדיין לא קראת אף נושא." posted: "עדיין לא פרסמת באף נושא." - latest: "אין נושאים מדוברים. זה עצוב." - hot: "אין נושאים חמים." - bookmarks: "אין לך עדיין סימניות לנושאים." - category: "אין נושאים בקטגוריה {{category}}." - top: "אין נושאים מובילים." + latest: "אין פוסטים מדוברים. זה עצוב." + hot: "אין פוסטים חמים." + bookmarks: "אין לך עדיין סימניות לפוסטים." + category: "אין פוסטים בקטגוריה {{category}}." + top: "אין פוסטים מובילים." search: "אין תוצאות חיפוש" - educate: - new: '

    הנושאים החדשים שלך יופיעו כאן.

    כברירת מחדל, נושאים נחשבים חדשים ויופיעו עם האינדיקציה חדש אם הם נוצרו ב-2 הימים האחרונים. .

    תוכלו לשנות זאת ב העדפות .

    ' - unread: '

    הנושאים הלא-נקראים שלך מופיעים כאן.

    כברירת מחדל נושאים נחשבים ככאלה שלא נקראו ויוצגו כ- 1 אם את/ה:

    • יצרת את הנושא

    או אם כיוונתם את הנושא הזה להיות תחת מעקב או צפייה באמצעות כפתור ההתראות שבתחתית כל נושא.

    את/ה יכולים לשנות זאת בהעדפות.

    ' bottom: - latest: "אין עוד נושאים מדוברים." - hot: "אין עוד נושאים חמים." - posted: "אין עוד נושאים שפורסמו." - read: "אין עוד נושאים שנקראו." - new: "אין עוד נושאים חדשים." - unread: "אין עוד נושאים שלא נקראו." - category: "אין עוד נושאים בקטגוריה {{category}}." - top: "אין עוד נושאים מובילים." - bookmarks: "אין עוד סימניות לנושאים." + latest: "אין עוד פוסטים מדוברים." + hot: "אין עוד פוסטים חמים." + posted: "אין עוד פוסטים שפורסמו." + read: "אין עוד פוסטים שנקראו." + new: "אין עוד פוסטים חדשים." + unread: "אין עוד פוסטים שלא נקראו." + category: "אין עוד פוסטים בקטגוריה {{category}}." + top: "אין עוד פוסטים מובילים." + bookmarks: "אין עוד סימניות לפוסטים." search: "אין עוד תוצאות חיפוש" topic: unsubscribe: stop_notifications: "תקבלו פחות התראות עבור {{title}}" change_notification_state: "מצב ההתראות הנוכחי שלך הוא" - filter_to: "{{post_count}} הודעות בנושא" - create: 'נושא חדש' - create_long: 'יצירת נושא חדש' + filter_to: "{{post_count}} הודעות בפוסט" + create: 'פוסט חדש' + create_long: 'יצירת פוסט חדש' private_message: 'תחילת הודעה' - list: 'נושאים' - new: 'נושא חדש' + list: 'פוסטים' + new: 'פוסט חדש' unread: 'לא נקרא/ו' new_topics: - one: 'נושא חדש אחד' - other: '{{count}} נושאים חדשים' + one: 'פוסט חדש אחד' + other: '{{count}} פוסטים חדשים' unread_topics: one: '1 שלא נקרא' - other: '{{count}} נושאים שלא נקראו' - title: 'נושא' + other: '{{count}} פוסטים שלא נקראו' + title: 'פוסט' invalid_access: - title: "הנושא פרטי" - description: "סליחה, איך אין לך גישה לנושא הזה!" - login_required: "עליכם להתחבר כדי לצפות בנושא זה." + title: "הפוסט פרטי" + description: "סליחה, איך אין לך גישה לפוסט הזה!" + login_required: "עליכם להתחבר כדי לצפות בפוסט זה." server_error: - title: "שגיאה בטעינת נושא" - description: "סליחה, לא יכולנו לטעון את הנושא הזה, ייתכן שבשל תקלת תקשורת. אנא נסי שוב. אם הבעיה נמשכת, הודיעו לנו." + title: "שגיאה בטעינת הפוסט" + description: "סליחה, לא יכולנו לטעון את הפוסט הזה, ייתכן שבשל תקלת תקשורת. אנא נסי שוב. אם הבעיה נמשכת, הודיעו לנו." not_found: - title: "נושא לא נמצא" - description: "סליחה, לא יכולנו למצוא את הנושא הזה. אולי הוא הוסר על ידי מנהל?" + title: "הפוסט לא נמצא" + description: "סליחה, לא יכולנו למצוא את הפוסט הזה. אולי הוא הוסר על ידי מנהל?" total_unread_posts: one: "יש לכם פרסום אחד שלא נקרא בנושא זה" - other: "יש לכם {{count}} פרסומים שלא נקראו בנושא זה" + other: "יש לכם {{count}} פרסומים שלא נקראו בפוסט זה" unread_posts: one: "יש לך הודעה אחת שלא נקראה בנושא הזה" - other: "יש לך {{count}} הודעות ישנות שלא נקראו בנושא הזה" + other: "יש לך {{count}} הודעות ישנות שלא נקראו בפוסט הזה" new_posts: one: "יש הודעה אחת חדשה בנושא הזה מאז שקראת אותו לאחרונה" - other: "יש {{count}} הודעות חדשות בנושא הזה מאז שקראת אותו לאחרונה" + other: "יש {{count}} הודעות חדשות בפוסט הזה מאז שקראת אותו לאחרונה" likes: one: "יש לייק אחד בנושא הזה" - other: "יש {{count}} לייקים בנושא הזה" - back_to_list: "חזרה לרשימת נושאים" - options: "אפשרויות נושא" - show_links: "הצג קישורים בתוך הנושא הזה" - toggle_information: "הצגת פרטי נושא" - read_more_in_category: "רוצה לקרוא עוד? עיין נושאים אחרים ב {{catLink}} או {{latestLink}}." + other: "יש {{count}} לייקים בפוסט הזה" + back_to_list: "חזרה לרשימת הפוסטים" + options: "אפשרויות פוסט" + show_links: "הצג קישורים בתוך הפוסט הזה" + toggle_information: "הצגת פרטי פוסט" + read_more_in_category: "רוצה לקרוא עוד? עיין פוסטים אחרים ב {{catLink}} או {{latestLink}}." read_more: "רוצה לקרוא עוד? {{catLink}} or {{latestLink}}." read_more_MF: "There { UNREAD, plural, =0 {} one { is 1 unread } other { are # unread } } { NEW, plural, =0 {} one { {BOTH, select, true{and } false {is } other{}} 1 new topic} other { {BOTH, select, true{and } false {are } other{}} # new topics} } remaining, or {CATEGORY, select, true {browse other topics in {catLink}} false {{latestLink}} other {}}" browse_all_categories: עיין בכל הקטגוריות - view_latest_topics: הצגת נושאים מדוברים - suggest_create_topic: לחץ כאן כדי ליצור נושא חדש. + view_latest_topics: הצגת פוסטים מדוברים + suggest_create_topic: לחץ כאן כדי ליצור פוסט חדש. jump_reply_up: קפיצה לתגובה קודמת jump_reply_down: קפיצה לתגובה מאוחרת - deleted: "הנושא הזה נמחק" - auto_close_notice: "הנושא הזה ינעל אוטומטית %{timeLeft}." - auto_close_notice_based_on_last_post: "נושא זה ייסגר %{duration} אחר התגובה האחרונה." + deleted: "הפוסט הזה נמחק" + auto_close_notice: "הפוסט הזה ינעל אוטומטית %{timeLeft}." + auto_close_notice_based_on_last_post: "פוסט זה ייסגר %{duration} אחר התגובה האחרונה." auto_close_title: 'הגדרות נעילה אוטומטית' auto_close_save: "שמור" - auto_close_remove: "אל תנעל נושא זה אוטומטית" + auto_close_remove: "אל תנעל פוסט זה אוטומטית" progress: - title: התקדמות נושא + title: התקדמות פוסט go_top: "למעלה" go_bottom: "למטה" go: "קדימה" @@ -986,31 +1033,31 @@ he: notifications: reasons: '3_6': 'תקבלו התראות כיוון שאת/ה עוקב אחרי קטגוריה זו.' - '3_5': 'תקבל/י התראות כיוון שהתחלת לעקוב אחרי הנושא הזה אוטומטית.' - '3_2': 'תקבל/י התראות כיוון שאת/ה עוקב אחרי נושא הזה.' - '3_1': 'תקבל/י התראות כיוון שאת/ה יצרת את הנושא הזה.' - '3': 'תקבל/י התראות כיוון שאת/ה עוקב אחרי נושא זה.' + '3_5': 'תקבל/י התראות כיוון שהתחלת לעקוב אחרי הפוסט הזה אוטומטית.' + '3_2': 'תקבל/י התראות כיוון שאת/ה עוקב אחרי הפוסט הזה.' + '3_1': 'תקבל/י התראות כיוון שאת/ה יצרת את הפוסט הזה.' + '3': 'תקבל/י התראות כיוון שאת/ה עוקב אחרי פוסט זה.' '2_8': 'תקבלו התראות כיוון שאת/ה צופה בקטגוריה הזו.' - '2_4': 'תקבל/י התראות כיוון שפרסמת תגובה לנושא הזה.' - '2_2': 'תקבל/י התראות כיוון שאת/ה צופה אחרי הנושא הזה.' - '2': 'תקבל/י התראות כיוון שקראת את הנושא הזה.' + '2_4': 'תקבל/י התראות כיוון שפרסמת תגובה לפוסט הזה.' + '2_2': 'תקבל/י התראות כיוון שאת/ה צופה אחרי הפוסט הזה.' + '2': 'תקבל/י התראות כיוון שקראת את הפוסט הזה.' '1_2': 'תקבלו התראה אם מישהו יזכיר את @שם_המשתמש/ת שלך או ישיב לפרסום שלך.' '1': 'תקבלו התראה אם מישהו יזכיר את @שם_המשתמש/ת שלך או ישיב לפרסום שלך.' '0_7': 'את/ה מתעלם/מתעלמת מכל ההתראות בקטגוריה זו.' - '0_2': 'אתה מתעלם מכל ההתראות בנושא זה.' - '0': 'אתה מתעלם מכל ההתראות בנושא זה.' + '0_2': 'אתה מתעלם מכל ההתראות בפוסט זה.' + '0': 'אתה מתעלם מכל ההתראות בפוסט זה.' watching_pm: title: "עוקב" description: "תקבל/י התראה על כל תגובה חדשה בהודעה זו. בנוסף מספר התגובות שלא נקראו יופיעו ליד ההודעה. " watching: title: "עוקב" - description: "תקבל/י התראה על כל תגובה חדשה בנושא זה ומספר התגובות החדשות יוצג. " + description: "תקבל/י התראה על כל תגובה חדשה בפוסט זה ומספר התגובות החדשות יוצג. " tracking_pm: title: "רגיל+" description: "כמו רגיל, בנוסף מספר התגובות החדשות יוצג ליד ההודעה. " tracking: title: "רגיל+" - description: "כמו רגיל, בנוסף מספר התגובות שלא נקראו יוצג לנושא זה. " + description: "כמו רגיל, בנוסף מספר התגובות שלא נקראו יוצג לפוסט זה. " regular: title: "רגיל" description: "תקבלו התראה אם מישהו יזכיר את @שם_המשתמש/ת שלך או ישיב לפרסום שלך." @@ -1022,67 +1069,55 @@ he: description: "לעולם לא תקבל/י התראה בנוגע להודעה זו." muted: title: "מושתק" - description: "לעולם לא תקבל/י התראות על הנושא הזה, והוא לא יופיע בעמוד ה\"לא נקראו\" שלך." actions: - recover: "שחזר נושא" - delete: "מחק נושא" - open: "פתח נושא" - close: "נעל נושא" + recover: "שחזר פוסט" + delete: "מחק פוסט" + open: "פתח פוסט" + close: "נעל פוסט" multi_select: "בחר/י פרסומים..." auto_close: "סגירה אוטומטית..." - pin: "נעיצת נושא.." - unpin: "שחרור נעיצת נושא..." - unarchive: "הוצא נושא מארכיון" - archive: "הכנס נושא לארכיון" + pin: "נעיצת פוסט.." + unpin: "שחרור נעיצת פוסט..." + unarchive: "הוצא פוסט מארכיון" + archive: "הכנס פוסט לארכיון" invisible: "הסתרה" visible: "גילוי" reset_read: "אפס מידע שנקרא" feature: - pin: "נעיצת נושא" - unpin: "שחרור נעיצת נושא" - pin_globally: "נעיצת נושא גלובלית" - make_banner: "באנר נושא" - remove_banner: "הסרת באנר נושא" + pin: "נעיצת פוסט" + unpin: "שחרור נעיצת פוסט" + pin_globally: "נעיצת פוסט גלובלית" + make_banner: "באנר פוסט" + remove_banner: "הסרת באנר פוסט" reply: title: 'תגובה' - help: 'החל בכתיבת הודעה לנושא זה' + help: 'החל בכתיבת הודעה לפוסט זה' clear_pin: title: "נקה נעיצה" - help: "נקה סטטוס נעוץ של נושא זה כדי שהוא לא יופיע עוד בראש רשימת הנושאים שלך" + help: "נקה סטטוס נעוץ של פוסט זה כדי שהוא לא יופיע עוד בראש רשימת הפוסטים שלך" share: title: 'שיתוף' - help: 'שתפו קישור לנושא זה' + help: 'שתפו קישור לפוסט זה' flag_topic: title: 'סימון' - help: 'סמנו נושא זה באופן פרטי לתשומת לב או שלחו התראה פרטית בנוגע אליו' - success_message: 'סמנת נושא זה בהצלחה.' + help: 'סמנו פוסט זה באופן פרטי לתשומת לב או שלחו התראה פרטית בנוגע אליו' + success_message: 'סמנת פוסט זה בהצלחה.' feature_topic: - title: "הצגת נושא זה" - pin: "גרמו לנושא זה להופיע בראש קטגוריה {{categoryLink}} עד" - confirm_pin: "יש לך כבר {{count}} נושאים נעוצים. מספר גדול מידי של נושאים נעוצים עשויים להכביד על משתמשים חדשים או אנונימיים. האם את/ה בטוחים שאתם רוצים להצמיד נושא נוסף בקטגוריה זו? " - unpin: "הסרת נושא זה מראש הקטגוריה {{categoryLink}}." - unpin_until: "גרמו לנושא זה להופיע בראש הקטגוריה {{categoryLink}} או המתן עד %{until}." - pin_note: "המשתמש/ת יכולים להסיר את הנושא באופן עצמאי עבור עצמם." - pin_validation: "דרוש תאריך על מנת לנעוץ את הנושא. " - already_pinned: - zero: "אין נושאים מוצמדים בקטגוריה {{categoryLink}}." - one: "נושאים שנעוצים ב {{categoryLink}}: 1." - other: "נושאים שנעוצים ב{{categoryLink}}: {{count}}." - pin_globally: "גרמו לנושא זה להופיע בראש כל רשימות הנושאים עד" - confirm_pin_globally: "יש לך כבר {{count}} נושאים המוצמדים באופן גלובאלי. עודף נושאים מוצמדים עשוי להכביד על משתמשים חדשים או אנונימיים. האם את/ה בטוחים שאתם מעוניינים להצמיד נושא גלובאלי נוסף?" - unpin_globally: "הסרת נושא זה מראש כל רשימות הנושאים." - unpin_globally_until: "הסרת נושא זה מראש כל רשימות הנושאים או המתינו עד %{until}." - global_pin_note: "משתמשים יכולים להסיר את הצמדת הנושא באופן עצמאי לעצמם." - already_pinned_globally: - zero: "אין נושאים המוצמדים באופן גלובלי." - one: "נושאים שכרגע נעוצים גלובלית: 1." - other: "נושאים שכרגע מוצמדים גלובלית: {{count}}." - make_banner: "הפכו נושא זה לבאנר אשר מופיע בראש כל העמודים." + title: "הצגת פוסט זה" + pin: "גרמו לפוסט זה להופיע בראש קטגוריה {{categoryLink}} עד" + confirm_pin: "יש לך כבר {{count}} פוסטים נעוצים. מספר גדול מידי של פוסטים נעוצים עשויים להכביד על משתמשים חדשים או אנונימיים. האם את/ה בטוחים שאתם רוצים להצמיד פוסט נוסף בקטגוריה זו? " + unpin: "הסרת פוסט זה מראש הקטגוריה {{categoryLink}}." + unpin_until: "גרמו לפוסט זה להופיע בראש הקטגוריה {{categoryLink}} או המתן עד %{until}." + pin_note: "המשתמש/ת יכולים להסיר את הפוסט באופן עצמאי עבור עצמם." + pin_validation: "דרוש תאריך על מנת לנעוץ את הפוסט. " + pin_globally: "גרמו לפוסט זה להופיע בראש כל רשימות הפוסטים עד" + confirm_pin_globally: "יש לך כבר {{count}} פוסטים המוצמדים באופן גלובאלי. עודף פוסטים מוצמדים עשוי להכביד על משתמשים חדשים או אנונימיים. האם את/ה בטוחים שאתם מעוניינים להצמיד פוסט גלובאלי נוסף?" + unpin_globally: "הסרת פוסט זה מראש כל רשימות הפוסטים." + unpin_globally_until: "הסרת פוסט זה מראש כל רשימות הפוסטים או המתינו עד %{until}." + global_pin_note: "משתמשים יכולים להסיר את הצמדת הפוסט באופן עצמאי לעצמם." + make_banner: "הפכו פוסט זה לבאנר אשר מופיע בראש כל העמודים." remove_banner: "הסרת הבאנר שמופיע בראש כל העמודים." - banner_note: "משתמשים יכולים לבטל את הבאנר על ידי סגירתו. רק נושא אחד יכול לשמש כבאנר בזמן נתון." - already_banner: - zero: "לא מוגדר באנר נושא" - one: "יש כרגע באנר נושאי." + banner_note: "משתמשים יכולים לבטל את הבאנר על ידי סגירתו. רק פוסט אחד יכול לשמש כבאנר בזמן נתון." inviting: "מזמין..." automatically_add_to_groups_optional: "הזמנה זו כוללת גישה לקבוצות הללו: (אופציונלי, רק מנהל/ת)" automatically_add_to_groups_required: "הזמנה זו כוללת גישה לקבוצות הללו: (חובה, רק מנהל/ת)" @@ -1098,16 +1133,16 @@ he: title: 'הזמנה' username_placeholder: "שם משתמש" action: 'שלח הזמנה' - help: 'הזמן אנשים אחרים לנושא זה דרך דואר אלקטרוני או התראות' + help: 'הזמן אנשים אחרים לפוסט זה דרך דואר אלקטרוני או התראות' to_forum: "נשלח מייל קצר המאפשר לחברך להצטרף באופן מיידי באמצעות לחיצה על קישור, ללא צורך בהתחברות למערכת הפורומים." - sso_enabled: "הכנס את שם המשתמש של האדם שברצונך להזמין לנושא זה." - to_topic_blank: "הכנס את שם המשתמש או כתובת דואר האלקטרוני של האדם שברצונך להזמין לנושא זה." - to_topic_email: "הזנת כתובת אימייל. אנחנו נשלח הזמנה שתאפשר לחברך להשיב לנושא הזה." - to_topic_username: "הזנת שם משתמש/ת. נשלח התראה עם לינק הזמנה לנושא הזה. " - to_username: "הכנסת את שם המשתמש של האדם שברצונך להזמין. אנו נשלח התראה למשתמש זה עם קישור המזמין אותו לנושא זה." + sso_enabled: "הכנס את שם המשתמש של האדם שברצונך להזמין לפוסט זה." + to_topic_blank: "הכנס את שם המשתמש או כתובת דואר האלקטרוני של האדם שברצונך להזמין לפוסט זה." + to_topic_email: "הזנת כתובת אימייל. אנחנו נשלח הזמנה שתאפשר לחברך להשיב לפוסט הזה." + to_topic_username: "הזנת שם משתמש/ת. נשלח התראה עם לינק הזמנה לפוסט הזה. " + to_username: "הכנסת את שם המשתמש של האדם שברצונך להזמין. אנו נשלח התראה למשתמש זה עם קישור המזמין אותו לפוסט זה." email_placeholder: 'name@example.com' success_email: "שלחנו הזמנה ל: {{emailOrUsername}}. נודיע לך כשהזמנה תענה. בדוק את טאב ההזמנות בעמוד המשתמש שלך בשביל לעקוב אחרי ההזמנות ששלחת. " - success_username: "הזמנו את המשתמש להשתתף בנושא." + success_username: "הזמנו את המשתמש להשתתף בפוסט." error: "מצטערים, לא יכלנו להזמין האיש הזה. אולי הוא כבר הוזמן בעבר? (תדירות שליחת ההזמנות מוגבלת)" login_reply: 'התחברו כדי להשיב' filters: @@ -1116,20 +1151,20 @@ he: other: "{{count}} הודעות" cancel: "הסרת הסינון" split_topic: - title: "העבר לנושא חדש" - action: "העבר לנושא חדש" - topic_name: "שם הנושא החדש" - error: "הייתה שגיאה בהעברת ההודעות לנושא החדש." + title: "העבר לפוסט חדש" + action: "העבר לפוסט חדש" + topic_name: "שם הפוסט החדש" + error: "הייתה שגיאה בהעברת ההודעות לפוסט החדש." instructions: - one: "אתה עומד ליצור נושא חדש ולמלא אותו עם ההודעה שבחרת." - other: "אתה עומד ליצור נושא חדש ולמלא אותו עם {{count}} ההודעות שבחרת." + one: "אתה עומד ליצור פוסט חדש ולמלא אותו עם ההודעה שבחרת." + other: "אתה עומד ליצור פוסט חדש ולמלא אותו עם {{count}} ההודעות שבחרת." merge_topic: - title: "העבר לנושא קיים" - action: "העבר לנושא קיים" - error: "התרחשה שגיאה בהעברת ההודעות לנושא הזה." + title: "העבר לפוסט קיים" + action: "העבר לפוסט קיים" + error: "התרחשה שגיאה בהעברת ההודעות לפוסט הזה." instructions: one: "בבקשה בחר נושא אליו הייתי רוצה להעביר את ההודעה" - other: "בבקשה בחר את הנושא אליו תרצה להעביר את {{count}} ההודעות." + other: "בבקשה בחר את הפוסט אליו תרצה להעביר את {{count}} ההודעות." change_owner: title: "שנה בעלים של הודעות" action: "שנה בעלות" @@ -1144,8 +1179,8 @@ he: title: "שנה חותמת זמן" action: "זנה חותמת זמן" invalid_timestamp: "חותמת זמן לא יכולה להיות בעתיד" - error: "הייתה שגיאה בשינוי חותמת הזמן של הנושא" - instructions: "אנא בחרו את חותמת הזמן החדשה של הנושא. פרסומים בנושא יועדכנו לאותם הפרשי זמנים." + error: "הייתה שגיאה בשינוי חותמת הזמן של הפוסט" + instructions: "אנא בחרו את חותמת הזמן החדשה של הפוסט. פרסומים בפוסט יועדכנו לאותם הפרשי זמנים." multi_select: select: 'בחירה' selected: 'נבחרו ({{count}})' @@ -1165,7 +1200,7 @@ he: edit_reason: "סיבה: " post_number: "הודעה {{number}}" last_edited_on: "הודעה נערכה לאחרונה ב" - reply_as_new_topic: "תגובה כנושא מקושר" + reply_as_new_topic: "תגובה כפוסט מקושר" continue_discussion: "ממשיך את הדיון מ {{postLink}}:" follow_quote: "מעבר להודעה המצוטטת" show_full: "הראה הודעה מלאה" @@ -1188,10 +1223,7 @@ he: has_likes_title: one: "מישהו אחד אהב את התגובה הזו" other: "{{count}} אנשים אהבו את התגובה הזו" - has_likes_title_you: - zero: "אתה אהבת את התגובה הזו" - one: "אתה ואדם נוסף אהבתם את התגובה הזו" - other: "אתה ו{{count}} אנשים נוספים אהבתם את התגובה הזו" + has_likes_title_only_you: "אתה אהבת את התגובה הזו" errors: create: "סליחה, הייתה שגיאה ביצירת ההודעה שלך. אנא נסה שנית." edit: "סליחה, הייתה שגיאה בעריכת ההודעה שלך. אנא נסה שנית." @@ -1210,8 +1242,6 @@ he: yes_value: "כן, נטוש" via_email: "פרסום זה הגיע באמצעות דוא\"ל" whisper: "פרסום זה הוא לחישה פרטית לצוות האתר" - wiki: - about: "פרסום זה הינו ויקי; משתמשים בסיסיים יכולים לערוך אותו" archetypes: save: 'שמור אפשרויות' controls: @@ -1239,6 +1269,7 @@ he: revert_to_regular: "הסרת צבע צוות" rebake: "בנייה מחודשת של HTML" unhide: "הסרת הסתרה" + change_owner: "שינוי בעלות" actions: flag: 'סימון' defer_flags: @@ -1259,20 +1290,8 @@ he: bookmark: "בטל העדפה" like: "בטל לייק" vote: "בטל הצבעה" - people: - off_topic: "{{icons}} סומן כמחוץ לנושא" - spam: "{{icons}} סומן כספאם" - spam_with_url: "{{icons}} סימון של זה כספאם " - inappropriate: "{{icons}} סומן בלתי ראוי" - notify_moderators: "{{icons}} הודיעו למנהלים" - notify_moderators_with_url: "{{icons}} הודיעו למנהלים" - notify_user: "{{icons}} שלח הודעה" - notify_user_with_url: "{{icons}} שלח הודעה" - bookmark: "{{icons}} סימנו כמועדף" - like: "{{icons}} נתנו לייק" - vote: "{{icons}} הצביעו עבור זה" by_you: - off_topic: "סמ נת פרסום זה כמחוץ לנושא" + off_topic: "סמנת פרסום זה כמחוץ לנושא הפוסט" spam: "סמנת את זה כספאם" inappropriate: "סמנת את זה כלא ראוי" notify_moderators: "סמנת את זה עבור המנהלים" @@ -1283,7 +1302,7 @@ he: by_you_and_others: off_topic: one: "אתה ועוד אחד דגללתם את זה כאוף-טופיק" - other: "את/ה ועוד {{count}} אנשים אחרים סמנתם את זה כמחוץ לנושא" + other: "את/ה ועוד {{count}} אנשים אחרים סמנתם את זה כמחוץ לנושא הפוסט" spam: one: "אתה ועוד אחד דגללתם את זה כספאם" other: "את/ה ועוד {{count}} אנשים אחרים סמנתם את זה כספאם" @@ -1330,10 +1349,6 @@ he: vote: one: "אדם אחד הצביע להודעה זו" other: "{{count}} אנשים הצביעו להודעה זו" - edits: - one: עריכה אחת - other: "{{count}} עריכות" - zero: אין עריכות delete: confirm: one: "Are you sure you want to delete that post?" @@ -1364,10 +1379,10 @@ he: choose: 'בחר קטגוריה…' edit: 'ערוך' edit_long: "עריכה" - view: 'הצג נושאים בקטגוריה' + view: 'הצג פוסטים בקטגוריה' general: 'כללי' settings: 'הגדרות' - topic_template: "תבנית נושא" + topic_template: "תבנית פוסט" delete: 'מחק קטגוריה' create: 'קטגוריה חדשה' create_long: 'צור קטגוריה חדשה' @@ -1395,11 +1410,11 @@ he: security: "אבטחה" special_warning: "Warning: This category is a pre-seeded category and the security settings cannot be edited. If you do not wish to use this category, delete it instead of repurposing it." images: "תמונות" - auto_close_label: "נעל נושאים אוטומטית אחרי:" + auto_close_label: "נעל פוסטים אוטומטית אחרי:" auto_close_units: "שעות" email_in: "כתובת דואר נכנס מותאמת אישית:" email_in_allow_strangers: "קבלת דוא\"ל ממשתמשים אנונימיים ללא חשבונות במערכת הפורומים" - email_in_disabled: "האפשרות פרסום נושאים חדשים דרך הדוא\"ל נוטרלה דרך הגדרות האתר. לאפשר פרסום באמצעות משלוח דוא\"ל." + email_in_disabled: "האפשרות פרסום פוסטים חדשים דרך הדוא\"ל נוטרלה דרך הגדרות האתר. לאפשר פרסום באמצעות משלוח דוא\"ל." email_in_disabled_click: 'אפשרו את את ההגדרה "דוא"ל נכנס"' suppress_from_homepage: "הרחק קטגוריה זו מהעמוד הראשי" allow_badges_label: "הרשו לתגים (badges) להיות מוענקים בקטגוריה זו" @@ -1414,24 +1429,23 @@ he: notifications: watching: title: "עוקב" - description: "תעקבו באופן אוטומטי אחרי כל הנושאים החדשים בקטגוריות אלה. תקבלו התראה על כל פרסום ונושא חדש." + description: "אתה תצפה באופן אוטומטי בכל הנושאים החדשים בקטגוריות אלה. תקבל התראות על כל הודעה חדשה בכל נושא, ומונה תגובות חדשות יופיע." tracking: title: "רגיל+" - description: "בקטגוריות אלה סך הפרסומים החדשים שלא נקראו יופיע לצד שם הנושא." + description: "אתה תעקוב באופן אוטומטי בכל הנושאים החדשים בקטגוריות אלה. תקבל התראות אם מישהו ציין את @שמך או מגיב לך, ומונה תגובות חדשות יופיע." regular: - title: "רגיל" + title: "נורמלי" description: "תקבלו התראה אם מישהו יזכיר את @שם_המשתמש/ת שלך או ישיב לפרסום שלך." muted: title: "מושתק" - description: "לא תקבל התראות בנוגע לנושאים חדשים בקטגוריות האלה, והם לא יופיעו בלשונית ה\"לא נקראו\" שלך." + description: "לא תקבלו התראות על נושאים חדשים בקטגוריות אלו, והם לא יופיעו בעמוד הלא נקראו שלך." flagging: title: 'תודה על עזרתך לשמירה על תרבות הקהילה שלנו!' - private_reminder: 'דגלים הם פרטיים וניתנים לצפייה ע"י הצוות בלבד' action: 'סימון פרסום' take_action: "בצע פעולה" notify_action: 'הודעה' delete_spammer: "מחק ספאמר" - delete_confirm: "אתה עומד למחוק %{posts} הודעות ו-%{topics} נושאים של המשתמש הזה, להסיר את החשבון שלהם, לחסור הרשמה מכתובת ה-IP שלהם %{ip_address}, ולהוסיף את כתובת הדואר האלקטרוני %{email} לרשימה שחורה. אתה בטוח שזה באמת ספאמר?" + delete_confirm: "אתה עומד למחוק %{posts} הודעות ו-%{topics} פוסטים של המשתמש הזה, להסיר את החשבון שלהם, לחסור הרשמה מכתובת ה-IP שלהם %{ip_address}, ולהוסיף את כתובת הדואר האלקטרוני %{email} לרשימה שחורה. אתה בטוח שזה באמת ספאמר?" yes_delete_spammer: "כן, מחק ספאמר" ip_address_missing: "(N/A)" hidden_email_address: "(מוסתר)" @@ -1439,7 +1453,7 @@ he: take_action_tooltip: "הגעה באופן מיידי למספר הסימונים האפשרי, במקום להמתין לסימונים נוספים מן הקהילה" cant: "סליחה, לא ניתן לסמן הודעה זו כרגע." formatted_name: - off_topic: "מחוץ לנושא" + off_topic: "מחוץ לנושא הפוסט" inappropriate: "לא ראוי" spam: "זהו ספאם" custom_placeholder_notify_user: "היה ממוקד, חיובי ואדיב תמיד." @@ -1450,10 +1464,10 @@ he: left: "{{n}} נותרו" flagging_topic: title: "תודה על עזרתך לשמירה על תרבות הקהילה שלנו!" - action: "סימון נושא" + action: "סימון פוסט" notify_action: "הודעה" topic_map: - title: "סיכום נושא" + title: "סיכום פוסט" participants_title: "מפרסמים מתמידים" links_title: "לינקים פופלארים" links_shown: "הצג את כל הקישורים {{totalLinks}}..." @@ -1464,27 +1478,26 @@ he: warning: help: "זוהי אזהרה רשמית." bookmarked: - help: "יצרת סימניה לנושא זה" + help: "יצרת סימניה לפוסט זה" locked: - help: "הנושא הזה נעול, הוא לא מקבל יותר תגובות חדשות" + help: "הפוסט הזה נעול, הוא לא מקבל יותר תגובות חדשות" archived: - help: "הנושא הזה אוכסן בארכיון; הוא הוקפא ולא ניתן לשנותו" + help: "הפוסט הזה אוכסן בארכיון; הוא הוקפא ולא ניתן לשנותו" locked_and_archived: - help: "הנושא הזה סגור ומאורכב. לא ניתן להגיב בו יותר או לשנות אותו. " + help: "הפוסט הזה סגור ומאורכב. לא ניתן להגיב בו יותר או לשנות אותו. " unpinned: title: "הורד מנעיצה" - help: "נושא זה אינו מקובע עבורך; הוא יופיע בסדר הרגיל" + help: "פוסט זה אינו מקובע עבורך; הוא יופיע בסדר הרגיל" pinned_globally: title: "נעוץ גלובאלית" - help: "הנושא הזה נעוץ גלובאלית; הוא יוצג בראש כל הרשימות" pinned: title: "נעוץ" - help: "נושא זה מקובע עבורך, הוא יופיע בראש הקטגוריה" + help: "פוסט זה מקובע עבורך, הוא יופיע בראש הקטגוריה" invisible: - help: "נושא זה מוסתר; הוא לא יוצג ברשימות הנושאים, וזמין רק באמצעות קישור ישיר." + help: "פוסט זה מוסתר; הוא לא יוצג ברשימות הפוסטים, וזמין רק באמצעות קישור ישיר." posts: "הודעות" posts_lowercase: "פרסומים" - posts_long: "יש {{number}} הודעות בנושא הזה" + posts_long: "יש {{number}} הודעות בפוסט הזה" posts_likes_MF: | לנושא זה יש {count, plural, one {פרסום אחד} other {# פרסומים}} נמוך {עם יחס גבוה של לייקים לפרסום} @@ -1497,13 +1510,13 @@ he: one: "צפיה" other: "צפיות" replies: "תגובות" - views_long: "הנושא הזה נצפה {{number}} פעמים" + views_long: "הפוסט הזה נצפה {{number}} פעמים" activity: "פעילות" likes: "לייקים" likes_lowercase: one: "לייקים" other: "לייקים" - likes_long: "יש {{number}} לייקים לנושא הזה" + likes_long: "יש {{number}} לייקים לפוסט הזה" users: "משתמשים" users_lowercase: one: "משתמש" @@ -1516,61 +1529,45 @@ he: not_available: "לא זמין!" categories_list: "רשימת קטגוריות" filters: - with_topics: "%{filter} נושאים" - with_category: "%{filter} %{category} נושאים" + with_topics: "%{filter} פוסטים" + with_category: "%{filter} %{category} פוסטים" latest: - title: - zero: "פורסמו לאחרונה" - one: "פורסמו לאחרונה" - other: "({{count}}) פורסמו לאחרונה" - help: "נושאים עם תגובות לאחרונה" + title: "פורסמו לאחרונה" + help: "פוסטים עם תגובות לאחרונה" hot: title: "חם" - help: "מבחר הנושאים החמים ביותר" + help: "מבחר הפוסטים החמים ביותר" read: title: "נקרא" - help: "נושאים שקראת, לפי סדר קריאתם" + help: "פוסטים שקראת, לפי סדר קריאתם" search: title: "חיפוש" - help: "חיפוש בכל הנושאים" + help: "חיפוש בכל הפוסטים" categories: title: "קטגוריות" title_in: "קטגוריה - {{categoryName}}" - help: "כל הנושאים תחת הקטגוריה הזו" + help: "כל הפוסטים תחת הקטגוריה הזו" unread: - title: - zero: "לא נקרא" - one: "לא נקרא (1)" - other: "לא נקראו ({{count}})" - help: "נושאים שאתם כרגע צופים או עוקבים אחריהם עם פרסומים שלא נקראו" - lower_title_with_count: - one: "1 שלא נקרא" - other: "{{count}} שלא נקראו" + help: "פוסטים שאתם כרגע צופים או עוקבים אחריהם עם פרסומים שלא נקראו" new: - lower_title_with_count: - one: "1 חדש" - other: "{{count}} חדשים" lower_title: "חדש" - title: - zero: "חדש" + title: "חדש" + title_with_count: one: "חדש (1)" other: "חדשים ({{count}})" help: "פרסומים נוצרו בימים האחרונים" posted: title: "ההודעות שלי" - help: "נושאים בהם פרסמת" + help: "פוסטים בהם פרסמת" bookmarks: title: "סימניות" - help: "נושאים עבורם יצרת סימניות" + help: "פוסטים עבורם יצרת סימניות" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" - other: "{{categoryName}} ({{count}})" - help: "נושאים מדוברים בקטגוריה {{categoryName}}" + title: "{{categoryName}}" + help: "פוסטים מדוברים בקטגוריה {{categoryName}}" top: title: "מובילים" - help: "הנושאים הפעילים ביותר בשנה, חודש, שבוע או יום האחרונים" + help: "הפוסטים הפעילים ביותר בשנה, חודש, שבוע או יום האחרונים" all: title: "תמיד" yearly: @@ -1667,18 +1664,18 @@ he: delete: "מחיקה" delete_title: "מחיקת הפרסום המסומן כאן." delete_post_defer_flag: "מחיקת הפרסום ודחיית הסימון" - delete_post_defer_flag_title: "מחיקת הפרסום; אם זהו הפרסום הראשון, מחיקת הנושא" + delete_post_defer_flag_title: "מחיקת הפרסום; אם זהו הפרסום הראשון, מחיקת הפוסט" delete_post_agree_flag: "מחיקת הפרסום והסכמה עם הסימון" - delete_post_agree_flag_title: "מחיקת פרסום; אם זהו הפרסום הראשון, מחיקת הנושא" + delete_post_agree_flag_title: "מחיקת פרסום; אם זהו הפרסום הראשון, מחיקת הפוסט" delete_flag_modal_title: "מחיקה ו..." delete_spammer: "מחיקת ספאמר" - delete_spammer_title: "הסרת המשתמש/ת וכל הפרסומים והנושאים של משתמש/ת אלו." + delete_spammer_title: "הסרת המשתמש/ת וכל הפרסומים והפוסטים של משתמש/ת אלו." disagree_flag_unhide_post: "אי-קבלה (הצגה מחדש של הפרסום)" disagree_flag_unhide_post_title: "הסרה של כל הסימונים מהפרסום הזה והחזרתו למצב תצוגה" disagree_flag: "אי קבלה" disagree_flag_title: "התעלמות מהסימון היות שאינו תקין או אינו נכון" clear_topic_flags: "סיום" - clear_topic_flags_title: "הנושא נבדק והבעיה נפתרה. לחצו על סיום כדי להסיר את הסימונים." + clear_topic_flags_title: "הפוסט נבדק והבעיה נפתרה. לחצו על סיום כדי להסיר את הסימונים." more: "(עוד תגובות...)" dispositions: agreed: "התקבל" @@ -1691,8 +1688,8 @@ he: error: "משהו השתבש" reply_message: "תגובה" no_results: "אין סימונים." - topic_flagged: "הנושא הזה דוגלל." - visit_topic: "בקרו בנושא כדי לנקוט פעולה" + topic_flagged: "הפוסט הזה דוגלל." + visit_topic: "בקרו בפוסט כדי לנקוט פעולה" was_edited: "הפרסום נערך לאחר הסימון הראשון" previous_flags_count: "פרסום זה כבר סומן {{count}} פעמים." summary: @@ -1726,15 +1723,22 @@ he: delete_confirm: "למחוק קבוצה זו?" delete_failed: "לא ניתן למחוק קבוצה זו. אם זו קבוצה אוטומטית, היא בלתי ניתנת למחיקה." delete_member_confirm: "להסיר את '%{username}' מהקבוצה '%{group}' ?" + delete_owner_confirm: "הסרת הרשאות מנהל עבור '%{username}'?" name: "שם" add: "הוספה" add_members: "הוספת חברים וחברות" custom: "מותאם" + bulk_complete: "המשתמשים התווספו לקבוצה." + bulk: "הוספ" + bulk_paste: "הדביקו רשימה של שמות משתמש או כתובות אימייל, אחת בכל שורה:" + bulk_select: "(בחר קבוצה)" automatic: "אוטומטי" automatic_membership_email_domains: "משתמשים אשר נרשמים עם מארח דוא\"ל שתואם בדיוק לאחד מהרשימה, יוספו באופן אוטומטי לקבוצה זו:" automatic_membership_retroactive: "החלת כלל מארח דוא\"ל זהה כדי להוסיף משתמשים רשומים" default_title: "ברירת המחדל לכל המשתמשים בקבוצה זו" primary_group: "קבע כקבוצה ראשית באופן אוטומטי" + group_owners: מנהלים + add_owners: הוספת מנהלים api: generate_master: "ייצר מפתח מאסטר ל-API" none: "אין מפתחות API פעילים כרגע." @@ -1746,7 +1750,7 @@ he: revoke: "שלול" confirm_regen: "אתה בטוח שברצונך להחליף את מפתח ה-API באחד חדש?" confirm_revoke: "אתה בטוח שברצונך לשלול את המפתח הזה?" - info_html: "מפתח הAPI שלך יאפשר לך ליצור ולעדכן נושאים בעזרת קריאות JSON." + info_html: "מפתח הAPI שלך יאפשר לך ליצור ולעדכן פוסטים בעזרת קריאות JSON." all_users: "כל המשתמשים" note_html: "שמרו על מפתח זה סודי, כל משתמש שיחזיק בו יוכל לייצר פרסומים שרירותית, כאילו היה כל משתמש/ת אחרים." plugins: @@ -1808,11 +1812,9 @@ he: is_disabled: "שחזור אינו מאופשר לפי הגדרות האתר." label: "שחזר" title: "שחזר את הגיבוי" - confirm: "אתה בטוח שברצונך לשחזר את הגיבוי הזה?" rollback: label: "חזור לאחור" title: "הזחר את מסד הנתונים למצב עבודה קודם" - confirm: "אתה בטוח שברצונך להחזיר את מסד הנתונים למצב עבודה קודם?" export_csv: user_archive_confirm: "האם את/ה בטוח/ה שאתם רוצים להוריד את הפרסומים שלכם?" success: "יצוא החל, תקבלו הודעה כשהתהליך יסתיים" @@ -1863,6 +1865,13 @@ he: color: "צבע" opacity: "טשטוש" copy: "העתק" + email_templates: + title: "תבניות דואר אלקטרוני" + subject: "נושא" + body: "הודעה" + none_selected: "בחרו תבנית דואר אלקטרוני לעריכה." + revert: "ביטול שינויים" + revert_confirm: "האם ברצונכם לבטל את השינויים?" css_html: title: "CSS/HTML" long_title: "התאמת CSS ו-HTML" @@ -1897,23 +1906,19 @@ he: description: "טקסט ואייקונים בכותרת האתר." highlight: name: 'הדגשה' - description: 'צבע הרקע של אלמנטים מודגשים בעמוד, כמו הודעות ונושאים.' + description: 'צבע הרקע של אלמנטים מודגשים בעמוד, כמו הודעות ופוסטים.' danger: name: 'זהירות' - description: 'צבע הדגשה של פעולות כמו מחיקת הודעות ונושאים.' + description: 'צבע הדגשה של פעולות כמו מחיקת הודעות ופוסטים.' success: name: 'הצלחה' description: 'משמש כדי לסמן פעולה מוצלחת.' love: name: 'חבב' description: "צבע הרקע של הכפתור \"חבב\"" - wiki: - name: 'ויקי' - description: "צבעי יסוד משמשים כצבעי רקע בפרסומי ויקי." email: - title: "דואר אלקטרוני" settings: "הגדרות" - all: "הכל" + preview_digest: "תצוגה מקדימה של סיכום" sending_test: "שולח דואר אלקטרוני לבדיקה..." error: "שגיאה - %{server_error}" test_error: "הייתה בעיה בשליחת הדואר האלקטרוני. בבקשה בדוק את ההגדרות שלך ונסה שנית." @@ -1928,7 +1933,6 @@ he: send_test: "שליחת מייל בדיקה" sent_test: "נשלח!" delivery_method: "שיטת העברה" - preview_digest: "תצוגה מקדימה של סיכום" preview_digest_desc: "תצוגה מקדימה של מייל סיכום שנשלח למשתמשים לא פעילים. " refresh: "רענן" format: "פורמט" @@ -1953,8 +1957,9 @@ he: last_match_at: "הותאם לאחרונה" match_count: "תואם" ip_address: "IP" - topic_id: "זהות (ID) נושא" + topic_id: "זהות (ID) פוסט" post_id: "זהות (ID) פרסום" + category_id: "מזהה קטגוריה" delete: 'מחק' edit: 'ערוך' save: 'שמור' @@ -1990,11 +1995,14 @@ he: grant_badge: "הענק תג" revoke_badge: "שלול תג" check_email: "בדיקת דוא\"ל" - delete_topic: "מחיקת נושא" + delete_topic: "מחיקת פוסט" delete_post: "מחיקת פרסום" impersonate: "התחזה" anonymize_user: "הפיכת משתמש/ת לאנונימיים" roll_up: "roll up IP blocks" + change_category_settings: "שינוי הגדרות קטגוריה" + delete_category: "מחק קטגוריה" + create_category: "יצירת קטגוריה" screened_emails: title: "הודעות דואר מסוננות" description: "כשמישהו מנסה ליצור חשבון חדש, כתובות הדואר האלקטרוני הבאות ייבדקו וההרשמה תחסם או שיבוצו פעולות אחרות." @@ -2061,9 +2069,9 @@ he: pending: 'משתמשים שממתינים לבדיקה' newuser: 'משתמשים ברמת אמון 0 (משתמש חדש)' basic: 'משתמשים ברמת אמון 1 (משתמש בסיסי)' - regular: 'משתמשים בדרגת אמון 2 (חברים)' - leader: 'משתמשים בדרגת אמון 3 (רגילים)' - elder: 'משתמשים בדרגת אמון 4 (מובילים)' + member: 'משתמשים בדרגת אמון 2 (חברים)' + regular: 'משתמשים בדרגת אמון 3 (רגילים)' + leader: 'משתמשים בדרגת אמון 4 (מובילים)' staff: "צוות" admins: 'מנהלים ראשיים' moderators: 'מנהלים' @@ -2089,7 +2097,7 @@ he: suspend_reason: "סיבה" suspended_by: "הושעה על ידי" delete_all_posts: "מחק את כל ההודעות" - delete_all_posts_confirm: "אתה עומד למחוק %{posts} הודעות ו-%{topics} נושאים. אתה בטוח?" + delete_all_posts_confirm: "אתה עומד למחוק %{posts} הודעות ו-%{topics} פוסטים. אתה בטוח?" suspend: "השעה" unsuspend: "בטל השעייה" suspended: "מושעה?" @@ -2117,10 +2125,10 @@ he: activity: פעילות like_count: לייקים שהוענקו / התקבלו last_100_days: 'ב-100 הימים האחרונים' - private_topics_count: נושאים פרטיים + private_topics_count: פוסטים פרטיים posts_read_count: הודעות שנקראו post_count: הודעות שנוצרו - topics_entered: נושאים שנצפו + topics_entered: פוסטים שנצפו flags_given_count: דגלים שניתנו flags_received_count: סימונים שהתקבלו warnings_received_count: התקבלו אזהרות @@ -2162,7 +2170,7 @@ he: block_failed: 'הייתה בעיה בחסימת המשתמש.' deactivate_explanation: "חשבון משתמש מנוטרל נדרש לוודא דואר אלקטרוני מחדש." suspended_explanation: "משתמש מושעה לא יכול להתחבר." - block_explanation: "משתמש חסום לא יכול לפרסם הודעות או נושאים." + block_explanation: "משתמש חסום לא יכול לפרסם הודעות או פוסטים." trust_level_change_failed: "הייתה בעיה בשינוי רמת האמון של המשתמש." suspend_modal_title: "השעה משתמש" trust_level_2_users: "משתמשי רמת אמון 2" @@ -2173,14 +2181,13 @@ he: unlock_trust_level: "שחרור רמת אמון מנעילה" tl3_requirements: title: "דרישות עבור רמת אמון 3" - table_title: "במאה הימים האחרונים:" value_heading: "ערך" requirement_heading: "דרישה" visits: "ביקורים" days: "ימים" - topics_replied_to: "נושאים להם הגיבו" - topics_viewed: "נושאים שנצפו" - topics_viewed_all_time: "נושאים שנצפו (בכל זמן)" + topics_replied_to: "פוסטים להם הגיבו" + topics_viewed: "פוסטים שנצפו" + topics_viewed_all_time: "פוסטים שנצפו (בכל זמן)" posts_read: "פרסומים שנקראו" posts_read_all_time: "פרסומים שנקראו (בכל זמן)" flagged_posts: "הודעות מדוגללות" @@ -2234,7 +2241,6 @@ he: confirm: 'אישור' dropdown: "נגלל" site_text: - none: "בחרו את סוג התוכן לתחילת עריכה." title: 'תוכן טקסטואלי' site_settings: show_overriden: 'הצג רק הגדרות ששונו' @@ -2281,7 +2287,7 @@ he: modal_title: תג קבוצות granted_by: הוענק ע"י granted_at: הוענק ב - reason_help: (קישור לפרסום או לנושא) + reason_help: (קישור לפרסום או לפוסט) save: שמור delete: מחק delete_confirm: אתה בטוח שברצונך למחוק את התג הזה? @@ -2323,10 +2329,7 @@ he: bad_count_warning: header: "זהירות!" text: "ישנן דוגמאות הענקה חסרות. זה קורה כחיפוש תגים מחזיר זהות (ID) של משתמש או פרסום שאינם קיימים. זה עלול לגרום לתוצאות לא צפויות מאוחר יותר - אנא בדקו שוב את מחרוזת החיפוש שלכם." - grant_count: - zero: "אין תגים להקצאה." - one: "1 תגים להקצאה." - other: "%{count}תגים שנותרו להקצאה." + no_grant_count: "אין תגים להקצאה." sample: "דוגמא:" grant: with: %{username} @@ -2354,7 +2357,7 @@ he: feed_description: "לספק פיד RSS/ATOM לאתרך יכול לשפר את היכולת של דיסקורס ליבא את התוכן שלך." crawling_settings: "Crawler Settings" crawling_description: "When Discourse creates topics for your posts, if no RSS/ATOM feed is present it will attempt to parse your content out of your HTML. Sometimes it can be challenging to extract your content, so we provide the ability to specify CSS rules to make extraction easier." - embed_by_username: "שם משתמש ליצירת נושא" + embed_by_username: "שם משתמש ליצירת פוסט" embed_post_limit: "מספר מקסימלי של פרסומים להטמעה." embed_username_key_from_feed: "מפתח למשיכת שם המשתמש ב-discourse מהפיד." embed_truncate: "חיתוך הפרסומים המוטמעים." @@ -2366,8 +2369,8 @@ he: permalink: title: "קישורים קבועים" url: "כתובת" - topic_id: "מזהה לנושא" - topic_title: "נושא" + topic_id: "מזהה לפוסט" + topic_title: "פוסט" post_id: "מזהה לפרסום" post_title: "הודעה" category_id: "מזהה לקטגוריה" @@ -2400,28 +2403,28 @@ he: jump: '# מעבר לפרסום #' back: 'u חזרה' up_down: 'k/j Move selection ↑ ↓' - open: 'o או Enter פתח נושא נבחר' + open: 'o או Enter פתח פוסט נבחר' next_prev: 'shift+j/shift+kלחלק הבא/קודם' application: title: 'יישום' - create: 'c צור נושא חדש' + create: 'c צור פוסט חדש' notifications: 'n פתח התראות' hamburger_menu: '= פתח תפריט המבורגר' user_profile_menu: 'pפתיחת תפריט משתמש/ת' - show_incoming_updated_topics: '. הצגת נושאים שעודכנו' + show_incoming_updated_topics: '. הצגת פוסטים שעודכנו' search: '/ חיפוש' help: '? הצגת עזרת מקלדת' dismiss_new_posts: 'x, r שחרור הודעות/חדשות' - dismiss_topics: 'x, t שחרור נושאים' + dismiss_topics: 'x, t שחרור פוסטים' log_out: 'shift+z shift+z התנתק' actions: title: 'פעולות' - bookmark_topic: 'f החלפת נושא סימניה' - pin_unpin_topic: 'shift+pקיבוע/שחרור נושא' - share_topic: 'shift+s שיתוף הנושא' + bookmark_topic: 'f החלפת פוסט סימניה' + pin_unpin_topic: 'shift+pקיבוע/שחרור פוסט' + share_topic: 'shift+s שיתוף הפוסט' share_post: 's שיתוף הודעה' - reply_as_new_topic: 't תגובה כנושא מקושר' - reply_topic: 'shift+r תשובה לנושא' + reply_as_new_topic: 't תגובה כפוסט מקושר' + reply_topic: 'shift+r תשובה לפוסט' reply_post: 'r להגיב להודעה' quote_post: ' q ציטוט פוסט' like: 'l תן לייק להודעה' @@ -2429,14 +2432,12 @@ he: bookmark: 'b הוסף הודעה למועדפים' edit: 'e ערוך הודעה' delete: 'd מחק הודעה' - mark_muted: 'm, m השתקת נושא' - mark_regular: 'm, r נושא רגיל (ברירת מחדל)' - mark_tracking: 'm, t מעקב נושא' - mark_watching: 'm, wצפייה בנושא' + mark_muted: 'm, m השתקת פוסט' + mark_regular: 'm, r פוסט רגיל (ברירת מחדל)' + mark_tracking: 'm, t מעקב פוסט' + mark_watching: 'm, wצפייה בפוסט' badges: title: תגים - allow_title: "יכול לשמש ככותרת" - multiple_grant: "יכול להיות מוענק מספר פעמים" badge_count: one: "תג אחד" other: "%{count} תגים" @@ -2459,97 +2460,6 @@ he: name: אחר posting: name: פרסום - badge: - editor: - name: עורך - description: עריכה ראשונה של פוסט - basic_user: - name: בסיסי - description: מאושרות כל - member: - name: חבר/ה - description: הענקת הזמנות - regular: - name: רגיל/ה - description: הענקת קטרוג מחודש, שינוי שם, קישורים עוקבים ולאונג' - leader: - name: מוביל/ה - description: הענקת עריכה גלובלית, הצמדה, סגירה, ארכוב, פיצול ומיזוג - welcome: - name: ברוכים הבאים - description: קיבל לייק - autobiographer: - name: אוטוביוגרפר/ית? - description: פרופיל מידע משתמש - anniversary: - name: יום השנה - description: חבר/ה פעיל/ה במשך שנה, פרסמ/ה לפחות פעם אחת - nice_post: - name: פרסום נחמד - description: קיבל/ה 10 לייקים על הפוסט. תג זה ניתן להעניק שוב ושוב ללא הגבלה - good_post: - name: פרסום מוצלח - description: קיבל/ה 25 לייקים על הפוסט. תג זה ניתן להעניק שוב ושוב ללא הגבלה - great_post: - name: פרסום מצויין - description: קבלת 50 לייקים על פרסום. תג זה יכול להיות מוענק מספר פעמים - nice_topic: - name: נושא נחמד - description: קיבל/ה 10 לייקים על נושא. תג זה יכול להיות מוענק כמה פעמים - good_topic: - name: נושא טוב - description: קיבל/ה 25 לייקים על הנושא. תג זה יכול להיות מוענק כמה פעמים - great_topic: - name: נושא מצויין - description: קיבל/ה 50 לייקים על הנושא. תג זה יכול להיות מוענק מספר פעמים - nice_share: - name: שיתוף נחמד - description: שיתפ/ה פרסום עם 25 מבקרים ייחודיים - good_share: - name: שיתוף טוב - description: שיתפ/ה פרסום עם 300 מבקרים ייחודיים - great_share: - name: שיתוף מעולה - description: חלק/ה פרסום עם 1000 מבקרים ייחודיים - first_like: - name: לייק ראשון - description: חיבב/ה פרסום - first_flag: - name: סימון ראשון - description: סימן/סימנה פרסום - promoter: - name: מקדם - description: הזמן משתמש - campaigner: - name: קמפיינר - description: הזמן 3 משתמשים בסיסים (דרגת אמון 1) - champion: - name: אלוף - description: הזמן 5 משתמשים (דרגת אמון 2) - first_share: - name: שיתוף ראשון - description: שיתף/שיתפה פרסום - first_link: - name: קישור (link) ראשון - description: הוסיף/הוסיפה קישור פנימי לנושא אחר - first_quote: - name: ציטוט ראשון - description: ציטוט משתמש - read_guidelines: - name: קריאת כללים מנחים - description: קראו את הכללים המנחים של הקהילה - reader: - name: מקראה - description: קראו כל פרסום בנושא עם יותר מ-100 פרסומים - popular_link: - name: לינק פופלארי - description: פרסם קישור חיצוני עם לפחות 50 לחיצות - hot_link: - name: קישור חם - description: פרסם קישור חיצוני עם לפחות 300 לחיצות - famous_link: - name: קישור מפורסם - description: פרסם קישור חיצוני עם לפחות 1000 לחיצות google_search: |

    חפש עם גוגל

    diff --git a/config/locales/client.id.yml b/config/locales/client.id.yml index b3a559e5d62..32c523008af 100644 --- a/config/locales/client.id.yml +++ b/config/locales/client.id.yml @@ -8,22 +8,30 @@ id: js: number: + format: + separator: "." + delimiter: "," human: storage_units: format: '%n %u' units: byte: - other: Bytes + other: Bit gb: GB kb: KB mb: MB tb: TB + short: + thousands: "{{number}}k" + millions: "{{number}}M" dates: time: "j:mm a" long_no_year: "BBB H j:mm a" long_no_year_no_time: "BBB H" + full_no_year_no_time: "MMMM Do" long_with_year: "BBB H, TTTT j:mm a" long_with_year_no_time: "BBB H, TTTT" + full_with_year_no_time: "MMMM Do, YYYY" long_date_with_year: "BBB H, 'TT LT" long_date_without_year: "BBB H, LT" long_date_with_year_without_time: "BBB H, 'TT" @@ -66,6 +74,13 @@ id: other: "%{count} jam yang lalu" x_days: other: "%{count} hari yang lalu" + later: + x_days: + other: "%{count} hari kemudian" + x_months: + other: "%{count} bulan kemudian" + x_years: + other: "%{count} bulan kemudian" share: topic: 'share link ke topik ini' post: 'post #%{postNumber}' @@ -74,6 +89,27 @@ id: facebook: 'share link ini di Facebook' google+: 'share link ini di Google+' email: 'kirim link ini melalui email' + action_codes: + split_topic: "pisahkan topik ini %{when}" + autoclosed: + enabled: 'ditutup %{when}' + disabled: 'dibuka %{when}' + closed: + enabled: 'ditutup %{when}' + disabled: 'dibuka %{when}' + archived: + enabled: 'diarsipkan %{when}' + disabled: 'tidak diarsipkan %{when}' + pinned: + enabled: 'disematkan %{when}' + disabled: 'tidak disematkan %{when}' + pinned_globally: + enabled: 'disematkan secara global %{when}' + disabled: 'tidak disematkan %{when}' + visible: + enabled: 'terdaftar %{when}' + disabled: 'tidak terdaftar %{when}' + topic_admin_menu: "topik aksi admin" emails_are_disabled: "Semua surel yang keluar telah dinonaktifkan oleh administrator. Tidak ada pemberitahuan email yang akan dikirimkan." edit: 'Ubah judul dan kategori topik ini' not_implemented: "Maaf, fitur ini belum diimplementasikan." @@ -84,56 +120,68 @@ id: sign_up: "Daftar" log_in: "Log In" age: "Umur" - joined: "Joined" + joined: "Bergabung" admin_title: "Admin" flags_title: "Flags" - show_more: "show more" - links: "Links" + show_more: "tampilkan lebih banyak" + show_help: "pilihan" + links: "Tautan" + links_lowercase: + other: "tautan" faq: "FAQ" - guidelines: "Guidelines" - privacy_policy: "Privacy Policy" - privacy: "Privacy" - terms_of_service: "Terms of Service" - mobile_view: "Mobile View" - desktop_view: "Desktop View" - you: "Kamu" + guidelines: "Petunjuk" + privacy_policy: "Kebijakan Privasi" + privacy: "Privasi" + terms_of_service: "Ketentuan Layanan" + mobile_view: "Tampilan Mobile" + desktop_view: "Tampilan Desktop" + you: "Anda" or: "atau" - now: "just now" - read_more: 'read more' - more: "Selebihnya" + now: "baru saja" + read_more: 'baca selengkapnya' + more: "Selengkapnya" less: "Lebih Singkat" - never: "Tidak pernah" - daily: "Harian" - weekly: "Mingguan" - every_two_weeks: "Setiap dua minggu" - max_of_count: "Maksimal {{count}}" + never: "tidak pernah" + daily: "harian" + weekly: "mingguan" + every_two_weeks: "setiap dua minggu" + every_three_days: "setiap tiga hari" + max_of_count: "maksimal dari {{count}}" + alternation: "atau" character_count: other: "{{count}} karakter" suggested_topics: - title: "Suggested Topics" + title: "Topik Yang Disarankan" about: simple_title: "Tentang" title: "Tentang %{title}" - stats: "Statistik situs" + stats: "Statistik Situs" our_admins: "Admin Kami" our_moderators: "Moderator Kami" stat: - all_time: "Setiap Waktu" - last_7_days: "Selama 7 Hari" - last_30_days: "30 hari terakhir" + all_time: "Sepanjang Waktu" + last_7_days: "7 Hari Terakhir" + last_30_days: "30 Hari Terakhir" + like_count: "Suka" topic_count: "Topik" - post_count: "Post" + post_count: "Pos" user_count: "Pengguna Baru" active_user_count: "Pengguna Aktif" contact: "Kontak kami" + contact_info: "Pada kegiatan dari sebuah isu kritikal atau penting terjadi pada situs ini, silahkan kontak kami di %{contact_info}." bookmarked: - title: "Markah" + title: "Penandaan" + clear_bookmarks: "Bersihkan Penandaan" + help: + bookmark: "Klik untuk membuat penandaan pos pertama di topik ini" + unbookmark: "Klik untuk menghapus semua penandaan di topik ini" bookmarks: not_logged_in: "Maaf, anda harus masuk untuk menandai post" created: "Anda telah menandai post ini" not_bookmarked: "Anda telah membaca post ini; klik untuk menandainya" last_read: "Ini adalah post terakhir yang anda baca; klik untuk menandainya" remove: "Hilangkan penandaan" + confirm_clear: "Apakah anda yakin ingin membersihkan semua penandaan dari topik ini?" topic_count_latest: other: "{{count}} topik baru atau diperbarui." topic_count_unread: @@ -141,26 +189,39 @@ id: topic_count_new: other: "{{count}} topik baru." click_to_show: "Klik untuk menampilkan" - preview: "preview" - cancel: "cancel" + preview: "pratinjau" + cancel: "batal" save: "Simpan Perubahan" saving: "Menyimpan..." saved: "Tersimpan!" upload: "Unggah" uploading: "Mengunggah..." + uploading_filename: "Sedang Mengunggah {{filename}}..." uploaded: "Sudah Diunggah!" enable: "Aktifkan" disable: "Nonaktifkan" undo: "Batalkan perintah" revert: "Kembali ke awal" failed: "Gagal" + switch_to_anon: "Mode Anonim" + switch_from_anon: "Keluar Anonim" banner: - close: "Abaikan Banner ini." + close: "Abaikan banner ini." + edit: "Ubah banner ini >>" choose_topic: - none_found: "Tidak ada topik." + none_found: "Tidak ada topik ditemukan." title: search: "Cari Topik berdasarkan nama, url atau id:" placeholder: "tulis judul topik disini" + queue: + topic: "Topik:" + approve: 'Terima' + reject: 'Tolak' + delete_user: 'Hapus Pengguna' + title: "Membutuhan Persetujuan" + none: "Tidak ada pos untuk di pratinjau." + edit: "Ubah" + cancel: "Batal" user_action: user_posted_topic: "{{user}} memposting topik" you_posted_topic: "Anda memposting the topic" @@ -182,7 +243,6 @@ id: members: "Anggota" posts: "Post" alias_levels: - title: "Siapa yang dapat menggunakan grup ini sebagai alias?" nobody: "Tak seorangpun" only_admins: "Hanya admin" mods_and_admins: "Hanya moderator dan Admin" @@ -195,7 +255,6 @@ id: '4': "Topik" '7': "Disebutkan" '9': "Kutipan" - '10': "Bertanda Bintang" '11': "Edit" '12': "Item Terkirim" '13': "Kotak masuk" @@ -260,7 +319,6 @@ id: warnings_received: "peringatan" messages: all: "Semua" - unread: "Belum dibaca" change_password: success: "(surel terkirim)" in_progress: "(mengirimkan surel)" @@ -280,7 +338,9 @@ id: email_settings: "Email" email_digests: daily: "harian" + every_three_days: "setiap tiga hari" weekly: "mingguan" + every_two_weeks: "setiap dua minggu" auto_track_options: never: "tidak pernah" password: @@ -297,6 +357,7 @@ id: forgot_password: action: "Saya lupa password" login: + title: "Log In" email_placeholder: "email atau username" twitter: title: "dengan Twitter" @@ -310,6 +371,7 @@ id: bold_title: "Strong" italic_title: "Emphasis" link_title: "Hyperlink" + modal_cancel: "Batal" notifications: more: "lihat notifikasi sebelumnya" topic: @@ -331,28 +393,26 @@ id: attachment_too_large: "Maaf, file yang kamu unggah terlalu besar (ukuran maksimal {{max_size_kb}}kb)." image_upload_not_allowed_for_new_user: "Maaf, pengguna baru belum diperbolehkan mengunggah gambar." attachment_upload_not_allowed_for_new_user: "Maaf, pengguna baru belum diperbolehkan mengunggah lampiran." + controls: + more: "Selengkapnya" revisions: controls: first: "Revisi pertama" category: + edit_long: "Ubah" auto_close_units: "jam" + posts: "Pos" + likes: "Suka" users: "Pengguna" filters: new: - lower_title_with_count: - one: "1 baru" - other: "{{count}} baru" lower_title: "baru" - title: - zero: "Baru" - one: "Baru(1)" - other: "Baru ({{count}})" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" - other: "{{categoryName}} ({{count}})" help: "topik terakhir di kategori {{categoryName}}" + top: + all: + title: "Sepanjang Waktu" + all_time: "Sepanjang Waktu" admin_js: admin: title: 'Admin Discourse' @@ -360,12 +420,21 @@ id: dashboard: latest_version: "Terbaru" last_checked: "Terakhir dicek" + reports: + last_7_days: "7 Hari Terakhir" + last_30_days: "30 Hari Terakhir" + all_time: "Sepanjang Waktu" flags: system: "Sistem" groups: delete: "Hapus" delete_confirm: "Hapus grup ini?" + backups: + operations: + cancel: + label: "Batal" customize: + preview: "pratinjau" new: "New" new_style: "preview" delete: "Hapus" @@ -374,12 +443,23 @@ id: sent_test: "terkirim!" delivery_method: "Metode Pengiriman" html: "html" + logs: + edit: 'Ubah' users: not_found: "Maaf, username tersebut tidak ada ditemukan." active: "Aktif" + nav: + staff: 'Staf' + titles: + staff: "Staf" user: suspend_duration_units: "(hari)" suspend_reason: "Alasan" + approve: 'Terima' + delete: "Hapus Pengguna" + user_fields: + edit: "Ubah" + cancel: "Batal" site_settings: categories: users: 'Pengguna' @@ -395,3 +475,12 @@ id: search: '/ Cari' actions: title: 'Aksi' + google_search: | +

    Cari dengan Google

    +

    +

    +

    diff --git a/config/locales/client.it.yml b/config/locales/client.it.yml index 0ddad6637a0..ba6ef6b710a 100644 --- a/config/locales/client.it.yml +++ b/config/locales/client.it.yml @@ -100,6 +100,8 @@ it: x_years: one: "1 anno dopo" other: "%{count} anni dopo" + previous_month: 'Mese Precedente' + next_month: 'Mese Successivo' share: topic: 'Condividi un link a questa conversazione' post: 'messaggio n°%{postNumber}' @@ -109,6 +111,9 @@ it: google+: 'Condividi questo link su Google+' email: 'invia questo collegamento via email' action_codes: + split_topic: "ha separato questo argomento %{when}" + invited_user: "Invitato %{who} %{when}" + removed_user: "rimosso %{who} %{when}" autoclosed: enabled: 'chiuso %{when}' disabled: 'aperto %{when}' @@ -135,7 +140,7 @@ it: yes_value: "Sì" generic_error: "Spiacenti! C'è stato un problema." generic_error_with_reason: "Si è verificato un errore: %{error}" - sign_up: "Registrati" + sign_up: "Iscriviti" log_in: "Accedi" age: "Età" joined: "Iscritto" @@ -227,6 +232,7 @@ it: revert: "Ripristina" failed: "Fallito" switch_to_anon: "Modalità Anonima" + switch_from_anon: "Abbandona Anonimato" banner: close: "Nascondi questo banner." edit: "Modifica questo annuncio >>" @@ -249,7 +255,6 @@ it: one: "Questo argomento ha 1 messaggio in attesa di approvazione" other: "Questo argomento ha {{count}} messaggi in attesa di approvazione" confirm: "Salva Modifiche" - delete_prompt: "Sei sicuro di voler eliminare %{username}? Ciò cancellerà tutti i suoi messaggi e bloccherà il suo indirizzo email e l'IP." approval: title: "Il Messaggio Richiede Approvazione" description: "Abbiamo ricevuto il tuo messaggio ma prima che appaia è necessario che venga approvato da un moderatore. Per favore sii paziente." @@ -292,14 +297,26 @@ it: one: "1 utente" other: "%{count} utenti" groups: + empty: + posts: "Non ci sono messaggi dai membri di questo gruppo." + members: "Non ci sono membri in questo gruppo." + mentions: "Non ci sono menzioni a questo gruppo." + messages: "Non ci sono messaggi per questo gruppo." + topics: "Non ci sono argomenti da membri di questo gruppo." + add: "Aggiungi" + selector_placeholder: "Aggiungi membri" + owner: "proprietario" visible: "Il Gruppo è visibile a tutti gli utenti" title: one: "gruppo" other: "gruppi" members: "Membri" + topics: "Argomenti" posts: "Messaggi" + mentions: "Menzioni" + messages: "Messaggi" alias_levels: - title: "Chi può usare questo gruppo come alias?" + title: "Chi può inviare @menzionare e inviare messaggi a questo gruppo?" nobody: "Nessuno" only_admins: "Solo gli amministratori" mods_and_admins: "Solo i moderatori e gli amministratori" @@ -308,6 +325,19 @@ it: trust_levels: title: "Livello di esperienza automaticamente assegnato ai membri quando vengono aggiunti:" none: "Nessuno" + notifications: + watching: + title: "In osservazione" + description: "Verrai avvertito per ogni nuovo messaggio, e verrà mostrato il conteggio delle nuove risposte." + tracking: + title: "Seguendo" + description: "Verrai avvertito se qualcuno menziona il tuo @nome o ti risponde, e verrà mostrato un conteggio delle nuove risposte." + regular: + title: "Esperto" + description: "Verrai avvertito se qualcuno menziona il tuo @nome o ti risponde." + muted: + title: "Silenziato" + description: "Non verrai mai avvertito per i nuovi argomenti in questo gruppo." user_action_groups: '1': "Mi piace - Assegnati" '2': "Mi piace - Ricevuti" @@ -317,7 +347,6 @@ it: '6': "Risposte" '7': "Menzioni" '9': "Citazioni" - '10': "Preferiti" '11': "Modifiche" '12': "Inviati" '13': "Posta in arrivo" @@ -327,6 +356,7 @@ it: all_subcategories: "tutte" no_subcategory: "nessuno" category: "Categoria" + category_list: "Visualizza l'elenco delle categorie" reorder: title: "Riordina Categorie" title_long: "Riorganizza l'elenco di categorie" @@ -383,16 +413,14 @@ it: invited_by: "Invitato Da" trust_level: "Livello Esperienza" notifications: "Notifiche" + statistics: "Statistiche" desktop_notifications: label: "Notifiche Desktop" not_supported: "Spiacenti, le notifiche non sono supportate su questo browser." perm_default: "Attiva Notifiche" perm_denied_btn: "Permesso Negato" - perm_denied_expl: "Hai negato il permesso per le notifiche. Usa il browser per abilitare le notifiche, poi premi il bottone quando hai finito. (Per il desktop: l'icona più a sinistra sulla barra degli indirizzi. Mobile: 'Informazioni sul sito'.)" disable: "Disabilita Notifiche" - currently_enabled: "(attualmente attivate)" enable: "Abilita Notifiche" - currently_disabled: "(attualmente disabilitate)" each_browser_note: "Nota: devi modificare questa impostazione per ogni browser che utilizzi." dismiss_notifications: "Imposta tutti come Letti" dismiss_notifications_tooltip: "Imposta tutte le notifiche non lette come lette " @@ -416,7 +444,7 @@ it: tracked_categories: "Seguite" tracked_categories_instructions: "Seguirai automaticamente tutti i nuovi argomenti appartenenti a queste categorie. Di fianco all'argomento comparirà il conteggio dei nuovi messaggi." muted_categories: "Silenziate" - muted_categories_instructions: "Non ti verrà notificato nulla sui nuovi argomenti in queste categorie, e non compariranno nel tab dei non letti." + muted_categories_instructions: "Non ti verrà notificato nulla sui nuovi argomenti in queste categorie, e non compariranno nell'elenco Ultimi." delete_account: "Cancella il mio account" delete_account_confirm: "Sei sicuro di voler cancellare il tuo account in modo permanente? Questa azione non può essere annullata!" deleted_yourself: "Il tuo account è stato eliminato con successo." @@ -426,6 +454,7 @@ it: users: "Utenti" muted_users: "Silenziati" muted_users_instructions: "Occulta tutte le notifiche da questi utenti." + muted_topics_link: "Mostra argomenti silenziati" staff_counters: flags_given: "segnalazioni utili" flagged_posts: "messaggi segnalati" @@ -434,8 +463,14 @@ it: warnings_received: "avvisi" messages: all: "Tutti" - mine: "Miei" - unread: "Non letti" + inbox: "In arrivo" + sent: "Spediti" + archive: "Archiviati" + groups: "I Miei Gruppi" + bulk_select: "Seleziona messaggi" + move_to_inbox: "Sposta in arrivo" + failed_to_move: "Errore nello spostare i messaggi selezionati (forse la tua connessione non è attiva)" + select_all: "Seleziona Tutti" change_password: success: "(email inviata)" in_progress: "(invio email in corso)" @@ -480,10 +515,10 @@ it: ok: "Ti invieremo una email di conferma" invalid: "Inserisci un indirizzo email valido" authenticated: "{{provider}} ha autenticato la tua email" + frequency_immediately: "Ti invieremo immediatamente una email se non hai letto ciò per cui ti stiamo scrivendo." frequency: - zero: "Ti invieremo immediatamente una email se non hai letto ciò per cui ti stiamo scrivendo." - one: "Ti invieremo email solo se non ti abbiamo visto nell'ultimo minuto." - other: "Ti invieremo email solo se non ti abbiamo visto negli ultimi {{count}} minuti." + one: "TI invieremo un email solo se non ti avremo visto nell'ultimo minuto." + other: "Ti invieremo una email solo se non ti si vede da almeno {{count}} minuti." name: title: "Nome" instructions: "Nome completo (facoltativo)" @@ -519,6 +554,9 @@ it: title: "Targhetta Scheda Utente" website: "Sito Web" email_settings: "Email" + like_notification_frequency: + always: "Sempre" + never: "Mai" email_digests: title: "Quando non visito il sito, invia un riassunto delle novità per email: " daily: "ogni giorno" @@ -555,7 +593,9 @@ it: user: "Utente Invitato" sent: "Spedito" none: "Non ci sono inviti in sospeso da visualizzare." - truncated: "Mostro i primi {{count}} inviti." + truncated: + one: "Mostro il primo invito." + other: "Mostro i primi {{count}} inviti." redeemed: "Inviti Accettati" redeemed_tab: "Riscattato" redeemed_tab_with_count: "Riscattato ({{count}})" @@ -575,7 +615,7 @@ it: account_age_days: "Età dell'utente in giorni" create: "Invia un Invito" generate_link: "Copia il collegamento di invito" - generated_link_message: '

    Il link di invito è stato generato con successo!

    Il link sarà disponibile solo per l''email: %{invitedEmail}

    ' + generated_link_message: '

    Il collegamento di invito è stato generato con successo!

    Il collegamento sarà valido solo per la seguente email: %{invitedEmail}

    ' bulk_invite: none: "Non hai ancora invitato nessuno qui. Puoi inviare inviti individuali, o invitare un gruppo di persone caricando un file di invito di massa." text: "Invito di Massa da File" @@ -590,6 +630,15 @@ it: same_as_email: "La password coincide con l'email." ok: "La password è adeguata" instructions: "Minimo %{count} caratteri." + summary: + title: "Riepilogo" + stats: "Statistiche" + top_replies: "Migliori Risposte" + more_replies: "Altre Risposte" + top_topics: "Migliori Argomenti" + more_topics: "Altri Argomenti" + top_badges: "Migliori Targhette" + more_badges: "Altre Targhette" associated_accounts: "Login" ip_address: title: "Ultimo indirizzo IP" @@ -615,11 +664,13 @@ it: server: "Errore del Server" forbidden: "Accesso Negato" unknown: "Errore" + not_found: "Pagina Non Trovata" desc: network: "Per favore controlla la connessione." network_fixed: "Sembra essere tornato." server: "Codice di errore: {{status}}" forbidden: "Non hai i permessi per visualizzarlo." + not_found: "Oops, l'applicazione ha cercato di caricare una URL inesistente." unknown: "Qualcosa è andato storto." buttons: back: "Torna Indietro" @@ -630,8 +681,10 @@ it: logout: "Ti sei disconnesso." refresh: "Ricarica" read_only_mode: - enabled: "La modalità di sola lettura è attiva. Puoi continuare a navigare nel sito ma le interazioni potrebbero non funzionare." login_disabled: "L'accesso è disabilitato quando il sito è in modalità di sola lettura." + too_few_topics_and_posts_notice: "Cominciamo a discutere! Ci sono al momento %{currentTopics} / %{requiredTopics} argomenti e %{currentPosts} / %{requiredPosts} messaggi. I nuovi visitatori vogliono qualche discussione da leggere e a cui rispondere." + too_few_topics_notice: "Cominciamo a discutere! Ci sono al momento %{currentTopics} / %{requiredTopics} argomenti. I nuovi visitatori vogliono qualche discussione da leggere e a cui rispondere." + too_few_posts_notice: "Cominciamo a discutere! Ci sono al momento %{currentTopics} / %{requiredTopics} argomenti e %{currentPosts} / %{requiredPosts} messaggi. I nuovi visitatori vogliono qualche discussione da leggere e a cui rispondere." learn_more: "per saperne di più..." year: 'all''anno' year_desc: 'argomenti creati negli ultimi 365 giorni' @@ -648,10 +701,17 @@ it: replies_lowercase: one: risposta other: risposte + signup_cta: + sign_up: "Iscriviti" + hide_session: "Ricordamelo domani" + hide_forever: "no grazie" + hidden_for_session: "Ok, te lo chiederò domani. Puoi sempre usare \"Accedi\" per creare un account." + intro: "Ciao! :heart_eyes: A quanto pare ti sta piacendo la discussione, ma non sei ancora iscritto." + value_prop: "Quando hai un account ci ricordiamo esattamente cosa stavi leggendo, così potrai riprendere da dove ti eri fermato. Inoltre ricevi le notifiche, sia qui sia via email, ogni volta che ci saranno nuovi messaggi. Inoltre potrai metterei i \"Mi piace\" ai messaggi e condividerne l'apprezzamento. :heartbeat:" summary: enabled_description: "Stai visualizzando un riepilogo dell'argomento: è la comunità a determinare quali sono i messaggi più interessanti." - description: "Ci sono {{count}} risposte." - description_time: "Ci sono {{count}} risposte con un tempo stimato di lettura di {{readingTime}} minuti." + description: "Ci sono {{replyCount}} risposte." + description_time: "Ci sono {{replyCount}} risposte con un tempo stimato di lettura di {{readingTime}} minuti." enable: 'Riassumi Questo Argomento' disable: 'Mostra Tutti i Messaggi' deleted_filter: @@ -705,6 +765,9 @@ it: admin_not_allowed_from_ip_address: "Non puoi collegarti come amministratore dal quell'indirizzo IP." resend_activation_email: "Clicca qui per inviare nuovamente l'email di attivazione." sent_activation_email_again: "Ti abbiamo mandato un'altra email di attivazione su {{currentEmail}}. Potrebbero essere necessari alcuni minuti di attesa; assicurati di controllare anche la cartella dello spam." + to_continue: "Per favore accedi" + preferences: "Devi effettuare l'accesso per cambiare le impostazioni." + forgot: "Non ricordo i dettagli del mio account" google: title: "con Google" message: "Autenticazione tramite Google (assicurati che il blocco pop up non sia attivo)" @@ -727,15 +790,24 @@ it: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Maiusc' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "altro..." + options: "Opzioni" + whisper: "sussurra" add_warning: "Questo è un avvertimento ufficiale." + toggle_whisper: "Attiva/Disattiva Sussurri" posting_not_on_topic: "A quale argomento vuoi rispondere?" saving_draft_tip: "salvataggio..." saved_draft_tip: "salvato" saved_local_draft_tip: "salvato in locale" similar_topics: "Il tuo argomento è simile a..." drafts_offline: "bozze offline" + group_mentioned: "Usando {{group}}, stai per mandare una notifica a {{count}} persone." error: title_missing: "Il titolo è richiesto" title_too_short: "Il titolo deve essere lungo almeno {{min}} caratteri" @@ -758,7 +830,7 @@ it: show_edit_reason: "(aggiungi motivo della modifica)" reply_placeholder: "Scrivi qui. Per formattare il testo usa Markdown, BBCode o HTML. Trascina o incolla le immagini." view_new_post: "Visualizza il tuo nuovo messaggio." - saving: "Salvataggio..." + saving: "Salvataggio" saved: "Salvato!" saved_draft: "Hai un messaggio in bozza in sospeso. Seleziona per riprendere la modifica." uploading: "In caricamento..." @@ -773,6 +845,7 @@ it: link_description: "inserisci qui la descrizione del collegamento" link_dialog_title: "Inserisci il collegamento" link_optional_text: "titolo opzionale" + link_placeholder: "http://example.com \"testo opzionale\"" quote_title: "Citazione" quote_text: "Citazione" code_title: "Testo preformattato" @@ -785,10 +858,11 @@ it: heading_title: "Intestazione" heading_text: "Intestazione" hr_title: "Linea Orizzontale" - undo_title: "Annulla" - redo_title: "Ripeti" help: "Aiuto Inserimento Markdown" toggler: "nascondi o mostra il pannello di editing" + modal_ok: "OK" + modal_cancel: "Annulla" + cant_send_pm: "Spiacenti, non puoi inviare un messaggio a %{username}." admin_options_title: "Impostazioni dello staff opzionali per l'argomento" auto_close: label: "Tempo per auto-chiusura argomento:" @@ -805,9 +879,9 @@ it: more: "visualizza le notifiche precedenti" total_flagged: "totale argomenti segnalati" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -825,14 +899,15 @@ it: edited: "Modifica il tuo messaggio da" liked: "Ha assegnato un \"Mi piace\" al tuo messaggio" private_message: "Messaggio privato da" - invited_to_private_message: "Invitato ad una conversazione privata da" - invited_to_topic: "Invitato ad un argomento da" + invited_to_private_message: "Invitato a un messaggio privato da" + invited_to_topic: "Invitato a un argomento da" invitee_accepted: "Invito accettato da" moved_post: "Il tuo messaggio è stato spostato da" linked: "Collegamento al tuo messaggio" granted_badge: "Targhetta assegnata" popup: mentioned: '{{username}} ti ha menzionato in "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} ti ha menzionato in "{{topic}}" - {{site_title}}' quoted: '{{username}} ti ha citato in "{{topic}}" - {{site_title}}' replied: '{{username}} ti ha risposto in "{{topic}}" - {{site_title}}' posted: '{{username}} ha pubblicato in "{{topic}}" - {{site_title}}' @@ -844,16 +919,25 @@ it: from_my_computer: "Dal mio dispositivo" from_the_web: "Dal web" remote_tip: "collegamento all'immagine" - remote_tip_with_attachments: "collegamento ad un'immagine o a un file ({{authorized_extensions}})" + remote_tip_with_attachments: "collegamento all'immagine o al file {{authorized_extensions}}" local_tip: "seleziona immagini dal tuo dispositivo" - local_tip_with_attachments: "seleziona immagini o file dal tuo dispositivo ({{authorized_extensions}})" + local_tip_with_attachments: "seleziona immagini o file dal tuo dispositivo {{authorized_extensions}}" hint: "(puoi anche trascinarle nell'editor per caricarle)" + hint_for_supported_browsers: "puoi fare il \"trascina e rilascia\" o incollare immagini nell'editor" uploading: "In caricamento" select_file: "Seleziona File" image_link: "collegamento a cui la tua immagine punterà" search: + sort_by: "Ordina per" + relevance: "Rilevanza" + latest_post: "Ultimo Messaggio" + most_viewed: "Più Visti" + most_liked: "Con più \"Mi Piace\"" select_all: "Seleziona Tutto" clear_all: "Cancella Tutto" + result_count: + one: "1 risultato per \"{{term}}\"" + other: "{{count}} risultati per \"{{term}}\"" title: "cerca argomenti, messaggi, utenti o categorie" no_results: "Nessun risultato trovato." no_more_results: "Nessun altro risultato trovato." @@ -872,12 +956,14 @@ it: current_user: 'vai alla pagina utente' topics: bulk: + unlist_topics: "Deselezione Topics" reset_read: "Reimposta Lettura" delete: "Elimina Argomenti" - dismiss_posts: "Chiudi Messaggi" - dismiss_posts_tooltip: "Azzera il contatore dei messaggi non-letti di questi argomenti, ma quando vengono creati nuovi messaggi continua a mostrarli nella mia lista dei non-letti " - dismiss_topics: "Chiudi Argomenti" - dismiss_topics_tooltip: "Quando viene creato un nuovo messaggio, non mostrare più questi argomenti nella mia lista dei non-letti " + dismiss: "Chiudi" + dismiss_read: "Chiudi tutti i non letti" + dismiss_button: "Chiudi..." + dismiss_tooltip: "Chiudi solo gli ultimi messaggi o smetti di seguire gli argomenti" + also_dismiss_topics: "Smetti di seguire questi argomenti così che non compariranno più come non letti per me" dismiss_new: "Chiudi Nuovo" toggle: "commuta la selezione multipla degli argomenti" actions: "Azioni Multiple" @@ -900,9 +986,6 @@ it: category: "Non ci sono argomenti in {{category}}." top: "Non ci sono argomenti di punta." search: "Non ci sono risultati della ricerca." - educate: - new: '

    Qui compaiono i tuoi nuovi argomenti.

    Per difetto, gli argomenti creati negli ultimi 2 giorni saranno considerati nuovi e mostreranno l''indicatore nuovo.

    Puoi cambiare questa configurazione nelle tue preferenze.

    ' - unread: '

    Qui compaiono i tuoi argomenti non letti.

    Per difetto, gli argomenti sono considerati non letti e mostrano un conteggio di non lettura 1 se hai:

    • Creato l''argomento
    • Risposto all''argomento
    • Letto l''argomento per più di 4 minuti

    Oppure se hai esplicitamente impostato l''argomento come Seguito o Osservato usando il pannello di controllo delle notifiche in fondo ad ogni argomento.

    Puoi cambiare questa configurazione nelle tue preferenze.

    ' bottom: latest: "Non ci sono altri argomenti più recenti." hot: "Non ci sono altri argomenti caldi." @@ -916,12 +999,18 @@ it: search: "Non ci sono altri risultati di ricerca." topic: unsubscribe: - stop_notifications: "Da ora riceverai meno notifiche su {{title}}" + stop_notifications: "Da ora riceverai meno notifiche per {{title}}" change_notification_state: "Lo stato delle tue notifiche è" filter_to: "{{post_count}} suoi messaggi" create: 'Nuovo Argomento' create_long: 'Crea un nuovo Argomento' private_message: 'Inizia a scrivere un messaggio' + archive_message: + help: 'Sposta il messaggio nel tuo archivio' + title: 'Archivio' + move_to_inbox: + title: 'Sposta in arrivo' + help: 'Sposta in arrivo' list: 'Argomenti' new: 'nuovo argomento' unread: 'non letto' @@ -960,7 +1049,7 @@ it: toggle_information: "commuta i dettagli dell'argomento" read_more_in_category: "Vuoi saperne di più? Leggi altri argomenti in {{catLink}} o {{latestLink}}." read_more: "Vuoi saperne di più? {{catLink}} o {{latestLink}}." - read_more_MF: "{ UNREAD, plural, =0 {} one { un argomento non letto } other { # argomenti non letti } } { NEW, plural, =0 {} one { {BOTH, select, true{e } false {} other{}} uno nuovo } other { {BOTH, select, true{e } false {} other{}} # nuovi } } oppure {CATEGORY, select, true {visualizza altri argomenti nella categoria \"{catLink}\"} false {{latestLink}} other {}}" + read_more_MF: "{ UNREAD, plural, =0 {} one { C'è 1 argomento non letto } other { Ci sono # argomenti non letti } } { NEW, plural, =0 {} one { {BOTH, select, true{e } false {è } other{}} 1 nuovo argomento} other { {BOTH, select, true{e } false {sono } other{}} # nuovi; argomenti} } restanti, o {CATEGORY, select, true {visualizza altri argomenti in {catLink}} false {{latestLink}} other {}}" browse_all_categories: Scorri tutte le categorie view_latest_topics: visualizza gli argomenti più recenti suggest_create_topic: Perché non crei un argomento? @@ -972,6 +1061,7 @@ it: auto_close_title: 'Impostazioni di auto-chiusura' auto_close_save: "Salva" auto_close_remove: "Non chiudere automaticamente questo argomento" + auto_close_immediate: "L'ultimo messaggio in questo argomento ha già %{hours}, pertanto l'argomento verrà chiuso immediatamente." progress: title: Avanzamento dell'argomento go_top: "alto" @@ -1021,7 +1111,7 @@ it: description: "Non ti verrà notificato nulla per questo messaggio." muted: title: "Silenziato" - description: "Non ti verrà notificato nulla di questo argomento e non comparirà nella tab dei non letti." + description: "Non riceverai mai notifiche o altro circa questo argomento e non apparirà nella sezione Ultimi." actions: recover: "Ripristina Argomento" delete: "Cancella Argomento" @@ -1057,31 +1147,30 @@ it: success_message: 'Hai segnalato questo argomento con successo.' feature_topic: title: "Poni argomento in primo piano" - pin: "Metti questo argomento in cima alla categoria \"{{categoryLink}}\" fino al" + pin: "Poni questo argomento in cima alla categoria {{categoryLink}} fino a" confirm_pin: "Hai già {{count}} argomenti puntati. Troppi argomenti puntati potrebbero essere un peso per gli utenti nuovi o anonimi. Sicuro di voler puntare un altro argomento in questa categoria?" unpin: "Rimuovi questo argomento dalla cima della categoria {{categoryLink}}." - unpin_until: "Rimuovi questo argomento dalla cima della categoria {{categoryLink}} o attendi fino al %{until}." + unpin_until: "Rimuovi questo argomento dalla cima della categoria {{categoryLink}} o attendi fino a %{until}." pin_note: "Gli utenti possono spuntare gli argomenti individualmente per loro stessi." - pin_validation: "È richiesta una data per appuntare questo argomento" + pin_validation: "È richiesta una data per appuntare questo argomento." + not_pinned: "Non ci sono argomenti appuntati in {{categoryLink}}." already_pinned: - zero: "Non ci sono argomenti puntati in {{categoryLink}}." - one: "Argomenti attualmente puntati in {{categoryLink}}: 1." - other: "Argomenti attualmente puntati in {{categoryLink}}: {{count}}." - pin_globally: "Metti questo argomento in cima a tutte le liste di messaggi fino al" + one: "Argomenti attualmente appuntati in {{categoryLink}}: 1" + other: "Argomenti attualmente appuntati in {{categoryLink}}: {{count}}" + pin_globally: "Poni questo argomento in cima a tutte le liste di argomenti fino a" confirm_pin_globally: "Hai già {{count}} argomenti puntati globalmente. Troppi argomenti puntati potrebbero essere un peso per gli utenti nuovi o anonimi. Sicuro di voler puntare un altro argomento globalmente?" unpin_globally: "Togli questo argomento dalla cima degli altri argomenti." - unpin_globally_until: "Rimuovi questo argomento dalla cima di tutte le liste di argomenti o attenti fino al %{until}." + unpin_globally_until: "Rimuovi questo argomento dalla cima di tutte le liste di argomenti o attendi fino a %{until}." global_pin_note: "Gli utenti possono spuntare gli argomenti autonomamente per loro stessi." + not_pinned_globally: "Non ci sono argomenti appuntati globalmente." already_pinned_globally: - zero: "Non ci sono argomenti puntati globalmente." - one: "Argomenti attualmente puntati globalmente: 1." - other: "Argomenti attualmente puntati globalmente: {{count}}." + one: "Argomenti attualmente appuntati globalmente in {{categoryLink}}: 1" + other: "Argomenti attualmente appuntati globalmente {{categoryLink}}: {{count}}" make_banner: "Rendi questo argomento uno striscione che apparirà in cima a tutte le pagine." remove_banner: "Rimuovi lo striscione che appare in cima a tutte le pagine." banner_note: "Gli utenti possono rimuovere lo striscione chiudendolo. Solo un argomento alla volta può diventare uno striscione." - already_banner: - zero: "Non c'è alcun argomento striscione." - one: "Al momento c'è un argomento striscione." + no_banner_exists: "Non c'è alcun argomento annuncio." + banner_exists: "C'è attualmente un argomento annuncio." inviting: "Sto invitando..." automatically_add_to_groups_optional: "Questo invito include anche l'accesso ai seguenti gruppi: (opzionale, solo amministratori)" automatically_add_to_groups_required: "Questo invito include anche l'accesso ai seguenti gruppi: (Richiesto, solo amministratori)" @@ -1093,21 +1182,22 @@ it: success: "Abbiamo invitato l'utente a partecipare a questo messaggio." error: "Spiacenti, si è verificato un errore durante l'invito dell'utente." group_name: "nome gruppo" + controls: "Impostazioni Argomento" invite_reply: title: 'Invita' username_placeholder: "nome utente" action: 'Invia Invito' - help: 'invita altri su questo argomento via email o notifiche' + help: 'invita altri su questo argomento via email o tramite notifiche' to_forum: "Invieremo una breve email che permetterà al tuo amico di entrare subito cliccando un collegamento, senza bisogno di effettuare il collegamento." sso_enabled: "Inserisci il nome utente della persona che vorresti invitare su questo argomento." to_topic_blank: "Inserisci il nome utente o l'indirizzo email della persona che vorresti invitare su questo argomento." - to_topic_email: "Hai inserito un indirizzo email. Manderemo una email di invito che permettterà al tuo amico di rispondere subito a questo argomento." - to_topic_username: "Hai inserito un nome utente. Gli mandermo una notifica con un link per invitarlo su questo argomento." - to_username: "Inserisci il nome utente della persona che vorresti invitare. Gli manderemo una notifica con un link di invito a questo argomento." + to_topic_email: "Hai inserito un indirizzo email. Invieremo una email di invito che permetterà al tuo amico di rispondere subito a questo argomento." + to_topic_username: "Hai inserito un nome utente. Gli invieremo una notifica con un collegamento per invitarlo su questo argomento." + to_username: "Inserisci il nome utente della persona che vorresti invitare. Gli invieremo una notifica con un collegamento di invito a questo argomento." email_placeholder: 'nome@esempio.com' - success_email: "Abbiamo mandato un invito via email a {{emailOrUsername}}. Ti avvertiremo quando l'invito verrà riscattato. Controlla la sezione \"inviti\" sulla tua pagina utente per tracciare lo stato degli inviti." + success_email: "Abbiamo inviato un invito via email a {{emailOrUsername}}. Ti avvertiremo quando l'invito verrà riscattato. Controlla la sezione \"inviti\" sulla tua pagina utente per tracciarne lo stato." success_username: "Abbiamo invitato l'utente a partecipare all'argomento." - error: "Spiacente, non siamo riusciti ad invitare questa persona. Forse è stata già invitata? (Gli inviti sono limitati)" + error: "Spiacenti, non siamo riusciti ad invitare questa persona. E' stata per caso già invitata (gli inviti sono limitati)? " login_reply: 'Collegati per Rispondere' filters: n_posts: @@ -1115,7 +1205,7 @@ it: other: "{{count}} messaggi" cancel: "Rimuovi filtro" split_topic: - title: "Sposta in un Nuovo Argomento" + title: "Sposta in un nuovo argomento" action: "sposta in un nuovo argomento" topic_name: "Nome Nuovo Argomento" error: "Si è verificato un errore spostando il messaggio nel nuovo argomento." @@ -1144,7 +1234,7 @@ it: action: "cambia timestamp" invalid_timestamp: "Il timestamp non può essere nel futuro." error: "Errore durante la modifica del timestamp dell'argomento." - instructions: "Seleziona un nuovo timestamp per l'argomento. I messaggi nell'argomento saranno aggiornati senza modificare l'intervallo di tempo" + instructions: "Seleziona il nuovo timestamp per l'argomento. I messaggi nell'argomento saranno aggiornati in modo che abbiano lo stesso intervallo temporale." multi_select: select: 'scegli' selected: 'selezionati ({{count}})' @@ -1174,23 +1264,23 @@ it: other: "(messaggio eliminato dall'autore, verrà automaticamente cancellato in %{count} ore se non segnalato)" expand_collapse: "espandi/raggruppa" gap: - one: "visualizza 1 riposta nascosta" + one: "visualizza 1 risposta nascosta" other: "visualizza {{count}} riposte nascoste" more_links: "{{count}} altri..." unread: "Messaggio non letto" has_replies: - one: "Una risposta" - other: "{{count}} risposte" + one: "{{count}} Risposta" + other: "{{count}} Risposte" has_likes: - one: "Un \"Mi piace\"" + one: "{{count}} \"Mi piace\"" other: "{{count}} \"Mi piace\"" has_likes_title: - one: "A una persona piace questo messaggio" - other: "A {{count}} persone piace questo messaggio" + one: "Una persona ha messo \"Mi piace\" a questo messaggio" + other: "{{count}} persone hanno messo \"Mi piace\" a questo messaggio" + has_likes_title_only_you: "hai messo \"Mi piace\" a questo messaggio" has_likes_title_you: - zero: "Ti è piaciuto questo messaggio" - one: "A te e ad un'altra persona è piaciuto questo messaggio" - other: "A te e ad altre {{count}} persone è piaciuto questo messaggio" + one: "tu e un'altra persona avete messo \"Mi piace\" a questo messaggio" + other: "tu e altre {{count}} persone avete messo \"Mi piace\" a questo messaggio" errors: create: "Spiacenti, si è verificato un errore nel creare il tuo messaggio. Prova di nuovo." edit: "Spiacenti, si è verificato un errore nel modificare il tuo messaggio. Prova di nuovo." @@ -1210,7 +1300,7 @@ it: via_email: "questo messaggio è arrivato via email" whisper: "questo messaggio è un sussurro privato per i moderatori" wiki: - about: "questo messaggio è una guida; gli utenti base possono modificarla" + about: "questo messaggio è una guida" archetypes: save: 'Opzioni di salvataggio' controls: @@ -1220,7 +1310,7 @@ it: undo_like: "rimuovi il \"Mi piace\"" edit: "modifica questo messaggio" edit_anonymous: "Spiacente, effettua l'accesso per poter modificare questo messaggio." - flag: "segnala privatamente questo post o invia una notifica privata" + flag: "segnala privatamente questo messaggio o invia una notifica privata" delete: "cancella questo messaggio" undelete: "recupera questo messaggio" share: "condividi un collegamento a questo messaggio" @@ -1238,6 +1328,7 @@ it: revert_to_regular: "Rimuovi Colore Staff" rebake: "Ricrea HTML" unhide: "Mostra nuovamente" + change_owner: "Cambia Proprietà" actions: flag: 'Segnala' defer_flags: @@ -1259,17 +1350,10 @@ it: like: "Annulla il \"Mi piace\"" vote: "Rimuovi voto" people: - off_topic: "{{icons}} l'hanno segnalato come fuori tema" - spam: "{{icons}} l'hanno segnalato come spam" - spam_with_url: "{{icons}} ha segnalato questo come spam" - inappropriate: "{{icons}} l'hanno segnalato come inappropriato" - notify_moderators: "{{icons}} hanno informato i moderatori" - notify_moderators_with_url: "{{icons}} hanno informato i moderatori" - notify_user: "{{icons}} ha inviato un messaggio" - notify_user_with_url: "{{icons}} ha inviato un messaggio" - bookmark: "{{icons}} l'hanno inserito nei segnalibri" - like: "A {{icons}} è piaciuto" - vote: "{{icons}} l'hanno votato" + off_topic: "l'hanno segnalato come fuori tema" + spam: "l'hanno segnalato come spam" + inappropriate: "l'hanno segnalato come inappropriato" + notify_moderators: "hanno informato i moderatori" by_you: off_topic: "L'hai segnalato come fuori tema" spam: "L'hai segnalato come spam" @@ -1329,10 +1413,6 @@ it: vote: one: "Una persona ha votato per questo post" other: "{{count}} persone hanno votato per questo post" - edits: - one: 1 modifica - other: "{{count}} modifiche" - zero: nessuna modifica delete: confirm: one: "Sei sicuro di voler cancellare questo messaggio?" @@ -1366,7 +1446,7 @@ it: view: 'Visualizza Argomenti della Categoria' general: 'Generale' settings: 'Impostazioni' - topic_template: "Modello di argomento" + topic_template: "Modello di Argomento" delete: 'Elimina Categoria' create: 'Crea Categoria' create_long: 'Crea una nuova categoria' @@ -1392,6 +1472,7 @@ it: change_in_category_topic: "Modifica Descrizione" already_used: 'Questo colore è già stato usato in un''altra categoria.' security: "Sicurezza" + special_warning: "Attenzione: questa è una categoria predefinita e le impostazioni di sicurezza ne vietano la modifica. Se non vuoi usare questa categoria, cancellala invece di modificarla." images: "Immagini" auto_close_label: "Chiudi automaticamente l'argomento dopo:" auto_close_units: "ore" @@ -1399,7 +1480,7 @@ it: email_in_allow_strangers: "Accetta email da utenti anonimi senza alcun account" email_in_disabled: "Le Impostazioni Sito non permettono di creare nuovi argomenti via email. Per abilitare la creazione di argomenti via email," email_in_disabled_click: 'abilita l''impostazione "email entrante".' - suppress_from_homepage: "Elimina questa categoria dalla homepage" + suppress_from_homepage: "Elimina questa categoria dalla homepage." allow_badges_label: "Permetti che le targhette vengano assegnate in questa categoria" edit_permissions: "Modifica Permessi" add_permission: "Aggiungi Permesso" @@ -1412,19 +1493,18 @@ it: notifications: watching: title: "In osservazione" - description: "Osserverai automaticamente tutti i nuovi argomenti in queste categorie. Riceverai notifiche su tutti i nuovi messaggi e argomenti e per tali argomenti apparirà il conteggio delle nuove risposte." + description: "Osserverai automaticamente tutti i nuovi argomenti presenti in queste categorie. Riceverai notifiche per ogni nuovo messaggio inserito in ogni argomento e apparirà il conteggio delle nuove risposte." tracking: title: "Seguendo" - description: "Seguirai automaticamente tutti i nuovi argomenti in queste categorie. Per tali argomenti apparirà un conteggio delle nuove risposte." + description: "Seguirai automaticamente tutti i nuovi argomenti in tali categorie. Ti verrà inviata una notifica se qualcuno menziona il tuo @nome o ti risponde, e apparirà un conteggio delle nuove risposte." regular: title: "Normale" description: "Riceverai una notifica se qualcuno menziona il tuo @nome o ti risponde." muted: title: "Silenziato" - description: "Non ti verrà notificato nulla sui nuovi argomenti di queste categorie, e non compariranno nella tua tab dei non letti." + description: "Non ti verrà mai notificato nulla sui nuovi argomenti di queste categorie, e non compariranno nell'elenco dei Non letti." flagging: title: 'Grazie per aiutarci a mantenere la nostra comunità civile!' - private_reminder: 'le segnalazioni sono private, visibili soltanto allo staff ' action: 'Segnala Messaggio' take_action: "Procedi" notify_action: 'Messaggio' @@ -1474,7 +1554,7 @@ it: help: "Questo argomento è per te spuntato; verrà mostrato con l'ordinamento di default" pinned_globally: title: "Appuntato Globalmente" - help: "Questo argomento è appuntato globalmente; verrà mostrato in cima ad ogni lista" + help: "Questo argomento è appuntato globalmente; verrà mostrato in cima all'elenco Ultimi e nella sua categoria." pinned: title: "Appuntato" help: "Questo argomento è per te appuntato; verrà mostrato con l'ordinamento di default" @@ -1486,10 +1566,10 @@ it: posts_likes_MF: | Questo argomento ha {count, plural, one {1 risposta} other {# risposte}} {ratio, select, low {con un alto rapporto "mi piace" / messaggi} med {con un altissimo rapporto "mi piace" / messaggi} high {con un estremamente alto rapporto "mi piace" / messaggi} other {}} original_post: "Messaggio Originale" - views: "Visualizzazioni" + views: "Visite" views_lowercase: - one: "vista" - other: "viste" + one: "visita" + other: "visite" replies: "Risposte" views_long: "questo argomento è stato visualizzato {{number}} volte" activity: "Attività" @@ -1513,8 +1593,8 @@ it: with_topics: "%{filter} argomenti" with_category: "%{filter} %{category} argomenti" latest: - title: - zero: "Ultimi" + title: "Ultimi" + title_with_count: one: "Ultimo (1)" other: "Ultimi ({{count}})" help: "argomenti con messaggi recenti" @@ -1532,8 +1612,8 @@ it: title_in: "Categoria - {{categoryName}}" help: "tutti gli argomenti raggruppati per categoria" unread: - title: - zero: "Non letti" + title: "Non letti" + title_with_count: one: "Non letto (1)" other: "Non letti ({{count}})" help: "argomenti che stai osservando o seguendo contenenti messaggi non letti" @@ -1545,8 +1625,8 @@ it: one: "1 nuovo" other: "{{count}} nuovi" lower_title: "nuovo" - title: - zero: "Nuovi" + title: "Nuovi" + title_with_count: one: "Nuovo (1)" other: "Nuovi ({{count}})" help: "argomenti creati negli ultimi giorni" @@ -1557,8 +1637,8 @@ it: title: "Segnalibri" help: "argomenti che hai aggiunto ai segnalibri" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "ultimi argomenti nella categoria {{categoryName}}" @@ -1720,15 +1800,24 @@ it: delete_confirm: "Cancellare questo gruppo?" delete_failed: "Impossibile cancellare il gruppo. Se questo è un gruppo automatico, non può essere eliminato." delete_member_confirm: "Rimuovere '%{username}' dal gruppo '%{group}'?" + delete_owner_confirm: "Rimuovere i privilegi per '%{username}'?" name: "Nome" add: "Aggiungi" add_members: "Aggiungi membri" custom: "Personalizzato" + bulk_complete: "Gli utenti sono stati aggiunti al gruppo." + bulk: "Aggiunta Massiva al Gruppo" + bulk_paste: "Incolla una lista di nomi utente o di email, uno per riga:" + bulk_select: "(seleziona un gruppo)" automatic: "Automatico" automatic_membership_email_domains: "Gli utenti che si registrano con un dominio email che corrisponde esattamente a uno presente in questa lista, saranno aggiunti automaticamente a questo gruppo:" automatic_membership_retroactive: "Applica la stessa regola sul dominio email per aggiungere utenti registrati esistenti" default_title: "Titolo predefinito per tutti gli utenti di questo gruppo" - primary_group: "Imposta automaticamente un gruppo principale" + primary_group: "Imposta automaticamente come gruppo principale" + group_owners: Proprietari + add_owners: Aggiungi proprietari + incoming_email: "Indirizzo email personalizzato" + incoming_email_placeholder: "inserisci l'indirizzo e-mail" api: generate_master: "Genera una Master API Key" none: "Non ci sono chiavi API attive al momento." @@ -1802,11 +1891,9 @@ it: is_disabled: "Il ripristino è disabilitato nelle opzioni del sito." label: "Ripristina" title: "Ripristina il backup" - confirm: "Sicuro di voler ripristinare questo backup?" rollback: label: "Rollback" title: "Ripristina il database a una versione funzionante precedente" - confirm: "Sicuro di voler ripristinare una precedente versione funzionante del database?" export_csv: user_archive_confirm: "Sei sicuro di voler scaricare i tuoi messaggi?" success: "Esportazione iniziata, verrai avvertito con un messaggio al termine del processo." @@ -1831,7 +1918,7 @@ it: header: "Intestazione" top: "Alto" footer: "Fondo pagina" - embedded_css: "CSS inclusi" + embedded_css: "CSS incorporato" head_tag: text: "" title: "HTML da inserire prima del tag " @@ -1857,6 +1944,14 @@ it: color: "Colore" opacity: "Opacità" copy: "Copia" + email_templates: + title: "Modelli e-mail" + subject: "Oggetto" + multiple_subjects: "Questo modello email ha più di un campo oggetto." + body: "Corpo" + none_selected: "Scegli un modello di e-mail per iniziare la modifica." + revert: "Annulla Cambiamenti" + revert_confirm: "Sei sicuro di voler annullare i cambiamenti?" css_html: title: "CSS/HTML" long_title: "Personalizzazioni CSS e HTML" @@ -1901,13 +1996,10 @@ it: love: name: 'amo' description: "Il colore del bottone \"Mi piace\"." - wiki: - name: 'wiki' - description: "Colore base usato per lo sfondo dei messaggi wiki." email: - title: "Email" settings: "Impostazioni" - all: "Tutto" + templates: "Template" + preview_digest: "Anteprima Riassunto" sending_test: "Invio email di prova in corso..." error: "ERRORE - %{server_error}" test_error: "C'è stato un problema nell'invio dell'email di test. Controlla nuovamente le impostazioni email, verifica che il tuo host non blocchi le connessioni email e riprova." @@ -1922,7 +2014,7 @@ it: send_test: "Invia una email di prova" sent_test: "inviata!" delivery_method: "Metodo di consegna" - preview_digest: "Anteprima Riassunto" + preview_digest_desc: "Vedi in anteprima il contenuto delle email di riassunto inviate agli utenti inattivi." refresh: "Aggiorna" format: "Formato" html: "html" @@ -1948,6 +2040,7 @@ it: ip_address: "IP" topic_id: "ID argomento" post_id: "ID messaggio" + category_id: "ID categoria" delete: 'Cancella' edit: 'Modifica' save: 'Salva' @@ -1978,6 +2071,7 @@ it: change_site_setting: "modifica le impostazioni del sito" change_site_customization: "modifica la personalizzazione del sito" delete_site_customization: "cancella la personalizzazione del sito" + change_site_text: "cambia il testo del sito" suspend_user: "utente sospeso" unsuspend_user: "utente riattivato" grant_badge: "assegna targhetta" @@ -1988,6 +2082,9 @@ it: impersonate: "impersona" anonymize_user: "rendi anonimo l'utente " roll_up: "inibisci blocchi di indirizzi IP" + change_category_settings: "cambia le impostazioni della categoria" + delete_category: "cancella categoria" + create_category: "crea categoria" screened_emails: title: "Email Scansionate" description: "Quando qualcuno cerca di creare un nuovo account, verrando controllati i seguenti indirizzi email e la registrazione viene bloccata, o eseguita qualche altra azione." @@ -2054,9 +2151,9 @@ it: pending: 'Revisione degli utenti in sospeso' newuser: 'Utenti con Livello Esperienza 0 (Nuovo)' basic: 'Utenti con Livello Esperienza 1 (Base)' - regular: 'Utenti al Livello Esperienza 2 (Assiduo)' - leader: 'Utenti al Livello Esperienza 3 (Esperto)' - elder: 'Utenti al Livello Esperienza 4 (Veterano)' + member: 'Utenti al Livello Esperienza 2 (Assiduo)' + regular: 'Utenti al Livello Esperienza 3 (Esperto)' + leader: 'Utenti al Livello Esperienza 4 (Veterano)' staff: "Staff" admins: 'Utenti Amministratori' moderators: 'Moderatori' @@ -2166,7 +2263,7 @@ it: unlock_trust_level: "Sblocca Livello Esperienza" tl3_requirements: title: "Requisiti per Livello Esperienza 3" - table_title: "Negli ultimi 100 giorni:" + table_title: "Negli ultimi %{time_period} giorni:" value_heading: "Valore" requirement_heading: "Requisito" visits: "Visite" @@ -2211,11 +2308,11 @@ it: delete_confirm: "Sicuro di voler cancellare il campo utente?" options: "Opzioni" required: - title: "Richiesto durante la registrazione?" + title: "Richiesto durante l'iscrizione?" enabled: "richiesto" disabled: "non richiesto" editable: - title: "Modificabile dopo la registrazione?" + title: "Modificabile dopo l'iscrizione?" enabled: "modificabile" disabled: "non modificabile" show_on_profile: @@ -2227,8 +2324,15 @@ it: confirm: 'Conferma' dropdown: "A tendina" site_text: - none: "Scegli un tipo di contenuto per iniziare la modifica." + description: "Puoi personalizzare qualsiasi testo del tuo forum. Comincia effettuando una ricerca qui sotto:" + search: "Trova il testo che vorresti modificare" title: 'Contenuto Testuale' + edit: 'modifica' + revert: "Annulla Modifiche" + revert_confirm: "Sei sicuro di voler annullare le modifiche?" + go_back: "Torna alla Ricerca" + recommended: "Consigliamo di personalizzare il seguente testo per tue adattarlo alle necessità:" + show_overriden: 'Mostra solo le opzioni sovrascritte' site_settings: show_overriden: 'Mostra solo le opzioni sovrascritte' title: 'Impostazioni' @@ -2259,7 +2363,7 @@ it: backups: "Backup" login: "Accesso" plugins: "Plugin" - user_preferences: "Preferenze utente" + user_preferences: "Preferenze Utente" badges: title: Targhette new_badge: Nuova Targhetta @@ -2316,8 +2420,8 @@ it: bad_count_warning: header: "ATTENZIONE!" text: "Ci sono esempi di grant mancanti. Ciò accade quando la query delle targhette ritorna ID utenti o ID messaggi inesistenti. Successivamente ciò può causare risultati inattesi - controlla bene la tua query." + no_grant_count: "Nessuna targhetta da assegnare." grant_count: - zero: "Nessuna targhetta da assegnare." one: "1 targhetta da assegnare." other: "%{count} targhette da assegnare." sample: "Esempio:" @@ -2334,24 +2438,26 @@ it: image: "Immagine" delete_confirm: "Sicuro di voler cancellare l'emoji :%{name}:?" embedding: - get_started: "Se lo desideri, puoi incorporare Discourse in un altro sito web. Comincia aggiungo il suo nome host" - confirm_delete: "Sei sicuro di volere cancellare questo host?" + get_started: "Se lo desideri, puoi incorporare Discourse in un altro sito web. Comincia aggiungendo il nome dell'host" + confirm_delete: "Sicuro di voler cancellare questo host?" sample: "Utilizza il seguente codice HTML nel tuo sito per creare e incorporare gli argomenti di Discourse. Sostituisci REPLACE_ME con l'URL canonical della pagina in cui lo stai incorporando." - title: "Incorporamento" - host: "Host abilitati" + title: "Incorporo" + host: "Host Abilitati" edit: "modifica" - add_host: "Aggiungi host" - settings: "Impostazioni di incorporamento" - feed_settings: "Impostazioni dei feed" - feed_description: "Aggiungendo un feed RSS/AROM al tuo sito, migliori l'importazione dei tuoi contenuti da parte di Discourse" + category: "Pubblica nella Categoria" + add_host: "Aggiungi Host" + settings: "Impostazioni di incorporo" + feed_settings: "Impostazioni Feed" + feed_description: "Aggiungendo un feed RSS/ATOM al tuo sito, migliora la capacità di Discourse di importare i tuoi contenuti." crawling_settings: "Impostazioni del crawler" - crawling_description: "Quando Discourse crea gli argomenti per i messaggi, se non è presente nessun feed RSS/ATOM, cercherà di estrarre il contenuto dal codice HTML. Il contenuto può risultate a volte ostico da estrarre e, per semplificare il processo, forniamo la possibilità di specificare le regole CSS." + crawling_description: "Quando Discourse crea gli argomenti per i tuoi messaggi, se non è presente nessun feed RSS/ATOM, cercherà di estrarre il contenuto dal codice HTML. Il contenuto può risultate a volte ostico da estrarre e, per semplificare il processo, forniamo la possibilità di specificare le regole CSS." embed_by_username: "Nome utente per la creazione dell'argomento" embed_post_limit: "Numero massimo di messaggi da includere" - embed_truncate: "Abbrevia i messaggi incorporati" - embed_whitelist_selector: "Selettore CSS per gli elementi da includere negli embed" + embed_username_key_from_feed: "Chiave per ottenere il nome utente discourse dal feed" + embed_truncate: "Tronca i messaggi incorporati" + embed_whitelist_selector: "Selettore CSS per gli elementi da permettere negli embed" embed_blacklist_selector: "Selettore CSS per gli elementi da rimuovere dagli embed" - feed_polling_enabled: "Importa gli articoli via RSS/ATOM" + feed_polling_enabled: "Importa i messaggi via RSS/ATOM" feed_polling_url: "URL del feed RSS/ATOM da recuperare" save: "Salva Impostazioni Inclusione" permalink: @@ -2368,7 +2474,7 @@ it: form: label: "Nuovo:" add: "Aggiungi" - filter: "Cerca (URL o URL esterna)" + filter: "Cerca (URL o URL Esterna)" lightbox: download: "scaricamento" search_help: @@ -2404,7 +2510,7 @@ it: help: '? Apri l''aiuto per le scorciatoie da tastiera' dismiss_new_posts: 'x, r Chiudi Nuovo/Messaggi' dismiss_topics: 'x, t Chiudi Argomenti' - log_out: 'shift+z shift+z Esci' + log_out: 'shift+z shift+z Scollegati' actions: title: 'Azioni' bookmark_topic: 'f Aggiungi/togli argomento nei segnalibri' @@ -2426,8 +2532,6 @@ it: mark_watching: 'm, w Osserva argomento' badges: title: Targhette - allow_title: "può essere usata come titolo" - multiple_grant: "può essere assegnata più volte" badge_count: one: "1 Targhetta" other: "%{count} Targhette" @@ -2450,97 +2554,6 @@ it: name: Altro posting: name: Pubblicazione - badge: - editor: - name: Editor - description: Prima modifica ad un messaggio - basic_user: - name: Base - description: Assegnate tutte le funzioni essenziali della comunità - member: - name: Assiduo - description: Assegnata inviti - regular: - name: Esperto - description: 'Concessi i permessi di: ricategorizzare, rinominare, collegamenti seguiti e accesso al Lounge' - leader: - name: Leader - description: 'Concessi i permessi di: modifica globale, evidenziare, chiudere, archiviare, separare e fondere' - welcome: - name: Benvenuto - description: Ricevuto un "Mi piace" - autobiographer: - name: Autobiografo - description: Completato le informazioni del tuo profilo utente - anniversary: - name: Compleanno - description: Membro attivo da un anno, ha scritto almeno una volta - nice_post: - name: Buon Messaggio - description: Ricevuto 10 "Mi piace" per un messaggio. Questa targhetta può essere assegnata più volte - good_post: - name: Ottimo Messaggio - description: Ricevuto 25 "Mi piace" per un messaggio. Questa targhetta può essere assegnata più volte. - great_post: - name: Fantastico Messaggio - description: Ricevuto 50 "Mi piace" per un messaggio. Questa targhetta può essere assegnata più volte. - nice_topic: - name: Argomento Buono - description: Ricevuti 10 "Mi piace" per un argomento. Questa targhetta può essere assegnata più volte - good_topic: - name: Argomento Ottimo - description: Ricevuti 25 "Mi piace" per un argomento. Questa targhetta può essere assegnata più volte - great_topic: - name: Argomento Eccellente - description: Ricevuti 50 "Mi piace" per un argomento. Questa targhetta può essere assegnata più volte - nice_share: - name: Condivisione Buona - description: Condiviso un messaggio con 25 visitatori unici - good_share: - name: Condivisione Ottima - description: Condiviso un messaggio con 300 visitatori unici - great_share: - name: Condivisione Eccellente - description: Condiviso un messaggio con 1000 visitatori unici - first_like: - name: Primo Mi Piace - description: Assegnato un "Mi piace" ad un messaggio - first_flag: - name: Prima Segnalazione - description: Segnalato un messaggio - promoter: - name: Promotore - description: Ha invitato un utente - campaigner: - name: Pubblicitario - description: Ha invitato 3 utenti Base (livello di esperienza 1) - champion: - name: Campione - description: Ha invitato 5 utenti Assiduo (livello di esperienza 2) - first_share: - name: Prima Condivisione - description: Condiviso un messaggio - first_link: - name: Primo Collegamento - description: Aggiunto un collegamento interno ad un altro argomento - first_quote: - name: Prima Citazione - description: Citato un utente - read_guidelines: - name: Linee Guida Lette - description: Letto le linee guida della comunità - reader: - name: Lettore - description: Letto tutti i messaggi in un argomento con più di 100 messaggi - popular_link: - name: Collegamento Popolare - description: Ha pubblicato un collegamento esterno con almeno 50 clic - hot_link: - name: Collegamento Caldo - description: Ha pubblicato un collegamento esterno con almeno 300 clic - famous_link: - name: Collegamento Famoso - description: Ha pubblicato un collegamento esterno con almeno 1000 clic google_search: |

    Cerca con Google

    diff --git a/config/locales/client.ja.yml b/config/locales/client.ja.yml index f4ed722ac71..3cf5e2b3a31 100644 --- a/config/locales/client.ja.yml +++ b/config/locales/client.ja.yml @@ -81,6 +81,8 @@ ja: other: "%{count} 月後" x_years: other: "%{count} 年後" + previous_month: '前月' + next_month: '来月' share: topic: 'このトピックのリンクをシェアする' post: 'ポスト #%{postNumber}' @@ -91,6 +93,19 @@ ja: email: 'メールでこのリンクを送る' topic_admin_menu: "トピック管理" emails_are_disabled: "全てのメールアドレスの送信が管理者によって無効化されています。全ての種類のメール通知は行われません" + s3: + regions: + us_east_1: "US East (N. Virginia)" + us_west_1: "US West (N. California)" + us_west_2: "US West (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "EU (Ireland)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asia Pacific (Singapore)" + ap_southeast_2: "Asia Pacific (Sydney)" + ap_northeast_1: "Asia Pacific (Tokyo)" + ap_northeast_2: "Asia Pacific (Seoul)" + sa_east_1: "South America (Sao Paulo)" edit: 'このトピックのタイトルとカテゴリを編集' not_implemented: "申し訳ありませんが、この機能はまだ実装されていません" no_value: "いいえ" @@ -104,6 +119,7 @@ ja: admin_title: "管理者" flags_title: "フラグ" show_more: "もっと見る" + show_help: "オプション" links: "リンク" links_lowercase: other: "リンク集" @@ -175,6 +191,7 @@ ja: saved: "保存しました" upload: "アップロード" uploading: "アップロード中..." + uploading_filename: "アップロード中 {{filename}}..." uploaded: "アップロードしました" enable: "有効にする" disable: "無効にする" @@ -182,6 +199,7 @@ ja: revert: "戻す" failed: "失敗" switch_to_anon: "匿名モード" + switch_from_anon: "匿名モード停止" banner: close: "バナーを閉じる。" edit: "このバナーを編集 >>" @@ -203,7 +221,6 @@ ja: has_pending_posts: other: "このトピックは{{count}}個の投稿が承認待ちです" confirm: "変更を保存" - delete_prompt: "%{username}を本当に削除しますか?全ての投稿が削除されるのと同時にメールアドレスとIPアドレスがブロックされます。" approval: title: "この投稿は承認が必要" description: "投稿された新規のポストは受付されましたがモデレータによる承認が必要です。もう少々お待ち下さい。" @@ -244,13 +261,17 @@ ja: total_rows: other: "%{count} 人のユーザ" groups: + empty: + posts: "このグループのメンバーによる投稿はありません。" + add: "追加" + selector_placeholder: "メンバー追加" + owner: "所有者" visible: "このグループは全てのユーザに表示されています。" title: other: "グループ" members: "メンバー" posts: "ポスト" alias_levels: - title: "このグループを仮名として使えるユーザ" nobody: "無し" only_admins: "管理者のみ" mods_and_admins: "管理者とモデレータのみ" @@ -265,7 +286,6 @@ ja: '6': "レスポンス数" '7': "タグ付け" '9': "引用" - '10': "お気に入り" '11': "編集" '12': "アイテム送信" '13': "インボックス" @@ -275,6 +295,9 @@ ja: all_subcategories: "全てのサブカテゴリ" no_subcategory: "サブカテゴリなし" category: "カテゴリ" + reorder: + title: "カテゴリを並び替える" + apply_all: "適用" posts: "ポスト" topics: "トピック" latest: "最新ポスト" @@ -325,11 +348,8 @@ ja: not_supported: "申し訳ありません。そのブラウザは通知をサポートしていません。" perm_default: "通知をONにする" perm_denied_btn: "アクセス拒否" - perm_denied_expl: "通知へのアクセスを拒否されています。利用しているブラウザの通知を有効にし、完了したら、このボタンをクリックしてください。(デスクトップ: アドレスバーの左端のアイコン。 モバイル: \"サイト情報\")" disable: "通知を無効にする" - currently_enabled: "(現在有効化されています)" enable: "通知を有効化" - currently_disabled: "(現在無効化されています)" each_browser_note: "注意: 利用するブラウザ全てでこの設定を変更する必要があります" dismiss_notifications: "全て既読にする" dismiss_notifications_tooltip: "全ての未読の通知を既読にします" @@ -353,7 +373,6 @@ ja: tracked_categories: "トラック中" tracked_categories_instructions: "これらのカテゴリの新規トピックを自動的にトラックします。トピックに対して新しい投稿があった場合、トピック一覧に新しい投稿数がつきます。" muted_categories: "ミュート中" - muted_categories_instructions: "このカテゴリに投稿されたトピックについての通知を受け取りません。また、未読タブにも通知されません。" delete_account: "アカウントを削除する" delete_account_confirm: "本当にアカウントを削除しますか?削除されたアカウントを復元できません。" deleted_yourself: "あなたのアカウントは削除されました。" @@ -371,8 +390,8 @@ ja: warnings_received: "注意" messages: all: "すべて" - mine: "受信トレイ" - unread: "未読" + inbox: "インボックス" + select_all: "全てを選択する" change_password: success: "(メールを送信しました)" in_progress: "(メールを送信中)" @@ -417,10 +436,6 @@ ja: ok: "確認用メールを送信します" invalid: "正しいメールアドレスを入力してください" authenticated: "あなたのメールアドレスは {{provider}} によって認証されています" - frequency: - zero: "未読メールがあった場合、すぐにメールを送信します" - one: "直前にページを閲覧していなかった場合だけメールを送信します" - other: "{{count}} 分間ページを閲覧していなかった場合だけメールを送信します" name: title: "名前" instructions: "フルネーム(任意)" @@ -475,11 +490,17 @@ ja: auto_track_options: never: "トラックしない" immediately: "今すぐ" + after_30_seconds: "30秒後" + after_1_minute: "1分後" + after_2_minutes: "2分後" + after_3_minutes: "3分後" + after_4_minutes: "4分後" + after_5_minutes: "5分後" + after_10_minutes: "10分後" invited: search: "招待履歴を検索するためにキーワードを入力してください..." title: "招待" user: "招待したユーザ" - truncated: "最初の {{count}} 個の招待履歴を表示しています。" redeemed: "受理された招待" redeemed_tab: "受理" redeemed_at: "受理日" @@ -550,7 +571,6 @@ ja: logout: "ログアウトしました" refresh: "Refresh" read_only_mode: - enabled: "読み取り専用モードが有効になっています。サイトをブラウズすることは引き続き出来ますが、機能は動作しません。" login_disabled: "読み取り専用モードにされています。ログインできません。" learn_more: "より詳しく..." year: '年' @@ -567,10 +587,10 @@ ja: last_reply_lowercase: 最新の回答 replies_lowercase: other: 回答 + signup_cta: + sign_up: "新しいアカウントを作成" summary: enabled_description: "トピックのまとめを表示されています。" - description: "{{count}} 返信があります。" - description_time: "全てを確認するのに {{readingTime}} 分 前後を要する {{count}} 個の回答があります。" enable: 'このトピックを要訳する' disable: '全ての投稿を表示する' deleted_filter: @@ -647,7 +667,7 @@ ja: twitter: "Twitter" emoji_one: "Emoji One" composer: - emoji: "Emoji :smile:" + options: "オプション" add_warning: "これは公式の警告です。" posting_not_on_topic: "回答したいトピックはどれですか?" saving_draft_tip: "保存中..." @@ -676,7 +696,7 @@ ja: edit_reason_placeholder: "編集する理由は何ですか?" show_edit_reason: "(編集理由を追加)" view_new_post: "新規ポストを見る。" - saving: "保存中..." + saving: "保存中" saved: "保存完了!" saved_draft: "編集中の投稿があります。選択すると再開します" uploading: "アップロード中..." @@ -703,10 +723,9 @@ ja: heading_title: "見出し" heading_text: "見出し" hr_title: "水平線" - undo_title: "取り消し" - redo_title: "やり直し" help: "Markdown 編集のヘルプ" toggler: "編集パネルの表示/非表示" + modal_cancel: "キャンセル" admin_options_title: "このトピックの詳細設定" auto_close: label: "このトピックを自動的に終了する時間:" @@ -725,7 +744,6 @@ ja: mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -748,14 +766,13 @@ ja: from_my_computer: "このデバイスから" from_the_web: "Web から" remote_tip: "画像へのリンク" - remote_tip_with_attachments: "画像かファイルへのリンク ({{authorized_extensions}})" local_tip: "ローカルからアップロードする画像を選択" - local_tip_with_attachments: "ローカルからアップロードする画像またはファイルを選択 ({{authorized_extensions}})" hint: "(アップロードする画像をエディタにドラッグ&ドロップすることもできます)" uploading: "アップロード中" select_file: "ファイル選択" image_link: "イメージのリンク先" search: + select_all: "全てを選択する" title: "トピック、ポスト、ユーザ、カテゴリを探す" no_results: "何も見つかりませんでした。" no_more_results: "これ以上結果が見つかりませんでした。" @@ -774,10 +791,6 @@ ja: bulk: reset_read: "未読に設定" delete: "トピックを削除" - dismiss_posts: "既読に設定" - dismiss_posts_tooltip: "未読トピック数をクリアする。" - dismiss_topics: "既読に設定" - dismiss_topics_tooltip: "新しい投稿を未読リストに非表示する" dismiss_new: "既読に設定" toggle: "選択したトピックを切り替え" actions: "操作" @@ -799,9 +812,6 @@ ja: category: "{{category}} トピックはありません。" top: "トップトピックはありません。" search: "検索結果はありません。" - educate: - new: '2日以内に投稿されたトピックは「最新」トピックとして表示されます。設定画面で日数変更が可能です。' - unread: '参加中のトピックに対して新しい投稿がある場合、未読記事として表示されます。' bottom: latest: "最新のトピックはこれ以上ありません。" hot: "ホットなトピックはこれ以上ありません。" @@ -909,7 +919,6 @@ ja: description: "このメッセージについての通知を受け取りません。" muted: title: "ミュート" - description: "このトピックについての通知を受け取りません。また、未読タブにも通知されません。" actions: recover: "トピック削除の取り消し" delete: "トピック削除" @@ -950,25 +959,14 @@ ja: unpin: "{{categoryLink}} カテゴリのトップからトピックを削除" unpin_until: "{{categoryLink}} カテゴリのトップからこのトピックを削除するか、%{until} まで待つ。" pin_note: "ユーザはトピックを個別にピン留め解除することができます" - already_pinned: - zero: "{{categoryLink}}にはピン留めされたトピックはありません" - one: "{{categoryLink}}内のトピックは現在1個ピン留めされています。" - other: "{{categoryLink}}内のトピックは現在{{count}}個ピン留めされています。" pin_globally: "このトピックをすべてのトピックリストのトップに表示する" confirm_pin_globally: "既に{{count}} 個ピン留めしています。 多すぎるピン留めは新規ユーザと匿名ユーザの負担になる場合があります。ピン留めを続けますか?" unpin_globally: "トピック一覧のトップからこのトピックを削除します" unpin_globally_until: "このトピックをすべてのトピックリストのトップから削除するか、%{until} まで待つ。" global_pin_note: "ユーザはトピックを個別にピン留め解除することができます" - already_pinned_globally: - zero: "現在ピン留めされていません" - one: "現在1個ピン留めされています" - other: "現在{{count}}個ピン留めされています" make_banner: "このトピックを全てのページのバナーに表示します" remove_banner: "全てのページのバナーを削除します" banner_note: "ユーザはバナーを閉じることができます。常に1つのトピックだけがバナー表示されます" - already_banner: - zero: "バナートピックはありません" - one: "これら現在のバナートピックです。" inviting: "招待中..." automatically_add_to_groups_optional: "この招待によって、リストされたグループに参加することができます。" automatically_add_to_groups_required: "この招待によって、リストされたグループに参加することができます。" @@ -1058,10 +1056,6 @@ ja: other: "{{count}} 個のいいね!" has_likes_title: other: "{{count}}人のユーザがこの回答に「いいね!」しました" - has_likes_title_you: - zero: "この投稿に「いいね!」する" - one: "あなたと1人がこの回答に「いいね!」しました" - other: "あなたと他{{count}}人がこの回答に「いいね!」しました" errors: create: "申し訳ありませんが、ポスト作成中にエラーが発生しました。もう一度やり直してください。" edit: "申し訳ありませんが、ポスト編集中にエラーが発生しました。もう一度やり直してください。" @@ -1079,8 +1073,6 @@ ja: no_value: "いいえ" yes_value: "はい" via_email: "メールで投稿されました。" - wiki: - about: "この投稿は「Wiki」である。ベーシックユーザが編集できます。" archetypes: save: '保存オプション' controls: @@ -1126,18 +1118,6 @@ ja: bookmark: "ブックマークを取り消す" like: "「いいね!」を取り消す" vote: "投票を取り消す" - people: - off_topic: "{{icons}} オフトピックとしてマーク" - spam: "{{icons}} スパムとしてマーク" - spam_with_url: "{{icons}} スパムとしてフラグ付き" - inappropriate: "{{icons}} 不適切であると報告するフラグを立つ" - notify_moderators: "{{icons}} がモデレータに通報しました" - notify_moderators_with_url: "{{icons}} 通知されたモデレータ" - notify_user: "{{icons}} メッセージを送信しました" - notify_user_with_url: "{{icons}} メッセージを送信しました" - bookmark: "{{icons}} がブックマークしました" - like: "{{icons}} が「いいね!」しています" - vote: "{{icons}} が投票しました" by_you: off_topic: "オフトピックのフラグを立てました" spam: "スパムを報告するフラグを立てました" @@ -1181,10 +1161,6 @@ ja: other: "{{count}}人のユーザが「いいね!」しました" vote: other: "{{count}}人のユーザがこのポストに投票しました" - edits: - one: 1回編集 - other: "{{count}}回編集" - zero: 編集なし delete: confirm: other: "本当にこれらのポストを削除しますか?" @@ -1261,19 +1237,14 @@ ja: notifications: watching: title: "カテゴリ参加中" - description: "これらのカテゴリに新しく投稿されたトピックを自動的に参加します。これらのカテゴリに対して新しい投稿があった場合、登録されたメールアドレスと、コミュニティ内の通知ボックスに通知が届き、トピック一覧に新しい回答数がつきます。" tracking: title: "トラック中" - description: "これらのカテゴリの新規トピックを自動的にトラックします。トピックに対して新しい投稿があった場合、トピック一覧に新しい回答数がつきます。" regular: - title: "通常" description: "他ユーザからタグ付けをされた場合、またはあなたの投稿に回答が付いた場合に通知されます。" muted: title: "ミュート中" - description: "このカテゴリに投稿されたトピックについての通知を受け取りません。また、未読タブにも通知されません。" flagging: title: '私達のコミュニティの維持を助けてくれてありがとうごうざいます' - private_reminder: 'フラグはプライベートです。スタッフのみが参照できます' action: 'フラグをつける' take_action: "アクションをする" notify_action: 'メッセージ' @@ -1320,7 +1291,6 @@ ja: help: "このトピックはピン留めされていません。 既定の順番に表示されます。" pinned_globally: title: "全サイト的にピン留めされました" - help: "このトピックは全サイト的にピン留めされました。全てのリストのトップに表示されます。" pinned: title: "ピン留め" help: "このトピックはピン留めされています。常にカテゴリのトップに表示されます" @@ -1360,10 +1330,7 @@ ja: with_topics: "%{filter} トピック" with_category: "%{filter} %{category} トピック" latest: - title: - zero: "最新ポスト" - one: "最新ポスト (1)" - other: "最新ポスト ({{count}})" + title: "最新" help: "最新のトピック" hot: title: "ホット" @@ -1379,23 +1346,19 @@ ja: title_in: "カテゴリ - {{categoryName}}" help: "カテゴリ毎に整理されたトピックを表示" unread: - title: - zero: "未読" - one: "未読 (1)" + title: "未読" + title_with_count: other: "未読 ({{count}})" help: "未読ポストのあるトピック" lower_title_with_count: - one: "1未読" other: "{{count}} 未読" new: lower_title_with_count: - one: "1件" other: "{{count}}件" lower_title: "新着" - title: - zero: "新規" - one: "新規 (1)" - other: "新規 ({{count}})" + title: "新規" + title_with_count: + other: "最新 ({{count}})" help: "最近投稿されたトピック" posted: title: "あなたのポスト" @@ -1404,9 +1367,8 @@ ja: title: "ブックマーク" help: "ブックマークしたトピック" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" + title: "{{categoryName}}" + title_with_count: other: "{{categoryName}} ({{count}})" help: "{{categoryName}} カテゴリの最新トピック" top: @@ -1426,7 +1388,7 @@ ja: title: "毎日" all_time: "今まで" this_year: "年" - this_quarter: "4分の1" + this_quarter: "季刊" this_month: "月" this_week: "週" today: "本日" @@ -1453,7 +1415,7 @@ ja: stale_data: "最近アップデートの確認が正しく動作していません。sidekiq が起動していることを確認してください。" version_check_pending: "まるでアップデート直後のようです。素晴らしい!" installed_version: "Installed" - latest_version: "Latest" + latest_version: "最新" problems_found: "Discourse のインストールにいくつか問題が発見されました:" last_checked: "最終チェック" refresh_problems: "更新" @@ -1644,11 +1606,9 @@ ja: is_disabled: "バックアップ復元を無効にされています。" label: "復元" title: "バックアップを復元" - confirm: "本当にバックアップを復元しますか?" rollback: label: "ロールバック" title: "データベースを元の作業状態にロールバックする" - confirm: "本当にデータベースを元の作業状態にロールバックしますか?" export_csv: user_archive_confirm: "あなたのポストをダウンロードしてよいですか?" success: "エスクポートを開始しました。処理が完了すると、メッセージで通知されます。" @@ -1742,13 +1702,9 @@ ja: love: name: 'love' description: "ライクボタンの色" - wiki: - name: 'wiki' - description: "Wiki投稿の背景に使用する基本色" email: - title: "メール" settings: "設定" - all: "全て" + preview_digest: "ダイジェストのプレビュー" sending_test: "テストメールを送信中..." error: "ERROR - %{server_error}" test_error: "テストメールを送れませんでした。メール設定、またはホストをメールコネクションをブロックされていないようを確認してください。" @@ -1763,7 +1719,6 @@ ja: send_test: "テストメールを送る" sent_test: "送信完了!" delivery_method: "送信方法" - preview_digest: "ダイジェストのプレビュー" refresh: "更新" format: "フォーマット" html: "html" @@ -1771,6 +1726,10 @@ ja: last_seen_user: "ユーザが最後にサイトを訪れた日:" reply_key: "回答キー" skipped_reason: "スキップの理由" + incoming_emails: + error: "エラー" + filters: + error_placeholder: "エラー" logs: none: "ログなし" filters: @@ -1789,6 +1748,7 @@ ja: ip_address: "IP" topic_id: "トピックID" post_id: "ポストID" + category_id: "カテゴリID" delete: '削除' edit: '編集' save: '保存' @@ -1829,6 +1789,13 @@ ja: impersonate: "なりすまし" anonymize_user: "匿名ユーザ" roll_up: "IPブロックをロールアップ" + delete_category: "カテゴリを削除する" + block_user: "ユーザをブロック" + unblock_user: "ユーザをブロック解除" + grant_admin: "管理者権限を付与" + revoke_admin: "管理者権限を剥奪" + grant_moderation: "モデレータ権限を付与" + revoke_moderation: "モデレータ権限を剥奪" screened_emails: title: "ブロック対象アドレス" description: "新規アカウント作成時、次のメールアドレスからの登録をブロックする。" @@ -1893,9 +1860,6 @@ ja: pending: '保留中のユーザ' newuser: 'トラストレベル0のユーザ (新規ユーザ)' basic: 'トラストレベル1のユーザ (ベーシックユーザ)' - regular: 'トラストレベル 2(メンバー)のユーザ' - leader: 'トラストレベル3(レギュラー)のユーザ' - elder: 'トラストレベル4(リーダー)のユーザ' staff: "スタッフ" admins: '管理者ユーザ' moderators: 'モデレータ' @@ -2000,7 +1964,7 @@ ja: unlock_trust_level: "トラストレベルをアンロック" tl3_requirements: title: "トラストレベル3の条件" - table_title: "過去100日に:" + table_title: "過去%{time_period} 日間に" value_heading: "値" requirement_heading: "条件" visits: "訪問" @@ -2061,8 +2025,8 @@ ja: confirm: '確認' dropdown: "ドロップダウン" site_text: - none: "コンテンツの種類を選択してください" title: 'テキストコンテンツ' + edit: '編集' site_settings: show_overriden: '上書き部分のみ表示' title: '設定' @@ -2149,10 +2113,6 @@ ja: bad_count_warning: header: "WARNING!" text: "There are missing grant samples. This happens when the badge query returns user IDs or post IDs that do not exist. This may cause unexpected results later on - please double-check your query." - grant_count: - zero: "付与されたバッジはありません" - one: "1 個のバッジが付与されています" - other: "%{count} 個のバッジが付与されています" sample: "サンプル:" grant: with: %{username} @@ -2166,6 +2126,8 @@ ja: name: "名前" image: "画像" delete_confirm: "Are you sure you want to delete the :%{name}: emoji?" + embedding: + edit: "編集" permalink: title: "パーマリンク" url: "URL" @@ -2234,8 +2196,6 @@ ja: mark_watching: 'm, w トピックを参加中にする' badges: title: バッジ - allow_title: "タイトルとして使用できる" - multiple_grant: "複数回受け取ることができる" badge_count: other: "%{count} バッジ" more_badges: @@ -2255,85 +2215,3 @@ ja: name: その他 posting: name: 投稿中 - badge: - editor: - name: 編集者 - description: 最初のポスト編集 - basic_user: - name: ベーシックユーザ - description: Granted all essential community functions - member: - name: メンバー - description: Granted invitations - regular: - name: レギュラー - description: Granted recategorize, rename, followed links and lounge - leader: - name: リーダー - description: Granted global edit, pin, close, archive, split and merge - welcome: - name: ようこそ - description: 「いいね!」を受けました - autobiographer: - name: Autobiographer - description: Filled user profile information - anniversary: - name: アニバーサリー - description: 今年一度でも投稿したアクティブメンバー - nice_post: - name: 良いポスト - description: 10人に「いいね!」をされました。このバッジは何度でももらえます。 - good_post: - name: 良い投稿! - description: 25人に「いいね!」をされました。このバッジは何度でももらえます。 - great_post: - name: 素晴らしい投稿! - description: 50人に「いいね!」をされました。このバッジは何度でももらえます。 - nice_topic: - name: ナイストピック - description: トピックが10回「いいね!」されました。このバッジは何度でももらえます - good_topic: - name: グッドトピック - description: トピックが25回「いいね!」されました。このバッジは何度でももらえます - great_topic: - name: グレートトピック - description: トピックが50回「いいね!」されました。このバッジは何度でももらえます - nice_share: - name: ナイスシェア - description: 25人の訪問者にポストがシェアされました - good_share: - name: グッドシェア - description: 300人の訪問者にポストがシェアされました - great_share: - name: グレートシェア - description: 1000人の訪問者にポストがシェアされました - first_like: - name: 初めての「いいね!」 - description: 投稿に「いいね!」した - first_flag: - name: 最初のフラグ - description: 投稿にフラグをつけた - promoter: - name: プロモーター - description: 招待したユーザ - campaigner: - name: キャンペイナー - description: 3人のベーシックユーザー(トラストレベル 1)を招待 - champion: - name: チャンピオン - description: 5 メンバー(トラストレベル2)を招待 - first_share: - name: 初めてのシェア - description: 投稿をシェアした - first_link: - name: 最初のリンク - description: サイト内投稿のリンクを挿入した - first_quote: - name: 最初の投稿 - description: ユーザにタグを付けた - read_guidelines: - name: ガイドラインを読んだ - description: community guidelinesを読みました - reader: - name: 閲覧者 - description: 100以上の投稿があるトピック内の投稿をすべて読みました。 diff --git a/config/locales/client.ko.yml b/config/locales/client.ko.yml index 4d631210af6..759b44a5218 100644 --- a/config/locales/client.ko.yml +++ b/config/locales/client.ko.yml @@ -81,6 +81,8 @@ ko: other: "%{count}달 후" x_years: other: "%{count}년 후" + previous_month: '이전 달' + next_month: '다음 달' share: topic: '토픽을 공유합니다.' post: '게시글 #%{postNumber}' @@ -90,12 +92,15 @@ ko: google+: 'Google+로 공유' email: '이메일로 공유' action_codes: + split_topic: "이 토픽을 ${when} 분리" + invited_user: "%{who}이(가) %{when}에 초대됨" + removed_user: "%{who}이(가) %{when}에 삭제됨" autoclosed: - enabled: '%{when} 닫기' - disabled: '%{when} 열기' + enabled: '%{when}에 닫힘' + disabled: '%{when}에 열림' closed: - enabled: '%{when} 닫기' - disabled: '%{when} 열기' + enabled: '%{when}에 닫힘' + disabled: '%{when}에 열림' archived: enabled: '%{when} 보관' disabled: '%{when} 보관 취소' @@ -110,6 +115,19 @@ ko: disabled: '%{when} 목록에서 감춤' topic_admin_menu: "토픽 관리자 기능" emails_are_disabled: "관리자가 이메일 송신을 전체 비활성화 했습니다. 어떤 종류의 이메일 알림도 보내지지 않습니다." + s3: + regions: + us_east_1: "미국 동부 (N. 버지니아)" + us_west_1: "미국 서부 (N. 캘리포니아)" + us_west_2: "미국 서부 (오레곤)" + us_gov_west_1: "AWS GovCloud(US)" + eu_west_1: "유럽연합 (아일랜드)" + eu_central_1: "유럽연합 (프랑크푸르트)" + ap_southeast_1: "아시아 태평양 (싱가폴)" + ap_southeast_2: "아시아 태평양 (시드니)" + ap_northeast_1: "아시아 태평양 (토쿄)" + ap_northeast_2: "아시아 태평양 (서울)" + sa_east_1: "남 아메리카 (상파울로)" edit: '이 토픽의 제목과 카테고리 편집' not_implemented: "죄송합니다. 아직 사용할 수 없는 기능입니다." no_value: "아니오" @@ -141,6 +159,8 @@ ko: more: "더" less: "덜" never: "전혀" + every_30_minutes: "매 30분 마다" + every_hour: "매 한시간 마다" daily: "매일" weekly: "매주" every_two_weeks: "격주" @@ -151,6 +171,7 @@ ko: other: "{{count}} 자" suggested_topics: title: "추천 토픽" + pm_title: "추천 메세지" about: simple_title: "About" title: "About %{title}" @@ -195,6 +216,7 @@ ko: saved: "저장 완료!" upload: "업로드" uploading: "업로드 중..." + uploading_filename: "{{filename}} 업로드 중..." uploaded: "업로드 완료!" enable: "활성화" disable: "비활성화" @@ -202,6 +224,7 @@ ko: revert: "되돌리기" failed: "실패" switch_to_anon: "익명 모드" + switch_from_anon: "익명모드 나가기" banner: close: "배너 닫기" edit: "이 배너 수정 >>" @@ -223,7 +246,7 @@ ko: has_pending_posts: other: "이 토픽은 {{count}}개의 승인 대기중인 게시글이 있습니다." confirm: "변경사항 저장" - delete_prompt: "정말로 %{username} 회원을 삭제하시겠습니까? 게시글이 모두 삭제되고 IP와 이메일이 블락됩니다." + delete_prompt: "정말로 %{username}; 회원을 삭제하시겠습니까? 게시글이 모두 삭제되고 IP와 이메일이 차단됩니다." approval: title: "게시글 승인 필요" description: "새로운 게시글이 있습니다. 그러나 이 게시글이 보여지려면 운영자의 승인이 필요합니다." @@ -264,18 +287,43 @@ ko: total_rows: other: "%{count} 사용자" groups: + empty: + posts: "이 그룹의 구성원에 의해 작성된 게시물은 없습니다." + members: "이 그룹에는 구성원이 없습니다." + mentions: "이 그룹에 대한 언급이 없습니다." + messages: "이 그룹에 대한 메시지는 없습니다." + topics: "이 그룹의 구성원에 의해 작성된 주제글이 없습니다." + add: "추가" + selector_placeholder: "멤버 추가" + owner: "소유자" visible: "모든 사용자에게 보이는 그룹입니다." title: other: "그룹" members: "멤버" posts: "게시글" alias_levels: - title: "누가 이 그룹을 별칭으로 사용할 수 있는가?" + title: "누가 이 그룹에 메시지와 @멘션을 보낼 수 있습니까?" nobody: "0명" only_admins: "관리자 전용" mods_and_admins: "운영자 및 관리자만" members_mods_and_admins: "그룹 멤버, 운영자, 관리자만" everyone: "모두" + trust_levels: + title: "멤버들이 추가되면 회원등급이 자동으로 부여됩니다:" + none: "없음" + notifications: + watching: + title: "알림 : 주시 중" + description: "이 메시지에 새로운 답글이 있을 때 알림을 받게 되며 새로운 답글의 개수는 표시됩니다." + tracking: + title: "알림 : 새 글 표시 중" + description: "누군가 당신의 @아이디 로 언급했거나 당신의 글에 답글이 달릴 때 알림을 받게 됩니다." + regular: + title: "알림 : 일반" + description: "누군가 당신의 @아이디 로 언급했거나 당신의 글에 답글이 달릴 때 알림을 받게 됩니다." + muted: + title: "알림 : 끔" + description: "이 메시지에 대해 어떠한 알림도 받지 않지 않습니다." user_action_groups: '1': "선사한 '좋아요'" '2': "받은 '좋아요'" @@ -285,7 +333,6 @@ ko: '6': "응답" '7': "멘션" '9': "인용" - '10': "즐겨찾기" '11': "편집" '12': "보낸 편지함" '13': "받은 편지함" @@ -295,13 +342,22 @@ ko: all_subcategories: "모든 하위 카테고리" no_subcategory: "없음" category: "카테고리" + category_list: "카테고리 목록 표시" + reorder: + title: "카테고리 순서변경" + title_long: "카테고리 목록 재구성" + fix_order: "위치 고정" + fix_order_tooltip: "카데고리에 고유 위치가 표시되지 않은 게 있습니다. 이 경우 예기치 않은 문제를 일으킬 수 있습니다." + save: "순서 저장" + apply_all: "적용" + position: "위치" posts: "게시글" topics: "토픽" latest: "최근" latest_by: "가장 최근" toggle_ordering: "정렬 컨트롤 토글" subcategories: "하위 카테고리" - topic_stats: "새 글타래 수" + topic_stats: "새로운 토픽 수" topic_stat_sentence: other: "지난 %{unit} 동안 %{count}개의 새로운 토픽이 있습니다." post_stats: "새 게시글 수" @@ -335,21 +391,21 @@ ko: private_messages: "메시지" activity_stream: "활동" preferences: "환경 설정" + expand_profile: "확장" bookmarks: "북마크" bio: "내 소개" invited_by: "(이)가 초대했습니다." trust_level: "신뢰도" notifications: "알림" + statistics: "통계" desktop_notifications: label: "데스크탑 알림" not_supported: "안타깝게도 지금 사용하고 계시는 브라우저는 알림을 지원하지 않습니다." perm_default: "알림 켜기" perm_denied_btn: "권한 거부" - perm_denied_expl: "알림에 대한 권한이 없습니다. 알림을 활성화하기위해 브라우저의 알림설정을 하시고 난 후에 버튼을 눌러주세요. (데스크탑: 주소 표시 막대 가장 왼쪽에 있는 아이콘, 모바일: '사이트 정보'.)" + perm_denied_expl: "통지를 위한 허용을 거절했었습니다. 브라우저 설정을 통해서 통지를 허용해주세요." disable: "알림 비활성화" - currently_enabled: "(현재 활성화됨)" enable: "알림 활성화" - currently_disabled: "(현재 비활성화됨)" each_browser_note: "노트: 사용하시는 모든 브라우저에서 이 설정을 변경해야합니다." dismiss_notifications: "모두 읽음으로 표시" dismiss_notifications_tooltip: "읽지 않은 알림을 모두 읽음으로 표시" @@ -361,28 +417,29 @@ ko: change: "변경" moderator: "{{user}}님은 운영자입니다" admin: "{{user}}님은 관리자 입니다" - moderator_tooltip: "이 사용자는 운영자 입니다" - admin_tooltip: "이 사용자는 관리자입니다." - blocked_tooltip: "이 사용자는 차단되었습니다" - suspended_notice: "이 사용자는 {{date}}까지 접근 금지 되었습니다." + moderator_tooltip: "이 회원은 운영자 입니다" + admin_tooltip: "이 회원은 관리자입니다." + blocked_tooltip: "이 회원은 차단되었습니다" + suspended_notice: "이 회원은 {{date}}까지 접근 금지 되었습니다." suspended_reason: "이유: " github_profile: "Github" - mailing_list_mode: "(글타래가나 카테고리의 알림을 끄지 않는 한) 모든 새로운 글에 대해 메일을 보내주세요." + mailing_list_mode: "(토픽이나 카테고리의 알림을 끄지 않는 한) 모든 새로운 글에 대해 메일을 보내주세요." watched_categories: "지켜보기" - watched_categories_instructions: "이 카테고리 내의 새로운 글타래들을 지켜보도록 자동으로 설정됩니다. 새로운 글이나 글타래에 대하여 알림을 받게되며 글타래 옆에 읽지 않은 글의 수가 표시됩니다." + watched_categories_instructions: "이 카테고리 내의 새로운 토픽들을 지켜보도록 자동으로 설정됩니다. 새로운 게시글이나 토픽에 대하여 알림을 받게되며 토픽 옆에 읽지 않은 게시글의 수가 표시됩니다." tracked_categories: "추적하기" - tracked_categories_instructions: "이 카테고리 내의 새로운 글타래들을 추적하도록 자동으로 설정됩니다. 글타래 옆에 읽지 않은 글의 수가 표시됩니다." + tracked_categories_instructions: "이 카테고리 내의 새로운 토픽들을 추적하도록 자동으로 설정됩니다. 토픽 옆에 읽지 않은 게시글의 수가 표시됩니다." muted_categories: "알림 끄기" - muted_categories_instructions: "이 카테고리들에 새로 작성되는 새로운 글타래에 대한 알림이 오지 않도록 합니다. '읽지 않은'탭에서도 보이지 않게 됩니다." + muted_categories_instructions: "이 카테고리 내의 새 토픽에 대해 어떠한 알림도 받을 수 없으며, 최근의 토픽도 나타나지 않습니다." delete_account: "내 계정 삭제" delete_account_confirm: "정말로 계정을 삭제할까요? 이 작업은 되돌릴 수 없습니다." deleted_yourself: "계정이 삭제 되었습니다." delete_yourself_not_allowed: "지금은 계정을 삭제할 수 없습니다. 관리자에게 연락해 주세요." unread_message_count: "메시지" admin_delete: "삭제" - users: "사용자" + users: "회원" muted_users: "알람 끄기" - muted_users_instructions: "이 사용자들이 보낸 알림 모두 숨김" + muted_users_instructions: "이 회원이 보낸 알림 모두 숨김" + muted_topics_link: "알림을 끈 토픽 보기" staff_counters: flags_given: "유용한 신고" flagged_posts: "신고된 글" @@ -391,8 +448,15 @@ ko: warnings_received: "경고" messages: all: "전체" - mine: "내가 보낸 메세지" - unread: "읽지 않음" + inbox: "수신함" + sent: "보냄" + archive: "저장됨" + groups: "내 그룹" + bulk_select: "메시지 선택" + move_to_inbox: "수신함으로 이동" + move_to_archive: "보관하기" + failed_to_move: "선택한 메시지를 이동할 수 없습니다 (아마도 네트워크가 다운됨)" + select_all: "모두 선택" change_password: success: "(이메일 전송)" in_progress: "(이메일 전송 중)" @@ -437,10 +501,9 @@ ko: ok: "내 이메일로 확인 메일이 전송됩니다." invalid: "유효한 이메일 주소를 입력해주세요." authenticated: "내 이메일이 {{provider}}에 의해 인증되었습니다." + frequency_immediately: "만약 전송된 메일을 읽지 않았을 경우, 즉시 메일을 다시 보내드립니다." frequency: - zero: "읽지 않은 내용이 있을 때 즉시 이메일로 알립니다." - one: "1분 후에도 내용을 확인하지 않았을 때에 이메일로 알립니다." - other: "{{count}}분 후에도 확인하지 않았을 때에 이메일로 알립니다." + other: "최근 {{count}}분 동안접속하지 않을 경우에만 메일이 전송됩니다." name: title: "이름" instructions: "이름을 적어주세요. (선택사항)" @@ -473,16 +536,23 @@ ko: log_out: "로그아웃" location: "위치" card_badge: - title: "사용자 카드 뱃지" + title: "사용자 카드 배지" website: "웹사이트" email_settings: "이메일" + email_previous_replies: + title: "이메일 밑부분에 이전 댓글을 포함합니다." + unless_emailed: "예전에 발송된 것이 아닌 한" + always: "항상" + never: "절대" email_digests: title: "사이트 방문이 없을 경우, 새로운 글을 요약하여 메일로 보냄" + every_30_minutes: "매 30분 마다" daily: "매일" every_three_days: "매 3일마다" weekly: "매주" every_two_weeks: "격주" - email_direct: "누군가 나를 인용했을 때, 내 글에 답글을 달았을때, 내 이름을 멘션했을때 혹은 글타래에 나를 초대했을 떄 이메일 보내기" + email_in_reply_to: "이메일에 글 응답내용을 발췌해서 포함하기 " + email_direct: "누군가 나를 인용했을 때, 내 글에 답글을 달았을때, 내 이름을 멘션했을때 혹은 토픽에 나를 초대했을 떄 이메일 보내기" email_private_messages: "누군가 나에게 메시지를 보냈을때 이메일 보내기" email_always: "사이트를 이용중 일 때도 이메일 알림 보내기" other_settings: "추가 사항" @@ -490,12 +560,12 @@ ko: new_topic_duration: label: "새글을 정의해주세요." not_viewed: "아직 보지 않았습니다." - last_here: "마지막 방문이후 작성된 글타래" - after_1_day: "지난 하루간 생성된 글타래" - after_2_days: "지난 2일간 생성된 글타래" - after_1_week: "최근 일주일간 생성된 글타래" - after_2_weeks: "지난 2주간 생성된 글타래" - auto_track_topics: "마지막 방문이후 작성된 글타래" + last_here: "마지막 방문이후 작성된 토픽" + after_1_day: "지난 하루간 생성된 토픽" + after_2_days: "지난 2일간 생성된 토픽" + after_1_week: "최근 일주일간 생성된 토픽" + after_2_weeks: "지난 2주간 생성된 토픽" + auto_track_topics: "마지막 방문이후 작성된 토픽" auto_track_options: never: "하지않음" immediately: "즉시" @@ -511,14 +581,17 @@ ko: title: "초대" user: "사용자 초대" sent: "보냄" - truncated: "처음 {{count}}개 초대장 보여주기" + none: "승인을 기다리는 초대가 더이상 없습니다." + truncated: + other: "앞 {{count}}개의 초대를 보여줍니다." redeemed: "초대를 받았습니다." redeemed_tab: "Redeemed" + redeemed_tab_with_count: "교환된 ({{count}})" redeemed_at: "에 초대되었습니다." pending: "초대를 보류합니다." pending_tab: "보류" pending_tab_with_count: "지연 ({{count}})" - topics_entered: "글타래가 입력되었습니다." + topics_entered: "토픽이 입력되었습니다." posts_read_count: "글 읽기" expired: "이 초대장의 기한이 만료되었습니다." rescind: "삭제" @@ -545,6 +618,15 @@ ko: same_as_email: "비밀번호가 이메일과 동일합니다." ok: "적절한 암호입니다." instructions: "글자 수가 %{count}자 이상이어야 합니다." + summary: + title: "요약" + stats: "통계" + top_replies: "인기 댓글" + more_replies: "답글 더 보기" + top_topics: "인기 토픽" + more_topics: "토픽 더 보기" + top_badges: "인기 배지" + more_badges: "배지 더 보기" associated_accounts: "로그인" ip_address: title: "마지막 IP 주소" @@ -561,7 +643,7 @@ ko: posted_by: "에 의해 작성되었습니다" sent_by: "에 의해 전송되었습니다" private_message: "메시지" - the_topic: "글타래" + the_topic: "토픽" loading: "로딩 중..." errors: prev_page: "로드하는 중" @@ -570,11 +652,13 @@ ko: server: "서버 에러" forbidden: "접근 거부됨" unknown: "에러" + not_found: "페이지를 찾을 수 없습니다" desc: network: "접속상태를 확인해주세요." network_fixed: "문제가 해결된 것으로 보입니다." server: "에러 코드: {{status}}" forbidden: "볼 수 있도록 허용되지 않았습니다." + not_found: "에구, 어플리케이션이 없는 URL를 가져오려고 시도했습니다." unknown: "문제가 발생했습니다." buttons: back: "뒤로가기" @@ -585,15 +669,18 @@ ko: logout: "로그아웃 되었습니다." refresh: "새로고침" read_only_mode: - enabled: "읽기 모드가 활성화 되었습니다. 사이트를 열람할 수 있으나 상호작용은 불가능 합니다." + enabled: "이 사이트는 현재 읽기전용 모드입니다. 브라우징은 가능하지만, 댓글달기, 좋아요 등 다른 행위들은 현재 비활성화 되어있습니다." login_disabled: "사이트가 읽기 전용모드로 되면서 로그인은 비활성화되었습니다." + too_few_topics_and_posts_notice: "토론을 시작하시죠! 현재 %{currentTopics} / %{requiredTopics} 토픽과 %{currentPosts} / %{requiredPosts} 글이 있습니다. 새 방문자는 읽고 응답할 대화꺼리가 좀 필요해요." + too_few_topics_notice: "토론을 시작하시죠! 현재 %{currentTopics} / %{requiredTopics} 토픽이 있습니다. 새 방문자는 읽고 응답할 대화꺼리가 좀 필요해요." + too_few_posts_notice: "토론을 시작하시죠! 현재 %{currentPosts} / %{requiredPosts} 글이 있습니다. 새 방문자는 읽고 응답할 대화꺼리가 좀 필요해요." learn_more: "더 배우기" year: '년' - year_desc: '지난 365일간 생성된 글타래' + year_desc: '지난 365일간 생성된 토픽' month: '월' - month_desc: '지난 30일간 생성된 글타래' + month_desc: '지난 30일간 생성된 토픽' week: '주' - week_desc: '지난 7일간 생성된 글타래' + week_desc: '지난 7일간 생성된 토픽' day: '일' first_post: 첫 번째 글 mute: 음소거 @@ -602,14 +689,21 @@ ko: last_reply_lowercase: 마지막 답글 replies_lowercase: other: 답글 + signup_cta: + sign_up: "회원가입" + hide_session: "내일 다시 알려주기" + hide_forever: "사양합니다." + hidden_for_session: "알겠습니다. 내일 다시 물어볼께요. 언제든지 '로그인'을 통해서도 계정을 만들 수 있습니다." + intro: "안녕하세요! :heart_eyes: 글읽기는 좋아하시는데 아직 회원가입은 안하신 것 같네요." + value_prop: "회원가입 하시면 글을 어디까지 읽으셨는지 저희가 기억하기 때문에, 언제든지 마지막 읽은 위치로 바로 돌아갈 수 있답니다. 그리고 새글이 뜰때마다 이 화면과 이메일로 알림을 받을수도 있고, 좋아요를 클릭해서 글에 대한 애정을 표현하실 수도 있어요. :heartbeat:" summary: - enabled_description: "현재 글타래에서 가장 인기 있는 몇 개의 글들을 보고 있습니다." - description: "{{count}}개의 답글이 있습니다." - description_time: "총 {{count}}개의 댓글이 있습니다. 예상 소요 시간은 {{readingTime}}분입니다.." - enable: '이 글타래를 요약' - disable: 'Show All Posts' + enabled_description: "현재 커뮤니티에서 가장 인기있는 토픽의 요약본을 보고 있습니다:" + description: "댓글이 {{replyCount}}개 있습니다." + description_time: "댓글이 {{replyCount}}개 있고 다 읽는데 {{readingTime}} 분이 걸립니다." + enable: '이 토픽을 요약Show All Posts' + disable: '모든 포스트 보기' deleted_filter: - enabled_description: "이 글타래는 삭제된 글들을 포함하고 있습니다. 삭제된 글을 보이지 않습니다." + enabled_description: "이 토픽은 삭제된 글들을 포함하고 있습니다. 삭제된 글을 보이지 않습니다." disabled_description: "삭제된 글들을 표시하고 있습니다." enable: "삭제된 글 숨김" disable: "삭제된 글 보기" @@ -619,10 +713,10 @@ ko: remove_allowed_user: "{{name}}에게서 온 메시지를 삭제할까요?" email: '이메일' username: '아이디' - last_seen: '마지막 접근' + last_seen: '마지막 접속' created: '생성' created_lowercase: '최초 글' - trust_level: '신뢰도' + trust_level: '회원등급' search_hint: '아이디, 이메일 혹은 IP 주소' create_account: title: "회원 가입" @@ -659,6 +753,9 @@ ko: admin_not_allowed_from_ip_address: "You can't log in as admin from that IP address." resend_activation_email: "다시 인증 이메일을 보내려면 여기를 클릭하세요." sent_activation_email_again: " {{currentEmail}} 주소로 인증 이메일을 보냈습니다. 이메일이 도착하기까지 몇 분 정도 걸릴 수 있습니다. 또한 스팸 메일을 확인하십시오." + to_continue: "로그인 해주세요" + preferences: "사용자 환경을 변경하려면 로그인이 필요합니다." + forgot: "내 계정의 상세내역 기억하지 않는다." google: title: "Google" message: "Google 인증 중(팝업 차단을 해제 하세요)" @@ -681,15 +778,24 @@ ko: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "이모지 :)" + more_emoji: "더보기..." + options: "온셥" + whisper: "귓속말" add_warning: "공식적인 경고입니다." - posting_not_on_topic: "어떤 글타래에 답글을 작성하시겠습니까?" + toggle_whisper: "귀속말 켜고 끄기" + posting_not_on_topic: "어떤 토픽에 답글을 작성하시겠습니까?" saving_draft_tip: "저장 중..." saved_draft_tip: "저장 완료" saved_local_draft_tip: "로컬로 저장됩니다." - similar_topics: "작성하려는 내용과 비슷한 글타래들..." + similar_topics: "작성하려는 내용과 비슷한 토픽들..." drafts_offline: "초안" + group_mentioned: "{{group}}을 이용해서 {{count}} 명의 회원에게 알림을 보내려고 합니다." error: title_missing: "제목은 필수 항목입니다" title_too_short: "제목은 최소 {{min}} 글자 이상이어야 합니다." @@ -699,17 +805,18 @@ ko: try_like: ' 버튼을 사용해 보셨나요?' category_missing: "카테고리를 선택해주세요." save_edit: "편집 저장" - reply_original: "기존 글타래에 대해 답글을 작성합니다." + reply_original: "기존 토픽에 대해 답글을 작성합니다." reply_here: "여기에 답글을 작성하세요." reply: "답글 전송" cancel: "취소" - create_topic: "글타래(글) 쓰기" + create_topic: "토픽(글) 쓰기" create_pm: "메시지" title: "혹은 Ctrl + Enter 누름" users_placeholder: "사용자 추가" title_placeholder: "이야기 나누고자 하는 내용을 한문장으로 적는다면?" edit_reason_placeholder: "why are you editing?" show_edit_reason: "(add edit reason)" + reply_placeholder: "여기에 타이핑 하세요. 마크다운 또는 BBCode, HTML 포맷을 이용하세요. 이미지를 끌어오거나 붙여넣기 하세요." view_new_post: "새로운 글을 볼 수 있습니다." saving: "저장 중..." saved: "저장 완료!" @@ -726,6 +833,7 @@ ko: link_description: "링크 설명을 입력" link_dialog_title: "하이퍼링크 삽입" link_optional_text: "옵션 제목" + link_placeholder: "http://example.com \"선택적 텍스트\"" quote_title: "인용구" quote_text: "인용구" code_title: "코드 샘플" @@ -734,33 +842,34 @@ ko: upload_description: "업로드 설명을 입력" olist_title: "번호 매기기 목록" ulist_title: "글 머리 기호 목록" - list_item: "글타래" + list_item: "토픽" heading_title: "표제" heading_text: "표제" hr_title: "수평선" - undo_title: "취소" - redo_title: "다시" help: "마크다운 편집 도움말" toggler: "작성 패널을 숨기거나 표시" - admin_options_title: "이 글타래에 대한 옵션 설정" + modal_ok: "OK" + modal_cancel: "취소" + cant_send_pm: "죄송합니다. %{username}님에게 메시지를 보낼 수 없습니다." + admin_options_title: "이 토픽에 대한 옵션 설정" auto_close: - label: "자동-닫기 글타래 시간:" + label: "토픽 자동-닫기 시간:" error: "유효한 값은 눌러주세요." - based_on_last_post: "적어도 글타래의 마지막 글이 이만큼 오래되지 않았으면 닫지 마세요." + based_on_last_post: "적어도 토픽의 마지막 글이 이만큼 오래되지 않았으면 닫지 마세요." all: examples: '시간을 숫자(24이하)로 입력하거나 분을 포함한 시간(17:30) 혹은 타임스탬프(2013-11-22 14:00) 형식으로 입력하세요.' limited: units: "(# 시간)" examples: '시간에 해당하는 숫자를 입력하세요. (24)' notifications: - title: "@name 멘션, 글과 글타래에 대한 답글, 개인 메시지 등에 대한 알림" + title: "@name 멘션, 글과 토픽에 대한 답글, 개인 메시지 등에 대한 알림" none: "현재 알림을 불러올 수 없습니다." more: "이전 알림을 볼 수 있습니다." total_flagged: "관심 표시된 총 글" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -769,9 +878,27 @@ ko: invitee_accepted: "

    {{username}} accepted your invitation

    " moved_post: "

    {{username}} moved {{description}}

    " linked: "

    {{username}} {{description}}

    " - granted_badge: "

    '{{description}}' 뱃지를 받았습니다.

    " + granted_badge: "

    '{{description}}' 배지를 받았습니다.

    " + group_message_summary: + other: "

    {{group_name}} 메시지상자에 {{count}}개의 메시지가 있습니다

    " + alt: + mentioned: "멘션 by" + quoted: "인용 by" + replied: "답글을 전송했습니다." + posted: "포스트 by" + edited: "당신 글이 다음 이용자에 의해 수정" + liked: "당신의 글을 좋아했음." + private_message: "다음 사람에게서온 개인 메시지" + invited_to_private_message: "다음 사람으로부터 개인 메시지가 초대됨" + invited_to_topic: "다음 사람으로부터 한 주제로 초대됨" + invitee_accepted: "다음 사람에 의해 초대가 수락됨." + moved_post: "다음 사람에 의해서 당신의 글이 이동됨" + linked: "당신 글로 링크하기" + granted_badge: "배지가 수여됨." + group_message_summary: "그룹 메시지함의 메시지" popup: mentioned: '"{{topic}}" - {{site_title}}에서 {{username}} 님이 나를 멘션했습니다' + group_mentioned: '"{{topic}}" - {{site_title}}에서 {{username}} 님이 당신을 언급했습니다' quoted: '"{{topic}}" - {{site_title}}에서 {{username}} 님이 나를 인용했습니다' replied: '"{{topic}}" - {{site_title}}에서 {{username}} 님이 내게 답글을 달았습니다' posted: '"{{topic}}" - {{site_title}}에서 {{username}}님이 글을 게시하였습니다' @@ -783,15 +910,25 @@ ko: from_my_computer: "컴퓨터에서 가져오기" from_the_web: "인터넷에서 가져오기" remote_tip: "이미지 링크" - remote_tip_with_attachments: "이미지 또는 파일 링크 ({{authorized_extensions}})" + remote_tip_with_attachments: "이미니자 파일 링크 {{authorized_extensions}}" local_tip: "기기에서 이미지 선택" - local_tip_with_attachments: "기기에서이미지 또는 파일을 선택 ({{authorized_extensions}})" + local_tip_with_attachments: "디바이스에서 이미지나 파일을 선택하세요 {{authorized_extensions}}" hint: "(드래그&드랍으로 업로드 가능)" + hint_for_supported_browsers: "편집창에 이미지를 끌어다 놓거나 붙여넣기 할 수도 있습니다" uploading: "업로드 중입니다..." select_file: "파일 선택" image_link: "이 이미지를 누르면 이동할 링크" search: - title: "글타래, 글, 사용자, 카테고리 검색" + sort_by: "다음으로 정렬" + relevance: "관련성" + latest_post: "가장 최근 글" + most_viewed: "가장 많이 본" + most_liked: "가장 많이 좋아요를 받은" + select_all: "모두 선택" + clear_all: "다 지우기" + result_count: + other: "\"{{term}}\" 검색결과 {{count}} 개" + title: "토픽, 글, 사용자, 카테고리 검색" no_results: "검색 결과가 없습니다" no_more_results: "더 이상 결과가 없습니다." search_help: 검색 도움말 @@ -800,108 +937,119 @@ ko: context: user: "@{{username}}의 글 검색" category: "\"{{category}}\" 카테고리 검색" - topic: "이 글타래를 검색" + topic: "이 토픽을 검색" private_messages: "메시지 검색" - hamburger_menu: "다른 글타래 목록이나 카테고리로 가기" + hamburger_menu: "다른 토픽 목록이나 카테고리로 가기" + new_item: "새로운" go_back: '돌아가기' not_logged_in_user: 'user page with summary of current activity and preferences' current_user: '사용자 페이지로 이동' topics: bulk: + unlist_topics: "토픽 내리기" reset_read: "읽기 초기화" - delete: "글타래 삭제" - dismiss_posts: "글 닫기" - dismiss_posts_tooltip: "이 글타래들의 '읽지 않은' 표시를 없애고 새 글타래가 발생하면 내 '읽지 않은' 목록에 표시하기" - dismiss_topics: "글타래 닫기" - dismiss_topics_tooltip: "새글이 발생할 때 내 '읽지 않은' 목록에 표시하지 않기" + delete: "토픽 삭제" + dismiss: "해지" + dismiss_read: "읽지않음 전부 해지" + dismiss_button: "해지..." + dismiss_tooltip: "새 글을 무시하거나 토픽 추적 멈추기" + also_dismiss_topics: "이 토픽 추적하는 걸 멈추고 내가 읽지 않은 걸 다시는 보여주지 않습니다" dismiss_new: "새글 제거" - toggle: "복수글타래 선택 기능" + toggle: "토픽 복수 선택" actions: "일괄 적용" change_category: "카테고리 변경" - close_topics: "글타래 닫기" - archive_topics: "글타래 보관하기" + close_topics: "토픽 닫기" + archive_topics: "토픽 보관하기" notification_level: "알림 설정 변경" - choose_new_category: "글타래의 새로운 카테고리를 선택" + choose_new_category: "토픽의 새로운 카테고리를 선택" selected: - other: "{{count}}개의 글타래가 선택되었습니다." + other: "{{count}}개의 토픽이 선택되었습니다." none: - unread: "읽지 않은 글타래가 없습니다." - new: "읽을 새로운 글타래가 없습니다." - read: "아직 어떠한 글타래도 읽지 않았습니다." - posted: "아직 어떠한 글타래도 작성되지 않았습니다." - latest: "최신 글타래가 없습니다." - hot: "인기있는 글타래가 없습니다." - bookmarks: "아직 북마크한 글타래가 없습니다." - category: "{{category}}에 글타래가 없습니다." - top: "Top 글타래가 없습니다." + unread: "읽지 않은 토픽이 없습니다." + new: "읽을 새로운 토픽이 없습니다." + read: "아직 어떠한 토픽도 읽지 않았습니다." + posted: "아직 어떠한 토픽도 작성되지 않았습니다." + latest: "최신 토픽이 없습니다." + hot: "인기있는 토픽이 없습니다." + bookmarks: "아직 북마크한 토픽이 없습니다." + category: "{{category}}에 토픽이 없습니다." + top: "Top 토픽이 없습니다." search: "검색 결과가 없습니다." educate: - new: '

    새로운 글타래는 여기에서 볼 수 있습니다.

    기본 설정으로 2일 이내에 생성된 글타래는 새로운 것으로 간주되며 new 표시가 나타납니다.

    환경설정에서 설정을 변경 할 수 있습니다.

    ' - unread: '

    읽지 않은 글타래는 여기에서 볼 수 있습니다.

    기본 설정으로 다음과 같은 경우 글타래는 읽지 않은 것으로 간주되며 읽지 않은 개수 1 가 표시됩니다.

    • 글타래를 만든 경우
    • 글타래에 리플을 단 경우
    • 글타래를 4분 이상 읽은 경우

    또는 각 글타래 아래에 있는 알림 설정에서 해당 글타래를 추적하거나 지켜보도록 설정한 경우

    환경설정에서 설정을 변경 할 수 있습니다.

    ' + new: '

    회원님의 토픽은 여기에 나타납니다.

    기본적으로 생긴 지 이틀 안된 토픽은 새것으로 간주하고 new 표시가 뜹니다.

    바꾸고 싶으면 환경설정으로 가보세요.

    ' + unread: '

    회원님이 읽지 않은 토픽은 여기에 나타납니다.

    기본적으로 토픽은 읽지 않은 것으로 간주하고 다음과 같은 조건 중 하나를 만족하면 읽지 않은 글갯수 1 을 표시합니다:

    • 토픽 만들기
    • 토픽에 댓글달기
    • 토픽을 4분 이상 읽기

    또는 토픽을 추적하거나 지켜보기 위해 각 토픽의 밑부분에 달린 알림제어판에서 설정하는 경우도 포합됩니다.

    설정을 바꾸려면 환경설정 페이지로 가세요.

    ' bottom: - latest: "더 이상 읽을 최신 글타래가 없습니다" - hot: "더 이상 읽을 인기있는 글타래가 없습니다" - posted: "더 이상 작성된 글타래가 없습니다" - read: "더 이상 읽을 글타래가 없습니다" - new: "더 이상 읽을 새로운 글타래가 없습니다." - unread: "더 이상 읽지 않은 글타래가 없습니다" - category: "더 이상 {{category}}에 글타래가 없습니다" - top: "더 이상 인기 글타래가 없습니다." - bookmarks: "더이상 북마크한 글타래가 없습니다." + latest: "더 이상 읽을 최신 토픽이 없습니다" + hot: "더 이상 읽을 인기있는 토픽이 없습니다" + posted: "더 이상 작성된 토픽이 없습니다" + read: "더 이상 읽을 토픽이 없습니다" + new: "더 이상 읽을 새로운 토픽이 없습니다." + unread: "더 이상 읽지 않은 토픽이 없습니다" + category: "더 이상 {{category}}에 토픽이 없습니다" + top: "더 이상 인기 토픽이 없습니다." + bookmarks: "더이상 북마크한 토픽이 없습니다." search: "더이상 검색 결과가 없습니다." topic: unsubscribe: + stop_notifications: "{{title}}에 대한 알림은 이제 덜 받게 됩니다." change_notification_state: "현재 당신의 알림 설정 : " - filter_to: "이 글타래에서 {{username}}님의 {{post_count}}건의 글만 보기" - create: '새 글타래 만들기' - create_long: '새로운 글타래를 개설' + filter_to: " {{post_count}} 게시글 in 토픽" + create: '새 토픽 만들기' + create_long: '새로운 토픽 만들기' private_message: '메시지 시작' - list: '글타래 목록' - new: '새로운 글타래' + archive_message: + help: '메시지를 아카이브로 옮기기' + title: '저장됨' + move_to_inbox: + title: '수신함으로 이동' + help: '메시지를 편지함으로 되돌리기' + list: '토픽 목록' + new: '새로운 토픽' unread: '읽지 않은' new_topics: - other: '{{count}}개의 새로운 글타래' + other: '{{count}}개의 새로운 토픽' unread_topics: - other: '{{count}}개의 읽지 않은 글타래' - title: '글타래' + other: '{{count}}개의 읽지 않은 토픽' + title: '토픽' invalid_access: - title: "이 글타래는 비공개입니다" - description: "죄송합니다. 그 글타래에 접근 할 수 없습니다!" - login_required: "해당 글타래를 보려면 로그인이 필요합니다." + title: "이 토픽은 비공개입니다" + description: "죄송합니다. 그 토픽에 접근 할 수 없습니다!" + login_required: "해당 토픽을 보려면 로그인이 필요합니다." server_error: - title: "글타래를 불러오지 못했습니다" - description: "죄송합니다. 연결 문제로 인해 해당 글타래를 불러올 수 없습니다. 다시 시도하십시오. 문제가 지속되면 문의해 주시기 바랍니다" + title: "토픽을 불러오지 못했습니다" + description: "죄송합니다. 연결 문제로 인해 해당 토픽을 불러올 수 없습니다. 다시 시도하십시오. 문제가 지속되면 문의해 주시기 바랍니다" not_found: - title: "글타래를 찾을 수 없습니다" - description: "죄송합니다. 글타래를 찾을 수 없습니다. 아마도 운영자에 의해 삭제된 것 같습니다." + title: "토픽을 찾을 수 없습니다" + description: "죄송합니다. 토픽을 찾을 수 없습니다. 아마도 운영자에 의해 삭제된 것 같습니다." total_unread_posts: - other: "이 글타래에 {{count}}개의 읽지 않을 게시 글이 있습니다." + other: "이 토픽에 {{count}}개의 읽지 않을 게시 글이 있습니다." unread_posts: - other: "이 글타래에 {{count}}개의 읽지 않을 게시 글이 있습니다." + other: "이 토픽에 {{count}}개의 읽지 않을 게시 글이 있습니다." new_posts: - other: "최근 읽은 이후 {{count}}개 글이 이 글타래 작성되었습니다." + other: "최근 읽은 이후 {{count}}개 글이 이 토픽에 작성되었습니다." likes: - other: "이 글타래에 {{count}}개의 '좋아요'가 있습니다." - back_to_list: "글타래 리스트로 돌아갑니다." - options: "글타래 옵션" - show_links: "이 글타래에서 링크를 표시합니다." - toggle_information: "글타래의 세부 정보를 토글합니다." - read_more_in_category: "더 많은 글타래들은 {{catLink}} 또는 {{latestLink}}에서 찾으실 수 있습니다" - read_more: "{{catLink}} 또는 {{latestLink}}에서 더 많은 글타래들을 찾으실 수 있습니다" - read_more_MF: "이 카테고리에 { UNREAD, plural, =0 {} one { is 1개의 안 읽은 } other { are #개의 안 읽은 } } { NEW, plural, =0 {} one { {BOTH, select, true{and } false {is } other{}} 1개의 새로운 글타래가} other { {BOTH, select, true{and } false {are } other{}} # 새로운 글타래가} } 남아 있고, {CATEGORY, select, true {{catLink} 글타래도 확인해보세요.} false {{latestLink}} other {}}" + other: "이 토픽에 {{count}}개의 '좋아요'가 있습니다." + back_to_list: "토픽 리스트로 돌아갑니다." + options: "토픽 옵션" + show_links: "이 토픽에서 링크를 표시합니다." + toggle_information: "토픽의 세부 정보를 토글합니다." + read_more_in_category: "더 많은 토픽들은 {{catLink}} 또는 {{latestLink}}에서 찾으실 수 있습니다" + read_more: "{{catLink}} 또는 {{latestLink}}에서 더 많은 토픽들을 찾으실 수 있습니다" + read_more_MF: "이 카테고리에 { UNREAD, plural, =0 {} one { is 1개의 안 읽은 } other { are #개의 안 읽은 } } { NEW, plural, =0 {} one { {BOTH, select, true{and } false {is } other{}} 1개의 새로운 토픽이} other { {BOTH, select, true{and } false {are } other{}} # 새로운 토픽이} } 남아 있고, {CATEGORY, select, true {{catLink} 토픽도 확인해보세요.} false {{latestLink}} other {}}" browse_all_categories: 모든 카테고리 보기 - view_latest_topics: 최신 글타래 보기 + view_latest_topics: 최신 토픽 보기 suggest_create_topic: 토픽(글)을 작성 해 보실래요? jump_reply_up: 이전 답글로 이동 jump_reply_down: 이후 답글로 이동 - deleted: "글타래가 삭제되었습니다" - auto_close_notice: "이 글타래는 곧 자동으로 닫힙니다. %{timeLeft}." - auto_close_notice_based_on_last_post: "이 글타래는 마지막 답글이 달린 %{duration} 후 닫힙니다." + deleted: "토픽이 삭제되었습니다" + auto_close_notice: "이 토픽은 곧 자동으로 닫힙니다. %{timeLeft}." + auto_close_notice_based_on_last_post: "이 토픽은 마지막 답글이 달린 %{duration} 후 닫힙니다." auto_close_title: '자동으로 닫기 설정' auto_close_save: "저장" - auto_close_remove: "이 글타래를 자동으로 닫지 않기" + auto_close_remove: "이 토픽을 자동으로 닫지 않기" + auto_close_immediate: "토픽에 마지막 글이 올라온 지 %{hours} 시간 지났기 때문에 이 토픽은 즉시 닫힐 예정입니다." progress: - title: 진행 중인 글타래 + title: 진행 중인 토픽 go_top: "맨위" go_bottom: "맨아래" go: "이동" @@ -914,30 +1062,30 @@ ko: reasons: '3_6': '이 카테고리를 보고 있어서 알림을 받게 됩니다.' '3_5': '자동으로 이 글을 보고있어서 알림을 받게 됩니다.' - '3_2': '이 글타래를 보고있어서 알림을 받게 됩니다.' - '3_1': '이 글타래를 생성하여서 알림을 받게 됩니다.' - '3': '이 글타래를 보고있어서 알림을 받게 됩니다.' - '2_8': '이 글타래를 추적하고 있어서 알림을 받게 됩니다.' - '2_4': '이 글타래에 답글을 게시하여서 알림을 받게 됩니다.' - '2_2': '이 글타래를 추적하고 있어서 알림을 받게 됩니다.' - '2': '이 글타래를 읽어서 알림을 받게 됩니다. (설정)' + '3_2': '이 토픽을 보고있어서 알림을 받게 됩니다.' + '3_1': '이 토픽을 생성하여서 알림을 받게 됩니다.' + '3': '이 토픽을 보고있어서 알림을 받게 됩니다.' + '2_8': '이 토픽을 추적하고 있어서 알림을 받게 됩니다.' + '2_4': '이 토픽에 답글을 게시하여서 알림을 받게 됩니다.' + '2_2': '이 토픽을 추적하고 있어서 알림을 받게 됩니다.' + '2': '이 토픽을 읽어서 알림을 받게 됩니다. (설정)' '1_2': '누군가 내 @아아디 으로 멘션했거나 내 글에 답글이 달릴 때 알림을 받게 됩니다.' '1': '누군가 내 @아아디 으로 멘션했거나 내 글에 답글이 달릴 때 알림을 받게 됩니다.' - '0_7': '이 글타래에 관한 모든 알림을 무시하고 있습니다.' - '0_2': '이 글타래에 관한 모든 알림을 무시하고 있습니다.' - '0': '이 글타래에 관한 모든 알림을 무시하고 있습니다.' + '0_7': '이 토픽에 관한 모든 알림을 무시하고 있습니다.' + '0_2': '이 토픽에 관한 모든 알림을 무시하고 있습니다.' + '0': '이 토픽에 관한 모든 알림을 무시하고 있습니다.' watching_pm: title: "알림 : 주시 중" description: "이 메시지에 새로운 답글이 있을 때 알림을 받게 되며 새로운 답글의 개수는 표시됩니다." watching: title: "주시 중" - description: "이 글타래에 새로운 답글이 있을 때 알림을 받게 되며 새로운 답글의 개수는 표시됩니다." + description: "이 토픽에 새로운 답글이 있을 때 알림을 받게 되며 새로운 답글의 개수는 표시됩니다." tracking_pm: title: "알림 : 새 글 표시 중" description: "이 메시지의 읽지않은 응답의 수가 표시됩니다. 누군가 내 @아이디를 멘션했거나 내게 답글을 작성하면 알림을 받습니다." tracking: title: "새 글 표시 중" - description: "이 글타래의 새로운 답글의 수가 표시됩니다. 누군가 내 @아이디를 멘션했거나 내게 답글을 작성하면 알림을 받습니다." + description: "이 토픽의 새로운 답글의 수가 표시됩니다. 누군가 내 @아이디를 멘션했거나 내게 답글을 작성하면 알림을 받습니다." regular: title: "알림 : 일반" description: "누군가 내 @아아디 으로 멘션했거나 내 글에 답글이 달릴 때 알림을 받게 됩니다." @@ -949,66 +1097,64 @@ ko: description: "이 메시지에 대해 어떠한 알림도 받지 않지 않습니다." muted: title: "알림 없음" - description: "아무 알림도 없습니다. '읽지 않은 글' 탭에 나타나지 않습니다." + description: "이 토픽에 대해 어떠한 알림도 받지 않고 최신글 목록에도 나타나지 않을 것입니다." actions: - recover: "글타래 다시 복구" - delete: "글타래 삭제" - open: "글타래 열기" - close: "글타래 닫기" + recover: "토픽 다시 복구" + delete: "토픽 삭제" + open: "토픽 열기" + close: "토픽 닫기" multi_select: "글 선택" auto_close: "자동으로 닫기..." - pin: "글타래 고정..." - unpin: "글타래 고정 취소..." - unarchive: "보관 안된 글타래" - archive: "보관된 글타래" + pin: "토픽 고정..." + unpin: "토픽 고정 취소..." + unarchive: "토픽 보관 취소" + archive: "토픽 보관" invisible: "목록에서 제외하기" visible: "목록에 넣기" reset_read: "값 재설정" feature: - pin: "글타래 고정" - unpin: "글타래 고정 취소" - pin_globally: "전역적으로 글타래 고정" - make_banner: "배너 글타래" - remove_banner: "배너 글타래 제거" + pin: "토픽 고정" + unpin: "토픽 고정 취소" + pin_globally: "전역적으로 토픽 고정" + make_banner: "배너 토픽" + remove_banner: "배너 토픽 제거" reply: title: '답글' - help: '이 글타래에 대한 답글 구성 시작' + help: '이 토픽에 대한 답글 작성 시작' clear_pin: title: "고정 취소" - help: "더 이상 목록의 맨 위에 표시하지 않도록 이 글타래의 고정 상태를 해제합니다." + help: "더 이상 목록의 맨 위에 표시하지 않도록 이 토픽의 고정 상태를 해제합니다." share: title: '공유' - help: '이 글타래의 링크를 공유' + help: '이 토픽의 링크를 공유' flag_topic: - title: '신고' - help: '운영자에게 이 글을 신고합니다.' - success_message: '성공적으로 글타래를 신고 하였습니다.' + title: '신고하기' + help: '이 토픽을 주의깊게 보거나 비밀리에 주의성 알림을 보내기 위해 신고합니다' + success_message: '신고했습니다' feature_topic: - title: "Feature 글타래" - pin: " {{categoryLink}} 카테고리 글타래 목록 상단에 고정 until" - confirm_pin: "이미 {{count}}개의 고정된 글타래가 있습니다. 너무 많은 글타래가 고정되어 있으면 새로운 사용자나 익명사용자에게 부담이 될 수 있습니다. 정말로 이 카테고리에 추가적으로 글타래를 고정하시겠습니까?" - unpin: "이 글타래를 {{categoryLink}} 카테고리 상단에서 제거 합니다." - unpin_until: "{{categoryLink}} 카테고리 글타래 목록 상단에서 이 글타래를 제거하거나 %{until}까지 기다림." - pin_note: "개별적으로 사용자가 글타래 고정을 취소할 수 있습니다." + title: "Feature 토픽" + pin: " {{categoryLink}} 카테고리 토픽 목록 상단에 고정 until" + confirm_pin: "이미 {{count}}개의 고정된 토픽이 있습니다. 너무 많은 토픽이 고정되어 있으면 새로운 사용자나 익명사용자에게 부담이 될 수 있습니다. 정말로 이 카테고리에 추가적으로 토픽을 고정하시겠습니까?" + unpin: "이 토픽을 {{categoryLink}} 카테고리 상단에서 제거 합니다." + unpin_until: "{{categoryLink}} 카테고리 토픽 목록 상단에서 이 토픽을 제거하거나 %{until}까지 기다림." + pin_note: "개별적으로 사용자가 토픽 고정을 취소할 수 있습니다." + pin_validation: "토픽을 고정하려면 날짜를 지정해야 합니다." + not_pinned: " {{categoryLink}} 카테고리에 고정된 토픽이 없습니다." already_pinned: - zero: " {{categoryLink}} 카테고리에 고정된 글타래가 없습니다." - one: "{{categoryLink}} 카테고리에 고정된 글타래: 1." - other: "{{categoryLink}} 카테고리에 고정된 글타래: {{count}}." - pin_globally: "모든 글타래 목록 상단 고정 until" - confirm_pin_globally: "이미 {{count}}개의 글타래가 전역적으로 고정되어 있습니다. 너무 많은 글타래가 고정되어 있으면 새로운 사용자나 익명사용자에게 부담이 될 수 있습니다. 정말로 이 글타래를 전역적으로 고정하시겠습니까?" - unpin_globally: "모든 글타래 목록 상단에서 이 글타래를 제거" - unpin_globally_until: "모든 글타래 목록 상단에서 이 글타래를 제거하거나 %{until}까지 기다림." - global_pin_note: "개별적으로 사용자가 글타래 고정을 취소할 수 있습니다." + other: "{{categoryLink}}에 고정된 토픽 갯수: {{count}}" + pin_globally: "모든 토픽 목록 상단 고정 until" + confirm_pin_globally: "이미 {{count}}개의 토픽이 전역적으로 고정되어 있습니다. 너무 많은 토픽이 고정되어 있으면 새로운 사용자나 익명사용자에게 부담이 될 수 있습니다. 정말로 이 토픽을 전역적으로 고정하시겠습니까?" + unpin_globally: "모든 토픽 목록 상단에서 이 토픽을 제거" + unpin_globally_until: "모든 토픽 목록 상단에서 이 토픽을 제거하거나 %{until}까지 기다림." + global_pin_note: "개별적으로 사용자가 토픽 고정을 취소할 수 있습니다." + not_pinned_globally: "전역적으로 고정된 토픽이 없습니다." already_pinned_globally: - zero: "전역적으로 고정된 글타래가 없습니다." - one: "전역적으로 고정된 글타래: 1." - other: "전역적으로 고정된 글타래: {{count}}." - make_banner: "이 글타래를 모든 페이지의 상단에 나타나는 배너로 만들기" + other: "전역적으로 고정된 토픽 갯수: {{count}}" + make_banner: "이 토픽을 모든 페이지의 상단에 나타나는 배너로 만들기" remove_banner: "모든 페이지에서 나타나는 배너에서 제거" - banner_note: "사용자는 배너를 닫음으로써 배너를 나타나지 않게 할 수 있습니다. 단지 어떤 기간동안 딱 하나의 글타래만이 배너로 지정 가능합니다." - already_banner: - zero: "배너 글타래가 없습니다." - one: "현재 배너글타래가 존재합니다." + banner_note: "사용자는 배너를 닫음으로써 배너를 나타나지 않게 할 수 있습니다. 단지 어떤 기간동안 딱 하나의 토픽만이 배너로 지정 가능합니다." + no_banner_exists: "배너 토픽이 없습니다." + banner_exists: "현재 배너 토픽이 있습니다." inviting: "초대 중..." automatically_add_to_groups_optional: "이 초대는 다음 그룹에 대한 접근 권한을 포함합니다: (선택, 관리자만 가능)" automatically_add_to_groups_required: "이 초대는 다음 그룹에 대한 접근 권한을 포함합니다: (필수, 관리자만 가능)" @@ -1024,16 +1170,16 @@ ko: title: '초대하기' username_placeholder: "아이디" action: '초대장 보내기' - help: '이메일을 통해 다른 사람을 이 글타래에 초대합니다.' + help: '이메일을 통해 다른 사람을 이 토픽에 초대합니다.' to_forum: "친구에게 요약 이메일을 보내고 이 포럼에 가입할 수 있도록 링크를 전송합니다." - sso_enabled: "이 글타래에 초대하고 싶은 사람의 아이디를 입력하세요." - to_topic_blank: "이 글타래에 초대하고 싶은 사람의 아이디나 이메일주소를 입력하세요." - to_topic_email: "이메일 주소를 입력하셨습니다. 친구들에게 이 글타래에 답변 달기가 가능하도록 조치하는 초대장을 보내겠습니다." - to_topic_username: "아이디를 입력하셨습니다. 이 글타래에 초대하는 링크와 함께 알림을 보내겠습니다." - to_username: "초대하려는 사용자의 아이디를 입력하세요. 이 글타래에 초대하는 링크와 함께 알림을 보내겠습니다." + sso_enabled: "이 토픽에 초대하고 싶은 사람의 아이디를 입력하세요." + to_topic_blank: "이 토픽에 초대하고 싶은 사람의 아이디나 이메일주소를 입력하세요." + to_topic_email: "이메일 주소를 입력하셨습니다. 친구들에게 이 토픽에 답변 달기가 가능하도록 조치하는 초대장을 보내겠습니다." + to_topic_username: "아이디를 입력하셨습니다. 이 토픽에 초대하는 링크와 함께 알림을 보내겠습니다." + to_username: "초대하려는 사용자의 아이디를 입력하세요. 이 토픽에 초대하는 링크와 함께 알림을 보내겠습니다." email_placeholder: '이메일 주소' success_email: "{{emailOrUsername}}로 초대장을 발송했습니다. 초대를 수락하면 알려 드리겠습니다. 초대상태를 확인하려면 사용자 페이지에서 '초대장' 탭을 선택하세요." - success_username: "사용자가 이 글타래에 참여할 수 있도록 초대했습니다." + success_username: "사용자가 이 토픽에 참여할 수 있도록 초대했습니다." error: "그 사람을 초대할 수 없습니다. 혹시 이미 초대하진 않았나요? (Invites are rate limited)" login_reply: '로그인하고 답글 쓰기' filters: @@ -1041,18 +1187,18 @@ ko: other: "{{count}} 글" cancel: "필터 제거" split_topic: - title: "새로운 글타래로 이동" - action: "새로운 글타래로 이동" - topic_name: "새로운 글타래 이름" - error: "새로운 글타래로 이동시키는데 문제가 발생하였습니다." + title: "새로운 토픽으로 이동" + action: "새로운 토픽으로 이동" + topic_name: "새로운 토픽 이름" + error: "새로운 토픽으로 이동시키는데 문제가 발생하였습니다." instructions: - other: "새로운 글타래를 생성하여, 선택한 {{count}}개의 글로 채우려고 합니다." + other: "새로운 토픽을 생성하여, 선택한 {{count}}개의 글로 채우려고 합니다." merge_topic: - title: "이미 있는 글타래로 옮기기" - action: "이미 있는 글타래로 옮기기" - error: "이 글타래를 이동시키는데 문제가 발생하였습니다." + title: "이미 있는 토픽으로 옮기기" + action: "이미 있는 토픽으로 옮기기" + error: "이 토픽을 이동시키는데 문제가 발생하였습니다." instructions: - other: " {{count}}개의 글을 옮길 글타래를 선택해주세요." + other: " {{count}}개의 글을 옮길 토픽을 선택해주세요." change_owner: title: "글 소유자 변경" action: "작성자 바꾸기" @@ -1062,6 +1208,11 @@ ko: instructions: other: "{{old_user}}(이)가 작성한 글의 새로운 작성자를 선택해주세요." instructions_warn: "이 글에 대한 알림이 새 사용자에게 자동으로 이전되지 않습니다.\n
    경고: 글과 연관된 데이터가 새로운 사용자로 이전되지 않습니다. 주의해서 사용하세요." + change_timestamp: + title: "타임스탬프 변경" + action: "타임스탬프 변경" + invalid_timestamp: "타임스탬프는 미래값으로 할 수 없습니다." + error: "토픽 타임스탬프를 바꾸는 중 에러가 발생하였습니다." multi_select: select: '선택' selected: '({{count}})개가 선택됨' @@ -1080,13 +1231,13 @@ ko: edit_reason: "Reason: " post_number: "{{number}}번째 글" last_edited_on: "마지막으로 편집:" - reply_as_new_topic: "링크된 글타래로 답글 작성하기" + reply_as_new_topic: "연결된 토픽으로 답글 작성하기" continue_discussion: "{{postLink}}에서 토론을 계속:" follow_quote: "인용 글로 이동" show_full: "전체 글 보기" show_hidden: '숨겨진 내용을 표시' deleted_by_author: - other: "(작성자에 의해 취소된 글입니다. 신고당한 글이 아니면 %{count} 시간 뒤에 자동으로 삭제됩니다)" + other: "(작성자에 의해 취소된 글입니다. 글이 신고된 것이 아닌 한 %{count} 시간 뒤에 자동으로 삭제됩니다)" expand_collapse: "확장/축소" gap: other: "{{count}}개의 숨겨진 답글 보기" @@ -1098,10 +1249,9 @@ ko: other: "{{count}} 좋아요" has_likes_title: other: "{{count}}명이 이 글을 좋아합니다" + has_likes_title_only_you: "당신이 이 글을 좋아합니다." has_likes_title_you: - zero: "이 글을 좋아합니다." - one: "당신과 다른 1명이 이 글을 좋아합니다." - other: "당신과 {{count}}명이 이 글을 좋아합니다." + other: "당신 외 {{count}}명이 이 글을 좋아합니다" errors: create: "죄송합니다. 글을 만드는 동안 오류가 발생했습니다. 다시 시도하십시오." edit: "죄송합니다. 글을 수정하는 중에 오류가 발생했습니다. 다시 시도하십시오." @@ -1118,9 +1268,10 @@ ko: confirm: "글 작성을 취소 하시겠습니까?" no_value: "아니오" yes_value: "예" - via_email: "이 글타래는 이메일을 통해 등록되었습니다." + via_email: "이 토픽은 이메일을 통해 등록되었습니다." + whisper: "이 포스트는 운영자를 위한 비공개 귓말입니다." wiki: - about: "이 글은 위키입니다. 누구나 수정할 수 있습니다." + about: "이 글은 위키(wiki) 입니다." archetypes: save: '옵션 저장' controls: @@ -1129,8 +1280,8 @@ ko: has_liked: "이 글을 좋아합니다." undo_like: "'좋아요' 취소" edit: "이 글 편집" - edit_anonymous: "이 글타래를 수정하려면 먼저 로그인을 해야합니다." - flag: "운영자에게 이 글을 신고합니다." + edit_anonymous: "이 토픽을 수정하려면 먼저 로그인을 해야합니다." + flag: "이 토픽에 관심을 가지기 위해 깃발을 표시해두고 개인적으로 알림을 받습니다" delete: "이 글을 삭제합니다." undelete: "이 글 삭제를 취소합니다." share: "이 글에 대한 링크를 공유합니다." @@ -1147,18 +1298,19 @@ ko: revert_to_regular: "스태프 색상 제거하기" rebake: "HTML 다시 빌드하기" unhide: "숨기지 않기" + change_owner: "소유자 변경" actions: - flag: '신고' + flag: '신고하기' defer_flags: - other: "신고 연기" + other: "신고 보류하기" it_too: - off_topic: "Flag it too" - spam: "저도 신고합니다" - inappropriate: "저도 신고합니다" - custom_flag: "신고 추가하기" - bookmark: "Bookmark it too" - like: "저도 '좋아요' 줄래요" - vote: "Vote for it too" + off_topic: "나도 신고하기" + spam: "나도 신고하기" + inappropriate: "나도 신고하기" + custom_flag: "나도 신고하기" + bookmark: "나도 북마크하기" + like: "나도 좋아해요" + vote: "나도 투표하기" undo: off_topic: "신고 취소" spam: "신고 취소" @@ -1167,64 +1319,57 @@ ko: like: "좋아요 취소" vote: "투표 취소" people: - off_topic: "{{icons}}님이 이 글을 글타래에서 제외했습니다." - spam: "{{icons}} 스팸으로 신고되었습니다" - spam_with_url: "{{icons}} 스팸으로 표시됨" - inappropriate: "{{icons}} 부적절하다고 신고했습니다" - notify_moderators: "{{icons}}님은 이 글을 운영자에게 보고했습니다." - notify_moderators_with_url: "{{icons}}님은 이 을 운영자에게 보고했습니다." - notify_user: "{{icons}} 메시지를 보냈습니다" - notify_user_with_url: "{{icons}} 메시지를 보냈습니다." - bookmark: "{{icons}}님이 북마크했습니다." - like: "{{icons}}님이 좋아합니다." - vote: "{{icons}}님이 투표했습니다." + off_topic: "주제에서 벗어났다고 신고했습니다" + spam: "스팸으로 신고했습니다" + inappropriate: "부적절한 글로 신고했습니다" + notify_moderators: "운영자에게 알렸습니다" + notify_user: "글쓴이에게 메시지를 보냈습니다" + bookmark: "북마크 했습니다" + like: "좋아해요" + vote: "이곳에 투표했습니다" by_you: - off_topic: "이 글을 글타래에서 벗어남으로 신고함" - spam: "이 글을 스팸으로 신고함" - inappropriate: "이 글을 부적절로 신고함" - notify_moderators: "이 글을 운영자에게 보고함" - notify_user: "이 사용자에게 메시지를 보냈습니다." - bookmark: "이 글을 북마크함" - like: "'좋아요' 했습니다" - vote: "이 글에 투표함" + off_topic: "이글을 주제에서 벗어났다고 신고했습니다" + spam: "이글을 스팸으로 신고했습니다" + inappropriate: "이 글을 부적절한 컨텐츠로 신고했습니다" + notify_moderators: "운영자에게 알렸습니다" + notify_user: "글쓴이에게 메시지를 보냈습니다" + bookmark: "이 글을 북마크했습니다" + like: "좋아해요" + vote: "이 글에 투표했습니다" by_you_and_others: off_topic: - other: "나와 {{count}}명의 다른 사용자가 이 글을 글타래에서 제외했습니다." + other: "당신 외 {{count}}명이 주제에서 벗어났다고 신고했습니다" spam: - other: "나와 {{count}}명의 다른 사람들이 스팸이라고 신고했습니다" + other: "당신 외 {{count}}명이 스팸이라고 신고했습니다" inappropriate: - other: "나와 {{count}}명의 다른 사람들이 부적절하다고 신고했습니다" + other: "당신 외 {{count}}명이 부적절한 컨텐츠라고 신고했습니다" notify_moderators: - other: "나와 {{count}}명의 다른 사람들이 적당하다고 표시했습니다." + other: "당신 외 {{count}}명이 운영자에게 알렸습니다" notify_user: - other: "나와 {{count}}명의 사용자가 이 사용자에게 메시지를 보냈습니다." + other: "당신 외 {{count}}명이 글쓴이에게 메시지를 보냈습니다" bookmark: - other: "나와 {{count}}명의 다른 사람들이 북마크 했습니다." + other: "당신 외 {{count}}명이 북마크 했습니다" like: - other: "나와 {{count}}명의 다른 사람들이 좋아합니다." + other: "당신 외 {{count}}명이 좋아합니다" vote: - other: "나와 {{count}}명의 다른 사람들이 이 포스트에 투표했습니다." + other: "당신 외 {{count}}명이 이 글에 투표했습니다" by_others: off_topic: - other: "{{count}}명의 사용자가 이 글을 글타래에서 제외했습니다." + other: "{{count}}명이 주제에서 벗어났다고 신고했습니다" spam: - other: "{{count}}명의 사람들이 스팸이라고 신고했습니다" + other: "{{count}}명의 스팸이라고 신고했습니다" inappropriate: - other: "{{count}}명의 사람들이 부적절하다고 신고했습니다" + other: "{{count}}명이 부적절한 컨텐츠라고 신고했습니다" notify_moderators: - other: "{{count}}명의 사람들이 이 글을 운영자에게 신고했습니다" + other: "{{count}}명이 운영자에게 알렸습니다" notify_user: - other: "{{count}}명이 이 사용자에게 메시지를 보냈습니다." + other: "{{count}}명이 글쓴이에게 메시지를 보냈습니다" bookmark: - other: "{{count}}명의 사용자가 이 글을 북마크했습니다." + other: "{{count}}명이 북마크했습니다" like: - other: "{{count}}명이 이 글을 좋아합니다" + other: "{{count}}명이 좋아합니다" vote: - other: "{{count}}명의 사용자가 이 글을 추천했습니다." - edits: - one: 하나 편집 - other: "{{count}}개 편집" - zero: 편집 안함 + other: "{{count}}명이 이 글에 투표했습니다" delete: confirm: other: "모든 글들을 삭제하시겠습니까?" @@ -1254,12 +1399,13 @@ ko: choose: '카테고리를 선택하세요…' edit: '편집' edit_long: "카테고리 편집" - view: '카테고리안의 글타래보기' - general: '일반' + view: '카테고리안의 토픽보기' + general: '장군' settings: '설정' - topic_template: "글타래 템플릿" + topic_template: "토픽 템플릿" delete: '카테고리 삭제' create: '새 카테고리' + create_long: '새 카테고리 만들기' save: '카테고리 저장' slug: '카테고리 Slug' slug_placeholder: '(Optional) dashed-words for url' @@ -1267,10 +1413,10 @@ ko: save_error: 카테고리 저장 중 오류가 발생했습니다. name: "카테고리 이름" description: "설명" - topic: "카테고리 글타래" + topic: "카테고리 토픽" logo: "카테고리 로고 이미지" background_image: "카테고리 백그라운드 이미지" - badge_colors: "뱃지 색상" + badge_colors: "배지 색상" background_color: "배경 색상" foreground_color: "글씨 색상" name_placeholder: "짧고 간결해야합니다" @@ -1283,13 +1429,14 @@ ko: already_used: '이 색은 다른 카테고리에서 사용되고 있습니다.' security: "보안" images: "이미지" - auto_close_label: "글타래 자동 닫기 :" + auto_close_label: "토픽 자동 닫기 :" auto_close_units: "시간" email_in: "incoming 메일 주소 수정" email_in_allow_strangers: "계정이 없는 익명 유저들에게 이메일을 받습니다." - email_in_disabled: "이메일로 새 글타래 작성하기 기능이 비활성화되어 있습니다. 사이트 설정에서 '이메일로 새 글타래작성하기'를 활성화 해주세요." + email_in_disabled: "이메일로 새 토픽 작성하기 기능이 비활성화되어 있습니다. 사이트 설정에서 '이메일로 새 토픽작성하기'를 활성화 해주세요." email_in_disabled_click: '"email in" 활성화' - allow_badges_label: "뱃지가 이 카테고리에서 주어질 수 있도록 허용" + suppress_from_homepage: "홈페이지에서 이 카테고리를 감춥니다." + allow_badges_label: "배지가 이 카테고리에서 주어질 수 있도록 허용" edit_permissions: "권한 수정" add_permission: "권한 추가" this_year: "올해" @@ -1301,46 +1448,42 @@ ko: notifications: watching: title: "주시 중" - description: "이 카테고리 내의 새로운 글타래들을 지켜보도록 자동으로 설정됩니다. 새로운 글이나 글타래에 대하여 알림을 받게되며 글타래 옆에 읽지 않은 글의 수가 표시됩니다." tracking: title: "새 글 표시 중" - description: "이 카테고리 내의 새로운 글타래들을 추적하도록 자동으로 설정됩니다. 글타래 옆에 읽지 않은 글의 수가 표시됩니다." regular: - title: "알림: 일반" + title: "알림 : 일반" description: "누군가 내 @아아디 으로 멘션했거나 당신의 글에 답글이 달릴 때 알림을 받게 됩니다." muted: title: "알림 꺼짐" - description: "이 카테고리의 새로운 글타래에 대한 알림을 받지 않고 읽지 않\x1C은 탭에도 표시하지 않습니다." flagging: - title: '우리 커뮤니티에 기여해 주셔서 감사합니다.' - private_reminder: '신고는 오직 관리자만 볼 수 있습니다.' - action: '글 신고하기' - take_action: "조치를 취하기" - notify_action: '메시지' - delete_spammer: "스팸 사용자 삭제" - delete_confirm: "이 사용자의 %{posts}개의 글과 %{topics}개의 글타래를 삭제하고 IP주소 %{ip_address}와 이메일 %{email}을 영구 블락하려고 합니다. 이 사용자가 악성 사용자임이 확실합니까? " - yes_delete_spammer: "예, 스팸 사용자 삭제." + title: '우리 커뮤니티 질서를 지키는데 도와주셔서 감사합니다!' + action: '글 신고했습니다' + take_action: "조치하기" + notify_action: '메시지 보내기' + delete_spammer: "네, 스패머 회원을 삭제합니다" + delete_confirm: "이 회원의 글 %{posts}개 및 토픽 %{topics}개를 삭제하고 IP주소 %{ip_address}와 이메일 %{email}을 영구 차단하려고 합니다. 이 회원이 정말 스패머 확실합니까?" + yes_delete_spammer: "예, 스팸 회원을 삭제합니다" ip_address_missing: "(알 수 없음)" - hidden_email_address: "(감춰짐)" - submit_tooltip: "신고 접수하기" + hidden_email_address: "(숨김)" + submit_tooltip: "비밀 신고하기" take_action_tooltip: "커뮤니티의 신고 수가 채워지기 기다리지 않고, 바로 신고 수를 제재 수준까지 채웁니다." - cant: "죄송합니다, 지금 이 글을 신고 할 수 없습니다." + cant: "죄송합니다, 지금은 이 글을 신고할 수 없습니다" formatted_name: - off_topic: "오프 글타래입니다." - inappropriate: "부적절함" + off_topic: "주제에 벗어났습니다" + inappropriate: "부적절 컨텐츠입니다" spam: "스팸입니다" custom_placeholder_notify_user: "구체적이고, 건설적이며, 항상 친절하세요." - custom_placeholder_notify_moderators: "구체적으로 사용자님께서 걱정하는 것과 가능한 모든 관련된 링크를 제공해주세요." + custom_placeholder_notify_moderators: "구체적으로 회원님이 걱정하는 내용과 가능한 모든 관련된 링크를 제공해주세요." custom_message: at_least: "최소한 {{n}}자를 입력하세요" more: "{{n}} 이동합니다" left: "{{n}} 나머지" flagging_topic: - title: "우리 커뮤니티에 기여해 주셔서 감사합니다." - action: "신고된 글타래" - notify_action: "메시지" + title: "우리 커뮤니티 질서를 지키는데 도와주셔서 감사합니다!" + action: "토픽 신고하기" + notify_action: "메시지 보내기" topic_map: - title: "글타래 요약" + title: "토픽 요약" participants_title: "빈번한 게시자" links_title: "인기 링크" links_shown: "show all {{totalLinks}} links..." @@ -1350,25 +1493,24 @@ ko: warning: help: "공식적인 주의입니다." bookmarked: - help: "북마크한 글타래" + help: "북마크한 토픽" locked: - help: "이 글타래는 폐쇄되었습니다. 더 이상 새 답글을 받을 수 없습니다." + help: "이 토픽은 폐쇄되었습니다. 더 이상 새 답글을 받을 수 없습니다." archived: - help: "이 글타래는 보관중입니다. 고정되어 변경이 불가능합니다." + help: "이 토픽은 보관중입니다. 고정되어 변경이 불가능합니다." unpinned: title: "핀 제거" - help: "이 글타래는 핀 제거 되었습니다. 목록에서 일반적인 순서대로 표시됩니다." + help: "이 토픽은 핀 제거 되었습니다. 목록에서 일반적인 순서대로 표시됩니다." pinned_globally: title: "핀 지정됨 (전역적)" - help: "이 글타래는 전역적으로 핀 지정 되었습니다. 모든 목록의 최상위에 표시됩니다." pinned: title: "핀 지정됨" - help: "이 글타래는 고정되었습니다. 카테고리의 상단에 표시됩니다." + help: "이 토픽은 고정되었습니다. 카테고리의 상단에 표시됩니다." invisible: - help: "이 글타래는 목록에서 제외됩니다. 글타래 목록에 표시되지 않으며 링크를 통해서만 접근 할 수 있습니다." + help: "이 토픽은 목록에서 제외됩니다. 토픽 목록에 표시되지 않으며 링크를 통해서만 접근 할 수 있습니다." posts: "글" posts_lowercase: "글" - posts_long: "이 글타래의 글 수는 {{number}}개 입니다." + posts_long: "이 토픽의 글 수는 {{number}}개 입니다." posts_likes_MF: | This topic has {count, plural, one {1 reply} other {# replies}} {ratio, select, low {with a high like to post ratio} @@ -1380,7 +1522,7 @@ ko: views_lowercase: other: "조회" replies: "답변" - views_long: "이 글타래는 {{number}}번 읽혔습니다." + views_long: "이 토픽은 {{number}}번 읽혔습니다." activity: "활동" likes: "좋아요" likes_lowercase: @@ -1397,61 +1539,55 @@ ko: not_available: "Raw 이메일이 가능하지 않습니다." categories_list: "카테고리 목록" filters: - with_topics: "%{filter} 글타래" - with_category: "%{filter} %{category} 글타래" + with_topics: "%{filter} 토픽" + with_category: "%{filter} %{category} 토픽" latest: - title: - zero: "최근" - one: "최근 (1)" - other: "최근 ({{count}})" - help: "가장 최근 글타래" + title: "최근글" + title_with_count: + other: "최근글 ({{count}})" + help: "가장 최근 토픽" hot: title: "인기 있는 글" - help: "가장 인기있는 글타래 중 하나를 선택" + help: "가장 인기있는 토픽 중 하나를 선택" read: title: "읽기" - help: "마지막으로 순서대로 읽은 글타래" + help: "마지막으로 순서대로 읽은 토픽" search: title: "검색" - help: "모든 글타래 검색" + help: "모든 토픽 검색" categories: title: "카테고리" title_in: "카테고리 - {{categoryName}}" - help: "카테고리별로 그룹화 된 모든 글타래" + help: "카테고리별로 그룹화 된 모든 토픽" unread: - title: - zero: "읽지 않은" - one: "읽지 않은(1)" - other: "읽지 않은({{count}})" - help: "지켜보거나 추적 중인 읽지 않은 글타래 " + title: "읽지 않은 글" + title_with_count: + other: "읽지 않은 글 ({{count}})" + help: "지켜보거나 추적 중인 읽지 않은 토픽 " lower_title_with_count: - one: "1개의 읽지 않은 글" - other: "{{count}}개의 읽지 않은 글" + other: "{{count}} unread" new: lower_title_with_count: - one: "1 new" other: "{{count}} new" lower_title: "new" - title: - zero: "새로운" - one: "새로운(1)" - other: "새로운({{count}})" - help: "며칠 내에 만들어진 글타래" + title: "새글" + title_with_count: + other: "새글 ({{count}})" + help: "며칠 내에 만들어진 토픽" posted: title: "내 글" help: "내가 게시한 글" bookmarks: title: "북마크" - help: "북마크된 글타래들" + help: "북마크된 토픽" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" + title: "{{categoryName}}" + title_with_count: other: "{{categoryName}} ({{count}})" - help: "{{categoryName}}카테고리의 최신 글타래" + help: "{{categoryName}}카테고리의 최신 토픽" top: - title: "인기" - help: "작년 또는 지난 달, 지난 주, 어제에 활발했던 글타래" + title: "인기글" + help: "작년 또는 지난 달, 지난 주, 어제에 활발했던 토픽" all: title: "전체 시간" yearly: @@ -1527,6 +1663,7 @@ ko: refresh_report: "보고서 새로고침" start_date: "시작일" end_date: "종료일" + groups: "모든 그룹" commits: latest_changes: "최근 변경 사항: 자주 업데이트하십시오!" by: "에 의해" @@ -1535,31 +1672,31 @@ ko: old: "지난" active: "활성화된" agree: "동의" - agree_title: "이 신고가 올바르고 타당한지 확인하세요." + agree_title: "이 신고가 올바르고 타당함을 확인합니다" agree_flag_modal_title: "동의 및 ..." - agree_flag_hide_post: "동의 (포스트 숨기기 + 개인 메시지 보내기)" - agree_flag_hide_post_title: "Hide this post and automatically send the user a message urging them to edit it" - agree_flag_restore_post: "동의하기(글 복원)" + agree_flag_hide_post: "동의 (글 숨기기 + 개인 메시지 보내기)" + agree_flag_hide_post_title: "이 글을 숨기고 글쓴이에게 글을 수정하라고 개인메시지 자동발송하기" + agree_flag_restore_post: "동의 (글 복원)" agree_flag_restore_post_title: "글을 복원하기" agree_flag: "신고에 동의함" agree_flag_title: "신고에 동의하며 글이 수정되지 않도록 유지하기" defer_flag: "연기" - defer_flag_title: "신고 제거하기. 현재 어떠한 행위를 할 필요 없음" + defer_flag_title: "신고 제거하기. 별도추가조치는 더이상 필요없습니다" delete: "삭제" delete_title: "신고에서 멘션된 글 삭제하기" - delete_post_defer_flag: "글을 삭제하고 신고에 결정을 따름" - delete_post_defer_flag_title: "글을 삭제하고 첫번째 글이면 글타래 삭제하기" + delete_post_defer_flag: "글을 삭제하고 신고를 보류함" + delete_post_defer_flag_title: "글을 삭제하고 첫번째 글이면 토픽 삭제하기" delete_post_agree_flag: "글을 삭제하고 신고에 동의함" - delete_post_agree_flag_title: "글을 삭제하고 첫번째 글이면 글타래 삭제하기" + delete_post_agree_flag_title: "글을 삭제하고 첫번째 글이면 토픽 삭제하기" delete_flag_modal_title: "삭제하고.." delete_spammer: "스패머 삭제" - delete_spammer_title: "사용자와 사용자가 작성한 모든 글타래과 글을 삭제함 " - disagree_flag_unhide_post: "Disagree (글 감추기 취소)" + delete_spammer_title: "글쓴이의 모든 글과 토픽을 삭제하고 회원계정도 제거하기" + disagree_flag_unhide_post: "동의안함 (글 숨김 취소)" disagree_flag_unhide_post_title: "글의 모든 신고를 삭제하고 글을 볼 수 있도록 변경" - disagree_flag: "Disagree" + disagree_flag: "동의안함" disagree_flag_title: "신고를 유효하지 않거나 올바르지 않은 것으로 거부함" clear_topic_flags: "완료" - clear_topic_flags_title: "이 글타래를 조사하였고 이슈는 해결되었습니다. 플래그를 지우기 위해 완료를 클리하세요" + clear_topic_flags_title: "토픽 조사를 끝냈고 이슈를 해결했습니다. 신고를 지우기 위해 완료를 클릭하세요" more: "(더 많은 답글...)" dispositions: agreed: "agreed" @@ -1572,8 +1709,8 @@ ko: error: "뭔가 잘못 됐어요" reply_message: "답글" no_results: "신고가 없습니다." - topic_flagged: "이 글타래은 신고 되었습니다." - visit_topic: "처리하기 위해 글타래로 이동" + topic_flagged: "이 토픽 은 신고 되었습니다." + visit_topic: "처리하기 위해 토픽으로 이동" was_edited: "첫 신고 이후에 글이 수정되었음" previous_flags_count: "이 글은 이미 {{count}}번 이상 신고 되었습니다." summary: @@ -1602,15 +1739,23 @@ ko: delete_confirm: "이 그룹을 삭제 하시겠습니까?" delete_failed: "이것은 자동으로 생성된 그룹입니다. 삭제할 수 없습니다." delete_member_confirm: "'%{group}' 그룹에서 '%{username}'을 제외시키겠습니까?" + delete_owner_confirm: "'%{username}' 님에게서 소유자권한을 제거할까요?" name: "이름" add: "추가" add_members: "사용자 추가하기" custom: "Custom" + bulk_complete: "회원들이 그룹에 추가되었습니다." + bulk: "그룹에 한꺼번에 추가하기" + bulk_paste: "한 줄당 하나씩 아이디 또는 이메일 리스트를 붙여넣기 하세요." + bulk_select: "(그룹을 선택하세요)" automatic: "자동화" automatic_membership_email_domains: "이 목록의 있는 항목과 사용자들이 등록한 이메일 도메인이 일치할때 이 그룹에 포함" automatic_membership_retroactive: "이미 등록된 사용자에게 같은 이메일 도메인 규칙 적용하기" default_title: "Default title for all users in this group" primary_group: "Automatically set as primary group" + group_owners: 소유자 + add_owners: 소유자 추가하기 + incoming_email_placeholder: "이메일 주소를 입력하세요" api: generate_master: "마스터 API 키 생성" none: "지금 활성화된 API 키가 없습니다." @@ -1622,7 +1767,7 @@ ko: revoke: "폐지" confirm_regen: "API 키를 새로 발급 받으시겠습니까?" confirm_revoke: "API 키를 폐지하겠습니까?" - info_html: "당신의 API 키는 JSON콜을 이용하여 글타래를 생성하거나 수정할 수 있습니다." + info_html: "당신의 API 키는 JSON콜을 이용하여 토픽을 생성하거나 수정할 수 있습니다." all_users: "전체 유저" note_html: "이 키의 보안에 특별히 주의하세요. 이 키를 아는 모든 사용자는 다른 사용자의 이름으로 글을 작성할 수 있습니다." plugins: @@ -1684,11 +1829,11 @@ ko: is_disabled: "사이트 설정에서 '복구 기능'이 비활성화 되어있습니다." label: "복구" title: "백업을 이용하여 복구" - confirm: "정말 이 백업을 이용하여 복구할까요?" + confirm: "정말 이 백업으로 복원할까요?" rollback: label: "롤백" title: "데이터베이스를 이전 workiong state로 되돌리기" - confirm: "정말로 이전 작업 상태로 데이터베이스를 롤백하시겠습니까?" + confirm: "데이타베이스를 이전 상태로 롤백 또는 되돌리기 할까요?" export_csv: user_archive_confirm: "정말로 내 글을 다운로드 받습니까?" success: "Export initiated, you will be notified via message when the process is complete." @@ -1739,6 +1884,14 @@ ko: color: "색" opacity: "투명도" copy: "복사" + email_templates: + title: "이메일 템플릿" + subject: "제목" + multiple_subjects: "이 이메일 양식은 제목이 여러가지 있습니다." + body: "본문" + none_selected: "편집하려는 이메일 템플릿을 선택하세요." + revert: "변경사항 취소" + revert_confirm: "정말로 변경사항을 되돌리시겠습니까?" css_html: title: "CSS/HTML" long_title: "CSS, HTML 사용자 정의" @@ -1773,7 +1926,7 @@ ko: description: "사이트 헤더에 텍스트와 아이콘" highlight: name: '하이라이트' - description: '페이지 내에 강조된 글 및 글타래 등의 배경색' + description: '페이지 내에 강조된 글 및 토픽 등의 배경색' danger: name: '위험' description: '글 삭제 등에 사용되는 강조색' @@ -1783,18 +1936,18 @@ ko: love: name: '사랑' description: "좋아요 버튼 색" - wiki: - name: '위키' - description: "위키 글의 배경색으로 사용될 기본 색상" email: title: "이메일" settings: "설정" - all: "전체" + templates: "템플릿" + preview_digest: "요약 미리보기" sending_test: "테스트 메일 발송중..." error: "에러 - %{server_error}" test_error: "테스트 메일을 전송하는데 문제가 있습니다. 메일 설정을 다시한번 체크해보고 메일 전송이 정상인지 다시 확인하고 시도해주세요." - sent: "보낸 메일" - skipped: "생략" + sent: "보냄" + skipped: "생략됨" + received: "전송받음" + rejected: "거부됨" sent_at: "보냄" time: "시간" user: "사용자" @@ -1804,7 +1957,6 @@ ko: send_test: "테스트 메일 전송" sent_test: "전송됨!" delivery_method: "전달 방법" - preview_digest: "요약 미리보기" preview_digest_desc: "초대 사용자들에게 보낼 요약 메일 내용 미리보기" refresh: "새로고침" format: "형식" @@ -1813,6 +1965,23 @@ ko: last_seen_user: "마지막으로 본 사용자" reply_key: "답글 단축키" skipped_reason: "생략 이유" + incoming_emails: + from_address: "보내는사람" + to_addresses: "받는사람" + cc_addresses: "참조" + subject: "제목" + error: "에러" + none: "수신된 이메일이 없습니다." + modal: + error: "에러" + subject: "제목" + body: "본문" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "제목..." + error_placeholder: "에러" logs: none: "로그가 없습니다." filters: @@ -1829,8 +1998,9 @@ ko: last_match_at: "마지막 방문" match_count: "방문" ip_address: "IP" - topic_id: "글타래 ID" + topic_id: "토픽 ID" post_id: "글 ID" + category_id: "카테고리 ID" delete: '삭제' edit: '편집' save: '저장' @@ -1855,22 +2025,33 @@ ko: no_previous: "이전 값이 없습니다." deleted: "새로운 값이 없습니다. 기록이 삭제되었습니다." actions: - delete_user: "사용자 삭제" - change_trust_level: "신뢰도 변경" + delete_user: "회원 삭제" + change_trust_level: "회원등급 변경" change_username: "아이디 변경" change_site_setting: "사이트 설정 변경" change_site_customization: "사이트 커스텀화 변경" delete_site_customization: "사이트 커스텀화 삭제" + change_site_text: "site text 변경" suspend_user: "suspend user" unsuspend_user: "unsuspend user" - grant_badge: "뱃지 부여" - revoke_badge: "뱃지 회수" + grant_badge: "배지 부여" + revoke_badge: "배지 회수" check_email: "이메일 확인" - delete_topic: "글타래 삭제" + delete_topic: "토픽 삭제" delete_post: "글 삭제" impersonate: "대역" anonymize_user: "anonymize user" roll_up: "roll up IP blocks" + change_category_settings: "카테고리 설정 변경" + delete_category: "카테고리 지우기" + create_category: "카테고리 만들기" + block_user: "사용자 차단" + unblock_user: "사용자 차단 해제" + grant_admin: "관리자권한 부여" + revoke_admin: "관리자권한 회수" + grant_moderation: "운영자권한 부여" + revoke_moderation: "운영자권한 회수" + backup_operation: "백업 작업" screened_emails: title: "블락된 이메일들" description: "누군가가 새로운 계정을 만들면 아래 이메일 주소는 체크되고 등록은 블락됩니다, 또는 다른 조치가 취해집니다." @@ -1878,12 +2059,12 @@ ko: actions: allow: "허용" screened_urls: - title: "블락된 URL들" + title: "노출된 URL들" description: "이 목록은 사용자에 의해 스팸으로 알려진 URL 목록입니다." url: "URL" domain: "도메인" screened_ips: - title: "블락된 IP들" + title: "노출된 IP들" description: 'IP 주소는 감시됩니다. "허용"으로 Whitelist에 등록해주세요.' delete_confirm: "%{ip_address}를 규칙에 의해 삭제할까요?" roll_up_confirm: "화면에 표시되는 IP 주소를 subnet으로 바꾸시겠습니까?" @@ -1923,27 +2104,27 @@ ko: staff: '스태프' suspended: '접근 금지 사용자' blocked: '블락된 사용자' - suspect: 'Suspect' + suspect: '의심스러운 사용자' approved: "승인?" approved_selected: other: "승인한 사용자 ({{count}}명)" reject_selected: other: "거부한 사용자 ({{count}}명)" titles: - active: '활성화된 사용자' - new: '새로운 사용자' - pending: '검토가 필요한 사용자' - newuser: '사용자 신뢰도 0 (새로운 사용자)' - basic: '사용자 신뢰도 1 (초보 사용자)' - regular: '사용자 신뢰도 2 (회원)' - leader: '사용자 신뢰도 3 (정규)' - elder: '사용자 신뢰도 4 (지도자)' + active: '활동적인 회원' + new: '신규회원' + pending: '검토 대기중인 회원' + newuser: '0등급 회원 (신규가입 회원)' + basic: '1등급 회원 (초보 회원)' + member: '2등급 회원 (부회원)' + regular: '3등급 회원 (정회원)' + leader: '4등급 회원 (리더)' staff: "스태프" - admins: '관리자 사용자 목록' + admins: '관리자' moderators: '운영자' blocked: '블락된 사용자들' suspended: '접근 금지된 사용자들' - suspect: 'Suspect Users' + suspect: '의심스러운 사용자들' reject_successful: other: "성공적으로 ${count}명의 사용자를 거절하였습니다." reject_failures: @@ -1961,13 +2142,14 @@ ko: suspend_reason: "Reason" suspended_by: "접근 금지자" delete_all_posts: "모든 글을 삭제합니다" - delete_all_posts_confirm: "%{posts}개의 글과 %{topics}개의 글타래를 지우려고 합니다. 확실합니까?" + delete_all_posts_confirm: "%{posts}개의 글과 %{topics}개의 토픽을 지우려고 합니다. 확실합니까?" suspend: "접근 금지" unsuspend: "접근 허용" suspended: "접근 금지?" moderator: "운영자?" admin: "관리자?" blocked: "블락" + staged: "격리조치?" show_admin_profile: "관리자" edit_title: "제목 수정" save_title: "제목 저장" @@ -1989,10 +2171,10 @@ ko: activity: 활동 like_count: 준/받은 '좋아요' last_100_days: '지난 100일간' - private_topics_count: 개인적인 글타래 수 + private_topics_count: 비공개 토픽 수 posts_read_count: 글 읽은 수 post_count: 글 수 - topics_entered: 읽은 글타래 수 + topics_entered: 읽은 토픽 수 flags_given_count: 작성한 신고 flags_received_count: 받은 신고 warnings_received_count: 받은 경고 @@ -2008,7 +2190,7 @@ ko: anonymize_failed: "There was a problem anonymizing the account." delete: "사용자 삭제" delete_forbidden_because_staff: "관리자 및 운영자 계정은 삭제할 수 없습니다." - delete_posts_forbidden_because_staff: "Can't delete all posts of admins and moderators." + delete_posts_forbidden_because_staff: "어드민와 운영자들의 포스트는 삭제할 수 없습니다." delete_forbidden: other: "사용자가 작성한 글이 있으면 사용자를 삭제 할 수 없습니다. 사용자를 삭제 하기 전에 사용자가 작성한 글을 모두 삭제해야 합니다. (%{count}일 이전에 작성한 글은 삭제할 수 없습니다.)" cant_delete_all_posts: @@ -2029,42 +2211,45 @@ ko: deactivate_failed: "사용자 비활성에 문제가 있습니다." unblock_failed: '사용자 언블락에 문제가 있습니다.' block_failed: '사용자 블락에 문제가 있습니다.' + block_confirm: '정말로 이 사용자를 차단하겠습니까? 차단된 사용자는 어떠한 토픽이나 포스트도 작성할 수 없습니다.' + block_accept: '네, 이 사용자를 차단합니다.' deactivate_explanation: "비활성화 사용자는 이메일 인증을 다시 받아야합니다." suspended_explanation: "접근 금지된 유저는 로그인 할 수 없습니다." - block_explanation: "블락 사용자는 글을 작성하거나 글타래를 작성할 수 없습니다." - trust_level_change_failed: "신뢰도 변경에 문제가 있습니다." - suspend_modal_title: "Suspend User" - trust_level_2_users: "신뢰도 2 사용자들" - trust_level_3_requirements: "사용자 신뢰도 3 이상이 필요" - trust_level_locked_tip: "신뢰도 시스템이 잠겼습니다. 시스템이 사용자를 승급이나 강등시키지 않을 것 입니다." - trust_level_unlocked_tip: "신뢰도 시스템이 잠금이 해제되었습니다. 시스템은 사용자를 승급이나 강등 시킬 것입니다." - lock_trust_level: "신뢰도 시스템 잠금" - unlock_trust_level: "신뢰도 시스템 잠금 해제" + block_explanation: "블락 사용자는 글을 작성하거나 토픽을 작성할 수 없습니다." + stage_explanation: "격리조치된 회원은 특정 토픽에만 이메일로만 글을 쓸 수 있습니다." + trust_level_change_failed: "회원등급 변경에 실패했습니다." + suspend_modal_title: "거부된 사용자" + trust_level_2_users: "2등급 회원들" + trust_level_3_requirements: "회원등급 3 이상이어야 합니다." + trust_level_locked_tip: "회원등급이 고정되었습니다. 시스템이 회원등급을 올리거나 내리지 않을 것입니다." + trust_level_unlocked_tip: "회원등급 고정이 풀렸습니다. 시스템이 회원등급을 자동적으로 올리거나 내릴 것입니다." + lock_trust_level: "회원등급 고정" + unlock_trust_level: "회원등급 고정 해제" tl3_requirements: - title: "레벨 3 권한이 필요합니다." - table_title: "최근 100일 간:" + title: "3등급 회원이 되기 위한 자격" + table_title: "지난 %{time_period} 일간" value_heading: "값" - requirement_heading: "필수" - visits: "방문수" + requirement_heading: "자격요건" + visits: "방문횟수" days: "일" - topics_replied_to: "답글 달린 글타래" - topics_viewed: "읽은 글타래 수" - topics_viewed_all_time: "읽은 글타래 수 (전체 기간)" - posts_read: "읽은 글 수" - posts_read_all_time: "읽은 글 수 (전체 기간)" - flagged_posts: "신고된 글" - flagged_by_users: "신고한 사용자들" - likes_given: "선사한 '좋아요'" - likes_received: "받은 '좋아요'" - likes_received_days: "받은 '좋아요' : 특정일" - likes_received_users: "받은 좋아요: 순사용자(unique users)" - qualifies: "신뢰 등급 3의 조건에 부합합니다." - does_not_qualify: "신뢰 등급 3의 조건에 부합하지 않습니다." + topics_replied_to: "댓글 달은 토픽 갯수" + topics_viewed: "열어본 토픽 갯수" + topics_viewed_all_time: "열어본 토픽 갯수 (전체 기간)" + posts_read: "읽은 글 갯수" + posts_read_all_time: "읽은 글 갯수 (전체 기간)" + flagged_posts: "신고당한 글 갯수" + flagged_by_users: "신고한 회원수" + likes_given: "'좋아요' 선물한 횟수" + likes_received: "'좋아요' 받은 횟수" + likes_received_days: "한번이라도 '좋아요' 받아본 날짜횟수" + likes_received_users: "한번이라도 '좋아요' 선물해준 회원수" + qualifies: "3등급회원 자격을 만족합니다" + does_not_qualify: "3등급회원 자격을 만족하지 않습니다" will_be_promoted: "곧 승급 됩니다." will_be_demoted: "곧 강등됩니다." on_grace_period: "현재 승급 유예 기간이므로 강등되지 않습니다." - locked_will_not_be_promoted: "신뢰도 시스템이 잠겼습니다. 승급되지 않습니다." - locked_will_not_be_demoted: "신뢰도 시스템이 잠겼습니다. 강등되지 않습니다." + locked_will_not_be_promoted: "회원등급이 고정되었습니다. 승급되지 않을 것입니다." + locked_will_not_be_demoted: "회원등급이 고정되었습니다. 강등되지 않을 것입니다." sso: title: "Single Sign On" external_id: "External ID" @@ -2103,8 +2288,15 @@ ko: confirm: '확인' dropdown: "드롭다운" site_text: - none: "편집할 콘텐츠 유형을 선택하세요." + description: "포럼에 있는 그 어떤 텍스트도 수정이 가능합니다. 아래의 검색기능을 통해 시작하세요." + search: "편집하고 싶은 텍스트를 검색하세요." title: '텍스트 콘텐츠' + edit: '편집' + revert: "변경사항 취소" + revert_confirm: "정말로 변경사항을 되돌리시겠습니까?" + go_back: "검색으로 돌아가기" + recommended: "다음의 텍스트를 요구에 맞게 편집하는 것을 권장:" + show_overriden: 'Override 된 설정만 보여주기' site_settings: show_overriden: '수정된 것만 표시' title: '사이트 설정' @@ -2115,87 +2307,86 @@ ko: add_url: "URL 추가" add_host: "Host 추가" categories: - all_results: 'All' + all_results: '전체' required: '필수' basic: '기본 설정' - users: '사용자' + users: '회원' posting: '글' email: '이메일' files: '파일' - trust: '신뢰도' + trust: '회원등급' security: '보안' onebox: "Onebox" - seo: 'SEO' + seo: '검색엔진최적화(SEO)' spam: '스팸' rate_limits: '제한' developer: '개발자' embedding: "Embedding" - legal: "합법적인" + legal: "법률조항" uncategorized: '카테고리 없음' backups: "백업" login: "로그인" plugins: "플러그인" - user_preferences: "사용자 환경 설정" + user_preferences: "회원 환경설정" badges: - title: 뱃지 - new_badge: 새로운 뱃지 + title: 배지 + new_badge: 새 배지 new: New name: 이름 - badge: 뱃지 + badge: 배지 display_name: 표시 이름 description: 설명 - badge_type: 뱃지 종류 + badge_type: 배지 종류 badge_grouping: 그룹 badge_groupings: - modal_title: 뱃지 그룹으로 나누기 + modal_title: 배지 그룹으로 나누기 granted_by: 배지 부여자 granted_at: 배지 수여일 - reason_help: ( 글타래가나 글 링크) + reason_help: (토픽 또는 댓글로 가는 링크) save: 저장 delete: 삭제 - delete_confirm: 정말로 이 뱃지를 삭제하시겠습니까? + delete_confirm: 정말로 이 배지를 삭제할까요? revoke: 회수 - reason: 원인 + reason: 이유 expand: 확장 … - revoke_confirm: 정말로 이 뱃지를 회수하시겠습니까? - edit_badges: 뱃지 수정 - grant_badge: 뱃지 부여 - granted_badges: 부여된 뱃지 + revoke_confirm: 정말로 이 배지를 회수할까요? + edit_badges: 배지 수정 + grant_badge: 배지 부여 + granted_badges: 부여된 배지 grant: 부여 - no_user_badges: "%{name}님은 수여받은 뱃지가 없습니다." - no_badges: 받을 수 있는 뱃지가 없습니다. - none_selected: "시작하려면 뱃지를 선택하세요" - allow_title: 뱃지를 칭호로 사용 가능하도록 허용 + no_user_badges: "%{name}님은 배지가 없습니다." + no_badges: 받을 수 있는 배지가 없습니다. + none_selected: "시작하려면 배지를 선택하세요" + allow_title: 배지를 칭호로 사용 가능하도록 허용 multiple_grant: 중복 부여할 수 있도록 허용 - listable: 공개 뱃지 페이지에 표시되는 뱃지입니다. - enabled: 뱃지 기능 사용 + listable: 공개 배지 페이지에 표시되는 배지입니다. + enabled: 배지 기능 사용 icon: 아이콘 image: 이미지 - icon_help: "Font Awesome class나 이미지 주소를 사용합니다" - query: 뱃지 Query(SQL) - target_posts: 포스트들을 타겟으로 하는 query - auto_revoke: 매일 회수 query를 실행한다. - show_posts: 뱃지 페이지에서 뱃지를 받게한 글을 보여줍니다. + icon_help: "이미지 주소로 Font Awesome 클래스 또는 URL을 사용합니다" + query: 배지 쿼리(SQL) + target_posts: 글들을 대상으로 하는 쿼리 + auto_revoke: 회수 쿼리를 매일 실행 + show_posts: 배지 페이지에서 배지를 받게한 글을 보여줍니다. trigger: Trigger trigger_type: none: "매일 업데이트" - post_action: "사용자가 포스트에 액션을 했을 때" - post_revision: "사용자가 포스트를 수정거나 작성했을 때" - trust_level_change: "사용자의 신뢰도가 변했을 떄" - user_change: "사용자가 수정되거나 생성되었을 때" + post_action: "회원이 글에 액션을 할 때" + post_revision: "회원이 새글을 쓰거나 글을 수정할 때" + trust_level_change: "회원등급이 바뀔 때" + user_change: "회원이 생성되거나 수정될 때" preview: - link_text: "수여된 뱃지 미리보기" - plan_text: "Query plan 미리보기" - modal_title: "뱃지 Query 미리보기" - sql_error_header: "Query에 오류가 있습니다." - error_help: "뱃지 query의 도움말을 보려면 다음의 링크를 확인하세요." + link_text: "수여된 배지 미리보기" + plan_text: "쿼리 플랜 미리보기" + modal_title: "배지 쿼리 미리보기" + sql_error_header: "질의 중 오류가 발생했습니다" + error_help: "배지 쿼리 도움말을 보려면 다음 링크를 확인하세요." bad_count_warning: header: "주의!" - text: "사라진 뱃지 샘플이 있습니다. 뱃지 query가 존재하지 않는 user ID나 post ID를 반환할 경우 발생합니다. 예상하지 못한 결과를 일으킬 수 있으니 query를 다시 한번 확인하세요." + text: "사라진 배지 샘플이 있습니다. 배지 query가 존재하지 않는 user ID나 post ID를 반환할 경우 발생합니다. 예상하지 못한 결과를 일으킬 수 있으니 query를 다시 한번 확인하세요." + no_grant_count: "할당된 배지가 없습니다." grant_count: - zero: "할당된 뱃지가 없습니다." - one: "1개의 뱃지가 할당됨." - other: "%{count}개의 뱃지가 할당됨." + other: "%{count}개의 배지가 할당됨." sample: "샘플:" grant: with: %{username} @@ -2203,28 +2394,40 @@ ko: with_post_time: %{username} for post in %{link} at %{time} with_time: %{username} at %{time} emoji: - title: "Emoji" - help: "모든 사용자가 사용가능한 새로운 이미지를 추가. (프로 팁: 여러개의 파일을 드래그 & 드롭으로 한번에)" - add: "새로운 Emoji 추가" + title: "이모지" + help: "모든 사람이 쓸 수 있는 이모지를 추가합니다. (팁: 여러개 파일을 한 번에 드래그 & 드롭할 수 있어요)" + add: "새 이모지 추가" name: "이름" image: "이미지" - delete_confirm: "정말 :%{name}: emoji를 삭제하시겠습니까?" + delete_confirm: "정말로 :%{name}: 이모지를 삭제할까요?" embedding: get_started: "다른 웹사이트에 Discourse를 임베드하려면 호스트 추가부터 하세요" confirm_delete: "정말로 host를 삭제할까요?" - title: "Embedding" + sample: "Discourse 토픽을 웨사이트에 삽입(embed)하기 위해 다음 HTML코드를 이용하세요. REPLACE_ME 부분을 당신이 삽입하려는 웨사이트의 정식URL로 바꿔치기 하시면 됩니다." + title: "삽입(Embedding)" host: "허용 Host" edit: "편집" category: "카테고리에 게시" add_host: "Host 추가" - settings: "Embedding 설정" - feed_settings: "Feed 설정" - crawling_settings: "클롤러 설정" + settings: "삽입(Embedding) 설정" + feed_settings: "피드 설정" + feed_description: "당신 사이트의 RSS/ATOM 피드를 알려주시면 Discourse가 그 사이트 컨텐트를 더 잘 가져올 수 있습니다." + crawling_settings: "크롤러 설정" + crawling_description: "When Discourse creates topics for your posts, if no RSS/ATOM feed is present it will attempt to parse your content out of your HTML. Sometimes it can be challenging to extract your content, so we provide the ability to specify CSS rules to make extraction easier." + embed_by_username: "토픽 생성 시 사용할 회원이름(Username)" + embed_post_limit: "삽입(embed)할 글 최대갯수" + embed_username_key_from_feed: "피드에서 discourse usename을 꺼내오기 위한 키(key)" + embed_truncate: "임베드된 글 뒷부분 잘라내기" + embed_whitelist_selector: "CSS selector for elements that are allowed in embeds" + embed_blacklist_selector: "CSS selector for elements that are removed from embeds" + feed_polling_enabled: "RSS/ATOM으로 글 가져오기" + feed_polling_url: "긁어올 RSS/ATOM 피드 URL" + save: "삽입(Embedding) 설정 저장하기" permalink: title: "고유링크" url: "URL" - topic_id: "글타래 ID" - topic_title: "글타래" + topic_id: "토픽 ID" + topic_title: "토픽" post_id: "글 ID" post_title: "글" category_id: "카테고리 ID" @@ -2248,34 +2451,37 @@ ko: new: 'g, n 새로운' unread: 'g, u 읽지 않은' categories: 'g, c 카테고리' - top: 'g, t 인기' + top: 'g, t 인기글' bookmarks: 'g, b 북마크' + profile: 'g, p 프로필' + messages: 'g, m 메시지' navigation: title: 'Navigation' jump: '# 글 번호로' back: 'u Back' up_down: 'k/j 선택된 글 이동 ↑ ↓' - open: 'o or Enter 선택한 글타래에 들어갑니다.' + open: 'o or Enter 선택한 토픽에 들어갑니다.' next_prev: 'shift+j/shift+k 이전/다음 섹션' application: title: 'Application' - create: 'c 새 글타래를 만듭니다.' + create: 'c 새 토픽을 만듭니다.' notifications: 'n Open notifications' hamburger_menu: '= 햄버거 메뉴 열기' user_profile_menu: 'p 사용자 메뉴 열기' - show_incoming_updated_topics: '. 갱신된 글타래 보기' + show_incoming_updated_topics: '. 갱신된 토픽 보기' search: '/ Search' help: '? 키보드 도움말 열기' dismiss_new_posts: 'x, r 새글을 읽은 상태로 표시하기' - dismiss_topics: 'x, t 글타래 무시하기' + dismiss_topics: 'x, t 토픽 무시하기' + log_out: 'shift+z shift+z 로그아웃' actions: title: 'Actions' - bookmark_topic: 'f 토글 북마크 글타래' + bookmark_topic: 'f 토글 북마크 토픽' pin_unpin_topic: 'shift+p 핀고정/핀해제' - share_topic: 'shift+s 글타래 공유' + share_topic: 'shift+s 토픽 공유' share_post: 's 글 공유' - reply_as_new_topic: 't 링크된 글타래로 답글 작성하기' - reply_topic: 'shift+r 글타래에 답글 달기' + reply_as_new_topic: 't 연결된 토픽으로 답글 작성하기' + reply_topic: 'shift+r 토픽에 답글 달기' reply_post: 'r 글에 답글 달기' quote_post: 'q 인용 글' like: 'l Like post' @@ -2283,21 +2489,21 @@ ko: bookmark: 'b Bookmark post' edit: 'e Edit post' delete: 'd Delete post' - mark_muted: 'm, m 글타래 알람 : 끄기' - mark_regular: 'm, r 글타래 알람 : 일반(기본)으로 설정하기' - mark_tracking: 'm, t 글타래 알람 : 추적하기' - mark_watching: 'm, w 글타래 알람 : 주시하기' + mark_muted: 'm, m 토픽 알람 : 끄기' + mark_regular: 'm, r 토픽 알람 : 일반(기본)으로 설정하기' + mark_tracking: 'm, t 토픽 알람 : 추적하기' + mark_watching: 'm, w 토픽 알람 : 주시하기' badges: - title: 뱃지 - allow_title: "can be used as a title" - multiple_grant: "can be awarded multiple times" + earned_n_times: + other: "이 배지를 %{count}번 받았습니다" + title: 배지 badge_count: - other: "뱃지 %{count}개" + other: "배지 %{count}개" more_badges: other: "+%{count} More" granted: other: "%{count} 개 부여" - select_badge_for_title: 칭호로 사용할 뱃지를 선택하세요 + select_badge_for_title: 칭호로 사용할 배지를 선택하세요 none: "<없음>" badge_grouping: getting_started: @@ -2305,102 +2511,11 @@ ko: community: name: 커뮤니티 trust_level: - name: 신뢰 등급 + name: 회원등급 other: name: 기타 posting: name: 글 관련 배지 - badge: - editor: - name: 편집자 - description: 첫 포스트 편집 - basic_user: - name: 기본 - description: 부여되면 커뮤니티의 기본 기능 수행 가능 - member: - name: 멤버 - description: Granted invitations - regular: - name: 일반 - description: Granted recategorize, rename, followed links and lounge - leader: - name: 중견 - description: Granted global edit, pin, close, archive, split and merge - welcome: - name: 환영합니다 - description: 좋아요 받음 - autobiographer: - name: 자서전 작가 - description: 사용자의 프로필 정보를 작성함 - anniversary: - name: 기념일 - description: Active member for a year, posted at least once - nice_post: - name: 괜찮은 글 - description: 작성한 글이 좋아요를 10개 받았습니다. 이 뱃지는 중복 수여 가능합니다. - good_post: - name: 좋은 글 - description: 작성한 글이 좋아요를 25개 받았습니다. 이 뱃지는 중복 수여 가능합니다. - great_post: - name: 굉장히 좋은 글 - description: 작성한 글이 좋아요를 50개 받았습니다. 이 뱃지는 중복 수여 가능합니다. - nice_topic: - name: Nice 글타래 - description: 10개의 '좋아요'를 받았습니다. 이 뱃지는 여러번 받을 수 있습니다. - good_topic: - name: Good 글타래 - description: 25개의 '좋아요'를 받았습니다. 이 뱃지는 여러번 받을 수 있습니다. - great_topic: - name: Great 글타래 - description: 50개의 '좋아요'를 받았습니다. 이 뱃지는 여러번 받을 수 있습니다. - nice_share: - name: Nice 공유 - description: 25명의 사용자로부터 공유되었습니다 - good_share: - name: Good 공유 - description: 300명의 사용자로부터 공유되었습니다 - great_share: - name: Great 공유 - description: 1000명의 사용자로부터 공유되었습니다 - first_like: - name: 첫 좋아요 - description: 처음으로 글에 '좋아요'를 했습니다. - first_flag: - name: 첫 신고 - description: 글을 처음으로 신고하였습니다. - promoter: - name: Promoter - description: 사용자 초대 - campaigner: - name: Campaigner - description: 기본 사용자 3명 초대하기 (신뢰도 1) - champion: - name: Champion - description: 기본 사용자 5명 초대하기 (신뢰도 2) - first_share: - name: 첫 공유 - description: 처음으로 글을 공유했습니다. - first_link: - name: 첫 링크 - description: 글 작성시, 다른 글타래로 가는 링크를 처음으로 추가하였습니다. - first_quote: - name: 첫 인용 - description: 글 작성시 다른 사용자의 글을 인용하였습니다. - read_guidelines: - name: 가이드라인 읽음 - description: 커뮤니티 가이드라인 을 읽었습니다. - reader: - name: 독서가 - description: 100개가 넘는 댓글이 달린 글타래의 댓글을 모두 읽었습니다. - popular_link: - name: 인기 링크 - description: 50회 이상 클릭이 발생한 외부 링크 게시 - hot_link: - name: HOT 링크 - description: 300회 이상 클릭이 발생한 외부 링크 게시 - famous_link: - name: Famous 링크 - description: 1000회 이상 클릭이 발생한 외부 링크 게시 google_search: |

    Google 검색

    diff --git a/config/locales/client.nb_NO.yml b/config/locales/client.nb_NO.yml index bc95f1c0eb2..d14a7cec02c 100644 --- a/config/locales/client.nb_NO.yml +++ b/config/locales/client.nb_NO.yml @@ -138,6 +138,7 @@ nb_NO: admin_title: "Admin" flags_title: "Rapporteringer" show_more: "vis mer" + show_help: "alternativer" links: "Lenker" links_lowercase: one: "link" @@ -214,6 +215,7 @@ nb_NO: saved: "Lagret!" upload: "Last opp" uploading: "Laster opp..." + uploading_filename: "Laster opp {{filename}}..." uploaded: "Lastet opp!" enable: "Aktiver" disable: "Deaktiver" @@ -243,7 +245,6 @@ nb_NO: one: "Dette emnet har 1 innlegg som venter på godkjenning" other: "Dette emnet har {{count}} innlegg som venter på godkjenning" confirm: "Lagre endringer" - delete_prompt: "Er du sikker du ønsker å slette %{username}? Dette vil fjerne alle brukerens innnlegg og blokkere epost og ip-addressen." approval: title: "Innlegg Behøver Godkjenning" description: "Vi har mottatt ditt nye innlegg men det krever godkjenning av en moderator før det vises. Venligst vær tålmodig." @@ -286,6 +287,13 @@ nb_NO: one: "1 bruker" other: "%{count} brukere" groups: + empty: + posts: "Det er ingen innlegg av medlemmene i denne gruppen." + members: "Det er ingen medlemmer i denne gruppen." + messages: "Det er ingen meldinger for denne gruppen." + add: "Legg til" + selector_placeholder: "Legg til medlemmer" + owner: "eier" visible: "Gruppen er synlig for alle brukere" title: one: "gruppe" @@ -293,12 +301,20 @@ nb_NO: members: "Medlemmer" posts: "Innlegg" alias_levels: - title: "Hvem kan benytte denne gruppen som alias?" nobody: "Ingen" only_admins: "Kun administratorer" mods_and_admins: "Kun moderatorer og administratorer" members_mods_and_admins: "Kun gruppemedlemmer, moderatorer og administratorer" everyone: "Alle" + trust_levels: + none: "ingen" + notifications: + watching: + title: "Følger" + tracking: + title: "Sporer" + regular: + title: "Normal" user_action_groups: '1': "Liker tildelt" '2': "Liker mottatt" @@ -308,7 +324,6 @@ nb_NO: '6': "Svar" '7': "Omtalelser" '9': "Sitater" - '10': "Favoritter" '11': "Redigeringer" '12': "Sendte elementer" '13': "Innboks" @@ -365,13 +380,12 @@ nb_NO: invited_by: "Invitert av" trust_level: "Tillitsnivå" notifications: "Varsler" + statistics: "Statistikk" desktop_notifications: perm_default: "Slå på varslinger" perm_denied_btn: "Tillatelse avslått" disable: "Slå av varslinger" - currently_enabled: "(slått på)" enable: "Slå på varslinger" - currently_disabled: "(slått av)" each_browser_note: "Merk: Du må endre denne innstillinger for hver nettleser du bruker." dismiss_notifications: "Merk alle som lest" dismiss_notifications_tooltip: "Merk alle uleste varslinger som lest" @@ -395,7 +409,6 @@ nb_NO: tracked_categories: "Sporet" tracked_categories_instructions: "Du vil automatisk spore alle nye emner i disse kategoriene. Antallet uleste og nye innlegg vil vises ved emnets oppføring." muted_categories: "Dempet" - muted_categories_instructions: "Du vil ikke bli varslet om nye emner i disse kategoriene og de vil ikke vises i listen over ulest innhold." delete_account: "Slett kontoen min" delete_account_confirm: "Er du sikker på at du vil slette kontoen din permanent? Denne handlingen kan ikke angres!" deleted_yourself: "Slettingen av din konto har vært vellykket." @@ -413,8 +426,10 @@ nb_NO: warnings_received: "advarsler" messages: all: "Alle" - mine: "Mine" - unread: "Uleste" + inbox: "Innboks" + sent: "Sendt" + groups: "Mine grupper" + select_all: "Velg Alle" change_password: success: "(e-post sendt)" in_progress: "(sender e-post)" @@ -458,10 +473,6 @@ nb_NO: ok: "Vi sender deg en e-post for å bekrefte" invalid: "Vennligst oppgi en gyldig e-postadresse" authenticated: "Din e-post har blitt autentisert av {{provider}}" - frequency: - zero: "Vi sender deg straks en e-post hvis du ikke har lest saken vi sendte deg en e-post om." - one: "Du får bare e-post hvis du ikke er blitt sett det siste minuttet." - other: "Du får bare e-post hvis du ikke har blitt sett de siste {{count}} minuttene." name: title: "Navn" instructions: "Ditt fulle navn (valgfritt)" @@ -520,7 +531,7 @@ nb_NO: search: "skriv for å søke etter invitasjoner..." title: "invitasjoner" user: "Invitert bruker" - truncated: "Viser de første {{count}} invitasjoner." + sent: "Sendt" redeemed: "Løs inn invitasjoner" redeemed_tab: "Brukt" redeemed_at: "Løst inn ved" @@ -551,6 +562,12 @@ nb_NO: same_as_email: "Ditt passord er det samme som din e-post." ok: "Passordet ditt ser bra ut" instructions: "Minst %{count} tegn." + summary: + title: "Oppsummering" + stats: "Statistikk" + top_replies: "Mest Populære Svar" + top_topics: "Mest Populære Emner" + more_topics: "Flere Emner" associated_accounts: "Innloggingsforsøk" ip_address: title: "Siste IP-adresse" @@ -576,11 +593,13 @@ nb_NO: server: "Serverfeil" forbidden: "Tilgang avslått" unknown: "Feil" + not_found: "Side Ikke funnet" desc: network: "Vennligst sjekk nettverkstilkoblingen din" network_fixed: "Ser ut som om den er tilbake." server: "Feilkode: {{status}}" forbidden: "Du har ikke tilgang til dette." + not_found: "Oops, applikasjonen forsøkte å laste en URL som ikke eksisterer." unknown: "Noe gikk galt." buttons: back: "Gå tilbake" @@ -591,7 +610,6 @@ nb_NO: logout: "Du ble logget ut" refresh: "Refresh" read_only_mode: - enabled: "Skrivebeskyttet modus er aktivert. Du kan fortsette å benytte siden med enkelte funksjoner vil muligens ikke fungere." login_disabled: "Innlogging er deaktivert mens nettsiden er i skrivebeskyttet modus." learn_more: "lær mer..." year: 'år' @@ -609,10 +627,15 @@ nb_NO: replies_lowercase: one: svar other: svar + signup_cta: + sign_up: "Registrer deg" + hide_session: "Spør meg igjen i morgen" + hide_forever: "nei takk" + hidden_for_session: "OK, jeg spør igjen i morgen. Du kan også registrere en konto når du vil!" + intro: "Hei du! :heart_eyes: Det ser ut som du følger diskusjonen, men ikke har registrert deg enda." + value_prop: "Når du registrerer deg husker vi hvor langt du har lest, så du starter på riktig sted neste gang du åpner en tråd. Du får også varsler, her og på e-post når det skjer ting i diskusjonene du vil følge. I tillegg kan du like innlegg :heartbeat:" summary: enabled_description: "Du ser for øyeblikket en oppsummering av dette emnet: de mest interessante innleggene i følge nettsamfunnet." - description: "Det er {{count}} svar." - description_time: "Det er {{count}} svar med en estimert lesetid på {{readingTime}} minutter." enable: 'Oppsummer dette emnet' disable: 'Vis alle innlegg' deleted_filter: @@ -666,6 +689,9 @@ nb_NO: admin_not_allowed_from_ip_address: "Du kan ikke logge inn som administrator fra den IP-adressen." resend_activation_email: "Klikk her for å sende e-posten for aktivering igjen." sent_activation_email_again: "Vi sendte deg en ny e-post for aktivering på {{currentEmail}}. Det kan ta noen minutter før den kommer fram; sørg for at du sjekker nettsøppel om du ikke finner den." + to_continue: "Vennligst Logg Inn" + preferences: "Du må være innlogget for å endre brukerinnstillinger." + forgot: "I husker ikke mine kontodetaljer" google: title: "med Google" message: "Autentiserer med Google (sørg for at du tillater pop-up vindu)" @@ -688,8 +714,15 @@ nb_NO: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "mer..." + options: "Alternativer" + whisper: "hvisker" add_warning: "Dette er en offisiell advarsel." posting_not_on_topic: "Du svarer på emnet \"{{title}}\", men for øyeblikket ser du på et annet emne." saving_draft_tip: "lagrer..." @@ -718,7 +751,7 @@ nb_NO: edit_reason_placeholder: "hvorfor endrer du?" show_edit_reason: "(legg till endringsbegrunnelse)" view_new_post: "Se ditt nye innlegg." - saving: "Lagrer..." + saving: "Lagrer" saved: "Lagret!" saved_draft: "Innleggsutkast. Velg for å fortsette." uploading: "Laster opp..." @@ -745,10 +778,10 @@ nb_NO: heading_title: "Overskrift" heading_text: "Overskrift" hr_title: "Horisontalt Skille" - undo_title: "Angre" - redo_title: "Gjenta" help: "Hjelp for redigering i Markdown" toggler: "gjem eller vis redigeringspanelet" + modal_ok: "OK" + modal_cancel: "Avbryt" admin_options_title: "Valgfrie emne-instillinger for ansatte" auto_close: label: "Tid for auto-lukking av emnet:" @@ -767,7 +800,6 @@ nb_NO: mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -777,6 +809,15 @@ nb_NO: moved_post: "

    {{username}} moved {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Ble tildelt '{{description}}'

    " + alt: + mentioned: "Nevnt av" + quoted: "Sitert av" + replied: "Svart" + posted: "Innlegg av" + liked: "Likte innlegget ditt" + private_message: "Privat melding fra" + linked: "Link til innlegget ditt" + granted_badge: "Merke innvilget" popup: mentioned: '{{username}} nevnte deg i "{{topic}}" - {{site_title}}' quoted: '{{username}} siterte deg i "{{topic}}" - {{site_title}}' @@ -790,14 +831,19 @@ nb_NO: from_my_computer: "Fra Min Enhet" from_the_web: "Fra nettet" remote_tip: "link til bilde" - remote_tip_with_attachments: "link til bilde eller fil ({{authorized_extensions}})" local_tip: "velg bilder fra din enhet" - local_tip_with_attachments: "velg bilder eller filer fra din enhet ({{authorized_extensions}})" hint: "(du kan også drag & drop inn i editoren for å laste dem opp)" uploading: "Laster opp bilde" select_file: "Velg Fil" image_link: "lenken som bildet skal peke til" search: + sort_by: "Sorter etter" + relevance: "Relevanse" + latest_post: "Nyeste Innlegg" + most_viewed: "Mest Lest" + most_liked: "Mest Likt" + select_all: "Velg Alle" + clear_all: "Fjern Alle" title: "søk etter emner, innlegg, brukere eller kategorier" no_results: "Ingen resultater funnet." no_more_results: "Ingen flere resultater funnet." @@ -809,6 +855,8 @@ nb_NO: category: "Søk i kategorien \"{{category}}\"" topic: "Søk i dette emnet" private_messages: "Søk i meldinger" + hamburger_menu: "gå til en annen emneliste eller kategori" + new_item: "ny" go_back: 'gå tilbake' not_logged_in_user: 'brukerside med oppsummering av nylig aktivtet og preferanser.' current_user: 'go til din brukerside' @@ -816,10 +864,6 @@ nb_NO: bulk: reset_read: "Nullstill lest" delete: "Slett Emne" - dismiss_posts: "Avvis innlegg" - dismiss_posts_tooltip: "Tøm antallet uleste innlegg i disse emnene men fortsett å vis dem i min liste over uleste innlegg når nye innlegg blir lagt inn" - dismiss_topics: "Avvis innlegg" - dismiss_topics_tooltip: "Ikke vis disse emnene i min ulest-liste når nye innlegg i disse forekommer" dismiss_new: "Lest" toggle: "Veksle mellom massevelging av emner" actions: "Massehandlinger" @@ -842,9 +886,6 @@ nb_NO: category: "Det er ingen {{category}} emner." top: "Det er ingen populære emner." search: "Det er ingen søkeresultater" - educate: - new: '

    Dine nye emner vises her.

    Som standard anses emner som nye, og vil ha indikatoren ny hvis emnet ble opprettet de siste 2 dagene

    Du kan endre dette i dine innstillinger.

    ' - unread: '

    Dine uleste emner vises her.

    Som standard anses emner som uleste, og vil vise antall uleste 1 dersom du:

    • Opprettet emnet
    • Svarte på emnet
    • Leste emnet i mer enn 4 minutter

    Eller dersom du eksplisitt har satt emnet som Sporet eller Fulgt via varslingskontrollene under hvert emne.

    Du kan endre dette i dine innstillinger.

    ' bottom: latest: "Det er ikke noen siste emner igjen å lese." hot: "Det er ikke noen populære emner igjen å lese." @@ -960,7 +1001,6 @@ nb_NO: description: "Du vil ikke få varslinger om noe i denne meldingnen. " muted: title: "Dempet" - description: "du vil ikke bli varslet om noen ting i dette emnet, og det vil ikke visest som ulest." actions: recover: "Gjenopprett emne" delete: "slett emne" @@ -999,23 +1039,12 @@ nb_NO: confirm_pin: "Du har allerede {{count}} låste emner. For mange låste emner kan være et problem for nye og anonyme brukere. Er du sikker på at du ønsker å låse et til emne i denne kategorien?" unpin: "Fjern dette emnet fra toppen av {{categoryLink}} kategorien." pin_note: "Brukere kan låse opp emnet selv." - already_pinned: - zero: "Det er ingen låste emner i {{categoryLink}}." - one: "Emner for øyeblikket låst i {{categoryLink}}: 1." - other: "Emner for øyeblikket låst i {{categoryLink}}: {{count}}." confirm_pin_globally: "Du har allerede {{count}} globalt låste emner. For mange låste emner kan bli en byrde for nye og anonyme brukere. Er du sikker på at du vil låse et til emne globalt? " unpin_globally: "Fjern dette emnet fra toppen av alle emnelister. " global_pin_note: "Brukere kan låse opp emner for dem selv. " - already_pinned_globally: - zero: "Det er ingen låste emner globalt." - one: "Emner for øyeblikket låst globalt: 1." - other: "Dette enmnet er låst globalt: {{count}}." make_banner: "Gjør dette emnet til et banner som dukker opp på toppen av alle sider." remove_banner: "Fjern banneret som dukker opp på toppen av alle sider. " banner_note: "Brukere kan fjerne banneret ved å lukke det. Kun et emne kan være banner på en og samme tid. " - already_banner: - zero: "Det er ingen banneremner. " - one: "Det er for øyeblikket et banneremne. " inviting: "Inviterer..." automatically_add_to_groups_optional: "Denne invitasjonen inkluderer også tilgang på disse gruppene: (valgfritt, kun for admin)" automatically_add_to_groups_required: "Denne invitasjonen inkluderer også tilgang til disse gruppene: (påkrevet, kun for admin)" @@ -1113,8 +1142,8 @@ nb_NO: has_likes_title: one: "{{count}} bruker likte dette innlegget" other: "{{count}} brukere likte dette innlegget" + has_likes_title_only_you: "du likte dette innlegget" has_likes_title_you: - zero: "du likte dette innlegget" one: "du og 1 annen bruker likte dette innlegget" other: "du og {{count}} andre likte dette innlegget" errors: @@ -1134,8 +1163,6 @@ nb_NO: no_value: "Nei" yes_value: "Ja" via_email: "Dette innlegget ankom via e-post" - wiki: - about: "Dette innlegget er en wiki; brukere kan redigere den" archetypes: save: 'Lagre Alternativene' controls: @@ -1183,18 +1210,6 @@ nb_NO: bookmark: "Angre bokmerke" like: "Angre liker" vote: "Angre stemme" - people: - off_topic: "{{icons}} rapporterte dette som irrelevant" - spam: "{{icons}} rapporterte dette som spam" - spam_with_url: "{{icons}} merket dette som spam" - inappropriate: "{{icons}} rapporterte dette som upassende" - notify_moderators: "{{icons}} varslet moderatorene" - notify_moderators_with_url: "{{icons}} varslet moderatorene" - notify_user: "{{icons}} sendte en melding" - notify_user_with_url: "{{icons}} sente en melding" - bookmark: "{{icons}} bokmerket dette" - like: "{{icons}} likte dette" - vote: "{{icons}} stemte for dette" by_you: off_topic: "Du rapporterte dette som irrelevant" spam: "Du rapporterte dette som spam" @@ -1254,10 +1269,6 @@ nb_NO: vote: one: "1 bruker stemte på dette innlegget" other: "{{count}} brukere stemte på dette innlegget" - edits: - one: 1 redigering - other: "{{count}} redigeringer" - zero: ingen redigeringer delete: confirm: one: "Er du sikker på at du vil slette det innlegget?" @@ -1294,6 +1305,7 @@ nb_NO: topic_template: "Emnemal" delete: 'Slett kategori' create: 'Ny Kategori' + create_long: 'Opprett en ny kategori' save: 'Lagre Kategori' slug: 'Kategorinavn i URL' slug_placeholder: '(valgfritt) sammensatte ord for bruk i URL' @@ -1335,19 +1347,15 @@ nb_NO: notifications: watching: title: "Følger" - description: "Du vil automatisk følge alle nye emner i disse kategoriene. Du vil bli varslet om alle nye innlegg og emner. Antallet uleste og nye emner vil også vises." tracking: title: "Sporing" - description: "Du vil automatisk spore alle nye emner i disse kategoriene. Antallet nye svar vises for disse." regular: - title: "Vanlig" + title: "Normal" description: "Du vil bli varslet om noen nevner ditt @navn eller svarer deg." muted: title: "Dempet" - description: "Du vil ikke bli varslet om noe vedrørende disse emnene i disse kategoriene og de vil ikke vises i din ulest-liste." flagging: title: 'Takk for at du hjelper å holde forumet ryddig!' - private_reminder: 'flagg er private, bare synlige for staben' action: 'Rapporter innlegg' take_action: "Ta Handling" notify_action: 'Melding' @@ -1395,7 +1403,6 @@ nb_NO: help: "Dette emnet er ikke lenger fastsatt, det vil vises i vanlig rekkefølge" pinned_globally: title: "Globalt fastsatt" - help: "Dette emnet er globalt fastsatt; det vil vises på toppen av alle lister" pinned: title: "Fastsatt" help: "Dette emnet er fastsatt for deg; det vil vises i toppen av sin kategori" @@ -1438,8 +1445,8 @@ nb_NO: with_topics: "%{filter} emner" with_category: "%{filter} %{category} emner" latest: - title: - zero: "Siste" + title: "Siste" + title_with_count: one: "Siste (1)" other: "Siste ({{count}})" help: "de sist oppdaterte emnene" @@ -1457,21 +1464,21 @@ nb_NO: title_in: "Kategori - {{categoryName}}" help: "alle emner sortert etter kategori" unread: - title: - zero: "Ulest" + title: "Ulest" + title_with_count: one: "Ulest (1)" other: "Ulest ({{count}})" help: "emner du for øyeblikket følger eller sporer med uleste innlegg" lower_title_with_count: - one: "919b31115946cb42960c0b286e3d5fae_tr" - other: "d17f3dd2f82a108995bff08a2571e0ca_tr" + one: "1 ulest" + other: "{{count}} uleste" new: lower_title_with_count: one: "1 ny" other: "{{count}} nye" lower_title: "ny" - title: - zero: "Nye" + title: "Ny" + title_with_count: one: "Nye (1)" other: "Nye ({{count}})" help: "emner opprettet de siste dagene" @@ -1482,8 +1489,8 @@ nb_NO: title: "Bokmerker" help: "emner du har bokmerket" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "siste emner i {{categoryName}}-kategorien" @@ -1727,11 +1734,9 @@ nb_NO: is_disabled: "Gjenoppretting er deaktivert i nettstedsinnstillingene." label: "Gjenooprett" title: "Gjenopprett sikkerhetskopien" - confirm: "Er du sikker på at du vil gjenopprette denne sikkerhetskopien?" rollback: label: "Gjenopprett" title: "Gjenopprett databasen til en tidligere fungerende tilstand" - confirm: "Er du sikker på at du vil gjenopprette databasen til en tidligere fungerende tilstand?" export_csv: user_archive_confirm: "Er du sikker på at du vil laste ned innleggene dine?" success: "Eksportering iverksatt. Du vil bli varslet med en melding når prosessen er fullført." @@ -1782,6 +1787,8 @@ nb_NO: color: "Farge" opacity: "Opacity" copy: "Kopier" + email_templates: + subject: "Emne" css_html: title: "CSS/HTML" long_title: "CSS og HTML-tilpasninger" @@ -1826,13 +1833,9 @@ nb_NO: love: name: 'liker' description: "Fargen til Liker-knappen." - wiki: - name: 'wiki' - description: "Grunnfarge brukt for bakgrunnen i wiki-poster." email: - title: "E-post" settings: "Instillinger" - all: "Alle" + preview_digest: "Forhåndsvis Oppsummering" sending_test: "Sender e-post for testing" error: "ERROR - %{server_error}" test_error: "Det oppsto et problem ved utsendelse av e-post for testing. Sjekk e-postinnstillinger nøye, sjekk at verten ikke blokkerer e-posttilkoblinger, og prøv igjen." @@ -1847,7 +1850,6 @@ nb_NO: send_test: "Send e-post for testing" sent_test: "sendt!" delivery_method: "Leveringsmetode" - preview_digest: "Forhåndsvis Oppsummering" refresh: "Refresh" format: "Format" html: "html" @@ -1855,6 +1857,12 @@ nb_NO: last_seen_user: "Sist Sett Bruker:" reply_key: "Svar ID" skipped_reason: "Hopp over grunn" + incoming_emails: + from_address: "Fra" + subject: "Emne" + error: "Feil" + filters: + error_placeholder: "Feil" logs: none: "Ingen logger funnet" filters: @@ -1873,6 +1881,7 @@ nb_NO: ip_address: "IP" topic_id: "Emne ID" post_id: "Innlegg ID" + category_id: "Kategori ID" delete: 'Slett' edit: 'Endre' save: 'Lagre' @@ -1913,6 +1922,8 @@ nb_NO: impersonate: "overta brukerkonto" anonymize_user: "anonymiser bruker" roll_up: "rull opp IP-blokker" + delete_category: "slett kategori" + create_category: "opprett kategori" screened_emails: title: "Kontrollerte e-poster" description: "Når noen forsøker å lage en ny konto, vil de følgende e-postadressene bli sjekket, og registreringen vil bli blokkert, eller en annen handling vil bli utført." @@ -1978,9 +1989,6 @@ nb_NO: pending: 'Brukere som venter på evaluering' newuser: 'Brukere med tillitsnivå 0 (Ny Bruker)' basic: 'Brukere med tillitsnivå 1 (Juniormedlem)' - regular: 'Brukere med tillitsnivå 2 (Medlem)' - leader: 'Brukere med tillitsnivå 3 (Aktivt medlem)' - elder: 'Brukere med tillitsnivå 4 (Leder)' staff: "Stab" admins: 'Admins' moderators: 'Moderatorer' @@ -2090,7 +2098,6 @@ nb_NO: unlock_trust_level: "Lås opp tillitsnivå" tl3_requirements: title: "Krav til tillitsnivå 3" - table_title: "De siste 100 dagene:" value_heading: "Verdi" requirement_heading: "Krav" visits: "Besøk" @@ -2151,7 +2158,6 @@ nb_NO: confirm: 'Bekreftelse' dropdown: "Nedtrekk" site_text: - none: "Velg en innholdstype for å starte redigering." title: 'Tekstinnhold' site_settings: show_overriden: 'Bare vis overstyrte' @@ -2239,10 +2245,6 @@ nb_NO: bad_count_warning: header: "ADVARSEL!" text: "Det er manglende grant samples. Dette skjer når badge søket returnerer bruker-IDer eller post IDer som ikke eksisterer. Dette kan føre til uventede resultater senere - vennligst dobbeltsjekk søket ditt." - grant_count: - zero: "Ingen merker klare for tildeling" - one: "1 merke kan bli tildelt." - other: "%{count} merker kan bli tildelt." sample: "Eksempel:" grant: with: %{username} @@ -2324,8 +2326,6 @@ nb_NO: mark_watching: 'm, w Følg emne' badges: title: Merker - allow_title: "kan bli brukt som tittel" - multiple_grant: "kan bli belønnet mange ganger" badge_count: one: "1 Merke" other: "%{count} Merker" @@ -2348,85 +2348,3 @@ nb_NO: name: Annet posting: name: Posting - badge: - editor: - name: Redaktør - description: Første redigering av innlegg - basic_user: - name: Basic - description: Innvilget alle essensielle forumfunksjoner - member: - name: Medlem - description: Innvilget invitasjonsmulighet - regular: - name: Aktivt Medlem - description: Innvilget omkategorisering, endring av navn, fulgte lenker og salong - leader: - name: Leder - description: Innvilget global redigering, fastsetting, lukking, arkivering, splitting og sammenslåing - welcome: - name: Velkommen - description: Fått en liker - autobiographer: - name: Selvbiograf - description: Fylte ut informasjon om brukerprofilen - anniversary: - name: Jubileum - description: Aktivt medlem i over ett år, postet minst en gang - nice_post: - name: Fint innlegg - description: Fått 10 liker for et innlegg. Dette merket kan bli tildelt flere ganger - good_post: - name: Bra innlegg - description: Fått 25 liker for et innlegg. Dette merket kan bli tildelt flere ganger - great_post: - name: Flott Innlegg - description: Fått 50 liker for et innlegg. Dette merket kan bli tildelt flere ganger - nice_topic: - name: Fint emne - description: Fått 10 liker for et emne. Dette merket kan bli tildelt flere ganger - good_topic: - name: Godt emne - description: Fått 25 liker for et emne. Dette merket kan bli tildelt flere ganger - great_topic: - name: Fantastisk emne - description: Fått 50 liker for et emne. Dette merket kan bli tildelt flere ganger - nice_share: - name: Fin deling - description: Delt et innlegg med 25 unike besøkende - good_share: - name: God deling - description: Delt et innlegg med 300 unike besøkende - great_share: - name: Fantastisk Deling - description: Delt et innlegg med 1000 unike besøkende - first_like: - name: Første liker - description: Likt et innlegg - first_flag: - name: Første rapportering - description: Rapportert et innlegg - promoter: - name: Forfrem - description: Inviterte en bruker - campaigner: - name: Campaigner - description: Inviterte 3 medlemmer (tillitsnivå 1) - champion: - name: Mester - description: Inviterte 5 medlemmer (tillitsnivå 2) - first_share: - name: Første deling - description: Delt et innlegg - first_link: - name: Første lenke - description: Link til et eksisterende emne - first_quote: - name: Første sitat - description: Sitert en bruker - read_guidelines: - name: Leste retningslinjene - description: Lest forumets retningslinjer - reader: - name: Leser - description: Leste hvert innlegg i et emne med mer enn 100 innlegg diff --git a/config/locales/client.nl.yml b/config/locales/client.nl.yml index 7474d3ec9d6..509ec503aeb 100644 --- a/config/locales/client.nl.yml +++ b/config/locales/client.nl.yml @@ -100,6 +100,8 @@ nl: x_years: one: "1 jaar later" other: "%{count} jaren later" + previous_month: 'Vorige Maand' + next_month: 'Volgende Maand' share: topic: 'deel een link naar deze topic' post: 'bericht #%{postNumber}' @@ -110,6 +112,8 @@ nl: email: 'deel deze link via e-mail' action_codes: split_topic: "deze topic splitsen %{when}" + invited_user: "uitgenodigd %{who} %{when}" + removed_user: "verwijderd %{who} %{when}" autoclosed: enabled: 'gesloten %{when}' disabled: 'geopend %{when}' @@ -130,6 +134,19 @@ nl: disabled: 'niet zichtbaar %{when}' topic_admin_menu: "Adminacties voor topic" emails_are_disabled: "Alle uitgaande e-mails zijn uitgeschakeld door een beheerder. Geen enkele vorm van e-mail notificatie wordt verstuurd." + s3: + regions: + us_east_1: "US Oost (N. Virginia)" + us_west_1: "US West (N. California)" + us_west_2: "US West (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "EU (Ierland)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Azië Pacific (Singapore)" + ap_southeast_2: "Azië Pacific (Sydney)" + ap_northeast_1: "Azië Pacific (Tokyo)" + ap_northeast_2: "Azië Pacific (Seoul)" + sa_east_1: "Zuid Amerika (Sao Paulo)" edit: 'bewerk de titel en categorie van deze topic' not_implemented: "Die functie is helaas nog niet beschikbaar. Sorry!" no_value: "Nee" @@ -162,6 +179,8 @@ nl: more: "Meer" less: "Minder" never: "nooit" + every_30_minutes: "elke dertig minuten" + every_hour: "elk uur" daily: "dagelijks" weekly: "wekelijks" every_two_weeks: "elke twee weken" @@ -173,6 +192,7 @@ nl: other: "{{count}} tekens" suggested_topics: title: "Aanbevolen topics" + pm_title: "Voorgestelde Berichten" about: simple_title: "Over" title: "Over %{title}" @@ -220,7 +240,7 @@ nl: saved: "Opgeslagen!" upload: "Upload" uploading: "Uploaden..." - uploading_filename: "Uploaden {{filename}}..." + uploading_filename: "Uploaden van {{filename}}..." uploaded: "Geupload!" enable: "Inschakelen" disable: "Uitschakelen" @@ -228,7 +248,7 @@ nl: revert: "Zet terug" failed: "Mislukt" switch_to_anon: "Anonieme modus" - switch_from_anon: "Anoniem afsluiten" + switch_from_anon: "Niet meer anoniem zijn" banner: close: "Verberg deze banner." edit: "Wijzig deze banner >>" @@ -251,7 +271,7 @@ nl: one: "Voor deze topic staat 1 bericht klaar om goedgekeurd te worden" other: "Voor dit topic staan {{count}} berichten klaar om goedgekeurd te worden" confirm: "Sla wijzigingen op" - delete_prompt: "Weet je zeker dat je %{username} wilt verwijderen? Dit zal alle zijn berichten verwijderen en zal zijn email en ip-adres blokkeren." + delete_prompt: "Weet je zeker dat je %{username} wilt verwijderen? Dit verwijdert al hun post en blokkeert hun IP adres en E-mail adres." approval: title: "Bericht vereist goedkeuring" description: "We hebben je nieuwe bericht ontvangen, maar deze moet eerst goedgekeurd worden door een moderator voordat deze zichtbaar wordt. Wees a.u.b. geduldig." @@ -294,6 +314,15 @@ nl: one: "1 lid" other: "%{count} leden" groups: + empty: + posts: "Er zijn geen posts van leden van deze groep." + members: "Er zijn geen leden in deze groep." + mentions: "Deze groep wordt niet benoemd." + messages: "Er zijn geen berichten voor deze groep." + topics: "Er is geen onderwerp door de leden van deze groep." + add: "Voeg toe" + selector_placeholder: "Voeg leden toe" + owner: "eigenaar" visible: "Groep is zichtbaar voor alle gebruikers" title: one: "groep" @@ -301,7 +330,7 @@ nl: members: "Leden" posts: "Berichten" alias_levels: - title: "Wie kan deze groep als alias gebruiken?" + title: "Wie kan deze groep een bericht sturen en taggen?" nobody: "Niemand" only_admins: "Alleen admins" mods_and_admins: "Alleen moderatoren and admins" @@ -310,6 +339,19 @@ nl: trust_levels: title: "Trustlevel dat automatisch wordt toegekend aan nieuwe gebruikers:" none: "Geen" + notifications: + watching: + title: "Kijken naar" + description: "Je krijgt een notificatie bij elke nieuwe post of bericht, en het aantal nieuwe reacties wordt weergeven." + tracking: + title: "Volgen" + description: "Je krijgt een notificatie wanneer iemand jouw @name noemt of reageert, en het aantal nieuwe reacties wordt weergeven." + regular: + title: "Normaal" + description: "Je krijgt een notificatie wanneer iemand jouw @name noemt of reageert." + muted: + title: "Gedempt" + description: "Je krijgt geen notificatie over nieuwe onderwerpen in deze groep." user_action_groups: '1': "Likes gegeven" '2': "Likes ontvangen" @@ -319,7 +361,6 @@ nl: '6': "Reacties" '7': "Genoemd" '9': "Citaten" - '10': "Met ster" '11': "Wijzigingen" '12': "Verzonden items" '13': "Inbox" @@ -329,11 +370,13 @@ nl: all_subcategories: "alle" no_subcategory: "geen" category: "Categorie" + category_list: "Geef categorieën lijst weer." reorder: - title: "Categorieën Herschikken " + title: "Categorieën herschikken " title_long: "Reorganiseer de categorielijst" - fix_order: "Posities fixen" - save: "Volgorde Opslaan" + fix_order: "Posities vastzetten" + fix_order_tooltip: "Niet alle categorien hebben een unieke nummer, dit resulteert soms in onverwachte resultaten." + save: "Volgorde opslaan" apply_all: "Toepassen" position: "Positie" posts: "Berichten" @@ -384,16 +427,15 @@ nl: invited_by: "Uitgenodigd door" trust_level: "Trustlevel" notifications: "Notificaties" + statistics: "Statistieken " desktop_notifications: - label: "Desktop Notificaties" + label: "Desktopnotificaties" not_supported: "Notificaties worden niet ondersteund door deze browser. Sorry." - perm_default: "Notificaties Aanzetten" - perm_denied_btn: "Toestemming Geweigerd" - perm_denied_expl: "Gebruik van notificaties staat niet ingeschakeld. Gebruik je browser om notificaties toe te staan, klik vervolgens op de knop. (Desktop: Het meest linkse icoon op de adresbalk. Mobiel: 'Site Info' )" - disable: "Notificaties Uitschakelen" - currently_enabled: "(momenteel ingeschakeld)" - enable: "Notificaties Inschakelen" - currently_disabled: "(momenteel uitgeschakeld)" + perm_default: "Notificaties aanzetten" + perm_denied_btn: "Toestemming geweigerd" + perm_denied_expl: "Je blokkeert notificaties. Sta deze toe in je browser instellingen." + disable: "Notificaties uitschakelen" + enable: "Notificaties inschakelen" each_browser_note: "Let op: Je moet deze optie instellen voor elke browser die je gebruikt." dismiss_notifications: "Markeer alles als gelezen" dismiss_notifications_tooltip: "Markeer alle ongelezen berichten als gelezen" @@ -417,7 +459,7 @@ nl: tracked_categories: "Gevolgd" tracked_categories_instructions: "Je volgt automatisch alle nieuwe topics in deze categorie. Naast het topic wordt het aantal nieuwe berichten weergegeven." muted_categories: "Genegeerd" - muted_categories_instructions: "Je zal geen notificaties krijgen over nieuwe topics en berichten in deze categoriën en ze verschijnen niet op je ongelezen overzicht." + muted_categories_instructions: "Je zal geen notificaties krijgen over nieuwe onderwerpen en berichten in deze categorieën en ze verschijnen niet op je ongelezen overzicht." delete_account: "Verwijder mijn account" delete_account_confirm: "Weet je zeker dat je je account definitief wil verwijderen? Dit kan niet meer ongedaan gemaakt worden!" deleted_yourself: "Je account is verwijderd." @@ -427,6 +469,8 @@ nl: users: "Leden" muted_users: "Negeren" muted_users_instructions: "Negeer alle meldingen van deze leden." + muted_topics_link: "Toon gedempte topics." + automatically_unpin_topics: "Topics automatisch lospinnen als ik het laatste bericht bereik." staff_counters: flags_given: "behulpzame markeringen" flagged_posts: "gemarkeerde berichten" @@ -435,8 +479,15 @@ nl: warnings_received: "waarschuwingen" messages: all: "Alle" - mine: "Mijn" - unread: "Ongelezen" + inbox: "Postvak In" + sent: "Verzend" + archive: "Archiveren" + groups: "Mijn Groepen" + bulk_select: "Selecteer berichten" + move_to_inbox: "Verplaats naar Postvak In" + move_to_archive: "Archiveren" + failed_to_move: "Het is niet gelukt om het geselecteerde bericht te verplaatsen (Waarschijnlijk is de internetconnectie verbroken)" + select_all: "Selecteer Alles" change_password: success: "(e-mail verzonden)" in_progress: "(e-mail wordt verzonden)" @@ -481,9 +532,9 @@ nl: ok: "We sturen een e-mail ter bevestiging" invalid: "Vul een geldig e-mailadres in " authenticated: "Je e-mail is geauthenticeerd door {{provider}}" + frequency_immediately: "We zullen je onmiddellijk e-mailen als je hetgeen waarover we je e-mailen niet gelezen hebt." frequency: - zero: "We zullen je onmiddelijk e-mailen als je hetgeen waarover we je e-mailen niet gelezen hebt." - one: "We zullen je alleen maar e-mailen als we je de laatste paar minuten niet gezien hebben." + one: "We zullen je alleen maar e-mailen als we je de laatste {{count}} minuten niet gezien hebben." other: "We zullen je alleen maar e-mailen als we je de laatste {{count}} minuten niet gezien hebben." name: title: "Naam" @@ -520,12 +571,25 @@ nl: title: "Badge van gebruikersprofiel" website: "Website" email_settings: "E-mail" + like_notification_frequency: + always: "Altijd" + first_time_and_daily: "De eerste keer dat iemand een bericht leuk vond en dagelijks" + first_time: "De eerste keer dat iemand een bericht leuk vond" + never: "Nooit" + email_previous_replies: + title: "Voeg de vorige reacties bij onderaan de emails" + unless_emailed: "tenzij eerder verzonden" + always: "altijd" + never: "nooit" email_digests: title: "Stuur me een mail met de laatste updates wanneer ik de site niet bezoek:" + every_30_minutes: "elke dertig minuten" + every_hour: "elk uur" daily: "dagelijks" every_three_days: "elke drie dagen" weekly: "wekelijks" every_two_weeks: "elke twee weken" + email_in_reply_to: "Voeg een deel van de reactie toe in de emails" email_direct: "Stuur me een e-mail wanneer iemand me citeert, reageert op mijn bericht, mijn @gebruikersnaam noemt of uitnodigt voor een topic." email_private_messages: "Ontvang een mail wanneer iemand je een bericht heeft gestuurd." email_always: "Stuur me e-mail notificaties, zelfs als ik ben actief op de site" @@ -556,7 +620,9 @@ nl: user: "Uitgenodigd lid" sent: "Verzonden" none: "Er zijn geen uitstaande uitnodigingen om weer te geven." - truncated: "De eerste {{count}} uitnodigingen." + truncated: + one: "Tonen van de eerste uitnodiging." + other: "Tonen van de eerste {{count}} uitnodigingen." redeemed: "Verzilverde uitnodigingen" redeemed_tab: "Verzilverd" redeemed_tab_with_count: "Verzilverd ({{count}})" @@ -591,6 +657,15 @@ nl: same_as_email: "Je wachtwoord is hetzelfde als je e-mail." ok: "Je wachtwoord ziet er goed uit." instructions: "Minimaal %{count} tekens." + summary: + title: "Overzicht " + stats: "Statistieken " + top_replies: "Beste Reacties" + more_replies: "Meer Antwoorden" + top_topics: "Top Topics" + more_topics: "Meer Topics" + top_badges: "Top Badges" + more_badges: "Meer Badges" associated_accounts: "Logins" ip_address: title: "Laatste IP-adres" @@ -616,11 +691,13 @@ nl: server: "Serverfout" forbidden: "Toegang geweigerd" unknown: "Fout" + not_found: "Pagina niet gevonden" desc: network: "Controleer je verbinding." network_fixed: "Het lijkt er op dat het terug is" server: "Fout code: {{status}}" forbidden: "Je hebt geen toestemming om dit te bekijken." + not_found: "Oeps, de applicatie heeft geprobeerd een URL te laden die niet bestaat." unknown: "Er is iets mis gegaan" buttons: back: "Ga terug" @@ -631,8 +708,9 @@ nl: logout: "Je bent uitgelogd." refresh: "Ververs" read_only_mode: - enabled: "Alleen-lezen modus is aangezet. Je kan de site bekijken, maar interacties werken mogelijk niet." + enabled: "De site is in alleen lezen modus. Interactie is niet mogelijk." login_disabled: "Zolang de site in read-only modus is, kan er niet ingelogd worden." + logout_disabled: "Uitloggen is uitgeschakeld als de site op alleen lezen staat." too_few_topics_and_posts_notice: "Laten we de discussie starten! Er zijn al %{currentTopics} / %{requiredTopics} topics en %{currentPosts} / %{requiredPosts} berichten. Nieuwe bezoekers hebben conversaties nodig om te lezen en reageren." too_few_topics_notice: "Laten we de discussie starten! Er zijn al %{currentTopics} / %{requiredTopics} topics en %{currentPosts} / %{requiredPosts} berichten. Nieuwe bezoekers hebben conversaties nodig om te lezen en reageren." too_few_posts_notice: "Laten we de discussie starten!. Er zijn al %{currentPosts} / %{requiredPosts} posts Nieuwe bezoekers hebben conversaties nodig om te lezen en reageren." @@ -655,12 +733,14 @@ nl: signup_cta: sign_up: "Aanmelden" hide_session: "Herrinner me morgen" - hide_forever: "Nee bedankt" + hide_forever: "nee dankje" hidden_for_session: "Ok, ik vraag het je morgen. Je kunt altijd 'Log in' gebruiken om in te loggen." + intro: "Hey! :heart_eyes: Praat mee in deze discussie, meld je aan met een account" + value_prop: "Wanneer je een account aangemaakt hebt, herinneren deze wat je gelezen hebt, zodat je direct door kan lezen vanaf waar je gestopt bent. Je krijgt ook notificaties, hier en via email, wanneer nieuwe posts gemaakt zijn. En je kan ook nog posts liken :heartbeat:" summary: enabled_description: "Je leest een samenvatting van dit topic: alleen de meeste interessante berichten zoals bepaald door de community. " - description: "Er zijn {{count}} reacties." - description_time: "Er zijn {{count}} reacties met een gemiddelde leestijd van {{readingTime}} minuten." + description: "Er zijn {{replyCount}} reacties." + description_time: "Er zijn {{replyCount}} reacties met een geschatte leestijd van{{readingTime}} minuten." enable: 'Samenvatting Topic' disable: 'Alle berichten' deleted_filter: @@ -714,6 +794,9 @@ nl: admin_not_allowed_from_ip_address: "Je kan jezelf niet aanmelden vanaf dat IP-adres." resend_activation_email: "Klik hier om de activatiemail opnieuw te ontvangen." sent_activation_email_again: "We hebben een nieuwe activatiemail gestuurd naar {{currentEmail}}. Het kan een aantal minuten duren voor deze aan komt. Check ook je spamfolder." + to_continue: "Log a.u.b. in" + preferences: "Je moet ingelogd zijn om je gebruikersinstellingen te wijzigen." + forgot: "Ik kan me de details van mijn gebruikersaccount niet herinneren." google: title: "met Google" message: "Inloggen met een Google-account (zorg ervoor dat je popup blocker uit staat)" @@ -723,6 +806,9 @@ nl: twitter: title: "met Twitter" message: "Inloggen met een Twitteraccount (zorg ervoor dat je popup blocker uit staat)" + instagram: + title: "met Instagram" + message: "Inloggen met een Instagram-account (zorg ervoor dat je pop-upblocker uitstaat)." facebook: title: "met Facebook" message: "Inloggen met een Facebookaccount (zorg ervoor dat je popup blocker uit staat)" @@ -736,15 +822,24 @@ nl: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "meer..." + options: "Opties" + whisper: "Fluister" add_warning: "Dit is een officiële waarschuwing." + toggle_whisper: "Schakel Fluistermode" posting_not_on_topic: "In welke topic wil je je antwoord plaatsen?" saving_draft_tip: "opslaan..." saved_draft_tip: "opgeslagen" saved_local_draft_tip: "lokaal opgeslagen" similar_topics: "Jouw topic lijkt op..." drafts_offline: "concepten offline" + group_mentioned: "Door het gebruik van {{group}}, sta je op het punt {{count}} op de hoogte te brengen." error: title_missing: "Titel is verplicht" title_too_short: "Titel moet uit minstens {{min}} tekens bestaan" @@ -765,8 +860,9 @@ nl: title_placeholder: "Waar gaat de discussie over in één korte zin?" edit_reason_placeholder: "vanwaar de wijziging?" show_edit_reason: "(geef een reden)" + reply_placeholder: "Typ hier. Gebruik Markdown, BBCode, of HTML om op te maken. Sleep of plak afbeeldingen." view_new_post: "Bekijk je nieuwe bericht." - saving: "Opslaan..." + saving: "Opslaan" saved: "Opgeslagen!" saved_draft: "Bezig met conceptbericht. Selecteer om door te gaan." uploading: "Uploaden..." @@ -781,6 +877,7 @@ nl: link_description: "geef hier een omschrijving" link_dialog_title: "Voeg weblink toe" link_optional_text: "optionele titel" + link_placeholder: "http://example.com \"optional text\"" quote_title: "Citaat" quote_text: "Citaat" code_title: "Opgemaakte tekst" @@ -793,10 +890,11 @@ nl: heading_title: "Kop" heading_text: "Kop" hr_title: "Horizontale lijn" - undo_title: "Herstel" - redo_title: "Opnieuw" help: "Uitleg over Markdown" toggler: "verberg of toon de editor" + modal_ok: "OK" + modal_cancel: "Annuleer" + cant_send_pm: "Sorry, je kan geen berichten sturen naar %{username}." admin_options_title: "Optionele stafinstellingen voor deze topic" auto_close: label: "Tijd waarna topic automatisch wordt gesloten:" @@ -813,9 +911,9 @@ nl: more: "bekijk oudere notificaties" total_flagged: "aantal gemarkeerde berichten" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -825,6 +923,9 @@ nl: moved_post: "

    {{username}} verplaatste {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    '{{description}}' ontvangen

    " + group_message_summary: + one: "

    {{count}} berichten in jouw {{group_name}} inbox

    " + other: "

    {{count}} berichten in jouw {{group_name}} inbox

    " alt: mentioned: "Genoemd door" quoted: "Gequoot door" @@ -839,8 +940,10 @@ nl: moved_post: "Je bericht is verplaatst door" linked: "Link naar je bericht" granted_badge: "Badge toegekend" + group_message_summary: "Berichten in groep Postvak In" popup: mentioned: '{{username}} heeft je genoemd in "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} noemde jouw naam in "{{topic}}" - {{site_title}}' quoted: '{{username}} heeft je geciteerd in "{{topic}}" - {{site_title}}' replied: '{{username}} heeft je beantwoord in "{{topic}}" - {{site_title}}' posted: '{{username}} heeft een bericht geplaats in "{{topic}}" - {{site_title}}' @@ -852,10 +955,11 @@ nl: from_my_computer: "Vanaf mijn apparaat" from_the_web: "Vanaf het web" remote_tip: "link naar afbeelding" - remote_tip_with_attachments: "vul een url in van een afbeelding of bestand (toegestane extensies: {{authorized_extensions}})." + remote_tip_with_attachments: "link naar afbeelding of bestand {{authorized_extensions}}" local_tip: "selecteer afbeeldingen van uw apparaat" - local_tip_with_attachments: "Selecteer afbeeldingen of bestanden van je apparaat ({{authorized_extensions}})" + local_tip_with_attachments: "selecteer afbeeldingen of bestanden vanaf je apparaat {{authorized_extensions}}" hint: "(je kan afbeeldingen ook slepen in de editor om deze te uploaden)" + hint_for_supported_browsers: "je kunt ook afbeeldingen slepen of plakken in de editor" uploading: "Uploaden" select_file: "Selecteer een bestand" image_link: "de link waar je afbeelding naar verwijst" @@ -867,6 +971,9 @@ nl: most_liked: "Meest geliked" select_all: "Selecteer Alles" clear_all: "Wis Alles" + result_count: + one: "1 resultaat voor \"{{term}}\"" + other: "{{count}} resultaat voor \"{{term}}\"" title: "zoek naar topics, berichten, gebruikers of categorieën" no_results: "Geen resultaten gevonden." no_more_results: "Geen resultaten meer gevonden." @@ -885,12 +992,14 @@ nl: current_user: 'ga naar je gebruikerspagina' topics: bulk: + unlist_topics: "Topics van lijst halen" reset_read: "markeer als ongelezen" delete: "Verwijder topics" - dismiss_posts: "Verwijder berichten" - dismiss_posts_tooltip: "Reset de teller voor ongelezen berichten voor deze topics, maar houd ze wel in mijn lijst van ongelezen topics als er nieuwe berichten worden toegevoegd" - dismiss_topics: "Verwijder topics" - dismiss_topics_tooltip: "Laat deze topics niet meer in mijn lijst van ongelezen topics zien wanneer er nieuwe berichten worden geplaatst." + dismiss: "Afwijzen" + dismiss_read: "Alle ongelezen afwijzen" + dismiss_button: "Afwijzen..." + dismiss_tooltip: "Alleen nieuwe posts afwijzen of stop het volgen van topics" + also_dismiss_topics: "Stop het volgen van deze topics, zodat deze nooit meer als ongelezen worden weergegeven. " dismiss_new: "markeer nieuwe berichten als gelezen" toggle: "toggle bulkselectie van topics" actions: "Bulk Acties" @@ -914,8 +1023,8 @@ nl: top: "Er zijn geen top-topics." search: "Er zijn geen zoekresultaten gevonden." educate: - new: '

    Je nieuwe topics verschijnen hier.

    Standaard worden topics als nieuw beschouwd en tonen een nieuw indicator als ze gemaakt zijn in de afgelopen 2 dagen.

    Je kan dit aanpassen in je voorkeuren.

    ' - unread: '

    Je ongelezen topics verschijnen hier.

    Standaard worden topics als ongelezen beschouwd en tonen een ongelezen aantal 1 als je:

    • Het topic gemaakt hebt
    • Geantwoord hebt in het topic
    • Het topic meer dan 4 minuten hebt gelezen

    Of als je het topic expliciet hebt gemarkeerd als Te Volgen via de notificatieknop onder aan de pagina van elk topic.

    Je kan dit aanpassen in je instellingen.

    ' + new: '

    Je nieuwe topics verschijnen hier.

    Standaard worden topics als nieuw weergegeven en als nieuw weergegeven als deze binnen de laatste 2 dagen zijn aangemaakt.

    Visit your voorkeuren om dit te veranderen.

    ' + unread: '

    Je ongelezen berichten verschijnen hier.

    Standaard worden topics als nieuw beschouwd en zullen als ongelezen worden weergegeven1 als je:

    • de topic hebt aangemaakt
    • reageert op dit bericht
    • leest voor meer dan 4 minuten

    Of als je het topic als volgen hebt gemarkeerd of hebt bekeken via het notificatie onderaan elk bericht.

    Bezoek jouwvoorkeuren om dit te veranderen

    ' bottom: latest: "Er zijn geen recente topics." hot: "Er zijn geen polulaire topics meer." @@ -935,6 +1044,12 @@ nl: create: 'Nieuw topic' create_long: 'Maak een nieuw topic' private_message: 'Stuur een bericht' + archive_message: + help: 'Verplaats berichten naar jouw archief ' + title: 'Archiveren ' + move_to_inbox: + title: 'Verplaats naar Postvak In' + help: 'Verplaats het bericht terug naar Postvak in' list: 'Topics' new: 'nieuw topic' unread: 'ongelezen' @@ -985,6 +1100,7 @@ nl: auto_close_title: 'Instellingen voor automatisch sluiten' auto_close_save: "Opslaan" auto_close_remove: "Sluit deze topic niet automatisch" + auto_close_immediate: "De laatste post in dit topic is al %{hours} uur oud, dus dit topic wordt meteen gesloten." progress: title: voortgang van topic go_top: "bovenaan" @@ -1034,7 +1150,7 @@ nl: description: "Je zal geen enkele notificatie ontvangen over dit bericht." muted: title: "Negeren" - description: "Je zal geen notificaties krijgen van dit topic en het zal ook niet verschijnen in je lijst ongelezen topics." + description: "Je zult nooit op de hoogte worden gebracht over dit topic, en het zal niet verschijnen in Nieuwste." actions: recover: "Herstel topic" delete: "Verwijder topic" @@ -1076,25 +1192,24 @@ nl: unpin_until: "Zet deze topic niet langer bovenaan in de {{categoryLink}} categorie of wacht tot %{until}." pin_note: "Gebruikers kunnen het vastpinnen voor dit topic voor zichzelf ongedaan maken." pin_validation: "Een datum is vereist om deze topic vast te pinnen." + not_pinned: "Er zijn geen topics vastgepind in {{categoryLink}}." already_pinned: - zero: "Er zijn geen topics vastgepind in {{categoryLink}}." - one: "Topics welke vastgepind zijn in {{categoryLink}}: 1." + one: "Topics welke vastgepind zijn in {{categoryLink}}: {{count}}" other: "Topics welke vastgepind zijn in {{categoryLink}}: {{count}}." pin_globally: "Zet deze topic bovenaan in alle topic lijsten tot" confirm_pin_globally: "Je hebt al {{count}} globaal vastgepinde topics. Teveel vastgepinde topics kunnen storend zijn voor nieuwe en anonieme gebruikers. Weet je zeker dat je nog een topic globaal wilt vastpinnen?" unpin_globally: "Zorg ervoor dat dit topic niet langer bovenaan alle topic lijsten komt." unpin_globally_until: "Zet deze topic niet langer bovenaan in alle topic lijsten of wacht tot %{until}." global_pin_note: "Gebruikers kunnen dit topic voor zichzelf ontpinnen." + not_pinned_globally: "Er zijn geen globaal vastgepinde topics." already_pinned_globally: - zero: "Er zijn geen globaal vastgepinde topics." - one: "Topics welke globaal vastgepind zijn: 1." + one: "Topics welke globaal vastgepind zijn: {{count}}" other: "Topics welke globaal vastgepind zijn: {{count}}." make_banner: "Zorg ervoor dat dit topic een banner wordt welke bovenaan alle pagina's komt." remove_banner: "Verwijder de banner die bovenaan alle pagina's staat." banner_note: "Gebruikers kunnen de banner negeren door deze te sluiten. Er kan maar een topic gebannered zijn." - already_banner: - zero: "Er is geen banner topic." - one: "Er is op het ogenblik een banner topic." + no_banner_exists: "Er is geen banner topic." + banner_exists: "Er is op het ogenblik een banner topic." inviting: "Uitnodigen..." automatically_add_to_groups_optional: "Deze uitnodiging geeft ook toegang tot de volgende groepen: (optioneel, alleen voor beheerders)" automatically_add_to_groups_required: "Deze uitnodiging geeft ook toegang tot de volgende groepen: (Verplicht, alleen voor beheerders)" @@ -1106,6 +1221,7 @@ nl: success: "Deze gebruiker is uitgenodigd om in de conversatie deel te nemen." error: "Sorry, er is iets misgegaan bij het uitnodigen van deze persoon" group_name: "groepsnaam" + controls: "Topic Controls" invite_reply: title: 'Uitnodigen' username_placeholder: "gebruikersnaam" @@ -1200,9 +1316,9 @@ nl: has_likes_title: one: "iemand vind dit bericht leuk" other: "{{count}} mensen vinden dit bericht leuk" + has_likes_title_only_you: "Je vind dit bericht leuk" has_likes_title_you: - zero: "Je vind dit bericht leuk" - one: "jij en 1 ander persoon vinden dit leuk" + one: "jij en 1 anderen vinden dit leuk" other: "jij en {{count}} anderen vinden dit leuk" errors: create: "Sorry, er is iets misgegaan bij het plaatsen van je bericht. Probeer het nog eens." @@ -1221,8 +1337,9 @@ nl: no_value: "Nee, behouden" yes_value: "Ja, verwijderen" via_email: "dit bericht kwam binnen via e-mail" + whisper: "deze posts zijn alleen toegankelijk voor moderators" wiki: - about: "deze discussie is een wiki; normale gebruikers kunnen hem aanpassen" + about: "dit bericht is een wiki" archetypes: save: 'Bewaar instellingen' controls: @@ -1250,6 +1367,7 @@ nl: revert_to_regular: "Verwijder stafkleur" rebake: "Maak HTML opnieuw" unhide: "Toon" + change_owner: "Eigenaar wijzigen " actions: flag: 'Markeer' defer_flags: @@ -1271,17 +1389,14 @@ nl: like: "Vind het niet meer leuk" vote: "Stem niet meer" people: - off_topic: "{{icons}} markeerden dit als off-topic" - spam: "{{icons}} markeerden dit als spam" - spam_with_url: "{{icons}} markeerde dit als spam" - inappropriate: "{{icons}} markeerden dit als ongepast" - notify_moderators: "{{icons}} lichtte moderators in" - notify_moderators_with_url: "{{icons}} lichtte moderators in" - notify_user: "{{icons}} verstuurde een bericht" - notify_user_with_url: "{{icons}} verstuurde een bericht" - bookmark: "{{icons}} voegden dit toe aan hun bladwijzers" - like: "{{icons}} vinden dit leuk" - vote: "{{icons}} hebben hier op gestemd" + off_topic: "heeft dit als off-topic gemeld" + spam: "markeerde dit als spam" + inappropriate: "markeerde dit als ongepast" + notify_moderators: "lichtte moderators in" + notify_user: "Stuur een bericht" + bookmark: "bladwijzer deze" + like: "Vind dit leuk" + vote: "stemde voor dit" by_you: off_topic: "Jij markeerde dit als off-topic" spam: "Jij markeerde dit als spam" @@ -1341,10 +1456,6 @@ nl: vote: one: "Iemand heeft op dit bericht gestemd" other: "{{count}} Mensen hebben op dit bericht gestemd" - edits: - one: één bewerking - other: "{{count}} bewerkingen" - zero: geen bewerkingen delete: confirm: one: "Weet je zeker dat je dit bericht wil verwijderen?" @@ -1404,6 +1515,7 @@ nl: change_in_category_topic: "Wijzig omschrijving" already_used: 'Deze kleur is al in gebruik door een andere categorie' security: "Beveiliging" + special_warning: "Waarschuwing: Dee catogorie is een vooringestelde categorie en de beveiligingsinstellingen kunnen hierdoor niet bewerkt worden. Als u deze categorie niet wenst te gebruiken, verwijder deze of herbestem deze." images: "Afbeeldingen" auto_close_label: "Sluit topics automatisch na:" auto_close_units: "uren" @@ -1424,19 +1536,18 @@ nl: notifications: watching: title: "In de gaten houden" - description: "Je ziet automatisch alle nieuwe topics in deze categorieën. Je ontvangt notificaties bij nieuwe berichten en topics, het aantal nieuwe reacties wordt voor deze topics weergegeven." + description: "Je krijgt automatisch alle nieuwe topics in deze categorie te zien. Je ontvangt notificaties bij nieuwe berichten en topics, naast het topic wordt het aantal nieuwe berichten weergegeven. " tracking: title: "Volgen" - description: "Je volgt automatisch alle topics in deze categorieën. Het aantal nieuwe reacties wordt voor deze topics weergegeven." + description: "Je ziet automatisch alle nieuwe topics in deze categorieën. Je ontvangt notificaties wanneer iemand je @name noemt of reageert op jou." regular: - title: "Regulier" + title: "Normaal" description: "Je krijgt een notificatie als iemand je @naam noemt of reageert op een bericht van jou." muted: title: "Genegeerd" - description: "Je zal geen notificaties krijgen over nieuwe topics en berichten in deze categoriën en ze verschijnen niet op je ongelezen overzicht." + description: "Je zult nooit op de hoogte worden gebracht over nieuwe topics in deze categorie, en ze zullen niet verschijnen in Nieuwste." flagging: title: 'Bedankt voor het helpen beleefd houden van onze gemeenschap!' - private_reminder: 'vlaggen zijn privé, alleen zichtbaar voor de staf' action: 'Meld bericht' take_action: "Onderneem actie" notify_action: 'Bericht' @@ -1486,7 +1597,7 @@ nl: help: "Dit topic is niet langer vastgepind voor je en zal weer in de normale volgorde getoond worden" pinned_globally: title: "Globaal vastgepind" - help: "Deze topic is globaal vastgepind en zal bovenaan alle topiclijsten getoond worden" + help: "Deze topic is globaal vastgepind en zal bovenaan de lijsten top en nieuwste getoond worden." pinned: title: "Vastgepind" help: "Dit topic is vastgepind voor je en zal bovenaan de categorie getoond worden" @@ -1529,8 +1640,8 @@ nl: with_topics: "%{filter} topics" with_category: "%{filter} %{category} topics" latest: - title: - zero: "Laatste" + title: "Laatste" + title_with_count: one: "Laatste (1)" other: "Laatste ({{count}})" help: "topics met recente reacties" @@ -1548,8 +1659,8 @@ nl: title_in: "Categorie - {{categoryName}}" help: "alle topics gesorteerd op categorie" unread: - title: - zero: "Ongelezen" + title: "Ongelezen" + title_with_count: one: "Ongelezen (1)" other: "Ongelezen ({{count}})" help: "topics die je volgt of bijhoudt met ongelezen berichten" @@ -1558,13 +1669,13 @@ nl: other: "{{count}} ongelezen" new: lower_title_with_count: - one: "1 nieuwe" - other: "{{count}} nieuwe" + one: "1 nieuw" + other: "{{count}} nieuw" lower_title: "nieuw" - title: - zero: "Nieuw" + title: "Nieuw" + title_with_count: one: "Nieuw (1)" - other: "Nieuw ({{count}})" + other: "({{count}}) Nieuwe" help: "topics gemaakt in de afgelopen dagen" posted: title: "Mijn berichten" @@ -1573,8 +1684,8 @@ nl: title: "Bladwijzers" help: "topics waar je een bladwijzer aan toe hebt gevoegd" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "recente topics in de categorie {{categoryName}}" @@ -1656,6 +1767,7 @@ nl: refresh_report: "Ververs Rapport" start_date: "Start datum" end_date: "Eind datum" + groups: "Alle groepen" commits: latest_changes: "Laatste wijzigingen: update regelmatig!" by: "door" @@ -1736,15 +1848,24 @@ nl: delete_confirm: "Verwijder deze groepen?" delete_failed: "Kan groep niet verwijderen. Als dit een automatische groep is, kan deze niet verwijderd worden." delete_member_confirm: "Verwijder '%{username}' van de '%{group'} groep?" + delete_owner_confirm: "Verwijder eigenaar privilege voor '% {username}'?" name: "Naam" add: "Voeg toe" add_members: "Voeg leden toe" custom: "Aangepast" + bulk_complete: "De gebruikers zijn toegevoegd aan de groep." + bulk: "Bulk toevoegen aan groep." + bulk_paste: "Plak een lijst van gebruikersnamen of e-mails, één per regel:" + bulk_select: "(selecteer een groep)" automatic: "Automatisch" automatic_membership_email_domains: "Gebruikers welke zich registeren met een email domein dat exact overeenkomt met de domeinen in deze lijst worden automatisch toegevoegd aan deze groep:" automatic_membership_retroactive: "Pas deze email domein regel toe op reeds geregistreerde gebruikers" default_title: "Standaard titel voor alle gebruikers in deze groep" primary_group: "Automatisch ingesteld als primaire groep" + group_owners: Eigenaren + add_owners: Eigenaren toevoegen + incoming_email: "Aangepaste inkomende email adressen " + incoming_email_placeholder: "Voer je email adres in" api: generate_master: "Genereer Master API Key" none: "Er zijn geen actieve API keys" @@ -1818,11 +1939,11 @@ nl: is_disabled: "Herstellen is uitgeschakeld in de instellingen." label: "Herstel" title: "Herstel van deze backup" - confirm: "Weet je zeker dat je van deze backup wil herstellen?" + confirm: "Weet je zeker dat je deze backup wilt terugzetten? " rollback: label: "Herstel" title: "Herstel de database naar de laatst werkende versie" - confirm: "Weet je zeker dat je de database wil herstellen naar de laatste versie?" + confirm: "Weet je zeker dat je de database wilt terugzetten naar de vorige staat?" export_csv: user_archive_confirm: "Weet je zeker dat je al je berichten wil downloaden?" success: "Exporteren is gestart, je zult gewaarschuwd worden als het proces is beeindigd." @@ -1873,6 +1994,14 @@ nl: color: "Kleur" opacity: "Doorzichtigheid" copy: "Kopieër" + email_templates: + title: "Email Sjabloon " + subject: "Onderwerp" + multiple_subjects: "Dit email sjabloon heeft meerdere onderwerpen." + body: "Body" + none_selected: "Kies een email sjabloon om te beginnen met bewerken." + revert: "Maak wijzigingen ongedaan" + revert_confirm: "Weet je zeker dat je de veranderingen ongedaan wilt maken?" css_html: title: "CSS/HTML" long_title: "CSS en HTML aanpassingen" @@ -1917,18 +2046,18 @@ nl: love: name: 'liefde' description: "De like knop kleur." - wiki: - name: 'wiki' - description: "Basiskleur die gebruikt wordt voor de achtergrond van wiki berichten." email: - title: "E-mail" + title: "E-mails" settings: "Instellingen" - all: "Alle" + templates: "Sjablonen " + preview_digest: "Voorbeeld digestmail" sending_test: "Testmail wordt verstuurd..." error: "FOUT - %{server_error}" test_error: "Er ging iets mis bij het versturen van de testmail. Kijk nog eens naar je mailinstellinen, controleer of je host mailconnecties niet blokkeert. Probeer daarna opnieuw." sent: "Verzonden" skipped: "Overgeslagen" + received: "Ontvangen" + rejected: "Geweigerd " sent_at: "Verzonden op" time: "Tijd" user: "Gebruiker" @@ -1938,7 +2067,6 @@ nl: send_test: "verstuur test e-mail" sent_test: "verzonden!" delivery_method: "Verzendmethode" - preview_digest: "Voorbeeld digestmail" preview_digest_desc: "Voorbeeld van de digest e-mails die naar inactieve leden worden verzonden." refresh: "Verniew" format: "Formaat" @@ -1947,6 +2075,24 @@ nl: last_seen_user: "Laatste online:" reply_key: "Reply key" skipped_reason: "Reden van overslaan" + incoming_emails: + from_address: "Van" + to_addresses: "Naar" + cc_addresses: "Cc" + subject: "Onderwerp" + error: "Error" + none: "Geen inkomende emails gevonden." + modal: + title: "Inkomende Email Details" + error: "Error" + subject: "Onderwerp" + body: "Body" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Onderwerp.." + error_placeholder: "Error" logs: none: "Geen logs gevonden." filters: @@ -1965,6 +2111,7 @@ nl: ip_address: "IP" topic_id: "Topic ID" post_id: "Bericht ID" + category_id: "Categorie ID" delete: 'Verwijder' edit: 'Wijzig' save: 'Opslaan' @@ -1995,6 +2142,7 @@ nl: change_site_setting: "verander instellingen" change_site_customization: "verander site aanpassingen" delete_site_customization: "verwijder site aanpassingen" + change_site_text: "Verander site tekst" suspend_user: "schors gebruiker" unsuspend_user: "hef schorsing op" grant_badge: "ken badge toe" @@ -2005,6 +2153,16 @@ nl: impersonate: "Log in als gebruiker" anonymize_user: "maak gebruiker anoniem" roll_up: "groepeer verbannen IP-adressen" + change_category_settings: "verander categorie instellingen" + delete_category: "categorie verwijderen" + create_category: "categorie creeren" + block_user: "blokkeer gebruiker" + unblock_user: "deblokkeer gebruiker" + grant_admin: "Ken Beheerdersrechten toe" + revoke_admin: "Ontneem beheerdersrechten" + grant_moderation: "Geef modereerrechten" + revoke_moderation: "Ontneem modereerrechten" + backup_operation: "backup handeling" screened_emails: title: "Gescreende e-mails" description: "Nieuwe accounts met een van deze mailadressen worden geblokkeerd of een andere actie wordt ondernomen." @@ -2071,9 +2229,9 @@ nl: pending: 'Nog niet geaccepteerde leden' newuser: 'Leden met Trust Level 0 (Nieuw lid)' basic: 'Leden met Trust Level 1 (Lid)' - regular: 'Leden op Trust Level 2 (Lid)' - leader: 'Leden op Trust Level 3 (Vaste bezoeker)' - elder: 'Leden op Trust Level 4 (Leider)' + member: 'Leden op Trust Level 2 (Lid)' + regular: 'Leden op Trust Level 3 (Vaste bezoeker)' + leader: 'Leden op Trust Level 4 (Leider)' staff: "Stafleden" admins: 'Administrators' moderators: 'Moderators' @@ -2106,6 +2264,7 @@ nl: moderator: "Moderator?" admin: "Beheerder?" blocked: "Geblokkeerd?" + staged: "Opvoeren?" show_admin_profile: "Beheerder" edit_title: "Wijzig titel" save_title: "Bewaar titel" @@ -2170,9 +2329,12 @@ nl: deactivate_failed: "Er ging iets mis bij het deactiveren van deze gebruiker." unblock_failed: 'Er ging iets mis bij het deblokkeren van deze gebruiker.' block_failed: 'Er ging iets mis bij het blokkeren van deze gebruiker.' + block_confirm: 'Weet je zeker dat je deze gebruikt wilt blokkeren? Deze gebruikers is dan niet meer in staat om nieuwe topics of berichten te plaatsen.' + block_accept: 'Ja, blokkeer deze gebruiker' deactivate_explanation: "Een gedeactiveerde gebruiker moet zijn e-mailadres opnieuw bevestigen." suspended_explanation: "Een geschorste gebruiker kan niet meer inloggen." block_explanation: "Een geblokkeerde gebruiker kan geen topics maken of reageren op topics." + stage_explanation: "Een opgevoerde gebruiker kan alleen via email in bepaalde topics berichten." trust_level_change_failed: "Er ging iets mis bij het wijzigen van het trust level van deze gebruiker." suspend_modal_title: "Schors gebruiker" trust_level_2_users: "Trust Level 2 leden" @@ -2183,7 +2345,7 @@ nl: unlock_trust_level: "Deblokkeer Trust Level" tl3_requirements: title: "Vereisten voor Trust Level 3" - table_title: "In de afgelopen 100 dagen:" + table_title: "In de laatste %{time_period} dagen:" value_heading: "Waarde" requirement_heading: "Vereiste" visits: "Bezoeken" @@ -2244,8 +2406,15 @@ nl: confirm: 'Bevestiging' dropdown: "Uitklapbaar" site_text: - none: "Kies een type van inhoud om te beginnen met bewerken." + description: "Je kunt alle tekst of jouw forum aanpassen. Begin met zoeken hieronder:" + search: "Zoek voor tekst die je graag wilt bewerken." title: 'Tekst Inhoud' + edit: 'bewerk' + revert: "Maak wijzigingen ongedaan" + revert_confirm: "Weet je zeker dat je de veranderingen ongedaan wilt maken?" + go_back: "Terug naar zoeken" + recommended: "We bevelen je aan die tekst aan te passen naar je eigen ingeving. " + show_overriden: 'Bekijk alleen bewerkte instellingen' site_settings: show_overriden: 'Bekijk alleen bewerkte instellingen' title: 'Instellingen' @@ -2333,8 +2502,8 @@ nl: bad_count_warning: header: "LET OP!" text: "Er zijn vermiste toekennings-voorbeelden. Dit gebeurt als de badge query gebruikers- of bericht-ID's retourneert die niet bestaan. Dit kan onverwachte resultaten veroorzaken op een later tijdstip - kijk a.u.b. uw query goed na." + no_grant_count: "Geen badges om toe te wijzen." grant_count: - zero: "Geen badges om toe te wijzen." one: "1 badge toe te wijzen." other: "%{count} badges toe te wijzen." sample: "Voorbeeld:" @@ -2444,9 +2613,10 @@ nl: mark_tracking: 'm, t Markeer topic als volgen' mark_watching: 'm, w Markeer topic als in de gaten houden' badges: + earned_n_times: + one: "Verdiende deze badge 1 keer" + other: "Verdiende deze badge %{count} keer" title: Badges - allow_title: "kan als titel gebruikt worden" - multiple_grant: "kan meerdere keren toegekend worden" badge_count: one: "1 Badge" other: "%{count} Badges" @@ -2469,97 +2639,6 @@ nl: name: Overige posting: name: Schrijven - badge: - editor: - name: Redacteur - description: Eerste berichtwijziging - basic_user: - name: Basis - description: Toegang verleend tot alle essentiële gemeenschaps-functionaliteit. - member: - name: Lid - description: Toegang verleend tot uitnodigingen - regular: - name: Vaste bezoeker - description: Toegang verleend tot hercategoriseren, hernoemen, gevolgde links en lounge - leader: - name: Leider - description: Toegang verleend tot globaal wijzigen, vastpinnen, sluiten, archiveren, splitsen en samenvoegen - welcome: - name: Welkom - description: Like ontvangen. - autobiographer: - name: Autobiografist - description: Gebruikersprofiel informatie ingevuld - anniversary: - name: Verjaardag - description: Actief lid voor een jaar, heeft tenminste eenmaal iets gepost - nice_post: - name: Prima bericht - description: 10 likes op een post ontvangen. Deze badge kan meerdere keren worden toegekend. - good_post: - name: Goed bericht - description: 25 likes op een post ontvangen. Deze badge kan meerdere keren worden toegekend. - great_post: - name: Fantastisch Bericht - description: 50 likes op een post ontvangen. Deze badge kan meerdere keren worden toegekend. - nice_topic: - name: Leuk Topic - description: 10 likes ontvangen op een topic. Deze badge kan meerdere keren toegewezen worden. - good_topic: - name: Goed Topic - description: 25 likes ontvangen op een topic. Deze badge kan meerdere keren toegewezen worden. - great_topic: - name: Geweldig Topic - description: 50 likes ontvangen op een topic. Deze badge kan meerdere keren toegewezen worden. - nice_share: - name: Leuk Gedeeld - description: Een bericht met 25 unieke bezoekers gedeeld - good_share: - name: Goed Gedeeld - description: Een bericht met 300 unieke bezoekers gedeeld - great_share: - name: Geweldig Gedeeld - description: Een bericht met 1000 unieke bezoekers gedeeld - first_like: - name: Eerste like - description: Hebt een bericht ge-vind-ik-leukt - first_flag: - name: Eerste markering - description: Een bericht gemarkeerd - promoter: - name: Promoter - description: Heeft een gebruiker uitgenodigd - campaigner: - name: Campaigner - description: Heeft 3 leden (trust level 1) uitgenodigd - champion: - name: Kampioen - description: Heeft 5 leden (trust level 2) uitgenodigd - first_share: - name: Eerste deel actie - description: Een bericht gedeeld - first_link: - name: Eerste link - description: Een interne link toegevoegd aan een ander topic - first_quote: - name: Eerste citaat - description: Een gebruiker geciteerd - read_guidelines: - name: Heeft de richtlijnen gelezen - description: Lees de community richtlijnen - reader: - name: Lezer - description: Lees elk bericht in een topic met meer dan 100 berichten. - popular_link: - name: Populaire Link - description: Heeft een externe link geplaatst die 50 keer of vaker is aangeklikt. - hot_link: - name: Zeer Populaire Link - description: Heeft een externe link geplaatst die 300 keer of vaker is aangeklikt - famous_link: - name: Uiterst Populaire Link - description: Heeft een externe link geplaatst die 1000 keer of vaker is aangeklikt google_search: |

    Zoek met Google

    diff --git a/config/locales/client.pl_PL.yml b/config/locales/client.pl_PL.yml index e25fbb600bf..fd308df18d1 100644 --- a/config/locales/client.pl_PL.yml +++ b/config/locales/client.pl_PL.yml @@ -9,7 +9,7 @@ pl_PL: js: number: format: - separator: "." + separator: "," delimiter: "," human: storage_units: @@ -119,6 +119,8 @@ pl_PL: one: "1 rok później" few: "%{count} lata później" other: "%{count} lat później" + previous_month: 'Poprzedni miesiąc' + next_month: 'Następny miesiąc' share: topic: 'udostępnij odnośnik do tego tematu' post: 'wpis #%{postNumber}' @@ -128,6 +130,9 @@ pl_PL: google+: 'udostępnij ten odnośnik na Google+' email: 'wyślij ten odnośnik przez email' action_codes: + split_topic: "podziel ten temat %{when}" + invited_user: "%{who} został zaproszony %{when}" + removed_user: "%{who} został usunięty %{when}" autoclosed: enabled: 'zamknięcie %{when}' disabled: 'otworzenie %{when}' @@ -148,6 +153,19 @@ pl_PL: disabled: 'odlistowanie %{when}' topic_admin_menu: "akcje administratora" emails_are_disabled: "Wysyłanie e-maili zostało globalnie wyłączone przez administrację. Powiadomienia e-mail nie będą dostarczane." + s3: + regions: + us_east_1: "US East (N. Virginia)" + us_west_1: "US West (N. California)" + us_west_2: "US West (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "EU (Ireland)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asia Pacific (Singapore)" + ap_southeast_2: "Asia Pacific (Sydney)" + ap_northeast_1: "Asia Pacific (Tokyo)" + ap_northeast_2: "Asia Pacific (Seoul)" + sa_east_1: "South America (Sao Paulo)" edit: 'edytuj tytuł i kategorię tego tematu' not_implemented: "Bardzo nam przykro, ale ta funkcja nie została jeszcze zaimplementowana." no_value: "Nie" @@ -181,6 +199,8 @@ pl_PL: more: "Więcej" less: "Mniej" never: "nigdy" + every_30_minutes: "co 30 minut" + every_hour: "co godzinę" daily: "dziennie" weekly: "tygodniowo" every_two_weeks: "co dwa tygodnie" @@ -193,6 +213,7 @@ pl_PL: other: "{{count}} znaków" suggested_topics: title: "Sugerowane tematy" + pm_title: "sugerowane wiadomości" about: simple_title: "O stronie" title: "O %{title}" @@ -251,6 +272,7 @@ pl_PL: revert: "Przywróć" failed: "Niepowodzenie" switch_to_anon: "Tryb anonimowy" + switch_from_anon: "Zakończ tryb anonimowy" banner: close: "Zamknij ten baner." edit: "Edytuj ten baner >>" @@ -274,7 +296,7 @@ pl_PL: few: "Ten temat posiada {{count}} wpisy oczekujące na akceptację" other: "Ten temat posiada {{count}} wpisów oczekujących na akceptację" confirm: "Zapisz zmiany" - delete_prompt: "Czy na pewno chcesz usunąć %{username}? Zostaną usunięte wszystkie wpisy utworzone z tego konta oraz zostanie zablokowany powiązany e-mail oraz adres IP." + delete_prompt: "Czy na pewno chcesz usunąć %{username}? To spowoduje usunięcie wszystkich wiadomości, zablokowanie adresu e-mail i adresu IP tego użytkownika." approval: title: "Wpis wymaga zatwierdzenia" description: "Twój nowy wpis został umieszczony w kolejce i pojawi się po zatwierdzeniu przez moderatora. Prosimy o cierpliwość." @@ -319,15 +341,25 @@ pl_PL: few: "%{count} użytkownicy" other: "%{count} użytkowników" groups: + empty: + posts: "Członkowie tej grupy nie opublikowali żadnych postów." + members: "W tej grupie nie ma żadnych członków." + topics: "Członkowie tej grupy nie opublikowali żadnych postów." + add: "Dodaj" + selector_placeholder: "Dodaj członków" + owner: "właściciel" visible: "Grupa jest widoczna dla wszystkich użytkowników" title: one: "grupa" few: "grupy" other: "grupy" members: "Członkowie" + topics: "Tematy" posts: "Wpisów" + mentions: "Wzmianki" + messages: "Wiadomości" alias_levels: - title: "Kto może użyć aliasu tej grupy?" + title: "Kto może wysyłać wiadomości i używać @aliasu tej grupy?" nobody: "Nikt" only_admins: "Tylko administratorzy" mods_and_admins: "Tylko moderatorzy i administratorzy" @@ -336,6 +368,18 @@ pl_PL: trust_levels: title: "Domyślny poziom zaufania przyznawany nowych użytkownikom:" none: "Brak" + notifications: + watching: + title: "Obserwowanie" + tracking: + title: "Śledzenie" + description: "Dostaniesz powiadomienie, gdy ktoś ci odpowie lub wspomni twoją @nazwę, zobaczysz również liczbę odpowiedzi." + regular: + title: "Normalny" + description: "Dostaniesz powiadomienie, gdy ktoś ci odpowie lub wspomni twoją @nazwę." + muted: + title: "Wyciszony" + description: "Nie otrzymasz powiadomień o nowych tematach w tej grupie." user_action_groups: '1': "Przyznane polubienia" '2': "Otrzymane polubienia" @@ -345,7 +389,6 @@ pl_PL: '6': "Odpowiedzi" '7': "Wzmianki" '9': "Cytaty" - '10': "Oznaczone" '11': "Edycje" '12': "Wysłane" '13': "Skrzynka odbiorcza" @@ -355,6 +398,7 @@ pl_PL: all_subcategories: "wszystkie" no_subcategory: "żadne" category: "Kategoria" + category_list: "Wyświetl listę kategorii" reorder: title: "Zmień kolejność kategorii" title_long: "Zmień kolejność listy kategorii" @@ -413,16 +457,14 @@ pl_PL: invited_by: "Zaproszono przez" trust_level: "Poziom zaufania" notifications: "Powiadomienia" + statistics: "Statystyki" desktop_notifications: label: "Powiadomienia systemowe" not_supported: "Powiadomienia nie są wspierane przez tę przeglądarkę. Przepraszamy." perm_default: "Włącz powiadomienia" perm_denied_btn: "Brak uprawnień" - perm_denied_expl: "Wyświetlanie powiadomień jest zablokowane. Użyj ustawień swojej przeglądarki, aby odblokować powiadomienia dla tej domeny." disable: "Wyłącz powiadomienia" - currently_enabled: "(aktualnie włączone)" enable: "Włącz powiadomienia" - currently_disabled: "(aktualnie wyłączone)" each_browser_note: "Uwaga: to ustawienie musisz zmienić w każdej przeglądarce której używasz." dismiss_notifications: "Oznacz jako przeczytane" dismiss_notifications_tooltip: "Oznacz wszystkie powiadomienia jako przeczytane" @@ -446,7 +488,7 @@ pl_PL: tracked_categories: "Śledzone" tracked_categories_instructions: "Będziesz automatycznie śledzić wszystkie nowe tematy w tych kategoriach. Licznik nowych wpisów pojawi się obok tytułu na liście tematów." muted_categories: "Wyciszone" - muted_categories_instructions: "Nie będziesz powiadamiany o niczym dotyczącym nowych tematów w tych kategoriach, i nie będą się one pojawiać na karcie nieprzeczytanych." + muted_categories_instructions: "Nie będziesz powiadamiany o nowych tematach w tych kategoriach. Nie pojawią się na liście nieprzeczytanych." delete_account: "Usuń moje konto" delete_account_confirm: "Czy na pewno chcesz usunąć swoje konto? To nieodwracalne!" deleted_yourself: "Twoje konto zostało usunięte." @@ -456,6 +498,7 @@ pl_PL: users: "Użytkownicy" muted_users: "Uciszeni" muted_users_instructions: "Wstrzymaj powiadomienia od tych użytkowników." + muted_topics_link: "Pokaż wyciszone tematy" staff_counters: flags_given: "uczynnych oflagowań" flagged_posts: "oflagowane wpisy" @@ -464,8 +507,15 @@ pl_PL: warnings_received: "otrzymanych ostrzeżeń" messages: all: "Wszystkie" - mine: "Moje" - unread: "Nieprzeczytane" + inbox: "Skrzynka odbiorcza" + sent: "Wysłane" + archive: "Archiwum" + groups: "Moje grupy" + bulk_select: "Zaznacz wiadomości" + move_to_inbox: "Przenieś do skrzynki odbiorczej" + move_to_archive: "Archiwum" + failed_to_move: "Nie udało się przenieść zaznaczonych wiadomości (prawdopodobnie wystąpił problem z Twoim połączeniem)" + select_all: "Zaznacz wszystko" change_password: success: "(email wysłany)" in_progress: "(email wysyłany)" @@ -510,10 +560,11 @@ pl_PL: ok: "Otrzymasz potwierdzenie emailem" invalid: "Podaj poprawny adres email" authenticated: "Twój email został potwierdzony przez {{provider}}" + frequency_immediately: "Wyślemy powiadomienie jeśli wskazana rzecz nie została jeszcze przez Ciebie przeczytana." frequency: - zero: "Otrzymasz email natychmiast jeśli nie widziałeś rzeczy na temat której wysyłamy email." - one: "Otrzymasz e-mail jeśli nie widzieliśmy Cię w ciągu ostatniej minuty." - other: "Otrzymasz e-mail jeśli nie widzieliśmy Cię w ciągu ostatnich {{count}} minut." + one: "Otrzymasz e-mail tylko jeśli nie widzieliśmy Cię w ciągu ostatniej minuty." + few: "Otrzymasz e-mail tylko jeśli nie widzieliśmy Cię w ciągu ostatnich {{count}} minut." + other: "Otrzymasz e-mail tylko jeśli nie widzieliśmy Cię w ciągu ostatnich {{count}} minut." name: title: "Pełna nazwa" instructions: "Twoja pełna nazwa (opcjonalna)" @@ -549,8 +600,16 @@ pl_PL: title: "Odznaka karty użytkownika" website: "Strona internetowa" email_settings: "Email" + like_notification_frequency: + always: "Zawsze" + never: "Nigdy" + email_previous_replies: + always: "zawsze" + never: "nigdy" email_digests: title: "Gdy nie odwiedzam strony, wysyłaj e-mail z podsumowaniem aktywności:" + every_30_minutes: "co 30 minut" + every_hour: "co godzinę" daily: "codziennie" every_three_days: "co trzy dni" weekly: "co tydzień" @@ -585,7 +644,10 @@ pl_PL: user: "Zaproszony(-a) użytkownik(-czka)" sent: "Wysłane" none: "Nie ma żadnych zaproszeń do wyświetlenia." - truncated: "Pokaż pierwsze {{count}} zaproszeń." + truncated: + one: "Wyświetlanie pierwszego zaproszenia." + few: "Wyświetlanie {{count}} pierwszych zaproszeń." + other: "Wyświetlanie {{count}} pierwszych zaproszeń." redeemed: "Cofnięte zaproszenia" redeemed_tab: "Przyjęte" redeemed_tab_with_count: "Zrealizowane ({{count}})" @@ -620,6 +682,15 @@ pl_PL: same_as_email: "Twoje hasło jest takie samo jak twój e-mail." ok: "Twoje hasło jest poprawne." instructions: "Co najmniej %{count} znaków." + summary: + title: "Podsumowanie" + stats: "Statystyki" + top_replies: "Najlepsze odpowiedzi" + more_replies: "Więcej odpowiedzi" + top_topics: "Najlepsze tematy" + more_topics: "Więcej tematów" + top_badges: "Najlepsze odznaki" + more_badges: "Więcej odznak" associated_accounts: "Powiązane konta" ip_address: title: "Ostatni adres IP" @@ -645,11 +716,13 @@ pl_PL: server: "błąd serwera" forbidden: "Brak dostępu" unknown: "Błąd" + not_found: "Nie znaleziono strony" desc: network: "Sprawdź swoje połączenie." network_fixed: "Chyba już w porządku." server: "Kod błędu: {{status}}" forbidden: "Nie możesz obejrzeć tego zasobu." + not_found: "Ups, aplikacja próbowała otworzyć URL który nie istnieje." unknown: "Coś poszło nie tak." buttons: back: "Cofnij" @@ -660,8 +733,10 @@ pl_PL: logout: "Nastąpiło wylogowanie." refresh: "Odśwież" read_only_mode: - enabled: "Aktywowani tryb tylko-do-odczytu. Możesz nadal przeglądać serwis, ale operacje zmieniające stan i treść mogą nie działać." login_disabled: "Logowanie jest zablokowane, gdy strona jest w trybie tylko do odczytu." + too_few_topics_and_posts_notice: "Pora rozruszać dyskusję! Aktualnie istnieje %{currentTopics} / %{requiredTopics} tematów i %{currentPosts} / %{requiredPosts} wpisów. Odwiedzający potrzebują więcej tematów i konwersacji do czytania i pisania na ich temat." + too_few_topics_notice: "Pora rozruszać dyskusję! Aktualnie istnieje %{currentTopics} / %{requiredTopics} tematów. Odwiedzający potrzebują więcej tematów i konwersacji do czytania i pisania na ich temat." + too_few_posts_notice: "Pora rozruszać dyskusję! Aktualnie istnieje %{currentPosts} / %{requiredPosts} wpisów. Odwiedzający potrzebują więcej tematów i konwersacji do czytania i pisania na ich temat." learn_more: "dowiedz się więcej…" year: 'rok' year_desc: 'tematy dodane w ciągu ostatnich 365 dni' @@ -679,10 +754,16 @@ pl_PL: one: odpowiedź few: odpowiedzi other: odpowiedzi + signup_cta: + sign_up: "Rejestracja" + hide_session: "Przypomnij mi jutro" + hide_forever: "nie, dziękuję" + hidden_for_session: "Ok, zapytamy jutro. Pamiętaj, że konto możesz w każdej chwili założyć klikając na 'Logowanie'." + intro: "Hej! :heart_eyes: Wygląda na to, że zainteresowała Cię dyskusja, ale nie posiadasz jeszcze konta." + value_prop: "Jeśli stworzysz konto, zapamiętamy przeczytane przez Ciebie wpisy i tematy, dzięki czemu zawsze powrócisz do odpowiedniego miejsca. Otrzymasz też powiadomienia o nowych wpisach. Dodatkowo możliwe będzie polubienie ciekawych wpisów :heartbeat:" summary: enabled_description: "Przeglądasz podsumowanie tego tematu: widoczne są jedynie najbardziej wartościowe wpisy zdaniem uczestników. " - description: "Istnieją {{count}} odpowiedzi." - description_time: "Istnieją {{count}} odpowiedzi z czasem czytania oszacowanym na {{readingTime}} minut." + description: "Jest {{replyCount}} odpowiedzi." enable: 'Podsumuj ten temat' disable: 'Pokaż wszystkie wpisy' deleted_filter: @@ -736,6 +817,9 @@ pl_PL: admin_not_allowed_from_ip_address: "Nie możesz się zalogować jako admin z tego adresu IP." resend_activation_email: "Kliknij tutaj, aby ponownie wysłać email z aktywacją konta." sent_activation_email_again: "Wysłaliśmy do ciebie kolejny email z aktywacją konta na {{currentEmail}}. Zanim dotrze, może minąć kilka minut; pamiętaj, żeby sprawdzić folder ze spamem." + to_continue: "Zaloguj się" + preferences: "Musisz się zalogować, aby zmieniać swoje ustawienia." + forgot: "Nie pamiętam konta" google: title: "przez Google" message: "Uwierzytelnianie przy pomocy konta Google (upewnij się, że blokada wyskakujących okienek nie jest włączona)" @@ -758,15 +842,23 @@ pl_PL: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + more_emoji: "więcej…" + options: "Opcje" + whisper: "szept" add_warning: "To jest oficjalne ostrzeżenie." + toggle_whisper: "Przełącz szept" posting_not_on_topic: "W którym temacie chcesz odpowiedzieć?" saving_draft_tip: "zapisuję..." saved_draft_tip: "zapisano" saved_local_draft_tip: "zapisano lokalnie" similar_topics: "Twój temat jest podobny do…" drafts_offline: "szkice offline" + group_mentioned: "Używając {{group}} powiadamiasz grupę {{count}} osób." error: title_missing: "tytuł jest wymagany" title_too_short: "tytuł musi zawierać co najmniej {{min}} znaków" @@ -789,7 +881,7 @@ pl_PL: show_edit_reason: "(dodaj powód edycji)" reply_placeholder: "Pisz w tym miejscu. Wspierane formatowanie to Markdown, BBCode lub HTML. Możesz też przeciągnąć tu obrazek." view_new_post: "Zobacz Twój nowy wpis." - saving: "Zapisuję…" + saving: "Zapisywanie" saved: "Zapisano!" saved_draft: "Posiadasz zachowany szkic wpisu. Kliknij tu aby wznowić jego edycję." uploading: "Wczytuję…" @@ -804,6 +896,7 @@ pl_PL: link_description: "wprowadź tutaj opis odnośnika" link_dialog_title: "Wstaw odnośnik" link_optional_text: "opcjonalny tytuł" + link_placeholder: "http://example.com \"opcjonalny tekst\"" quote_title: "Cytat" quote_text: "Cytat" code_title: "Tekst sformatowany" @@ -816,10 +909,11 @@ pl_PL: heading_title: "Nagłówek" heading_text: "Nagłówek" hr_title: "Pozioma linia" - undo_title: "Cofnij" - redo_title: "Ponów" help: "Pomoc formatowania Markdown" toggler: "ukryj lub pokaż panel kompozytora tekstu" + modal_ok: "OK" + modal_cancel: "Anuluj" + cant_send_pm: "Przepraszamy, niestety nie możesz wysłać prywatnej wiadomości do %{username}." admin_options_title: "Opcjonalne ustawienia obsługi dla tego tematu" auto_close: label: "Automatycznie zamykaj tematy po:" @@ -836,11 +930,16 @@ pl_PL: more: "pokaż starsze powiadomienia" total_flagged: "wszystkie oflagowane wpisy" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_many: + one: "

    {{username}}, {{username2}} oraz 1 inna osoba {{description}}

    " + few: "

    {{username}}, {{username2}} i {{count}} innych osób {{description}}

    " + other: "

    {{username}}, {{username2}} i {{count}} innych osób {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -848,6 +947,10 @@ pl_PL: moved_post: "

    {{username}} przenosi {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Otrzymujesz '{{description}}'

    " + group_message_summary: + one: "

    masz {{count}} wiadomość w skrzynce odbiorczej {{group_name}}

    " + few: "

    masz {{count}} wiadomości w skrzynce odbiorczej {{group_name}}

    " + other: "

    masz {{count}} wiadomości w skrzynce odbiorczej {{group_name}}

    " alt: mentioned: "Wywołanie przez" quoted: "Cytowanie przez" @@ -864,6 +967,7 @@ pl_PL: granted_badge: "Przyznanie odznaki" popup: mentioned: '{{username}} wspomina o tobie w "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} wspomniał o Tobie w "{{topic}}" - {{site_title}}' quoted: '{{username}} cytuje cie w "{{topic}}" - {{site_title}}' replied: '{{username}} odpowiada na twój wpis w "{{topic}}" - {{site_title}}' posted: '{{username}} pisze w "{{topic}}" - {{site_title}}' @@ -875,17 +979,26 @@ pl_PL: from_my_computer: "Z mojego urządzenia" from_the_web: "Z Internetu" remote_tip: "link do obrazu" - remote_tip_with_attachments: "odnośnik do obrazu lub pliku ({{authorized_extensions}})" + remote_tip_with_attachments: "link do obrazu lub pliku {{authorized_extensions}}" local_tip: "wybierz obrazy ze swojego urządzenia" - local_tip_with_attachments: "wybierz obrazy lub pliki ze swojego urządzenia ({{authorized_extensions}})" + local_tip_with_attachments: "wybierz obrazy lub pliki ze swojego urządzenia {{authorized_extensions}}" hint: "(możesz także upuścić plik z katalogu komputera w okno edytora)" hint_for_supported_browsers: "możesz też przeciągać lub wklejać grafiki do edytora" uploading: "Wgrywanie" select_file: "Wybierz plik" image_link: "odnośnik do którego Twój obraz będzie kierował" search: + sort_by: "Sortuj po" + relevance: "Trafność" + latest_post: "Aktualne wpisy" + most_viewed: "Popularne" + most_liked: "Lubiane" select_all: "Zaznacz wszystkie" clear_all: "Wyczyść wszystkie" + result_count: + one: "1 wynik dla \"{{term}}\"" + few: "{{count}} wyniki dla \"{{term}}\"" + other: "{{count}} wyników dla \"{{term}}\"" title: "szukaj tematów, wpisów, użytkowników lub kategorii" no_results: "Brak wyników wyszukiwania" no_more_results: "Nie znaleziono więcej wyników." @@ -904,13 +1017,15 @@ pl_PL: current_user: 'idź do swojej strony użytkowanika' topics: bulk: + unlist_topics: "Ukryj tematy" reset_read: "Wyzeruj przeczytane" delete: "Usuń tematy" - dismiss_posts: "Wyczyść liczniki wpisów" - dismiss_posts_tooltip: "Wyczyść liczniki nieprzeczytanych wpisów w tych tematach, ale informuj mnie jeśli pojawią się w nich nowe wpisy w przyszłości." - dismiss_topics: "Wyczyść status termatów" - dismiss_topics_tooltip: "Nie pokazuj tych tematów na mojej liście nieprzeczytanych gdy pojawią się w nich nowe wpisy." - dismiss_new: "Wyczyść nieprzeczytane" + dismiss: "Wyczyść" + dismiss_read: "Wyczyść nieprzeczytane" + dismiss_button: "Wyczyść…" + dismiss_tooltip: "Wyczyść nowe wpisy lub przestań śledzić tematy" + also_dismiss_topics: "Przestać śledzić wskazane tematy. Nie chcę, aby pojawiały się w zakładce nieprzeczytane." + dismiss_new: "Wyczyść nowe" toggle: "włącz grupowe zaznaczanie tematów" actions: "Operacje grupowe" change_category: "Zmień kategorię" @@ -934,10 +1049,7 @@ pl_PL: top: "Brak najlepszych tematów." search: "Brak wyników wyszukiwania." educate: - new: '

    Pojawią się tu nowe tematy.

    Domyślnie, tematy są traktowane jako nowe jeśli zostały utworzone w ciągu ostatnich 2 dni.

    Możesz to zmienić w swoich ustawieniach.

    ' - unread: '

    Pojawią się tu tematy oznaczone licznikiem 1 nieprzeczytanych wpisów.

    - -

    Domyślnie, jako nieprzeczytane rozumiane są tematy:

    • twojego autorstwa
    • te w których są twoje odpowiedzi
    • czytane przez ciebie dłużej niż 4 minuty

    Znajdą się tu też te, którym ręcznie przyznano status Śledzony lub Obserwowany przyciskiem znajdującym się na końcu każdego tematu.

    Możesz zmienić te zachowania w swoich ustawieniach.

    ' + new: '

    Nowe tematy będą pojawiać się tutaj.

    Domyślnie tematy są określane jako nowe i będą oznaczone jakonowe jeśli były stworzone w ciągu ostatnich 2 dni.

    Odwiedź swoje ustawienia by to zmienić.

    ' bottom: latest: "Nie ma więcej najnowszych tematów." hot: "Nie ma więcej gorących tematów." @@ -957,6 +1069,12 @@ pl_PL: create: 'Nowy temat' create_long: 'Utwórz nowy temat' private_message: 'Napisz wiadomość' + archive_message: + help: 'Przenieś wiadomość do archiwum' + title: 'Archiwum' + move_to_inbox: + title: 'Przenieś do skrzynki odbiorczej' + help: 'Przenieś wiadomość z powrotem do skrzynki odbiorczej' list: 'Tematy' new: 'nowy temat' unread: 'nieprzeczytane' @@ -1012,6 +1130,7 @@ pl_PL: auto_close_title: 'Ustawienia automatycznego zamykania' auto_close_save: "Zapisz" auto_close_remove: "Nie zamykaj automatycznie tego tematu" + auto_close_immediate: "Ostatni wpis w tym temacie został zamieszczony %{hours} godzin temu, więc zostanie on natychmiastowo zamknięty." progress: title: postęp tematu go_top: "początek" @@ -1061,7 +1180,7 @@ pl_PL: description: "Nie będziesz otrzymywać powiadomień dotyczących tej dyskusji." muted: title: "Wyciszenie" - description: "Nie będzie jakichkolwiek powiadomień dotyczących tego tematu i nie będzie się on pojawiać na karcie nieprzeczytanych." + description: "Nie otrzymasz powiadomień o nowych wpisach w tym temacie. Nie pojawią się na liście nieprzeczytanych" actions: recover: "Przywróć temat" delete: "Usuń temat" @@ -1103,25 +1222,26 @@ pl_PL: unpin_until: "Odepnij ten temat z początku kategorii {{categoryLink}} lub poczekaj do %{until}." pin_note: "Użytkownicy mogą przypinać tematy dla samych siebie." pin_validation: "Przypięcie tego tematu wymaga podania daty." + not_pinned: "Brak przypiętych tematów w {{categoryLink}}." already_pinned: - zero: "Brak przypiętych tematów w {{categoryLink}}." - one: "Tematy przypięte w {{categoryLink}}: 1." - other: "Tematy przypięte w {{categoryLink}}: {{count}}." + one: "Tematy przypięte w {{categoryLink}}: 1" + few: "Tematy przypięte w {{categoryLink}}: {{count}}" + other: "Tematy przypięte w {{categoryLink}}: {{count}}" pin_globally: "Wyróżnij ten temat przypinając go na górze wszystkich list do" confirm_pin_globally: "Czy na pewno chcesz globalnie przypiąć kolejny temat? Masz już {{count}} przypiętych tematów -- zbyt wiele może obniżyć czytelność innych aktywnych tematów." unpin_globally: "Usuń wyróżnienie dla tego tematu odpinając go z początku wszystkich list." unpin_globally_until: "Usuń wyróżnienie dla tego tematu odpinając go z początku wszystkich list lub poczekaj do %{until}." global_pin_note: "Użytkownicy mogą przypinać tematy dla samych siebie." + not_pinned_globally: "Brak przypiętych globalnie tematów." already_pinned_globally: - zero: "Brak przypiętych globalnie tematów." one: "Tematy przypięte globalnie: 1." - other: "Tematy przypięte globalnie: {{count}}." + few: "Tematy przypięte globalnie: {{count}}." + other: "Tematy przypięte globalnie: {{count}}." make_banner: "Ustaw ten temat jako baner wyświetlany na górze każdej strony." remove_banner: "Usuń ten temat jako baner wyświetlany na górze każdej strony." banner_note: "Użytkownicy mogą usunąć baner zamykając go przyciskiem. Tylko jeden temat może być banerem w danej chwili." - already_banner: - zero: "Baner nie jest obecnie ustawiony." - one: "Baner jest ustawiony." + no_banner_exists: "Baner nie jest obecnie ustawiony." + banner_exists: "Baner jest obecnie ustawiony." inviting: "Zapraszam…" automatically_add_to_groups_optional: "To zaproszenie daje dostęp do tych grup: (opcjonalne, tylko dla admina)" automatically_add_to_groups_required: "To zaproszenie daje dostęp do tych grup: (Wymagane, tylko dla admina)" @@ -1237,10 +1357,11 @@ pl_PL: one: "1 osoba polubiła ten wpis" few: "{{count}} osoby polubiły ten wpis" other: "{{count}} osób polubiło ten wpis" + has_likes_title_only_you: "polubiony wpis" has_likes_title_you: - zero: "polubiono ten wpis" - one: "wpis polubiony przez ciebie i 1 inną osobę" - other: "wpis polubiony przez ciebie i {{count}} innych osób" + one: "ty i 1 inna osoba polubiliście ten wpis" + few: "ty i {{count}} inne osoby polubiliście ten wpis" + other: "ty i {{count}} innych osób polubiło ten wpis" errors: create: "Przepraszamy, podczas tworzenia twojego wpisu wystąpił błąd. Spróbuj ponownie." edit: "Przepraszamy, podczas edytowania twojego wpisu wystąpił błąd. Spróbuj ponownie." @@ -1258,9 +1379,7 @@ pl_PL: no_value: "Nie, pozostaw" yes_value: "Tak, porzuć" via_email: "ten wpis został dodany emailem" - whisper: "ten wpis jest prywatną notatką dla moderatorów" - wiki: - about: "to wpis typu Wiki: zwykli użytkownicy mogą go edytować" + whisper: "ten wpis jest prywatnym szeptem do moderatorów" archetypes: save: 'Opcje zapisu' controls: @@ -1289,6 +1408,7 @@ pl_PL: revert_to_regular: "Wyłącz kolor moderatora" rebake: "Odśwież HTML" unhide: "Wycofaj ukrycie" + change_owner: "Zmiana właściciela" actions: flag: 'Oflaguj' defer_flags: @@ -1311,17 +1431,14 @@ pl_PL: like: "Cofnij" vote: "Cofnij głos" people: - off_topic: "{{icons}} oznaczyli jako nie-na-temat" - spam: "{{icons}} oznaczyli jako spam" - spam_with_url: "{{icons}} oznacza to jako spam" - inappropriate: "{{icons}} oznaczyli jako niewłaściwe" - notify_moderators: "{{icons}} powiadomiło moderatorów" - notify_moderators_with_url: "{{icons}} powiadomiło moderatorów" - notify_user: "{{icons}} wysłana wiadomość" - notify_user_with_url: "{{icons}} wysłana wiadomość" - bookmark: "{{icons}} dodało to do zakładek" - like: "{{icons}} lubi to" - vote: "{{icons}} zagłosowało za tym" + off_topic: "Oflagowano jako nie-na-temat" + spam: "oznacz jako spam" + inappropriate: "Oflagowano jako nieodpowiednie" + notify_moderators: "Powiadomiono moderatorów" + notify_user: "Wysłano wiadomość" + bookmark: "dodaj do zakładek" + like: "polubiło to" + vote: "zagłosowało" by_you: off_topic: "Oznaczono jako nie-na-temat" spam: "Oflagowano jako spam" @@ -1397,10 +1514,6 @@ pl_PL: one: "1 osoba zagłosowała za tym wpisem" few: "{{count}} osoby zagłosowały za tym wpisem" other: "{{count}} osób zagłosowało za tym wpisem" - edits: - one: 1 edycja - other: "Liczba edycji: {{count}}" - zero: brak edycji delete: confirm: one: "Jesteś pewny(-a), że chcesz usunąć ten wpis?" @@ -1482,19 +1595,18 @@ pl_PL: notifications: watching: title: "Obserwuj wszystko" - description: "Będziesz automatycznie śledzić wszystkie nowe tematy w tych kategoriach. Dostaniesz powiadomienie o każdym nowym wpisie i temacie. Liczba nowych odpowiedzi będzie wyświetlana na liście tematów." + description: "Będziesz automatycznie śledzić wszystkie nowe tematy w tych kategoriach. Otrzymasz powiadomienie o każdym nowym wpisie i temacie. Wyświetlimy liczbę nowych odpowiedzi na liście tematów." tracking: title: "Śledzona" - description: "Będziesz automatycznie śledzić wszystkie tematy w tych kategoriach. Llicznik nowych odpowiedzi pojawi się obok ich tytułów." + description: "Będziesz automatycznie śledzić wszystkie tematy w tych kategoriach. Otrzymasz powiadomienie jeśli ktoś wspomni twój @login lub odpowie na twój wpis. Licznik nowych odpowiedzi pojawi się na liście tematów." regular: title: "Normalny" description: "Dostaniesz powiadomienie jedynie, gdy ktoś wspomni twoją @nazwę lub odpowie na twój wpis." muted: title: "Wyciszone" - description: "Nie będziesz powiadamiany o nowych tematach w tych kategoriach i nie będą się one pojawiać w karcie Nieprzeczytane." + description: "Nie otrzymasz powiadomień o nowych tematach w tych kategoriach. Nie pojawią się na liście nieprzeczytanych." flagging: title: 'Dziękujemy za pomoc w utrzymaniu porządku w naszej społeczności!' - private_reminder: 'oflagowania są poufne i widoczne jedynie dla obsługi serwisu' action: 'Oflaguj wpis' take_action: "Podejmij działanie" notify_action: 'Wiadomość' @@ -1545,7 +1657,7 @@ pl_PL: help: "Temat nie jest przypięty w ramach twojego konta. Będzie wyświetlany w normalnej kolejności." pinned_globally: title: "Przypięty globalnie" - help: "Temat przypięty globalnie. Będzie wyświetlany na początku wszystkich list." + help: "Ten temat jest przypięty globalnie. Będzie wyświetlany na początku głównej listy oraz swojej kategorii." pinned: title: "Przypięty" help: "Temat przypięty dla twojego konta. Będzie wyświetlany na początku swojej kategorii." @@ -1585,9 +1697,10 @@ pl_PL: with_topics: "%{filter} tematy" with_category: "%{filter} tematy w %{category} " latest: - title: - zero: "Aktualne" + title: "Aktualne" + title_with_count: one: "Aktualne (1)" + few: "Aktualne ({{count}})" other: "Aktualne ({{count}})" help: "tematy z ostatnimi wpisami" hot: @@ -1604,22 +1717,26 @@ pl_PL: title_in: "Kategoria - {{categoryName}}" help: "wszystkie tematy zgrupowane przez kategorię" unread: - title: - zero: "Nieprzeczytane" + title: "Nieprzeczytane" + title_with_count: one: "Nieprzeczytane (1)" + few: "Nieprzeczytane ({{count}})" other: "Nieprzeczytane ({{count}})" help: "obserwowane lub śledzone tematy z nieprzeczytanymi wpisami" lower_title_with_count: one: "1 nieprzeczytany" + few: "{{count}} nieprzeczytane" other: "{{count}} nieprzeczytanych" new: lower_title_with_count: - one: "1 nowy" + one: "1 nowa" + few: "{{count}} nowe" other: "{{count}} nowych" lower_title: "nowe" - title: - zero: "Nowe" + title: "Nowe" + title_with_count: one: "Nowe (1)" + few: "Nowe ({{count}})" other: "Nowe ({{count}})" help: "tematy dodane w ciągu ostatnich kilku dni" posted: @@ -1629,9 +1746,10 @@ pl_PL: title: "Zakładki" help: "tematy dodane do zakładek" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" + few: "{{categoryName}} ({{count}})" other: "{{categoryName}} ({{count}})" help: "najnowsze tematy w kategorii {{categoryName}}" top: @@ -1797,15 +1915,24 @@ pl_PL: delete_confirm: "Usunąć tę grupę?" delete_failed: "Nie można usunąć grupy. Jeżeli jest to grupa automatyczna, nie może zostać zniszczona." delete_member_confirm: "Usunąć '%{username}' z grupy '%{group}' ?" + delete_owner_confirm: "Usunąć status właściciela dla '%{username}'?" name: "Nazwa" add: "Dodaj" add_members: "Dodaj członków" custom: "Niestandardowe" + bulk_complete: "Użytkownicy zostali dodani do wskazanej grupy." + bulk: "Dodaj więcej do grupy" + bulk_paste: "Podaj listę nazw użytkowników lub adresów e-mail, każdy w oddzielnej linii:" + bulk_select: "(wybierz grupę)" automatic: "Automatyczne" automatic_membership_email_domains: "Użytkownicy rejestrujący się przy pomocy adresu z tej listy zostaną automatycznie przypisani do tej grupy." automatic_membership_retroactive: "Zastosuj tę regułę domenową do już istniejących użytkowników." default_title: "Domyślny tytuł użytkowników należących do tej grupy" primary_group: "Automatycznie ustawiaj jako główną grupę" + group_owners: Właściciele + add_owners: Dodaj właścicieli + incoming_email: "Niestandardowy adres poczty przychodzącej" + incoming_email_placeholder: "podaj adres e-mail" api: generate_master: "Generuj Master API Key" none: "Nie ma teraz aktywnych kluczy API." @@ -1879,11 +2006,9 @@ pl_PL: is_disabled: "Przywracanie jest zablokowane w ustawieniach." label: "Przywróć" title: "Przywróć kopię zapasową" - confirm: "Czy na pewno chcesz przywrócić tą kopię zapasową?" rollback: label: "Wycofaj" title: "Wycofaj bazę danych do poprzedniego poprawnego stanu" - confirm: "Czy na pewno chcesz przywrócić bazę danych do poprzedniego poprawnego stanu?" export_csv: user_archive_confirm: "Czy na pewno chcesz pobrać swoje wszystkie wpisy?" success: "Rozpoczęto eksport: otrzymasz wiadomość, gdy proces zostanie zakończony." @@ -1934,6 +2059,14 @@ pl_PL: color: "Kolor" opacity: "Widoczność" copy: "Kopiuj" + email_templates: + title: "Szablony email" + subject: "Temat" + multiple_subjects: "Ten szablon e-mail zawiera wiele tematów." + body: "Treść" + none_selected: "Aby rozpocząć edycję, wybierz szablon wiadomości e-mail. " + revert: "Cofnij zmiany" + revert_confirm: "Czy na pewno chcesz wycofać swoje zmiany?" css_html: title: "CSS, HTML" long_title: "Personalizacja kodu CSS i HTML" @@ -1978,18 +2111,16 @@ pl_PL: love: name: 'polubienie' description: "Kolor przycisku polub" - wiki: - name: 'wiki' - description: "Kolor tła wpisów typu wiki." email: - title: "Email" settings: "Ustawienia" - all: "Wszystkie" + preview_digest: "Pokaż zestawienie aktywności" sending_test: "Wysyłanie testowego emaila…" error: "BŁAD - %{server_error}" test_error: "Wystąpił problem podczas wysyłania testowego maila. Sprawdź ustawienia poczty, sprawdź czy Twój serwer nie blokuje połączeń pocztowych i spróbuj ponownie." sent: "Wysłane" skipped: "Pominięte" + received: "Otrzymane" + rejected: "Odrzucone" sent_at: "Wysłany na" time: "Czas" user: "Użytkownik" @@ -1999,7 +2130,6 @@ pl_PL: send_test: "Wyślij email testowy" sent_test: "wysłany!" delivery_method: "Metoda Dostarczenia" - preview_digest: "Pokaż zestawienie aktywności" preview_digest_desc: "Podgląd treści zestawienia wysyłanego e-mailem do nieaktywnych użytkowników." refresh: "Odśwież" format: "Format" @@ -2008,6 +2138,20 @@ pl_PL: last_seen_user: "Ostatnia " reply_key: "Klucz odpowiedzi" skipped_reason: "Powód pominięcia" + incoming_emails: + from_address: "Od" + to_addresses: "Do" + subject: "Temat" + error: "Błąd" + modal: + error: "Błąd" + subject: "Temat" + body: "Treść" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + error_placeholder: "Błąd" logs: none: "Nie znaleziono logów." filters: @@ -2026,6 +2170,7 @@ pl_PL: ip_address: "IP" topic_id: "ID tematu" post_id: "ID wpisu" + category_id: "ID kategorii" delete: 'Usuń' edit: 'Edytuj' save: 'Zapisz' @@ -2066,6 +2211,11 @@ pl_PL: impersonate: "udawanie użytkownika" anonymize_user: "anonimizuj użytkownika" roll_up: "zwiń bloki IP" + change_category_settings: "zmiana ustawień kategorii" + delete_category: "Usuń kategorię" + create_category: "Dodaj nową kategorię" + block_user: "zablokuj użytkownika" + unblock_user: "odblokuj użytkownika" screened_emails: title: "Ekranowane emaile" description: "Kiedy ktoś próbuje założyć nowe konto, jego adres email zostaje sprawdzony i rejestracja zostaje zablokowana, lub inna akcja jest podejmowana." @@ -2134,9 +2284,9 @@ pl_PL: pending: 'Użytkownicy oczekujący na akceptację' newuser: 'Użytkownicy na 0 poziomie zaufania (Nowi)' basic: 'Użytkownicy na 1 poziomie zaufania (Podstawowi)' - regular: 'Użytkownicy na 2 poziomie zaufania (Zwyczajni)' - leader: 'Użytkownicy na 3 poziomie zaufania (Regularni)' - elder: 'Użytkownicy na 4 poziomie zaufania (Weterani)' + member: 'Użytkownicy na 2 poziomie zaufania (Zwyczajni)' + regular: 'Użytkownicy na 3 poziomie zaufania (Regularni)' + leader: 'Użytkownicy na 4 poziomie zaufania (Weterani)' staff: "Zespół" admins: 'Administratorzy' moderators: 'Moderatoratorzy' @@ -2238,6 +2388,7 @@ pl_PL: deactivate_failed: "Wystąpił problem przy deaktywacji konta użytkownika." unblock_failed: 'Wystąpił problem podczaj odblokowania użytkownika.' block_failed: 'Wystąpił problem podczas blokowania użytkownika.' + block_accept: 'Tak, zablokuj tego użytkownika' deactivate_explanation: "Wymusza ponowne potwierdzenie adresu email tego konta." suspended_explanation: "Zawieszony użytkownik nie może się logować." block_explanation: "Zablokowany użytkownik nie może tworzyć wpisów ani zaczynać tematów." @@ -2251,7 +2402,7 @@ pl_PL: unlock_trust_level: "Odblokuj poziom zaufania" tl3_requirements: title: "Wymagania dla osiągnięcia 3. poziomu zaufania" - table_title: "W ciągu ostatnich 100 dni:" + table_title: "W ciągu ostatnich %{time_period} dni:" value_heading: "Wartość" requirement_heading: "Wymaganie" visits: "Odwiedziny" @@ -2312,8 +2463,15 @@ pl_PL: confirm: 'Potwierdzenie' dropdown: "Lista rozwijana" site_text: - none: "Aby rozpocząć edycję, wybierz typ treści. " + description: "Możesz dostosować dowolny tekst na swoim forum. Rozpocznij wyszukując poniżej:" + search: "Znajdź etykietę lub tekst który chcesz zmienić" title: 'Kontekst' + edit: 'edytuj' + revert: "Cofnij zmiany" + revert_confirm: "Czy na pewno chcesz wycofać swoje zmiany?" + go_back: "Wróć do wyszukiwania" + recommended: "Zalecamy zmianę poniższego tekstu, aby lepiej odpowiadał Twoim potrzebom:" + show_overriden: 'Pokaż tylko nadpisane' site_settings: show_overriden: 'Pokaż tylko nadpisane' title: 'Ustawienia' @@ -2401,9 +2559,10 @@ pl_PL: bad_count_warning: header: "UWAGA!" text: "Brakuje przykładowych wyników. Zapytanie odznaki zwraca nieistniejące ID użytkowników lub wpisów. Może to spowodować nieoczekiwane rezultaty w przyszłości – sprawdź ponownie swoje zapytanie. " + no_grant_count: "Brak odznak do przyznania." grant_count: - zero: "Brak odznak do przyznania." one: "1 odznaka do przyznania." + few: "%{count} odznaki do przyznania." other: "%{count} odznak do przyznania." sample: "Podgląd:" grant: @@ -2512,9 +2671,11 @@ pl_PL: mark_tracking: 'm, t śledź temat' mark_watching: 'm, w śledź wszystko w temacie' badges: + earned_n_times: + one: "Otrzymano tą odznakę 1 raz" + few: "Otrzymano tą odznakę %{count} razy" + other: "Otrzymano tą odznakę %{count} razy" title: Odznaki - allow_title: "może być użyta jako tytuł" - multiple_grant: "może być przyznana wielokrotnie" badge_count: one: "1 odznaka" few: "%{count} odznaki" @@ -2540,97 +2701,6 @@ pl_PL: name: Inne posting: name: Wpisy - badge: - editor: - name: Edytor - description: Pierwsza edycja - basic_user: - name: Podstawowy - description: Przyznano wszystkie podstawowe funkcje - member: - name: Zwykły - description: Przyznano zaproszenia - regular: - name: Regularny - description: Przyznano zmianę kategorii, tytułu, wyłączenie nofollow linków oraz Salon - leader: - name: Weteran - description: Przyznano możliwość edycji, przypinania, zamykania, archiwizacji, podziału i scalania - welcome: - name: Powitanie - description: Otrzymano polubienie - autobiographer: - name: Autobiograf - description: Wypełnienie profilu użytkownika - anniversary: - name: Rocznica - description: Aktywność przez rok, co najmniej jeden wpis - nice_post: - name: Niezły wpis - description: Otrzymano 10 polubień za wpis. Ta odznaka może być przyznawana wielokrotnie - good_post: - name: Dobry wpis - description: Otrzymano 25 polubień za wpis. Ta odznaka może być przyznawana wielokrotnie - great_post: - name: Wspaniały wpis - description: Otrzymano 50 polubień za wpis. Ta odznaka może być przyznawana wielokrotnie - nice_topic: - name: Niezły temat - description: Otrzymano 10 polubień w temacie. Ta odznaka może być przyznawana wielokrotnie. - good_topic: - name: Dobry temat - description: Otrzymano 25 polubień w temacie. Ta odznaka może być przyznawana wielokrotnie. - great_topic: - name: Świetny temat - description: Otrzymano 50 polubień w temacie. Ta odznaka może być przyznawana wielokrotnie. - nice_share: - name: Niezłe udostępnienie - description: Udostępniono wpis 25 unikalnym odwiedzającym. - good_share: - name: Dobre udostępnienie - description: Udostępniono wpis 300 unikalnym odwiedzającym. - great_share: - name: Świetne udostępnienie - description: Udostępniono wpis 1000 unikalnych odwiedzających. - first_like: - name: Pierwsze polubienie - description: Polubiono wpis - first_flag: - name: Pierwsza flaga - description: Zgłoszenie wpisu - promoter: - name: Promotor - description: Zaproszenie użytkownika - campaigner: - name: Działacz - description: Zaproszenie 3 użytkowników (poziom zaufania 1) - champion: - name: Czempion - description: Zaproszenie 5 użytkowników (poziom zaufania 2) - first_share: - name: Pierwsze udostępnienie - description: Udostępniono wpis - first_link: - name: Pierwszy link - description: Dodano wewnętrzny link do innego tematu - first_quote: - name: Pierwszy cytat - description: Zacytowano użytkownika - read_guidelines: - name: Przeczytany przewodnik - description: Przeczytanie wytycznych społeczności - reader: - name: Czytelnik - description: Przeczytanie każdego wpisu w temacie z ponad 100 wpisami - popular_link: - name: Popularny link - description: Opublikowanie zewnętrznego linku, który otrzymał co najmniej 50 kliknięć - hot_link: - name: Gorący link - description: Opublikowanie zewnętrznego linku, który otrzymał co najmniej 300 kliknięć - famous_link: - name: Słynny link - description: Opublikowanie zewnętrznego linku, który otrzymał co najmniej 1000 kliknięć google_search: |

    Wyszukaj z Google

    diff --git a/config/locales/client.pt.yml b/config/locales/client.pt.yml index 593e8db406f..490da9de51e 100644 --- a/config/locales/client.pt.yml +++ b/config/locales/client.pt.yml @@ -100,6 +100,8 @@ pt: x_years: one: "1 ano mais tarde" other: "%{count} anos mais tarde" + previous_month: 'Mês Anterior' + next_month: 'Mês Seguinte' share: topic: 'partilhar uma hiperligação para este tópico' post: 'Mensagem #%{postNumber}' @@ -110,6 +112,8 @@ pt: email: 'enviar esta hiperligação por email' action_codes: split_topic: "dividir este tópico %{when}" + invited_user: "Convidou %{who} %{when}" + removed_user: "Removeu %{who} %{when}" autoclosed: enabled: 'fechado %{when}' disabled: 'aberto %{when}' @@ -130,6 +134,19 @@ pt: disabled: 'removido da lista %{when}' topic_admin_menu: "Ações administrativas dos Tópicos" emails_are_disabled: "Todos os envios de e-mail foram globalmente desativados por um administrador. Nenhum e-mail de notificação será enviado." + s3: + regions: + us_east_1: "Este dos E.U.A. (Virgínia do Norte)" + us_west_1: "Oeste dos E.U.A. (California do Norte)" + us_west_2: "Oeste dos E.U.A. (Óregon)" + us_gov_west_1: "AWS GovCloud (E.U.A.)" + eu_west_1: "U.E. (Irlanda)" + eu_central_1: "U.E. (Francoforte)" + ap_southeast_1: "Ásia-Pacífico (Singapura)" + ap_southeast_2: "Ásia-Pacífico (Sydney)" + ap_northeast_1: "Ásia-Pacífico (Tóquio)" + ap_northeast_2: "Ásia-Pacífico (Seoul)" + sa_east_1: "América do Sul (São Paulo)" edit: 'editar o título e a categoria deste tópico' not_implemented: "Essa funcionalidade ainda não foi implementada, pedimos desculpa!" no_value: "Não" @@ -162,6 +179,8 @@ pt: more: "Mais" less: "Menos" never: "nunca" + every_30_minutes: "a cada 30 minutos" + every_hour: "a cada hora" daily: "diário" weekly: "semanal" every_two_weeks: "a cada duas semanas" @@ -173,6 +192,7 @@ pt: other: "{{count}} caracteres" suggested_topics: title: "Tópicos Sugeridos" + pm_title: "Mensagens Sugeridas" about: simple_title: "Acerca" title: "Acerca de %{title}" @@ -294,14 +314,26 @@ pt: one: "1 utilizador" other: "%{count} utilizadores" groups: + empty: + posts: "Não há nenhuma publicação feita por membros deste grupo." + members: "Não há nenhum membro neste grupo." + mentions: "Não há nenhuma menção deste grupo." + messages: "Não há nenhuma mensagem para este grupo." + topics: "Não há nenhum tópico feito por membros deste grupo." + add: "Adicionar" + selector_placeholder: "Adicionar membros" + owner: "proprietário" visible: "O grupo é visível para todos os utilizadores" title: one: "grupo" other: "grupos" members: "Membros" + topics: "Tópicos" posts: "Mensagens" + mentions: "Menções" + messages: "Mensagens" alias_levels: - title: "Quem pode usar este grupo como pseudónimo?" + title: "Quem pode mandar mensagens e @mencionar este grupo?" nobody: "Ninguém" only_admins: "Apenas administradores" mods_and_admins: "Apenas moderadores e Administradores" @@ -310,6 +342,19 @@ pt: trust_levels: title: "Nível de confiança concedido automaticamente a membros quando são adicionados:" none: "Nenhum" + notifications: + watching: + title: "A vigiar" + description: "Será notificado de cada nova publicação em todas as mensagens, e uma contagem de novas respostas será exibida." + tracking: + title: "A Acompanhar" + description: "Será notificado se alguém mencionar o seu @nome ou lhe responder, e uma contagem de novas respostas será exibida." + regular: + title: "Habitual" + description: "Será notificado se alguém mencionar o seu @nome ou responder-lhe." + muted: + title: "Mudo" + description: "Não será notificado de nada relacionado com novos tópicos neste grupo." user_action_groups: '1': "Gostos Dados" '2': "Gostos Recebidos" @@ -319,7 +364,6 @@ pt: '6': "Respostas" '7': "Menções" '9': "Citações" - '10': "Favoritos" '11': "Edições" '12': "Itens Enviados" '13': "Caixa de Entrada" @@ -329,6 +373,7 @@ pt: all_subcategories: "todas" no_subcategory: "nenhuma" category: "Categoria" + category_list: "Exibir lista de categorias" reorder: title: "Re-organizar Categorias" title_long: "Re-organizar a lista de categorias" @@ -385,16 +430,15 @@ pt: invited_by: "Convidado Por" trust_level: "Nível de Confiança" notifications: "Notificações" + statistics: "Estatísticas" desktop_notifications: label: "Notificações de Desktop" not_supported: "Não são suportadas notificações neste navegador. Desculpe." perm_default: "Ligar Notificações" perm_denied_btn: "Permissão Negada" - perm_denied_expl: "Tem permissões negadas para notificações. Utilize o seu navegador para ativar notificações, de seguida clique no botão quando concluir. (Desktop: O ícone mais à esquerda na barra de endereço. Móvel: 'Info do Sítio'.)" + perm_denied_expl: "Negou a permissão para as notificações. Autorize as notificações através das configurações do seu navegador." disable: "Desativar Notificações" - currently_enabled: "(atualmente ativo)" enable: "Ativar Notificações" - currently_disabled: "(atualmente inativo)" each_browser_note: "Nota: Tem que alterar esta configuração em todos os navegadores de internet que utiliza." dismiss_notifications: "Marcar tudo como lido" dismiss_notifications_tooltip: "Marcar como lidas todas as notificações por ler" @@ -418,7 +462,7 @@ pt: tracked_categories: "Acompanhado" tracked_categories_instructions: "Irá acompanhar automaticamente todos os novos tópicos nestas categorias. Uma contagem de novas mensagens irá aparecer junto ao tópico." muted_categories: "Silenciado" - muted_categories_instructions: "Não será notificado relativamente a novos tópicos nestas categorias, e não aparecerão no seu separador de tópicos não lidos." + muted_categories_instructions: "Não será notificado de nada acerca de novos tópicos nestas categorias, e estes não irão aparecer nos recentes." delete_account: "Eliminar A Minha Conta" delete_account_confirm: "Tem a certeza que pretende eliminar a sua conta de forma permanente? Esta ação não pode ser desfeita!" deleted_yourself: "A sua conta foi eliminada com sucesso." @@ -428,6 +472,8 @@ pt: users: "Utilizadores" muted_users: "Mudo" muted_users_instructions: "Suprimir todas as notificações destes utilizadores." + muted_topics_link: "Mostrar tópicos mudos" + automatically_unpin_topics: "Desafixar tópicos automaticamente quando eu chegar ao final." staff_counters: flags_given: "sinalizações úteis" flagged_posts: "mensagens sinalizadas" @@ -436,8 +482,15 @@ pt: warnings_received: "avisos" messages: all: "Todas" - mine: "Minha" - unread: "Não lidas" + inbox: "Caixa de Entrada" + sent: "Enviado" + archive: "Arquivo" + groups: "Os Meus Grupos" + bulk_select: "Selecionar mensagens" + move_to_inbox: "Mover para Caixa de Entrada" + move_to_archive: "Arquivo" + failed_to_move: "Falha ao mover as mensagens selecionadas (talvez a sua rede esteja em baixo)" + select_all: "Selecionar Tudo" change_password: success: "(email enviado)" in_progress: "(a enviar email)" @@ -482,8 +535,8 @@ pt: ok: "Enviar-lhe-emos um email para confirmar" invalid: "Por favor introduza um endereço de email válido" authenticated: "O seu email foi autenticado por {{provider}}" + frequency_immediately: "Enviar-lhe-emos um email imediatamente caso não leia o que lhe estamos a enviar." frequency: - zero: "Enviar-lhe-emos um email imediatamente caso não leia o que lhe estamos a enviar." one: "Só iremos enviar-lhe um email se não o tivermos visto no último minuto." other: "Só iremos enviar-lhe um email se não o tivermos visto nos últimos {{count}} minutos." name: @@ -521,12 +574,27 @@ pt: title: "Medalha de cartão de utilizador" website: "Sítio da Internet" email_settings: "Email" + like_notification_frequency: + title: "Notificar quando alguém gostar" + always: "Sempre" + first_time_and_daily: "Na primeira vez que mensagem é gostada e diariamente" + first_time: "A primeira vez que uma mensagem é gostada." + never: "Nunca" + email_previous_replies: + title: "Incluir respostas prévias no fundo do email." + unless_emailed: "a não ser quê previamente enviado" + always: "sempre" + never: "nunca" email_digests: title: "Quando não visitar o sítio, enviar um email com o resumo das novidades:" + every_30_minutes: "a cada 30 minutos" + every_hour: "A cada hora" daily: "diariamente" every_three_days: "a cada três dias" weekly: "semanalmente" every_two_weeks: "a cada duas semanas" + include_tl0_in_digests: "Incluir mensagens de novos utilizadores nos emails de resumo" + email_in_reply_to: "Incluir um excerto do mensagem respondida nos emails" email_direct: "Enviar-me um email quando alguém me citar, responder às minhas mensagens, mencionar o meu @nomedeutilizador, ou convidar-me para um tópico" email_private_messages: "Enviar-me um email quando alguém me envia uma mensagem" email_always: "Enviar-me notificações de email mesmo quando estou ativo no sítio" @@ -557,7 +625,9 @@ pt: user: "Utilizadores Convidados" sent: "Enviado" none: "Não há convites pendentes para mostrar." - truncated: "A mostrar os primeiros {{count}} convites." + truncated: + one: "A exibir o primeiro convite." + other: "A exibir os primeiros {{count}} convites." redeemed: "Convites Resgatados" redeemed_tab: "Resgatado" redeemed_tab_with_count: "Resgatados ({{count}})" @@ -592,6 +662,15 @@ pt: same_as_email: "A sua palavra-passe é a mesma que o seu email." ok: "A sua palavra-passe parece correta." instructions: "Pelo menos %{count} caracteres." + summary: + title: "Sumário" + stats: "Estatísticas" + top_replies: "Respostas" + more_replies: "Mais Respostas" + top_topics: "Melhores Tópicos" + more_topics: "Mais Tópicos" + top_badges: "Melhores Distintivos" + more_badges: "Mais Distintivos" associated_accounts: "Contas associadas" ip_address: title: "Último endereço IP" @@ -617,11 +696,13 @@ pt: server: "Erro de Servidor" forbidden: "Acesso Negado" unknown: "Erro" + not_found: "Página Não Encontrada" desc: network: "Por favor verifique a sua ligação." network_fixed: "Parece que está de volta." server: "Código de Erro: {{status}}" forbidden: "Não tem permissão para visualizar isso." + not_found: "Oops, a aplicação tentou carregar um URL que não existe." unknown: "Algo correu mal." buttons: back: "Voltar Atrás" @@ -632,8 +713,9 @@ pt: logout: "A sua sessão estava encerrada." refresh: "Atualizar" read_only_mode: - enabled: "O modo só de leitura está ativo. Pode continuar a navegar no sítio mas as interações podem não funcionar." + enabled: "Este sítio encontra-se no modo só de leitura. Por favor continue a navegar mas responder, dar gostos e outras acções estão de momento desativadas." login_disabled: "A função de início de sessão está desativada enquanto o sítio se encontrar no modo só de leitura." + logout_disabled: "A função de término de sessão está desativada enquanto o sítio se encontrar no modo só de leitura." too_few_topics_and_posts_notice: "Vamos começar esta discussão! Atualmente existem %{currentTopics} / %{requiredTopics} tópicos e %{currentPosts} / %{requiredPosts} mensagens. Novos visitantes precisam de conversações para ler e responder a." too_few_topics_notice: "Vamos começar esta discussão! Atualmente existem %{currentTopics} / %{requiredTopics} tópios. Novos visitantes precisam de algumas conversações para ler e responder a." too_few_posts_notice: "Vamos começar esta discussão! Atualmente existem %{currentPosts} / %{requiredPosts} mensagens. Novos visitantes precisam de algumas conversações para ler e responder a." @@ -656,22 +738,14 @@ pt: signup_cta: sign_up: "Inscrever-se" hide_session: "Lembrar-me amanhã" - hide_forever: "Não obrigado" + hide_forever: "não obrigado" hidden_for_session: "OK, Irei perguntar-lhe amanhã. Pode sempre usar 'Iniciar Sessão' para criar uma conta, também." intro: "Olá! :heart_eyes: Parece que está a gostar da discussão, mas não está inscrito para uma conta." - value_prop: "Quando cria uma conta, pode acompanhar exatamente o que leu, por isso volta sempre ao sítio onde ficou. Pode também obter notificações, aqui e por email, sempre que novas mensagens são feitas. E pode gostar de mensagens para partilhar o amor. :heartbeat:" - methods: - sso: "Inscrever-se é fácil: tudo o que precisa é uma conta no sítio principal." - only_email: "Inscrever-se é fácil: tudo o que precisa é um email e uma palavra-passe." - only_other: "Utilize a sua conta %{provider} para se inscrever." - one_and_email: "Utilize a sua conta %{provider}, ou um email e palavra-passe, para se inscrever." - multiple_no_email: "Inscrever-se é fácil: utilize qualquer um dos nossos %{count} inícios de sessão sociais." - multiple: "Inscrever-se é fácil: utilize qualquer um dos nossos %{count} inícios de sessão sociais, ou um email e palavra-passe." - unknown: "erro ao obter métodos suportados de início de sessão " + value_prop: "Quando cria uma conta, nós lembramo-nos exatamente do que leu, por isso volta sempre ao sítio onde ficou. Também recebe notificações, aqui ou por email, sempre que novas mensagens são feitas. E pode gostar de mensagens para partilhar o amor. :heartbeat:" summary: enabled_description: "Está a ver um resumo deste tópico: as mensagens mais interessantes são determinados pela comunidade." - description: "Existem {{count}} respostas." - description_time: "Existem {{count}} respostas com um tempo de leitura estimado de {{readingTime}} minutos." + description: "Existem {{replyCount}} respostas." + description_time: "Existem {{replyCount}} respostas com um tempo de leitura estimado de {{readingTime}} minutos." enable: 'Resumir Este Tópico' disable: 'Mostrar Todas As Mensagens' deleted_filter: @@ -725,6 +799,9 @@ pt: admin_not_allowed_from_ip_address: "Não pode iniciar sessão como administrador a partir desse endereço IP." resend_activation_email: "Clique aqui para enviar o email de ativação novamente." sent_activation_email_again: "Enviámos mais um email de ativação para o endereço {{currentEmail}}. Pode ser que demore alguns minutos; certifique-se que verifica a sua pasta de spam ou lixo." + to_continue: "Por favor Inicie Sessão" + preferences: "Necessita de ter sessão iniciada para alterar as suas preferências de utilizador." + forgot: "Não me recordo dos detalhes da minha conta" google: title: "com Google" message: "A autenticar com Google (certifique-se de que os bloqueadores de popup estão desativados)" @@ -734,6 +811,9 @@ pt: twitter: title: "com Twitter" message: "A autenticar com Twitter (certifique-se de que os bloqueadores de popup estão desativados)" + instagram: + title: "com Instagram" + message: "A autenticar com Instagram (certifique-se de que os bloqueadores de popup estão desativados)" facebook: title: "com Facebook" message: "A autenticar com o Facebook (certifique-se de que os bloqueadores de popup estão desativados)" @@ -747,8 +827,13 @@ pt: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "mais..." options: "Opções" whisper: "susurro" add_warning: "Este é um aviso oficial." @@ -759,6 +844,7 @@ pt: saved_local_draft_tip: "guardado localmente" similar_topics: "O seu tópico é similar a..." drafts_offline: "rascunhos offline" + group_mentioned: "Ao usar {{group}}, estará a notificar {{count}} pessoas." error: title_missing: "O título é obrigatório" title_too_short: "O título tem que ter pelo menos {{min}} caracteres." @@ -781,7 +867,7 @@ pt: show_edit_reason: "(adicione a razão para a edição)" reply_placeholder: "Digite aqui. Utilize Markdown, BBCode, ou HTML para formatar. Arraste ou cole imagens." view_new_post: "Ver a sua nova mensagem." - saving: "A Guardar..." + saving: "A Guardar" saved: "Guardado!" saved_draft: "Rascunho da mensagem em progresso. Selecione para continuar." uploading: "A carregar…" @@ -796,6 +882,7 @@ pt: link_description: "digite a descrição da hiperligação aqui" link_dialog_title: "Inserir Hiperligação" link_optional_text: "título opcional" + link_placeholder: "http://example.com \"texto opcional\"" quote_title: "Bloco de Citação" quote_text: "Bloco de Citação" code_title: "Texto pré-formatado" @@ -808,10 +895,11 @@ pt: heading_title: "Título" heading_text: "Título" hr_title: "Barra horizontal" - undo_title: "Desfazer" - redo_title: "Refazer" help: "Ajuda de Edição Markdown" toggler: "esconder ou exibir o painel de composição" + modal_ok: "OK" + modal_cancel: "Cancelar" + cant_send_pm: "Desculpe, não pode enviar uma mensagem para %{username}." admin_options_title: "Configurações opcionais do pessoal para este tópico" auto_close: label: "Tempo de fecho automático do tópico:" @@ -828,11 +916,16 @@ pt: more: "ver notificações antigas" total_flagged: "total de mensagens sinalizadas" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " + liked_many: + one: "

    {{username}}, {{username2}} e 1 outro {{description}}

    " + other: "

    {{username}}, {{username2}} e {{count}} outros {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -840,6 +933,9 @@ pt: moved_post: "

    {{username}} moveu {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Ganhou '{{description}}'

    " + group_message_summary: + one: "

    {{count}} mensagem na caixa de entrada do seu grupo {{group_name}}

    " + other: "

    {{count}} mensagens na caixa de entrada do seu grupo {{group_name}}

    " alt: mentioned: "Mencionado por" quoted: "Citado por" @@ -854,8 +950,10 @@ pt: moved_post: "A sua mensagem foi movida por" linked: "Hiperligação para a sua mensagem" granted_badge: "Distintivo concedido" + group_message_summary: "Mensagens na caixa de entrada do seu grupo" popup: mentioned: '{{username}} mencionou-o em "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} mencionou-o em "{{topic}}" - {{site_title}}' quoted: '{{username}} citou-o em "{{topic}}" - {{site_title}}' replied: '{{username}} respondeu-lhe em "{{topic}}" - {{site_title}}' posted: '{{username}} publicou em "{{topic}}" - {{site_title}}' @@ -867,9 +965,9 @@ pt: from_my_computer: "Do meu dispositivo " from_the_web: "Da internet" remote_tip: "hiperligação para imagem" - remote_tip_with_attachments: "hiperligação para imagem ou ficheiro ({{authorized_extensions}})" + remote_tip_with_attachments: "hiperligação para imagem ou ficheiro {{authorized_extensions}}" local_tip: "selecionar imagens do seu dispositivo" - local_tip_with_attachments: "selecionar imagens ou ficheiros do seu dispositivo ({{authorized_extensions}})" + local_tip_with_attachments: "selecionar imagens ou ficheiros a partir do seu dispositivo {{authorized_extensions}}" hint: "(pode também arrastar o ficheiro para o editor para fazer o carregamento)" hint_for_supported_browsers: "pode também arrastar e largar ou colar imagens no editor" uploading: "A carregar" @@ -904,12 +1002,14 @@ pt: current_user: 'ir para a sua página de utilizador' topics: bulk: + unlist_topics: "Remover Tópicos da Lista" reset_read: "Repor Leitura" delete: "Eliminar Tópicos" - dismiss_posts: "Destituir mensagens" - dismiss_posts_tooltip: "Remover contagem de não lidos nestes tópicos, mas manter a exibição dos mesmos na minha lista de não lidos quando novas mensagens são criadas." - dismiss_topics: "Destituir Tópicos" - dismiss_topics_tooltip: "Parar a exibição destes tópicos na minha lista de não lidos quando são criadas novas mensagens" + dismiss: "Destituir" + dismiss_read: "Destituir todos os não lidos" + dismiss_button: "Destituir..." + dismiss_tooltip: "Destituir apenas novas mensagens ou parar o acompanhamento de tópicos" + also_dismiss_topics: "Parar de acompanhar estes tópicos para que estes nunca me apareçam como não lidos novamente" dismiss_new: "Destituir Novo" toggle: "ativar seleção em massa de tópicos" actions: "Ações em Massa" @@ -933,8 +1033,8 @@ pt: top: "Não existem tópicos recentes." search: "Não há resultados na pesquisa." educate: - new: '

    Os seus novos tópicos aparecem aqui.

    Por defeito, os tópicos são considerados novos e mostrarão o indicador novo caso tenham sido criados nos últimos 2 dias.

    Pode alterar isto nas suas preferências.

    ' - unread: '

    Os seus tópicos não lidos aparecem aqui.

    Por defeito, os tópicos são considerados não lidos e aparecem nas contagens de não lidos 1 Se:

    • Criou o tópico
    • Respondeu ao tópico
    • Leu o tópico por mais de 4 minutos

    Ou, se definiu explicitamente o tópico para acompanhar ou vigiar através do controlo de notificações que se encontra na parte inferior de cada tópico.

    Pode alterar isto nas suas preferências.

    ' + new: '

    Os seus novos tópicos aparecem aqui.

    Por defeito, os tópicos são considerados novos e mostrarão o indicador novo caso tenham sido criados nos últimos 2 dias.

    Pode alterar isto nas suas preferências.

    ' + unread: '

    Os seus tópicos não lidos aparecem aqui.

    Por defeito, os tópicos são considerados não lidos e aparecem nas contagens de não lidos 1 Se:</p>

    • Criou o tópico
    • Respondeu ao tópico
    • Leu o tópico por mais de 4 minutos

    Ou, se definiu explicitamente o tópico para acompanhar ou vigiar através do controlo de notificações que se encontra na parte inferior de cada tópico.

    Visite as preferências para alterar isto.

    ' bottom: latest: "Não existem mais tópicos recentes." hot: "Não existem mais tópicos quentes." @@ -954,6 +1054,12 @@ pt: create: 'Novo Tópico' create_long: 'Criar um novo Tópico' private_message: 'Iniciar uma mensagem' + archive_message: + help: 'Mover mensagem para o seu arquivo' + title: 'Arquivo' + move_to_inbox: + title: 'Mover para Caixa de Entrada' + help: 'Mover mensagem de volta para a Caixa de Entrada' list: 'Tópicos' new: 'novo tópico' unread: 'não lido' @@ -1004,6 +1110,7 @@ pt: auto_close_title: 'Configurações para Fechar Automaticamente' auto_close_save: "Guardar" auto_close_remove: "Não Fechar Este Tópico Automaticamente" + auto_close_immediate: "A última mensagem neste tópico já tem %{hours} horas, por isso o tópico será fechado imediatamente." progress: title: progresso do tópico go_top: "topo" @@ -1053,7 +1160,7 @@ pt: description: "Não será notificado de nada relacionado com esta mensagem." muted: title: "Silenciado" - description: "Não será notificado de nada que esteja relacionado com este tópico, e este não será apresentado no seu separador de 'não lido'." + description: "Nunca será notificado de nada acerca deste tópico, e este não irá aparecer nos recentes." actions: recover: "Recuperar Tópico" delete: "Eliminar Tópico" @@ -1095,25 +1202,24 @@ pt: unpin_until: "Remover este tópico do topo da categoria {{categoryLink}} ou espere até %{until}." pin_note: "Os utilizadores podem desafixar individualmente o tópico por si próprios." pin_validation: "É necessária uma data para fixar este tópico." + not_pinned: "Não há tópicos fixados em {{categoryLink}}." already_pinned: - zero: "Não há tópicos fixados em {{categoryLink}}." - one: "Tópicos atualmente fixados em {{categoryLink}}: 1." - other: "Tópicos atualmente fixados em {{categoryLink}}: {{count}}." + one: "Tópicos atualmente fixados em {{categoryLink}}: 1" + other: "Tópicos atualmente fixados em {{categoryLink}}: {{count}}" pin_globally: "Fazer com que este tópico apareça no topo da lista de todos os tópicos até" confirm_pin_globally: "Já tem {{count}} tópicos fixados globalmente. Demasiados tópicos fixados podem ser um fardo para utilizadores novos e anónimos. Tem a certeza que deseja fixar outro tópico globalmente?" unpin_globally: "Remover este tópico do topo de todas as listas de tópicos." unpin_globally_until: "Remover este tópico do topo da lista de todos os tópicos ou espere até %{until}." global_pin_note: "Os utilizadores podem desafixar individualmente o tópico por si próprios." + not_pinned_globally: "Não existem tópicos fixados globalmente." already_pinned_globally: - zero: "Não há tópicos fixados globalmente." - one: "Tópicos atualmente fixados globalmente: 1." - other: "Tópicos atualmente fixados globalmente: {{count}}." + one: "Tópicos atualmente fixados globalmente: 1" + other: "Tópicos atualmente fixados globalmente: {{count}}" make_banner: "Tornar este tópico numa faixa que apareça no topo de todas as páginas." remove_banner: "Remover a faixa que aparece no topo de todas as páginas." banner_note: "Os utilizadores podem destituir a faixa ao fecharem-na. Apenas um tópico pode ser considerado uma faixa em qualquer momento." - already_banner: - zero: "Não há nenhum tópico de faixa." - one: " atualmente um tópico de faixa." + no_banner_exists: "Não existe tópico de faixa." + banner_exists: "Existe atualmente um tópico de faixa." inviting: "A Convidar..." automatically_add_to_groups_optional: "Este convite também inclui acesso a estes grupos: (opcional, apenas Administração)" automatically_add_to_groups_required: "Esse convite também inclui acesso a estes grupos: (Obrigatório, apenas Administração)" @@ -1125,6 +1231,7 @@ pt: success: "Convidámos esse utilizador para participar nesta mensagem." error: "Pedimos desculpa, ocorreu um erro ao convidar esse utilizador." group_name: "nome do grupo" + controls: "Controlos de Tópico" invite_reply: title: 'Convidar' username_placeholder: "nome de utilizador" @@ -1219,8 +1326,8 @@ pt: has_likes_title: one: "1 pessoa gostou desta mensagem" other: "{{count}} pessoas gostaram desta mensagem" + has_likes_title_only_you: "você gostou desta mensagem" has_likes_title_you: - zero: "você gostou desta mensagem" one: "você e 1 outra pessoa gostaram desta mensagem" other: "você e {{count}} outras pessoas gostaram desta mensagem" errors: @@ -1242,9 +1349,10 @@ pt: via_email: "esta mensagem chegou por email" whisper: "esta mensagem é um susurro privado para os moderadores" wiki: - about: "esta mensagem é uma wiki; utilizadores comuns podem editá-la" + about: "esta mensagem é uma wiki" archetypes: save: 'Guardar as Opções' + few_likes_left: "Obrigado por partilhar o amor! Restam-lhe apenas um gostos para hoje." controls: reply: "começar a compor uma resposta a este tópico" like: "gostar deste tópico" @@ -1270,6 +1378,7 @@ pt: revert_to_regular: "Remover Cor do Pessoal" rebake: "Reconstruir HTML" unhide: "Mostrar" + change_owner: "Mudar Titularidade" actions: flag: 'Sinalizar' defer_flags: @@ -1291,17 +1400,14 @@ pt: like: "Retirar gosto" vote: "Retirar voto" people: - off_topic: "{{icons}} sinalizou isto como fora de contexto" - spam: "{{icons}} sinalizou isto como spam" - spam_with_url: "{{icons}} sinalizaram isto como spam" - inappropriate: "{{icons}} sinalizou isto como inapropriado" - notify_moderators: "{{icons}} moderadores notificados" - notify_moderators_with_url: "{{icons}} moderadores notificados" - notify_user: "{{icons}} enviou uma mensagem" - notify_user_with_url: "{{icons}} enviou uma mensagem" - bookmark: "{{icons}} adicionaram um marcador a isto" - like: "{{icons}} gostaram disto" - vote: "{{icons}} votaram nisto" + off_topic: "sinalizou isto como fora de contexto" + spam: "sinalizou isto como spam" + inappropriate: "sinalizou isto como inapropriado" + notify_moderators: "moderadores notificados" + notify_user: "enviou uma mensagem" + bookmark: "adicionou um marcador disto" + like: "gostou disto" + vote: "votou nisto" by_you: off_topic: "Sinalizou isto como fora de contexto" spam: "Sinalizou isto como spam" @@ -1361,10 +1467,6 @@ pt: vote: one: "1 pessoa votou nesta mensagem" other: "{{count}} pessoas votaram nesta mensagem" - edits: - one: 1 edição - other: "{{count}} edições" - zero: sem edições delete: confirm: one: "Tem a certeza que quer eliminar essa mensagem?" @@ -1377,6 +1479,7 @@ pt: last: "Última revisão" hide: "Esconder revisão" show: "Mostrar revisão" + revert: "Reverter para esta revisão" comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" displays: inline: @@ -1445,19 +1548,18 @@ pt: notifications: watching: title: "A vigiar" - description: "Irá vigiar automaticamente todos os novos tópicos nestas categorias. Será notificado de todas as novas mensagens e tópicos, e uma contagem de novas respostas irá aparecer para estes tópicos." + description: "Irá vigiar automaticamente todos os novos tópicos nestas categorias. Irá ser notificado de cada nova mensagem em cada tópico, e uma contagem de novas respostas será exibida." tracking: title: "Acompanhar" - description: "Irá acompanhar automaticamente todos os novos tópicos nestas categorias. Uma contagem de novas respostas irá aparecer para estes tópicos." + description: "Irá acompanhar automaticamente todos os novos tópicos nestas categorias. Irá ser notificado se alguém mencionar o seu @nome ou lhe responder, e uma contagem de novas respostas será exibida." regular: - title: "Habitual" + title: "Normal" description: "Será notificado se alguém mencionar o seu @nome ou responder-lhe." muted: title: "Silenciado" - description: "Não será notificado relativamente acerca de novos tópicos nestas categorias, e não aparecerão no seu separador de não lidos." + description: "Nunca será notificado de nada acerca de novos tópicos nestas categorias, e estes não irão aparecer nos recentes." flagging: title: 'Obrigado por ajudar a manter a nossa comunidade cívica!' - private_reminder: 'as sinalizações são privadas, visíveis apenas para o pessoal' action: 'Sinalizar Mensagem' take_action: "Acionar" notify_action: 'Mensagem' @@ -1469,6 +1571,7 @@ pt: submit_tooltip: "Submeter a sinalização privada" take_action_tooltip: "Atingir imediatamente o limite de sinalizações, em vez de esperar por mais denúncias da comunidade" cant: "Pedimos desculpa, não é possível colocar uma sinalização nesta mensagem neste momento." + notify_staff: 'Notificar o pessoal privadamente' formatted_name: off_topic: "Está fora do contexto" inappropriate: "É inapropriado" @@ -1507,7 +1610,7 @@ pt: help: "Este tópico foi desafixado por si; será mostrado na ordem habitual" pinned_globally: title: "Fixado Globalmente" - help: "Este tópico está fixado globalmente; será mostrado no topo de todas as listas" + help: "Este tópico está fixado globalmente; será exibido no topo dos recentes e da sua categoria" pinned: title: "Fixado" help: "Este tópico foi fixado por si; será mostrado no topo da sua categoria" @@ -1550,8 +1653,8 @@ pt: with_topics: "%{filter} tópicos" with_category: "%{filter} %{category} tópicos" latest: - title: - zero: "Recentes" + title: "Recente" + title_with_count: one: "Recente (1)" other: "Recentes ({{count}})" help: "tópicos com mensagens recentes" @@ -1569,10 +1672,10 @@ pt: title_in: "Categoria - {{categoryName}}" help: "todos os tópicos agrupados por categoria" unread: - title: - zero: "Não lido" - one: "Não lido (1)" - other: "Não lidos ({{count}})" + title: "Não Lido" + title_with_count: + one: "Não Lido (1)" + other: "Não Lidos ({{count}})" help: "tópicos que está atualmente a vigiar ou a acompanhar com mensagens não lidas" lower_title_with_count: one: "1 não lido" @@ -1582,8 +1685,8 @@ pt: one: "1 novo" other: "{{count}} novos" lower_title: "novo" - title: - zero: "Novo" + title: "Novo" + title_with_count: one: "Novo (1)" other: "Novos ({{count}})" help: "tópicos criados nos últimos dias" @@ -1594,8 +1697,8 @@ pt: title: "Marcadores" help: "tópicos que marcou" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "tópicos recentes na categoria {{categoryName}}" @@ -1677,6 +1780,7 @@ pt: refresh_report: "Atualizar relatório" start_date: "Data de Início" end_date: "Data final" + groups: "Todos os grupos" commits: latest_changes: "Últimas alterações: atualize com frequência!" by: "por" @@ -1757,15 +1861,24 @@ pt: delete_confirm: "Eliminar este grupo?" delete_failed: "Impossível eliminar grupo. Se se trata de um grupo automático, não pode ser eliminado." delete_member_confirm: "Remova o '%{username}' do grupo '%{group}'?" + delete_owner_confirm: "Remover privilégios do proprietário para '%{username}'?" name: "Nome" add: "Adicionar" add_members: "Adicionar membros" custom: "Personalizar" + bulk_complete: "Os utilizadores foram adicionados ao grupo." + bulk: "Adicionar ao Grupo em Massa" + bulk_paste: "Colar uma lista de nomes de utilizador ou emails, um por linha:" + bulk_select: "(selecionar um grupo)" automatic: "Automático" automatic_membership_email_domains: "Utilizadores que registem um domínio de email que corresponde exactamente a algum desta lista irão ser automaticamente adicionados a este grupo:" automatic_membership_retroactive: "Aplicar a mesma regra de domínio de email para adicionar utilizadores registados existentes" default_title: "Título padrão para todos os utilizadores neste grupo" primary_group: "Definir automaticamente como grupo primário" + group_owners: Proprietários + add_owners: Adicionar proprietários + incoming_email: "Endereço de email de entrada personalizado" + incoming_email_placeholder: "introduza o endereço de email" api: generate_master: "Gerar Chave Mestra API " none: "Não existem chaves API ativas neste momento." @@ -1839,11 +1952,11 @@ pt: is_disabled: "A opção de restauro encontra-se desativada nas configurações do sítio." label: "Restaurar" title: "Restaurar a cópia de segurança" - confirm: "Tem a certeza que deseja restaurar esta cópia de segurança?" + confirm: "Tem a certeza que deseja recuperar esta cópia de segurança?" rollback: label: "Reverter" title: "Reverter a base de dados para um estado anterior operacional" - confirm: "Tem a certeza que deseja reverter a base de dados para um estado anterior operacional?" + confirm: "Tem a certeza que pretende reverter a base de dados para o estado de funcionamento anterior?" export_csv: user_archive_confirm: "Tem a certeza que deseja descarregar as suas mensagens?" success: "Exportação iniciada, será notificado através de mensagem assim que o processo estiver concluído." @@ -1894,6 +2007,14 @@ pt: color: "Cor" opacity: "Opacidade" copy: "Copiar" + email_templates: + title: "Modelos de Email" + subject: "Assunto" + multiple_subjects: "Este modelo de email tem múltiplos assuntos." + body: "Corpo" + none_selected: "Selecione um modelo de email para começar a editar." + revert: "Reverter Alterações" + revert_confirm: "Tem a certeza que quer reverter as suas alterações?" css_html: title: "CSS/HTML" long_title: "Personalizações CSS e HTML" @@ -1938,18 +2059,18 @@ pt: love: name: 'amor' description: "A cor do botão 'gosto'." - wiki: - name: 'wiki' - description: "Cor base utilizada para o fundo de mensagens wiki" email: - title: "Email" + title: "Emails" settings: "Configurações" - all: "Todos" + templates: "Templates" + preview_digest: "Pré-visualizar Resumo" sending_test: "A enviar Email de teste..." error: "ERRO - %{server_error}" test_error: "Occorreu um problema no envio do email de teste. Por favor verifique novamente as suas definições de email, verifique se o seu host não está a bloquear conexões de email, e tente novamente." sent: "Enviado" skipped: "Ignorado" + received: "Recebido" + rejected: "Rejeitado" sent_at: "Enviado em" time: "Tempo" user: "Utilizador" @@ -1959,7 +2080,6 @@ pt: send_test: "Enviar Email de Teste" sent_test: "enviado!" delivery_method: "Método de Entrega" - preview_digest: "Pré-visualizar Resumo" preview_digest_desc: "Pré-visualizar o conteúdo dos emails de resumo enviados aos utilizadores inativos." refresh: "Atualizar" format: "Formato" @@ -1968,6 +2088,25 @@ pt: last_seen_user: "Último Utilizador Visto:" reply_key: "Chave de Resposta" skipped_reason: "Ignorar Motivo" + incoming_emails: + from_address: "De" + to_addresses: "Para" + cc_addresses: "Cc" + subject: "Assunto" + error: "Erro" + none: "Nenhum email de entrada encontrado." + modal: + title: "Detalhes de emails recebidos." + error: "Erro" + subject: "Assunto" + body: "Corpo" + rejection_message: "Correio de rejeição" + filters: + from_placeholder: "de@exemplo.com" + to_placeholder: "para@exemplo.com" + cc_placeholder: "cc@exemplo.com" + subject_placeholder: "Assunto..." + error_placeholder: "Erro" logs: none: "Nenhuns logs encontrados." filters: @@ -1986,6 +2125,7 @@ pt: ip_address: "IP" topic_id: "ID do Tópico" post_id: "ID da Mensagem" + category_id: "ID da Categoria" delete: 'Eliminar' edit: 'Editar' save: 'Guardar' @@ -2016,6 +2156,7 @@ pt: change_site_setting: "alterar configurações do sítio" change_site_customization: "alterar personalização do sítio" delete_site_customization: "remover personalização do sítio" + change_site_text: "alterar texto do sítio" suspend_user: "utilizador suspenso" unsuspend_user: "utilizador não suspenso" grant_badge: "conceder distintivo" @@ -2026,6 +2167,16 @@ pt: impersonate: "personificar" anonymize_user: "tornar utilizador anónimo" roll_up: "agregar blocos IP" + change_category_settings: "alterar configurações de categoria" + delete_category: "eliminar categoria" + create_category: "criar categoria" + block_user: "utilizador bloqueado" + unblock_user: "Desbloquear utilizador" + grant_admin: "conceder administração" + revoke_admin: "revogar administração" + grant_moderation: "conceder moderação" + revoke_moderation: "revogar moderação" + backup_operation: "operação de cópia de segurança" screened_emails: title: "Emails Filtrados" description: "Quando alguém tenta criar uma nova conta, os seguintes endereços de email serão verificados e o registo será bloqueado, ou outra ação será executada." @@ -2092,9 +2243,9 @@ pt: pending: 'Utilizadores com Confirmação Pendente' newuser: 'Utilizadores no Nível de Confiança 0 (Novo Utilizador)' basic: 'Utilizadores no Nível de Confiança 1 (Utilizador Básico)' - regular: 'Utilizadores no Nível de Confiança 2 (Membro)' - leader: 'Utilizadores no Nível de Confiança 3 (Habitual)' - elder: 'Utilizadores no Nível de Confiança 4(Líder)' + member: 'Utilizadores no Nível de Confiança 2 (Membro)' + regular: 'Utilizadores no Nível de Confiança 3 (Habitual)' + leader: 'Utilizadores no Nível de Confiança 4 (Líder)' staff: "Pessoal" admins: 'Utilizadores da Administração' moderators: 'Moderadores' @@ -2127,6 +2278,7 @@ pt: moderator: "Moderador?" admin: "Administração?" blocked: "Bloqueado?" + staged: "Temporário?" show_admin_profile: "Administração" edit_title: "Editar Título" save_title: "Guardar Título" @@ -2191,9 +2343,12 @@ pt: deactivate_failed: "Ocorreu um problema ao desativar o utilizador." unblock_failed: 'Ocorreu um problema ao desbloquear o utilizador.' block_failed: 'Ocorreu um problema ao bloquear o utilizador.' + block_confirm: 'Tem a certeza que pretende bloquear este utilizador? Este não será capaz de criar novos tópicos ou mensagens.' + block_accept: 'Sim, bloquear este utilizador' deactivate_explanation: "Um utilizador desativado deve revalidar o seu email." suspended_explanation: "Um utilizador suspenso não pode iniciar sessão." block_explanation: "Um utilizador bloqueado não pode publicar mensagens ou iniciar tópicos." + stage_explanation: "Um utilizador em estado temporário pode apenas publicar por email em tópicos específicos." trust_level_change_failed: "Ocorreu um problema ao alterar o Nível de Confiança do utilizador." suspend_modal_title: "Utilizador Suspenso" trust_level_2_users: "Utilizadores no Nível de Confiança 2" @@ -2204,7 +2359,7 @@ pt: unlock_trust_level: "Desbloquear Nível de Confiança" tl3_requirements: title: "Requisitos para o Nível de Confiança 3" - table_title: "Nos últimos 100 dias:" + table_title: "Nos últimos %{time_period} dias:" value_heading: "Valor" requirement_heading: "Requisito" visits: "Visitas" @@ -2265,8 +2420,15 @@ pt: confirm: 'Confirmação' dropdown: "Suspenso" site_text: - none: "Escolha um tipo de conteúdo para começar a editar." + description: "Pode personalizar qualquer texto no seu fórum. Por favor comece por pesquisar abaixo:" + search: "Pesquisar o texto que gostaria de editar" title: 'Conteúdo do Texto' + edit: 'editar' + revert: "Reverter Alterações" + revert_confirm: "Tem a certeza que quer reverter as suas alterações?" + go_back: "De volta à Pesquisa" + recommended: "Recomendamos personalizar o seguinte texto para que se aplique às suas necessidades." + show_overriden: 'Apenas mostrar valores alterados' site_settings: show_overriden: 'Apenas mostrar valores alterados' title: 'Configurações' @@ -2354,8 +2516,8 @@ pt: bad_count_warning: header: "AVISO!" text: "Estão em falta amostras de concessão. Isto acontece quando a \"query\" do sistema de distintivos devolve IDs de nomes de utilizador ou IDs de mensagens que não existem. Isto pode causar resultados inesperados futuramente, sendo que deverá rever a sua \"query\"." + no_grant_count: "Nenhuns distintivos a atribuir." grant_count: - zero: "Nenhuns distintivos a atribuir." one: "1 distintivo a atribuir." other: "%{count} distintivos a atribuir." sample: "Amostra:" @@ -2465,9 +2627,10 @@ pt: mark_tracking: 'm, t Acompanhar tópico' mark_watching: 'm, w Vigiar este tópico' badges: + earned_n_times: + one: "Ganhou este distintivo 1 vez" + other: "Ganhou este distintivo %{count} vezes" title: Distintivos - allow_title: "pode ser usado como título" - multiple_grant: "pode ser premiado múltiplas vezes" badge_count: one: "1 Distintivo" other: "%{count} Distintivos" @@ -2490,97 +2653,6 @@ pt: name: Outro posting: name: A publicar - badge: - editor: - name: Editor - description: Primeira edição de uma mensagem - basic_user: - name: Básico - description: Atribuídas todas as funções comunitárias essenciais - member: - name: Membro - description: Atribuídos convites - regular: - name: Habitual - description: Atribuída re-categorização, renomeação, seguimento de hiperligações e lounge - leader: - name: Líder - description: Atribuída a edição, destaque, encerramento, arquivo, separação e junção globais - welcome: - name: Bem-vindo - description: Recebeu um gosto - autobiographer: - name: Autobiógrafo - description: 'Preencheu informações no perfil de utilizador ' - anniversary: - name: Aniversário - description: Membro ativo há um ano, publicou pelo menos uma vez - nice_post: - name: Boa Mensagem - description: Recebeu 10 gostos numa mensagem. Este distintivo pode ser concedido diversas vezes - good_post: - name: Ótima Mensagem - description: 'Recebeu 25 gostos numa mensagem. Este distintivo pode ser concedido diversas vezes ' - great_post: - name: Excelente Mensagem - description: Recebeu 50 gostos numa mensagem. Este distintivo pode ser concedido diversas vezes - nice_topic: - name: Bom Tópico - description: Recebeu 10 gostos num tópico. Este distintivo pode ser concedido diversas vezes - good_topic: - name: Ótimo Tópico - description: 'Recebeu 25 gostos num tópico. Este distintivo pode ser concedido diversas vezes ' - great_topic: - name: Excelente Tópico - description: Recebeu 50 gostos num tópico. Este distintivo pode ser concedido diversas vezes - nice_share: - name: Boa Partilha - description: Partilhou uma mensagem com 25 visitantes únicos - good_share: - name: Ótima Partilha - description: Partilhou uma mensagem com 300 visitantes únicos - great_share: - name: Excelente Partilha - description: Partilhou uma mensagem com 1000 visitantes únicos - first_like: - name: Primeiro Gosto - description: Gostou de uma mensagem - first_flag: - name: Primeira Sinalização - description: Sinalizou uma mensagem - promoter: - name: Promotor - description: Convidou um utilizador - campaigner: - name: Partidário - description: Convidou 3 utilizadores básicos (nível de confiança 1) - champion: - name: Campeão - description: Convidou 5 membros (nível de confiança 2) - first_share: - name: Primeira Partilha - description: Partilhou uma mensagem - first_link: - name: Primeira Hiperligação - description: Adicionou uma hiperligação interna para outro tópico - first_quote: - name: Primeira Citação - description: Citou um utilizador - read_guidelines: - name: Ler Diretrizes - description: Leu as diretrizes da comunidade - reader: - name: Leitor - description: Ler todas as mensagens num tópico com mais de 100 mensagens - popular_link: - name: Hiperligação Popular - description: Foi publicada uma hiperligação externa com pelo menos 50 cliques - hot_link: - name: Hiperligação Quente - description: Foi publicada uma hiperligação externa com pelo menos 300 cliques - famous_link: - name: Hiperligação Famosa - description: Foi publicada uma hiperligação externa com pelo menos 1000 cliques google_search: |

    Pesquise com o Google

    diff --git a/config/locales/client.pt_BR.yml b/config/locales/client.pt_BR.yml index d9e7b213413..74cae231c1c 100644 --- a/config/locales/client.pt_BR.yml +++ b/config/locales/client.pt_BR.yml @@ -9,8 +9,8 @@ pt_BR: js: number: format: - separator: "," - delimiter: "." + separator: "." + delimiter: "," human: storage_units: format: '%n %u' @@ -100,6 +100,8 @@ pt_BR: x_years: one: "1 ano depois" other: "%{count} anos depois" + previous_month: 'Mês Anterior' + next_month: 'Próximo Mês' share: topic: 'compartilhe o link desse tópico' post: 'post #%{postNumber}' @@ -108,8 +110,33 @@ pt_BR: facebook: 'compartilhe este link no Facebook' google+: 'compartilhe este link no Google+' email: 'enviar esse link para um email' + action_codes: + split_topic: "dividiu este tópico %{when}" + invited_user: "convidou %{who} %{when}" + removed_user: "removido %{who} %{when}" + autoclosed: + enabled: 'fechou %{when}' + disabled: 'abriu %{when}' + closed: + enabled: 'fechou %{when}' + disabled: 'abriu %{when}' + archived: + enabled: 'arquivou %{when}' + disabled: 'desarquivou %{when}' + pinned: + enabled: 'fixou %{when}' + disabled: 'desafixou %{when}' + pinned_globally: + enabled: 'fixou globalmente %{when}' + disabled: 'desafixou %{when}' + visible: + enabled: 'listou %{when}' + disabled: 'desalistou %{when}' topic_admin_menu: "ações administrativas do tópico" emails_are_disabled: "Todo o envio de email foi globalmente desabilitado por algum administrador. Nenhum email de notificações de qualquer tipo será enviado." + s3: + regions: + sa_east_1: "América do Sul (São Paulo)" edit: 'edite o título e a categoria deste tópico' not_implemented: "Esse recurso ainda não foi implementado, desculpe!" no_value: "Não" @@ -123,6 +150,7 @@ pt_BR: admin_title: "Admin" flags_title: "Sinalizações" show_more: "mostrar mais" + show_help: "opções" links: "Links" links_lowercase: one: "link" @@ -141,6 +169,8 @@ pt_BR: more: "Mais" less: "Menos" never: "nunca" + every_30_minutes: "a cada 30 minutos" + every_hour: "a cada hora" daily: "diário" weekly: "semanal" every_two_weeks: "a cada duas semanas" @@ -152,6 +182,7 @@ pt_BR: other: "{{count}} caracteres" suggested_topics: title: "Tópicos sugeridos" + pm_title: "Mensagens Sugeridas" about: simple_title: "Sobre" title: "Sobre %{title}" @@ -161,7 +192,7 @@ pt_BR: stat: all_time: "Desde o começo" last_7_days: "Últimos 7 dias" - last_30_days: "Últimos 30 Dias" + last_30_days: "Últimos 30 dias" like_count: "Curtidas" topic_count: "Tópicos" post_count: "Mensagens" @@ -199,6 +230,7 @@ pt_BR: saved: "Salvo!" upload: "Enviar" uploading: "Enviando..." + uploading_filename: "Enviando {{filename}}" uploaded: "Enviado!" enable: "Habilitar" disable: "Desabilitar" @@ -206,6 +238,7 @@ pt_BR: revert: "Reverter" failed: "Falhou" switch_to_anon: "Modo Anônimo" + switch_from_anon: "Sair do Modo Anônimo" banner: close: "Ignorar este banner." edit: "Editar este banner >>" @@ -228,7 +261,7 @@ pt_BR: one: "Este tópico tem 1 mensagem aguardando aprovação" other: "Este tópico tem {{count}} mensagens aguardando aprovação" confirm: "Salvar Mudanças" - delete_prompt: "Você tem certeza que deseja deletar %{username}? Isso irá remover todas as mensagens e irá bloquear o email e endereço IP desse usuário." + delete_prompt: "Você tem certeza que quer deletar %{username}? Esta ação irá remover todas as suas postagens e bloquear seu email e endereço IP." approval: title: "Aprovação Necessária da Mensagem" description: "Nós recebemos sua nova postagem mas é necessário que seja aprovada por um moderador antes de ser exibida. Por favor tenha paciência." @@ -271,19 +304,47 @@ pt_BR: one: "1 usuário" other: "%{count} usuários" groups: + empty: + posts: "Não há postagens por membros deste grupo." + members: "Não há membros neste grupo." + mentions: "Não há menção a este grupo." + messages: "Não há mensagens para este grupo." + topics: "Não há topicos por membros deste grupo." + add: "Adicionar" + selector_placeholder: "Adicionar membros" + owner: "proprietário" visible: "Grupo é visível para todos os usuários" title: one: "grupo" other: "grupos" members: "Membros" + topics: "Tópicos" posts: "Mensagens" + mentions: "Menções" + messages: "Mensagens" alias_levels: - title: "Quem pode usar este grupo como um apelido?" + title: "Quem pode enviar mensagem e @mention a este grupo?" nobody: "Ninguém" only_admins: "Somente administradores" mods_and_admins: "Somente moderadores e Administradores" members_mods_and_admins: "Somente membros do grupo, moderadores e administradores" everyone: "Todos" + trust_levels: + title: "Nível de Confiança automaticamente concedido aos membros quando eles são incluídos" + none: "Nenhum" + notifications: + watching: + title: "Assistindo" + description: "Você será notificado sobre toda nova postagem em toda mensagem, e uma contagem de novas mensagens será mostrada." + tracking: + title: "Rastreando" + description: "Você será notificado se alguém mencionar seu @name ou responder a você, e uma contagem de novas respostas será mostrada." + regular: + title: "Normal" + description: "Você será notificado se alguém mencionar seu @name ou responder a você." + muted: + title: "Mudo" + description: "Você será notificado sobre qualquer coisa sobre novos tópicos neste grupo." user_action_groups: '1': "Curtidas dadas" '2': "Curtidas recebidas" @@ -293,7 +354,6 @@ pt_BR: '6': "Respostas" '7': "Menções" '9': "Citações" - '10': "Favoritos" '11': "Edições" '12': "Itens enviados" '13': "Caixa de Entrada" @@ -303,6 +363,15 @@ pt_BR: all_subcategories: "todos" no_subcategory: "nenhum" category: "Categoria" + category_list: "Exibir lista de categorias." + reorder: + title: "Reordenar Categorias" + title_long: "Reorganizar a lista de categorias" + fix_order: "Fixar Posições" + fix_order_tooltip: "Algumas categorias não possuem um número de posição único, o que pode causar resultados inesperados." + save: "Salvar Ordem" + apply_all: "Aplicar" + position: "Posição" posts: "Respostas" topics: "Tópicos" latest: "Recentes" @@ -345,18 +414,21 @@ pt_BR: private_messages: "Mensagens" activity_stream: "Atividade" preferences: "Preferências" + expand_profile: "Expandir" bookmarks: "Favoritos" bio: "Sobre mim" invited_by: "Convidado por" trust_level: "Nível de Confiança" notifications: "Notificações" + statistics: "Estatísticas" desktop_notifications: + label: "Notificações de Área de Trabalho" not_supported: "Notificações não são suportadas nesse browser. Desculpe-nos." + perm_default: "Habilitar Notificações" perm_denied_btn: "Permissão Negada" + perm_denied_expl: "Você negou a permissão para notificações. Configure as permissões para notificações no seu navegador." disable: "Desativar Notificações" - currently_enabled: "(atualmente ativado)" enable: "Ativar Notificações" - currently_disabled: "(atualmente desativado)" each_browser_note: "Nota: Você deve modificar essa configuração em todos navegadores que você usa." dismiss_notifications: "Marcar todas como lidas" dismiss_notifications_tooltip: "Marcar todas as notificações não lidas como lidos" @@ -380,7 +452,7 @@ pt_BR: tracked_categories: "Monitorado" tracked_categories_instructions: "Automaticamente monitora todos novos tópicos nestas categorias. Uma contagem de posts não lidos e novos aparecerá próximo ao tópico." muted_categories: "Silenciado" - muted_categories_instructions: "Você não será notificado sobre novos tópicos dessas categorias e eles não vão aparecer na guia de mensagens não lidas." + muted_categories_instructions: "Você não será notificado sobre novos tópicos nessas categorias, e não aparecerão no Recentes" delete_account: "Excluir Minha Conta" delete_account_confirm: "Tem certeza de que deseja excluir permanentemente a sua conta? Essa ação não pode ser desfeita!" deleted_yourself: "Sua conta foi excluída com sucesso." @@ -390,6 +462,7 @@ pt_BR: users: "Usuários" muted_users: "Silenciado" muted_users_instructions: "Suprimir todas as notificações destes usuários." + muted_topics_link: "Mostrar tópicos silenciados" staff_counters: flags_given: "sinalizadas úteis" flagged_posts: "posts marcados" @@ -398,8 +471,12 @@ pt_BR: warnings_received: "avisos" messages: all: "Todas" - mine: "Minha" - unread: "Não lidas" + sent: "Enviado" + groups: "Meus Grupos" + bulk_select: "Selecionar mensagens" + move_to_inbox: "Mover para Caixa de Entrada" + failed_to_move: "Falha ao mover as mensagens selecionadas (talvez você esteja sem conexão com a rede)" + select_all: "Selecionar Tudo" change_password: success: "(email enviado)" in_progress: "(enviando email)" @@ -431,6 +508,7 @@ pt_BR: upload_title: "Enviar sua foto" upload_picture: "Enviar imagem" image_is_not_a_square: "Aviso: nós cortamos sua imagem; largura e altura não eram iguais." + cache_notice: "Você alterou sua foto de perfil com sucesso, porém pode levar algum tempo para que a mesma apareça devido ao cachê do navegador." change_profile_background: title: "Fundo do perfil" instructions: "Fundos do perfil será centralizado e tera uma largura padrão de 850px." @@ -443,10 +521,6 @@ pt_BR: ok: "Nós vamos pedir confirmação por email" invalid: "Insira um endereço de email" authenticated: "Seu email foi autenticado por {{provider}}" - frequency: - zero: "Não se preocupe, caso você não leia uma mensagem, enviaremos um email para você." - one: "Nós apenas te enviaremos email se não o tivermos visto no último minuto." - other: "Nós apenas te enviaremos email se não o tivermos visto nos últimos {{count}} minutos." name: title: "Nome" instructions: "Seu nome completo (opcional)" @@ -482,32 +556,56 @@ pt_BR: title: "Cartão de emblemas do usuário" website: "Web Site" email_settings: "Email" + email_previous_replies: + always: "sempre" + never: "nunca" email_digests: title: "Quando eu não visitar aqui, envie um resumo via email do que há de novo:" + every_30_minutes: "a cada 30 minutos" daily: "diariamente" every_three_days: "a cada três dias" weekly: "semanalmente" every_two_weeks: "a cada duas semanas" email_direct: "Me envie um email quando alguém me citar, responder minhas mensagens, mencionar meu @usuário, ou me convidar para um tópico" email_private_messages: "Me envie um email quando alguém me enviar mensagem particular" + email_always: "Envie-me notificações mesmo quando eu estiver ativo no site." other_settings: "Outros" categories_settings: "Categorias" new_topic_duration: label: "Considerar tópicos como novos quando" not_viewed: "Eu ainda não os vi" last_here: "criado desde de que eu estava aqui pela última vez" + after_1_day: "criado(s) no último(s) dia" + after_2_days: "criado(s) nos último(s) 2 dias" + after_1_week: "criado na última semana" + after_2_weeks: "criado nas últimas 2 semanas" auto_track_topics: "Seguir automaticamente tópicos que eu entro" auto_track_options: never: "nunca" immediately: "imediatamente" + after_30_seconds: "depois de 30 segundos" + after_1_minute: "depois de 1 minuto" + after_2_minutes: "depois de 2 minutos" + after_3_minutes: "depois de 3 minutos" + after_4_minutes: "depois de 4 minutos" + after_5_minutes: "depois de 5 minutos" + after_10_minutes: "depois de 10 minutos" invited: search: "digite para pesquisar convites..." title: "Convites" user: "Usuários convidados" - truncated: "Exibindo os primeiros {{count}} convites." + sent: "Enviado" + none: "Não existem convites pendentes para exibir." + truncated: + one: "Mostrando os primeiro convite." + other: "Mostrando os primeiros {{count}} convites." redeemed: "Convites usados" + redeemed_tab: "Resgatado" + redeemed_tab_with_count: "Resgatado ({{count}})" redeemed_at: "Usado" pending: "Convites pendentes" + pending_tab: "Pendente" + pending_tab_with_count: "Pendente ({{count}})" topics_entered: "Tópicos vistos" posts_read_count: "Mensagens vistas" expired: "Este convite expirou." @@ -519,6 +617,8 @@ pt_BR: days_visited: "Dias visitados" account_age_days: "Idade da conta em dias" create: "Enviar um convite" + generate_link: "Copiar Link do Convite" + generated_link_message: '

    Link do convite gerado com sucesso!

    Link do convite válido apenas para este endereço de email: %{invitedEmail}

    ' bulk_invite: none: "Você ainda não convidou ninguém. Você pode enviar convites individuais, ou enviar vários de uma vez através da ferramenta de enviar em massa." text: "Convidar em massa a partir de arquivo" @@ -533,6 +633,10 @@ pt_BR: same_as_email: "Sua senha é a mesma que o seu email." ok: "A sua senha parece boa." instructions: "Deve ter pelo menos %{count} caracteres." + summary: + stats: "Estatísticas" + top_replies: "Mais Respondidos" + more_topics: "Mais Tópicos" associated_accounts: "Logins" ip_address: title: "Último endereço IP" @@ -558,11 +662,13 @@ pt_BR: server: "Erro de Servidor" forbidden: "Acesso Negado" unknown: "Erro" + not_found: "Página não encontrada" desc: network: "Por favor verifique sua conexão." network_fixed: "Parece que voltou." server: "Código de erro: {{status}}" forbidden: "Você não tem permissão para ver isso." + not_found: "Oops, a aplicação tentou carregar uma URL que não existe." unknown: "Algo deu errado." buttons: back: "Voltar" @@ -573,8 +679,11 @@ pt_BR: logout: "Você foi desconectado." refresh: "Atualizar" read_only_mode: - enabled: "O modo somente-leitura está habilitado. Você pode navegador mas as interações podem não funcionar." + enabled: "Este site está em modo de leitura apenas. Por favor continue a navegar, no entanto, respostas, curtidas e outras ações estão desativadas por enquanto." login_disabled: "Login é desativado enquanto o site está em modo de somente leitura." + too_few_topics_and_posts_notice: "Vamos começar essa discussão! Existem atualmente %{currentTopics} / %{requiredTopics} tópicos e %{currentPosts} / %{requiredPosts} mensagens. Novos visitantes precisam de algumas conversas para ler e responder." + too_few_topics_notice: "Vamos começar essa discussão! Existem atualmente %{currentTopics} / %{requiredTopics} tópicos. Novos visitantes precisam de algumas conversas para ler e responder." + too_few_posts_notice: "Vamos começar essa discussão! Existem atualmente %{currentPosts} / %{requiredPosts} mensagens. Novos visitantes precisam de algumas conversas para ler e responder." learn_more: "aprenda mais..." year: 'ano' year_desc: 'tópicos criados nos últimos 365 dias' @@ -591,10 +700,17 @@ pt_BR: replies_lowercase: one: resposta other: respostas + signup_cta: + sign_up: "Registrar-se" + hide_session: "Lembre-me amanhã" + hide_forever: "não obrigado" + hidden_for_session: "OK, Eu vou perguntar amanhã. Você pode também sempre usar o 'Registre-se' para criar uma conta." + intro: "Ei você! :heart_eyes: Para que você está gostando da discussão, mas ainda não criou uma conta." + value_prop: "Quando você cria uma conta, nós lembramos exatamente o que você leu, assim você sempre volta exatamente aonde estava. Você também recebe notificações, aqui e por e-mail, quando novas mensagens são feitas. E você pode curtir tópicos para compartilhar o amor. :heartbeat:" summary: enabled_description: "Você está vendo um sumário deste tópico: os posts mais interessantes conforme determinados pela comunidade." - description: "Há {{count}} respostas." - description_time: "Há {{count}} respostas com um tempo de leitura estimado de {{readingTime}} minutos." + description: "Existem {{replyCount}} respostas." + description_time: "Existem {{replyCount}} respostas com tempo de leitura estimado em {{readingTime}} minutos." enable: 'Resumir Este Tópico' disable: 'Exibir Todas as Mensagens' deleted_filter: @@ -648,6 +764,9 @@ pt_BR: admin_not_allowed_from_ip_address: "Você não pode entrar como administrador a partir deste endereço IP." resend_activation_email: "Clique aqui para enviar o email de ativação novamente." sent_activation_email_again: "Nós enviamos mais um email de ativação para você no endereço {{currentEmail}}. Pode ser que demore alguns minutos para chegar; verifique sempre sua caixa de spams." + to_continue: "Por favor efetue o login" + preferences: "Você precisa estar logado para mudar suas preferências de usuário." + forgot: "Não me recordo dos detalhes da minha conta." google: title: "Entrar com Google" message: "Autenticando com Google (certifique-se de que os bloqueadores de popup estejam desativados)" @@ -670,15 +789,23 @@ pt_BR: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + more_emoji: "mais..." + options: "Opções" + whisper: "sussuro" add_warning: "Este é um aviso oficial." + toggle_whisper: "Habilitar Sussuro" posting_not_on_topic: "Qual tópico você gostaria de responder?" saving_draft_tip: "gravando..." saved_draft_tip: "salvo" saved_local_draft_tip: "salvo localmente" similar_topics: "Seu tópico é parecido com..." drafts_offline: "rascunhos offline" + group_mentioned: "Ao usar {{group}}, você irá notificar {{count}} pessoas.." error: title_missing: "Título é obrigatório" title_too_short: "O título tem que ter no mínimo {{min}} caracteres" @@ -699,8 +826,9 @@ pt_BR: title_placeholder: "Sobre o que é esta discussão em uma pequena frase?" edit_reason_placeholder: "por que você está editando?" show_edit_reason: "(adicione motivo da edição)" + reply_placeholder: "Escreva aqui. Use Markdown, BBCode ou HTML para formatar. Arraste ou cole uma imagens." view_new_post: "Ver sua nova resposta." - saving: "Salvando..." + saving: "Salvando" saved: "Salvo!" saved_draft: "Rascunho salvo, clique em selecionar para continuar editando." uploading: "Enviando..." @@ -715,6 +843,7 @@ pt_BR: link_description: "digite a descrição do link aqui" link_dialog_title: "Inserir link" link_optional_text: "título opcional" + link_placeholder: "http://example.com \"texto opcional\"" quote_title: "Bloco de citação" quote_text: "Bloco de citação" code_title: "Texto pré-formatado" @@ -727,10 +856,11 @@ pt_BR: heading_title: "Título" heading_text: "Título" hr_title: "Barra horizontal" - undo_title: "Desfazer" - redo_title: "Refazer" help: "Ajuda da edição Markdown" toggler: "esconder ou exibir o painel de composição" + modal_ok: "OK" + modal_cancel: "Cancelar" + cant_send_pm: "Desculpe, você não pode enviar uma mensagem para %{username}." admin_options_title: "Configurações opcionais da equipe para este tópico" auto_close: label: "Tempo para fechamento automático do tópico:" @@ -749,7 +879,6 @@ pt_BR: mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -759,6 +888,20 @@ pt_BR: moved_post: "

    {{username}} moved {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Adquirido '{{description}}'

    " + alt: + mentioned: "Mencionado por" + quoted: "Citado por" + replied: "Respondido" + posted: "Mensagem por" + edited: "Edição na sua mensagem por" + liked: "Curtiu sua mensagem" + private_message: "Mensagem privada de" + invited_to_private_message: "Convidou para uma mensagem privada" + invited_to_topic: "Convite para um tópico de" + invitee_accepted: "Convite aceito por" + moved_post: "Seu tópico foi movido por" + linked: "Link para sua mensagem" + granted_badge: "Emblema recebido" popup: mentioned: '{{username}} mencionou você em "{{topic}}" - {{site_title}}' quoted: '{{username}} citou você em "{{topic}}" - {{site_title}}' @@ -772,15 +915,29 @@ pt_BR: from_my_computer: "Do meu dispositivo" from_the_web: "Da internet" remote_tip: "link da imagem" - remote_tip_with_attachments: "link da imagem ou arquivo ({{authorized_extensions}})" + remote_tip_with_attachments: "link para imagem ou arquivo {{authorized_extensions}}" local_tip: "selecione imagens a partir do seu dispositivo" + local_tip_with_attachments: "selecione imagens ou arquivos do seu dispositivo {{authorized_extensions}}" hint: "(Você também pode arrastar e soltar para o editor para carregá-las)" + hint_for_supported_browsers: "Você pode também arrastar e soltar ou copiar imagens no editor" uploading: "Enviando" select_file: "Selecionar Arquivo" image_link: "link da sua imagem" search: + sort_by: "Ordenar por" + relevance: "Relevância" + latest_post: "Última Mensagem" + most_viewed: "Mais Visto" + most_liked: "Mais Curtido" + select_all: "Selecionar Todos" + clear_all: "Limpar Todos" + result_count: + one: "1 resultado para \"{{term}}\"" + other: "{{count}} resultados para \"{{term}}\"" title: "procurar em tópicos, respostas, usuários ou categorias" no_results: "Nenhum resultado encontrado." + no_more_results: "Sem mais resultados encontrados." + search_help: Ajuda na busca searching: "Procurando..." post_format: "#{{post_number}} por {{username}}" context: @@ -788,17 +945,19 @@ pt_BR: category: "Procurar a categoria \"{{category}}\"" topic: "Procurar nesse tópico" private_messages: "Procurar mensagens" + hamburger_menu: "ir para outra listagem de tópicos ou categoria" + new_item: "novo" go_back: 'voltar' not_logged_in_user: 'página do usuário com resumo de atividades correntes e preferencias' current_user: 'ir para a sua página de usuário' topics: bulk: + unlist_topics: "Tópicos Não Listados" reset_read: "Redefinir Lido" delete: "Apagar Tópicos" - dismiss_posts: "Ignorar Posts" - dismiss_posts_tooltip: "Zerar contagem de não lidos nestes tópicos, mas continuar a mostrar eles em minha lista de não lidos quando novos posts forem feitos." - dismiss_topics: "Ignorar Tópicos" - dismiss_topics_tooltip: "Para de mostrar estes tópicos em minha lista de não lidos quando novos posts forem feitos." + dismiss: "Marcar como lida" + dismiss_read: "Marcar todas como lida" + dismiss_button: "Descartar..." dismiss_new: "Dispensar Nova" toggle: "alternar a seleção em massa de tópicos" actions: "Ações em Massa" @@ -821,9 +980,6 @@ pt_BR: category: "Não há tópicos na categoria {{category}}." top: "Não há tópicos em alta." search: "Não foram encontrados resultados." - educate: - new: '

    Seus novos tópicos aparecerão aqui.

    Por padrão, tópicos são considerados novos e irão mostrar um indicador novo se eles foram criados nos últimos 2 dias.

    Você pode mudar isto nas suas preferências.

    ' - unread: '

    Seus tópicos não lidos aparecerão aqui.

    Por padrão, tópicos são considerados não lidos e irão mostrar contadores 1 se você:

    • Criou o tópico
    • Respondeu para o tópico
    • Leu o tópico por mais de 4 minutos

    Ou se você explicitamente marcou o tópico para Acompanhar ou Assistir via o controle de notificação na parte de baixo de cada tópico.

    Você pode mudar isto nas suas preferências.

    ' bottom: latest: "Não há mais tópicos recentes." hot: "Não mais tópicos quentes." @@ -836,10 +992,18 @@ pt_BR: bookmarks: "Não há mais tópicos nos favoritos." search: "Não existem mais resultados." topic: + unsubscribe: + stop_notifications: "Você agora vai receber menos notificações de {{title}}" + change_notification_state: "Seu estado de notificação atual é" filter_to: "{{post_count}} mensagens no tópico" create: 'Novo tópico' create_long: 'Criar um novo tópico' private_message: 'Iniciar uma mensagem' + archive_message: + help: 'Mover mensagens para o seu arquivo' + move_to_inbox: + title: 'Mover para caixa de entrada' + help: 'Mover mensagem para Caixa de Entrada' list: 'Tópicos' new: 'novo tópico' unread: 'não lido' @@ -890,6 +1054,7 @@ pt_BR: auto_close_title: 'Configurações para fechar automaticamente' auto_close_save: "Salvar" auto_close_remove: "Não fechar automaticamente este tópico" + auto_close_immediate: "O último tópico postado foi há %{hours} horas, então o tópico será fechado imadiatamente.." progress: title: progresso do tópico go_top: "topo" @@ -929,15 +1094,16 @@ pt_BR: title: "Monitorar" description: "Um contador de novas respostas será mostrado para este tópico. Você será notificado se alguém mencionar seu @nome ou responder à sua mensagem." regular: + title: "Normal" description: "Você será notificado se alguém mencionar o seu @nome ou responder à sua mensagem." regular_pm: + title: "Normal" description: "Você será notificado se alguém mencionar o seu @nome ou responder à sua mensagem." muted_pm: title: "Silenciado" description: "Você nunca será notificado de qualquer coisa sobre essa mensagem privada." muted: title: "Silenciar" - description: "Você nunca será notificado em nada sobre esse tópico e não aparecerá na guia de não lidas." actions: recover: "Recuperar Tópico" delete: "Apagar tópico" @@ -973,26 +1139,22 @@ pt_BR: success_message: 'Você sinalizou com sucesso este tópico.' feature_topic: title: "Destacar este tópico" + pin: "Fazer que este tópico apareça no topo da categoria {{categoryLink}} até" confirm_pin: "Você já tem {{count}} tópicos fixos. Muitos tópicos fixados podem atrapalhar usuários novos e anônimos. Tem certeza que quer fixar outro tópico nesta categoria?" unpin: "Remover este tópico do inicio da {{categoryLink}} categoria." + unpin_until: "Remover este tópico do topo da categoria {{categoryLink}} ou esperar até %{until}." pin_note: "Usuários podem desafixar o tópico individualmente para si." - already_pinned: - zero: "Não existem tópicos fixados em {{categoryLink}}." - one: "Tópicos atualmente fixados em {{categoryLink}}: 1." - other: "Tópicos atualmente fixados {{categoryLink}}: {{count}}." + pin_validation: "Uma data é necessária para fixar este tópico." + not_pinned: "Não existem tópicos fixados em {{categoryLink}}." + pin_globally: "Fazer com que este tópico apareça no topo de todas listas de tópicos até" confirm_pin_globally: "Você já tem {{count}} tópicos fixados globalmente. Muitos tópicos fixados podem prejudicar usuários novos e anônimos. Tem certeza que quer fixar outro tópico globalmente?" unpin_globally: "Remover este tópico do inicio de todas as listas de tópicos." + unpin_globally_until: "Remover este tópico do topo de todas listagens de tópicos ou esperar até %{until}." global_pin_note: "Usuários podem desafixar o tópico individualmente para si." - already_pinned_globally: - zero: "Não existem tópicos fixados globalmente." - one: "Tópicos atualmente fixados globalmente: 1." - other: "Tópicos atualmente fixados globalmente: {{count}}." + not_pinned_globally: "Não existem tópicos fixados globalmente." make_banner: "Tornar este tópico em um banner que apareça no inicio de todas as páginas." remove_banner: "Remover o banner que aparece no inicio de todas as páginas." banner_note: "Usuários podem dispensar o banner fechando-o. Apenas um tópico pode ser colocado como banner a cada momento." - already_banner: - zero: "Não existe tópico banner." - one: "Existe atualmente um tópico banner." inviting: "Convidando..." automatically_add_to_groups_optional: "Esse convite também inclui o acesso a esses grupos: (Opacional, admins apenas)" automatically_add_to_groups_required: "Esse convite também inclui o acesso a esses grupos: (Necessário, admins apenas)" @@ -1050,6 +1212,12 @@ pt_BR: one: "Por favor, escolha o novo dono do post por {{old_user}}." other: "Por favor, escolha o novo autor dessas {{count}} mensagens que eram de {{old_user}}." instructions_warn: "Note que qualquer notificação sobre esta mensagem não irá ser transferida para o novo usuário retroativamente.
    Alerta: Atualmente, nenhum dado dependente da mensagem será transferido para o novo usuário. Use com cuidado." + change_timestamp: + title: "Alterar Horário" + action: "alterar horário" + invalid_timestamp: "Horário não pode ser no futuro." + error: "Ocorreu um erro alterando o horário do tópico." + instructions: "Por favor selecione um novo horário para o tópico. Mensagens no tópico serão atualizadas para manter a mesma diferença de tempo." multi_select: select: 'selecionar' selected: '({{count}}) selecionados' @@ -1062,6 +1230,8 @@ pt_BR: one: 1 resposta selecionada. other: {{count}} respostas selecionadas. post: + reply: " {{replyAvatar}} {{usernameLink}}" + reply_topic: " {{link}}" quote_reply: "citar resposta" edit: "Em resposta a {{link}} por {{replyAvatar}} {{username}}" edit_reason: "Motivo:" @@ -1090,10 +1260,7 @@ pt_BR: has_likes_title: one: "{{count}} pessoa curtiu esta mensagem" other: "{{count}} pessoas curtiram esta mensagem" - has_likes_title_you: - zero: "você curtiu esta mensagem" - one: "você e 1 outra pessoa curtiu esta mensagem" - other: "Você e mais {{count}} pessoas curtiram esta mensagem" + has_likes_title_only_you: "você curtiu esta postagem" errors: create: "Desculpe, houve um erro ao criar sua resposta. Por favor, tente outra vez." edit: "Desculpe, houve um erro ao editar sua resposta. Por favor, tente outra vez." @@ -1111,8 +1278,9 @@ pt_BR: no_value: "Não, manter" yes_value: "Sim, abandone" via_email: "post recebido via email" + whisper: "esta mensagem é um sussuro privado para moderadores" wiki: - about: "essa resposta é uma wiki; usuários básicos podem editá-lo" + about: "esta postagem é uma wiki" archetypes: save: 'Salvar as opções' controls: @@ -1140,6 +1308,7 @@ pt_BR: revert_to_regular: "Remover da Moderação" rebake: "Reconstruir HTML" unhide: "Revelar" + change_owner: "Trocar autor" actions: flag: 'Sinalização' defer_flags: @@ -1161,17 +1330,9 @@ pt_BR: like: "Descurtir" vote: "Desfazer voto" people: - off_topic: "{{icons}} marcado como off-topic" - spam: "{{icons}} marcado como spam" - spam_with_url: "{{icons}} marcou isto como spam" - inappropriate: "{{icons}} marcado como inapropriado" - notify_moderators: "{{icons}} notificaram os moderadores" - notify_moderators_with_url: "{{icons}} notificaram os moderadores" - notify_user: "{{icons}} enviou uma mensagem particular" - notify_user_with_url: "{{icons}} enviou uma mensagem particular" - bookmark: "{{icons}} favoritaram isto" - like: "{{icons}} curtiram isto" - vote: "{{icons}} votaram nisto" + off_topic: "marcado como off-topic" + spam: "marcado como spam" + inappropriate: "marcado como inapropriado" by_you: off_topic: "Você sinalizou isto como off-topic" spam: "Você sinalizou isto como spam" @@ -1231,10 +1392,6 @@ pt_BR: vote: one: "1 pessoa votou nesta resposta" other: "{{count}} pessoas votaram nesta resposta" - edits: - one: 1 edição - other: "{{count}} edições" - zero: sem edições delete: confirm: one: "Tem certeza que quer apagar esta resposta?" @@ -1271,6 +1428,7 @@ pt_BR: topic_template: "Modelo de Tópico" delete: 'Apagar categoria' create: 'Nova categoria' + create_long: 'Criar uma nova categoria' save: 'Salvar categoria' slug: 'Slug da Categoria' slug_placeholder: '(Opcional) palavras hifenizadas para url' @@ -1293,6 +1451,7 @@ pt_BR: change_in_category_topic: "Editar Descrição" already_used: 'Esta cor já foi usada para outra categoria' security: "Segurança" + special_warning: "Atenção: Esta categoria é uma categoria padrão e as configurações de segurança e não podem ser editadas. Se você não quer usar esta categoria, apague-a ao invés de reaproveitá-la." images: "Imagens" auto_close_label: "Fechar automaticamente tópicos depois de:" auto_close_units: "horas" @@ -1300,6 +1459,7 @@ pt_BR: email_in_allow_strangers: "Aceitar emails de usuários anônimos sem cont" email_in_disabled: "Postar novos tópicos via email está desabilitado nas Configurações do Site. Para habilitar respostas em novos tópicos via email," email_in_disabled_click: 'habilitar a configuração de "email em".' + suppress_from_homepage: "Suprimir esta categoria da página inicial." allow_badges_label: "Permitir emblemas serem concedidos nessa categoria" edit_permissions: "Editar Permissões" add_permission: "Adicionar Permissões" @@ -1312,19 +1472,18 @@ pt_BR: notifications: watching: title: "Observar" - description: "Você vai acompanhar automaticamente todos os novos tópicos dessas categorias. Você será notificado de todas as novas mensagens e tópicos. Além disso, a contagem de mensagens não lidas e novas também aparecerá ao lado do tópico." + description: "Você vai acompanhar automaticamente todos os novos tópicos dessas categorias. Você será notificado de todas as novas mensagens em todos tópicos, e uma contagem de novas respostas será mostrada." tracking: title: "Monitorar" - description: "Automaticamente monitora todos novos tópicos nestas categorias. Uma contagem de posts não lidos e novos aparecerá próximo ao tópico." + description: "Você vai monitorar automaticamente todos os novos tópicos dessas categorias. Você será notificado se alguém mencionar seu @nome ou te responder, e uma contagem de novas respostas será mostrada." regular: title: "Normal" description: "Você será notificado se alguém mencionar o seu @nome ou responder à sua mensagem." muted: title: "Silenciar" - description: "Você não será notificado sobre novos tópicos dessas categorias e eles não vão aparecer na guia de mensagens não lidas." + description: "Você nunca será notificado sobre novos tópicos nessas categorias, e não aparecerão no Recentes." flagging: title: 'Obrigado por ajudar a manter a civilidade da nossa comunidade!' - private_reminder: 'sinalizações são privadas, apenas ficam visíveis a moderação' action: 'Sinalizar resposta' take_action: "Tomar Atitude" notify_action: 'Mensagem' @@ -1367,12 +1526,14 @@ pt_BR: help: "Este tópico está fechado; não serão aceitas mais respostas" archived: help: "Este tópico está arquivado; está congelado e não pode ser alterado" + locked_and_archived: + help: "Este tópico está fechado e arquivado; ele não aceita novas respostas e não pode ser alterado." unpinned: title: "Não fixo" help: "Este tópico está desfixado para você; ele será mostrado em ordem normal" pinned_globally: title: "Fixo Globalmente" - help: "Esse tópico está fixo; ele será mostrado no topo de todas as listas" + help: "Este tópico está fixado globalmente; ele será exibido no topo da aba Recentes e no topo da sua categoria" pinned: title: "Fixo" help: "Este tópico está fixado para você; ele será mostrado no topo de sua categoria" @@ -1415,9 +1576,9 @@ pt_BR: with_topics: "%{filter} tópicos" with_category: "%{filter} %{category} tópicos" latest: - title: - zero: "Recentes" - one: "Recentes (1)" + title: "Recente" + title_with_count: + one: "Recente (1)" other: "Recentes ({{count}})" help: "tópicos com mensagens recentes" hot: @@ -1434,8 +1595,8 @@ pt_BR: title_in: "Categoria - {{categoryName}}" help: "todos os tópicos agrupados por categoria" unread: - title: - zero: "Não lido" + title: "Não lidas" + title_with_count: one: "Não lido (1)" other: "Não lidos ({{count}})" help: "tópicos que você está acompanhando ou monitorando com mensagens não lidas" @@ -1447,11 +1608,11 @@ pt_BR: one: "1 nova" other: "{{count}} novas" lower_title: "nova" - title: - zero: "Novo" + title: "Novo" + title_with_count: one: "Novo (1)" other: "Novos ({{count}})" - help: "tópicos criatods nos últimos dias" + help: "tópicos criados nos últimos dias" posted: title: "Minhas mensagens" help: "tópicos nos quais você postou" @@ -1459,8 +1620,8 @@ pt_BR: title: "Favoritos" help: "tópicos que você adicionou aos favoritos" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" help: "tópicos recentes na categoria {{categoryName}}" @@ -1471,6 +1632,8 @@ pt_BR: title: "Tempo Todo" yearly: title: "Anualmente" + quarterly: + title: "Trimestralmente" monthly: title: "Mensalmente" weekly: @@ -1479,6 +1642,7 @@ pt_BR: title: "Diariamente" all_time: "Tempo Todo" this_year: "Ano" + this_quarter: "Trimestre" this_month: "Mês" this_week: "Semana" today: "Hoje" @@ -1619,15 +1783,21 @@ pt_BR: delete_confirm: "Apagar este grupos?" delete_failed: "Unable to delete group. If this is an automatic group, it cannot be destroyed." delete_member_confirm: "Remover '%{username}' do grupo '%{group}'?" + delete_owner_confirm: "Remover privilégio de proprietário de '%{username}'?" name: "Nome" add: "Adicionar" add_members: "Adicionar membros" custom: "Definidos" + bulk_complete: "Os usuários foram adicionados ao grupo." + bulk_paste: "Cole uma lista de usernames ou emails, um por linha:" + bulk_select: "(selecione um grupo)" automatic: "Automático" automatic_membership_email_domains: "Usuários que se registram com um domínio de email que confere precisamente com algum desta lista serão automaticamente adicionados a este grupo:" automatic_membership_retroactive: "Aplicar a mesma regra de domínio de email para adicionar usuários registrados" default_title: "Título padrão para todos usuários nesse grupo" primary_group: "Configurar automaticamente como grupo primário" + group_owners: Prorietários + add_owners: Adicionar proprietários api: generate_master: "Gerar chave Mestra de API" none: "Não existem chaves API ativas no momento." @@ -1701,11 +1871,9 @@ pt_BR: is_disabled: "Restaurar está desativado nas configurações do site." label: "Restaurar" title: "Restaurar o backup" - confirm: "Tem certeza de que quer restaurar este backup?" rollback: label: "Reverter" title: "Reverter o banco de dados para seu estado anterior" - confirm: "Tem certeza de que quer reverter o banco de dados para o estado anterior?" export_csv: user_archive_confirm: "Tem certeza que você quer baixar os seus tópicos?" success: "Exportação iniciada, você será notificado por mensagem particular quando o processo estiver completo." @@ -1730,6 +1898,7 @@ pt_BR: header: "Cabeçalho" top: "Superior" footer: "Rodapé" + embedded_css: "CSS Incorporada" head_tag: text: "" title: "HTML que será inserido antes da tag " @@ -1755,6 +1924,13 @@ pt_BR: color: "Cor" opacity: "Opacidade" copy: "Copiar" + email_templates: + title: "Modelos de E-mail" + subject: "Assunto" + body: "Corpo" + none_selected: "Selecione um modelo de e-mail para iniciar a edição." + revert: "Reverter Alterações" + revert_confirm: "Tem certeza de que deseja reverter as alterações?" css_html: title: "CSS/HTML" long_title: "Customizações CSS e HTML" @@ -1799,13 +1975,9 @@ pt_BR: love: name: 'curtir' description: "A cor do botão curtir." - wiki: - name: 'wiki' - description: "Cor base usada para o fundo em postagens do wiki." email: - title: "Email" settings: "Settings" - all: "Todas" + preview_digest: "Preview Digest" sending_test: "Enviando e-mail de teste..." error: "ERRO - %{server_error}" test_error: "Houve um problema ao enviar o email de teste. Por favor, verifique as configurações de email, se o seu provedor não está bloqueando conexões de email e tente novamente." @@ -1820,7 +1992,7 @@ pt_BR: send_test: "Enviar email de teste" sent_test: "enviado!" delivery_method: "Delivery Method" - preview_digest: "Preview Digest" + preview_digest_desc: "Pré-visualizar o conteúdo do e-mail de resumo enviado para usuários inativos." refresh: "Atualizar" format: "Formato" html: "html" @@ -1846,6 +2018,7 @@ pt_BR: ip_address: "IP" topic_id: "ID do Tópico" post_id: "ID Mensagem" + category_id: "ID da Categoria" delete: 'Excluir' edit: 'Editar' save: 'Salvar' @@ -1886,6 +2059,9 @@ pt_BR: impersonate: "personificar" anonymize_user: "tornar usuário anônimo" roll_up: "Agrupar bloco de IP" + change_category_settings: "mudas configurações da categoria" + delete_category: "apagar a categoria" + create_category: "criar uma categoria" screened_emails: title: "Emails Filtrados" description: "Quando alguém tenta cria uma nova conta, os seguintes endereços de email serão verificados e o registro será bloqueado, ou outra ação será executada." @@ -1952,9 +2128,9 @@ pt_BR: pending: 'Usuários com Confirmação Pendente' newuser: 'Usuários no Nível de Confiança 0 (Usuário Novo)' basic: 'Usuários no Nível de Confiança 1 (Usuário Básico)' - regular: 'Usuário no Nível de Confiança 2 (Regular)' - leader: 'Usuário no Nível de Confiança 3 (Líder)' - elder: 'Usuário no Nível de Confiança 4 (Ancião)' + member: 'Usuário em Nível de Confiança 2 (Membro)' + regular: 'Usuário em Nível de Confiança 3 (Regular)' + leader: 'Usuário em Nível de Confiança 4 (Líder)' staff: "Equipe de apoio" admins: 'Usuários Administradores' moderators: 'Moderadores' @@ -2064,7 +2240,6 @@ pt_BR: unlock_trust_level: "Destravar Nível de Confiança" tl3_requirements: title: "Requisitos para o Nível de Confiança 3" - table_title: "Nos últimos 100 dias:" value_heading: "Valor" requirement_heading: "Requisito" visits: "Visitas" @@ -2123,9 +2298,15 @@ pt_BR: field_types: text: 'Campo Texto' confirm: 'Confirmação' + dropdown: "Caixa de seleção" site_text: - none: "Escolha um tipo de conteúdo para começar a editar." + description: "Você pode personalizar qualquer parte do texto em seu fórum. Por favor, comece pesquisando abaixo:" + search: "Procure peloo texto que você gostaria de editar" title: 'Conteúdo do Texto' + edit: 'editar' + revert: "Reverter alterações" + revert_confirm: "Tem certeza que deseja reverter as alterações?" + show_overriden: 'Apenas mostrar valores alterados' site_settings: show_overriden: 'Exibir apenas valores alterados' title: 'Configurações' @@ -2156,6 +2337,7 @@ pt_BR: backups: "Backups" login: "Entrar" plugins: "Plugins" + user_preferences: "Preferências de Usuário" badges: title: Emblemas new_badge: Novo Emblema @@ -2212,8 +2394,8 @@ pt_BR: bad_count_warning: header: "CUIDADO!" text: "Faltam amostras de concessão. Isso acontece quando a consulta de emblemas retorna IDs de usuários ou IDs de postagens que não existem. Isso pode causar resultados inesperados futuramente - por favor verifique novamente a sua consulta." + no_grant_count: "Sem emblemas para serem atribuídos." grant_count: - zero: "Sem emblemas para serem atribuídos." one: "1 emblema para ser atribuído." other: "%{count} emblemas para serem atribuídos." sample: "Exemplo:" @@ -2229,15 +2411,44 @@ pt_BR: name: "Nome" image: "Imagem" delete_confirm: "Tem certeza que deseja excluir o emoji :%{name}: ?" + embedding: + get_started: "Se você deseja incorporar Discourse em outro site, começe adicionando seu host." + confirm_delete: "Você tem certeza que deseja apagar este host?" + sample: "Use o seguinte código HTML no seu site para criar e incorporar tópicos do Discourse. Troque REPLACE_ME com a URL canônica da página na qual você está incorporando." + title: "Incorporar" + host: "Hosts Permitidos" + edit: "editar" + category: "Postar na Categoria" + add_host: "Adicionar Host" + settings: "Configurações de Incorporação" + feed_settings: "Configurações de Feed" + feed_description: "Prover um feed de RSS/ATOM de seu site pode melhorar a habilidade do Discourse para importar seu conteúdo." + crawling_settings: "Configurações de Crawler" + crawling_description: "Quando Discourse cria tópicos para suas postagens, se nenhum feed RSS/ATOM estiver presente ele tentar recuperar o conteúdo do seu HTML. Algumas vezes isso pode sem um desafio, então provemos a habilidade de prover as regras específicas de CSS para fazer a extração mais fácil." + embed_by_username: "Nome de usuário para criação do tópico" + embed_post_limit: "Número máximo de postagens para incorporar" + embed_username_key_from_feed: "Chave para obter o nome de usuário no discourse do feed" + embed_truncate: "Truncar as postagens incorporadas" + embed_whitelist_selector: "Seletor de CSS para elementos que são permitidos na incorporação" + embed_blacklist_selector: "Seletor de CSS para elementos que são removidos da incorporação" + feed_polling_enabled: "Importar postagens via RSS/ATOM" + feed_polling_url: "URL do feed RSS/ATOM para pesquisar" + save: "Salvar Configurações de Incorporação" permalink: + title: "Links permanentes" url: "URL" + topic_id: "ID do Tópico" topic_title: "Tópico" + post_id: "ID da Mensagem" post_title: "Mensagem" + category_id: "ID da Categoria" category_title: "Categoria" external_url: "URL externa" + delete_confirm: Você tem certeza que quer apagar esse link permanente? form: label: "Novo:" add: "Adicionar" + filter: "Busca (URL ou URL Externa)" lightbox: download: "download" search_help: @@ -2253,6 +2464,8 @@ pt_BR: categories: 'g, c Categorias' top: 'g, t Topo' bookmarks: 'g, b Favoritos' + profile: 'g, p Perfil' + messages: 'g, m Mensagens' navigation: title: 'Navegação' jump: '# Ir para a resposta #' @@ -2264,12 +2477,14 @@ pt_BR: title: 'Aplicação' create: 'c Criar um tópico novo' notifications: 'n Abre notificações' + hamburger_menu: '= Abrir menu hamburger' user_profile_menu: 'p Abrir menu do usuário' show_incoming_updated_topics: '. Exibir tópicos atualizados' search: '/ Pesquisa' help: '? Abrir ajuda de teclado' dismiss_new_posts: 'x, r Descartar Novas Postagens' dismiss_topics: 'x, t Descartar Tópicos' + log_out: 'shift+z shift+z Deslogar' actions: title: 'Ações' bookmark_topic: 'f Adicionar tópico aos favoritos' @@ -2291,8 +2506,6 @@ pt_BR: mark_watching: 'm, w Acompanhar tópico' badges: title: Emblemas - allow_title: "pode ser usado como um título" - multiple_grant: "pode ser recebido várias vezes" badge_count: one: "1 Emblema" other: "%{count} Emblemas" @@ -2315,85 +2528,12 @@ pt_BR: name: Outro posting: name: Postando - badge: - editor: - name: Editor - description: Primeira edição da resposta - basic_user: - name: Básico - description: Concedido todas as funções essenciais da comunidade - member: - name: Membro - description: Concedido envio de convites - regular: - name: Regular - description: Concedido recategorizar, renomear, seguir links e sala de lazer - leader: - name: Líder - description: Concedido edição global, fixar, fechar, arquivar, dividir e mesclar - welcome: - name: Bem-Vindo - description: Recebeu uma curtida - autobiographer: - name: Autobiógrafo - description: Preencher informações do perfil - anniversary: - name: Aniversário - description: Membro ativo por um ano, postou ao menos uma vez - nice_post: - name: Post Legal - description: Recebeu 10 curtidas em uma resposta. Esse emblema pode ser concedido várias vezes. - good_post: - name: Bom Post - description: Recebeu 25 curtidas em uma resposta. Esse emblema pode ser concedido várias vezes. - great_post: - name: Ótimo Post - description: Recebeu 50 curtidas em uma resposta. Esse emblema pode ser concedido várias vezes. - nice_topic: - name: Tópico Interessante - description: Recebeu 10 curtidas em um tópico. Esse emblema pode ser concedido várias vezes. - good_topic: - name: Tópico Bom - description: Recebeu 25 curtidas em um tópico. Esse emblema pode ser concedido várias vezes. - great_topic: - name: Tópico Excelente - description: Recebeu 50 curtidas em um tópico. Esse emblema pode ser concedido várias vezes. - nice_share: - name: Compartilhamento Interessante - description: Compartilhou uma postagem com 25 visitas únicas - good_share: - name: Compartilhamento Bom - description: Compartilhou uma postagem com 300 visitas únicas - great_share: - name: Compartilhamento Excelente - description: Compartilhou uma postagem com 1000 visitas únicas - first_like: - name: Primeiro Like - description: Curtiu uma resposta - first_flag: - name: Primeira Marcação - description: Sinalizar uma resposta - promoter: - name: Promotor - description: Convidou um usuário - campaigner: - name: Veterano - description: Convidou 3 usuários básicos (nível de confiança 1) - champion: - name: Campeão - description: Convidou 5 usuários básicos (nível de confiança 2) - first_share: - name: Primeiro Compartilhamento - description: Compartilhar uma resposta - first_link: - name: Primeiro Link - description: Adicionar um link interno em outro tópico - first_quote: - name: Primeira citação - description: Citado um usuário - read_guidelines: - name: Ler as regras - description: Leia as regras da comunidade - reader: - name: Leitor - description: Leia cada resposta em um tópico com mais de 100 respostas + google_search: | +

    Buscar com o Google

    +

    +

    +

    diff --git a/config/locales/client.ro.yml b/config/locales/client.ro.yml index 7e3e9f054ac..27eac3046cc 100644 --- a/config/locales/client.ro.yml +++ b/config/locales/client.ro.yml @@ -8,24 +8,32 @@ ro: js: number: + format: + separator: "." + delimiter: "," human: storage_units: format: '%n %u' units: byte: - one: Bit - few: Biți - other: Biți + one: Byte + few: Bytes + other: Bytes gb: GB kb: KB mb: MB tb: TB + short: + thousands: "{{number}}k" + millions: "{{number}}M" dates: time: "HH:mm" long_no_year: "DD MMM HH:mm" long_no_year_no_time: "DD MMM" + full_no_year_no_time: "Do MMMM " long_with_year: "DD MMM YYYY HH:mm" long_with_year_no_time: "DD MMM YYYY" + full_with_year_no_time: "Do MMMM YYYY" long_date_with_year: "DD MMM 'YY HH:mm" long_date_without_year: "DD MMM HH:mm" long_date_with_year_without_time: "DD MMM 'YY" @@ -69,8 +77,8 @@ ro: one: "1a" few: "%{count}a" other: "%{count}a" - date_month: "Z LLL" - date_year: "LLL 'AA" + date_month: "DD MMMM" + date_year: "MMM 'YY" medium: x_minutes: one: "1 min" @@ -84,10 +92,10 @@ ro: one: "1 zi" few: "%{count} zile" other: "%{count} zile" - date_year: "Z LL AAAA" + date_year: "D MM YYYY" medium_with_ago: x_minutes: - one: "acum 1 min" + one: "acum un min" few: "acum %{count} min" other: "acum %{count} min" x_hours: @@ -98,16 +106,64 @@ ro: one: "acum o zi" few: "acum %{count} zile" other: "acum %{count} zile" + later: + x_days: + one: "După o zi" + few: "După %{count} zile" + other: "După %{count} zile" + x_months: + one: "o lună mai târziu" + few: "%{count} luni mai târziu" + other: "%{count} de luni mai târziu" + x_years: + one: "După un an" + few: "După %{count} ani" + other: "După %{count} ani" + previous_month: 'Luna anterioară' + next_month: 'Luna următoare' share: - topic: 'distribuie adresă către această discuție' - post: 'distribuie o adresă către postarea #%{postNumber}' + topic: 'distribuie această discuție' + post: 'distribuie postarea #%{postNumber}' close: 'închide' - twitter: 'distribuie această adresă pe Twitter' - facebook: 'distribuie această adresă pe Facebook' - google+: 'distribuie această adresă pe Google+' - email: 'trimite această adresă în email' + twitter: 'distribuie pe Twitter' + facebook: 'distribuie pe Facebook' + google+: 'distribuie pe Google+' + email: 'trimite această adresă peemail' + action_codes: + split_topic: "desparte acest topic %{when}" + autoclosed: + enabled: 'închis %{when}' + disabled: 'deschis %{when}' + closed: + enabled: 'închis %{when}' + disabled: 'deschis %{when}' + archived: + enabled: 'arhivat %{when}' + disabled: 'dezarhivat %{when}' + pinned: + enabled: 'Prins %{when}' + disabled: 'desprinse %{when}' + pinned_globally: + enabled: 'promovat global %{when}' + disabled: 'desprins %{when}' + visible: + enabled: 'listat %{when}' + disabled: 'retras %{when}' topic_admin_menu: "acțiuni subiect administrator" emails_are_disabled: "Trimiterea de emailuri a fost dezactivată global de către un administrator. Nu vor fi trimise notificări email de nici un fel." + s3: + regions: + us_east_1: "US East (N. Virginia)" + us_west_1: "US West (N. California)" + us_west_2: "US West (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "EU (Irlanda)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asia Pacific (Singapore)" + ap_southeast_2: "Asia Pacific (Sydney)" + ap_northeast_1: "Asia Pacific (Tokyo)" + ap_northeast_2: "Asia Pacific (Seoul)" + sa_east_1: "South America (Sao Paulo)" edit: 'editează titlul și categoria acestui subiect' not_implemented: "Această caracteristică nu a fost implementată încă, ne pare rău!" no_value: "Nu" @@ -117,10 +173,11 @@ ro: sign_up: "Înregistrare" log_in: "Autentificare" age: "Vârsta" - joined: "Adăugat" + joined: "Înregistrat" admin_title: "Admin" flags_title: "Semnalare" show_more: "Detaliază" + show_help: "Opțiuni" links: "Adrese" links_lowercase: one: "adresă" @@ -133,41 +190,45 @@ ro: terms_of_service: "Termenii serviciului" mobile_view: "Ecran pentru mobil" desktop_view: "Ecran pentru desktop" - you: "Dumneavoastră" + you: "Tu" or: "sau" now: "Adineauri" read_more: 'citește mai mult' more: "Mai mult" less: "Mai puțin" never: "Niciodată" + every_30_minutes: "La fiecare 30 de minute" + every_hour: "La fiecare oră" daily: "Zilnic" weekly: "Săptămânal" every_two_weeks: "Odată la două săptamâni" every_three_days: "la fiecare trei zile" max_of_count: "max din {{count}}" + alternation: "sau" character_count: - one: "{{count}} caracter" - few: "2 caractere" + one: "Un caracter" + few: "{{count}} caractere" other: "{{count}} caractere" suggested_topics: - title: "Subiecte Propuse" + title: "Subiecte sugerate" + pm_title: "Mesaje sugerate" about: simple_title: "Despre" title: "Despre %{title}" - stats: "Statistica site-ului" - our_admins: "Doar administratorii" - our_moderators: "Doar moderatorii" + stats: "Statisticile site-ului" + our_admins: "Administratorii" + our_moderators: "Moderatorii" stat: all_time: "Tot timpul" last_7_days: "Ultimele 7 zile" last_30_days: "Ultimele 30 de zile" - like_count: "Like-uri" + like_count: "Aprecieri" topic_count: "Subiecte" post_count: "Postări" user_count: "Utilizatori noi" active_user_count: "Utilizatori activi" - contact: "Contactați-ne" - contact_info: "În cazul în care o problemă critică sau alt aspect urgent afectează site-ul, va rugăm să ne contactaţi la %{contact_info}." + contact: "Contactează-ne" + contact_info: "În cazul în care o problemă critică sau alt aspect urgent afectează site-ul, contactează-ne la %{contact_info}." bookmarked: title: "Semn de carte" clear_bookmarks: "Șterge semnele de carte" @@ -180,36 +241,39 @@ ro: not_bookmarked: "Ai citit deja aceast mesaj; fă clic să adaugi semn de carte" last_read: "Acesta este ultimul mesaj citit de tine; fă click să adaugi semn de carte" remove: "Semn de carte înlăturat" - confirm_clear: "Sunteţi sigur că doriţi să ştergeţi toate bookmark-urile din acest subiect?" + confirm_clear: "Ești sigur că dorești să ştergi toate bookmark-urile din acest subiect?" topic_count_latest: one: "{{count}} subiect nou sau actualizat." few: "{{count}} subiecte noi sau actualizate." other: "{{count}} subiecte noi sau actualizate." topic_count_unread: - one: "{{count}} subiect necitit." + one: "Un subiect necitit." few: "{{count}} subiecte necitite." - other: "{{count}} subiecte necitite." + other: "{{count}} de subiecte necitite." topic_count_new: - one: "{{count}} subiect nou." + one: "Un subiect nou." few: "{{count}} subiecte noi." - other: "{{count}} subiecte noi." + other: "{{count}} de subiecte noi." click_to_show: "Click pentru vizualizare." preview: "vizualizează" cancel: "anulează" save: "Salvează Schimbările" - saving: "Salvează..." + saving: "Se Salvează..." saved: "Salvat!" upload: "Încarcă" uploading: "Încărcare..." + uploading_filename: "Se încarcă {{filename}}..." uploaded: "Încărcat!" enable: "Activează" disable: "Dezactivează" undo: "Anulează acțiunea precedentă" - revert: "Rescrie acțiunea precedentă" + revert: "Refacere" failed: "Eșuat" switch_to_anon: "Mod anonim" + switch_from_anon: "Ieșire din mod anonim" banner: close: "Ignoră acest banner." + edit: "Editează acest banner >>" choose_topic: none_found: "Nu au fost găsite discuții." title: @@ -225,15 +289,19 @@ ro: edit: "Editează" cancel: "Anulează" view_pending: "vezi postările în aşteptare" + has_pending_posts: + one: "Această discuție are 1 postare în așteptare" + few: "Această discuţie are {{count}} postări în aşteptare." + other: "Această discuţie are {{count}} de postări în aşteptare." confirm: "Salvează Schimbările" - delete_prompt: "Sunteţi sigur că vreţi să ştergeţi %{username}? Această operaţiune va şterge toate postările, va bloca adresa de email şi adresa de IP." + delete_prompt: "Ești sigur că vrei să ștergi utilizatorul %{username}? Vor fi șterse toate postările iar email-ul și IP-ul vor fi blocate." approval: title: "Necesită aprobare" description: "Am primit nouă postare dar trebuie să fie aprobată de un moderator înainte că ea să apară pe site. Va rugăm să aveţi răbdare." pending_posts: one: "Aveţi 1 postare în aşteptare." few: "Aveţi {{count}} postări în aşteptare." - other: "Aveţi {{count}} postări în aşteptare." + other: "Aveţi {{count}} de postări în aşteptare." ok: "OK" user_action: user_posted_topic: "{{user}} a postat discuția" @@ -271,20 +339,38 @@ ro: few: "%{count} utilizatori" other: "%{count} utilizatori" groups: + empty: + mentions: "Nu sunt mențiuni ale acestui grup." + messages: "Nu este nici un mesaj pentru acest grup." + add: "Adaugă" + selector_placeholder: "Adaugă membri" + owner: "proprietar" visible: "Grupul este vizibil tuturor utilizatorilor" title: one: "grup" few: "grupuri" other: "grupuri" members: "Membri" + topics: "Discuții" posts: "Postări" + mentions: "Mențiuni" + messages: "Mesaje" alias_levels: - title: "Cine poate folosii acest grup ca pseudonim?" nobody: "Nimeni" only_admins: "Doar Adminii" mods_and_admins: "Doar moderatorii și adminii" members_mods_and_admins: "Doar membri grupului, moderatorii și adminii" everyone: "Toată lumea" + notifications: + watching: + title: "Urmărit" + tracking: + title: "Urmărit" + regular: + title: "Normal" + description: "Vei fi notificat dacă cineva îți menționează @numele sau îți va scrie un reply." + muted: + title: "Mut" user_action_groups: '1': "Aprecieri Date" '2': "Aprecieri Primite" @@ -294,7 +380,6 @@ ro: '6': "Răspunsuri" '7': "Mențiuni" '9': "Citate" - '10': "Participări" '11': "Editări" '12': "Obiecte Trimise" '13': "Primite" @@ -304,6 +389,14 @@ ro: all_subcategories: "toate" no_subcategory: "niciuna" category: "Categorie" + reorder: + title: "Rearanjeaza Categoriile" + title_long: "Rearanjeaza lista de categorii" + fix_order: "Pozitii fixe" + fix_order_tooltip: "Nu toate categoriile au un numar de pozitie unic, asta poate cauze rezultate neasteptate." + save: "Salveaza ordinea" + apply_all: "Aplica" + position: "Pozitie" posts: "Postări" topics: "Discuții" latest: "Ultimele" @@ -334,7 +427,9 @@ ro: read_time: "Timp de citire" topics_entered: "Discuții la care particip" post_count: "# postari" - confirm_delete_other_accounts: "Sunteți sigur că vreți să ștergeți aceste conturi?" + confirm_delete_other_accounts: "Ești sigur că vrei să ștergi aceste conturi?" + user_fields: + none: "(selecteaza o optiune)" user: said: "{{username}} a spus:" profile: "Profil" @@ -346,11 +441,21 @@ ro: private_messages: "Mesaje" activity_stream: "Activitate" preferences: "Preferințe" + expand_profile: "Extinde" bookmarks: "Semne de carte" bio: "Despre mine" invited_by: "Invitat de" trust_level: "Nivel de Încredere" notifications: "Notificări" + statistics: "Statistici" + desktop_notifications: + label: "Notificari desktop" + not_supported: "Notificarile nu sunt suportate in acest browser." + perm_default: "Activeaza notificarile" + perm_denied_btn: "Nu se permite accesul" + disable: "Dezactiveaza notificarile" + enable: "Activeaza Notificarile" + each_browser_note: "Notati: Setarile vor fi modificate pe orice alt browser." dismiss_notifications: "Marchează toate ca citite" dismiss_notifications_tooltip: "Marchează cu citit toate notificările necitite" disable_jump_reply: "Nu sări la postarea mea după ce răspund" @@ -361,8 +466,9 @@ ro: change: "schimbă" moderator: "{{user}} este moderator" admin: "{{user}} este admin" - moderator_tooltip: "Acest user este moderator" - admin_tooltip: "Acest user este admin" + moderator_tooltip: "Acest utilizator este moderator" + admin_tooltip: "Acest utilizator este admin" + blocked_tooltip: "Acest utilizator este blocat." suspended_notice: "Acest user este suspendat păna la {{date}}." suspended_reason: "Motiv: " github_profile: "Github" @@ -370,9 +476,8 @@ ro: watched_categories: "Văzut" tracked_categories: "Tracked" muted_categories: "Muted" - muted_categories_instructions: "Nu vei fii notificat de dicuțiile apărute în aceste categorii și ele nu vor apărea în tabul necitite." delete_account: "Șterge-mi contul" - delete_account_confirm: "Ești sigur că vrei sa ștergi contul? Această acțiune poate fi anulată!" + delete_account_confirm: "Ești sigur că vrei sa ștergi contul? Această acțiune nu este reversibilă!" deleted_yourself: "Contul tău a fost șters cu succes." delete_yourself_not_allowed: "Nu iți poți sterge contul deocamdată. Contactează administratorul pentru ștergerea contului." unread_message_count: "Mesaje" @@ -380,6 +485,7 @@ ro: users: "Utilizatori" muted_users: "Silențios" muted_users_instructions: "Suprimă toate notificările de la aceşti utilizatori" + muted_topics_link: "Arata topicurile dezactivate." staff_counters: flags_given: "Semnale ajutătoare" flagged_posts: "postări semnalate" @@ -388,8 +494,14 @@ ro: warnings_received: "avertizări" messages: all: "Toate" - mine: "Ale mele" - unread: "Necitite" + inbox: "Inbox" + sent: "Trimise" + archive: "Arhivează" + groups: "Grupurile Mele" + bulk_select: "Selectează mesaje" + move_to_inbox: "Mută în Inbox" + move_to_archive: "Arhivează" + select_all: "Selectează tot" change_password: success: "(email trimis)" in_progress: "(se trimite email)" @@ -401,26 +513,27 @@ ro: error: "A apărut o eroare la schimbarea acestei valori" change_username: title: "Schimbă numele utilizatorului" - confirm: "Dacă schimbați numele utilizatorului, toate citatele din posturile precedente inclusiv mențiunile de nume vor fi anulate. Ești absolut sigur?" - taken: "Ne pare rău, acest nume de utilizator este deja folosit." + confirm: "Dacă schimbi numele utilizatorului, toate citatele din posturile precedente inclusiv @mențiunile nu vor mai funcționa. Ești absolut sigur?" + taken: "Acest nume de utilizator este deja folosit." error: "S-a intâmpinat o eroare pe parcursul schimbării numelui de utilizator." invalid: "Acest nume de utilizator este invalid. Trebuie să includă doar cifre și litere." change_email: title: "Schimbă Email" - taken: "Ne pare rău, acest email nu este disponibil." - error: "S-a întâmpinat o eroare la schimbarea de email. Poate această adresă este deja in folosința?" - success: "Am trimis un email către adresa respectivă. Urmați, vă rugăm, instrucțiunile de confirmare." + taken: "Acest email nu este disponibil." + error: "A apărut o eroare la schimbarea de email. Poate această adresă este deja in folosința?" + success: "Am trimis un email către adresa respectivă. Urmează instrucțiunile de confirmare." change_avatar: title: "Schimbă poză profilului personal" gravatar: "Gravatar, bazat pe" gravatar_title: "Schimbă avatarul de pe site-ul Gravatar." - refresh_gravatar_title: "Reîmprospatați Gravatarul" - letter_based: "Poză profilul atribuită de sistem." + refresh_gravatar_title: "Reactualizează Gravatarul" + letter_based: "Poză de profil atribuită de sistem." uploaded_avatar: "Poză preferată" uploaded_avatar_empty: "Adaugă poza preferată" upload_title: "Încarcă poza personală" upload_picture: "Încarcă poza" image_is_not_a_square: "Atenţie: poză este decupată, dar înălţimea şi lăţimea nu sunt egale." + cache_notice: "Fotografia de profil a fost schimbata, dar poate dura ceva timp pana sa apara datorita caching-ului din browser." change_profile_background: title: "Datele Profilului" instructions: "Fundalul profilului va fi centrat şi va avea o dimensiune standard de 850px." @@ -429,14 +542,10 @@ ro: instructions: "Fundalul va fi centrat şi va avea o dimensiune standard de 590px." email: title: "Email" - instructions: "Emailul dumneavoastră nu va fi făcut public." - ok: "Arată bine. Vă trimitem un email pentru confirmare." + instructions: "Emailul nu va fi făcut public." + ok: "Îți vom trimite un email pentru confirmare." invalid: "introduceți o adresă validă pentru confirmare." - authenticated: "Emailul dumneavoastră a fost autentificat de către {{provider}}." - frequency: - zero: "Vă vom trimite un email imediat dacă nu aţi citit încă ce v-am trimis." - one: "Va vom trimite un email dacă nu v-am văzut în ultimul minut." - other: "Va vom trimite un email doar dacă nu v-am văzut în ultimele {{count}} minute." + authenticated: "Emailul a fost autentificat de către {{provider}}." name: title: "Nume" instructions: "Versiunea lungă a numelui." @@ -461,7 +570,7 @@ ro: instructions: "Limba este folosită de interfața forumului. Schimbarea se va produce odată ce reîmprospatați pagina." default: "(din oficiu)" password_confirmation: - title: "Incă odată parola" + title: "Confirmă parola" last_posted: "Ultima postare" last_emailed: "Ultimul email dat" last_seen: "Văzut" @@ -472,32 +581,58 @@ ro: title: "Insignă utilizator" website: "Website" email_settings: "Email" + like_notification_frequency: + always: "Întotdeauna" + never: "Niciodată" + email_previous_replies: + always: "întotdeauna" + never: "niciodată" email_digests: title: "Cand nu vizitez site-ul, trimite-mi un email cu rezumatul noutăților:" + every_30_minutes: "La fiecare 30 de minute " daily: "zilnic" every_three_days: "la fiecare trei zile" weekly: "săptămânal" every_two_weeks: "la fiecare două săptămâni" email_direct: "Trimite un email când cineva mă citează, îmi răspunde la un post, menţionează @username meu, sau mă invită la o discuţie." email_private_messages: "Trimite-mi un mesaj când cineva îmi răspunde." + email_always: "Trimite-mi notificarile de email atunci cand sunt activ pe site." other_settings: "Altele" categories_settings: "Categorii" new_topic_duration: label: "Consideră discuțiile ca fiind noi" not_viewed: "Nu le-am văzut încă " last_here: "Create de la ultima vizită " + after_1_day: "creat azi" + after_2_days: "creat in ultimele 2 zile" + after_1_week: "creat in ultima saptamana" + after_2_weeks: "creat in ultimele 2 saptamni" auto_track_topics: "Urmăreşte automat discuţiile pe care le vizitez " auto_track_options: never: "niciodată" immediately: "imediat" + after_30_seconds: "dupa 30 de secunde" + after_1_minute: "dupa 1 minut" + after_2_minutes: "dupa 2 minute" + after_3_minutes: "dupa 3 minute" + after_4_minutes: "dupa 4 minute" + after_5_minutes: "dupa 5 minute" + after_10_minutes: "dupa 10 minute" invited: search: "Scrie pentru a căuta invitații..." title: "Invitații" user: "Utilizatori invitați" - truncated: "Afișeaza primele {{count}} invitații." + sent: "Trimis" + none: "Nu sunt invitații în așteptare." + truncated: + one: "Se arată prima invitație." + few: "Se arată primele {{count}} invitații." + other: "Se arată primele {{count}} de invitații." redeemed: "Invitații rascumpărate" redeemed_at: "Răscumpărate" pending: "Invitații in așteptare" + pending_tab: "In asteptare" + pending_tab_with_count: "In asteptare ({{count}})" topics_entered: "Subiecte văzute" posts_read_count: "Posturi citite" expired: "Această invitație a expirat." @@ -510,11 +645,11 @@ ro: account_age_days: "Vârsta contului în zile" create: "Trimite o invitație" bulk_invite: - none: "Nu ai invitat încă pe nimeni. Poți trimite invitații individuale, sau mai multor oameni deodată prin incărcarea fișierului de invitație multiplă." + none: "Nu ai invitat încă pe nimeni. Poți trimite invitații individuale sau mai multor oameni deodată prin incărcarea fișierului de invitație multiplă." text: "Invitație multiplă din fișierul" uploading: "Incarcă" success: "Fişier încărcat cu succes, veţi fi înştiinţat printr-un mesaj când procesarea va fi completă." - error: "S-a întâmpinat o eroare la încărcarea fișierului '{{filename}}': {{message}}" + error: "A apărut o eroare la încărcarea fișierului '{{filename}}': {{message}}" password: title: "Parolă" too_short: "Parola este prea scurtă." @@ -523,6 +658,9 @@ ro: same_as_email: "Parolă este identică cu adresa de email" ok: "Parola dumneavoastră arată bine." instructions: "Trebuiesc minim %{count} de caractere." + summary: + title: "Sumar" + stats: "Statistici" associated_accounts: "Conectări" ip_address: title: "Ultima adresă de IP" @@ -548,22 +686,23 @@ ro: server: "Eroare de server: {{code}}" forbidden: "Acces nepermis" unknown: "Eroare" + not_found: "Pagina nu a fost găsită" desc: - network: "Verificați conexiunea." + network: "Te rugăm să verifici conexiunea." network_fixed: "Se pare ca și-a revenit." server: "Ceva nu a funcționat." - forbidden: "Nu sunteţi autorizat să vedeţi aceasta." + forbidden: "Nu ești autorizat să vezi această pagină." + not_found: "Oops, aplicația încearcă să încarce un URL care nu există." unknown: "Ceva nu a funcționat." buttons: back: "Înapoi" again: "Încearcă din nou" fixed: "Încarcare pagină" close: "Închide" - assets_changed_confirm: "Acest site tocmai a fost updatat. Reîmprospătați pentru cea mai nouă versiune?" + assets_changed_confirm: "Acest site tocmai a fost actualizat. Reîmprospătați pentru cea mai nouă versiune?" logout: "Aţi fost deconectat." refresh: "Reîmprospătează" read_only_mode: - enabled: "Modul doar citire a fost activat. Puteţi continuă să vizitaţi acest site dar anumite acţiuni vor fi limitate." login_disabled: "Autentificarea este dezactivată când siteul este în modul doar pentru citit." learn_more: "află mai multe..." year: 'an' @@ -582,10 +721,14 @@ ro: one: răspuns few: răspunsuri other: răspunsuri + signup_cta: + sign_up: "Înregistrare" + hide_session: "Aminteste-mi maine." + hide_forever: "Nu, Multumesc" + hidden_for_session: "Ok, te vom intreba maine. Poti oricand folosi 'Autentificare' pentru a crea un cont." + value_prop: "Cand creati un cont nou, vom retine exact ce ati citit, astfel continuati intotdeauna de unde ati ramas. Deasemenea primiti notificari, aici sau prin email atunci se posteaza ceva nou. Puteti \"aprecia\" postari pentru a impartasi iubire :heartbeat:" summary: enabled_description: "Vizualizați sumarul discuției: cea mai interesantă postare, așa cum a fost determinată de comunitate. Pentru toate postările, faceți click dedesubt." - description: "Există {{count}} de răspunsuri." - description_time: "Există {{count}} de răspunsuri cu timp de citit estimat la {{readingTime}} de minute." enable: 'Fă sumarul discuției' disable: 'Arată toate postările' deleted_filter: @@ -605,15 +748,15 @@ ro: trust_level: 'Nivel de încredere' search_hint: 'Numele de utilizator sau email' create_account: - title: "Crează cont" + title: "Creează cont" failed: "Ceva a decurs greșit, poate că acest email e deja înregistrat, încearcă linkul parolă uitată " forgot_password: title: "Resetare parolă" action: "Mi-am uitat parola" invite: "Introduce-ți numele de utilizator sau adresa de email și vă vom trimite un email pentru resetarea parolei." reset: "Resetare Parolă" - complete_username: "Dacă contul se potrivește numelui de utilizator %{username}, ar trebuii să primiți un email cu instrucțiunile de resetare a parolei, în scurt timp." - complete_email: "dacă un cont se potrivește %{email}, ar trebuii să primiți un email cu instrucțiunile de resetare a parolei, în scurt timp." + complete_username: "Dacă contul se potrivește numelui de utilizator %{username}, ar trebui să primiți în scurt timp un email cu instrucțiunile de resetare a parolei." + complete_email: "Dacă un cont se potrivește cu %{email}, ar trebui să primiți un email în cel mai scurt timp cu instrucțiunile de resetare a parolei." complete_username_found: "Am găsit un cont care se potriveşte cu utilizatorul %{username}, veţi primi un email cu instrucţiunile cum să resetati parolă în cel mai scurt timp." complete_email_found: "Am găsit un cont care se potriveşte cu adresa %{email}, veţi primi un email cu instrucţiunile cum să resetati parolă în cel mai scurt timp." complete_username_not_found: "Nici un cont nu se potriveşte cu utilizatorul %{username}" @@ -625,6 +768,7 @@ ro: email_placeholder: "email sau nume de utilizator" caps_lock_warning: "Caps Lock este apăsat" error: "Eroare necunoscută" + rate_limit: "Te rog asteapta inainte de a te reconecta." blank_username_or_password: "Introduceți emailul sau numele de utilizator și parola." reset_password: 'Resetare parolă' logging_in: "În curs de autentificare..." @@ -638,6 +782,9 @@ ro: admin_not_allowed_from_ip_address: "Nu va puteţi conecta ca administrator de la această adresa de IP." resend_activation_email: "Click aici pentru a trimite emailul de activare încă odată." sent_activation_email_again: "Am trimis un alt email de activare pentru dvs la {{currentEmail}}. Poate dura câteva minute până ajunge; Vizitați și secțiunea de spam a mailului." + to_continue: "Te rog sa te autentifici." + preferences: "Trebuie sa fi autentificat pentru a schimba preferintele." + forgot: "Nu imi amintesc detaliile contului meu." google: title: "cu Google" message: "Autentificare cu Google (Asigurați-vă că barierele de pop up nu sunt active)" @@ -660,8 +807,14 @@ ro: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "mai multe..." + options: "Optiuni" add_warning: "Această este o avertizare oficială." posting_not_on_topic: "Cărei discuții vrei să-i răspunzi?" saving_draft_tip: "salvează..." @@ -675,22 +828,23 @@ ro: title_too_long: "Titlul nu poate avea {{max}} de caractere" post_missing: "Postarea nu poate fi gol" post_length: "Postarea trebuie sa aibă minim {{min}} de caractere" - try_like: 'Aţi încercat butonul ?' + try_like: 'Ai încercat butonul ?' category_missing: "Trebuie să alegi o categorie" save_edit: "Salvează Editarea" reply_original: "Răspunde discuției originale" reply_here: "Răspunde aici" reply: "Răspunde" cancel: "Anulează" - create_topic: "Crează o Discuţie" + create_topic: "Creează o Discuţie" create_pm: "Mesaj" - title: "sau apasă Ctrl+Enter" - users_placeholder: "adaugă un utilizator" + title: "Sau apasă Ctrl+Enter" + users_placeholder: "Adaugă un utilizator" title_placeholder: "Care este tema discuției într-o singură propoziție?" edit_reason_placeholder: "de ce editați?" show_edit_reason: "(adaugă motivul editării)" + reply_placeholder: "Scrie aici. Utilizeaza Markdown, BBCode or HTML la format. Trage sau lipeste imagini." view_new_post: "Vizualizează noua postare." - saving: "Salvează..." + saving: "Salvare" saved: "Salvat!" saved_draft: "Ai o postare în stadiul neterminat. Fă click oriunde pentru a continua editarea." uploading: "Încarcă..." @@ -705,6 +859,7 @@ ro: link_description: "adaugă aici descrierea adresei hyper" link_dialog_title: "Introdu adresă hyper" link_optional_text: "titlu opțional" + link_placeholder: "http://example.com \"text optional\"" quote_title: "Citat-bloc" quote_text: "Citat-bloc" code_title: "Text preformatat" @@ -716,11 +871,12 @@ ro: list_item: "conținut de listă" heading_title: "Titlu" heading_text: "Titlu" - hr_title: "Regulă de ordonare orizontală" - undo_title: "Anulează schimbările" - redo_title: "Refă schimbările" + hr_title: "Linie orizontală" help: "Ajutor de editare" - toggler: "ascunde sau arată panelul de compus" + toggler: "ascunde sau arată editorul" + modal_ok: "Ok" + modal_cancel: "Anuleaza" + cant_send_pm: "Nu poți trimite mesaje către %{username}" admin_options_title: "Setări opționale ale discuției pentru moderatori" auto_close: label: "Închide automat discuţia după:" @@ -732,16 +888,21 @@ ro: units: "(# de ore)" examples: 'Introdu numărul de ore (24).' notifications: - title: "notifică menționarea @nume, răspunsuri la postări, discuții, mesaje private, etc" + title: "notifică menționarea @numelui, răspunsuri la postările mele, discuții, mesaje private, etc" none: "Nu pot încarcă notificările în acest moment." more: "vezi notificările mai vechi" total_flagged: "toate postările semnalate" mentioned: "@

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " + liked_many: + one: "

    {{username}}, {{username2}} și încă cineva {{description}}

    " + few: "

    {{username}}, {{username2}} și alți {{count}} {{description}}

    " + other: "

    {{username}}, {{username2}} și alți {{count}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -749,26 +910,43 @@ ro: moved_post: "

    {{username}} mutată {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Ţi s-a acordat {{description}}

    " + alt: + mentioned: "Mentionat de" + quoted: "Citat de" + replied: "Raspuns" + posted: "Postat de" popup: - mentioned: '{{username}} va menţionat în "{{topic}}" - {{site_title}}' - quoted: '{{username}} va citat în"{{topic}}" - {{site_title}}' - replied: '{{username}} va răspuns la "{{topic}}" - {{site_title}}' + mentioned: '{{username}} te-a menţionat în "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} te-a menţionat în "{{topic}}" - {{site_title}}' + quoted: '{{username}} te-a citat în "{{topic}}" - {{site_title}}' + replied: '{{username}} ți-a răspuns la "{{topic}}" - {{site_title}}' posted: '{{username}} a postal în "{{topic}}" - {{site_title}}' - private_message: '{{username}} va trimis un mesaj privat în "{{topic}}" - {{site_title}}' - linked: '{{username}} a făcut o legătură la post-ul dvs. din "{{topic}}" - {{site_title}}' + private_message: '{{username}} ți-a trimis un mesaj privat în "{{topic}}" - {{site_title}}' + linked: '{{username}} a făcut o legătură la post-ul tău din "{{topic}}" - {{site_title}}' upload_selector: title: "Adaugă o imagine" title_with_attachments: "adaugă o imagine sau un fișier" from_my_computer: "din dispozitivul meu" from_the_web: "De pe web" remote_tip: "adresă către imagine http://example.com/image.jpg" - remote_tip_with_attachments: "adresă către imagine sau fișier http://example.com/file.ext (extensii permise: {{authorized_extensions}})." hint: "(puteți să trageți și să aruncați în editor pentru a le încărca)" uploading: "Încarcă" + select_file: "Slectează fișier" image_link: "Adresa din imagine va duce la" search: + sort_by: "Sortează după" + relevance: "Relevanță" + latest_post: "Ultimele postări" + most_viewed: "Cele mai văzute" + most_liked: "Cele mai apreciate" + select_all: "Selectează tot" + result_count: + one: "Un rezultat pentru \"{{term}}\"" + few: "{{count}} rezultate pentru \"{{term}}\"" + other: "{{count}} de rezultate pentru \"{{term}}\"" title: "caută discuții ,postări sau categorii" no_results: "Fără rezultat." + search_help: Ajutor căutare searching: "Caută..." post_format: "#{{post_number}} de {{username}}" context: @@ -776,6 +954,7 @@ ro: category: "Caută în categoria\"{{category}}\" " topic: "Caută în această discuție" private_messages: "Caută mesaje" + new_item: "nou" go_back: 'înapoi' not_logged_in_user: 'pagina utilizatorului cu sumarul activităților și preferințelor' current_user: 'mergi la pagina proprie de utilizator' @@ -783,10 +962,6 @@ ro: bulk: reset_read: "resetează citirea" delete: "Șterge subiectele" - dismiss_posts: "Șterge postarea" - dismiss_posts_tooltip: "Șterge părțile necitite din această discuție dar continuă afișarea lor în lista de necitite când au loc postări noi" - dismiss_topics: "Sterge discuția" - dismiss_topics_tooltip: "Nu arăta aceste discuții în lista de necitite când au loc postări noi" dismiss_new: "Anulează cele noi" toggle: "activează selecția în masă pentru discuții" actions: "Acțiuni în masă" @@ -798,20 +973,18 @@ ro: selected: one: "Ai selectat un subiect." few: "Ai selectat {{count}} subiecte." - other: "Ai selectat {{count}} subiecte." + other: "Ai selectat {{count}} de subiecte." none: - unread: "Nu aveți discuții necitite." - new: "Nu aveți discuții noi." - read: "Nu ați citit nicio discuție încă." - posted: "Nu ați postat în nicio discuție încă." - latest: "Nu există nicio discuție nouă. Trist." + unread: "Nu sunt discuții necitite." + new: "Nu sunt discuții noi." + read: "Nu ai citit nicio discuție încă." + posted: "Nu ai postat în nicio discuție încă." + latest: "Nu există nicio discuție nouă." hot: "Nu există nicio discuție importantă." bookmarks: "Nu aveţi nici un semn de carte încă." category: "Nu există nicio discuție din categoria {{category}}." top: "Nu exită nicio discuție de top." search: "Nu sunt rezulate la căutare." - educate: - new: '

    Discuţiile noi vor apărea aici.

    Implicit, discuţiile sunt considerate noi şi vor afişa indicatorul new dacă au fost create în ultimele 2 zile.

    Puteţi schimba aceasta în preferinţele dvs.

    ' bottom: latest: "Nu există nicio ultimă discuție." hot: "Nu mai există discuții importante." @@ -824,59 +997,67 @@ ro: bookmarks: "Nu mai sunt semne de carte." search: "Nu mai sunt rezultate." topic: - filter_to: "{{post_count}} de postări în discuție" - create: 'Crează discuție' - create_long: 'Crează discuție nouă' + unsubscribe: + stop_notifications: "Vei primi mai puține notificări pentru {{title}}" + filter_to: "{{post_count}} postări în discuție" + create: 'Discuție Nouă' + create_long: 'Creează discuție nouă' private_message: 'Scrie un mesaj.' + archive_message: + help: 'Mută mesajul în arhivă' + title: 'Arhivează' + move_to_inbox: + title: 'Mută în Inbox' + help: 'Mută mesajul în Inbox' list: 'Discuții' new: 'discuție nouă' unread: 'necitită' new_topics: - one: '1 subiect nou' + one: 'Un subiect nou' few: '{{count}} subiecte noi' - other: '{{count}} subiecte noi' + other: '{{count}} de subiecte noi' unread_topics: - one: '1 subiect necitit' + one: 'Un subiect necitit' few: '{{count}} subiecte necitite' - other: '{{count}} subiecte necitite' + other: '{{count}} de subiecte necitite' title: 'Discuție' invalid_access: - title: "Discuție pirvată" + title: "Discuția este privată" description: "Ne pare rău nu ai acces la acea discuție!" login_required: "Trebuie să fii autentificat să poți vedea discuția." server_error: title: "Discuția nu s-a putut încărca" - description: "Ne pare rău, nu am putut încărca discuția, posibil din cauza unei probleme de conexiune. Încercați din nou. Dacă problema persistă, anunțați-ne." + description: "Ne pare rău, nu am putut încărca discuția, posibil din cauza unei probleme de conexiune. Încercați din nou. Dacă problema persistă, anunță-ne." not_found: title: "Discuție negăsită" description: "Ne pare rău, Nu am putut găsii discuția. Poate a fost ștearsă de un moderator?" total_unread_posts: - one: "aveţi 1 mesaj necitit în această discuţie." - few: "aveţi {{count}} mesaje necitite în această discuţie." - other: "aveţi {{count}} mesaje necitite în această discuţie." + one: "ai un mesaj necitit în această discuţie." + few: "ai {{count}} mesaje necitite în această discuţie." + other: "ai {{count}} de mesaje necitite în această discuţie." unread_posts: - one: "aveţi 1 mesaj vechi necitit în această discuţie." - few: "aveţi {{count}} mesaje vechi necitite în această discuţie." - other: "aveţi {{count}} mesaje vechi necitite în această discuţie." + one: "ai un mesaj vechi necitit în această discuţie." + few: "ai {{count}} mesaje vechi necitite în această discuţie." + other: "ai {{count}} de mesaje vechi necitite în această discuţie." new_posts: - one: "este 1 mesaj nou în această discuţie de la ultima citire" + one: "este un mesaj nou în această discuţie de la ultima citire" few: "sunt {{count}} mesaje noi în această discuţie de la ultima citire" - other: "sunt {{count}} mesaje noi în această discuţie de la ultima citire" + other: "sunt {{count}} de mesaje noi în această discuţie de la ultima citire" likes: - one: "este 1 apreciere pentru această discuţie" + one: "există o apreciere pentru această discuţie" few: "sunt {{count}} aprecieri pentru această discuţie" - other: "sunt {{count}} aprecieri pentru această discuţie" + other: "sunt {{count}} de aprecieri pentru această discuţie" back_to_list: "Înapoi la lista de discuții" options: "Opțiunile discuției" - show_links: "arată adresele din această discuție" + show_links: "arată link-urile din această discuție" toggle_information: "activează detaliile discuției" read_more_in_category: "Vreți să citiți mai mult? Priviți alte discuții din {{catLink}} sau {{latestLink}}." read_more: "Vreți să citiți mai mult? {{catLink}} sau {{latestLink}}." browse_all_categories: Priviți toate categoriile - view_latest_topics: priviți ultimele discuții + view_latest_topics: arată ultimele discuții suggest_create_topic: De ce să nu creați o discuție? - jump_reply_up: răspundeți imediat - jump_reply_down: răspundeți mai târziu + jump_reply_up: sări la un răspuns mai vechi + jump_reply_down: sări la un răspuns mai nou deleted: "Discuția a fost ștearsă" auto_close_notice: "Această discuție va fi inchisă în %{timeLeft}." auto_close_notice_based_on_last_post: "Această discuţie se va închide %{duration} după ultimul răspuns." @@ -885,7 +1066,7 @@ ro: auto_close_remove: "nu închide automat această discuție" progress: title: Progresul Discuției - go_top: "capăt" + go_top: "început" go_bottom: "sfârșit" go: "mergi" jump_bottom: "sări la ultimul mesaj" @@ -895,58 +1076,70 @@ ro: position: "postarea %{current} din %{total}" notifications: reasons: - '3_6': 'Veți primii notificări fiindcă priviți această categorie.' - '3_5': 'Veți primii notificări fiindcă ați început să citiți această discuție automat.' - '3_2': 'Veți primii notificări fiindcă citiți această discuție.' - '3_1': 'Veți primii notificări fiindcă ați creat această discuție.' - '3': 'Veți primii notificări fiindcă priviți această discuție.' - '2_8': 'Veți primii notificări fiindcă urmariți această categorie.' - '2_4': 'Veți primii notificări fiindcă ați postat un răspuns în această discuție.' - '2_2': 'Veți primii notificări fiindcă urmariți această discuție.' - '2': 'Veți primii notificări fiindcă citiți această discuție.' - '0_7': 'Ignorați toate notificările din această categorie.' - '0_2': 'Ignorați toate notificările din această discuție.' - '0': 'Ignorați toate notificările din această discuție.' + '3_6': 'Vei primi notificări deoarece urmărești activ această categorie.' + '3_5': 'Vei primi notificări deoarece ai început să urmărești activ această discuție automat.' + '3_2': 'Vei primi notificări deoarece urmărești activ această discuție.' + '3_1': 'Vei primi notificări deoarece ați creat această discuție.' + '3': 'Vei primi notificări deoarece urmărești activ această discuție.' + '2_8': 'Vei primi notificări deoarece urmărești această categorie.' + '2_4': 'Vei primi notificări deoarece ai postat un răspuns în această discuție.' + '2_2': 'Vei primi notificări fiindcă urmărești această discuție.' + '2': 'Vei primi notificări fiindcă citești această discuție.' + '1_2': 'Vei fi notificat dacă cineva îți menționează @numele sau îți scrie un răspuns.' + '1': 'Vei fi notificat dacă cineva îți menționează @numele sau îți scrie un răspuns.' + '0_7': 'Ignori toate notificările din această categorie.' + '0_2': 'Ignori toate notificările din această discuție.' + '0': 'Ignori toate notificările din această discuție.' watching_pm: - title: "Privind" + title: "Urmărit Activ" + description: "Numărul postărilor noi va fi arătat pentru acest mesaj și vei fi notificat pentru orice răspuns scris." watching: - title: "Privind" + title: "Urmărit Activ" + description: "Numărul postărilor noi va fi arătat pentru această discuție și vei fi notificat pentru orice răspuns scris." tracking_pm: - title: "Urmărind" + title: "Urmărit" + description: "Numărul postărilor noi va fi arătat pentru acest mesaj. Vei fi notificat dacă cineva îți menționează @numele sau îți scrie un răspuns." tracking: - title: "Urmărind" + title: "Urmărit" + description: "Numărul postărilor noi va fi arătat pentru acest topic. Vei fi notificat dacă cineva îți menționează @numele sau îți scrie un răspuns." + regular: + title: "Normal" + description: "Vei fi notificat dacă cineva îți menționează @numele sau îți scrie un răspuns." + regular_pm: + title: "Normal" + description: "Vei fi notificat dacă cineva îți menționează @numele sau îți scrie un răspuns." muted_pm: title: "Silențios" - description: "Nu veţi fi niciodată notificat despre acest mesaj." + description: "Nu vei fi niciodată notificat despre acest mesaj." muted: title: "Silențios" - description: "Nu veți fi notificat de nimic în legătură cu această dicuție, nu va apărea în tabul necitite." + description: "Nu vei fi notificat de răspunsurile noi din această discuție și nu vor apărea în tabul necitite." actions: - recover: "Rescrie discuție" + recover: "Restaurează discuția" delete: "Șterge Discuție" - open: "Deschide discuție" - close: "Închide discuție" + open: "Redeschide discuția" + close: "Închide discuția" multi_select: "Selectează discuţiile ..." auto_close: "Închide automat" - pin: "Fixează discuţia pe pagină..." - unpin: "Anulează fixarea discuției" + pin: "Promovează discuţia pe pagină..." + unpin: "Anulează promovarea discuției" unarchive: "Dezarhivează discuția" archive: "Arhivează discuția" invisible: "Fă invizibil" visible: "Fă vizibil" reset_read: "Resetează informația citită" feature: - pin: "Fixează discuţia pe pagină..." - unpin: "Anulează fixarea discuției" - pin_globally: "Fixează discuţia pe site..." + pin: "Promovează discuţia pe pagină..." + unpin: "Anulează promovarea discuției" + pin_globally: "Promovează discuţia pe site..." make_banner: "Marchează discuție" remove_banner: "Demarchează discuție" reply: title: 'Răspunde' help: 'începe să compui un răspuns pentru această discuție' clear_pin: - title: "Înlătură fixarea" - help: "Înlătură statutul de fix al acestei discuții pentru a nu mai apărea în vârful listei de discuții" + title: "Înlătură promovarea" + help: "Înlătură promovarea acestei discuții pentru a nu mai apărea la începutul listei de discuții" share: title: 'Distribuie' help: 'distribuie o adresă acestei discuții' @@ -955,26 +1148,19 @@ ro: help: 'marchează privat această discuție pentru atenție sau trimite o notificare privată despre ea' success_message: 'Ai marcat cu succes această discuție.' feature_topic: - title: "Promovează această discuţia" - confirm_pin: "Aveţi deja {{count}} discuţii promovate. Prea multe discuţii promovate pot fi deveni o problemă pentru utilizatorii noi sau anonimi. Sunteţi sigur că vrei să promovaţi o altă discuţie în această categorie?" + title: "Promovează această discuţie" + confirm_pin: "Ai deja {{count}} discuţii promovate. Prea multe discuţii promovate pot fi deveni o problemă pentru utilizatorii noi sau anonimi. Ești sigur că vrei să promovezi o altă discuţie în această categorie?" unpin: "Îndepărtează aceast mesaje din top-ul categoriei {{categoryLink}}" - pin_note: "Utilizatorii pot anula fixarea unui subiect individual pentru ei înșiși." - already_pinned: - zero: "Nu există subiecte fixate în {{categoryLink}}." - one: "Subiecte fixate în acest moment în {{categoryLink}}: 1." - other: "Subiecte fixate în acest moment în {{categoryLink}}: {{count}}." - confirm_pin_globally: "Aveţi deja {{count}} discuţii promovate la nivel global. Prea multe discuţii promovate pot fi deveni o problemă pentru utilizatorii noi sau anonimi. Sunteţi sigur că vrei să promovaţi o altă discuţie la nivel global?" + pin_note: "Utilizatorii pot anula promovarea unui subiect individual pentru ei înșiși." + pin_validation: "Este nevoie de o dată pentru a putea promova această discuție." + not_pinned: "Nu sunt discuții promovate în {{categoryLink}}." + confirm_pin_globally: "Sunt {{count}} discuţii promovate la nivel global. Prea multe discuţii promovate pot fi deveni o problemă pentru utilizatorii noi sau anonimi. Ești sigur că vrei să promovezi o altă discuţie la nivel global?" unpin_globally: "Eliminați acest subiect din partea de sus a tuturor listelor de discuţii." - global_pin_note: "Utilizatorii pot anula fixarea unui subiect individual pentru ei înșiși." - already_pinned_globally: - zero: "Nu există subiecte fixate global." - one: "Subiecte fixate în acest moment la nivel global: 1." - other: "Subiecte fixate în acest moment la nivel global: {{count}}." + global_pin_note: "Utilizatorii pot anula promovarea unui subiect individual pentru ei înșiși." + not_pinned_globally: "Nu există subiecte promovate global." make_banner: "Transformă acest subiect într-un banner care apare în partea de sus a tuturor paginilor." remove_banner: "Îndepărtaţi mesajul banner care apare în partea de sus a fiecărei pagini." - banner_note: "Utilizatorii pot îndepărta baner-ul închizându-l. Doar un singur mesaj poate fi folosit că bane într-un moment dat." - already_banner: - zero: "Nu există nici un subiect banner." + banner_note: "Utilizatorii pot îndepărta baner-ul închizându-l. Doar un singur mesaj poate fi folosit că baner într-un moment dat." inviting: "Invită..." automatically_add_to_groups_optional: "Aceasta invitație include și accesul la grupurile: (opțional, doar admin)" automatically_add_to_groups_required: "Aceasta invitație include și accesul la grupurile: (Neapărat, doar admin)" @@ -984,27 +1170,27 @@ ro: email_or_username_placeholder: "adresa de email sau numele utilizatorului" action: "Invită" success: "Am invitat acest utilizator să participe la acest mesaj." - error: "Ne pare rău, s-a întâmpinat o eroare la trimiterea invitației către acel utilizator." + error: "Ne pare rău, a apărut o eroare la trimiterea invitației către acel utilizator." group_name: "numele grupului" invite_reply: title: 'Invitație' username_placeholder: "nume utilizator" action: 'Trimite o invitație' help: 'invită alţi utilizatori la această discuţie via email sau notificare' - to_forum: "Vom trimite un email scurt permițând prietenilor dumneavoastră să participe făcând click pe o adesă, nu necesită autentificare." - sso_enabled: "Introduceţi numele de utilizator al persoanei pe care doriţi să o invitaţi la acesta discuţie." - to_topic_blank: "Introduceţi numele de utilizator sau adresa de email a persoanei pe care doriţi să o invitaţi la acesta discuţie." - to_topic_email: "Aţi introdus o adresa de e-mail. Vom trimite via email o invitaţie, care permite prietenul dvs. să răspundă imediat la această discuţie." + to_forum: "Vom trimite un email scurt permițând prietenilor tăisă participe făcând click pe o adesă fără a necesita autentificare." + sso_enabled: "Introdu numele de utilizator al persoanei pe care dorești să o inviți la acesta discuţie." + to_topic_blank: "Introdu numele de utilizator sau adresa de email a persoanei pe care dorești să o inviți la acesta discuţie." + to_topic_email: "Ai introdus o adresa de e-mail. Vom trimite un email cu o invitaţie ce va permite prietenului tău să răspundă imediat la această discuţie." email_placeholder: 'exemplu@nume.com' - success_email: "Am trimis o invitaţie către {{emailOrUsername}}.. Va vom anunţă când invitaţia este folosită. Verificaţi fila invitaţii pe pagină dvs. de utilizator pentru a monitoriza invitaţiile. " + success_email: "Am trimis o invitaţie către {{emailOrUsername}}.. Te vom anunţă când invitaţia este folosită. Verifică tab-ul invitaţii pe pagină ta de utilizator pentru a monitoriza invitaţiile. " success_username: "Am invitat acest utilizator să participe la această discuţie." error: "Ne pare rău, nu am putut invită persoană indicată. Poate că a fost deja invitată? (Invitaţiile sunt limitate)" login_reply: 'Autentifică-te pentru a răspunde.' filters: n_posts: - one: "1 mesaj" + one: "O Postare" few: "{{count}} postări" - other: "{{count}} postări" + other: "{{count}} de postări" cancel: "Arată din nou toate postările din această discuție." split_topic: title: "Mutare în discuție nouă " @@ -1012,9 +1198,9 @@ ro: topic_name: "Numele noii discuții" error: "S-a semnalat o eroare la mutarea postărilor către discuția nouă." instructions: - one: "Veţi crea o nouă discuţie care va fi populată cu postarea selectată." - few: "Veţi crea o nouă discuţie care va fi populată cu cele {{count}} postări selectate." - other: "Veţi crea o nouă discuţie care va fi populată cu cele {{count}} postări selectate." + one: "Vei crea o nouă discuţie care va fi populată cu postarea selectată." + few: "Vei crea o nouă discuţie care va fi populată cu cele {{count}} postări selectate." + other: "Vei crea o nouă discuţie care va fi populată cu cele {{count}} de postări selectate." merge_topic: title: "Mută în discuție existentă" action: "mută în discuție existentă" @@ -1022,7 +1208,7 @@ ro: instructions: one: "Vă rugăm să alegeţi discuţia unde doriţi să mutaţi acest mesaj." few: "Vă rugăm să alegeţi discuţia unde doriţi să mutaţi aceste {{count}} mesaje." - other: "Vă rugăm să alegeţi discuţia unde doriţi să mutaţi aceste {{count}} mesaje." + other: "Vă rugăm să alegeţi discuţia unde doriţi să mutaţi aceste {{count}} de mesaje." change_owner: title: "Schimbă deținătorul postărilor" action: "Schimbă apartenența" @@ -1032,8 +1218,11 @@ ro: instructions: one: "Va rugăm să alegeţi noul propietar pentru mesajul postat de {{old_user}}." few: "Va rugăm să alegeţi noul propietar pentru cele {{count}} mesajele postate de {{old_user}}." - other: "Va rugăm să alegeţi noul propietar pentru cele {{count}} mesajele postate de {{old_user}}." - instructions_warn: " aveți în vedere că nicio notificare ce privește această postare nu va fi transferabilă retroactiv către noul utilizator.
    Avertisment: Acum, nicio informație ce depinde de postare nu va fi transferată noului utilizator. Folosiți cu grijă." + other: "Va rugăm să alegeţi noul propietar pentru cele {{count}} de mesajele postate de {{old_user}}." + instructions_warn: "NB: nicio notificare ce privește această postare nu va fi transferabilă retroactiv către noul utilizator.
    Avertisment: Acum, nicio informație ce depinde de postare nu va fi transferată noului utilizator. Folosește cu atenție." + change_timestamp: + title: "Schimbă data publicării" + action: "schimbă data publicării" multi_select: select: 'selectează' selected: 'selectate ({{count}})' @@ -1043,10 +1232,12 @@ ro: select_all: selectează tot deselect_all: deselectează tot description: - one: Aţi selectat 1 mesaj. - few: Aţi selectat {{count}} mesaje. - other: Aţi selectat {{count}} mesaje. + one: Ai selectat un mesaj. + few: Ai selectat {{count}} mesaje. + other: Ai selectat {{count}} de mesaje. post: + reply: " {{replyAvatar}} {{usernameLink}}" + reply_topic: " {{link}}" quote_reply: "răspunde prin citat" edit: "Editează {{link}} {{replyAvatar}} {{username}}" edit_reason: "Motivul: " @@ -1063,39 +1254,54 @@ ro: other: "(postări retrase de autor, vor fi şterse automat în %{count} ore, cu excepţia cazului în care mesajele sunt marcate)" expand_collapse: "expandează/restrânge" gap: - one: "vedeţi 1 răspuns ascuns" - few: "vedeţi {{count}} răspunsuri ascunse" - other: "vedeţi {{count}} răspunsuri ascunse" + one: "vezi un răspuns ascuns" + few: "vezi {{count}} răspunsuri ascunse" + other: "vezi {{count}} de răspunsuri ascunse" more_links: "{{count}} mai multe..." unread: "postarea nu a fost citită" + has_replies: + one: "Un răspuns" + few: "{{count}} răspunsuri" + other: "{{count}} de răspunsuri" + has_likes: + one: "O Apreciere" + few: "{{count}} Aprecieri" + other: "{{count}} de Aprecieri" + has_likes_title: + one: "O persoană a apreciat acest post." + few: "{{count}} persoane au apreciat acest post." + other: "{{count}} de persoane au apreciat acest post." + has_likes_title_only_you: "Ai apreciat acest post" + has_likes_title_you: + one: "Ai apreciat acest post împreună cu un alt utilizator." + few: "Ai apreciat acest post împreună cu alți {{count}} utilizatori." + other: "Ai apreciat acest post împreună cu alți {{count}} de utilizatori." errors: - create: "Ne pare rău , s-a semnalat o eroare în creerea postării dumneavoastră.Vă rugăm încercati iar." - edit: "Ne pare rău , s-a semnalat o eroare în editarea postării dumneavoastră . Vă rugăm încercati iar." - upload: "Ne pare rău ,s-a semnalat o eroare în încarcarea acelui fișier. Vă rugăm încercati iar." + create: "Ne pare rău, a apărut o eroare în creerea postării. Te rugăm să încerci iar." + edit: "Ne pare rău, a apărut o eroare în editarea postării. Te rugăm să încerci iar." + upload: "Ne pare rău, a apărut o eroare în încărcarea acelui fișier. Te rugăm să încerci iar." attachment_too_large: "Ne pare rău, fișierul pe care-l încarcați este prea mare (marimea maximă este de {{max_size_kb}}kb)." file_too_large: "Ne pare rău, fişierul pe care încercaţi să îl încărcaţi este prea mare (mărimea maximă este de {{max_size_kb}}kb)" - too_many_uploads: "Ne pare rău, puteți încarca doar cate un fișier." - too_many_dragged_and_dropped_files: "Ne pare rău, dar nu puteţi trage mai mult de 10 fişiere în acelaşi timp." - upload_not_authorized: "Ne pare rău, fișierul pe care-l încarcați nu este autorizat (extensia pentru autorizare: {{authorized_extensions}})." - image_upload_not_allowed_for_new_user: "Ne pare rău, noul utilizator nu poate încarca imagini." - attachment_upload_not_allowed_for_new_user: "Ne pare rău, noul utilizator nu poate încarca atașamnete." - attachment_download_requires_login: "Ne pare rău, dar trebuie să fiţi autentificat pentru a descarcă ataşamentele." + too_many_uploads: "Ne pare rău, poți încarca doar câte un fișier." + too_many_dragged_and_dropped_files: "Ne pare rău, dar nu poți trage mai mult de 10 fişiere în acelaşi timp." + upload_not_authorized: "Ne pare rău, fișierul pe care-l încarci nu este autorizat (extensia pentru autorizare: {{authorized_extensions}})." + image_upload_not_allowed_for_new_user: "Ne pare rău, un utilizator nou nu poate încarca imagini." + attachment_upload_not_allowed_for_new_user: "Ne pare rău, un utilizator nou nu poate încarca atașamnete." + attachment_download_requires_login: "Ne pare rău, dar trebuie să fii autentificat pentru a descarca ataşamente." abandon: - confirm: "Sunteți sigur că doriți să abandonați postarea?" + confirm: "Ești sigur că dorești să abandonezi postarea?" no_value: "Nu, pastrează" yes_value: "Da, abandonează" via_email: "acest post a sosit via email" - wiki: - about: "Acest post este un wiki; oricine poate edita" archetypes: save: 'Opțiuni de salvare' controls: reply: "începe compunerea unui răspuns pentru această postare" like: "apreciează acestă postăre" - has_liked: "ai retras aprecierea acestei postări " + has_liked: "ai apreciat acest răspuns" undo_like: "anuleazaă aprecierea" edit: "editează această postare" - edit_anonymous: "Ne pare rău, dar trebuie să fiţi autentificat pentru a edita." + edit_anonymous: "Ne pare rău, dar trebuie să fii autentificat pentru a edita acest post." flag: "marchează privat această postare pentru atenție sau trimite o notificare privată despre aceasta" delete: "șterge această postare" undelete: "rescrie această postare" @@ -1103,9 +1309,9 @@ ro: more: "Mai mult" delete_replies: confirm: - one: "Doriţi să ştergeţi răspunsul direct la acest mesaj?" - few: "Doriţi să ştergeţi cele {{count}} răspunsuri directe la acest mesaj?" - other: "Doriţi să ştergeţi cele {{count}} răspunsuri directe la acest mesaj?" + one: "Dorești să ștergi răspunsul direct la acest mesaj?" + few: "Dorești să ștergi cele {{count}} răspunsuri directe la acest mesaj?" + other: "Dorești să ștergi cele {{count}} de răspunsuri directe la acest mesaj?" yes_value: "Da, șterge și răspunsurile" no_value: "Nu, doar postarea" admin: "acțiuni administrative de postare" @@ -1122,13 +1328,13 @@ ro: few: "Marcate pentru amânare." other: "Marcate pentru amânare." it_too: - off_topic: "Și semnalează" - spam: "Și semnalează" - inappropriate: "Și semnalează" - custom_flag: "Și semnalează" - bookmark: "și marchează" - like: "Și acordă-i apreciere " - vote: "Și votează pentru" + off_topic: "Semnalează și tu" + spam: "Semnalează și tu" + inappropriate: "Semnalează și tu" + custom_flag: "Semnalează și tu" + bookmark: "Adaugă-l și tu la favorite" + like: "Apreciază și tu" + vote: "Votează și tu" undo: off_topic: "Retrage semnalare" spam: "Retrage semnalare" @@ -1137,21 +1343,13 @@ ro: like: "Retrage apreciere" vote: "Retrage vot" people: - off_topic: "{{icons}} Semnalază asta ca în afara discuției" - spam: "{{icons}} Semnalează asta ca spam" - spam_with_url: "{{icons}} semnalează ca spam" - inappropriate: "{{icons}} Semnalează asta ca necorespunzator" - notify_moderators: "{{icons}} moderatorii notificați" - notify_moderators_with_url: "{{icons}} moderatori notificați" - notify_user: "{{icons}} a trimis un mesaj" - notify_user_with_url: "{{icons}} a trimis un mesaj" - bookmark: "{{icons}} marchează asta" - like: "{{icons}} apreciat" - vote: "{{icons}} votat" + off_topic: "semnalat ca offtopic" + spam: "somnalat ca spam" + inappropriate: "semnalat ca nepotrivit" by_you: - off_topic: "Ați marcat ca fiind în afara discutiei" + off_topic: "Ați marcat ca fiind în afara discuției" spam: "Ați marcat ca fiind spam" - inappropriate: "Ați marcat ca necorespunzator" + inappropriate: "Ați marcat ca nepotrivit" notify_moderators: "Ați marcat pentru a fi moderată" notify_user: "Aţi trimis un mesaj către acest utilizator" bookmark: "Ați marcat ca semn de carte această postare" @@ -1161,72 +1359,68 @@ ro: off_topic: one: "Dvs. şi încă o persoană aţi marcat acest mesaj ca fiind în afară discuţiei." few: "Dvs. şi alte {{count}} persoane aţi marcat acest mesaj ca fiind în afară discuţiei." - other: "Dvs. şi alte {{count}} persoane aţi marcat acest mesaj ca fiind în afară discuţiei." + other: "Dvs. şi alte {{count}} de persoane aţi marcat acest mesaj ca fiind în afară discuţiei." spam: one: "Dvs. şi încă o persoană aţi marcat acest mesaj ca spam. " few: "Dvs. şi alte {{count}} persoane aţi marcat acest mesaj ca spam. " - other: "Dvs. şi alte {{count}} persoane aţi marcat acest mesaj ca spam. " + other: "Dvs. şi alte {{count}} de persoane aţi marcat acest mesaj ca spam. " inappropriate: one: "Dvs. şi încă o persoană aţi marcat acest mesaj ca inadecvat. " few: "Dvs. şi alte {{count}} persoane aţi marcat acest mesaj ca inadecvat. " - other: "Dvs. şi alte {{count}} persoane aţi marcat acest mesaj ca inadecvat. " + other: "Dvs. şi alte {{count}} de persoane aţi marcat acest mesaj ca inadecvat. " notify_moderators: one: "Dvs. şi încă o persoană aţi marcat acest mesaj pentru moderare." few: "Dvs. şi alte {{count}} persoane aţi marcat acest mesaj pentru moderare." - other: "Dvs. şi alte {{count}} persoane aţi marcat acest mesaj pentru moderare." + other: "Dvs. şi alte {{count}} de persoane aţi marcat acest mesaj pentru moderare." notify_user: one: "Dvs. şi încă o persoană aţi trimis un mesaj către acest utilizator." few: "Dvs. şi alte {{count}} persoane aţi trimis un mesaj către acest utilizator." - other: "Dvs. şi alte {{count}} persoane aţi trimis un mesaj către acest utilizator." + other: "Dvs. şi alte {{count}} de persoane aţi trimis un mesaj către acest utilizator." bookmark: one: "Dvs. şi încă o persoană aţi pus un semn de carte pentru această postare." few: "Dvs. şi alte {{count}} persoane aţi pus un semn de carte pentru această postare." - other: "Dvs. şi alte {{count}} persoane aţi pus un semn de carte pentru această postare." + other: "Dvs. şi alte {{count}} de persoane aţi pus un semn de carte pentru această postare." like: one: "Dvs. şi încă o persoană aţi apreciat aceasta." few: "Dvs. şi alte {{count}} persoane aţi apreciat aceasta." - other: "Dvs. şi alte {{count}} persoane aţi apreciat aceasta." + other: "Dvs. şi alte {{count}} de persoane aţi apreciat aceasta." vote: one: "Dvs. şi încă o persoană aţi votat pentru această postare." few: "Dvs. şi alte {{count}} persoane aţi votat pentru această postare." - other: "Dvs. şi alte {{count}} persoane aţi votat pentru această postare." + other: "Dvs. şi alte {{count}} de persoane aţi votat pentru această postare." by_others: off_topic: - one: "1 persoană a marcat acesta ca fiind în afară discuţiei" + one: "O persoană a marcat acesta ca fiind în afară discuţiei" few: "{{count}} persoane au marcat acesta ca fiind în afară discuţiei" - other: "{{count}} persoane au marcat acesta ca fiind în afară discuţiei" + other: "{{count}} de persoane au marcat acesta ca fiind în afară discuţiei" spam: - one: "1 persoană a marcat acesta ca spam" + one: "O persoană a marcat acesta ca spam" few: "{{count}} persoane au marcat acesta ca spam" - other: "{{count}} persoane au marcat acesta ca spam" + other: "{{count}} de persoane au marcat acesta ca spam" inappropriate: one: "o persoană a marcat acesta ca inadecvat" few: "{{count}} persoane au marcat acesta ca inadecvat" - other: "{{count}} persoane au marcat acesta ca inadecvat" + other: "{{count}} de persoane au marcat acesta ca inadecvat" notify_moderators: - one: "o persoană a marcat acest mesaj pentru moderare" + one: "O persoană a marcat acest mesaj pentru moderare" few: "{{count}} persoane au marcat acest mesaj pentru moderare" other: "{{count}} persoane au marcat acest mesaj pentru moderare" notify_user: one: "o persoană a trimis un mesaj către acest utilizator" - few: "{{count}} au trimis un mesaj către acest utilizator" - other: "{{count}} au trimis un mesaj către acest utilizator" + few: "{{count}} persoane au trimis un mesaj către acest utilizator" + other: "{{count}} de persoane au trimis un mesaj către acest utilizator" bookmark: - one: "o persoană a pus un semn de carte la acest mesaj" + one: "O persoană a pus un semn de carte la acest mesaj" few: "{{count}} persoane au pus un semn de carte la acest mesaj" - other: "{{count}} persoane au pus un semn de carte la acest mesaj" + other: "{{count}} de persoane au pus un semn de carte la acest mesaj" like: one: "o persoană a apreciat aceasta" few: "{{count}} persoane au apreciat aceasta" - other: "{{count}} persoane au apreciat aceasta" + other: "{{count}} de persoane au apreciat aceasta" vote: - one: "o persoană a votat pentru acest mesaj" + one: "O persoană a votat pentru acest mesaj" few: "{{count}} persoane au votat pentru acest mesaj" - other: "{{count}} persoane au votat pentru acest mesaj" - edits: - one: o editare - other: "{{count}} editari" - zero: nicio editare + other: "{{count}} de persoane au votat pentru acest mesaj" delete: confirm: one: "Sunteți sigur că vreți să ștergeți acest mesaj?" @@ -1254,6 +1448,7 @@ ro: category: can: 'can… ' none: '(nicio categorie)' + all: 'Toate categoriile' choose: 'Selectează o categorie…' edit: 'editează' edit_long: "Editează" @@ -1261,7 +1456,7 @@ ro: general: 'General' settings: 'Setări' delete: 'Șterge categorie' - create: 'Crează categorie' + create: 'Creează categorie' save: 'Salvează categorie' slug: 'Slug Categorie' slug_placeholder: '(Opțional) cuvinte-punctate pentru url' @@ -1307,12 +1502,11 @@ ro: title: "Urmărire" regular: title: "Normal" + description: "Veți fi notificat dacă cineva vă menționează @numele sau vă scrie un reply." muted: title: "Silențios" - description: "Nu veți fi niotificat de discuțiile noi din aceste categorii, ele nu vor apărea în tabul necitite." flagging: title: 'De ce marcați această postare ca fiind privată?' - private_reminder: 'steagurile sunt private, vizibile numai personalului' action: 'Marcare' take_action: "Actionează" notify_action: 'Mesaj' @@ -1360,10 +1554,9 @@ ro: title: "Desprinde" help: "Această discuţie va fi afişată în ordinea iniţială, nici un mesaj nu este promovat la inceputul listei." pinned_globally: - title: "Fixată Global" - help: "Această discuție a fost fixată global; va fi afișată în capătul tuturor listelor" + title: "Promovat Global" pinned: - title: "Fixată" + title: "Promovat" help: "Aceast mesaj va fi promovat. Va fi afişat la începutul discuţiei." invisible: help: "Această discuție este invizibilă; nu va fi afișată în listele de discuții și va fi accesată numai prin adresa directă" @@ -1384,7 +1577,7 @@ ro: one: "apreciere" few: "aprecieri" other: "aprecieri" - likes_long: "sunt {{number}} de aprecieri în această discuție" + likes_long: "sunt {{number}} aprecieri în această discuție" users: "Utilizatori" users_lowercase: one: "utilizator" @@ -1401,6 +1594,7 @@ ro: with_topics: "%{filter} Discuții" with_category: "%{filter} %{category} discuții" latest: + title: "Ultimele" help: "Discuții cu postări recente" hot: title: "Interesant" @@ -1416,23 +1610,19 @@ ro: title_in: "Categoria - {{categoryName}}" help: "toate discuțiile grupate pe categorii" unread: - title: - zero: "Necitite" - one: "(1) necitită" - other: "({{count}}) necitite" + title: "Necitite" + title_with_count: + one: "Necitit (1)" + few: "Necitite ({{count}})" + other: "Necitite ({{count}})" help: "discuțiile pe care le vizualizați sau urmariți momentan ce includ postări necitite" - lower_title_with_count: - one: "1 necitită" - other: "{{count}} necitite" new: - lower_title_with_count: - one: "o nouă" - other: "{{count}} noi" - lower_title: "noi" - title: - zero: "Noi" - one: "o nouă" - other: "({{count}}) noi" + lower_title: "nou" + title: "Noi" + title_with_count: + one: "Nou (1)" + few: "Noi ({{count}})" + other: "Noi ({{count}})" help: "discuții create în ultimele zile" posted: title: "Postările mele" @@ -1441,10 +1631,6 @@ ro: title: "Semne de carte" help: "discuții cu semne de carte" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" - other: "{{categoryName}} ({{count}})" help: "discuțiile recente din categoria {{categoryName}}" top: title: "Top" @@ -1453,6 +1639,8 @@ ro: title: "Dintotdeauna" yearly: title: "Anual" + quarterly: + title: "Trimestrial" monthly: title: "Lunar" weekly: @@ -1460,10 +1648,15 @@ ro: daily: title: "Zilnic" all_time: "Dintotdeauna" + this_year: "An" + this_quarter: "Trimestru" + this_month: "Lună" + this_week: "Săptămană" today: "Astăzi" + other_periods: "vezi topul" browser_update: 'Din nefericire, browserul dumneavoastră este prea vechi pentru a funcționa pe acest forum . Va rugăm reânoiți browserul.' permission_types: - full: "Crează / Răspunde / Vizualizează" + full: "Creează / Răspunde / Vizualizează" create_post: "Răspunde / Vizualizaează" readonly: "Vizualizaează" admin_js: @@ -1494,9 +1687,10 @@ ro: suspended: 'Suspendați:' private_messages_short: "Msgs" private_messages_title: "Mesaje" + mobile_title: "Mobil" space_free: "{{size}} liber" uploads: "încărcări" - backups: "salvări" + backups: "backups" traffic_short: "trafic" traffic: "Cereri web" page_views: "Cereri API" @@ -1516,6 +1710,7 @@ ro: refresh_report: "Reactualizează Raportul" start_date: "Data de început " end_date: "Data de sfârşit" + groups: "Toate grupurile" commits: latest_changes: "Ultimele schimbări: Vă rugăm reactualizați des!" by: "de către" @@ -1601,15 +1796,23 @@ ro: delete_confirm: "Șterg acest grup?" delete_failed: "Imposibil de șters grupul. Dacă este unul automat, nu se poate șterge." delete_member_confirm: "Şterge '%{username}' din grupul '%{group}'?" + delete_owner_confirm: "Revocă dreptul de proprietar pentru '%{username}'?" name: "Nume" add: "Adaugă" add_members: "Adaugă membri" custom: "Personalizat" + bulk_complete: "Utilizatorii au fost adăugați în grup." + bulk: "Adaugă în grup la grămadă" + bulk_paste: "Lipiți o listă de utilizatori sau email-uri, unul pe linie:" + bulk_select: "(selectați un grup)" automatic: "Automat" automatic_membership_email_domains: "Utilizatorii care se înregistrează cu un domeniu de email care se potriveşte cu unul din lista va fi adăugat automat în aces grup:" automatic_membership_retroactive: "Aplicaţi aceeaşi regulă pentru domeniul de email pentru a adaugă utilizatorii existenţi" default_title: "Titlu automat pentru toţi utilizatorii din acest grup" primary_group: "Setează automat că grup primar" + group_owners: Proprietari + add_owners: Adaugă proprietari + incoming_email_placeholder: "introduceți adresa de email" api: generate_master: "Generează cheie API principală" none: "Nu sunt chei API principale active deocamdată." @@ -1630,12 +1833,16 @@ ro: name: "Nume" none_installed: "Nu aveţi nici un plugin instalat." version: "Versiune" + enabled: "Activat?" + is_enabled: "D" + not_enabled: "N" change_settings: "Schimbă Setările" + change_settings_short: "Setări" howto: "Cum instalez un plugin?" backups: - title: "Rezervare" + title: "Backups" menu: - backups: "Rezerve" + backups: "Backups" logs: "Rapoarte" none: "Nicio rezervare valabilă." read_only: @@ -1647,7 +1854,7 @@ ro: title: "Dezactivearea modului doar-citire" label: "Dezactivează modul doar-citire" logs: - none: "Nu exista rapoarte..." + none: "Nu există rapoarte..." columns: filename: "Numele fișierului" size: "Mărime" @@ -1663,7 +1870,7 @@ ro: cancel: label: "Anulează" title: "Anulează operația curentă" - confirm: "Sunteți sigur că doriți să anulati operația curentă?" + confirm: "Sunteți sigur că doriți să anulați operația curentă?" backup: label: "Salvare de siguranţă" title: "Creați o rezervă" @@ -1679,11 +1886,9 @@ ro: is_disabled: "Restabilirea este dezactivată din setările siteului." label: "Restaurează" title: "Restabilește rezervă" - confirm: "Sunteți sigur că doriți restabilirea acestei rezerve?" rollback: label: "Revenire la situaţia anterioară" title: "Restabilește baza de date în stadiul anterior" - confirm: "Sunteți sigur că doriți restabilirea bazei de date în stadul precedent?" export_csv: user_archive_confirm: "Sunteţi sigur că doriţi să descărcaţi mesajele dvs.?" success: "Exportul a fost iniţiat. Veţi primi un mesaj de notificare când procesul se va termina." @@ -1696,6 +1901,8 @@ ro: screened_email: "Exportă lista totală a adreselor de email verificate în format CSV." screened_ip: "Exportă lista totală a adreselor de IP verificate în format CSV." screened_url: "Exportă lista totală a adreselor URL verificate în format CSV." + export_json: + button_text: "Exportă" invite: button_text: "Trimite o invitație" button_title: "Trimite o invitație" @@ -1706,6 +1913,7 @@ ro: header: "Titlu" top: "Top" footer: "Subsol" + embedded_css: "Embedded CSS" head_tag: text: "" title: "HTML care va fi inserat înaintea de tag-ul " @@ -1723,12 +1931,22 @@ ro: save: "Salvează" new: "Nou" new_style: "Stil nou" + import: "Importă" + import_title: "Selectați un fișier sau lipiți un text" delete: "Șterge" delete_confirm: "Șterge aceste preferințe?" about: "Modifică foaia de stil CSS și capetele HTML Modify CSS din site. Adaugă o preferința pentru a începe." color: "Culoare" opacity: "Opacitate" copy: "Copiază" + email_templates: + title: "Sabloane" + subject: "Subiect" + multiple_subjects: "Acest șablon are mai multe subiecte" + body: "Body" + none_selected: "Selectați un șablon pentru a începe editarea" + revert: "Revocați schimbările" + revert_confirm: "Ești sigur că vreți să revocați schimbările?" css_html: title: "CSS/HTML" long_title: "Customizarile CSS and HTML" @@ -1773,18 +1991,18 @@ ro: love: name: 'Iubire' description: "Culoarea butonului de apreciere." - wiki: - name: 'wiki' - description: "Culoarea de bază folosită pentru fundalul postărilor pe wiki." email: - title: "Email" + title: "Emails" settings: "Opțiuni" - all: "Toate" + templates: "Șabloane" + preview_digest: "Previzualizează rezumat" sending_test: "Trimite email de test..." error: "EROARE - %{server_error}" test_error: "S-a semnalat o problemă la trimtirerea email-ului. Vă rugăm verificați setările mailului, Verificați ca gazda sa nu bocheze conexiunile de email și reâncercați." sent: "Trimise" skipped: "Omise" + received: "Primite" + rejected: "Respinse" sent_at: "Trimise la" time: "Timp" user: "Utilizator" @@ -1794,7 +2012,6 @@ ro: send_test: "Trimite Email de test" sent_test: "trimis!" delivery_method: "Metoda de livrare" - preview_digest: "Previzualizează rezumat" refresh: "Reîmprospătează" format: "Format" html: "html" @@ -1802,6 +2019,18 @@ ro: last_seen_user: "Ultimul utilizator văzut:" reply_key: "Cheie de răspuns" skipped_reason: "Motiv omiterii" + incoming_emails: + from_address: "De la" + to_addresses: "Către" + cc_addresses: "Cc" + subject: "Subiect" + error: "Eroare" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Subiect..." + error_placeholder: "Eroare" logs: none: "Nu s-au găsit rapoarte." filters: @@ -1820,6 +2049,7 @@ ro: ip_address: "Adresa IP" topic_id: "ID Discuție" post_id: "ID Mesaj" + category_id: "ID categorie" delete: 'Șterge' edit: 'Editează' save: 'Salvează' @@ -1850,6 +2080,7 @@ ro: change_site_setting: "schimbă setările site-ului" change_site_customization: "schimbă preferințele site-ului" delete_site_customization: "șterge preferințele site-ului" + change_site_text: "schimbă textul site-ului" suspend_user: "suspendă utilizator" unsuspend_user: "reactivează utilizator" grant_badge: "acordă insignă" @@ -1859,6 +2090,15 @@ ro: delete_post: "şterge mesajul" impersonate: "joacă rolul" anonymize_user: "fă userul anonim" + change_category_settings: "schimbă setările categoriei" + delete_category: "șterge categorie" + create_category: "creează categorie" + block_user: "blochează utilizator" + unblock_user: "deblochează utilizator" + grant_admin: "Acordă titlul de Admin" + revoke_admin: "Revocă titlul de Admin" + grant_moderation: "Acordă titlul de Moderator" + revoke_moderation: "Revocă titlul de Moderator" screened_emails: title: "Email-uri filtrate" description: "Când cineva încearcă să creeze un nou cont, următorul email va fi verificat iar înregistrarea va fi blocată, sau o altă acțiune va fi inițiată." @@ -1923,9 +2163,9 @@ ro: pending: 'Utilizatori în așteptare de previzualizare' newuser: 'Utilizatori la nielul de încredere 0 (utilizator nou)' basic: 'Utilizatori la nivel de încredere 1 (utilizator de baza)' - regular: 'Utilizatori la nivel de încredere 2 (Utilizator normal)' - leader: 'Utilizatori la nivel de încredere 3 (Lider)' - elder: 'Utilizatori la nivel de încredere 4 (Batran)' + member: 'Utilizatori la nivel de încredere 2 (Membri)' + regular: 'Utilizatori la nivel de încredere 3 (Utilizator activ)' + leader: 'Utilizatori la nivel de încredere 4 (Lider)' staff: "Personalul" admins: 'Utilizatori admin' moderators: 'Moderatori' @@ -2027,9 +2267,10 @@ ro: deactivate_failed: "S-a semnalat o problemă la dezactivarea utilizatoprului." unblock_failed: 'S-a semnalat o problemă la deblocarea utlizatorului.' block_failed: 'S-a semnalat o problemă la blocarea utilizatorului.' - deactivate_explanation: "Un utilizator dezactivat va trebuii sa-și reactvieze emailul." + block_accept: 'Blochează utilizatorul' + deactivate_explanation: "Un utilizator dezactivat va trebui să-și revalideze email-ul." suspended_explanation: "Un utilizator suspendat nu se poate autentifica" - block_explanation: "Un utilizator blocat nu poate posta sau pornii o discuție." + block_explanation: "Un utilizator blocat nu poate posta sau porni o discuție." trust_level_change_failed: "S-a semnalat o problemă la schimbarea nivelului de încredere al utilizatorului." suspend_modal_title: "Suspendă utilizator" trust_level_2_users: "utilizatori de nivel de încredere 2 " @@ -2040,7 +2281,6 @@ ro: unlock_trust_level: "Deblochează Nivelul de Încredere" tl3_requirements: title: "Cerințe pentru nivelul 3 de încredere" - table_title: "În ultimele 100 de zile:" value_heading: "Valoarea" requirement_heading: "Cerințe" visits: "Vizite" @@ -2073,7 +2313,7 @@ ro: user_fields: title: "Câmpuri utilizator" help: "Adăugaţi câmpuri pe care utilizatorii le pot completa." - create: "Crează un câmp utilizator" + create: "Creează un câmp utilizator" untitled: "Fără titlu" name: "Nume câmp" type: "Tip câmp" @@ -2083,6 +2323,7 @@ ro: delete: "Șterge" cancel: "Anulează" delete_confirm: "Sunteți sigur că stergeți acest câmp utilizator?" + options: "Optiuni" required: title: "Necesar la înscriere?" enabled: "necesar" @@ -2098,9 +2339,14 @@ ro: field_types: text: 'Câmp Text' confirm: 'Confirmare' + dropdown: "Select" site_text: - none: "Alege un tip de conținut pentru editare." title: 'Conținut' + edit: 'editează' + revert: "Revocați schimbările" + revert_confirm: "Ești sigur că vreți să revocați schimbările?" + go_back: "Înapoi la căutare" + show_overriden: 'Arată doar rescrierile' site_settings: show_overriden: 'Arată doar rescrierile' title: 'Setări' @@ -2130,6 +2376,7 @@ ro: backups: "Rezervări" login: "Autentificare" plugins: "Plugin-uri" + user_preferences: "Preferințe" badges: title: Insigne new_badge: Insignă nouă @@ -2174,7 +2421,7 @@ ro: trigger_type: none: "reinprospatează zilnic" post_action: "Când un utilizator reacționează la un mesaj" - post_revision: "Când un utlizator crează sau editează un mesaj" + post_revision: "Când un utlizator creează sau editează un mesaj" trust_level_change: "Când un utilizator schimbă nivelul de încredere" user_change: "Când un utilizator este editat sau creat" preview: @@ -2185,10 +2432,6 @@ ro: error_help: "Vezi legăturile următoare pentru ajutor referitor la interogări pentru insigne." bad_count_warning: header: "ATENȚIE!" - grant_count: - zero: "Nu sunt insigne care pot fi asignate." - one: "1 insignă de alocat." - other: "%{count} insigne de alocat." sample: "Specimen:" grant: with: %{username} @@ -2202,6 +2445,33 @@ ro: name: "Nume" image: "Imagine" delete_confirm: "Sunteţi sigur că doriţi să ștergeți :%{name}: emoji?" + embedding: + confirm_delete: "Sunteți sigur că vreți să ștergeți acest host?" + sample: "Folosiți următorul cod HTML în site-ul dvs. pentru a crea și pentru a embed-ui topic-uri discourse. Înlocuiți REPLACE_ME cu URL-ul canonic al paginii pe care doriți să o embed-uiți." + title: "Embedding" + host: "Host-uri permise" + edit: "editează" + category: "Postează în categoria" + add_host: "Adaugă host" + settings: "Setări pentru embeding" + feed_settings: "Setări Feed" + embed_post_limit: "Numărul maxim de postări de încorporat." + save: "Salvați setările pentru embeding" + permalink: + title: "Link-uri" + url: "URL" + topic_id: "ID discuție" + topic_title: "Discuție" + post_id: "ID postare" + post_title: "Postare" + category_id: "ID categorie" + category_title: "Categorie" + external_url: "URL extern" + delete_confirm: Sigur doriți să ștergeți acest link ? + form: + label: "Nou:" + add: "Adăugați" + filter: "Căutare (URL sau URL extern)" lightbox: download: "descarcă" search_help: @@ -2217,6 +2487,7 @@ ro: categories: 'g apoi c Categorii' top: 'g, t Top' bookmarks: 'g, b Semne de carte' + messages: 'g, m Mesaje' navigation: title: 'Navigare' jump: '# Mergi la mesajul #' @@ -2226,37 +2497,37 @@ ro: next_prev: '`/~ selecția Urmatoare/Precedentă' application: title: 'Applicația' - create: 'c Crează discuție nouă' + create: 'c Creează discuție nouă' notifications: 'n Deschide notificare' + hamburger_menu: '= Deschide meniul hamburger' user_profile_menu: 'p Deschide meniu utilizator' show_incoming_updated_topics: '. Arată discuţiile actualizate' search: '/ Caută' - help: '? Deschide ajutorul de scurtături de tastatură' - dismiss_new_posts: 'x, r Respinge Nou/Mesaj' - dismiss_topics: 'x, t Respinge Discuţia' + help: '? Vezi comenzi rapide disponibile' + dismiss_new_posts: 'x, r Respinge Nou/Mesaje' + dismiss_topics: 'x, t Respinge discuţiile' + log_out: 'shift+z shift+z Ieșire din cont' actions: title: 'Acțiuni' bookmark_topic: 'f Comută semnul de carte pentru discuţie' - pin_unpin_topic: 'shift+p Pin/Unpin topic' + pin_unpin_topic: 'shift+p Promovează discuția' share_topic: 'shift s distribuie discuție' share_post: 's Distribuie mesajul' - reply_as_new_topic: 't Răspunde că discuţie legată' + reply_as_new_topic: 't Răspunde că discuţie conexă' reply_topic: 'shift r Raspunde la discuție' reply_post: 'r Răspunde la postare' quote_post: 'q Citează mesajul' like: 'l Apreciează mesajul' - flag: '! Marchează mesajul' - bookmark: 'b Marchează cu semn de carte postarea' + flag: '! Reclamă mesajul' + bookmark: 'b Salvează postarea' edit: 'e Editează mesaj' delete: 'd Șterge mesaj' - mark_muted: 'm apoi m Marchează discuția ca silențios' - mark_regular: 'm apoi r Marchează discuția ca normală' - mark_tracking: 'm apoi t Marchează discuția ca urmărită' - mark_watching: 'm apoi w Marchează discuția ca privită' + mark_muted: 'm apoi m Treceți discuția în mod silențios' + mark_regular: 'm, r Discuție normală (implicită)' + mark_tracking: 'm, t Urmăriți discuția' + mark_watching: 'm, w Urmăriți discuția îndeaproape' badges: title: Insigne - allow_title: "poate fi folosit ca titlu" - multiple_grant: "pot fi acordate de mai multe ori" badge_count: one: "1 Insignă" few: "%{count} Insigne" @@ -2273,7 +2544,7 @@ ro: none: "" badge_grouping: getting_started: - name: Să începem + name: Cum începem community: name: Communitate trust_level: @@ -2281,83 +2552,13 @@ ro: other: name: Altele posting: - name: Scrie mesaj - badge: - editor: - name: Editor - description: Primul mesaj editat - basic_user: - name: De baza - description: Acordată toate funcțiile esențiale - member: - name: Membru - description: Invitaţii Acordate - regular: - name: Normal - leader: - name: Lider - description: Acrodată recategorisește , redenumește, adrese urmărite și lounge - welcome: - name: Bine ai venit - description: A primit o apreceiere - autobiographer: - name: Autobiograf - description: Informația de profil completă a utilizatorului - anniversary: - name: Aniversare - description: Membru activ pentru un an, a scris măcar un mesaj - nice_post: - name: Mesaj drăguţ - description: A primit 10 aprecieri pentru o postare. Această insignă poate fi acordată de multiple ori - good_post: - name: Mesaj bun - description: A primit 25 de aprecieri pentru un mesaj. Această insignă poate fi acordată de mai multe ori - great_post: - name: Mesaj foarte bun - description: A primit 50 de aprecieri pentru un mesaj. Această insignă poate fi acordată de mai multe ori - nice_topic: - name: Discuţie Drăguţă - description: A primit 10 de aprecieri pentru o discuţie. Această insignă poate fi acordată de mai multe ori - good_topic: - name: Discuţie Bună - description: A primit 25 de aprecieri pentru o discuţie. Această insignă poate fi acordată de mai multe ori - great_topic: - name: Discuţie Foarte Bună - description: A primit 50 de aprecieri pentru o discuţie. Această insignă poate fi acordată de mai multe ori - nice_share: - name: Drăguţ - description: A împărţit un mesaj cu 25 utilizatori unici - good_share: - name: Bun - description: A împărţit un mesaj cu 300 utilizatori unici - great_share: - name: Perfect - description: A împărţit un mesaj cu 1000 utilizatori unici - first_like: - name: Prima apreciere - description: A apreciat un mesaj - first_flag: - name: Primul marcaj - description: A marcat un mesaj - promoter: - name: Promotor - description: A invitat un utilizator - campaigner: - name: Combatant - champion: - name: Campion - first_share: - name: Primul - description: A distribuit un mesaj - first_link: - name: Prima adresă - description: A adăugat o adresă internă catre altă discuție - first_quote: - name: Primul citat - description: A citat un alt utilizator - read_guidelines: - name: Citește reguli de ajutor - description: Citește comune - reader: - name: Cititorul - description: Citeşte fiecare mesaj dintr-o discuție cu mai mult de 100 de mesaje + name: Postând + google_search: | +

    Căutați cu Google

    +

    +

    +

    diff --git a/config/locales/client.ru.yml b/config/locales/client.ru.yml index 902f5de2b23..eca8a712e58 100644 --- a/config/locales/client.ru.yml +++ b/config/locales/client.ru.yml @@ -25,8 +25,8 @@ ru: mb: МБ tb: ТБ short: - thousands: "{{number}} тыс." - millions: "{{number}} млн" + thousands: "{{number}} тыс." + millions: "{{number}} млн." dates: time: "HH:mm" long_no_year: "D MMM HH:mm" @@ -138,6 +138,8 @@ ru: few: "%{count} года спустя" many: "%{count} лет спустя" other: "%{count} лет спустя" + previous_month: 'Предыдущий Месяц' + next_month: 'Следующий Месяц' share: topic: 'Поделиться ссылкой на эту тему' post: 'Ссылка на сообщение №%{postNumber}' @@ -146,8 +148,43 @@ ru: facebook: 'Поделиться ссылкой через Facebook' google+: 'Поделиться ссылкой через Google+' email: 'Поделиться ссылкой по электронной почте' + action_codes: + split_topic: "Разделил эту тему %{when}" + invited_user: "Пригласил %{who} %{when}" + removed_user: "Исключил %{who} %{when}" + autoclosed: + enabled: 'Закрыл тему %{when}' + disabled: 'Открыл тему %{when}' + closed: + enabled: 'Закрыл тему %{when}' + disabled: 'Открыл тему %{when}' + archived: + enabled: 'Заархивировал тему %{when}' + disabled: 'Разархивировал тему %{when}' + pinned: + enabled: 'Закрепил тему %{when}' + disabled: 'Открепил тему %{when}' + pinned_globally: + enabled: 'Закрепил тему глобально %{when}' + disabled: 'Открепил тему глобально %{when}' + visible: + enabled: 'Включил в списки %{when}' + disabled: 'Исключил из списков %{when}' topic_admin_menu: "действия администратора над темой" emails_are_disabled: "Все исходящие письма были глобально отключены администратором. Уведомления любого вида не будут отправляться на почту." + s3: + regions: + us_east_1: "US East (N. Virginia)" + us_west_1: "US West (N. California)" + us_west_2: "US West (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "EU (Ireland)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asia Pacific (Singapore)" + ap_southeast_2: "Asia Pacific (Sydney)" + ap_northeast_1: "Asia Pacific (Tokyo)" + ap_northeast_2: "Asia Pacific (Seoul)" + sa_east_1: "South America (Sao Paulo)" edit: 'отредактировать название и раздел темы' not_implemented: "Извините, эта функция еще не реализована!" no_value: "Нет" @@ -161,6 +198,7 @@ ru: admin_title: "Админка" flags_title: "Жалобы" show_more: "показать дальше" + show_help: "Cправка" links: "Ссылки" links_lowercase: one: "ссылка" @@ -180,6 +218,8 @@ ru: more: "Больше" less: "Меньше" never: "никогда" + every_30_minutes: "каждые 30 минут" + every_hour: "каждый час" daily: "ежедневно" weekly: "еженедельно" every_two_weeks: "каждые две недели" @@ -193,6 +233,7 @@ ru: other: "{{count}} букв" suggested_topics: title: "Похожие темы" + pm_title: "Похожие Сообщения" about: simple_title: "Информация" title: "Информация про %{title}" @@ -246,6 +287,7 @@ ru: saved: "Сохранено!" upload: "Загрузить" uploading: "Загрузка..." + uploading_filename: "Загрузка файла {{filename}}..." uploaded: "Загружено!" enable: "Включить" disable: "Отключить" @@ -253,6 +295,7 @@ ru: revert: "Вернуть" failed: "Проблема" switch_to_anon: "Анонимный режим" + switch_from_anon: "Выйти из анонимного режима" banner: close: "Больше не показывать это объявление." edit: "Редактировать это объявление >>" @@ -277,7 +320,7 @@ ru: many: "В этой теме {{count}} сообщений, ожидающих проверки" other: "В этой теме {{count}} сообщений, ожидающих проверки" confirm: "Сохранить" - delete_prompt: "Вы уверены, что хотите удалить пользователя %{username}? Это приведет к удалению всех его сообщений, а также заблокирует email и ip адрес." + delete_prompt: "Вы уверены, что хотите удалить %{username}? Это также удалит все его сообщения и заблокирует его email и IP-адрес." approval: title: "Сообщения для проверки" description: "Ваше сообщение отправлено, но требует проверки и утверждения модератором. Пожалуйста, будьте терпеливы." @@ -324,6 +367,9 @@ ru: many: "%{count} пользователей" other: "%{count} пользователей" groups: + add: "Добавить" + selector_placeholder: "Добавить участников" + owner: "владелец" visible: "Группа видима всем пользователям" title: one: "группа" @@ -331,14 +377,23 @@ ru: many: "групп" other: "групп" members: "Участники" + topics: "Темы" posts: "Сообщения" + messages: "Сообщения" alias_levels: - title: "Кто может использовать данную группу как псевдоним?" nobody: "Никто" only_admins: "Только администраторы" mods_and_admins: "Только модераторы и администраторы" members_mods_and_admins: "Только члены группы, модераторы и администраторы" everyone: "Все" + trust_levels: + title: "Уровень доверия участника при создании:" + none: "(Нет)" + notifications: + watching: + title: "Отслеживание" + tracking: + title: "Следить" user_action_groups: '1': "Выразил симпатий" '2': "Получил симпатий" @@ -348,7 +403,6 @@ ru: '6': "Ответы" '7': "Упоминания" '9': "Цитаты" - '10': "Избранное" '11': "Изменения" '12': "Отправленные" '13': "Входящие" @@ -358,6 +412,15 @@ ru: all_subcategories: "Все подкатегории" no_subcategory: "Вне подкатегорий" category: "Раздел" + category_list: "Показать список разделов" + reorder: + title: "Упорядочивание разделов" + title_long: "Реорганизация списка разделов" + fix_order: "Зафиксировать порядковые номера" + fix_order_tooltip: "Не всем разделам назначен уникальный порядковый номер. Это может привести к непредсказуемому порядку разделов." + save: "Сохранить порядок" + apply_all: "Применить" + position: "Порядковый номер" posts: "Сообщения" topics: "Темы" latest: "Последние" @@ -391,6 +454,8 @@ ru: topics_entered: "посещено тем" post_count: "сообщений" confirm_delete_other_accounts: "Вы уверены, что хотите удалить эти учетные записи?" + user_fields: + none: "(выберите)" user: said: "{{username}}:" profile: "Профиль" @@ -402,11 +467,21 @@ ru: private_messages: "Личные сообщения" activity_stream: "Активность" preferences: "Настройки" + expand_profile: "Развернуть" bookmarks: "Закладки" bio: "Обо мне" - invited_by: "Приглашен пользователем" - trust_level: "Уровень доверия" + invited_by: "Пригласил" + trust_level: "Уровень" notifications: "Уведомления" + statistics: "Статистика" + desktop_notifications: + label: "Оповещения" + not_supported: "К сожалению, оповещения не поддерживаются этим браузером." + perm_default: "Включить оповещения" + perm_denied_btn: "Отказано в разрешении" + disable: "Отключить оповещения" + enable: "Включить оповещения" + each_browser_note: "Примечание: эта настройка устанавливается в каждом браузере индивидуально." dismiss_notifications: "Пометить все прочитанными" dismiss_notifications_tooltip: "Пометить все непрочитанные уведомления прочитанными" disable_jump_reply: "Не переходить к вашему новому сообщению после ответа" @@ -419,6 +494,7 @@ ru: admin: "{{user}} - админ" moderator_tooltip: "{{user}} - модератор" admin_tooltip: "{{user}} - админ" + blocked_tooltip: "Этот пользователь заблокирован" suspended_notice: "Пользователь заморожен до {{date}}." suspended_reason: "Причина:" github_profile: "Github" @@ -428,7 +504,7 @@ ru: tracked_categories: "Отслеживаемые разделы" tracked_categories_instructions: "Автоматически следить за всеми новыми темами из следующих разделов. Счетчик новых и непрочитанных сообщений будет появляться рядом с названием темы." muted_categories: "Выключенные разделы" - muted_categories_instructions: "Вы не будете получать уведомления о новых темах в этих разделах. Также, они не будут показываться во вкладке Непрочитанное." + muted_categories_instructions: "Не уведомлять меня о новых темах в этих разделах и не показывать новые темы на странице «Непрочитанные»." delete_account: "Удалить мою учётную запись" delete_account_confirm: "Вы уверены, что хотите удалить свою учётную запись? Отменить удаление будет невозможно!" deleted_yourself: "Ваша учётная запись была успешно удалена." @@ -438,6 +514,7 @@ ru: users: "Пользователи" muted_users: "Выключено" muted_users_instructions: "Не отображать уведомления от этих пользователей." + muted_topics_link: "Показать темы \"Без уведомлений\"" staff_counters: flags_given: "полезные жалобы" flagged_posts: "сообщения с жалобами" @@ -446,8 +523,15 @@ ru: warnings_received: "предупреждения" messages: all: "Все" - mine: "Мои" - unread: "Непрочитанные" + inbox: "Входящие" + sent: "Отправленные" + archive: "Архив" + groups: "Мои группы" + bulk_select: "Выберите сообщения" + move_to_inbox: "Переместить во входящие" + move_to_archive: "Архив" + failed_to_move: "Невозможно переместить выделенные сообщения (возможно, у вас проблемы с Интернетом)" + select_all: "Выбрать все" change_password: success: "(письмо отправлено)" in_progress: "(отправка письма)" @@ -479,6 +563,7 @@ ru: upload_title: "Загрузка собственного аватара" upload_picture: "Загрузить изображение" image_is_not_a_square: "Внимание: мы обрезали ваше изображение; ширина и высота не равны друг другу." + cache_notice: "Вы изменили аватар. Аватар поменяется через некоторое время из-за кеширования браузера." change_profile_background: title: "Фон профиля" instructions: "Картинки фона профилей будут отцентрированы и по-умолчанию имеют ширину 850 пикселей." @@ -492,9 +577,10 @@ ru: invalid: "Введите действующий адрес электронной почты" authenticated: "Ваш адрес электронной почты подтвержден {{provider}}" frequency: - zero: "Получать уведомления о новых непрочитанных сообщениях незамедлительно." - one: "Мы отправим вам письмо только если не видели вас онлайн в последние несколько минут." - other: "Мы отправим вам письмо только если вы не были в онлайне последние {{count}} мин." + one: "Мы отправим вам письмо только в том случае, если вы более минуты находитесь оффлайн." + few: "Мы отправим вам письмо только в том случае, если вы не были онлайн последние {{count}} минуты." + many: "Мы отправим вам письмо только в том случае, если вы не были онлайн последние {{count}} минут." + other: "Мы отправим вам письмо только в том случае, если вы не были онлайн последние {{count}} минyт." name: title: "Имя" instructions: "Ваше полное имя (опционально)" @@ -530,48 +616,78 @@ ru: title: "Иконка карточки пользователя" website: "Веб-сайт" email_settings: "E-mail" + like_notification_frequency: + always: "Всегда" + never: "Никогда" + email_previous_replies: + always: "всегда" + never: "никогда" email_digests: - title: "В случае моего отсутствия на форуме присылайте мне сводку новостей по почте:" + title: "В случае моего отсутствия на сайте присылайте мне сводку новостей по почте:" + every_30_minutes: "каждые 30 минут" + every_hour: "каждый час" daily: "ежедневно" every_three_days: "каждые 3 дня" weekly: "еженедельно" every_two_weeks: "каждые 2 недели" email_direct: "Присылать почтовое уведомление, когда кто-то цитирует меня, отвечает на мой пост, упоминает мой @псевдоним или приглашает меня в тему" email_private_messages: "Присылать почтовое уведомление, когда кто-то оставляет мне сообщение" + email_always: "Присылать почтовое уведомление, даже если я присутствую на сайте" other_settings: "Прочее" categories_settings: "Разделы" new_topic_duration: label: "Считать темы новыми, если" - not_viewed: "Еще не просмотрены" - last_here: "создано после вашего последнего визита" + not_viewed: "ещё не просмотрены" + last_here: "созданы после вашего последнего визита" + after_1_day: "созданы за прошедший день" + after_2_days: "созданы за последние 2 дня" + after_1_week: "созданы за последнюю неделю" + after_2_weeks: "созданы за последние 2 недели" auto_track_topics: "Автоматически отслеживать темы, которые я просматриваю" auto_track_options: never: "никогда" immediately: "немедленно" + after_30_seconds: "более 30 секунд" + after_1_minute: "более 1ой минуты" + after_2_minutes: "более 2х минут" + after_3_minutes: "более 3х минут" + after_4_minutes: "более 4х минут" + after_5_minutes: "более 5 минут" + after_10_minutes: "более 10 минут" invited: - search: "введите текст для поиска приглашений..." + search: "Введите текст для поиска по приглашениям..." title: "Приглашения" - user: "Приглашенный пользователь" - truncated: "Отображаются первые {{count}} приглашений." + user: "Кто приглашен" + sent: "Когда" + none: "Приглашения, ожидающие одобрения, отсутствуют." + truncated: + one: "Первое приглашение" + few: "Первые {{count}} приглашений" + many: "Первые {{count}} приглашений" + other: "Первые {{count}} приглашений" redeemed: "Принятые приглашения" - redeemed_tab: "Принято" + redeemed_tab: "Принятые" + redeemed_tab_with_count: "Принятые ({{count}})" redeemed_at: "Принято" pending: "Еще не принятые приглашения" - pending_tab: "Ожидает одобрения" - topics_entered: "Просмотрено тем" - posts_read_count: "Прочитано сообщений" - expired: "Это истёкшее приглашение." - rescind: "Отменить приглашение" + pending_tab: "Ожидающие" + pending_tab_with_count: "Ожидающие ({{count}})" + topics_entered: "Просмотрел тем" + posts_read_count: "Прочитал сообщений" + expired: "Это приглашение истекло." + rescind: "Отозвать" rescinded: "Приглашение отозвано" reinvite: "Повторить приглашение" reinvited: "Приглашение выслано повторно" - time_read: "Время чтения" - days_visited: "Дней посещения" + time_read: "Времени читал" + days_visited: "Дней посещал" account_age_days: "Дней с момента регистрации" create: "Отправить приглашение" + generate_link: "Скопировать ссылку для приглашений" + generated_link_message: '

    Пригласительная ссылка сгенерирована!

    Эта ссылка действует только для следующего e-mail:%{invitedEmail}

    ' bulk_invite: - none: "Вы еще никого не приглашали сюда. Вы можете отправить индивидуальные приглашения или пригласить группу людей сразу загрузив групповой файл приглашений." - text: "Групповое приглашение из файла" + none: "Вы еще никого не приглашали на этот форум. Можно отправить индивидуальные приглашения по одному, или же пригласить сразу несколько людей из файла." + text: "Пригласить всех из файла" uploading: "Загрузка..." success: "Файл успешно загружен, вы получите сообщение, когда процесс будет завершен." error: "В процессе загрузки файла '{{filename}}' произошла ошибка: {{message}}" @@ -583,6 +699,15 @@ ru: same_as_email: "Ваш пароль такой же, как и ваш email." ok: "Допустимый пароль." instructions: "Не менее %{count} символов." + summary: + title: "Сводка" + stats: "Статистика" + top_replies: "Лучшие сообщения" + more_replies: "... другие сообщения" + top_topics: "Лучшие темы" + more_topics: "... другие темы" + top_badges: "Самые престижные награды" + more_badges: "... другие награды" associated_accounts: "Связанные аккаунты" ip_address: title: "Последний IP адрес" @@ -608,11 +733,13 @@ ru: server: "Ошибка сервера" forbidden: "Доступ закрыт" unknown: "Ошибка" + not_found: "Страница не найдена" desc: network: "Пожалуйста, проверьте ваше соединение." network_fixed: "Похоже, сеть появилась." server: "Ошибка: {{status}}" forbidden: "У вас нет доступа для просмотра этого." + not_found: "Упс, произошла попытка загрузить несуществующую ссылку" unknown: "Что-то пошло не так." buttons: back: "Вернуться" @@ -623,7 +750,6 @@ ru: logout: "Вы вышли." refresh: "Обновить" read_only_mode: - enabled: "Администратор включил режим сайта ТОЛЬКО ДЛЯ ЧТЕНИЯ. Вы можете продолжать просматривать сайт. В данном режиме Ваши посты не будут сохранятся и публиковаться на сайте." login_disabled: "Вход отключён, пока сайт в режиме «только для чтения»" learn_more: "подробнее..." year: 'год' @@ -642,10 +768,17 @@ ru: one: ответ few: ответа other: ответов + signup_cta: + sign_up: "Зарегистрироваться" + hide_session: "Напомнить мне завтра" + hide_forever: "Нет, спасибо" + hidden_for_session: "Хорошо, напомню завтра. Кстати, зарегистрироваться можно также и с помощью кнопки \"Войти\"." + intro: "Привет! :heart_eyes: Кажется, форум пришелся вам по душе, но вы все еще не зарегистрировались." + value_prop: "После регистрации мы сможем запоминать, где вы закончили чтение, а когда вы заглянете в ту или иную тему снова, мы откроем ее там, где вы остановились в прошлый раз. Мы также сможем уведомлять вас о новых ответах в любимых темах в вашем личном кабинете или по электронной почте. А самое приятное - после регистрации можно ставить сердечки, тем самым выражая свою симпатию автору. :heartbeat:" summary: enabled_description: "Вы просматриваете выдержку из темы - только самые интересные сообщения по мнению сообщества." - description: "Есть {{count}} ответ(ов)." - description_time: "В теме {{count}} сообщений с ожидаемым временем чтения {{readingTime}} минут." + description: "Есть {{replyCount}} ответов." + description_time: "{{replyCount}} ответов с предполагаемым временем прочтения около {{readingTime}} минут." enable: 'Сводка по теме' disable: 'Показать все сообщения' deleted_filter: @@ -663,7 +796,7 @@ ru: created: 'Создан' created_lowercase: 'создано' trust_level: 'Уровень доверия' - search_hint: 'псевдоним, e-mail или IP адрес' + search_hint: 'Псевдоним, e-mail или IP адрес' create_account: title: "Зарегистрироваться" failed: "Произошла ошибка. Возможно, этот Email уже используется. Попробуйте восстановить пароль" @@ -699,6 +832,9 @@ ru: admin_not_allowed_from_ip_address: "Вы не можете войти в качестве админа с этого IP адреса." resend_activation_email: "Щелкните здесь, чтобы мы повторно выслали вам письмо для активации учетной записи." sent_activation_email_again: "По адресу {{currentEmail}} повторно отправлено письмо с инструкциями по активации вашей учетной записи. Доставка сообщения может занять несколько минут. Имейте в виду, что иногда по ошибке письмо может попасть в папку Спам." + to_continue: "Войдите пожалуйста" + preferences: "Вам необходимо войти на сайт для редактирования настроек пользователя" + forgot: "Я не помню данные моего аккаунта" google: title: "С помощью Google" message: "Вход с помощью учетной записи Google (убедитесь, что блокировщик всплывающих окон отключен)" @@ -708,6 +844,8 @@ ru: twitter: title: "С помощью Twitter" message: "Вход с помощью учетной записи Twitter (убедитесь, что блокировщик всплывающих окон отключен)" + instagram: + message: "Вход с помощью учетной записи Instagram (убедитесь, что блокировщик всплывающих окон отключен)" facebook: title: "С помощью Facebook" message: "Вход с помощью учетной записи Facebook (всплывающие окна должны быть разрешены)" @@ -721,74 +859,86 @@ ru: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Смайлики :)" + more_emoji: "еще..." + options: "Дополнительные опции" + whisper: "внутреннее сообщение" add_warning: "Это официальное предупреждение." + toggle_whisper: "Внутреннее сообщение" posting_not_on_topic: "В какой теме вы хотите ответить?" saving_draft_tip: "Сохранение..." - saved_draft_tip: "сохранено" - saved_local_draft_tip: "сохранено локально" + saved_draft_tip: "Сохранено" + saved_local_draft_tip: "Сохранено локально" similar_topics: "Ваша тема похожа на..." - drafts_offline: "Сохраненные черновики" + drafts_offline: "Черновики, сохраненные в офлайн" + group_mentioned: "При использовании {{group}}, {{count}} людям будут отправлены уведомления." error: - title_missing: "Требуется заголовок" - title_too_short: "Заголовок должен быть не менее {{min}} символов" - title_too_long: "Заголовок не может быть длиннее {{max}} символов" + title_missing: "Требуется название темы" + title_too_short: "Название темы должно быть не короче {{min}} символов" + title_too_long: "Название темы не может быть длиннее {{max}} символов" post_missing: "Сообщение не может быть пустым" - post_length: "Сообщение должно содержать минимум {{min}} символов" - try_like: 'А вы пробовали лайкнуть сообщение с помощью кнопки ?' + post_length: "Сообщение должно быть не короче {{min}} символов" + try_like: 'Пробовали ли вы выразить симпатию с помощью кнопки ?' category_missing: "Нужно выбрать раздел" save_edit: "Сохранить" reply_original: "Ответ в первоначальной теме" reply_here: "Ответить в текущей теме" reply: "Ответить" - cancel: "Отменить" + cancel: "Отмена" create_topic: "Создать тему" - create_pm: "Сообщение" + create_pm: "Личное сообщение" title: "Или нажмите Ctrl+Enter" users_placeholder: "Добавить пользователя" - title_placeholder: "Название: суть обсуждения коротким предложением" - edit_reason_placeholder: "почему вы хотите изменить?" + title_placeholder: "Название: суть темы коротким предложением" + edit_reason_placeholder: "Причина редактирования..." show_edit_reason: "(добавить причину редактирования)" + reply_placeholder: "Поддерживаемые форматы: Markdown, BBCode и HTML. Чтобы вставить картинку, перетащите ее сюда или вставьте с помощью Ctrl+V, Command-V, или нажмите правой кнопкой мыши и выберите меню \"вставить\"." view_new_post: "Посмотреть созданное вами сообщение." saving: "Сохранение..." saved: "Сохранено!" - saved_draft: "Черновик сообщения. Нажмите, чтобы продолжить редактирование." + saved_draft: "Черновик сохранен; нажмите сюда, чтобы его открыть." uploading: "Загрузка..." - show_preview: 'предпросмотр »' + show_preview: 'показать предпросмотр »' hide_preview: '« скрыть предпросмотр' - quote_post_title: "Процитировать всё сообщение" - bold_title: "Выделение жирным" + quote_post_title: "Процитировать сообщение целиком" + bold_title: "Жирный" bold_text: "текст, выделенный жирным" - italic_title: "Выделение курсивом" + italic_title: "Курсив" italic_text: "текст, выделенный курсивом" link_title: "Ссылка" link_description: "введите описание ссылки" link_dialog_title: "Вставить ссылку" - link_optional_text: "необязательное название" + link_optional_text: "текст ссылки" + link_placeholder: "Пример: http://example.com \"текст ссылки\"" quote_title: "Цитата" - quote_text: "Цитата" - code_title: "Форматированный текст" - code_text: "добавьте 4 символа пробела, перед форматированным текстом" + quote_text: "Впишите текст цитаты сюда" + code_title: "Текст \"как есть\" (без применения форматирования)" + code_text: "впишите текст сюда; также, отключить форматирование текста можно, начав строку с четырех пробелов" upload_title: "Загрузить" - upload_description: "введите здесь описание загружаемого объекта" + upload_description: "введите описание загружаемого объекта" olist_title: "Нумерованный список" - ulist_title: "Маркированный список" - list_item: "Элемент списка" + ulist_title: "Ненумерованный список" + list_item: "Пункт первый" heading_title: "Заголовок" heading_text: "Заголовок" hr_title: "Горизонтальный разделитель" - undo_title: "Отменить" - redo_title: "Повторить" - help: "Справка по Markdown" + help: "Справка по форматированию (Markdown)" toggler: "скрыть / показать панель редактирования" + modal_ok: "OK" + modal_cancel: "Отмена" + cant_send_pm: "К сожалению, вы не можете отправлять сообщения пользователю %{username}." admin_options_title: "Дополнительные настройки темы" auto_close: label: "Закрыть тему через:" error: "Пожалуйста, введите корректное значение." based_on_last_post: "Не закрывать, пока не пройдет хотя бы такой промежуток времени с момента последнего сообщения в этой теме." all: - examples: 'Введите количество часов (24), абсолютное время (17:30), или дату и время (2013-11-22 14:00).' + examples: 'Введите количество часов (напр., 24), время (напр., 17:30) или дату и время (2013-11-22 14:00).' limited: units: "(кол-во часов)" examples: 'Введите количество часов (24).' @@ -800,7 +950,6 @@ ru: mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -810,8 +959,20 @@ ru: moved_post: "

    {{username}} переместил(а) {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Вы награждены: {{description}}

    " + alt: + mentioned: "Упомянуто" + quoted: "Процитировано пользователем" + replied: "Ответил" + posted: "Опубликовано" + edited: "Изменил ваше сообщение" + liked: "Понравилось ваше сообщение" + private_message: "Личное сообщение от" + invitee_accepted: "Приглашение принято" + linked: "Ссылка на ваше сообщение" + granted_badge: "Награда получена от" popup: mentioned: '{{username}} упомянул вас в "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} упомянул вас в "{{topic}}" - {{site_title}}' quoted: '{{username}} процитировал Вас в "{{topic}}" - {{site_title}}' replied: '{{username}} ответил вам в "{{topic}}" - {{site_title}}' posted: '{{username}} написал в "{{topic}}" - {{site_title}}' @@ -823,32 +984,53 @@ ru: from_my_computer: "From my device" from_the_web: "From the web" remote_tip: "ссылка на изображение" - remote_tip_with_attachments: "ссылка на изображение или файл ({{authorized_extensions}})" + remote_tip_with_attachments: "ссылка на изображение или файл {{authorized_extensions}}" + local_tip: "выбрать изображения с вашего устройства" + local_tip_with_attachments: "выбрать изображения или файлы с вашего устройства {{authorized_extensions}}" hint: "(вы так же можете перетащить объект в редактор для его загрузки)" + hint_for_supported_browsers: "вы так же можете перетащить или скопировать изображения в редактор" uploading: "Загрузка" select_file: "Выбрать файл" image_link: "ссылка, на которую будет указывать ваше изображение" search: - title: "поиск по темам, сообщениям, пользователям или разделам" + sort_by: "Сортировка" + relevance: "По смыслу" + latest_post: "С недавними сообщениями" + most_viewed: "Самые просматриваемые" + most_liked: "Больше всего симпатий" + select_all: "Выбрать все" + clear_all: "Сбросить все" + result_count: + one: "Найдено 1: \"{{term}}\"" + few: "Найдено {{count}}: \"{{term}}\"" + many: "Найдено {{count}}: \"{{term}}\"" + other: "Найдено {{count}}: \"{{term}}\"" + title: "Поиск по темам, сообщениям, псевдонимам и разделам" no_results: "Ничего не найдено." + no_more_results: "Больше ничего не найдено." + search_help: Справка по поиску searching: "Поиск ..." post_format: "#{{post_number}} от {{username}}" context: user: "Искать сообщения от @{{username}}" category: "Искать в разделе \"{{category}}\"" topic: "Искать в этой теме" - private_messages: "Поиск в сообщениях" + private_messages: "Искать в личных сообщениях" + hamburger_menu: "перейти к другому списку тем или другому разделу" + new_item: "новый" go_back: 'вернуться' not_logged_in_user: 'страница пользователя с историей его последней активности и настроек' current_user: 'перейти на вашу страницу пользователя' topics: bulk: + unlist_topics: "Исключить из списков" reset_read: "Сбросить прочтённые" delete: "Удалить темы" - dismiss_posts: "Отложить сообщения" - dismiss_posts_tooltip: "Сбросить текущие непрочитанные сообщения в этих темах сейчас, но снова показывать в непрочитанных, когда появятся новые ответы." - dismiss_topics: "Отложить темы" - dismiss_topics_tooltip: "Больше не показывать эти темы в непрочитанных, когда в них появятся новые ответы." + dismiss: "OK" + dismiss_read: "Отклонить все непрочитанные" + dismiss_button: "Отложить..." + dismiss_tooltip: "Отложить новые сообщения или перестать следить за этими темами" + also_dismiss_topics: "Перестать следить за этими темами, чтобы они никогда больше не высвечивались как непрочитанные" dismiss_new: "Отложить новые" toggle: "Вкл./выкл. выбор нескольких тем" actions: "Массовое действие" @@ -873,9 +1055,6 @@ ru: category: "В разделе {{category}} отсутствуют темы." top: "Нет обсуждаемых тем." search: "Ничего не найдено." - educate: - new: '

    Это список новых тем.

    По-умолчанию, тема считается новой и отображается с индикатором новое, если она была создана в течении последних 2-х дней.

    Это можно изменить в своих настройках.

    ' - unread: '

    Это ваш список непрочитанных тем.

    По-умолчанию, темы считаются непрочитанными и напротив них отображается счетчик непрочитанных сообщений 1, если вы:

    • создали тему;
    • ответили в теме;
    • читали тему более 4-х минут.

    Или же если вы намеренно выбрали Следить или Наблюдать в настройках уведомлений в самом низу темы.

    Эту функциональность можно дополнительно отрегулировать в ваших настройках.

    ' bottom: latest: "Тем больше нет." hot: "Популярных тем больше нет." @@ -888,10 +1067,18 @@ ru: bookmarks: "Больше нет избранных тем." search: "Больше ничего не найдено." topic: + unsubscribe: + change_notification_state: "Ваше текущее состояние уведомлений" filter_to: "{{post_count}} сообщений в теме" create: 'Создать Тему' create_long: 'Создать новую тему' private_message: 'Написать сообщение' + archive_message: + help: 'Переместить сообщение в архив' + title: 'Архив' + move_to_inbox: + title: 'Переместить во входящие' + help: 'Переместить сообщение во входящие' list: 'Темы' new: 'новая тема' unread: 'непрочитанно' @@ -942,7 +1129,7 @@ ru: toggle_information: "скрыть / показать подробную информацию о теме" read_more_in_category: "Хотите почитать что-нибудь еще? Можно посмотреть темы в {{catLink}} или {{latestLink}}." read_more: "Хотите почитать что-нибудь еще? {{catLink}} или {{latestLink}}." - read_more_MF: "У вас { UNREAD, plural, =0 {} one { 1 непрочитанное } other { # непрочитанных } } { NEW, plural, =0 {} one { {BOTH, select, true{and } false { } other{}} 1 новая тема} other { {BOTH, select, true{and } false { } other{}} # новых тем} } осталось, или {CATEGORY, select, true {посмотреть другие темы в{catLink}} false {{latestLink}} other {}}" + read_more_MF: "У вас { UNREAD, plural, =0 {} one { 1 непрочитанная } other { # непрочитанных } } { NEW, plural, =0 {} one { {BOTH, select, true{and } false { } other{}} 1 новая тема} other { {BOTH, select, true{and } false { } other{}} # новых тем} } осталось, или {CATEGORY, select, true {посмотрите другие темы в разделе {catLink}} false {{latestLink}} other {}}" browse_all_categories: Просмотреть все разделы view_latest_topics: посмотреть последние темы suggest_create_topic: Почему бы вам не создать новую тему? @@ -958,7 +1145,7 @@ ru: title: текущее местоположение в теме go_top: "перейти наверх" go_bottom: "перейти вниз" - go: "перейти" + go: "=>" jump_bottom: "перейти к последнему сообщению" jump_bottom_with_number: "перейти к сообщению %{post_number}" total: всего сообщений @@ -993,15 +1180,17 @@ ru: title: "Следить" description: "Количество непрочитанных сообщений появится рядом с названием этой темы. Вам придёт уведомление, только если кто-нибудь упомянет ваш @псевдоним или ответит на ваше сообщение." regular: + title: "Уведомлять" description: "Вам придёт уведомление, только если кто-нибудь упомянет ваш @псевдоним или ответит на ваше сообщение." regular_pm: + title: "Уведомлять" description: "Вам придёт уведомление, только если кто-нибудь упомянет ваш @псевдоним или ответит на ваше сообщение." muted_pm: title: "Без уведомлений" description: "Никогда не получать уведомлений, связанных с этой беседой." muted: title: "Без уведомлений" - description: "Никогда не получать уведомлений, связанных с этой темой, и не показывать ее во вкладке «Непрочитанные»." + description: "Не уведомлять об изменениях в этой теме и скрыть её из последних." actions: recover: "Отменить удаление темы" delete: "Удалить тему" @@ -1040,23 +1229,17 @@ ru: confirm_pin: "У вас уже есть {{count}} закрепленных тем. Слишком большое количество закрепленных тем может стать препятствием для новых и анонимных пользователей. Вы уверены, что хотите закрепить еще одну тему в этом разделе?" unpin: "Убрать эту тему из верха раздела {{categoryLink}}." pin_note: "Пользователи могут открепить тему для себя." - already_pinned: - zero: "В разделе {{categoryLink}} нет закрепленных тем." - one: "Закрепленные темы в разделе {{categoryLink}}: 1." - other: "Закрепленные темы в разделе {{categoryLink}}: {{count}}." + pin_validation: "Дата необходима, чтобы прикрепить эту тему" + not_pinned: "В разделе {{categoryLink}} нет закрепленных тем." confirm_pin_globally: "У вас уже есть {{count}} глобально закрепленных тем. Слишком большое количество закрепленных тем может стать препятствием для новых и анонимных пользователей. Вы уверены, что хотите глобально закрепить еще одну тему?" unpin_globally: "Убарть эту тему из верха всех списков тем." + unpin_globally_until: "Убарть эту тему из верха всех списков тем." global_pin_note: "Пользователи могут открепить тему для себя." - already_pinned_globally: - zero: "Нет глобально закрепленных тем." - one: "Глобально закрепленные темы: 1." - other: "Глобально закрепленные темы: {{count}}." + not_pinned_globally: "Нет глобально закрепленных тем." make_banner: "Превратить эту тему в объявление, которое будет отображаться вверху всех страниц." remove_banner: "Убрать объявление, которое отображается вверху всех страниц." banner_note: "Пользователи могут отклонить объявление, закрыв его. Только одну тему можно сделать текущим объявлением." - already_banner: - zero: "Нет текущих объявлений." - one: "Есть текущее объявление." + no_banner_exists: "Нет текущих объявлений." inviting: "Высылаю приглашение..." automatically_add_to_groups_optional: "Это приглашение также включает в себя доступ к следующим группам: (опционально, только для администратора)" automatically_add_to_groups_required: "Это приглашение также включает в себя доступ к следующим группам: (Обязательно, только для администратора)" @@ -1122,6 +1305,12 @@ ru: many: "Пожалуйста, выберите нового владельца {{count}} сообщений от {{old_user}}." other: "Пожалуйста, выберите нового владельца {{count}} сообщений от {{old_user}}." instructions_warn: "Обратите внимание, что все уведомления об этом сообщении не будут переданы новому пользователю задним числом.
    Внимание: В настоящее время никакие данные, имеющие отношение к сообщению, не передаются новому пользователю. Используйте с осторожностью." + change_timestamp: + title: "Изменить временную метку" + action: "изменить временную метку" + invalid_timestamp: "Временная метка не может быть в будущем" + error: "При изменении временной метки темы возникла ошибка" + instructions: "Пожалуйста, выберите новую временную метку. Сообщения в теме будут обновлены, чтобы убрать временные различия." multi_select: select: 'выбрать' selected: 'выбрано ({{count}})' @@ -1136,6 +1325,8 @@ ru: many: Вы выбрали {{count}} сообщений. other: Вы выбрали {{count}} сообщений. post: + reply: " {{replyAvatar}} {{usernameLink}}" + reply_topic: " {{link}}" quote_reply: "ответить цитированием" edit: "Изменить {{link}} {{replyAvatar}} {{username}}" edit_reason: "Причина:" @@ -1174,10 +1365,7 @@ ru: few: "Это сообщение понравилось {{count}} людям" many: "Это сообщение понравилось {{count}} людям" other: "Это сообщение понравилось {{count}} людям" - has_likes_title_you: - zero: "Вам понравилось это сообщение" - one: "Вам еще 1 человеку понравилось это сообщение" - other: "Вам и еще {{count}} людям понравилось это сообщение" + has_likes_title_only_you: "Вам понравилось это сообщение" errors: create: "К сожалению, не удалось создать сообщение из-за ошибки. Попробуйте еще раз." edit: "К сожалению, не удалось изменить сообщение. Попробуйте еще раз." @@ -1195,8 +1383,7 @@ ru: no_value: "Нет, оставить" yes_value: "Да, отказаться" via_email: "это сообщение пришло с почты" - wiki: - about: "это вики-сообщение - любой пользователь может отредактировать его, чтобы улучшить, дополнить или исправить ошибки" + whisper: "Это внутреннее сообщение, т.е. оно видно только модераторам" archetypes: save: 'Параметры сохранения' controls: @@ -1226,6 +1413,7 @@ ru: revert_to_regular: "Убрать цвет модератора" rebake: "Обработать сообщение заново - HTML" unhide: "Снова сделать видимым" + change_owner: "Изменить владельца" actions: flag: 'Жалоба' defer_flags: @@ -1249,17 +1437,9 @@ ru: like: "Больше не нравится" vote: "Отозвать голос" people: - off_topic: "{{icons}} отметили как оффтопик" - spam: "{{icons}} отметили как спам" - spam_with_url: "{{icons}} пометил это как спам" - inappropriate: "{{icons}} отметили как неуместное" - notify_moderators: "{{icons}} пожаловались модераторам" - notify_moderators_with_url: "{{icons}} пожаловались модераторам" - notify_user: "{{icons}} отправил(и) сообщение" - notify_user_with_url: "{{icons}} отправил(и) сообщение" - bookmark: "{{icons}} добавили в закладки" - like: "Выразили симпатию: {{icons}}" - vote: "{{icons}} проголосовали за" + notify_user: "отправил сообщение" + like: "понравилось это" + vote: "проголосовал за это" by_you: off_topic: "Помечена вами как оффтопик" spam: "Помечена вами как спам" @@ -1349,10 +1529,6 @@ ru: few: "{{count}} человека проголосовали за это сообщение" many: "{{count}} человек проголосовали за это сообщение" other: "{{count}} человек проголосовали за это сообщение" - edits: - one: редактировалось 1 раз - other: "редактировалось {{count}} раз" - zero: не редактировалось delete: confirm: one: "Вы уверены, что хотите удалить это сообщение?" @@ -1391,6 +1567,7 @@ ru: topic_template: "Шаблон темы" delete: 'Удалить раздел' create: 'Создать Раздел' + create_long: 'Создать новый раздел' save: 'Сохранить раздел' slug: 'Ссылка Категории' slug_placeholder: '(Опция) дефисы в url' @@ -1413,6 +1590,7 @@ ru: change_in_category_topic: "Изменить описание" already_used: 'Цвет уже используется другим разделом' security: "Безопасность" + special_warning: "Внимание: данная категория была предустановлена и настройки безопасности не могут быть изменены. Если не хотите использовать эту категорию, удалите ее вместо изменения." images: "Изображения" auto_close_label: "Закрыть тему через:" auto_close_units: "часов" @@ -1432,19 +1610,18 @@ ru: notifications: watching: title: "Наблюдать" - description: "Автоматически наблюдать за всеми новыми темами в этих разделах и уведомлять меня о новых сообщениях в них. Счетчик новых сообщений будет появляться рядом с названием темы." + description: "Наблюдать за каждой новой темой в этом разделе. Уведомлять о всех ответах в темах и показывать счетчик новых непрочитанных ответов." tracking: title: "Следить" - description: "Автоматически следить за всеми новыми темами в этих разделах. Счетчик новых сообщений будет появляться рядом с названием темы." + description: "Следить за каждой новой темой в этом разделе и показывать счетчик новых непрочитанных ответов. Вам придет уведомление, если кто-нибудь упомянет ваш @псевдоним или ответит на ваше сообщение." regular: title: "Уведомлять" description: "Уведомлять, если кто-нибудь упомянет мой @псевдоним или ответит на мое сообщение." muted: title: "Без уведомлений" - description: "Не уведомлять меня о новых темах в этих разделах и не показывать новые темы на странице «Непрочитанные»." + description: "Не уведомлять о новых темах в этом разделе и скрыть их из последних." flagging: title: 'Спасибо за вашу помощь в поддержании порядка!' - private_reminder: 'жалобы анонимны и видны только персоналу' action: 'Пожаловаться' take_action: "Принять меры" notify_action: 'Сообщение' @@ -1489,12 +1666,14 @@ ru: help: "Тема закрыта; в ней больше нельзя отвечать" archived: help: "Тема заархивирована и не может быть изменена" + locked_and_archived: + help: "Тема закрыта и заархивирована. Она больше не принимает новые ответы и не может быть изменена" unpinned: title: "Откреплена" help: "Эта тема не закреплена; она будет отображаться в обычном порядке" pinned_globally: title: "Закреплена глобально" - help: "Эта тема закреплена глобально и будет отображаться в начале всех списков" + help: "Эта тема закреплена глобально; она будет отображаться на главной и вверху своего раздела" pinned: title: "Закреплена" help: "Тема закреплена; она будет показана вверху соответствующего раздела" @@ -1540,9 +1719,11 @@ ru: with_topics: "%{filter} темы" with_category: "%{filter} %{category} темы" latest: - title: - zero: "Последние" + title: "Последние" + title_with_count: one: "Последние (1)" + few: "Последние ({{count}})" + many: "Последние ({{count}})" other: "Последние ({{count}})" help: "темы с недавними сообщениями" hot: @@ -1559,22 +1740,30 @@ ru: title_in: "Раздел - {{categoryName}}" help: "все темы, сгруппированные по разделам" unread: - title: - zero: "Непрочитанные" + title: "Непрочитанные" + title_with_count: one: "Непрочитанные (1)" + few: "Непрочитанные ({{count}})" + many: "Непрочитанные ({{count}})" other: "Непрочитанные ({{count}})" help: "наблюдаемые или отслеживаемые темы с непрочитанными сообщениями" lower_title_with_count: - one: "1 непрочитано" - other: "{{count}} непрочитано" + one: "1 непрочитанная" + few: "{{count}} непрочитанных" + many: "{{count}} непрочитанных" + other: "{{count}} непрочитанных" new: lower_title_with_count: - one: "1 новое" + one: "1 новая" + few: "{{count}} новых" + many: "{{count}} новых" other: "{{count}} новых" lower_title: "новые" - title: - zero: "Новые" + title: "Новые" + title_with_count: one: "Новые (1)" + few: "Новые ({{count}})" + many: "Новые ({{count}})" other: "Новые ({{count}})" help: "темы, созданные за последние несколько дней" posted: @@ -1584,18 +1773,22 @@ ru: title: "Закладки" help: "темы, которые вы добавили в закладки" category: - title: - zero: "{{categoryName}}" + title: "{{categoryName}}" + title_with_count: one: "{{categoryName}} (1)" + few: "{{categoryName}} ({{count}})" + many: "{{categoryName}} ({{count}})" other: "{{categoryName}} ({{count}})" help: "последние темы в разделе {{categoryName}}" top: title: "Обсуждаемые" - help: "наиболее активные темы за прошлый год, месяц, неделю или день" + help: "Самые активные темы за последний год, месяц, квартал, неделю или день" all: title: "За все время" yearly: title: "За год" + quarterly: + title: "За квартал" monthly: title: "За месяц" weekly: @@ -1603,11 +1796,12 @@ ru: daily: title: "За день" all_time: "За все время" - this_year: "Год" - this_month: "Месяц" - this_week: "Неделя" - today: "Сегодня" - other_periods: "просмотреть выше" + this_year: "За год" + this_quarter: "За квартал" + this_month: "За месяц" + this_week: "За неделю" + today: "За сегодня" + other_periods: "показать самые обсуждаемые" browser_update: 'К сожалению, ваш браузер устарел и не поддерживается этим сайтом. Пожалуйста, обновите браузер (нажмите на ссылку, чтобы узнать больше).' permission_types: full: "Создавать / Отвечать / Просматривать" @@ -1664,6 +1858,7 @@ ru: refresh_report: "Обновить отчет" start_date: "Дата от" end_date: "Дата до" + groups: "Все группы" commits: latest_changes: "Обновления в репозитории Github" by: "от" @@ -1758,11 +1953,15 @@ ru: add: "Добавить" add_members: "Добавить участников" custom: "Настраиваемые" + bulk_select: "(выберите группу)" automatic: "Автоматические" automatic_membership_email_domains: "Пользователи, которые регистрируются с доменом электронной почты, включенным в этот список, будут автоматически добавлены в эту группу:" automatic_membership_retroactive: "Применить тот же домен электронной почты чтобы добавить существующих зарегистрированных пользователей" default_title: "Заголовок по умолчанию для всех пользователей в группе" primary_group: "Автоматически использовать в качестве главной группы" + group_owners: Владельцы + add_owners: Добавить владельцев + incoming_email_placeholder: "введите email адрес" api: generate_master: "Сгенерировать ключ API" none: "Отсутствует ключ API." @@ -1836,11 +2035,11 @@ ru: is_disabled: "Восстановление отключено в настройках сайта." label: "Восстановить" title: "Восстановить резервную копию" - confirm: "Вы уверенны, что желаете восстановить эту резервную копию?" + confirm: "Вы уверены, что хотите восстановить этот бэкап?" rollback: label: "Откатить" title: "Откатить базу данных к предыдущему рабочему состоянию" - confirm: "Вы уверены, что хотите откатить базу данных к предыдущему рабочему состоянию?" + confirm: "Вы уверены, что хотите откатить базу данных до предыдущего рабочего состояния?" export_csv: user_archive_confirm: "Вы уверены, то хотите скачать все ваши сообщения?" success: "Процедура экспорта начата, мы отправим вам сообщение, когда процесс будет завершен." @@ -1890,6 +2089,11 @@ ru: color: "Цвет" opacity: "Прозрачность" copy: "Копировать" + email_templates: + subject: "Тема" + body: "Текст сообщения" + none_selected: "Выберите шаблон письма, чтобы начать редактирование." + revert: "Отменить изменения" css_html: title: "CSS/HTML" long_title: "Настройка CSS и HTML" @@ -1934,18 +2138,17 @@ ru: love: name: 'любовь' description: "Цвет кнопки «Мне нравится»." - wiki: - name: 'вики' - description: "Базовый цвет, используемый для фона вики-сообщений." email: - title: "Email" settings: "Настройки" - all: "Все" + templates: "Шаблоны" + preview_digest: "Просмотр сводки" sending_test: "Отправка тестового письма..." error: "ОШИБКА - %{server_error}" test_error: "При отправке тестового письма произошла ошибка. Пожалуйста, внимательно проверьте ваши почтовые настройки, проверьте, что ваш сервер не блокирует почтовые соединения, и попытайтесь снова." sent: "Отправлено" skipped: "Пропущенные" + received: "Принято" + rejected: "Отклонено" sent_at: "Отправлено" time: "Время" user: "Пользователь" @@ -1955,7 +2158,6 @@ ru: send_test: "Отправить тестовое письмо" sent_test: "отправлено!" delivery_method: "Метод отправки" - preview_digest: "Просмотр сводки" refresh: "Обновить" format: "Формат" html: "html" @@ -1963,6 +2165,22 @@ ru: last_seen_user: "Последнее посещение:" reply_key: "Ключ ответа" skipped_reason: "Причина пропуска" + incoming_emails: + from_address: "От" + to_addresses: "Кому" + cc_addresses: "Скрытая копия" + subject: "Тема" + error: "Ошибка" + none: "Входящих сообщений нет" + modal: + title: "Подробности Входящего Email" + error: "Ошибка" + subject: "Тема" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + error_placeholder: "Ошибка" logs: none: "Записи в журнале регистрации не найдены." filters: @@ -1981,6 +2199,7 @@ ru: ip_address: "IP" topic_id: "ID темы" post_id: "ID сообщения" + category_id: "ID раздела" delete: 'Удалить' edit: 'Изменить' save: 'Сохранить' @@ -1989,11 +2208,11 @@ ru: do_nothing: "ничего не делать" staff_actions: title: "Действия персонала" - instructions: "Кликните по имени пользователя и действиям для фильтрации списка. Кликните по аватару для перехода на страницу пользователя." + instructions: "Кликните по псевдониму или действиям для фильтрации списка. Кликните по аватару для перехода на страницу пользователя." clear_filters: "Показать все" staff_user: "Персонал" target_user: "Целевой пользователь" - subject: "Тема" + subject: "Субъект" when: "Когда" context: "Контекст" details: "Подробности" @@ -2005,22 +2224,32 @@ ru: no_previous: "Старое значение отсутствует." deleted: "Новое значение отсутствует. Запись была удалена." actions: - delete_user: "удаление пользователя" - change_trust_level: "изменение уровня доверия" - change_username: "изменить имя пользователя" - change_site_setting: "изменение настройки сайта" - change_site_customization: "изменение настройки сайта" - delete_site_customization: "удаление настроек сайта" - suspend_user: "заморозка пользователя" - unsuspend_user: "разморозка пользователя" - grant_badge: "выдача награды" - revoke_badge: "отозыв награды" - check_email: "открыть e-mail" - delete_topic: "удаление темы" - delete_post: "удаление сообщения" - impersonate: "выдать себя за" - anonymize_user: "анонимизировать пользователя" - roll_up: "Сгруппировать IP адреса в подсети" + delete_user: "удален пользователь" + change_trust_level: "изменен уровень доверия" + change_username: "изменен псевдоним" + change_site_setting: "изменена настройка сайта" + change_site_customization: "изменена настройка сайта" + delete_site_customization: "удалена настройка сайта" + change_site_text: "изменен текст" + suspend_user: "пользователь заморожен" + unsuspend_user: "пользователь разморожен" + grant_badge: "выдана награда" + revoke_badge: "отозвана награда" + check_email: "доступ к адресу e-mail" + delete_topic: "удалена тема" + delete_post: "удалено сообщение" + impersonate: "вход от имени пользователя" + anonymize_user: "пользователь анонимизрован" + roll_up: "сгруппированы заблокированные IP адреса в подсеть" + change_category_settings: "изменена настройка раздела" + delete_category: "удален раздел" + create_category: "создан раздел" + block_user: "пользователь заблокирован" + unblock_user: "пользователь разблокирован" + grant_admin: "выданы права администратора" + revoke_admin: "отозваны права администратора" + grant_moderation: "выданы права модератора" + revoke_moderation: "отозваны права модератора" screened_emails: title: "Почтовые адреса" description: "Когда кто-то создает новую учетную запись, проверяется данный почтовый адрес и регистрация блокируется или производятся другие дополнительные действия." @@ -2091,9 +2320,9 @@ ru: pending: 'Пользователи, ожидающие одобрения' newuser: 'Пользователи с уровнем доверия 0 (Новые пользователи)' basic: 'Пользователи с уровнем доверия 1 (Базовые пользователи)' - regular: 'Пользователи с уровнем доверия 2 (активные)' - leader: 'Пользователи с уровнем доверия 3 (лидеры сообщества)' - elder: 'Пользователи с уровнем доверия 4 (старейшины)' + member: 'Пользователи с уровнем доверия 2 (активные)' + regular: 'Пользователи с уровнем доверия 3 (лидеры сообщества)' + leader: 'Пользователи с уровнем доверия 4 (старейшины)' staff: "Персонал" admins: 'Администраторы' moderators: 'Модераторы' @@ -2200,6 +2429,8 @@ ru: deactivate_failed: "Во время деактивации пользователя произошла ошибка." unblock_failed: 'Не удалось разблокировать пользователя.' block_failed: 'Не удалось заблокировать пользователя.' + block_confirm: 'Вы уверены что хотите заблокировать этого пользователя? Он больше не сможет создавать темы и отправлять сообщения.' + block_accept: 'Подтвердить блокировку' deactivate_explanation: "Дезактивированные пользователи должны заново подтвердить свой e-mail." suspended_explanation: "Замороженный пользователь не может войти." block_explanation: "Заблокированный не может отвечать и создавать новые темы." @@ -2213,7 +2444,6 @@ ru: unlock_trust_level: "Разморозить уровень доверия" tl3_requirements: title: "Требования для 3 уровня доверия" - table_title: "За последние 100 дней:" value_heading: "Значение" requirement_heading: "Требование" visits: "Посещений" @@ -2256,24 +2486,29 @@ ru: delete: "Удалить" cancel: "Отмена" delete_confirm: "Вы уверены, что хотите удалить это поле?" + options: "Опции" required: title: "Обязательное во время регистрации?" - enabled: "обязательное" - disabled: "необязательное" + enabled: "Обязательное" + disabled: "Необязательное" editable: title: "Редактируемое после регистрации?" - enabled: "редактируемое" - disabled: "нередактируемое" + enabled: "Редактируемое" + disabled: "Нередактируемое" show_on_profile: - title: "Показать в публичном профиле?" - enabled: "показывается в профиле" - disabled: "не показывается в профиле" + title: "Показывать в публичном профиле?" + enabled: "Показывать в профиле" + disabled: "Не показывать в профиле" field_types: text: 'Текстовое поле' confirm: 'Подтверждение' + dropdown: "Выпадающий список" site_text: - none: "Выберите секцию для редактирования." title: 'Текстовое содержание' + edit: 'изменить' + revert: "Отменить изменения" + go_back: "Вернуться к поиску" + show_overriden: 'Показывать только измененные' site_settings: show_overriden: 'Показывать только измененные' title: 'Настройки' @@ -2304,6 +2539,7 @@ ru: backups: "Резервные копии" login: "Учетные записи" plugins: "Плагины" + user_preferences: "Пользовательские настройки" badges: title: Награды new_badge: Новая награда @@ -2360,10 +2596,12 @@ ru: bad_count_warning: header: "ВНИМАНИЕ!" text: "Обнаружены несуществующие примеры выдачи наград. Это может произойти, когда запрос возвращает несуществующие идентификаторы ID пользователей или сообщений. Это может привести к неожиданным проблемам со временем, поэтому внимательно проверьте ваш запрос." + no_grant_count: "Нет наград для выдачи." grant_count: - zero: "Нет наград для выдачи." - one: "1 награда для выдачи." - other: "%{count} наград на выдачу." + one: "Будет выдана 1 награда." + few: "%{count} наград будут выданы." + many: "%{count} наград будут выданы." + other: "%{count} наград будут выданы." sample: "Пример:" grant: with: %{username} @@ -2377,6 +2615,35 @@ ru: name: "Название" image: "Изображение" delete_confirm: "Вы уверены, что хотите удалить иконку :%{name}:?" + embedding: + title: "Встраивание" + host: "Разрешённые Хосты" + edit: "изменить" + add_host: "Добавить хост" + settings: "Настройки встраивания" + feed_settings: "Настройки Фида" + embed_post_limit: "Максимальное количество вложенных сообщений" + embed_username_key_from_feed: "Ключ для извлечения пользователя из ленты" + embed_truncate: "Обрезать встроенные сообщения." + embed_whitelist_selector: "Селекторы CSS которые разрешены для использования." + embed_blacklist_selector: "Селекторы CSS которые запрещены для использования." + feed_polling_enabled: "Импорт сообщений через RSS/ATOM" + save: "Сохранить настройки встраивания" + permalink: + title: "Постоянные ссылки" + url: "Ссылка URL" + topic_id: "Номер темы" + topic_title: "Тема" + post_id: "Номер сообщения" + post_title: "Сообщение" + category_id: "Номер раздела" + category_title: "Раздел" + external_url: "Внешняя ссылка" + delete_confirm: Удалить эту постоянную ссылку? + form: + label: "Новая постоянная ссылка:" + add: "Добавить" + filter: "Поиск по ссылке или внешней ссылке (URL)" lightbox: download: "загрузить" search_help: @@ -2392,6 +2659,8 @@ ru: categories: 'g, c Разделы' top: 'g, t Вверх' bookmarks: 'g, b Закладки' + profile: 'g, p Профиль' + messages: 'g, m Сообщения' navigation: title: 'Навигация' jump: '# Перейти к сообщение №' @@ -2403,12 +2672,14 @@ ru: title: 'Приложение' create: 'c Создать новую тему' notifications: 'n Открыть уведомления' + hamburger_menu: '= Открыть меню' user_profile_menu: 'p Открыть меню моего профиля' show_incoming_updated_topics: '. Показать обновленные темы' search: '/ Поиск' help: '? Открыть помощь по горячим клавишам' dismiss_new_posts: 'x, r Отложить новые сообщения' dismiss_topics: 'x, t Отложить темы' + log_out: 'shift+z shift+z Выйти' actions: title: 'Действия' bookmark_topic: 'f Добавить в Избранное' @@ -2430,8 +2701,6 @@ ru: mark_watching: 'm, w Наблюдать за темой' badges: title: Награды - allow_title: "Разрешить использовать в качестве титула" - multiple_grant: "может быть получено несколько раз" badge_count: one: "1 награда" few: "%{count} награды" @@ -2460,91 +2729,12 @@ ru: name: Прочее posting: name: Темы и сообщения - badge: - editor: - name: Редактор - description: Впервые отредактировал сообщение - basic_user: - name: Базовый - description: Получил доступ ко всем основным функциям сообщества - member: - name: Участник - description: Получил возможность приглашать новых пользователей в сообщество - regular: - name: Активный - description: Получил возможность изменять раздел тем и переименовывать их, а также доступ к Фойе и отслеживаемым ссылкам - leader: - name: Лидер - description: Получил глобальные права редактировать, прилепливать, закрывать, архивировать, разделять и соединять темы - welcome: - name: Добро пожаловать - description: Получил отметку "Мне нравится" - autobiographer: - name: Автобиограф - description: Заполнил информацию в профиле пользователя - anniversary: - name: Годовщина - description: Активный пользователь в течении года, создал как минимум одну тему. - nice_post: - name: Хорошее сообщение - description: Получил 10 отметок "Мне нравится" за свое сообщение. Эта награда может быть выдана более одного раза - good_post: - name: Отличное сообщение - description: Получил 25 отметок "Мне нравится" за свое сообщение. Эта награда может быть выдана более одного раза - great_post: - name: Отменное сообщение - description: Получил 50 отметок "Мне нравится" за свое сообщение. Эта награда может быть выдана более одного раза - nice_topic: - name: Хорошая тема - description: Получил 10 отметок "Мне нравится" за свою тему. Эта награда может быть выдана более одного раза - good_topic: - name: Отличная тема - description: Получил 25 отметок "Мне нравится" за свою тему. Эта награда может быть выдана более одного раза - great_topic: - name: Отменная тема - description: Получил 50 отметок "Мне нравится" за свою тему. Эта награда может быть выдана более одного раза - nice_share: - name: Хороший вклад в популярность - description: Поделился ссылкой на сообщение, и ее открыли 25 раз - good_share: - name: Значительный вклад в популярность - description: Поделился ссылкой на сообщение, и ее открыли 300 раз - great_share: - name: Бесценный вклад в популярность - description: Поделился ссылкой на сообщение, и ее открыли 1000 раз - first_like: - name: Первая симпатия - description: Понравилось сообщение - first_flag: - name: Первая жалоба - description: Помог модератору, обратив его внимание на проблемное сообщение - promoter: - name: Промоутер - description: Пригласил нового пользователя - campaigner: - name: Активист - description: Пригласил троих пользователей, достигших 1-го уровня доверия - champion: - name: Чемпион - description: Пригласил пятерых пользователей, достигших 2-го уровня доверия - first_share: - name: Первый вклад в популярность - description: Впервые поделился ссылкой на сообщение - first_link: - name: Первая ссылка - description: Добавил внутреннюю ссылку на другую тему - first_quote: - name: Первая цитата - description: Процитировал другого пользователя - read_guidelines: - name: Руководство пользователя - description: Прочитал руководство пользователя - reader: - name: Читатель - description: Прочитал каждое сообщение в теме с более чем 100 сообщениями - popular_link: - name: Популярная ссылка - description: Оставил внешнюю ссылку с более чем 50 кликов - hot_link: - name: Горячая ссылка - description: Оставил внешнюю ссылку с более чем 300 кликов + google_search: | +

    Поиск через Google

    +

    +

    +

    diff --git a/config/locales/client.sk.yml b/config/locales/client.sk.yml new file mode 100644 index 00000000000..ca49d8f9b13 --- /dev/null +++ b/config/locales/client.sk.yml @@ -0,0 +1,2728 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +sk: + js: + number: + format: + separator: "," + delimiter: "," + human: + storage_units: + format: '%n %u' + units: + byte: + one: bajt + few: bajtov + other: bajtov + gb: GB + kb: KB + mb: MB + tb: TB + short: + thousands: "{{number}}tis" + millions: "{{number}}mil" + dates: + time: "h:mm a" + long_no_year: "MMM D h:mm a" + long_no_year_no_time: "MMM D" + full_no_year_no_time: "MMMM Do" + long_with_year: "MMM D, YYYY h:mm a" + long_with_year_no_time: "MMM D, YYYY" + full_with_year_no_time: "MMMM Do, YYYY" + long_date_with_year: "MMM D, 'YY LT" + long_date_without_year: "MMM D, LT" + long_date_with_year_without_time: "MMM D, 'YY" + long_date_without_year_with_linebreak: "MMM D
    LT" + long_date_with_year_with_linebreak: "MMM D, 'YY
    LT" + tiny: + half_a_minute: "< 1m" + less_than_x_seconds: + one: "< 1s" + few: "< %{count}s" + other: "< %{count}s" + x_seconds: + one: "1s" + few: "1s" + other: "%{count}s" + less_than_x_minutes: + one: "< 1m" + few: "< 1m" + other: "< %{count}m" + x_minutes: + one: "1m" + few: "%{count}m" + other: "%{count}m" + about_x_hours: + one: "1h" + few: "%{count}h" + other: "%{count}h" + x_days: + one: "1d" + few: "%{count}d" + other: "%{count}d" + about_x_years: + one: "1r" + few: "%{count}r" + other: "%{count}r" + over_x_years: + one: "> 1r" + few: "> %{count}r" + other: "> %{count}r" + almost_x_years: + one: "1r" + few: "%{count}r" + other: "%{count}r" + date_month: "MMM D" + date_year: "MMM 'YY" + medium: + x_minutes: + one: "1 minúta" + few: "%{count} minúty" + other: "%{count} minút" + x_hours: + one: "1 hodina" + few: "%{count} hodiny" + other: "%{count} hodín" + x_days: + one: "1 deň" + few: "%{count} dni" + other: "%{count} dní" + date_year: "MMM D, 'YY" + medium_with_ago: + x_minutes: + one: "pred 1 minútou" + few: "pred %{count} minútami" + other: "pred %{count} minútami" + x_hours: + one: "pred 1 hodinou" + few: "pred %{count} hodinami" + other: "pred %{count} hodinami" + x_days: + one: "pred 1 dňom" + few: "pred %{count} dňami" + other: "pred %{count} dňami" + later: + x_days: + one: "1 deň neskôr" + few: "%{count} dni neskôr" + other: "%{count} dní neskôr" + x_months: + one: "1 mesiac neskôr" + few: "%{count} mesiace neskôr" + other: "%{count} mesiacov neskôr" + x_years: + one: "1 rok neskôr" + few: "%{count} roky neskôr" + other: "%{count} rokov neskôr" + previous_month: 'Predchádzajúci mesiac' + next_month: 'Nasledujúci mesiac' + share: + topic: 'zdieľaj odkaz na túto tému' + post: 'príspevok #%{postNumber}' + close: 'zatvoriť' + twitter: 'zdieľaj odkaz na Twitteri' + facebook: 'zdieľaj odkaz na Facebooku' + google+: 'zdieľaj odkaz na Google+' + email: 'pošli odkaz emailom' + action_codes: + split_topic: "rozdeľ tému %{when}" + invited_user: "pozvaný %{who} %{when}" + removed_user: "odstránený %{who} %{when}" + autoclosed: + enabled: 'uzavreté %{when}' + disabled: 'otvorené %{when}' + closed: + enabled: 'uzavreté %{when}' + disabled: 'otvorené %{when}' + archived: + enabled: 'archivované %{when}' + disabled: 'odarchivované %{when}' + pinned: + enabled: 'pripnuné %{when}' + disabled: 'odopnuté %{when}' + pinned_globally: + enabled: 'globálne pripnuté %{when}' + disabled: 'odopnuté %{when}' + visible: + enabled: 'zverejnené %{when}' + disabled: 'stiahnuté %{when}' + topic_admin_menu: "akcie administrátora témy" + emails_are_disabled: "Odosielanie emailov bolo globálne vypnuté administrátorom. Žiadne emailové notifikácie nebudú odoslané." + s3: + regions: + us_east_1: "USA Východ (S. Virginia)" + us_west_1: "USA Západ (S. Kalifornia)" + us_west_2: "USA Západ (Oregon)" + us_gov_west_1: "AWS GovCloud (USA)" + eu_west_1: "EU (Írsko)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Ázia Tichomorie (Singapur)" + ap_southeast_2: "Ázia Tichomorie (Sydney)" + ap_northeast_1: "Ázia Tichomorie (Tokio)" + ap_northeast_2: "Asia Pacific (Soul)" + sa_east_1: "Južná Amerika (Sao Paulo)" + edit: 'upraviť názov a kategóriu témy' + not_implemented: "Táto funkcia ešte bohužiaľ nie je implementovaná." + no_value: "Nie" + yes_value: "Áno" + generic_error: "Bohužiaľ nastala chyba." + generic_error_with_reason: "Nastala chyba: %{error}" + sign_up: "Registrácia" + log_in: "Prihlásenie" + age: "Vek" + joined: "Registovaný" + admin_title: "Administrácia" + flags_title: "Nahlásenie" + show_more: "zobraz viac" + show_help: "možnosti" + links: "Odkazy" + links_lowercase: + one: "odkaz" + few: "odkazy" + other: "odkazy" + faq: "FAQ" + guidelines: "Pokyny" + privacy_policy: "Ochrana súkromia" + privacy: "Súkromie" + terms_of_service: "Podmienky používania" + mobile_view: "Mobilná verzia" + desktop_view: "Desktop verzia" + you: "Vy" + or: "alebo" + now: "práve teraz" + read_more: 'čítaj ďalej' + more: "Viac" + less: "Menej" + never: "nikdy" + every_30_minutes: "každých 30 mintút" + every_hour: "každú hodinu" + daily: "denne" + weekly: "týždenne" + every_two_weeks: "každé dva týždne" + every_three_days: "každé tri dni" + max_of_count: "najviac {{count}}" + alternation: "alebo" + character_count: + one: "1 znak" + few: "{{count}} znakov" + other: "{{count}} znakov" + suggested_topics: + title: "Odporúčané témy" + pm_title: "Odporúčané správy" + about: + simple_title: "O fóre" + title: "O %{title}" + stats: "Štatistiky stránky" + our_admins: "Naši admini" + our_moderators: "Naši moderátori" + stat: + all_time: "Za celú dobu" + last_7_days: "Posledných 7 dní" + last_30_days: "Posledných 30 dní" + like_count: "Páči sa mi" + topic_count: "Témy" + post_count: "Príspevky" + user_count: "Noví používatelia" + active_user_count: "Aktívni používatelia" + contact: "Kontaktujte nás" + contact_info: "V prípade kritickej chyby alebo naliehavej záležitosti nás prosím konaktujte na %{contact_info}." + bookmarked: + title: "Záložka" + clear_bookmarks: "Odstrániť záložku" + help: + bookmark: "Kliknutím vložíte záložku na prvý príspevok tejto témy" + unbookmark: "Kliknutím odstánite všetky záložky v tejto téme" + bookmarks: + not_logged_in: "pre pridanie záložky sa musíte prihlásiť" + created: "záložka bola pridaná" + not_bookmarked: "príspevok je prečítaný, kliknite pre pridanie záložky" + last_read: "toto je posledný prečítaný príspevok, kliknite pre pridanie záložky" + remove: "Odstrániť záložku" + confirm_clear: "Ste si istý že chcete odstrániť všetky záložky z tejto témy?" + topic_count_latest: + one: "1 nová alebo upravená téma." + few: "{{count}} nové alebo upravené témy." + other: "{{count}} nových alebo upravených tém." + topic_count_unread: + one: "1 neprečítaná téma." + few: "{{count}} neprečítané témy." + other: "{{count}} neprečítaných tém." + topic_count_new: + one: "1 nová téma." + few: "{{count}} nové témy." + other: "{{count}} nových tém." + click_to_show: "Kliknite pre zobrazenie." + preview: "náhľad" + cancel: "zrušiť" + save: "Uložiť zmeny" + saving: "Ukladám zmeny..." + saved: "Zmeny uložené." + upload: "Upload" + uploading: "Upload prebieha..." + uploading_filename: "Nahrávám {{filename}}..." + uploaded: "Upload úspešne dokončený." + enable: "Zapnúť" + disable: "Vypnúť" + undo: "Späť" + revert: "Vrátiť zmeny" + failed: "Nepodarilo sa" + switch_to_anon: "Anonymný mód" + switch_from_anon: "Opustiť anonymný mód" + banner: + close: "Zamietnuť tento banner." + edit: "Upraviť tento banner >>" + choose_topic: + none_found: "Nenašli sa žiadne témy." + title: + search: "Hľadaj tému podľa názvu, url alebo id:" + placeholder: "sem napíšte názov témy" + queue: + topic: "Téma:" + approve: 'Schváliť' + reject: 'Zamietnuť' + delete_user: 'Odstrániť používateľa' + title: "Vyžaduje schválenie" + none: "Žiadne príspevky na kontrolu." + edit: "Upraviť" + cancel: "Zrušiť" + view_pending: "zobraziť príspevky čakajúce na schválenie" + has_pending_posts: + one: "Téma má {{count}} príspevkov čakajúci na schválenie" + few: "Téma má {{count}} príspevky čakajúce na schválenie" + other: "Téma má {{count}} príspevkov čakajúcich na schválenie" + confirm: "Uložiť zmeny" + delete_prompt: "Táto akcia zmaže všetky príspevky, zablokuje e-mail a IP adresu užívateľa %{username}. Ste si istý, že chcete zmazať tohto užívateľa? " + approval: + title: "Príspevok vyžaduje schválenie" + description: "Váš príspevok sme obdžali, ale skôr než bude zverejnený musí byť schválený moderátorom. Prosíme o trpezlivosť." + pending_posts: + one: "Máte 1 neprečítaný príspevok." + few: "Máte {{count}} neprečítané príspevky." + other: "Máte {{count}} neprečítaných príspevkov." + ok: "OK" + user_action: + user_posted_topic: "{{user}} založil tému" + you_posted_topic: "Vy ste založili tému" + user_replied_to_post: "{{user}} odpovedal na {{post_number}}" + you_replied_to_post: "Vy ste odpovedali na {{post_number}}" + user_replied_to_topic: "{{user}} odpovedal na tému" + you_replied_to_topic: "Vy ste odpovedali natému" + user_mentioned_user: "{{user}} spomenul {{another_user}}" + user_mentioned_you: "{{user}} spomenul Vás" + you_mentioned_user: "Vy ste spomenuli {{another_user}}" + posted_by_user: "Príspevok od {{user}}" + posted_by_you: "Príspevok od Vás" + sent_by_user: "Poslané od {{user}}" + sent_by_you: "Poslané Vami" + directory: + filter_name: "filtrovať podľa používateľského mena" + title: "Používatelia" + likes_given: "Rozdané" + likes_received: "Prijaté" + topics_entered: "Navštívené" + topics_entered_long: "Navšívených tém" + time_read: "Čas strávený čítaním" + topic_count: "Témy" + topic_count_long: "Vytvorených tém" + post_count: "Odpovede" + post_count_long: "Odpovedí" + no_results: "Žiadne výsledky" + days_visited: "Návštev" + days_visited_long: "Navštívených dní" + posts_read: "Prečítané" + posts_read_long: "Prečítaných príspevkov" + total_rows: + one: "1 užívateľ" + few: "%{count} užívatelia" + other: "%{count} užívateľov" + groups: + empty: + posts: "Neexistuje žiadny príspevok od člena tejto skupiny." + members: "Táto skupina neobsahuje žiadnych členov." + mentions: "Táto skupina nieje nikde spomenutá." + messages: "Neexistujú žiadne správy pre túto skupinu." + topics: "Neexistuje žiadna téma od členov tejto skupiny." + add: "Pridať" + selector_placeholder: "Pridať členov" + owner: "vlastník" + visible: "Skupina je viditeľná všetkým používateľom" + title: + one: "skupina" + few: "skupiny" + other: "skupiny" + members: "Členovia" + posts: "Príspevky" + alias_levels: + title: "Kto môže poslať správu a @uváadzať túto skupinu?" + nobody: "Nikto" + only_admins: "Iba administrátori" + mods_and_admins: "Iba moderátori a administrátori" + members_mods_and_admins: "Iba členovia skupiny, moderátori a administrátori" + everyone: "Každý" + trust_levels: + title: "Stupeň dôvery automaticky pridelený členom po ich pridaní:" + none: "Žiadny" + notifications: + watching: + title: "Pozerať" + description: "Budete upozornený na každý nový príspevok vo všetkých správach a zobrazí sa počet nových odpovedí." + tracking: + title: "Sledovať" + description: "Budete upozornený ak niekto spomenie Vaše @meno alebo Vám odpovie a zobrazí sa počet nových odpovedí." + regular: + title: "Bežný" + description: "Budete upozornený ak niekto spomenie Vaše @meno alebo Vám odpovie." + muted: + title: "Ignorovaný" + description: "Nikdy nebudete upozornení na nič ohľadom nových tém v tejto skupine." + user_action_groups: + '1': "Rozdaných 'páči sa mi'" + '2': "Obdržaných 'páči sa mi'" + '3': "Záložky" + '4': "Témy" + '5': "Odpovede" + '6': "Odozvy" + '7': "Zmienky" + '9': "Citácie" + '11': "Úpravy" + '12': "Odoslané správy" + '13': "Prijaté správy" + '14': "Čakajúce správy" + categories: + all: "všetky kategórie" + all_subcategories: "všetky" + no_subcategory: "žiadne" + category: "Kategória" + category_list: "Zobraziť zoznam kategórií" + reorder: + title: "Usporiadať Kategórie" + title_long: "Usporiadať zoznam kategórií" + fix_order: "Pevné pozície" + fix_order_tooltip: "Nie všetky kategórie majú unikátne číslo pozície, čo môže zpôsobovať neočakávané výsledky." + save: "Ulož poradie" + apply_all: "Použi" + position: "Pozícia" + posts: "Príspevky" + topics: "Témy" + latest: "Najnovšie" + latest_by: "najnovšie podľa" + toggle_ordering: "zmeniť radenie" + subcategories: "Podkategórie" + topic_stats: "Počet nových tém." + topic_stat_sentence: + one: "%{count} nová téma za posledných %{unit}." + few: "%{count} nové témy za posledných %{unit}." + other: "%{count} nových tém za posledných %{unit}." + post_stats: "Počet nových príspevkov." + post_stat_sentence: + one: "%{count} nový príspevok za posledných %{unit}." + few: "%{count} nové príspevky za posledných %{unit}." + other: "%{count} nových príspevkov za posledných %{unit}." + ip_lookup: + title: Vyhľadávanie podľa IP adresy + hostname: Hostname + location: Lokácia + location_not_found: (neznáma) + organisation: Organizácia + phone: Telefón + other_accounts: "Ostatné účty s touto IP adresou:" + delete_other_accounts: "Zmazaných %{count}" + username: "používateľské meno" + trust_level: "Dôvera" + read_time: "čas strávený čítaním" + topics_entered: "založených tém" + post_count: "# príspevkov" + confirm_delete_other_accounts: "Ste si istý že chcete zmazať tieto účty?" + user_fields: + none: "(vyberte možnosť)" + user: + said: "{{username}}:" + profile: "Profil" + mute: "Ignorovať" + edit: "Upraviť nastavenia" + download_archive: "Stiahnutie mojich prípevkov" + new_private_message: "Nová správa" + private_message: "Správa" + private_messages: "Správy" + activity_stream: "Aktivita" + preferences: "Nastavenia" + expand_profile: "Rozbaľ" + bookmarks: "Záložky" + bio: "O mne" + invited_by: "Pozvaný od" + trust_level: "Stupeň dôvery" + notifications: "Upozornenia" + statistics: "Štatistiky" + desktop_notifications: + label: "Upozornenia na pracovnej ploche" + not_supported: "Tento prehliadač nepodporuje upozornenia. Prepáčte." + perm_default: "Zapnúť upozornenia" + perm_denied_btn: "Prístup zamietnutý" + perm_denied_expl: "Povolenie pre zobrazenie notifikácií ste zakázali. Notifikácie povolíte v nastaveniach vášho prehliadača." + disable: "Zakázať upozornenia" + enable: "Povoliť upozornenia" + each_browser_note: "Poznámka: Toto nastavenie musíte zmeniť v každom používanom prehliadači." + dismiss_notifications: "Označiť všetky ako prečítané" + dismiss_notifications_tooltip: "Označiť všetky neprečítané upozornenia ako prečítané" + disable_jump_reply: "Neskočiť na môj príspevok po odpovedi" + dynamic_favicon: "Zobraziť počet nových/upravených tém na ikone prehliadača" + edit_history_public: "Povoliť ostatným užívateľom zobrazenie všetkých verzií môjho príspevku" + external_links_in_new_tab: "Otvoriť všekty externé odkazy v novej záložke" + enable_quoting: "Umožniť odpoveď s citáciou z označeného textu" + change: "zmeniť" + moderator: "{{user}} je moderátor" + admin: "{{user}} je administrátor" + moderator_tooltip: "Tento používateľ je moderátor" + admin_tooltip: "Tento používateľ je administrátor" + blocked_tooltip: "Tento používateľ je zablokovaný" + suspended_notice: "Tento používateľ je suspendovaný do {{date}}" + suspended_reason: "Dôvod:" + github_profile: "Github" + mailing_list_mode: "Pošli mi email pri každom novom príspevku (pokiaľ neignorujem tému alebo kategóriu)" + watched_categories: "Sledované" + watched_categories_instructions: "Budete automaticky sledovať všetky nové témy v týchto kategóriách. Budete upozornený na všetky nové príspevky a témy, a zároveň bude vedľa témy zobrazený počet nových príspevkov." + tracked_categories: "Sledované" + tracked_categories_instructions: "Budete automaticky sledovať všetky nové témy v týchto kategóriách. Počet nových príspevkov sa bude zobraziť vedľa témy." + muted_categories: "Ignorovaný" + muted_categories_instructions: "Nebudete informovaní o udalostiach v nových témach týchto kategórií. Tieto témy sa zároveň nebudú zobrazovať v zozname posledných udalostí." + delete_account: "Vymazať môj účet" + delete_account_confirm: "Ste si istý, že chcete permanentne vymazať váš účet? Táto akcia je nenávratná." + deleted_yourself: "Váš účet bol úspešne vymazaný." + delete_yourself_not_allowed: "Momentálne nie je možné vymazať váš učet. Kontaktujte administrátora a ten vám ho vymaže." + unread_message_count: "Správy" + admin_delete: "Vymazať" + users: "Používatelia" + muted_users: "Ignorovaný" + muted_users_instructions: "Pozastaviť všetky notifikácie od týchto užívateľov." + muted_topics_link: "Zobraziť umlčané témy" + staff_counters: + flags_given: "nápomocné značky" + flagged_posts: "označkované príspevky" + deleted_posts: "vymazané príspevky" + suspensions: "pozastavenia" + warnings_received: "upozornenia" + messages: + all: "Všetky" + inbox: "Prijatá pošta" + sent: "Odoslané" + archive: "Archív" + groups: "Moje skupiny" + bulk_select: "Označ správy" + move_to_inbox: "Presuň do prijatej pošty" + move_to_archive: "Archív" + failed_to_move: "Zlyhalo presunutie označených správ (možno je chyba vo vašom pripojení)" + select_all: "Označ všetky" + change_password: + success: "(email odoslaný)" + in_progress: "(email sa odosiela)" + error: "(chyba)" + action: "Odoslať email na reset hesla" + set_password: "Nastaviť heslo" + change_about: + title: "Upraviť O mne" + error: "Pri úprave hodnoty nastala chyba" + change_username: + title: "Zmeniť užívateľské meno" + confirm: "Ak si zmeníte vaše užívateľské meno, všetky predchádajúce cítacie vašich príspevkov a @zmienok prestanú platiť. Ste si určite istý, že to chcete?" + taken: "Sorry, toto užívateľské meno je obsadené." + error: "Pri zmene užívateľského mena prišlo k chybe." + invalid: "Toto užívateľské meno nie je platné. Musí obsahovať iba znaky a čísla." + change_email: + title: "Zmeniť email" + taken: "Prepáčte, tento email je už obsadený." + error: "Pri zmene emailu nastala chyba. Je možné, že je email už použitý?" + success: "Na email sme odoslali správu. Nasledujte prosím inštrukcie pre potvrdenie." + change_avatar: + title: "Zmeniť váš profilový obrázok" + gravatar: "Gravatar, podľa" + gravatar_title: "Zmeňte váš avatar na webe Gravatar " + refresh_gravatar_title: "Obnoviť váš Gravatar" + letter_based: "Systém pridelil profilový obrázok" + uploaded_avatar: "Vlastný obrázok" + uploaded_avatar_empty: "Pridať vlastný obrázok" + upload_title: "Nahrať váš obrázok" + upload_picture: "Nahrať obrázok" + image_is_not_a_square: "Upozornenie: váš obrázok sme orezali; mal rozdielnu šírku a výšku" + cache_notice: "Váš profilový obrázok bol úspešne zmenený, ale jeho zobrazenie môže chvíľu trvať kvôli vyrovnávacej pamäti prehliadača." + change_profile_background: + title: "Pozadie profilu" + instructions: "Pozadie profilu bude vystredené a s predvolenou šírkou 850px." + change_card_background: + title: "Pozadie karty používateľa" + instructions: "Obrázky pozadia budú vystredené a s predvolenou šírkou 590px." + email: + title: "Email" + instructions: "Nikdy verejne nezobrazené" + ok: "Pošleme vám email pre potvrdenie" + invalid: "Zadajte prosím platný email" + authenticated: "Váš email bude autentifikovaný pomocou {{provider}}" + frequency_immediately: "Odošleme vám email ak ste neprečítali to, čo vám posielame emailom." + frequency: + one: "Odošleme vám email iba ak sme vás nevideli poslednú minútu" + few: "Odošleme vám email iba ak sme vás nevideli posledné {{count}} minúty." + other: "Odošleme vám email iba ak sme vás nevideli posledných {{count}} minút" + name: + title: "Meno" + instructions: "Vaše celé meno (nepovinné)" + instructions_required: "Vaše celé meno" + too_short: "Vaše meno je prikrátke" + ok: "Vaše meno je v poriadku" + username: + title: "Užívateľské meno" + instructions: "Unikátne, bez medzier, krátke" + short_instructions: "Ostatní vás môžu označiť ako @{{username}}" + available: "Vaše užívateľské meno je voľné" + global_match: "Email zodpovedá registrovanému užívateľskému menu" + global_mismatch: "Už zaregistrované. Skúste {{suggestion}}?" + not_available: "Nie je k dispozícii. Skúste {{suggestion}}?" + too_short: "Vaše užívateľské meno je prikrátke" + too_long: "Vaše užívateľské meno je pridlhé" + checking: "Kontrolujeme dostupnosť užívateľského meno" + enter_email: 'Užívateľské meno nájdené, zadajte zodpovedajúci email' + prefilled: "Email zodpovedá tomuto registrovanému užívateľskému menu" + locale: + title: "Jazyk rozhrania" + instructions: "Jazyk úžívateľského rozhrania. Zmení sa po obnovení stránky." + default: "(predvolené)" + password_confirmation: + title: "Heslo znova" + last_posted: "Posledný príspevok" + last_emailed: "Posledný odemailovaný" + last_seen: "Videný" + created: "Spojený" + log_out: "Odhlásiť sa" + location: "Poloha" + card_badge: + title: "Odznak karty užívateľa" + website: "Webová stránka" + email_settings: "Email" + like_notification_frequency: + title: "Oznámiť pri lajknutí" + always: "Vždy" + never: "Nikdy" + email_previous_replies: + always: "vždy" + never: "nikdy" + email_digests: + title: "Ak to tu nenavštívim, pošlite mi emailový súhrn s novinkami:" + every_30_minutes: "každých 30 mintút" + every_hour: "každú hodinu" + daily: "denne" + every_three_days: "každé tri dni" + weekly: "týždenne" + every_two_weeks: "každé dva týždne" + email_direct: "Pošlite mi email ak ma niekto cituje, odpovie na môj príspevok, spomenie moje @užívateľské meno alebo ma pozve do témy." + email_private_messages: "Pošlite mi email keď mi niekto pošle správu" + email_always: "Pošlite mi emailovú notifikáciu aj keď som aktívny na stránke" + other_settings: "Ostatné" + categories_settings: "Kategórie" + new_topic_duration: + label: "Považuj témy za nové keď" + not_viewed: "Ešte som ich nevidel" + last_here: "vytvorené odkedy som tu bol naposledy" + after_1_day: "vytvorené za posledný deň" + after_2_days: "vytvorené posledné 2 dni" + after_1_week: "vytvorené za posledný týždeň" + after_2_weeks: "vytvorené za posledné 2 týždne" + auto_track_topics: "Automaticky sleduj témy, do ktorých vstúpim" + auto_track_options: + never: "nikdy" + immediately: "ihneď" + after_30_seconds: "po 30 sekundách" + after_1_minute: "po 1 minúte" + after_2_minutes: "po 2 minútach" + after_3_minutes: "po 3 minútach" + after_4_minutes: "po 4 minútach" + after_5_minutes: "po 5 minútach" + after_10_minutes: "po 10 minútach" + invited: + search: "začni písať pre hľadanie pozvánok" + title: "Pozvánky" + user: "Pozvaný užívateľ" + sent: "Odoslané" + none: "Nemáte žiadne čakajúce pozvánky." + truncated: + one: "Zobrazuje sa prvá pozvánka." + few: "Zobrazujú sa prvé {{count}} pozvánky." + other: "Zobrazuje sa prvých {{count}} pozvánok." + redeemed: "Použité pozvánky" + redeemed_tab: "Použitá" + redeemed_tab_with_count: "Použité ({{count}})" + redeemed_at: "Použitá" + pending: "Čakajúce pozvánky" + pending_tab: "Čakajúca" + pending_tab_with_count: "Čakajúce ({{count}})" + topics_entered: "Zobrazených tém" + posts_read_count: "Prečítaných príspevkov" + expired: "Táto pozvánka vypršala." + rescind: "Odstrániť" + rescinded: "Pozvánka odstránená" + reinvite: "Poslať pozvánku znovu" + reinvited: "Poslať pozvánku znovu" + time_read: "Doba čítania" + days_visited: "Dní na stránke" + account_age_days: "Vek účtu v dňoch" + create: "Poslať Pozvánku" + generate_link: "Kopírovať Odkaz Pozvánky" + generated_link_message: '

    Odkaz pre pozvánku bol úspešne vytvorený!

    Odkaz je platný iba pre túto adresu: %{invitedEmail}

    ' + bulk_invite: + none: "Zatiaľ ste tu nikoho nepozvali. Môžete odosielať pozvánky individuálne alebo pozvať skupinu ľudí naraz pomocou nahratia súboru." + text: "Hromadná pozvánka zo súboru" + uploading: "Prebieha nahrávanie..." + success: "Súbor bol úspešne odoslaný. Keď sa nahrávanie dokončí, budete na to upozornený cez správu." + error: "Pri nahrávaní '{{filename}}' sa vyskytla chyba: {{message}}" + password: + title: "Heslo" + too_short: "Vaše heslo je príliš krátke." + common: "Toto heslo je príliš časté." + same_as_username: "Vaše heslo je rovnaké ako používateľské meno." + same_as_email: "Vaše heslo je rovnaké ako e-mail." + ok: "Vaše heslo je v poriadku." + instructions: "Minimálne %{count} znakov." + summary: + title: "Sumarizácia" + stats: "Štatistiky" + top_replies: "Najvýznamnejšie odpovede" + more_replies: "Viac odpovedí" + top_topics: "Najvýznamnejšie témy" + more_topics: "Viac tém" + top_badges: "Najvýznamnejšie odznaky" + more_badges: "Viac odznakov" + associated_accounts: "Prihlásenia" + ip_address: + title: "Posledná IP adresa" + registration_ip_address: + title: "IP adresa pri registrácii" + avatar: + title: "Profilový obrázok" + header_title: "profil, správy, záložky a nastavenia" + title: + title: "Názov" + filters: + all: "Všetky" + stream: + posted_by: "Autor príspevku" + sent_by: "Odoslané používateľom" + private_message: "správa" + the_topic: "téma" + loading: "Prebieha načítavanie..." + errors: + prev_page: "pri pokuse o načítanie" + reasons: + network: "Chyba siete" + server: "Chyba na serveri" + forbidden: "Prístup zamietnutý" + unknown: "Chyba" + not_found: "Stránka nenájdená" + desc: + network: "Skontrolujte, prosím, svoje pripojenie." + network_fixed: "Zdá sa, že sme späť." + server: "Kód chyby: {{status}}" + forbidden: "Nemáte oprávnenie na zobrazenie." + not_found: "Hopla, aplikácia sa pokúsila načítať adresu, ktorá neexistuje." + unknown: "Niečo sa pokazilo." + buttons: + back: "Späť" + again: "Skúsiť znova" + fixed: "Načítať stránku" + close: "Zatvoriť" + assets_changed_confirm: "Táto stránka bola práve aktualizovaná. Obnoviť na najnovšiu verziu?" + logout: "Boli ste odhlásený." + refresh: "Obnoviť" + read_only_mode: + enabled: "Stránky sú v móde iba na čítanie. Prosím pokračujte v prezeraní, ale iné akcie, ako odpovedanie, dávanie páči sa mi alebo niektové ďalšie sú teraz vypnuté." + login_disabled: "Keď je zapnutý mód iba na čítanie, prihlásenie nie je možné." + logout_disabled: "Odhlásenie nie je možné, kým je stránka v móde iba na čítanie." + too_few_topics_and_posts_notice: "Začnime diskusiu! Je tu %{currentTopics} / %{requiredTopics} tém a %{currentPosts} / %{requiredPosts} príspevkov. Noví návštevníci potrebujú mať témy, ktoré môžu čítať a na ktoré budú reagovať." + too_few_topics_notice: "Začnime diskusiu! Je tu %{currentTopics} / %{requiredTopics} tém. Noví návštevníci potrebujú mať témy, ktoré môžu čítať a na ktoré budú reagovať." + too_few_posts_notice: "Začnime diskusiu! Je tu %{currentPosts} / %{requiredPosts} príspevkov. Noví návštevníci potrebujú mať témy, ktoré môžu čítať a na ktoré budú reagovať." + learn_more: "zistiť viac..." + year: 'rok' + year_desc: 'témy vytvorené za posledných 365 dní' + month: 'mesiac' + month_desc: 'témy vytvorené za posledných 30 dní' + week: 'týždeň' + week_desc: 'témy vytvorené za posledných 7 dní' + day: 'deň' + first_post: Prvý príspevok + mute: Ignorovať + unmute: Prestať ignorovať + last_post: Posledný príspevok + last_reply_lowercase: posledná odpoveď + replies_lowercase: + one: odpoveď + few: odpovede + other: odpovedí + signup_cta: + sign_up: "Registrovať sa" + hide_session: "Pripomenúť zajtra" + hide_forever: "nie, ďakujem" + hidden_for_session: "Fajn, opýtam sa vás to zajtra. Stále môžete na vytvorenie účtu použiť aj možnosť 'Prihlásenie'." + intro: "Zdravím! :heart_eyes: Vyzerá, že sa vám diskusia páči, ale stále nie ste prihlásený na svojom účte." + value_prop: "Keď si vytvoríte účet, zapamätáme si čo ste čítali, takže sa môžete vrátiť presne tam, kde ste prestali. Okrem toho dostanete upozornenie tu, aj na váš e-mail, vždy keď pribudnú nové príspevky. A môžete označiť príspevky ktoré sa vám páčia. :heartbeat:" + summary: + enabled_description: "Pozeráte sa na zhrnutie tejto témy: najzaujímavejšie príspevky podľa výberu komunity." + enable: 'Zhrnutie tejto témy' + disable: 'Zobraziť všetky príspevky' + deleted_filter: + enabled_description: "Táto téma obsahuje zmazané príspevky, ktoré boli skryté." + disabled_description: "Zmazané príspevky sa v téme zobrazujú." + enable: "Skryť zmazané príspevky" + disable: "Zobraziť zmazané príspevky" + private_message_info: + title: "Správa" + invite: "Pozvať ostatných..." + remove_allowed_user: "Skutočne chcete odstrániť {{name}} z tejto správy?" + email: 'Email' + username: 'Používateľské meno' + last_seen: 'Videné' + created: 'Vytvorené' + created_lowercase: 'vytvorené' + trust_level: 'Stupeň dôvery' + search_hint: 'používateľské meno, email alebo IP adresa' + create_account: + title: "Vytvoriť nový účet" + failed: "Niečo sa pokazilo, možno je tento e-mail už registrovaný, vyskúšajte odkaz pre zabudnuté heslo" + forgot_password: + title: "Obnovenie hesla" + action: "Zabudol som svoje heslo" + invite: "Napíšte vaše používateľské meno alebo e-mailovú adresu a pošleme vám e-mail pre obnovu hesla." + reset: "Obnoviť heslo" + complete_username: "Ak je účet priradený k používateľskému menu %{username}, čoskoro dostanete e-mail s pokynmi, ako si obnoviť svoje heslo." + complete_email: "Ak je účet priradený k %{email}, čoskoro dostanete e-mail s pokynmi, ako si obnoviť svoje heslo." + complete_username_found: "Našli sme účet priradený k používateľskému menu %{username}, čoskoro dostanete e-mail s pokynmi, ako si obnoviť svoje heslo." + complete_email_found: "Našli sme účet priradený k %{email}, čoskoro dostanete e-mail s pokynmi, ako si obnoviť svoje heslo." + complete_username_not_found: "Žiadny účet nemá priradené používateľské meno %{username}" + complete_email_not_found: "Žiadny účet nie je s e-mailom %{email}" + login: + title: "Prihlásenie" + username: "Používateľ" + password: "Heslo" + email_placeholder: "e-mail alebo používateľské meno" + caps_lock_warning: "Caps Lock je zapnutý" + error: "Neznáma chyba" + rate_limit: "Pred opätovným prihlásením chvíľku počkajte." + blank_username_or_password: "Zadajte prosím svoj e-mail alebo používateľské meno a heslo." + reset_password: 'Obnoviť heslo' + logging_in: "Prebieha prihlásenie..." + or: "Alebo" + authenticating: "Prebieha overovanie..." + awaiting_confirmation: "Váš účet čaká na aktiváciu. Ak chcete zaslať aktivačný e-mail znova, použite odkaz pre zabudnuté heslo." + awaiting_approval: "Váš účet zatiaľ nebol schválený členom tímu. Keď bude schválený, dostanete e-mail." + requires_invite: "Prepáčte, ale prístup k tomuto fóru majú iba pozvaní používatelia." + not_activated: "Systém vás nemôže prihlásiť. Na emailovú adresu {{sentTo}} sme vám poslali aktivačný email. Prosím, postupujte podľa inštrukcií na aktiváciu účtu, ktoré sú uvedené v tomto emaile." + not_allowed_from_ip_address: "Nie je možné prihlásenie z tejto IP adresy." + admin_not_allowed_from_ip_address: "Nie je možné prihlásenie ako admin z tejto IP adresy." + resend_activation_email: "Kliknite sem pre opätovné odoslanie aktivačného emailu." + sent_activation_email_again: "Odoslali sme vám ďalší aktivačný email na {{currentEmail}}. Môže trvať niekoľko minút kým príde; pre istotu si skontrolujte spamový priečinok." + to_continue: "Prosím, prihláste sa" + preferences: "Na zmenu používateľských nastavení musíte byť prihlásený." + forgot: "Nepamätám si detaily môjho účtu" + google: + title: "pomocou Google" + message: "Prihlásenie pomocou Google účtu (prosím uistite sa, že vyskakovacie okná sú povolené)" + google_oauth2: + title: "pomocou Google" + message: "Prihlásenie pomocou Google účtu (prosím uistite sa, že vyskakovacie okná sú povolené)" + twitter: + title: "pomocou Twitter účtu" + message: "Prihlásenie pomocou Twitter účtu (prosím uistite sa, že vyskakovacie okná sú povolené)" + instagram: + title: "so službou Instagram" + message: "Prihlásenie pomocou Instagram účtu (prosím uistite sa, že vyskakovacie okná sú povolené)" + facebook: + title: "pomocou stránky Facebook" + message: "Prihlásenie pomocou Facebook účtu (prosím uistite sa, že vyskakovacie okná sú povolené)" + yahoo: + title: "pomocou Yahoo" + message: "Prihlásenie pomocou Yahoo účtu (prosím uistite sa, že vyskakovacie okná sú povolené)" + github: + title: "pomocou GitHub" + message: "Prihlásenie pomocou GitHub účtu (prosím uistite sa, že vyskakovacie okná sú povolené)" + apple_international: "Apple/Medzinárodné" + google: "Google" + twitter: "Twitter" + emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' + composer: + emoji: "Emoji :)" + more_emoji: "viac ..." + options: "Možnosti" + whisper: "šepot" + add_warning: "Toto je oficiálne varovanie." + toggle_whisper: "Prepnúť šepot" + posting_not_on_topic: "Na akú tému chcete odpovedať?" + saving_draft_tip: "ukladám..." + saved_draft_tip: "uložené" + saved_local_draft_tip: "uložené lokálne" + similar_topics: "Vaša téma je podobná..." + drafts_offline: "offline koncepty" + group_mentioned: "Použitím tejto {{group}} , upozorníte {{count}} ľudí." + error: + title_missing: "Názov je povinný" + title_too_short: "Názov musí mať minimálne {{min}} znakov" + title_too_long: "Názov nesmie byť dlhší než {{max}} znakov" + post_missing: "Príspevok nesmie byť prázdny" + post_length: "Príspevok musí mať minimálne {{min}} znakov" + try_like: 'Skúsili ste tlačítko?' + category_missing: "Musíte vybrať kategóriu" + save_edit: "Uložiť úpravy" + reply_original: "Odpovedať na pôvodnú tému" + reply_here: "Odpovedať tu" + reply: "Odpovedať" + cancel: "Zrušiť" + create_topic: "Vytvoriť tému" + create_pm: "Správa" + title: "Alebo stlačte Ctrl+Enter" + users_placeholder: "Pridať používateľa" + title_placeholder: "O čom je této diskusia v jednej stručnej vete?" + edit_reason_placeholder: "prečo upravujete?" + show_edit_reason: "(pridajte dôvod úpravy)" + reply_placeholder: "Píšte sem. Formátujte pomocou Markdown, BBCode alebo HTML. Pretiahnite alebo vložte obrázky." + view_new_post: "Zobraziť nový príspevok." + saving: "Ukladanie" + saved: "Uložené!" + saved_draft: "Návrh príspevku rozpracovaný. Vyberte na obnovenie." + uploading: "Upload prebieha..." + show_preview: 'zobraziť náhľad »' + hide_preview: '» skryť náhľad' + quote_post_title: "Citovať celý príspevok" + bold_title: "Výrazne" + bold_text: "výrazný text" + italic_title: "Zdôraznene" + italic_text: "zdôraznený text" + link_title: "Hyperlink" + link_description: "tu zadaj popis odkazu" + link_dialog_title: "Vložte hyperlink" + link_optional_text: "nepovinný názov" + link_placeholder: "http://example.com \"voliteľný text\"" + quote_title: "Úvodzovky" + quote_text: "Úvodzovky" + code_title: "Preformátovaný text" + code_text: "Odsaďte preformátovaný text 4 medzerami" + upload_title: "Upload" + upload_description: "tu zadajte popis uploadu" + olist_title: "Číslované odrážky" + ulist_title: "Odrážky" + list_item: "Položka zoznamu" + heading_title: "Nadpis" + heading_text: "Nadpis" + hr_title: "Horizonálny oddeľovač" + help: "Nápoveda úprav pre Markdown" + toggler: "skryť alebo zobraziť panel úprav" + modal_ok: "OK" + modal_cancel: "Zrušiť" + cant_send_pm: "Ľutujeme, nemôžete poslať správu pre %{username}." + admin_options_title: "Nepovinné zamestnanecké nastavenia pre túto tému" + auto_close: + label: "Čas na automatické uzavretie témy:" + error: "Prosím zadajte platnú hodnotu." + based_on_last_post: "Nezatvárať pokým posledný príspevok v téme nie je takto starý." + all: + examples: 'Zadajte číslo v hodinách (24), absolútny čas (17:30) alebo časovú značku (2013-11-22 14:00).' + limited: + units: "(# hodín)" + examples: 'Zadajte počet hodín (24).' + notifications: + title: "oznámenia o zmienkach pomocou @name, odpovede na vaše príspevky a témy, správy atď." + none: "Notifikácie sa nepodarilo načítať" + more: "zobraziť staršie upozornenia" + total_flagged: "označených príspevkov celkom" + mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " + quoted: "

    {{username}} {{description}}

    " + replied: "

    {{username}} {{description}}

    " + edited: "

    {{username}} {{description}}

    " + liked: "

    {{username}} {{description}}

    " + private_message: "

    {{username}} {{description}}

    " + invited_to_private_message: "

    {{username}} {{description}}

    " + invited_to_topic: "

    {{username}} {{description}}

    " + invitee_accepted: "

    {{username}} prijal Vaše pozvanie

    " + moved_post: "

    {{username}} presunul {{description}}

    " + linked: "

    {{username}} {{description}}

    " + granted_badge: "

    Získal '{{description}}'

    " + group_message_summary: + one: "

    {{count}} správa vo vašej {{group_name}} schránke

    " + few: "

    {{count}} správy vo vašej {{group_name}} schránke

    " + other: "

    {{count}} správ vo vašej {{group_name}} schránke

    " + alt: + mentioned: "Spomenutý od" + quoted: "Citovaný od" + replied: "Odpovedané" + posted: "Príspevok od" + edited: "Upravte Váš príspevok do" + liked: "Váš príspevok sa páčil" + private_message: "Súkromná správa od" + invited_to_private_message: "Pozvaný na súkromné správy od" + invited_to_topic: "Pozvaný k téme od" + invitee_accepted: "Pozvánka akceptovaná " + moved_post: "Váš príspevok bol presunutý " + linked: "Odkaz na váš príspevok" + granted_badge: "Priznaný odznak" + group_message_summary: "Správy v skupinovej schránke" + popup: + mentioned: '{{username}} vás spomenul v "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} vás spomenul v "{{topic}}" - {{site_title}}' + quoted: '{{username}} vás citoval v "{{topic}}" - {{site_title}}' + replied: '{{username}} vám odpovedal v "{{topic}}" - {{site_title}}' + posted: '{{username}} prispel v "{{topic}}" - {{site_title}}' + private_message: '{{username}} vám poslal súkromnú správu v "{{topic}}" - {{site_title}}' + linked: '{{username}} odkázal na váš príspevok z "{{topic}}" - {{site_title}}' + upload_selector: + title: "Pridať obrázok" + title_with_attachments: "Pridať obrázok alebo súbor" + from_my_computer: "Z počítača" + from_the_web: "Z webu" + remote_tip: "odkaz na obrázok" + remote_tip_with_attachments: "odkaz na obrázok alebo súbor {{authorized_extensions}}" + local_tip: "zvoľte obrázok z vášho počítača" + local_tip_with_attachments: "zvoľte obrázok alebo súbor z vášho počítača {{authorized_extensions}}" + hint: "(môžete taktiež potiahnuť a pustiť do editora pre nahratie)" + hint_for_supported_browsers: "môžete taktiež potiahnuť a pustiť alebo priložiť obrázky do editora" + uploading: "Nahrávanie" + select_file: "Zvoľte súbor" + image_link: "adresa na ktorú bude odkazovať váš obrázok" + search: + sort_by: "Zoradiť podľa" + relevance: "Relevancia" + latest_post: "Najnovší príspevok" + most_viewed: "Najviac prezerané" + most_liked: "Najviac sa páčia" + select_all: "Označ všetky" + clear_all: "Odznač všetky" + result_count: + one: "1 výsledok pre \"{{term}}\"" + few: "{{count}} výsledky pre \"{{term}}\"" + other: "{{count}} výsledkov pre \"{{term}}\"" + title: "hľadaj témy, príspevky, užívateľov, alebo kategórie" + no_results: "Žiadne výsledky" + no_more_results: "Nenašlo sa viac výsledkov" + search_help: Pomoc pri vyhľadávaní + searching: "Vyhľadávam....." + post_format: "#{{post_number}} podľa {{username}}" + context: + user: "Vyhľadávanie podľa @{{username}}" + category: "Vyhľadávanie podľa \"{{category}}\" kategórie" + topic: "Hľadaj v tejto téme" + private_messages: "Hľadaj správy" + hamburger_menu: "prejsť na iné témy, alebo kategórie" + new_item: "nový" + go_back: 'späť' + not_logged_in_user: 'užívateľská stránka so súhrnom aktivít a nastavení' + current_user: 'prejsť na Vašu uťívateľskú stránku' + topics: + bulk: + unlist_topics: "Dôverné témy" + reset_read: "Obnoviť prečítané" + delete: "Zmazať témy" + dismiss: "Zahodiť" + dismiss_read: "Zahodiť všetký neprečítané" + dismiss_button: "Zahadzujem....." + dismiss_tooltip: "Zahoď nové príspevky, alebo prestaň sledovať témy" + also_dismiss_topics: "Prestať sledovať tieto témy. Už sa nikdy nebudu ukazovať medzi neprečítanými" + dismiss_new: "Zahodiť. Nová" + toggle: "prepnuť hromadne vybrané témy" + actions: "Hromadné akcie" + change_category: "Zmeň kategóriu" + close_topics: "Uzavrieť tému" + archive_topics: "Archivuj témy" + notification_level: "Zmeň úroveň upozorňovania" + choose_new_category: "Vyberte pre tému novú kategóriu:" + selected: + one: "Označíli ste 1 tému." + few: "Označíli ste {{count}} tém.y" + other: "Označíli ste {{count}} tém." + none: + unread: "Nemáte neprečítanú tému" + new: "Nemáte žiadnu novú tému" + read: "Neprečítali ste ešte žiadnu tému." + posted: "Nanapísali ste ešte žiadnu tému." + latest: "Nie sú žiadne nové témy. To je smutné." + hot: "Nie sú žiadne horúce témy." + bookmarks: "Nemáte žiadne témy v záložke" + category: "V kategórii {{category}} nie je žiadna téma" + top: "Nie sú žiadne populárne témy." + search: "Nenašli sa žiadne výsledky" + bottom: + latest: "Nie je už viac najnovšich tém." + hot: "Nie je už viac horúcich tém" + posted: "Žiadne ďalšie témy na čítanie." + read: "Žiadne ďalšie prečítané témy." + new: "Žiadne nové témy." + unread: "Žiadne ďalšie neprečítané témy." + category: "Žiadne ďalšie témy v {{category}}." + top: "Nie je už viac poulárnych tém" + bookmarks: "Žiadne ďalšie témy v záložkách." + search: "Nenašlo sa viac výsledkov." + topic: + unsubscribe: + stop_notifications: "Teraz budete dostávať menej upozornení na {{title}}" + change_notification_state: "Váš súčasný stav upozornení je" + filter_to: "{{post_count}} príspevkov k téme" + create: 'Nová téma' + create_long: 'Vytvoriť novú tému' + private_message: 'Vytvoríť správu' + archive_message: + help: 'Presunúť správu do archívu' + title: 'Archivovať' + move_to_inbox: + title: 'Presunúť do schránky' + help: 'Presunúť správu späť do schránky' + list: 'Témy' + new: 'nová téma' + unread: 'neprečítané' + new_topics: + one: '1 nová téma' + few: '{{count}} nové témy' + other: '{{count}} nových tém' + unread_topics: + one: '1 neprečítaná téma' + few: '{{count}} neprečítané témy' + other: '{{count}} neprečítaných tém' + title: 'Témy' + invalid_access: + title: "Téma je súkromná" + description: "Prepáčte, nemáte prístup k tejto téme!" + login_required: "Musíte sa prihlásiť, aby ste videli túto tému." + server_error: + title: "Tému sa nepodarilo načítať" + description: "Prepáčte, nepodarllo sa nám načítať túto tému, možno je problém s Vaším pripojením. Prosim skúste znova. Ak problém pretrváva, dajte nám vedieť" + not_found: + title: "Téma sa nenašla" + description: "Prepáčte, hľadaná téma nebola nájdená. Nebola odstránená moderátorom?" + total_unread_posts: + one: "máte 1 neprečítaný príspevok k tejto téme" + few: "máte {{count}} neprečítanépríspevky k tejto téme" + other: "máte {{count}} neprečítaných príspevkov k tejto téme" + unread_posts: + one: "máte 1 starší neprečítaný príspevok k tejto téme" + few: "máte {{count}} staršie neprečítané príspevky k tejto téme" + other: "máte {{count}} starších neprečítaných príspevkov k tejto téme" + new_posts: + one: "pribudol 1 nový príspevok odkedy ste čítali túto tému naposledy " + few: "pribudlo {{count}} nové príspevky odkedy ste čítali túto tému naposledy " + other: "pribudlo {{count}} nových príspevkov odkedy ste čítali túto tému naposledy " + likes: + one: "v tejto téme je jedo \"Páči sa\"" + few: "v tejto téme je {{count}} \"Páči sa\"" + other: "v tejto téme je {{count}} \"Páči sa\"" + back_to_list: "Naspäť na zoznam tém" + options: "Možnosti tém" + show_links: "zobrazovať odkazy v tejto téme" + toggle_information: "zmeniť detaily témy" + read_more_in_category: "Chcete si prečítať viac? Prezrite si témy v {{catLink}} alebo v {{latestLink}}." + read_more: "Chcete si prečítať viac? {{catLink}} alebo v {{latestLink}}." + read_more_MF: "Máte { UNREAD, plural, =0 {} one { 1 neprečítanú } other { # neprečítané } } { NEW, plural, =0 {} one { {BOTH, select, true{a} false { } other{}} 1 novú tému} other { {BOTH, select, true{a } false {} other{}} # nových tém} } na prečítanie, prípadne {CATEGORY, select, true {si pozrite iné témy v {catLink}} false {{latestLink}} other {}}" + browse_all_categories: Prezrieť všetky kategórie + view_latest_topics: zobraziť najnošie témy + suggest_create_topic: Čo tak vytvoriť novú tému? + jump_reply_up: prejsť na predchádzajúcu odpoveď + jump_reply_down: prejsť na nasledujúcu odpoveď + deleted: "Téma bola vymazaná" + auto_close_notice: "Táto téma bude automaticky uzavretá o %{timeLeft}." + auto_close_notice_based_on_last_post: "Táto téma bude uzavretá %{duration} po poslednej odpovedi." + auto_close_title: 'Nastavenia automatického zatvárania' + auto_close_save: "Uložiť" + auto_close_remove: "Neuzatvárať túto tému automaticky" + auto_close_immediate: "Posledný príspevok k téme je starý už %{hours} hodín, takže téma bude okamžite uzavretá. " + progress: + title: pozícia v téme + go_top: "na začiatok" + go_bottom: "na spodok" + go: "Choď" + jump_bottom: "choď na posledný príspevok" + jump_bottom_with_number: "choď na príspevok číslo %{post_number}" + total: Všetkých príspevkov + current: tento príspevok + position: "%{current} príspevok z %{total}" + notifications: + reasons: + '3_6': 'Budete dostávať upozornenia, pretože sa pozeráte na túto kategóriu.' + '3_5': 'Budete automaticky dostávať upozornenie pretože ste začali pozorovať túto tému.' + '3_2': 'Budete dostávať upozornenia, pretože sa pozeráte na túto tému.' + '3_1': 'Budete dostávať upozornenia, pretože ste vytvorili túto tému.' + '3': 'Budete dostávať upozornenia, pretože sa pozeráte na túto tému.' + '2_8': 'Budete dostávať upozornenia, pretože sledujete túto kategóriu.' + '2_4': 'Budete dostávať upozornenia, pretože ste zaslali odpoveď na túto tému.' + '2_2': 'Budete dostávať upozornenia, pretože sledujete túto tému.' + '2': 'Budete dostávať upozornenia, pretože ste čítali túto tému.' + '1_2': 'Budete upozornený ak niekto spomenie Vaše @meno alebo Vám odpovie.' + '1': 'Budete upozornený ak niekto spomenie Vaše @meno alebo Vám odpovie.' + '0_7': 'Ignorujete všetky upozornenia v tejto kategórii.' + '0_2': 'Ignorujete všetky upozornenia k tejto téme.' + '0': 'Ignorujete všetky upozornenia k tejto téme.' + watching_pm: + title: "Pozerať" + description: "Budete upozornený na každú novu dopoveť na túto správu, a zobrazí sa počet nových odpovedí" + watching: + title: "Pozerať" + description: "Budete upozornený na každú novu dopoveť na túto tému, a zobrazí sa počet nových odpovedí" + tracking_pm: + title: "Sledovať" + description: "Zobrazí počet nových odpovedí na túto správu. Budete upozornený ak niekto spomenie Vaše @meno alebo Vám odpovie." + tracking: + title: "Sledovať" + description: "Zobrazí počet nových odpovedí na túto tému. Budete upozornený ak niekto spomenie Vaše @meno alebo Vám odpovie." + regular: + title: "Bežný" + description: "Budete upozornený ak niekto spomenie Vaše @meno alebo Vám odpovie." + regular_pm: + title: "Bežný" + description: "Budete upozornený ak niekto spomenie Vaše @meno alebo Vám odpovie." + muted_pm: + title: "Stíšené" + description: "Nikdy nebudete upozornení na nič ohľadom tejto správy" + muted: + title: "Stíšené" + description: "Nikdy nebudete upozornení na nič ohľadom tejto témy, a nebude sa zobrazovať medzi najnovšími." + actions: + recover: "Obnoviť zmazanú tému" + delete: "Zmazať tému" + open: "Otvoriť tému" + close: "Uzavrieť tému" + multi_select: "Označ príspevky...." + auto_close: "Automaticky zatvor...." + pin: "Pripni tému...." + unpin: "Odopni tému...." + unarchive: "Zruš archiváciu témy" + archive: "Archívuj tému" + invisible: "Skyť" + visible: "Zobraziť" + reset_read: "Zrušiť načítané údaje" + feature: + pin: "Pripni tému" + unpin: "Odopni tému" + pin_globally: "Pripni tému globálne" + make_banner: "Banerová téma" + remove_banner: "Odstrániť banerovú tému" + reply: + title: 'Odpovedať' + help: 'vytvor odpoveď k tejto téme' + clear_pin: + title: "Zruš pripnutie" + help: "Zruší pripnutie tejto témy takže sa už viac nebude objavovať na vrchu Vášho zoznamu tém" + share: + title: 'Zdielaj' + help: 'zdieľaj odkaz na túto tému' + flag_topic: + title: 'Označ' + help: 'súkromne označiť túto tému do pozornosti, alebo na ňu poslať súkromne upozornenie' + success_message: 'Úspešne ste označili tému.' + feature_topic: + title: "Vyzdvihni túto tému" + pin: "Zobrazuj túto tému na vrchu {{categoryLink}} kategórie do" + confirm_pin: "Máte už {{count}} pripnutých tém. Príliš veľa pripnutých tém môže byť na príťaž pre nových a anonymných užívateľov. Ste si istý že chcete pripnúť ďalšiu tému v tejto kategórii?" + unpin: "Zruš túto tému z vrcholu kategórie {{categoryLink}} . " + unpin_until: "Zruš túto tému z vrcholu kategórie {{categoryLink}} , alebo počkaj do %{until}." + pin_note: "Užívatelia si môžu sami odopnúť tému " + pin_validation: "Dátum je vyžadovaný k pripnutiu tejto témy." + not_pinned: "V {{categoryLink}} nie sú pripnuté žiadne témy." + already_pinned: + one: "Téma pripnutá k {{categoryLink}}: 1" + few: "Témy pripnuté ku {{categoryLink}}: {{count}}" + other: "Tém pripnutých k {{categoryLink}}: {{count}}" + pin_globally: "Zobrazuj túto tému na vrchu všetkých zoznamov tém do" + confirm_pin_globally: "Máte už {{count}} globálne pripnutých tém. Príliš veľa pripnutých tém môže byť na príťaž pre nových a anonymných užívateľov. Ste si istý že chcete pripnúť ďalšiu globálnu tému?" + unpin_globally: "Zruš túto tému z vrcholu všetkých zoznamov tém. " + unpin_globally_until: "Zruš túto tému z vrcholu všetkých zoznamov tém, alebo počkaj do %{until}." + global_pin_note: "Užívatelia si môžu sami odopnúť tému." + not_pinned_globally: "Nie sú pripnuté žiadne globálne témy." + already_pinned_globally: + one: "Globálne pripnutá téma : 1" + few: "Globálne pripnuté témy : {{count}}" + other: "Globálne pripnutých tém : {{count}}" + make_banner: "Spraviť z tejto témy baner, ktorý sa zobrazí navrchu každej stránky." + remove_banner: "Odstrániť baner, ktorý sa zobrazuje navrchu každej stránky." + banner_note: "Užívatelia môžu banner kedykoľvek zrušiť. Bannerom môže byť v jednom momente len jedna téma." + no_banner_exists: "Neexistuje žiadna banerová téma." + banner_exists: "Banerová téma je aktuálne nastavená." + inviting: "Pozývam..." + automatically_add_to_groups_optional: "Táto pozvánka obsahuje taktiež prístup do týchto skupín: ( nepovinné, iba správca) " + automatically_add_to_groups_required: "Táto pozvánka obsahuje taktiež prístup do týchto skupín: ( Povinné, iba správca) " + invite_private: + title: 'Pozvať do konverzácie' + email_or_username: "Email, alebo užívateľské meno pozvaného" + email_or_username_placeholder: "emailova adresa alebo uťívateľské meno" + action: "Pozvi" + success: "Pozvali sme tohoto uťívateľa aby sa podieľal na tejto správe" + error: "Prepáčte, pri pozývaní tohto užívateľa nastala chyba." + group_name: "názov skupiny" + controls: "Ovládacie prvky Témy" + invite_reply: + title: 'Pozvi' + username_placeholder: "používateľské meno" + action: 'Pošli pozvánku' + help: 'pozvite ostatných k tejto téme prostredníctvom emailu, alebo upozornení' + to_forum: "Pošleme krátký email dovoľujúci Vášmu priateľovi okamžité pripojenie kliknutím na odkaz bez potreby prihlasovania" + sso_enabled: "Zadajte uťívateľské meno osoby, ktorú by ste radi pozvali k tejto téme" + to_topic_blank: "Zadajte uťívateľské meno alebo email osoby, ktorú by ste radi pozvali k tejto téme" + to_topic_email: "Zadali ste emailovú adresu. Pošleme pozvánku ktorá umožní Vášmu priateľovi okamžitú odpoveď k tejto téme." + to_topic_username: "Zadali ste užívateľské meno. Pošleme mu pozvánku s odkazom na túto tému." + to_username: "Zadajte užívateľské meno osoby, ktorú chcete pozvať. Pošleme mu pozvánku s odkazom na túto tému." + email_placeholder: 'name@example.com' + success_email: "Poslali sme email s pozvánkou na {{emailOrUsername}}. Upozorníme vas keď bude pozvánka použítá. Svoje pozvánky môžte sledovať v tabuľke pozvánok vo svojom užívateľskom profile." + success_username: "Pozvali sme tohoto uťívateľa aby sa podieľal na tejto téme." + error: "Prepáčte, Nepodarilo sa nám pozvať túto osobu. Nebola už náhodou pozvaná ? (Počet opakovaných pozvánok je obmedzený)" + login_reply: 'Príhláste sa ak chcete odpovedať' + filters: + n_posts: + one: "1 príspevok" + few: "{{count}} príspevky" + other: "{{count}} príspevkov" + cancel: "Zruš filter" + split_topic: + title: "Presuň na novú tému" + action: "presuň na novú tému" + topic_name: "Názov novej témy" + error: "Nastala chyba pri presune príspevku na novú tému." + instructions: + one: "Vytvárate novú tému do ktorej bude vložený príspevok, ktorý ste označili. " + few: "Vytvárate novú tému do ktorej bude vložených {{count}} príspevkov, ktoré ste označili. " + other: "Vytvárate novú tému do ktorej budú vložené {{count}} príspevky, ktoré ste označili. " + merge_topic: + title: "Presuň do existujúcej témy." + action: "presuň do existujúcej témy" + error: "Nastala chyba pri presune príspevku do tejto témy." + instructions: + one: "Prosím vyberte tému do ktorej chcete presunúť tento príspevok." + few: "Prosím vyberte tému do ktorej chcete presunúť tieto {{count}} príspevky." + other: "Prosím vyberte tému do ktorej chcete presunúť týchto {{count}} príspevkov." + change_owner: + title: "Zmeň vlástníka príspevkov" + action: "zmeň vlastníka" + error: "Nastala chyba pri zmene vlastníka príspevkov." + label: "Príspevky nového vlastníka" + placeholder: "užívateľske meno nového vlastnika" + instructions: + one: "Prosím vyberte nového vlastníka príspevku vytvoreného {{old_user}}." + few: "Prosím vyberte nového vlastníka {{count}} príspevkov vytvorených {{old_user}}." + other: "Prosím vyberte nového vlastníka {{count}} príspevkov vytvorených {{old_user}}." + instructions_warn: "Poznámka: Žiadne upozornenie o tomto príspevku nebude spätne zaslané novým užívateľom
    Upozornenie: Momentálne nie sú prenášané žiadne dáta vťahujúce sa k príspevku na nových užívateľov. Používajte opatrne." + change_timestamp: + title: "Nastavte časovú značku" + action: "nastavte časovú značku" + invalid_timestamp: "Časová značka nemôže byť v budúcnosti. " + error: "Nastala chyba pri zmene časovej značky témy." + instructions: "Prosím vyberte novú časovú značku témy. Príspevky k téme budu aktualizované so zachovaním časoveho rozdielu." + multi_select: + select: 'označ' + selected: 'označených ({{count}})' + select_replies: 'označ +odpovede' + delete: zmaž označené + cancel: zrušiť výber + select_all: označ všetko + deselect_all: odznač všetko + description: + one: Označili ste 1 príspevok + few: Označili ste {{count}} príspevky + other: Označili ste {{count}} príspevkov + post: + reply: " {{replyAvatar}} {{usernameLink}}" + reply_topic: " {{link}}" + quote_reply: "citovať odpoveď" + edit: "Upravujete {{link}} {{replyAvatar}} {{username}}" + edit_reason: "Dôvod:" + post_number: "príspevok {{number}}" + last_edited_on: "príspevok naposledy upravený" + reply_as_new_topic: "Odpoveď ako súvisiaca téma" + continue_discussion: "Pokračovanie diskusie z {{postLink}}:" + follow_quote: "prejsť na citovaný príspevok" + show_full: "Zobraziť celý príspevok" + show_hidden: 'Zobraziť skrytý obsah.' + deleted_by_author: + one: "(príspevky stiahnuté autorom budú automaticky zmazané za jednu hodinu pokiaľ nie sú označené)" + few: "(príspevky stiahnuté autorom budú automaticky zmazané za %{count} hodiny pokiaľ nie sú označené)" + other: "(príspevky stiahnuté autorom budú automaticky zmazané za %{count} hodín pokiaľ nie sú označené)" + expand_collapse: "rozbaliť/zbaliť" + gap: + one: "zobraziť skrytú odpoveď" + few: "zobraziť {{count}} skryté odpovede" + other: "zobraziť {{count}} skrytých odpovedí" + more_links: "ešte {{count}} " + unread: "Príspevok je neprečítaný." + has_replies: + one: "{{count}} Odpoveď" + few: "{{count}} Odpovede" + other: "{{count}} Odpovedí" + has_likes: + one: "{{count}} \"Páči sa\"" + few: "{{count}} \"Páči sa\"" + other: "{{count}} \"Páči sa\"" + has_likes_title: + one: "Tento príspevok sa páčil jedej osobe" + few: "Tento príspevok sa páčil {{count}} ľuďom" + other: "Tento príspevok sa páčil {{count}} ľuďom" + has_likes_title_only_you: "tento príspevok sa Vám páči" + has_likes_title_you: + one: "Tento príspevok sa páčil Vám a jednej ďalšej osobe" + few: "Tento príspevok sa páčil Vám a ďalším {{count}} ľuďom" + other: "Tento príspevok sa páčil Vám a ďalším {{count}} ľuďom" + errors: + create: "Ľutujeme, pri vytváraní príspevku nastala chyba. Prosím, skúste znovu." + edit: "Ľutujeme, pri úprave príspevku nastala chyba. Prosím, skúste znovu." + upload: "Ľutujeme, pri nahrávaní súboru nastala chyba. Prosím, skúste znovu." + attachment_too_large: "Ľutujeme, súbor, ktorý sa pokúšate nahrať, je príliš veľký (maximálna veľkosť je {{max_size_kb}}kb)." + file_too_large: "Ľutujeme, súbor, ktorý sa pokúšate nahrať je príliš veľký (maximálna veľkosť je {{max_size_kb}}kb)" + too_many_uploads: "Ľutujeme, ale naraz je možné nahrať len jeden súbor." + too_many_dragged_and_dropped_files: "Prepáčte, naraz môžte presunúť maximálne 10 súborov." + upload_not_authorized: "Ľutujeme, súbor, ktorý sa pokúšate nahrať nemá povolenú príponu (povolené prípony sú: {{authorized_extensions}})." + image_upload_not_allowed_for_new_user: "Ľutujeme, noví použivatelia nemôžu nahrávať obrázky." + attachment_upload_not_allowed_for_new_user: "Ľutujeme, noví používatelia nemôžu nahrávať prílohy." + attachment_download_requires_login: "Ľutujeme, pre stiahnutie príloh musíte byť prihlásený." + abandon: + confirm: "Ste si istý, že chcete zahodiť tento príspevok?" + no_value: "Nie, ponechať." + yes_value: "Áno, zahodiť." + via_email: "tento príspevok prišiel emailom" + whisper: "tento príspevok je súkromným šepotom pre moderátorov" + wiki: + about: "tento príspevok je wiki" + archetypes: + save: 'Uložiť možnosti' + controls: + reply: "vytvorte odpoveď na tento príspevok" + like: "páči sa mi tento príspevok" + has_liked: "tento príspevok sa Vám páči" + undo_like: "zruš \"Páči sa\"" + edit: "Editovať tento príspevok." + edit_anonymous: "Ľutujeme, ale pre úpravu príspevku je potrebné sa prihlásiť." + flag: "súkromne označiť tento príspevok do pozornosti, alebo naň poslať súkromne upozornenie" + delete: "odstrániť tento príspevok" + undelete: "vrátiť späť odstránenie príspevku" + share: "zdieľať odkaz na tento príspevok" + more: "Viac" + delete_replies: + confirm: + one: "Chcete tiež odstrániť {{count}} priamu reakciu na tento príspevok?" + few: "Chcete tiež odstrániť {{count}} priame reakcie na tento príspevok?" + other: "Chcete tiež odstrániť {{count}} priamych reakcií na tento príspevok?" + yes_value: "Áno, odstrániť aj reakcie." + no_value: "Nie, len tento príspevok." + admin: "akcie administrátora príspevku" + wiki: "Spraviť Wiki" + unwiki: "Odstrániť Wiki" + convert_to_moderator: "Pridať farbu personálu" + revert_to_regular: "Odobrať farbu personálu" + rebake: "Pregenerovať HTML" + unhide: "Odokryť" + change_owner: "Zmeniť vlastníctvo" + actions: + flag: 'Označ' + defer_flags: + one: "Zrušiť označenie" + few: "Zrušiť označenia" + other: "Zrušiť označenia" + it_too: + off_topic: "Tiež označ" + spam: "Tiež označ" + inappropriate: "Tiež označ" + custom_flag: "Tiež označ" + bookmark: "Tiež vytvoriť záložku" + like: "Tiež sa mi páči" + vote: "Tiež hlasujem za" + undo: + off_topic: "Zruš označenie" + spam: "Zruš označenie" + inappropriate: "Zruš označenie" + bookmark: "Vrátiť záložku späť" + like: "Zruš \"Páči sa\"" + vote: "Zruš hlasovanie" + people: + vote: "hlasovať za toto" + by_you: + off_topic: "Označíli ste to ako mimo tému" + spam: "Označíli ste to ako spam" + inappropriate: "Označíli ste to ako nevhodné" + notify_moderators: "Označíli ste to pre moderátora" + notify_user: "Poslali ste správu užívateľovi " + bookmark: "Vytvorili ste si záložku na tento príspevok" + like: "Páči sa Vám to" + vote: "Hlasoval ste za tento príspevok" + by_you_and_others: + off_topic: + one: "Vy a 1 ďalšia osoba to označílo ako mimo tému" + few: "Vy a ďalšie {{count}} osoby to označíli ako mimo tému" + other: "Vy a ďalších {{count}} osôb to označílo ako mimo tému" + spam: + one: "Vy a 1 ďalšia osoba to označíla ako spam" + few: "Vy a ďalšie {{count}} osoby to označíli ako spam" + other: "Vy a ďalších {{count}} osôb to označílo ako spam" + inappropriate: + one: "Vy a jedna ďalšia osoba to označila ako nevhodné" + few: "Vy a ďalšie {{count}} osoby to označili ako nevhodné" + other: "Vy a ďalších {{count}} osôb to označilo ako nevhodné" + notify_moderators: + one: "Vy a jedna ďalšia osoba to označila na moderovanie" + few: "Vy a ďalšie {{count}} osoby to označili na moderovanie" + other: "Vy a ďalších {{count}} osôb to označilo na moderovanie" + notify_user: + one: "Vy a jedna ďalšia osoba poslala správu tomuto užívateľovi" + few: "Vy a ďalšie {{count}} osoby poslali správu tomuto užívateľovi" + other: "Vy a ďalších {{count}} osôb poslalo správu tomuto užívateľovi" + bookmark: + one: "Vy a jedna ďalšia osoba si vytvorilo záložku na tento príspevok" + few: "Vy a ďalšie {{count}} osoby si vytvorili záložku na tento príspevok" + other: "Vy a ďalších {{count}} osôb si vytvorilo záložku na tento príspevok" + like: + one: "Páči sa to Vám a jendej ďalšej osobe" + few: "Páči sa to Vám a ďalším {{count}} osobám" + other: "Páči sa to Vám a ďalším {{count}} osobám" + vote: + one: "Vy a jenda ďalšia osoba hlasovala za tento príspevok" + few: "Vy a ďalšie {{count}} osoby hlasovalo za tento príspevok" + other: "Vy a ďalších {{count}} osôb hlasovalo za tento príspevok" + by_others: + off_topic: + one: "1 osoba to označíla ako mimo tému" + few: "{{count}} osoby to označíli ako mimo tému" + other: "{{count}} osôb to označílo ako mimo tému" + spam: + one: "1 osoba to označíla ako spam" + few: "{{count}} osoby to označíli ako spam" + other: "{{count}} osôb to označílo ako spam" + inappropriate: + one: "1 osoba to označila ako nevhodné" + few: "{{count}} osoby to označili ako nevhodné" + other: "{{count}} osôb to označilo ako nevhodné" + notify_moderators: + one: "1 osoba to označila na moderovanie" + few: "{{count}} osoby to označili na moderovanie" + other: "{{count}} osôb to označilo na moderovanie" + notify_user: + one: "1 osoba poslala správu tomuto užívateľovi" + few: "{{count}} osoby poslali správu tomuto užívateľovi" + other: "{{count}} osôb poslalo správu tomuto užívateľovi" + bookmark: + one: "1 osoba si vytvorila záložku na tento príspevok" + few: "{{count}} osoby si vytvorili záložku na tento príspevok" + other: "{{count}} osôb si vytvorilo záložku na tento príspevok" + like: + one: " {{count}} osobe sa to páčilo" + few: " {{count}} osobám sa to páčilo" + other: " {{count}} osobám sa to páčilo" + vote: + one: "1 osoba hlasovala za tento príspevok" + few: "{{count}} osoby hlasovali za tento príspevok" + other: "{{count}} osôb hlasovalo za tento príspevok" + delete: + confirm: + one: "Ste si istý že chcete zmazať tento príspevok?" + few: "Ste si istý že chcete zmazať všetky tieto príspevky?" + other: "Ste si istý že chcete zmazať všetky tieto príspevky?" + revisions: + controls: + first: "Prvá revízia" + previous: "Predchádzajúca revízia" + next: "Ďalšia revízia" + last: "Posledná revízia" + hide: "Skriť revíziu" + show: "Ukáza revíziu" + comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" + displays: + inline: + title: "Zobraz výstup vrátane pridaného a zmazaného v riadku" + button: ' HTML' + side_by_side: + title: "Zobraziť rozdiely v generovanom výstupe vedľa seba" + button: ' HTML' + side_by_side_markdown: + title: "Zobraziť rozdiely v pôvodnom zdroji vedľa seba" + button: ' Neupravený' + category: + can: 'môže … ' + none: '(Bez kategórie)' + all: 'Všetky kategórie' + choose: 'Vyber kategóriu…' + edit: 'uprav' + edit_long: "Upraviť" + view: 'Prezerať témy v kategórii' + general: 'Všeobecné' + settings: 'Nastavenia' + topic_template: "Formulár témy" + delete: 'Odstrániť kategóriu' + create: 'Nová kategória' + create_long: 'Vytvoriť novú kategóriu' + save: 'Uložiť kategóriu' + slug: 'URL kategórie' + slug_placeholder: '(Voliteľné) pomlčkou-prerušované-slová pre url' + creation_error: Nastala chyba počas vytvárania kategórie. + save_error: Nastala chyba počas ukladania kategórie + name: "Názov kategórie" + description: "Popis" + topic: "kategória témy" + logo: "Logo kategórie" + background_image: "Pozadie kategórie" + badge_colors: "Farby odznakov" + background_color: "Farba pozadia" + foreground_color: "Farba popredia" + name_placeholder: "Maximálne jedno dve slová" + color_placeholder: "Ľubovoľná farba stránky" + delete_confirm: "Ste si istý že chcete zmazať túto kategóriu?" + delete_error: "Nastala chyba počas mazania kategórie" + list: "Zoznam kategórií" + no_description: "Prosím, pridajte popis k tejto kategórii." + change_in_category_topic: "Uprav popis" + already_used: 'Táto farba je už použitá inou kategóriou' + security: "Bezpečnosť" + special_warning: "Upozornenie: Toto je preddefinovaná kategória a jej bezpečnostné nastavenia sa nedajú upraviť. Pokiaľ si neželáte použiť túto kategóriu, neupravujte ju, ale zmažte." + images: "Obrázky" + auto_close_label: "Automaticky uzavrieť tému po:" + auto_close_units: "hodinách" + email_in: "Vlastná e-mailová adresa pre príchodziu poštu:" + email_in_allow_strangers: "Prijímať emaily od anonymných užívateľov bez účtu" + email_in_disabled: "Vkladanie nových tém cez email je zablokované v Nastaveniach stránky. Ak chcete povoliť vkladanie nových téme cez email," + email_in_disabled_click: 'povoľte nastavenie "email in"' + suppress_from_homepage: "Pozastaviť kategóriu z domovskej stránky." + allow_badges_label: "Povoliť získavanie odznakov v tejto kategórii" + edit_permissions: "Upraviť práva" + add_permission: "Pridať práva" + this_year: "tento rok" + position: "pozícia" + default_position: "Predvolená pozícia" + position_disabled: "Kategórie budú zobrazené podľa aktivity. Pre možnosť ovládania poradia kategórií v zozname," + position_disabled_click: 'povoľte možnosť "pevné poradie kategórií"' + parent: "Nadradená kategória" + notifications: + watching: + title: "Pozerať" + description: "Budete automaticky pozerať všetky nové témy v týchto kategóriách. Budete upozornený na všetky nové príspevky vo všetkých témach. Zároveň bude zobrazený počet nových odpovedí." + tracking: + title: "Sledovať" + description: "Budete automaticky sledovať všetky nové témy v týchto kategóriách. Budete upozornený ak niekto uvedie vaše @meno alebo Vám odpovie. Zároveň bude zobrazený počet nových odpovedí." + regular: + title: "Bežný" + description: "Budete upozornený ak niekto spomenie Vaše @meno alebo Vám odpovie." + muted: + title: "Stíšené" + description: "Nikdy nebudete informovaní o udalostiach v nových témach týchto kategórií. Tieto témy sa zároveň nebudú zobrazovať v zozname posledných udalostí." + flagging: + title: 'Ďakujeme, že pomáhate udržiavať slušnosť v našej komunite!' + action: 'Označ príspevok' + take_action: "Vykonať akciu" + notify_action: 'Správa' + delete_spammer: "Zmazať spammera" + delete_confirm: "Idete vymazať %{posts} príspevky a %{topics} témy tohto užívateľa, zmazať jeho účet, zakázať prihlásenia z jeho IP adresy %{ip_address}, a pridať jeho email %{email} na zoznam trvalo zakázaných. Ste si istý, že tento užívateľ je skutočne spamer?" + yes_delete_spammer: "Áno, zmazať spammera" + ip_address_missing: "(nedostupné)" + hidden_email_address: "(skryté)" + submit_tooltip: "Odoslať súkromné označenie" + take_action_tooltip: "Dosiahnuť okamžite limit označení, namiesto čakania na ďalšie označenia od komunity" + cant: "Ľutujeme, ale tento príspevok sa teraz nedá označiť ." + formatted_name: + off_topic: "Je to mimo témy" + inappropriate: "Je to nevhodné" + spam: "Je to spam" + custom_placeholder_notify_user: "Buďte konkrétny, buďte konštruktívny a buďte vždy milý." + custom_placeholder_notify_moderators: "Dajte nám vedieť, z čoho konkrétne máte obavy, a priložte príslušné odkazy a príklady, ak je to možné." + custom_message: + at_least: "zadajte aspoň {{n}} znakov" + more: "zostáva ešte {{n}} ..." + left: "{{n}} zostáva" + flagging_topic: + title: "Ďakujeme, že pomáhate udržiavať slušnosť v našej komunite!" + action: "Označ príspevok" + notify_action: "Správa" + topic_map: + title: "Zhrnutie článku" + participants_title: "Častí prispievatelia" + links_title: "Populárne odkazy" + links_shown: "ukázať všetkých {{totalLinks}} odkazov..." + clicks: + one: "%{count} kilk" + few: "%{count} kliky" + other: "%{count} klikov" + topic_statuses: + warning: + help: "Toto je oficiálne varovanie." + bookmarked: + help: "Vytvorili ste si záložku na túto tému" + locked: + help: "Táto téma je už uzavretá. Nové odpovede už nebudú akceptované" + archived: + help: "Táto téma je archivovaná. Už sa nedá meniť. " + locked_and_archived: + help: "Táto téma je už uzavretá a archivovaná. Nové odpovede ani zmeny už nebudú akceptované " + unpinned: + title: "Odopnuté" + help: "Túto tému ste odopli. Bude zobrazená v bežnom poradí." + pinned_globally: + title: "Globálne pripnuté" + help: "Tento príspevok je globálne uprednostnený. Zobrazí sa na začiatku v: zozname posledných článkov a vo svojej kategórii." + pinned: + title: "Pripnutý" + help: "Túto tému ste pripli. Bude zobrazená na vrchole svojej kategórie" + invisible: + help: "Táto téma je skrytá. Nebude zobrazená v zozname tém a prístup k nej bude možný len prostrednictvom priameho odkazu na ňu" + posts: "Príspevky" + posts_lowercase: "príspevky" + posts_long: "v tejto téme je {{number}} príspevkov" + posts_likes_MF: | + Táto téma obsahuje {count, plural, one {1 odpoveď} other {# odpovedí}} {ratio, select, + low {s vysokým pomerom "Páči sa" na príspevok} + med {s veľmi vysokým pomerom "Páči sa" na príspevok} + high {s extrémne vysokým pomerom "Páči sa" na príspevok} + other {}} + original_post: "Pôvodný príspevok" + views: "Zobrazenia" + views_lowercase: + one: "zobrazenie" + few: "zobrazenia" + other: "zobrazení" + replies: "Odpovede" + views_long: "táto téma bola prezeraná {{number}} krát " + activity: "Aktivita" + likes: "Páči sa mi" + likes_lowercase: + one: "\"Páči sa\"" + few: "\"Páči sa\"" + other: "\"Páči sa\"" + likes_long: "v tejto téme je {{number}} \"Páči sa\"" + users: "Používatelia" + users_lowercase: + one: "užívateľ" + few: "užívatelia" + other: "užívatelia" + category_title: "Kategória" + history: "História" + changed_by: "od {{author}}" + raw_email: + title: "Neupravený email" + not_available: "Nedostupné!" + categories_list: "Zoznam kategórií" + filters: + with_topics: "%{filter} témy" + with_category: "%{filter} %{category} témy" + latest: + title: "Najnovšie" + title_with_count: + one: "Posledný (1)" + few: "Posledné ({{count}})" + other: "Posledných ({{count}})" + help: "témy s nedávnymi príspevkami" + hot: + title: "Horúca" + help: "výber najhorúcejších tém" + read: + title: "Prečítaná" + help: "prečítané témy, zoradené podľa času ich prečítania" + search: + title: "Hľadať" + help: "hľadaj vo všetkych témach" + categories: + title: "Kategórie" + title_in: "Kategória - {{categoryName}}" + help: "všetky témy zoskupené podľa kategórie" + unread: + title: "Neprečítané" + title_with_count: + one: "Neprečítaná (1)" + few: "Neprečítané ({{count}})" + other: "Neprečítaných ({{count}})" + help: "témy ktorých neprečítané príspevky v súčastnosti pozeráte alebo sledujete " + lower_title_with_count: + one: "1 neprečítaná" + few: "{{count}} neprečítané" + other: "{{count}} neprečítaných" + new: + lower_title_with_count: + one: "1 nová" + few: "{{count}} nové" + other: "{{count}} nových" + lower_title: "nový" + title: "Nový" + title_with_count: + one: "Nová (1)" + few: "Nové ({{count}})" + other: "Nových ({{count}})" + help: "témy vytvorené za posledných pár dní" + posted: + title: "Moje príspevky" + help: "témy s vašimi príspevkami" + bookmarks: + title: "Záložky" + help: "témy, ktoré máte v záložkách" + category: + title: "{{categoryName}}" + title_with_count: + one: "{{categoryName}} ({{count}})" + few: "{{categoryName}} ({{count}})" + other: "{{categoryName}} ({{count}})" + help: "najnovšie témy v kategórii {{categoryName}}" + top: + title: "Vrch" + help: "najaktívnejšie témy za posledný rok, mesiac, týždeň, alebo deň" + all: + title: "Za celú dobu" + yearly: + title: "Ročne" + quarterly: + title: "Štvrťročne" + monthly: + title: "Mesačne" + weekly: + title: "Týždenne" + daily: + title: "Denne" + all_time: "Za celú dobu" + this_year: "Rok" + this_quarter: "Štvrťrok" + this_month: "Mesiac" + this_week: "Týždeň" + today: "Dnes" + other_periods: "pozri hore" + browser_update: 'Ľutujeme, Váš prehliadač je príliš starý na prácu na tejto stránke. Prosím aktualizujte Váš prehliedač.' + permission_types: + full: "Vytvor / Odpovedz / Zobraz" + create_post: "Odpovedz / Zobraz" + readonly: "Zobraz" + admin_js: + type_to_filter: "zadajte, čo chcete filtrovať ..." + admin: + title: 'Administrátor Discourse' + moderator: 'Moderátor' + dashboard: + title: "Ovládací panel" + last_updated: "Dashboard naposledy aktualizovaný:" + version: "Verzia" + up_to_date: "Máte nainštalovanú najnovšiu verziu!" + critical_available: "Je dostupná kritická aktualizácia." + updates_available: "Aktualizácie sú k dispozícii." + please_upgrade: "Prosím aktualizujte!" + no_check_performed: "Neprebehlo zisťovanie aktualizácií. Uistite sa že je spustený sidekiq." + stale_data: "V poslednej dobe neprebehlo zisťovanie aktualizácií. Uistite sa že je spustený sidekiq." + version_check_pending: "Zdá sa že ste nedávno aktualizovali. Fantastické!" + installed_version: "Nainštalované" + latest_version: "Najnovšie" + problems_found: "Boli zistené nejaké problémy s Vašou inštaláciou Discourse." + last_checked: "Naposledy overené" + refresh_problems: "Obnoviť" + no_problems: "Nenašli sa žiadne problémy." + moderators: 'Moderátori:' + admins: 'Administrátori:' + blocked: 'Zablokované:' + suspended: 'Odobraté:' + private_messages_short: "Správy" + private_messages_title: "Správy" + mobile_title: "Mobil" + space_free: "{{size}} voľné" + uploads: "nahraté" + backups: "zálohy" + traffic_short: "Vyťaženie" + traffic: "Požiadavky webových aplikácií" + page_views: "Požiadavky API" + page_views_short: "Požiadavky API" + show_traffic_report: "Zobraziť detaily vyťaženia" + reports: + today: "Dnes" + yesterday: "Včera" + last_7_days: "Posledných 7 dní" + last_30_days: "Posledných 30 dní" + all_time: "Za celú dobu" + 7_days_ago: "Pred 7 dňami" + 30_days_ago: "Pred 30 dňami" + all: "Všetky" + view_table: "tabuľka" + view_chart: "stĺpcový graf" + refresh_report: "Obnoviť report" + start_date: "Od" + end_date: "Do" + groups: "Všetky skupiny" + commits: + latest_changes: "Najnov3ie zmeny. Prosime aktualizujte čo najčastejšie!" + by: "podľa" + flags: + title: "Označenia" + old: "Staré" + active: "Aktívny" + agree: "Súhlasiť" + agree_title: "Akceptovať toto označenie ako platné a správne" + agree_flag_modal_title: "Súhlasiť a ...." + agree_flag_hide_post: "Súhlasiť (skryť príspevok a poslať súkromnú správu)" + agree_flag_hide_post_title: "Skryť tento príspevok a automaticky poslať súkromnú správu s výzvou na úpravu príspevku." + agree_flag_restore_post: "Súhlasiť (obnoviť príspevok)" + agree_flag_restore_post_title: "Obnoviť tento príspevok" + agree_flag: "Súhlasiť s označením" + agree_flag_title: "Súhlasiť s označením, ale nemeníť príspevok" + defer_flag: "Odložiť" + defer_flag_title: "Zrušíť označenie. Žiadna akcia nie je nateraz potrebná." + delete: "Odstrániť" + delete_title: "Zmazať príspevok na ktorý označenie odkazuje ." + delete_post_defer_flag: "Zmazať príspevok a zrušiť označenie" + delete_post_defer_flag_title: "Zmazať prípspevok; ak ide o prvý príspevok, zmazať aj tému" + delete_post_agree_flag: "Zmazať príspevok a súhlasiť s označením" + delete_post_agree_flag_title: "Zmazať prípspevok; ak ide o prvý príspevok, zmazať aj tému" + delete_flag_modal_title: "Zmazať a..." + delete_spammer: "Zmazať spammera" + delete_spammer_title: "Zmazať užívateľa aj všetky príspevky a témy ktoré vytvoril." + disagree_flag_unhide_post: "Nesúhlasiť (odkryť príspevok)" + disagree_flag_unhide_post_title: "Zrušíť všetky označenia z príspevku a znova odkryť príspevok" + disagree_flag: "Nesúhlasiť" + disagree_flag_title: "Zamietnuť toto označenie ako neplatné, alebo nesprávne" + clear_topic_flags: "Hotovo" + clear_topic_flags_title: "Téma bola preskúmaná a problémy boli vyriešené. Kliknite Hotovo pre zrušenie označení." + more: "(viac odpovedí...)" + dispositions: + agreed: "odsúhlasené" + disagreed: "neodsúhlasené" + deferred: "odložené" + flagged_by: "Označené " + resolved_by: "Vyriešené" + took_action: "Prijal opatrenia" + system: "Systém" + error: "Niečo sa pokazilo" + reply_message: "Odpovedať" + no_results: "Žiadne označenia." + topic_flagged: "Táto téma bola označená. " + visit_topic: "Navšťívte tému pre prijatie opatrení" + was_edited: "Príspevok bol upravený po prvom označení" + previous_flags_count: "Tento príspevok bol už označený {{count}} krát." + summary: + action_type_3: + one: "mimo tému" + few: "mimo tému x{{count}}" + other: "mimo tému x{{count}}" + action_type_4: + one: "nevhodný" + few: "nevhodné x{{count}}" + other: "nevhodných x{{count}}" + action_type_6: + one: "vlastná" + few: "vlastné x{{count}}" + other: "vlastných x{{count}}" + action_type_7: + one: "vlastný" + few: "vlastné x{{count}}" + other: "vlastných x{{count}}" + action_type_8: + one: "spam" + few: "spam x{{count}}" + other: "spam x{{count}}" + groups: + primary: "Hlavná skupina" + no_primary: "(bez hlavnej skupiny)" + title: "Skupiny" + edit: "Upraviť skupiny" + refresh: "Obnoviť" + new: "Nový" + selector_placeholder: "zadať používateľské meno" + name_placeholder: "Názov skupiny, bez medzier, rovnaké pravidlá ako pre uťívateľa" + about: "Tu upravíte Vaše členstvo v skupinách a mená" + group_members: "Členovia skupiny" + delete: "Odstrániť" + delete_confirm: "Zmazať túto skupinu?" + delete_failed: "Nepodarilo sa zmazať skupinu. Pokiaľ je skupina automatická, nemôže byť zrušená." + delete_member_confirm: "Odstrániť '%{username}' zo skupiny '%{group}'?" + delete_owner_confirm: "Odobrať vlastnícke práva %{username}'?" + name: "Meno" + add: "Pridať" + add_members: "Pridať členov" + custom: "Vlastné" + bulk_complete: "Užívatelia boli pridaní do skupiny." + bulk: "Hromadné pridanie do skupiny" + bulk_paste: "Vlož zoznam používateľov alebo emailov, jeden na riadok:" + bulk_select: "(vyberte skupinu)" + automatic: "Automaticky" + automatic_membership_email_domains: "Užívatelia, ktorí sa zaregistrovali s emailovou doménou uvedenou v zozname budú automaticky pridaní do tejto skupiny. " + automatic_membership_retroactive: "Použi pravidlo rovnakej emailovej domény pre pridanie registrovaných užívateľov" + default_title: "Štandardné označenie pre všetkých používateľov v tejto skupine" + primary_group: "Automaticky nastav ako hlavnú skupinu" + group_owners: Vlastníci + add_owners: Pridať vlastníkov + incoming_email: "Vlastná e-mailová adresa pre príchodziu poštu" + incoming_email_placeholder: "zadajte emailovú adresu" + api: + generate_master: "Vygenerovať Master API kľúč" + none: "V súčasnosti neexistujú žiadne aktívne API kľúče." + user: "Používateľ" + title: "API" + key: "API kľúč" + generate: "Generovať" + regenerate: "Obnov" + revoke: "Zrušiť" + confirm_regen: "Ste si istý, že chcete nahradiť tento API kľúč novým?" + confirm_revoke: "Ste si istý, že chcete obnoviť tento kľúč?" + info_html: "Váš API kľúč Vám umožní vytváranie a aktualizovanie tém prostredníctvom volaní JSON." + all_users: "Všetci používatelia" + note_html: "Držte tento kľúč v tajnosti, všetci užívatelia ktorí ho vlastnia môžu vytvárať ľubovoľné príspevky pod ľubovoľným užívateľským menom. " + plugins: + title: "Pluginy" + installed: "Nainštalované pluginy" + name: "Meno" + none_installed: "Nemáte nainštalované žiadne pluginy." + version: "Verzia" + enabled: "Povolené?" + is_enabled: "A" + not_enabled: "N" + change_settings: "Zmeniť nastavenia" + change_settings_short: "Nastavenia" + howto: "Ako nainštalujem pluginy?" + backups: + title: "Zálohy" + menu: + backups: "Zálohy" + logs: "Logy" + none: "Nie je dostupná žiadna záloha." + read_only: + enable: + title: "Povoliť mód len na čítanie." + label: "Povoliť mód len na čítanie." + confirm: "Ste si istý, že chcete povoliť mód len na čítanie?" + disable: + title: "Zakázať mód len na čítanie" + label: "Zakázať mód len na čítanie" + logs: + none: "Zatiaľ žiadne logy..." + columns: + filename: "Názov súboru" + size: "Veľkosť" + upload: + label: "Upload" + title: "Nahrať zálohu do tejto inštancie" + uploading: "Upload prebieha..." + success: "'{{filename}}' bol úspešne nahratý." + error: "Počas nahrávania '{{filename}}' nastala chyba: {{message}}" + operations: + is_running: "Operácia práve prebieha..." + failed: " Zlyhalo vykonanie {{operation}} . Prosím skontrolujte logy. " + cancel: + label: "Zrušiť" + title: "Zrušiť prebiehajúcu operáciu" + confirm: "Ste si istý, že chcete zrušiť prebiehajúcu operáciu?" + backup: + label: "Záloha" + title: "Vytvoriť zálohu" + confirm: "Prajete si spustiť novú zálohu?" + without_uploads: "Áno (nezahŕňať súbory)" + download: + label: "Stiahnuť" + title: "Stiahnuť zálohu" + destroy: + title: "Odstrániť zálohu" + confirm: "Ste si istý, že chcete odstrániť túto zálohu?" + restore: + is_disabled: "Obnovenie je vypnuté na Nastaveniach stránky." + label: "Obnoviť" + title: "Obnoviť zálohu" + rollback: + label: "Vrátiť späť" + title: "Vrátiť databázu do predchádzajúceho funkčného stavu" + export_csv: + user_archive_confirm: "Ste si istý, že si chcete stiahnut svoje príspevky?" + success: "Export bol spustený, o jeho skončení budete informovaný správou." + failed: "Export zlyhal. Skontrolujte prosím logy." + rate_limit_error: "Príspevky možu byť stiahnuté len raz za deň. Skúste opäť zajtra." + button_text: "Export" + button_title: + user: "Exportovať celý zoznam používateľov v CSV formáte." + staff_action: "Exportovať celý log akcií redakcie v CSV formáte." + screened_email: "Exportovať celý zobrazený zoznam emailov v CSV formáte." + screened_ip: "Exportovať celý zobrazený zoznam IP adries v CSV formáte." + screened_url: "Exportovať celý zobrazený zoznam URL adries v CSV formáte." + export_json: + button_text: "Export" + invite: + button_text: "Poslať pozvánky" + button_title: "Poslať pozvánky" + customize: + title: "Upraviť" + long_title: "Úpravy webu" + css: "CSS" + header: "Hlavička" + top: "Vrch" + footer: "Päta" + embedded_css: "Vnorené CSS" + head_tag: + text: "" + title: "HTML, ktoré bude vložené pred tag" + body_tag: + text: "" + title: "HTML, ktoré bude vložené pred tag" + override_default: "Nevkladať štandardné štýly" + enabled: "Povolené?" + preview: "náhľad" + undo_preview: "zmazať náhľad" + rescue_preview: "predvolený štýl" + explain_preview: "Nastaviť na stránke vlastné štýly" + explain_undo_preview: "Vrátiť sa k akruálnym vlastným štýlom" + explain_rescue_preview: "Nastavit na stránke štandardné štýly" + save: "Uložiť" + new: "Nový" + new_style: "Nový štýl" + import: "Import" + import_title: "Vyberte súbor alebo vložte text" + delete: "Odstrániť" + delete_confirm: "Zmazať túto úpravu?" + about: "Upraviť CSS štýly a HTML hlavičky na stránke. Začnite pridaním úpravy." + color: "Farba" + opacity: "Nepriesvitnosť" + copy: "Kopírovať" + email_templates: + title: "Emailové šablóny" + subject: "Predmet" + multiple_subjects: "Táto emailova šablóna obsahuje viac predmetov" + body: "Telo" + none_selected: "Vyberte šablénu emailu pre začatie úpravy." + revert: "Vrátiť zmeny" + revert_confirm: "Ste si istý, že chcete vrátiť vykonané zmeny späť?" + css_html: + title: "CSS/HTML" + long_title: "Úpravy CSS a HTML" + colors: + title: "Farby" + long_title: "Farebné schémy" + about: "Upravte farby použité na stránke bez použitia CSS. Začnite pridaním schémy." + new_name: "Nová farebná schéma" + copy_name_prefix: "Kópia" + delete_confirm: "Zmazať túto farebnú schému?" + undo: "späť" + undo_title: "Zrušiť zmeny farby a vrátiť sa k predchádzajucej uloženej verzii. " + revert: "vrátiť zmeny" + revert_title: "Nastaviť východziu farebnú schému Discourse. " + primary: + name: 'primárny' + description: 'Väčšina textov, ikony, a okraje.' + secondary: + name: 'sekundárny' + description: 'Hlavná farba pozadia a farba textu niektorých ovládacích prvkov.' + tertiary: + name: 'terciárny' + description: 'Odkazy, nejaké tlačidlá, upozornenia a zvýrazňovacie farby.' + quaternary: + name: "štvrťročne" + description: "Navigačné odkazy." + header_background: + name: "pozadie hlavičky" + description: "Farba pozadia hlavičky stránky." + header_primary: + name: "hlavné záhlavie" + description: "Texty a ikony v záhlaví stránky." + highlight: + name: 'zvýraznenie' + description: 'Farba pozadia zvýrazneného prvku na stránke, napríklad príspevku alebo témy.' + danger: + name: 'nebezpečenstvo' + description: 'Zvýrazňovacia farba pre akcie ako napríklad mazanie príspevkov a tém.' + success: + name: 'úspech' + description: 'Použitá pre úspešne vykonané akcie.' + love: + name: 'obľúbené' + description: "Farba tlačidla \"Páči sa\"" + email: + title: "Email" + settings: "Nastavenia" + templates: "Šablóny" + preview_digest: "Súhrn" + sending_test: "Odosielam testovací email..." + error: "CHYBA - %{server_error}" + test_error: "Pri posielaní testovacieho emailu nastala chyba. Prosím preverte Vaše emailové nastavenia, overte si, že váš hostiteľ neblokuje emailové spojenia a skúste znova." + sent: "Odoslané" + skipped: "Preskočené" + received: "Obdržané" + rejected: "Zamietnuté" + sent_at: "Odoslané" + time: "Čas" + user: "Používateľ" + email_type: "Typ emailu" + to_address: "Adresát" + test_email_address: "testovacia emailová adresa" + send_test: "Odoslať testovací email" + sent_test: "odoslané!" + delivery_method: "Spôsob doručenia" + preview_digest_desc: "Náhľad obsahu súhrnných emailov zaslaných neaktívnym užívateľom." + refresh: "Obnoviť" + format: "Formát" + html: "html" + text: "text" + last_seen_user: "Posledný videný užívateľ" + reply_key: "Tlačidlo odpovedať" + skipped_reason: "Preskočiť zdôvodnenie" + incoming_emails: + from_address: "Od" + to_addresses: "Komu" + cc_addresses: "Kópia" + subject: "Predmet" + error: "Chyba" + none: "Nenájdené žiadne ďalšie emaily." + modal: + error: "Chyba" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Predmet..." + error_placeholder: "Chyba" + logs: + none: "Nenašli sa žiadne logy." + filters: + title: "Filter" + user_placeholder: "používateľské meno" + address_placeholder: "meno@príklad.com" + type_placeholder: "súhrn, registácia..." + reply_key_placeholder: "tlačidlo odpovedať" + skipped_reason_placeholder: "dôvod" + logs: + title: "Logy" + action: "Akcia" + created_at: "Vytvorené" + last_match_at: "Posledný zodpovedajúci" + match_count: "Zodpovedá" + ip_address: "IP" + topic_id: "ID témy" + post_id: "ID príspevku" + category_id: "ID kategórie" + delete: 'Odstrániť' + edit: 'Upraviť' + save: 'Uložiť' + screened_actions: + block: "blokovať" + do_nothing: "nerob nič" + staff_actions: + title: "Akcie personálu" + instructions: "Vyberte uťívateľské meno a akcie na filtrovanie zoznamu. Kliknite na profilovú fotku pre navigáciu na užívateľské stránky." + clear_filters: "Ukázať všetko" + staff_user: "Člen redakcie" + target_user: "Cieľový používateľ" + subject: "Predmet" + when: "Kedy" + context: "Kontext" + details: "Detaily" + previous_value: "Predchádzajúci" + new_value: "Nový" + diff: "Rozdiel" + show: "Zobraziť" + modal_title: "Detaily" + no_previous: "Neexistuje predchádzajúca hodnota" + deleted: "Žiadna nová hodnota. Záznam bol vymazaný." + actions: + delete_user: "odstrániť používateľa" + change_trust_level: "zmeniť stupeň dôvery" + change_username: "zmeniť používateľské meno" + change_site_setting: "zmeniť nastavenia webu" + change_site_customization: "zmeniť úpravy webu" + delete_site_customization: "zmazať úpravy webu" + change_site_text: "zmeniť text stránky" + suspend_user: "zruš práva užívateľovi" + unsuspend_user: "obnov práva užívateľovi" + grant_badge: "udeliť odznak" + revoke_badge: "odobrať odznak" + check_email: "skontrolovať email" + delete_topic: "odstrániť tému" + delete_post: "odstrániť príspevok" + impersonate: "privlastniť" + anonymize_user: "anonymizovať používateľa" + roll_up: "zbaliť IP bloky" + change_category_settings: "zmeniť nastavenia kategórie" + delete_category: "odstrániť kategóriu" + create_category: "vytvoriť kategóriu" + block_user: "blokovať používateľa" + unblock_user: "odblokovať používateľa" + grant_admin: "udeliť admin" + revoke_admin: "odobrať admin" + grant_moderation: "udeliť moderovanie" + revoke_moderation: "odvolať moderovanie" + screened_emails: + title: "Kontrolované emaily" + description: "Keď niekto skúsi vytvoriť nový účet, nasledujúce emailove adresy budú preverené a registrácia bude zablokovaná, alebo bude vykonaná nejaka iná akcia. " + email: "Emailové adresy" + actions: + allow: "Povoliť" + screened_urls: + title: "Kontrolované URL adresy" + description: "URL adresy v tomto zozname boli použité v príspevkoch užívateľov, ktorí boli identifikovaní ako spameri." + url: "URL" + domain: "Doména" + screened_ips: + title: "Kontrolované IP adresy" + description: 'IP adresy pod dohľadom. Použi "Povoľ" pre povolenie IP adries.' + delete_confirm: "Ste si istý, že chcete zrušiť pravidlo pre %{ip_address}?" + roll_up_confirm: "Ste si istý, že chcete zosumarizovať bežne kontrolované IP do podsietí?" + rolled_up_some_subnets: "Zakázané IP adresy boli úspešne zosumarizované do podsietí: %{subnets}." + rolled_up_no_subnet: "Nebolo čo zbaliť." + actions: + block: "Blokovať" + do_nothing: "Povoliť" + allow_admin: "Povoliť admin" + form: + label: "Nový:" + ip_address: "IP adresy" + add: "Pridať" + filter: "Hľadať" + roll_up: + text: "Zbaliť" + title: "Vytvorí novú podsieť zakázaných záznamov pokiaľ existuje aspoň 'min_ban_entries_for_roll_up' záznamov" + logster: + title: "Chybové Logy" + impersonate: + title: "Privlastniť" + help: "Použite tento nástroj na privlastnenie si užívateľského účtu na účely debugovania. Po skončení sa budete musieť odhlásiť." + not_found: "Tento používateľ sa nenašiel." + invalid: "Ľutujeme, nesmiete si privlatniť tohto užívateľa." + users: + title: 'Používatelia' + create: 'Pridať admin používateľa' + last_emailed: "Posledný odemailovaný" + not_found: "Prepáčte, toto užívateľské meno sa nenachádza v našom systéme." + id_not_found: "Prepáčte, toto užívateľské id sa nenachádza v našom systéme." + active: "Aktívny" + show_emails: "Ukázať Emaily" + nav: + new: "Nový" + active: "Aktívny" + pending: "Čakajúca" + staff: 'Zamestnanci' + suspended: 'Odobrate práva' + blocked: 'Zablokovaný' + suspect: 'Podozrivý' + approved: "Schválený?" + approved_selected: + one: "schváliť užívateľa" + few: "schváliť ({{count}}) užívateľov " + other: "schváliť ({{count}}) užívateľov " + reject_selected: + one: "zamietnuť užívateľa" + few: "zamietnuť ({{count}}) užívateľov " + other: "zamietnuť ({{count}}) užívateľov " + titles: + active: 'Aktívni používatelia' + new: 'Noví používatelia' + pending: 'Užívatelia čakajúci na kontrolu' + newuser: 'Užívatelia na Stupni dôvery 0 (Noví užívatelia)' + basic: 'Užívatelia na Stupni dôvery 1 (Bežný užívateľ)' + member: 'Užívatelia na Stupni dôvery 2 (Člen)' + regular: 'Užívatelia na Stupni dôvery 3 (Stály člen)' + leader: 'Užívatelia na Stupni dôvery 4 (Vodca)' + staff: "Zamestnanci" + admins: 'Admin používatelia' + moderators: 'Moderátori' + blocked: 'Zablokovaní užívatelia' + suspended: 'Užívatelia s odobratými právami' + suspect: 'Podozriví užívatelia' + reject_successful: + one: "Úspešne zamietnutý užívateľ" + few: "Úspešne zamietnutí %{count} užívatelia" + other: "Úspešne zamietnutých %{count} užívateľov" + reject_failures: + one: "Nepodarilo sa zamietnuť 1 užívateľa" + few: "Nepodarilo sa zamietnuť %{count} užívateľov" + other: "Nepodarilo sa zamietnuť %{count} užívateľov" + not_verified: "Neoverený" + check_email: + title: "Odhaliť emailovú adresu tohto používateľa" + text: "Zobraziť" + user: + suspend_failed: "Niečo sa pokazilo pri odoberaní práv tomuto užívateľovi {{error}}" + unsuspend_failed: "Niečo sa pokazilo pri obnovovaní práv tomuto užívateľovi {{error}}" + suspend_duration: "Ako dlho budú užívateľovi odobrate práva?" + suspend_duration_units: "(dni)" + suspend_reason_label: "Prečo mu odoberáte práva? Tento text sa zobrazí každému na stránke profilu užívateľa a bude zobrazený užívateľovi pri pokuse o prihlásenie. Buďte strucný." + suspend_reason: "Dôvod" + suspended_by: "Práva odobraté" + delete_all_posts: "Zmazať všetky príspevky" + delete_all_posts_confirm: "Chystáte sa zmazať %{posts} príspevkov a %{topics} tém. Ste si istý?" + suspend: "Odobrať" + unsuspend: "Obnoviť" + suspended: "Odobrate práva?" + moderator: "Moderátor?" + admin: "Admin?" + blocked: "Blokovaný?" + staged: "Dočasný?" + show_admin_profile: "Admin" + edit_title: "Upraviť názov" + save_title: "Uložiť názov" + refresh_browsers: "Vynútiť refresh browsera." + refresh_browsers_message: "Správa odoslaná všetkým klientom!" + show_public_profile: "Ukázať verejný profil" + impersonate: 'Privlastniť' + ip_lookup: "Vyhľadávanie IP" + log_out: "Odhlásiť sa" + logged_out: "Užívateľ bol odhlásený na všetkých zariadeniach" + revoke_admin: 'Odobrať admin' + grant_admin: 'Udeliť admin' + revoke_moderation: 'Odobrať moderovanie' + grant_moderation: 'Udeliť moderovanie' + unblock: 'Odblokovať' + block: 'Blokovať' + reputation: Reputácia + permissions: Práva + activity: Aktivita + like_count: '"Páči sa" Rozdané / Prijaté' + last_100_days: 'za posledných 100 dní' + private_topics_count: Súkromné témy + posts_read_count: Prečítané príspevky + post_count: Vytvorené príspevky + topics_entered: Zobrazených tém + flags_given_count: Rozdané označenia + flags_received_count: Prijaté označenia + warnings_received_count: Prijaté varovania + flags_given_received_count: 'Rozdané a prijaté označenia' + approve: 'Schváliť' + approved_by: "schválený" + approve_success: "Uťívateľ schválený a bol zaslaný email s aktivačnými inštrukciami" + approve_bulk_success: "Úspech! Všetci vybraní uťívateľia boli schválení a oboznáamení." + time_read: "Doba Čítania" + anonymize: "Anonymizovať používateľa" + anonymize_confirm: "Ste si istý že chcete zmeniť tento účet na anonymný? Zmeni to užívateľské meno, email a zmažú sa všetky informácie z profilu. " + anonymize_yes: "Áno, zmeň tento účet na anonymný" + anonymize_failed: "Nastala chyba pri anonymizovaní účtu." + delete: "Odstrániť používateľa" + delete_forbidden_because_staff: "Správcovia a moderátori nemôžu byť vymazaní." + delete_posts_forbidden_because_staff: "Nedá sa zmazať príspevky správcov a moderátorov." + delete_forbidden: + one: "Užívatelia nemôžu byť vymazaní ak majú príspevky. Najprv zmažte príspevky až potom užívateľa. (Príspevky staršie ako %{count} deň nemožno zmazať)" + few: "Užívatelia nemôžu byť vymazaní ak majú príspevky. Najprv zmažte príspevky až potom užívateľa. (Príspevky staršie ako %{count} dni nemožno zmazať)" + other: "Užívatelia nemôžu byť vymazaní ak majú príspevky. Najprv zmažte príspevky až potom užívateľa. (Príspevky staršie ako %{count} dní nemožno zmazať)" + cant_delete_all_posts: + one: "Nepodarilo sa zmazať všetky príspevky. Niektoré príspevky sú staršie ako %{count} deň. (Nastavenie delete_user_max_post_age )" + few: "Nepodarilo sa zmazať všetky príspevky. Niektoré príspevky sú staršie ako %{count} dni. (Nastavenie delete_user_max_post_age )" + other: "Nepodarilo sa zmazať všetky príspevky. Niektoré príspevky sú staršie ako %{count} dní. (Nastavenie delete_user_max_post_age )" + cant_delete_all_too_many_posts: + one: "Nedá sa zmazať všetky píspevky, pretože užívateľ má viac ako 1 príspevok. (delete_all_posts_max)" + few: "Nedá sa zmazať všetky píspevky, pretože užívateľ má viac ako %{count} príspevky. (delete_all_posts_max)" + other: "Nedá sa zmazať všetky píspevky, pretože užívateľ má viac ako %{count} príspevkov. (delete_all_posts_max)" + delete_confirm: "Ste si ISTÝ, že chcete zmazať tohoto užívateľa? Už sa to nedá obnoviť!" + delete_and_block: "Zazať a zablokovať tento email a IP adresu" + delete_dont_block: "Iba vymazať" + deleted: "Používateľ bol vymazaný." + delete_failed: "Počas vymazávania používateľa nastala chyba. Pred vymazaním používateľa sa uistite, že všetky jeho príspevky sú zmazané." + send_activation_email: "Poslať aktivačný email." + activation_email_sent: "Aktivačný emial bol odoslaný." + send_activation_email_failed: "Počas odosielania ďalšieho aktivačného emailu nastala chyba. %{error}" + activate: "Aktivovať účet" + activate_failed: "Počas aktivácie používateľa nastala chyba." + deactivate_account: "Deaktivovať účet" + deactivate_failed: "Počas deaktivácie používateľa nastala chyba." + unblock_failed: 'Nastala chyba pri odblokovaní užívateľa.' + block_failed: 'Nastala chyba pri zablokovaní užívateľa.' + block_confirm: 'Ste si istý tým, že chcete zablokovať tohoto používateľa? Nebude môcť vytvárať žiadne nové témy alebo príspevky.' + block_accept: 'Ano, zablokovať používateľa' + deactivate_explanation: "Deaktivovaý užívateľ musí znovu overiť svoj email" + suspended_explanation: "Suspendovaní užívatelia sa nemôžu prihlasovať." + block_explanation: "Zablokovaní uťívatelia nemôžu zakladať témy ani pridávať príspevky." + stage_explanation: "Dočasný používateľ môže prispievať emailom iba do vybraných tém." + trust_level_change_failed: "Nastala chyba pri zmene úrovne dôveryhodnosti užívateľa." + suspend_modal_title: "Zruš práva užívateľovi" + trust_level_2_users: "Užívatelia na 2 Stupni dôvery" + trust_level_3_requirements: "Požiadavky pre 3 stupeň" + trust_level_locked_tip: "stupeň dôvery je zamknutý, systém užívateľovi stupeň nezvýši ani nezníži " + trust_level_unlocked_tip: "stupeň dôvery je odomknutý, systém môže užívateľovi stupeň zvýšiť alebo znížiť" + lock_trust_level: "Zamknúť stupeň dôvery" + unlock_trust_level: "Odomknúť stupeň dôvery" + tl3_requirements: + title: "Požiadavky pre stupeň dôvery 3" + table_title: "Za posledných %{time_period} dní:" + value_heading: "Hodnota" + requirement_heading: "Požiadavka" + visits: "Návštev" + days: "dní" + topics_replied_to: "Témy na ktoré odpovedal" + topics_viewed: "Zobrazených tém" + topics_viewed_all_time: "Videné témy (za celú dobu)" + posts_read: "Prečítané príspevky" + posts_read_all_time: "Prečítaných príspevkov (za celú dobu)" + flagged_posts: "Označené príspevky" + flagged_by_users: "Užívatelia, ktorí označili" + likes_given: "Rozdaných 'páči sa mi'" + likes_received: "Obdržaných 'páči sa mi'" + likes_received_days: "Obdržaných 'páči sa mi' na jednotlivé dni" + likes_received_users: "Obdržaných 'páči sa mi' na jednotlivých užívateľov" + qualifies: "Spĺňa požiadavky pre stupeň dôvery 3" + does_not_qualify: "Nespĺňa požiadavky pre stupeň dôvery 3" + will_be_promoted: "Bude čoskoro povýšený" + will_be_demoted: "Čoskoro bude degradovaný" + on_grace_period: "V súčastnosti je v povyšovacej skúšobnej dobe, nebude degradovaný." + locked_will_not_be_promoted: "Stupeň dôvery je zamknutý. Nikdy nebude povýšený." + locked_will_not_be_demoted: "Stupeň dôvery je zamknutý. Nikdy nebude degradovaný" + sso: + title: "Jednotné prihlásenie" + external_id: "Externé ID" + external_username: "Používateľské meno" + external_name: "Meno" + external_email: "Email" + external_avatar_url: "URL profilovej fotky" + user_fields: + title: "Užívateľské polia" + help: "Pridaj polia, ktoré môžu užívatelia vyplniť" + create: "Vytvor užívateľske pole" + untitled: "Bez názvu" + name: "Názov poľa" + type: "Typ poľa" + description: "Popis poľa" + save: "Uložiť" + edit: "Upraviť" + delete: "Odstrániť" + cancel: "Zrušiť" + delete_confirm: "Ste si istý, že chcete zmazať toto užívateľské pole?" + options: "Možnosti" + required: + title: "Požadované pri registrácii?" + enabled: "povinné" + disabled: "nepovinné" + editable: + title: "Upravovateľné po registrácii?" + enabled: "upravovateľné " + disabled: "neupravovateľné " + show_on_profile: + title: "Ukázať na verejnom profile?" + enabled: "zobrazené na profile" + disabled: "nezobrazené na profile" + field_types: + text: 'Textové pole' + confirm: 'Potvrdenie' + dropdown: "Zoznam" + site_text: + description: "Môžete prispôsobiť hociktorý text na Vašom fóre. Prosím začnite hľadaním nižšie:" + search: "Hľadajte text, ktorý chcete upraviť" + title: 'Textový obsah' + edit: 'uprav' + revert: "Vrátiť zmeny" + revert_confirm: "Ste si istý, že chcete vrátiť vykonané zmeny späť?" + go_back: "Návrat na vyhľadávanie" + recommended: "Odporúčame prispôsobenie nasledujúceho textu podľa vašich potrieb:" + show_overriden: 'Ukázať iba zmenené' + site_settings: + show_overriden: 'Ukázať iba zmenené' + title: 'Nastavenia' + reset: 'zrušiť' + none: 'žiadne' + no_results: "Žiadne výsledky" + clear_filter: "Vyčistiť" + add_url: "pridaj URL" + add_host: "pridať hostiteľa" + categories: + all_results: 'Všetky' + required: 'Povinné' + basic: 'Základné nastavenia' + users: 'Používatelia' + posting: 'Prispievam' + email: 'Email' + files: 'Súbory' + trust: 'Stupne dôvery' + security: 'Bezpečnosť' + onebox: "Onebox" + seo: 'SEO' + spam: 'Spam' + rate_limits: 'Limity a obmedzenia' + developer: 'Vývojár' + embedding: "Vkladám" + legal: "Právne záležitosti" + uncategorized: 'Ostatné' + backups: "Zálohy" + login: "Prihlásenie" + plugins: "Pluginy" + user_preferences: "Užívateľské Nastavenia" + badges: + title: Odznaky + new_badge: Nový odznak + new: Nový + name: Meno + badge: Odznak + display_name: Zobrazované meno + description: Popis + badge_type: Typ odznaku + badge_grouping: Skupina + badge_groupings: + modal_title: Zoskupovanie odznakov + granted_by: Pridelené užívateľom + granted_at: Pridelené na + reason_help: (Odkaze na príspevok, alebo tému) + save: Uložiť + delete: Odstrániť + delete_confirm: Ste si istý, že chcete zmazať tento odznak? + revoke: Zrušiť + reason: Dôvod + expand: Rozbaliť … + revoke_confirm: Ste si istý, že chcete obnoviť tento odznak? + edit_badges: Upraviť odznaky + grant_badge: Prideliť odznaky + granted_badges: Pridelené odznaky + grant: Prideliť + no_user_badges: "%{name} nebol pridelený žiaden odznak." + no_badges: Nie sú žiadne odznaky, ktoré môžu byť pridelené. + none_selected: "Vyberte odznak, aby ste mohli začať" + allow_title: Povoliť použitie odznaku namiesto názvu + multiple_grant: Môže byť pridelené viacnásobne + listable: Zobraziť odznak na stránke verejných odznakov + enabled: Povoliť odznak + icon: Ikona + image: Obrázok + icon_help: "Použi buď font z triedy Awesome, alebo URL na obrázok" + query: Požiadavka na Odznak (SQL) + target_posts: Požiadavka cieli príspevky + auto_revoke: Spúšťať stornovaciu požiadavku denne + show_posts: Zobraziť príspevok o pridelení odznaku na stránke odznakov + trigger: Spúšťač + trigger_type: + none: "Obnovovať denne" + post_action: "Keď užívateľ zareaguje na príspevok" + post_revision: "Keď užívateľ vytvorí príspevok" + trust_level_change: "Keď užívateľ zmení stupeň dôvery" + user_change: "Keď je užívateľ vytvorený, alebo upravený" + preview: + link_text: "Prezerať pridelené odznaky" + plan_text: "Náhľad na plán požiadaviek" + modal_title: "Požiadavka na Odznak Prezeranie" + sql_error_header: "Nastala chyba s požiadavkou." + error_help: "Pozrite si nasledujäce odkazy pre pomoc s dopytovacími odznakmi." + bad_count_warning: + header: "UPOZORNENIE!" + text: "Chýbajú ukážky práv. Toto sa stane, ak dotaz na odznak vráti ID používateľa alebo príspevku, ktorý neexistuje. Toto môže zapríčiniť neskoršie neočakávané výsledky - prosíme znovu overte Váš dotaz." + no_grant_count: "Žiadne odznaky na pridelenie." + grant_count: + one: "1 odznak na pridelenie" + few: "%{count} odznaky na pridelenie" + other: "%{count} odznakov na pridelenie" + sample: "Vzor:" + grant: + with: %{username} + with_post: %{username} za príspevok v %{link} + with_post_time: %{username} za príspevok v %{link} v čase %{time} + with_time: %{username} v čase %{time} + emoji: + title: "Emoji" + help: "Pridaj nové emoji, ktoré bude dostupné pre všetkých (TIP: môžete pretiahnuť viac súborov naraz)" + add: "Pridaj nové Emoji" + name: "Meno" + image: "Obrázok" + delete_confirm: "Ste si istý, že chcete zmazať: %{name}: emoji?" + embedding: + get_started: "Pokiaľ chcete vložiť Discourse na inú stránku, začnite pridaním jej hostiteľa." + confirm_delete: "Ste si istý, že chcete zmazať tohoto hostiteľa?" + sample: "Použite nasledovný HTML kód vo Vašej stránke pre vytvorenie vloženej témy Discourse. Nahraďte REPLACE_ME kanonickou URL adresou stránky, do ktorej to vkladáte." + title: "Vkladám" + host: "Povolení hostitelia" + edit: "uprav" + category: "Prispievať do kategórií" + add_host: "Pridať hostiteľa" + settings: "Nastavenia vkladania" + feed_settings: "Nastavenie zdrojov" + feed_description: "Zadaním RSS/ATOM kanálu Vašich stránok zlepší schopnosť Discourse vladať Váš obsah." + crawling_settings: "Nastavenia vyhľadávača" + crawling_description: "Ak Discourse vytvorí tému pre Váš príspevok a neexistuje žiadny RSS/ATOM kanál tak sa pokúsime získať Váš obsah z HTML. Získanie obsahu môže byt niekedy výzva a preto poskytujeme možnosť špecifikovať CSS pravidlá na uľahčenie získania obsahu." + embed_by_username: "Užívateľské meno pre vytváranie tém" + embed_post_limit: "Maximálny počet vložených príspevkov" + embed_username_key_from_feed: "Kľúč na získanie užívateľského mena discourse zo zdroja" + embed_truncate: "Skrátiť vložené príspevky" + embed_whitelist_selector: "CSS selector pre elementy ktoré je možné vkladať" + embed_blacklist_selector: "CSS selector pre elementy ktoré nie je možné vkladať" + feed_polling_enabled: "importovať príspevky cez RSS/ATOM" + feed_polling_url: "URL adresa zdroja RSS/ATOM na preskúmanie" + save: "Uložiť Nastavenia vkladania" + permalink: + title: "Trvalé odkazy" + url: "URL" + topic_id: "IT témy" + topic_title: "Témy" + post_id: "ID príspevku" + post_title: "Príspevok" + category_id: "ID kategórie" + category_title: "Kategória" + external_url: "Externá URL" + delete_confirm: Ste si istý, že chcete zmazať tento trvalý odkaz? + form: + label: "Nový:" + add: "Pridať" + filter: "Hľadať (URL alebo externá URL)" + lightbox: + download: "stiahnuť" + search_help: + title: 'Pomoc pri vyhľadávaní' + keyboard_shortcuts_help: + title: 'Klávesové skratky' + jump_to: + title: 'Preskočiť na' + home: 'g, h Domov' + latest: 'g, l Najnovšie' + new: 'g, n Nové' + unread: 'g, u Neprečítané' + categories: 'g, c Kategórie' + top: 'g, t Hore' + bookmarks: 'g, b Záložky' + profile: 'g, p Profil' + messages: 'g, m Správy' + navigation: + title: 'Navigácia' + jump: '# Choď na príspevok #' + back: 'u Späť' + up_down: 'k/j Presuň označené ↑ ↓' + open: 'o or EnterOtvoriť zvolenú tému' + next_prev: 'shift+j/shift+k Nasledujúca/predchádzajúca sekcia' + application: + title: 'Aplikácia' + create: 'c Vytvoriť novú tému' + notifications: 'n Otvor upozornenia' + hamburger_menu: '= Otvoriť hamburger menu' + user_profile_menu: 'p Otvor užívateľské menu' + show_incoming_updated_topics: '. Zobraz aktualizované témy' + search: '/ Hľadať' + help: '? Pomoc s klávesovými skratkami' + dismiss_new_posts: 'x, r Zahodiť Nové/Príspevky' + dismiss_topics: 'x, t Zahodiť témy' + log_out: 'shift+z shift+z Odhlásiť sa' + actions: + title: 'Akcie' + bookmark_topic: 'f Zmeniť tému záložky' + pin_unpin_topic: 'shift+p Pripnúť/Odopnúť tému' + share_topic: 'shift+s Zdielať tému' + share_post: 's Zdielať príspevok' + reply_as_new_topic: 't Odpoveď ako súvisiaca téma' + reply_topic: 'shift+r Odpovedať na tému' + reply_post: 'r Odpovedať na príspevok' + quote_post: 'q Citovať príspevok' + like: 'l Označiť príspevok "Páči sa"' + flag: '! Označiť príspevok ' + bookmark: 'b Pridať príspevok do záložiek' + edit: 'e Editovat príspevok' + delete: 'd Zmazať príspevok' + mark_muted: 'm, m Umlčať tému' + mark_regular: 'm, r Obyčajná (preddefinovaná) téma' + mark_tracking: 'm, w Sledovať tému' + mark_watching: 'm, w Sledovať tému' + badges: + earned_n_times: + one: "Získal tento odkaz 1 krát" + few: "Získal tento odkaz %{count} krát" + other: "Získal tento odkaz %{count} krát" + title: Odznaky + badge_count: + one: "1 Odznak" + few: "%{count} Odznaky" + other: "%{count} Odznakov" + more_badges: + one: "+1 Viac" + few: "+%{count} Viac" + other: "+%{count} Viac" + granted: + one: "1 povolené" + few: "%{count} povolené" + other: "%{count} povolených" + select_badge_for_title: Vyberte odznak, ktorý chcete použiť ako Váš titul + none: "" + badge_grouping: + getting_started: + name: Začíname + community: + name: Komunita + trust_level: + name: Stupeň dôvery + other: + name: Ostatné + posting: + name: Prispievam + google_search: | +

    Vyhľadávať pomocou Google

    +

    +

    +

    diff --git a/config/locales/client.sq.yml b/config/locales/client.sq.yml index caed2c2f490..2f97296d433 100644 --- a/config/locales/client.sq.yml +++ b/config/locales/client.sq.yml @@ -100,6 +100,8 @@ sq: x_years: one: "1 year later" other: "%{count} years later" + previous_month: 'Muaji i Kaluar' + next_month: 'Muaji Tjetër' share: topic: 'shpërnda një lidhje tek kjo temë' post: 'postim #%{postNumber}' @@ -108,8 +110,39 @@ sq: facebook: 'shpërndaje këtë lidhje ne Facebook' google+: 'shpërndaje këtë lidhje në Google+' email: 'dërgo këtë lidhje me email' + action_codes: + split_topic: "ndaje këtë teme %{when}" + invited_user: "ftuar %{who} %{when}" + removed_user: "hequr %{who} %{when}" + autoclosed: + enabled: 'mbyllur %{when}' + disabled: 'hapur %{when}' + closed: + enabled: 'mbyllur %{when}' + disabled: 'hapur %{when}' + archived: + enabled: 'arkivuar %{when}' + disabled: 'ç''arkivuar %{when}' + pinned: + enabled: 'mbërthyer %{when}' + disabled: 'ç''mbërthyer %{when}' + pinned_globally: + enabled: 'mbërthyer globalisht %{when}' + disabled: 'ç''mbërthyer %{when}' + visible: + enabled: 'listuar %{when}' + disabled: 'ç''listuar %{when}' topic_admin_menu: "topic admin actions" emails_are_disabled: "All outgoing email has been globally disabled by an administrator. No email notifications of any kind will be sent." + s3: + regions: + us_east_1: "US East (N. Virginia)" + us_west_1: "US West (N. California)" + us_west_2: "US West (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "EU (Ireland)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asia Pacific (Singapore)" edit: 'redakto titullin dhe kategorinë e kësaj teme' not_implemented: "Kjo veçori nuk është implementuar akoma, na vjen keq!" no_value: "Jo" @@ -123,6 +156,7 @@ sq: admin_title: "Admin" flags_title: "Flags" show_more: "trego më shumë" + show_help: "opsione" links: "Lidhjet" links_lowercase: one: "lidhje" @@ -141,6 +175,8 @@ sq: more: "Më shumë" less: "Më pak" never: "asnjëher" + every_30_minutes: "çdo 30 minuta" + every_hour: "çdo orë" daily: "ditore" weekly: "javore" every_two_weeks: "çdo dy javë" @@ -152,6 +188,7 @@ sq: other: "{{count}} karakterë" suggested_topics: title: "Temat e Sugjeruara" + pm_title: "Mesazhet e Sygjeruara" about: simple_title: "Rreth" title: "Rreth %{title}" @@ -199,6 +236,7 @@ sq: saved: "U ruajt!" upload: "Ngarko" uploading: "Duke nga ngarkuar..." + uploading_filename: "Duke Ngarkuar {{filename}}..." uploaded: "U ngarkua!" enable: "Aktivizo" disable: "Disaktivizo" @@ -206,6 +244,7 @@ sq: revert: "Rikthe" failed: "Dështojë" switch_to_anon: "Mënyrë Anonime" + switch_from_anon: "Dalja e Anonimit" banner: close: "Hiq këtë reklamë." edit: "Edit this banner >>" @@ -228,7 +267,7 @@ sq: one: "This topic has 1 post awaiting approval" other: "This topic has {{count}} posts awaiting approval" confirm: "Ruaj ndryshimet" - delete_prompt: "Are you sure you want to delete %{username}? This will remove all of their posts and block their email and ip address." + delete_prompt: "A jeni te sigurtë që doni të fshini %{username}? Ky veprim do të fshijë çdo shkrim të tyre dhe do bllokojë e-mailin dhe IP e tyre." approval: title: "Post Needs Approval" description: "We've received your new post but it needs to be approved by a moderator before it will appear. Please be patient." @@ -271,19 +310,47 @@ sq: one: "1 user" other: "%{count} users" groups: + empty: + posts: "Nuk ka postim nga anëtarët e këtij grupi." + members: "Nuk ka asnjë anëtar në këtë grup." + mentions: "Nuk ka përmendje në këtë grup." + messages: "Nuk ka mesazhe për këtë grup." + topics: "Nuk ka asnjë temë nga anëtarët e këtij grupi." + add: "Shto" + selector_placeholder: "Shto anëtarë" + owner: "pronar" visible: "Grupi është i dukshëm për të gjithë përdoruesit" title: one: "grupë" other: "grupet" members: "Anëtarë" + topics: "Tema" posts: "Postime" + mentions: "Përmendje" + messages: "Nesazhe" alias_levels: - title: "Kush mund ta përdori këtë grup si një nofkë?" + title: "Kush mund ti bëjë mesazh dhe @permendje këtij grupi?" nobody: "Asnjëri" only_admins: "Vetëm adminët" mods_and_admins: "Vetëm moderatorët dhe Adminët" members_mods_and_admins: "Vetëm anëtarët e grupit, moderatorët dhe administratorët" everyone: "Të gjithë" + trust_levels: + title: "Niveli i besimit automatikisht shtohet për anëtarët e grupit:" + none: "Asnje" + notifications: + watching: + title: "Duke Parë" + description: "Ju do të njoftoheni në çdo postim të ri, dhe numburi i ri i përgjigjeve do të tregohet." + tracking: + title: "Ndjekje" + description: "Ju do të njoftoheni në qoftë se dikush ju pëmend me @emri ose ju përgjigjet, gjithashtu numbri i përgjigjeve do të tregohet." + regular: + title: "Normale" + description: "Ju do të njoftoheni në qoftë se dikush ju përmend me @emrin ose ju përgjigjet." + muted: + title: "Heshtur" + description: "Ju asnjëherë nuk do të njoftoheni për cdo gjë qe mund të ndodhë në këtë teme të këtij grupi." user_action_groups: '1': "Pëlqime të Dhëna" '2': "Pëlqime të marra" @@ -293,7 +360,6 @@ sq: '6': "Responses" '7': "Përmendje" '9': "Citim" - '10': "Shënuar" '11': "Redaktuar" '12': "Sent Items" '13': "Inbox" @@ -303,6 +369,15 @@ sq: all_subcategories: "të gjitha" no_subcategory: "asnjë" category: "Kategori" + category_list: "Trego listen e kateogorive" + reorder: + title: "Rendit Kategoritë" + title_long: "Ri-organizo listën e kategorive" + fix_order: "Rregullo Pozicionet" + fix_order_tooltip: "Jo të gjitha kategoritë kanë një numbë pozicioni unik, kjo mund të shkaktojë rezultate të pa vlefshme." + save: "Ruaje Renditjen" + apply_all: "Apliko" + position: "Pozicioni" posts: "Postime" topics: "Tema" latest: "Të fundit" @@ -345,21 +420,20 @@ sq: private_messages: "Mesazhet" activity_stream: "Aktiviteti" preferences: "Preferencat" + expand_profile: "Shpalos" bookmarks: "Të Preferuarat" bio: "Rreth meje" invited_by: "Të ftuar nga unë" trust_level: "Niveli Besimit" notifications: "Njoftimet" + statistics: "Statistikat" desktop_notifications: label: "Desktop Notifications" not_supported: "Notifications are not supported on this browser. Sorry." perm_default: "Turn On Notifications" perm_denied_btn: "Permission Denied" - perm_denied_expl: "You have denied permission for notifications. Use your browser to enable notifications, then click the button when done. (Desktop: The leftmost icon in the address bar. Mobile: 'Site Info'.)" disable: "Disable Notifications" - currently_enabled: "(currently enabled)" enable: "Enable Notifications" - currently_disabled: "(currently disabled)" each_browser_note: "Note: You have to change this setting on every browser you use." dismiss_notifications: "Shënoj të gjitha si të lexuara" dismiss_notifications_tooltip: "Shëno njoftimet e palexuara si të lexuara" @@ -383,7 +457,6 @@ sq: tracked_categories: "Gjurmuar" tracked_categories_instructions: "You will automatically track all new topics in these categories. A count of new posts will appear next to the topic." muted_categories: "Heshtur" - muted_categories_instructions: "You will not be notified of anything about new topics in these categories, and they will not appear on your unread tab." delete_account: "Fshi Llogarin Time" delete_account_confirm: "Are you sure you want to permanently delete your account? This action cannot be undone!" deleted_yourself: "Llogaria juaj u fshi me sukses." @@ -401,8 +474,6 @@ sq: warnings_received: "paralajmërimet" messages: all: "Të gjithë" - mine: "Mine" - unread: "Palexuar" change_password: success: "(email u dërgua)" in_progress: "(duke dërguar emailin)" @@ -447,10 +518,6 @@ sq: ok: "We will email you to confirm" invalid: "Please enter a valid email address" authenticated: "Your email has been authenticated by {{provider}}" - frequency: - zero: "We'll email you immediately if you haven't read the thing we're emailing you about." - one: "We'll only email you if we haven't seen you in the last minute." - other: "We'll only email you if we haven't seen you in the last {{count}} minutes." name: title: "Emri" instructions: "Emri i Plotë (fakultativ)" @@ -488,6 +555,7 @@ sq: email_settings: "Email" email_digests: title: "When I don't visit here, send an email digest of what's new:" + every_30_minutes: "çdo 30 minuta" daily: "ditore" every_three_days: "çdo 3 ditë" weekly: "javore" @@ -505,11 +573,12 @@ sq: auto_track_options: never: "asnjëherë" immediately: "menjëherë" + after_30_seconds: "pas 30 sekonda" + after_1_minute: "pas 1 minute" invited: search: "shkruaj për të kërkuar ftesat..." title: "Ftesa" user: "Anëtarët e Ftuar" - truncated: "Shfaq {{count}} ftesat e para." redeemed: "Ridërgo ftesat" redeemed_tab: "Redeemed" redeemed_at: "Redeemed" @@ -540,6 +609,8 @@ sq: same_as_email: "Your password is the same as your email." ok: "Fjalëkalimi është i pranueshëm." instructions: "Të paktën %{count} karaktere." + summary: + stats: "Statistikat" associated_accounts: "Logins" ip_address: title: "Adresa IP e Fundit" @@ -565,6 +636,7 @@ sq: server: "Gabim në Server" forbidden: "Ndalohet Hyrja" unknown: "Gabim" + not_found: "Faqja nuk u gjet" desc: network: "Ju lutemi, kontrolloni lidhjen me Internetin." network_fixed: "Duket sikur u ktheve." @@ -580,7 +652,6 @@ sq: logout: "Ju jeni shkëputur!" refresh: "Rifresko" read_only_mode: - enabled: "Read-only mode is enabled. You can continue to browse the site but interactions may not work." login_disabled: "Login is disabled while the site is in read only mode." learn_more: "mëso më shumë..." year: 'vit' @@ -598,10 +669,10 @@ sq: replies_lowercase: one: përgjigje other: përgjigje + signup_cta: + hide_forever: "jo faleminderit" summary: enabled_description: "You're viewing a summary of this topic: the most interesting posts as determined by the community." - description: "Janë {{count}} përgjigje." - description_time: "There are {{count}} replies with an estimated read time of {{readingTime}} minutes." enable: 'Përmbidhë këtë Diskutim' disable: 'Shfaq të gjithë Postimet' deleted_filter: @@ -655,6 +726,7 @@ sq: admin_not_allowed_from_ip_address: "You can't log in as admin from that IP address." resend_activation_email: "Click here to send the activation email again." sent_activation_email_again: "We sent another activation email to you at {{currentEmail}}. It might take a few minutes for it to arrive; be sure to check your spam folder." + to_continue: "Ju lutem, Identifikohuni" google: title: "me Google" message: "Authenticating with Google (make sure pop up blockers are not enabled)" @@ -677,8 +749,13 @@ sq: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + more_emoji: "më shumë..." + options: "Opsione" add_warning: "This is an official warning." posting_not_on_topic: "Which topic do you want to reply to?" saving_draft_tip: "duke e ruajtur..." @@ -707,7 +784,7 @@ sq: edit_reason_placeholder: "pse jeni duke e redaktuar?" show_edit_reason: "(arsye redaktimit)" view_new_post: "Shikoni postimin tuaj te ri." - saving: "Duke ruajtur..." + saving: "Duke e ruajtur" saved: "U Ruajt!" saved_draft: "Post draft in progress. Select to resume." uploading: "Duke nga ngarkuar..." @@ -734,10 +811,10 @@ sq: heading_title: "Heading" heading_text: "Heading" hr_title: "Horizontal Rule" - undo_title: "Rikthe" - redo_title: "Ribëj" help: "Markdown Editing Help" toggler: "hide or show the composer panel" + modal_ok: "OK" + modal_cancel: "Anulo" admin_options_title: "Optional staff settings for this topic" auto_close: label: "Auto-close topic time:" @@ -756,7 +833,6 @@ sq: mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -766,6 +842,9 @@ sq: moved_post: "

    {{username}} moved {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Earned '{{description}}'

    " + alt: + quoted: "Cituar nga" + posted: "Postim nga" popup: mentioned: '{{username}} mentioned you in "{{topic}}" - {{site_title}}' quoted: '{{username}} quoted you in "{{topic}}" - {{site_title}}' @@ -779,14 +858,13 @@ sq: from_my_computer: "Nga çdo paisje" from_the_web: "Nga web" remote_tip: "lidhje tek imazhi" - remote_tip_with_attachments: "lidhje për tek imazhi ose skedari ({{authorized_extensions}})" local_tip: "select images from your device" - local_tip_with_attachments: "select images or files from your device ({{authorized_extensions}})" hint: "(you can also drag & drop into the editor to upload them)" uploading: "Duke ngarkaur" select_file: "Select File" image_link: "link your image will point to" search: + sort_by: "Rendit sipas" title: "search topics, posts, users, or categories" no_results: "Nuk i gjet asnjë rezultat." no_more_results: "No more results found." @@ -798,6 +876,7 @@ sq: category: "Kërko tek kategoria \"{{category}}\"" topic: "Kërko tek kjo temë" private_messages: "Search messages" + new_item: "e re" go_back: 'kthehu mbrapa' not_logged_in_user: 'user page with summary of current activity and preferences' current_user: 'go to your user page' @@ -805,10 +884,6 @@ sq: bulk: reset_read: "Reseto Leximet" delete: "Delete Topics" - dismiss_posts: "Dismiss Posts" - dismiss_posts_tooltip: "Clear unread counts on these topics but continue to show them on my unread list when new posts are made" - dismiss_topics: "Dismiss Topics" - dismiss_topics_tooltip: "Stop showing these topics in my unread list when new posts are made" dismiss_new: "Dismiss New" toggle: "toggle bulk selection of topics" actions: "Bulk Actions" @@ -831,9 +906,6 @@ sq: category: "Nuk ka {{category}} tema." top: "Nuk ka tema të populluara." search: "There are no search results." - educate: - new: '

    Your new topics appear here.

    By default, topics are considered new and will show a new indicator if they were created in the last 2 days.

    You can change this in your preferences.

    ' - unread: '

    Your unread topics appear here.

    By default, topics are considered unread and will show unread counts 1 if you:

    • Created the topic
    • Replied to the topic
    • Read the topic for more than 4 minutes

    Or if you have explicitly set the topic to Tracked or Watched via the notification control at the bottom of each topic.

    You can change this in your preferences.

    ' bottom: latest: "Nuk ka më tema së fundmi." hot: "Nuk ka më tema të populluara." @@ -939,15 +1011,16 @@ sq: title: "Tracking" description: "A count of new replies will be shown for this topic. You will be notified if someone mentions your @name or replies to you. " regular: + title: "Normal" description: "You will be notified if someone mentions your @name or replies to you." regular_pm: + title: "Normal" description: "You will be notified if someone mentions your @name or replies to you." muted_pm: title: "Muted" description: "You will never be notified of anything about this message." muted: title: "Muted" - description: "You will never be notified of anything about this topic, and it will not appear on your unread tab." actions: recover: "Un-Delete Topic" delete: "Fshi Diskutimin" @@ -988,25 +1061,14 @@ sq: unpin: "Remove this topic from the top of the {{categoryLink}} category." unpin_until: "Remove this topic from the top of the {{categoryLink}} category or wait until %{until}." pin_note: "Users can unpin the topic individually for themselves." - already_pinned: - zero: "There are no topics pinned in {{categoryLink}}." - one: "Topics currently pinned in {{categoryLink}}: 1." - other: "Topics currently pinned in {{categoryLink}}: {{count}}." pin_globally: "Make this topic appear at the top of all topic lists until" confirm_pin_globally: "You already have {{count}} globally pinned topics. Too many pinned topics may be a burden for new and anonymous users. Are you sure you want to pin another topic globally?" unpin_globally: "Remove this topic from the top of all topic lists." unpin_globally_until: "Remove this topic from the top of all topic lists or wait until %{until}." global_pin_note: "Users can unpin the topic individually for themselves." - already_pinned_globally: - zero: "There are no topics pinned globally." - one: "Topics currently pinned globally: 1." - other: "Topics currently pinned globally: {{count}}." make_banner: "Make this topic into a banner that appears at the top of all pages." remove_banner: "Remove the banner that appears at the top of all pages." banner_note: "Users can dismiss the banner by closing it. Only one topic can be bannered at any given time." - already_banner: - zero: "There is no banner topic." - one: "There is currently a banner topic." inviting: "Inviting..." automatically_add_to_groups_optional: "This invite also includes access to these groups: (optional, admin only)" automatically_add_to_groups_required: "This invite also includes access to these groups: (Required, admin only)" @@ -1106,10 +1168,6 @@ sq: has_likes_title: one: "1 person liked this post" other: "{{count}} people liked this post" - has_likes_title_you: - zero: "ju pëlqeni këtë post" - one: "ju dhe 1 person tjetër pëlqeni këtë post" - other: "you and {{count}} other people liked this post" errors: create: "Na vjen keq, por ndodhi një gabim gjatë hapjes së temës. Provojeni përsëri." edit: "Na vjen keq, ndodhi një gabim gjatë redaktimit të temës. Provojeni përsëri." @@ -1127,8 +1185,6 @@ sq: no_value: "Jo, mbaji" yes_value: "Po, braktise" via_email: "this post arrived via email" - wiki: - about: "this post is a wiki; basic users can edit it" archetypes: save: 'Ruaj Opsionet' controls: @@ -1176,18 +1232,6 @@ sq: bookmark: "Undo bookmark" like: "Anulo pëlqimin" vote: "Rikthe votën" - people: - off_topic: "{{icons}} flagged this as off-topic" - spam: "{{icons}} flagged this as spam" - spam_with_url: "{{icons}} flagged this as spam" - inappropriate: "{{icons}} flagged this as inappropriate" - notify_moderators: "{{icons}} notified moderators" - notify_moderators_with_url: "{{icons}} notified moderators" - notify_user: "{{icons}} sent a message" - notify_user_with_url: "{{icons}} sent a message" - bookmark: "{{icons}} bookmarked this" - like: "{{icons}} liked this" - vote: "{{icons}} voted for this" by_you: off_topic: "You flagged this as off-topic" spam: "You flagged this as spam" @@ -1247,10 +1291,6 @@ sq: vote: one: "1 person voted for this post" other: "{{count}} people voted for this post" - edits: - one: 1 redaktim - other: "{{count}} edits" - zero: no edits delete: confirm: one: "Are you sure you want to delete that post?" @@ -1328,19 +1368,15 @@ sq: notifications: watching: title: "Watching" - description: "You will automatically watch all new topics in these categories. You will be notified of all new posts and topics, and a count of new replies will appear for these topics." tracking: title: "Tracking" - description: "You will automatically track all new topics in these categories. A count of new replies will appear for these topics." regular: - title: "Regular" + title: "Normal" description: "You will be notified if someone mentions your @name or replies to you." muted: title: "Muted" - description: "You will not be notified of anything about new topics in these categories, and they will not appear on your unread tab." flagging: title: 'Faleminderit për ndihmën që i jepni këtij komuniteti!' - private_reminder: 'flags are private, only visible to staff' action: 'Flag Post' take_action: "Take Action" notify_action: 'Mesazh' @@ -1388,7 +1424,6 @@ sq: help: "This topic is unpinned for you; it will display in regular order" pinned_globally: title: "Pinned Globally" - help: "This topic is pinned globally; it will display at the top of all lists" pinned: title: "Pinned" help: "This topic is pinned for you; it will display at the top of its category" @@ -1431,10 +1466,6 @@ sq: with_topics: "%{filter} topics" with_category: "%{filter} %{category} topics" latest: - title: - zero: "Latest" - one: "Të fundit (1)" - other: "Të fundit ({{count}})" help: "temat me postime të fundit" hot: title: "Kryesoret" @@ -1450,23 +1481,11 @@ sq: title_in: "Category - {{categoryName}}" help: "all topics grouped by category" unread: - title: - zero: "Palexuar" - one: "Palexuar (1)" - other: "Palexuar ({{count}})" + title: "Palexuar " help: "topics you are currently watching or tracking with unread posts" - lower_title_with_count: - one: "1 pa lexuar" - other: "{{count}} unread" new: - lower_title_with_count: - one: "1 e re" - other: "{{count}} të ri" lower_title: "e re" - title: - zero: "Tema të Reja" - one: "Tema të Reja (1)" - other: "Të Reja ({{count}})" + title: "I Ri" help: "topics created in the last few days" posted: title: "Postimet e Mia" @@ -1475,10 +1494,6 @@ sq: title: "Bookmarks" help: "topics you have bookmarked" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" - other: "{{categoryName}} ({{count}})" help: "latest topics in the {{categoryName}} category" top: title: "Kryesoret" @@ -1720,11 +1735,9 @@ sq: is_disabled: "Restore is disabled in the site settings." label: "Rikthe" title: "Restore the backup" - confirm: "Are your sure you want to restore this backup?" rollback: label: "Rollback" title: "Rollback the database to previous working state" - confirm: "Are your sure you want to rollback the database to the previous working state?" export_csv: user_archive_confirm: "Are you sure you want to download your posts?" success: "Export initiated, you will be notified via message when the process is complete." @@ -1818,13 +1831,9 @@ sq: love: name: 'love' description: "The like button's color." - wiki: - name: 'wiki' - description: "Base color used for the background of wiki posts." email: - title: "Email" settings: "Rregullimet" - all: "Të gjithë" + preview_digest: "Preview Digest" sending_test: "Sending test Email..." error: "ERROR - %{server_error}" test_error: "There was a problem sending the test email. Please double-check your mail settings, verify that your host is not blocking mail connections, and try again." @@ -1839,7 +1848,6 @@ sq: send_test: "Send Test Email" sent_test: "u dërgua!" delivery_method: "Delivery Method" - preview_digest: "Preview Digest" refresh: "Rifresko" format: "Formati" html: "html" @@ -1971,9 +1979,6 @@ sq: pending: 'Users Pending Review' newuser: 'Users at Trust Level 0 (New User)' basic: 'Users at Trust Level 1 (Basic User)' - regular: 'Users at Trust Level 2 (Member)' - leader: 'Users at Trust Level 3 (Regular)' - elder: 'Users at Trust Level 4 (Leader)' staff: "Stafi" admins: 'Admin Users' moderators: 'Moderators' @@ -2083,7 +2088,6 @@ sq: unlock_trust_level: "Unlock Trust Level" tl3_requirements: title: "Requirements for Trust Level 3" - table_title: "Në 100 ditët e fundit:" value_heading: "Vlera" requirement_heading: "Requirement" visits: "Vizita" @@ -2144,8 +2148,8 @@ sq: confirm: 'Confirmation' dropdown: "Dropdown" site_text: - none: "Choose a type of content to begin editing." title: 'Text Content' + edit: 'redakto' site_settings: show_overriden: 'Only show overridden' title: 'Rregullimet' @@ -2232,10 +2236,6 @@ sq: bad_count_warning: header: "KUJDES!" text: "There are missing grant samples. This happens when the badge query returns user IDs or post IDs that do not exist. This may cause unexpected results later on - please double-check your query." - grant_count: - zero: "No badges to be assigned." - one: "1 badge to be assigned." - other: "%{count} badges to be assigned." sample: "Shëmbull:" grant: with: %{username} @@ -2249,6 +2249,8 @@ sq: name: "Name" image: "Imazh" delete_confirm: "Are you sure you want to delete the :%{name}: emoji?" + embedding: + edit: "redakto" permalink: title: "Permalinks" url: "URL" @@ -2317,8 +2319,6 @@ sq: mark_watching: 'm, w Watch topic' badges: title: Badges - allow_title: "can be used as a title" - multiple_grant: "can be awarded multiple times" badge_count: one: "1 Badge" other: "%{count} Badges" @@ -2341,85 +2341,3 @@ sq: name: Other posting: name: Posting - badge: - editor: - name: Editor - description: First post edit - basic_user: - name: Basic - description: Granted all essential community functions - member: - name: Member - description: Granted invitations - regular: - name: Regular - description: Granted recategorize, rename, followed links and lounge - leader: - name: Leader - description: Granted global edit, pin, close, archive, split and merge - welcome: - name: Welcome - description: Received a like - autobiographer: - name: Autobiographer - description: Filled user profile information - anniversary: - name: Përvjetori - description: Active member for a year, posted at least once - nice_post: - name: Nice Post - description: Received 10 likes on a post. This badge can be granted multiple times - good_post: - name: Good Post - description: Received 25 likes on a post. This badge can be granted multiple times - great_post: - name: Great Post - description: Received 50 likes on a post. This badge can be granted multiple times - nice_topic: - name: Nice Topic - description: Received 10 likes on a topic. This badge can be granted multiple times - good_topic: - name: Good Topic - description: Received 25 likes on a topic. This badge can be granted multiple times - great_topic: - name: Great Topic - description: Received 50 likes on a topic. This badge can be granted multiple times - nice_share: - name: Nice Share - description: Shared a post with 25 unique visitors - good_share: - name: Good Share - description: Shared a post with 300 unique visitors - great_share: - name: Great Share - description: Shared a post with 1000 unique visitors - first_like: - name: Pëlqimi i Parë - description: Liked a post - first_flag: - name: First Flag - description: Flagged a post - promoter: - name: Promoter - description: Invited a user - campaigner: - name: Campaigner - description: Invited 3 basic users (trust level 1) - champion: - name: Champion - description: Invited 5 members (trust level 2) - first_share: - name: First Share - description: Shared a post - first_link: - name: First Link - description: Added an internal link to another topic - first_quote: - name: Citimi i Parë - description: Quoted a user - read_guidelines: - name: Read Guidelines - description: Read the community guidelines - reader: - name: Lexues - description: Read every post in a topic with more than 100 posts diff --git a/config/locales/client.sv.yml b/config/locales/client.sv.yml index b2608010cec..f91320f6982 100644 --- a/config/locales/client.sv.yml +++ b/config/locales/client.sv.yml @@ -8,6 +8,9 @@ sv: js: number: + format: + separator: "." + delimiter: "," human: storage_units: format: '%n %u' @@ -19,12 +22,17 @@ sv: kb: KB mb: MB tb: TB + short: + thousands: "{{number}}k" + millions: "{{number}}M" dates: time: "h:mm a" long_no_year: "MMM D h:mm a" long_no_year_no_time: "MMM D" + full_no_year_no_time: "MMMM Do" long_with_year: "D MMM, YYYY h:mm a" long_with_year_no_time: "D MMM, YYYY" + full_with_year_no_time: "MMMM Do, YYYY" long_date_with_year: "D MMM, 'YY LT" long_date_without_year: "D MMM, LT" long_date_with_year_without_time: "D MMM, 'YY" @@ -75,10 +83,10 @@ sv: medium_with_ago: x_minutes: one: "1 min sedan" - other: "%{count} min sedan" + other: "%{count} minuter sedan" x_hours: one: "1 timme sedan" - other: "%{count} tim sedan" + other: "%{count} timmar sedan" x_days: one: "1 dag sedan" other: "%{count} dagar sedan" @@ -101,6 +109,7 @@ sv: google+: 'dela denna länk på Google+' email: 'skicka denna länk i ett email' action_codes: + split_topic: "Dela den här tråden %{when}" autoclosed: enabled: 'stängdes %{when}' disabled: 'öppnades %{when}' @@ -112,7 +121,7 @@ sv: disabled: 'avarkiverades %{when}' pinned: enabled: 'klistrades %{when}' - topic_admin_menu: "ämne admin åtgärder" + topic_admin_menu: "ämne administratörs åtgärder" emails_are_disabled: "All utgående e-post har blivit globalt deaktiverad av en administratör. Inga e-postnotifikationer av något slag kommer att skickas ut." edit: 'redigera titel och kategori för denna tråd' not_implemented: "Denna funktion har inte implementerats än, vi beklagar!" @@ -127,6 +136,7 @@ sv: admin_title: "Admin" flags_title: "Flaggningar" show_more: "visa mer" + show_help: "alternativ" links: "Länkar" links_lowercase: one: "länk" @@ -203,6 +213,7 @@ sv: saved: "Sparat!" upload: "Ladda upp" uploading: "Laddar upp..." + uploading_filename: "Laddar upp {{filename}}..." uploaded: "Uppladdad!" enable: "Aktivera" disable: "Avaktivera" @@ -232,7 +243,6 @@ sv: one: "Detta ämne har 1 ämne som inväntar godkännande" other: "Detta ämne har {{count}} inlägg som inväntar godkännande" confirm: "Spara ändringar" - delete_prompt: "Är du säker på att du vill ta bort %{username}? Detta kommer ta bort all deras poster och blockera deras epostadresser samt IP-adresser." approval: title: "Inlägget behöver godkännande" description: "Vi har mottagit ditt nya inlägg men det behöver bli godkänt av en moderator innan det kan visas. Ha tålamod." @@ -275,6 +285,9 @@ sv: one: "1 användare" other: "%{count} användare" groups: + add: "Lägg till" + selector_placeholder: "Lägg till medlemmar" + owner: "ägare" visible: "Gruppen är synlig för alla användare" title: one: "grupp" @@ -282,7 +295,6 @@ sv: members: "Medlemmar" posts: "Inlägg" alias_levels: - title: "Vem kan använda denna grupp som ett alias?" nobody: "Ingen" only_admins: "Bara administratörer" mods_and_admins: "Bara moderatorer och administratörer" @@ -290,6 +302,11 @@ sv: everyone: "Alla" trust_levels: none: "Inga" + notifications: + regular: + title: "Normal" + muted: + title: "Tystad" user_action_groups: '1': "Gillningar givna" '2': "Gillningar mottagna" @@ -299,7 +316,6 @@ sv: '6': "Svar" '7': "Omnämnanden" '9': "Citat" - '10': "Stjärnmärkt" '11': "Redigeringar" '12': "Skickade föremål" '13': "Inkorg" @@ -309,6 +325,7 @@ sv: all_subcategories: "alla" no_subcategory: "ingen" category: "Kategori" + category_list: "Visa kategori-lista" reorder: title: "Sortera kategorier" title_long: "Sortera litan av katergorier" @@ -343,6 +360,8 @@ sv: topics_entered: "besökta ämnen" post_count: "# inlägg" confirm_delete_other_accounts: "Är du säker på att du vill ta bort dessa här konton?" + user_fields: + none: "(välj ett alternativ)" user: said: "{{username}}:" profile: "Profil" @@ -354,11 +373,14 @@ sv: private_messages: "Meddelanden" activity_stream: "Aktivitet" preferences: "Inställningar" + expand_profile: "Expandera" bookmarks: "Bokmärken" bio: "Om mig" invited_by: "Inbjuden Av" trust_level: "Förtroendenivå" notifications: "Notifieringar" + desktop_notifications: + perm_denied_btn: "Behörighet saknas" dismiss_notifications: "Markera alla som lästa" dismiss_notifications_tooltip: "Markera alla olästa aviseringar som lästa" disable_jump_reply: "Hoppa inte till mitt inlägg efter att jag har svarat" @@ -381,7 +403,6 @@ sv: tracked_categories: "Bevakade" tracked_categories_instructions: "Du kommer automatiskt att följa alla nya ämnen i dessa kategorier. Antalet nya inlägg visas bredvid ämnet." muted_categories: "Tystad" - muted_categories_instructions: "Du kommer inte att få notifieringar om nya ämnen inom dessa kategorier, och de kommer inte att visas under din \"oläst\"-flik." delete_account: "Radera mitt konto" delete_account_confirm: "Är du säker på att du vill ta bort ditt konto permanent? Denna åtgärd kan inte ångras!" deleted_yourself: "Ditt konto har tagits bort." @@ -399,8 +420,13 @@ sv: warnings_received: "varningar" messages: all: "Alla" - mine: "Mina" - unread: "Olästa" + inbox: "Inkorg" + sent: "Skickat" + archive: "Arkiv" + groups: "Mina Grupper" + bulk_select: "Välj meddelanden" + move_to_inbox: "Flytta till inkorg" + select_all: "Markera alla" change_password: success: "(e-brev skickat)" in_progress: "(skickar e-brev)" @@ -444,8 +470,8 @@ sv: ok: "Vi skickar e-post till dig för bekräftelse" invalid: "Vänligen ange en giltig e-postadress" authenticated: "Din e-postadress har blivit verifierad av {{provider}}" + frequency_immediately: "Vi kommer att skicka e-post till dig omedelbart om du inte har läst det som vi skickar e-post till dig om." frequency: - zero: "Vi kommer att skicka e-post till dig omedelbart om du inte har läst det som vi skickar e-post till dig om." one: "Vi skickar bara e-post om du inte synts till den senaste minuten." other: "Vi skickar bara e-post om du inte synts till de senaste {{count}} minuterna." name: @@ -500,15 +526,23 @@ sv: after_1_day: "skapade de senaste dagarna" after_2_days: "skapade de senaste 2 dagarna" after_1_week: "skapade den senaste veckan" + after_2_weeks: "skapade de senaste 2 veckorna" auto_track_topics: "Följ automatiskt nya ämnen jag går in i" auto_track_options: never: "aldrig" immediately: "genast" + after_30_seconds: "efter 30 sekunder" + after_1_minute: "efter 1 minut" + after_2_minutes: "efter 2 minuter" + after_3_minutes: "efter 3 minuter" + after_4_minutes: "efter 4 minuter" + after_5_minutes: "efter 5 minuter" + after_10_minutes: "efter 10 minuter" invited: search: "sök efter inbjudningar..." title: "Inbjudningar" user: "Inbjuden Användare" - truncated: "Visar de första {{count}} inbjudningarna." + sent: "skickat" redeemed: "Inlösta Inbjudnignar" redeemed_at: "Inlöst" pending: "Avvaktande Inbjudningar" @@ -577,7 +611,6 @@ sv: logout: "Du loggades ut." refresh: "Uppdatera" read_only_mode: - enabled: "Skrivskyddat läge är aktiverat. Du kan fortsätta visa sidan men interaktioner kanske inte fungerar." login_disabled: "Det går inte att logga in medan siten är i skrivskyddat läge." learn_more: "lär dig mer..." year: 'år' @@ -595,10 +628,10 @@ sv: replies_lowercase: one: svar other: svar + signup_cta: + hide_forever: "Nej tack" summary: enabled_description: "Sammanfattning över de inlägg som användarna tycker är mest intressanta." - description: "Det finns {{count}} svar." - description_time: "Det finns {{count}} svar med en uppskattad lästid på {{readingTime}} minuter." enable: 'Sammanfatta detta ämne' disable: 'Visa alla inlägg' deleted_filter: @@ -651,6 +684,7 @@ sv: admin_not_allowed_from_ip_address: "Du kan inte logga in som admin från den IP-adressen." resend_activation_email: "Klicka här för att skicka aktiveringsmailet igen." sent_activation_email_again: "Vi har skickat ännu ett aktiveringsmail till dig via {{currentEmail}}. Det kan ta ett par minuter för det att komma fram; var noga med att kolla din skräppost." + to_continue: "Var vänligen och logga in" google: title: "med Google" message: "Autentiserar med Google (kolla så att pop up-blockare inte är aktiverade)" @@ -673,8 +707,12 @@ sv: google: "Google" twitter: "Twitter" emoji_one: "Emoji Ett" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + more_emoji: "mer..." add_warning: "Det här är en officiell varning" posting_not_on_topic: "Vilket ämne vill du svara på?" saving_draft_tip: "sparar…" @@ -703,7 +741,7 @@ sv: edit_reason_placeholder: "varför redigerar du?" show_edit_reason: "(lägg till anledningar för redigering)" view_new_post: "Visa ditt nya inlägg." - saving: "Sparar..." + saving: "sparar" saved: "Sparat!" saved_draft: "Utkast för inlägg. Välj för att fortsätta." uploading: "Laddar upp..." @@ -718,6 +756,7 @@ sv: link_description: "skriv en länkbeskrivning här" link_dialog_title: "Infoga Hyperlänk" link_optional_text: "valfri titel" + link_placeholder: "http://example.com \"valfri text\"" quote_title: "Citat" quote_text: "Citat" code_title: "Förformaterad text" @@ -730,10 +769,10 @@ sv: heading_title: "Rubrik" heading_text: "Rubrik" hr_title: "Horisontell linje" - undo_title: "Ångra" - redo_title: "Återställ" help: "Markdown Redigeringshjälp" toggler: "Dölj eller visa composer-panelen" + modal_ok: "OK" + modal_cancel: "Avbryt" admin_options_title: "Valfria personalinställningar för detta ämne" auto_close: label: "Stäng automatiskt ämnet efter:" @@ -752,7 +791,6 @@ sv: mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -762,6 +800,13 @@ sv: moved_post: "

    {{username}} flyttade {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    Fötjänade '{{description}}'

    " + alt: + posted: "Postat av" + liked: "Gillade ditt inlägg" + private_message: "Privat meddelande från" + invitee_accepted: "Inbjudan accepterades av" + moved_post: "Ditt inlägg blev flyttad av" + linked: "Länk till ditt inlägg" popup: mentioned: '{{username}} nämnde dig i "{{topic}}" - {{site_title}}' quoted: '{{username}} citerade dig i "{{topic}}" - {{site_title}}' @@ -775,14 +820,20 @@ sv: from_my_computer: "Från min enhet" from_the_web: "Från webben" remote_tip: "länk till bild" - remote_tip_with_attachments: "länk till bild eller fil ({{authorized_extensions}})" + remote_tip_with_attachments: "länk till bild eller fil {{authorized_extensions}}" + local_tip: "välj bilder från din enhet" hint: "(du kan också dra & släppa in i redigeraren för att ladda upp dem)" uploading: "Laddar upp bild" select_file: "Välj fil" image_link: "länk dit din bild ska peka" search: + sort_by: "Sortera efter" + latest_post: "Senaste inlägg" + select_all: "Markera Alla" title: "sök efter ämnen, inlägg, användare, eller kategorier" no_results: "Inga resultat hittades." + no_more_results: "Inga fler resultat hittades." + search_help: Sökhjälp searching: "Söker ..." post_format: "#{{post_number}} av {{username}}" context: @@ -790,6 +841,7 @@ sv: category: "Sök i kategorin \"{{category}}\"" topic: "Sök i denna diskussion" private_messages: "Sök meddelanden" + new_item: "ny" go_back: 'gå tillbaka' not_logged_in_user: 'användarsida med sammanställning av aktuell aktivitet och inställningar' current_user: 'gå till din användarsida' @@ -797,10 +849,6 @@ sv: bulk: reset_read: "Återställ Lästa" delete: "Ta bort diskussioner" - dismiss_posts: "Avfärda inlägg" - dismiss_posts_tooltip: "Nollställ räknaren för olästa i dessa diskussioner men fortsätt visa mig dem på min olästalista när nya inlägg har gjorts. " - dismiss_topics: "Avfärda Diskussioner" - dismiss_topics_tooltip: "Sluta visa mig dessa diskussioner i min olästalista när nya inlägg har gjorts" dismiss_new: "Avfärda Nya" toggle: "toggla val av multipla ämnen" actions: "Massändringar" @@ -823,9 +871,6 @@ sv: category: "Det finns inga ämnen i {{category}}." top: "Det finns inga toppämnen." search: "Inga sökresultat hittades." - educate: - new: '

    Dina nya ämnen hamnar här.

    Som standard är ämnen sedda som nya och kommer att visa en ny indikator om de skapats de senaste 2 dagarna.

    Du kan ändra detta i dina inställningar.

    ' - unread: '

    Dina olästa ämnen hamnar här

    Som standard är ämnen sedda som olästa och kommer att visa antal olästa 1 om du:

    • Skapade ämnet
    • Svarade på ämnet
    • Läst ämnet längre än 4 minuter

    Eller om du explicit har satt ämnet till Följd eller Sedd via notifieringspanelen längst ned i varje ämne.

    Du kan ändra detta i dina inställningar.

    ' bottom: latest: "Det finns inga fler senaste ämnen." hot: "Det finns inga fler heta ämnen." @@ -931,15 +976,16 @@ sv: title: "Följer" description: "En räknare över antal nya svar visas för detta ämne. Du notifieras om någon nämner ditt @namn eller svarar dig." regular: + title: "Normal" description: "Du kommer att få en notifiering om någon nämner ditt @namn eller svarar dig." regular_pm: + title: "Normal" description: "Du kommer att notifieras om någon nämner ditt @namn eller svarar dig." muted_pm: title: "tystade" description: "Du kommer aldrig bli notifierad om något gällande detta meddelande." muted: title: "Dämpad" - description: "Du kommer aldrig meddelas om detta ämne alls, och den kommer inte visas i din \"oläst\"-flik." actions: recover: "Återställ ämne" delete: "Radera ämne" @@ -978,23 +1024,12 @@ sv: confirm_pin: "Du har redan {{count}} klistrade ämnen. För många klistrade ämnen kan vara störande för nya och anonyma användare. Är du säker på att du vill klistra ytterligare ett ämne i denna kategori?" unpin: "Ta bort detta ämne från toppen av kategorin {{categoryLink}}." pin_note: "Användare kan avklistra ämnet individuellt för sig själva." - already_pinned: - zero: "Det finns inga klistrade ämnen i {{categoryLink}}." - one: "Klistrade ämnen i {{categoryLink}} just nu: 1." - other: "Klistrade ämnen i {{categoryLink}} just nu: {{count}}." confirm_pin_globally: "Du har redan {{count}} globalt klistrade ämnen. För många klistrade ämnen kan vara störande för nya och anonyma användare. Är du säker på att du vill klistra ytterligare ett ämne globalt?" unpin_globally: "Ta bort detta ämne från toppen av alla ämneslistor." global_pin_note: "Användare kan avklistra ämnet individuellt för sig själva." - already_pinned_globally: - zero: "Det finns inga globalt klistrade ämnen." - one: "Globalt klistrade ämnen just nu: 1." - other: "Globalt klistrade ämnen just nu: {{count}}." make_banner: "Gör detta ämne till en banner som dyker upp i toppen av alla sidor." remove_banner: "Ta bort bannern som dyker upp i toppen av alla sidor." banner_note: "Användare kan avfärda bannern genom att stänga det. Endast ett ämne kan agera banner åt gången." - already_banner: - zero: "Inget ämne är banner." - one: "Det är förnärvarande ett ämne som banner." inviting: "Bjuder in..." automatically_add_to_groups_optional: "Denna inbjudan inkluderar även tillgång till dessa grupper: (valfritt, enbart för administratörer)" automatically_add_to_groups_required: "Denna inbjudan inkluderar även tillgång till dessa grupper: (Krävs, enbart för admninistörer)" @@ -1091,10 +1126,6 @@ sv: has_likes_title: one: "1 person gillade detta inlägg" other: "{{count}} personer gillade detta inlägg" - has_likes_title_you: - zero: "Du gillade detta inlägg" - one: "du och 1 annan person gillade detta inlägg" - other: "du och {{count}} andra personer gillade detta inlägg" errors: create: "Tyvärr, det uppstod ett fel under skapandet av ditt inlägg. Var god försök igen." edit: "Tyvärr, det uppstod ett fel under ändringen av ditt inlägg. Var god försök igen." @@ -1112,8 +1143,6 @@ sv: no_value: "nej, behåll" yes_value: "Ja, överge" via_email: "det här inlägget har gjorts via epost" - wiki: - about: "det här inlägget är en wiki; vanliga användare kan redigera det" archetypes: save: 'Spara Inställningar' controls: @@ -1161,18 +1190,6 @@ sv: bookmark: "Ångra bokmärkning" like: "Ångra gillning" vote: "Ångra röstning" - people: - off_topic: "{{icons}} flaggade det här som off-topic" - spam: "{{icons}} flaggade det här som spam" - spam_with_url: "{{icons}} flaggade detta som skräp" - inappropriate: "{{icons}} flaggade det här som olämpligt" - notify_moderators: "{{icons}} notifierade moderatorer" - notify_moderators_with_url: "{{icons}} notifierade moderatorer" - notify_user: "{{icons}} skickade ett meddelande" - notify_user_with_url: "{{icons}} skickade ett meddelande" - bookmark: "{{icons}} bokmärkte detta" - like: "{{icons}} gillade detta" - vote: "{{icons}} röstade för detta" by_you: off_topic: "Du flaggade detta som off-topic" spam: "Du flaggade detta som spam" @@ -1232,10 +1249,6 @@ sv: vote: one: "1 person röstade för detta inlägg" other: "{{count}} personer röstade för detta inlägg" - edits: - one: 1 ändring - other: "{{count}} ändringar" - zero: inga ändringar delete: confirm: one: "Är du säker på att du vill radera detta inlägg?" @@ -1311,19 +1324,15 @@ sv: notifications: watching: title: "Bevakar" - description: "Du kommer automatiskt bevaka alla nya ämnen i dessa kategorier. Du notifieras om alla nya inlägg och ämnen, och en räknare över antalet nya svar visas för dessa ämnen." tracking: title: "Följer" - description: "Du kommer automatiskt att följa alla nya ämnen i dessa kategorier. Antalet olästa inlägg kommer att synas för dessa ämnen." regular: - title: "Vanlig" + title: "Normal" description: "Du notifieras om någon nämner ditt @namn eller svarar på ditt inlägg." muted: title: "Tystad" - description: "Du kommer inte att notifieras om något som rör nya ämnen i de här kategorierna, och de kommer inte att dyka upp i din olästa tabb." flagging: title: 'Tack för att du hjälper till att hålla vår gemenskap civiliserad!' - private_reminder: 'flaggor är privata, endast synliga för funktionärer' action: 'Flagga Inlägg' take_action: "Åtgärda" notify_action: 'Meddelande' @@ -1371,7 +1380,6 @@ sv: help: "Detta ämne är oklistrat för dig. Det visas i vanlig ordning" pinned_globally: title: "Klistrat Globalt" - help: "Det här ämnet är klistrat globalt; det kommer att visas högst upp i alla listor" pinned: title: "Klistrat" help: "Detta ämne är klistrat för dig. Det visas i toppen av dess kategori" @@ -1414,10 +1422,6 @@ sv: with_topics: "%{filter} ämnen" with_category: "%{filter} %{category} ämnen" latest: - title: - zero: "Senaste" - one: "Senaste (1)" - other: "Senaste ({{count}})" help: "ämnen med nya inlägg" hot: title: "Hett" @@ -1433,23 +1437,9 @@ sv: title_in: "Kategori - {{categoryName}}" help: "alla ämnen grupperade efter kategori" unread: - title: - zero: "Olästa" - one: "Olästa (1)" - other: "Olästa ({{count}})" help: "ämnen som du bevakar eller följer med olästa inlägg" - lower_title_with_count: - one: "1 oläst" - other: "{{count}} olästa" new: - lower_title_with_count: - one: "1 ny" - other: "{{count}} nya" lower_title: "ny" - title: - zero: "Nya" - one: "Nya (1)" - other: "Nya ({{count}})" help: "ämnen skapade de senaste dagarna" posted: title: "Mina Inlägg" @@ -1458,10 +1448,6 @@ sv: title: "Bokmärken" help: "Ämnen du har bokmärkt" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" - other: "{{categoryName}} ({{count}})" help: "senaste ämnena i kategorin {{categoryName}}" top: title: "Topp" @@ -1694,11 +1680,9 @@ sv: is_disabled: "Återställ är inaktiverat i sidans inställningar." label: "Återställ" title: "återställ säkerhetskopian" - confirm: "Är du säker på att du vill återställa denna säkerhetskopia?" rollback: label: "Tillbakarullning" title: "Gör rollback på databasen till ett tidigare fungerande tillstånd." - confirm: "Är du säker på att du vill göra rollback på databasen till det tidigare fungerande tillståndet?" export_csv: user_archive_confirm: "Är du säker på att du vill ladda ner dina inlägg?" success: "Export påbörjad, du får en notis via meddelande när processen är genomförd." @@ -1792,13 +1776,9 @@ sv: love: name: 'älska' description: "Gillaknappens färg." - wiki: - name: 'wiki' - description: "Huvudfärg som används som bakgrund till wikiinlägg." email: - title: "E-postloggar" settings: "Inställningar" - all: "alla" + preview_digest: "Sammandrag" sending_test: "Skickar testmail..." error: "ERROR - %{server_error}" test_error: "Det uppstod ett problem med att skicka test meddelandet. Dubbelkolla dina e-postinställningar, verifiera att din host inte blockerar e-postkopplingar, och försök igen." @@ -1813,7 +1793,6 @@ sv: send_test: "Skicka Test Mail" sent_test: "skickat!" delivery_method: "Leveransmetod" - preview_digest: "Sammandrag" refresh: "Uppdatera" format: "Format" html: "html" @@ -1839,6 +1818,7 @@ sv: ip_address: "IP" topic_id: "Ämnes-ID" post_id: "Inlägg ID" + category_id: "Kategori ID" delete: 'Radera' edit: 'Redigera' save: 'Spara' @@ -1878,6 +1858,8 @@ sv: delete_post: "ta bort inlägg" impersonate: "imitera" anonymize_user: "Anonymisera användare" + delete_category: "radera kategori" + create_category: "skapa kategori" screened_emails: title: "Kontrollerade email" description: "När någon försöker skapa ett nytt konto, kommer följande emailadresser att kontrolleras och registrationen blockeras, eller någon annan åtgärd vidtas." @@ -1940,9 +1922,6 @@ sv: pending: 'Användare under granskning' newuser: 'Användare på Förtroendenivå 0 (ny användare)' basic: 'Användare på Förtroendenivå 1 (grundnivå)' - regular: 'Användare på förtroendenivå 2 (Medlem)' - leader: 'Användare på förtroendenivå 3 (Stammis)' - elder: 'Användare på förtroendenivå 4 (ledare)' staff: "Medarbetare" admins: 'Admin-användare' moderators: 'Moderatorer' @@ -2052,7 +2031,6 @@ sv: unlock_trust_level: "Lås upp förtroendenivå" tl3_requirements: title: "Krav för Förtroendenivå 3" - table_title: "Under de senaste 100 dagarna:" value_heading: "värde" requirement_heading: "krav" visits: "besök" @@ -2109,7 +2087,6 @@ sv: text: 'Textfält' confirm: 'Bekräftelse' site_text: - none: "Välj typ av innehåll för att börja redigera." title: 'Textinnehåll' site_settings: show_overriden: 'Visa bara överskrivna' @@ -2130,6 +2107,7 @@ sv: files: 'Filer' trust: 'Förtroendenivå' security: 'Säkerhet' + onebox: "Onebox" seo: 'SEO' spam: 'Spam' rate_limits: 'Begränsningar' @@ -2185,10 +2163,6 @@ sv: link_text: "Förhandsvisa utfärdade utmärkelser" bad_count_warning: header: "VARNING!" - grant_count: - zero: "Inga utmärkelser som ska tilldelas." - one: "1 utmärkelse som ska tilldelas." - other: "%{count} utmärkelser som ska tilldelas." sample: "Exempel:" grant: with: %{username} @@ -2202,6 +2176,20 @@ sv: name: "Namn" image: "Bild" delete_confirm: "Är du säker på att du vill radera emoji-ikonen :%{name}:?" + embedding: + edit: "ändra" + permalink: + url: "URL" + topic_id: "Ämnes ID" + post_id: "Inlägg ID" + post_title: "Publicera" + category_id: "Kategori ID" + category_title: "Kategori" + external_url: "Extern URL" + form: + label: "Ny:" + add: "Lägg till" + filter: "Sök (URL eller Extern URL)" lightbox: download: "ladda ned" search_help: @@ -2217,6 +2205,8 @@ sv: categories: 'g, c Kategorier' top: 'g, t Upp till toppen' bookmarks: 'g, b Bokmärken' + profile: 'g, p Profil' + messages: 'g, m Meddelande' navigation: title: 'Navigering' jump: '# Gå till inlägg #' @@ -2225,6 +2215,7 @@ sv: open: 'ö eller Välj Öppna valt ämne' next_prev: 'shift+j/shift+k Nästa/föregående avsnitt' application: + title: 'Applikation' create: 's Skapa ett nytt ämne' notifications: 'n Öppna notifikationer' user_profile_menu: 'p Öppna användarmeny' @@ -2253,8 +2244,6 @@ sv: mark_watching: 'm, w Bevaka ämne' badges: title: Utmärkelser - allow_title: "kan användas som titel" - multiple_grant: "kan tilldelas flera gånger" badge_count: one: "1 Utmärkelse" other: "%{count} Utmärkelser" @@ -2269,81 +2258,11 @@ sv: badge_grouping: getting_started: name: Komma igång + community: + name: Community trust_level: name: Förtroendenivå other: name: Övrigt posting: name: Inlägg - badge: - basic_user: - name: Grundläggande - member: - name: Medlem - regular: - name: Vanligt - leader: - name: Ledare - welcome: - name: Välkommen - description: Fick en gilla - autobiographer: - name: Självbiograf - description: Fyllde ut sin profilinformation - anniversary: - name: Årsdag - description: Aktiv medlem ett år, har skrivit minst en gång - nice_post: - name: Bra inlägg - description: Fick 10 gilla på ett inlägg. Denna utmärkelse kan utfärdas flera gånger. - good_post: - name: Jättebra inlägg - description: Fick 25 gilla på ett inlägg. Denna utmärkelse kan utfärdas flera gånger. - great_post: - name: Fantastiskt inlägg - description: Fick 50 gilla på ett inlägg. Denna utmärkelse kan utfärdas flera gånger. - nice_topic: - name: Bra ämne - description: Fick 10 gilla på ett ämne. Denna utmärkelse kan utfärdas flera gånger. - good_topic: - name: Jättebra ämne - description: Fick 25 gilla på ett ämne. Denna utmärkelse kan utfärdas flera gånger. - great_topic: - name: Fantastiskt ämne - description: Fick 50 gilla på ett ämne. Denna utmärkelse kan utfärdas flera gånger. - nice_share: - name: Bra delning - description: Delade ett inlägg med 25 unika besökare - good_share: - name: Jättebra delning - description: Delade ett inlägg med 300 unika besökare - great_share: - name: Fantastisk delning - description: Delade ett inlägg med 1000 unika besökare - first_like: - name: Första gillning - description: Gillade ett inlägg - first_flag: - name: Första flaggning - description: Flaggade ett inlägg - promoter: - description: Bjöd in en användare - first_share: - name: Första delning - description: Delade ett inlägg - first_link: - name: Första länk - description: Länkade internt till ett annat ämne - first_quote: - name: Första citation - description: Citerade en användare - read_guidelines: - name: Läst riktlinjer - description: Läste forumets riktlinjer - reader: - name: Läsare - description: Läs varje inlägg i en diskussion med över 100 inlägg - popular_link: - name: Populär länk - hot_link: - name: Het länk diff --git a/config/locales/client.te.yml b/config/locales/client.te.yml index e9726bc6b37..6710bcdefb7 100644 --- a/config/locales/client.te.yml +++ b/config/locales/client.te.yml @@ -220,7 +220,6 @@ te: members: "సభ్యులు" posts: "టపాలు" alias_levels: - title: "ఈ గుంపును మారుపేరుతో ఎవరు వాడవచ్చు?" nobody: "ఎవరూకాదు" only_admins: "కేవలం అధికారులే" mods_and_admins: "కేవలం అధికారులు మరియు నిర్వాహకులు మాత్రమే" @@ -233,7 +232,6 @@ te: '4': "విషయాలు" '7': "ప్రస్తావనలు" '9': "కోట్ లు" - '10': "నక్షత్రపు" '11': "సవరణలు" '12': "పంపిన అంశాలు" '13': "ఇన్ బాక్స్" @@ -303,7 +301,6 @@ te: watched_categories: "ఒకకన్నేసారు" tracked_categories: "గమనించారు" muted_categories: "నిశ్శబ్దం" - muted_categories_instructions: "ఈ వర్గాలలోని ఏ కొత్త విషయాల గురించీ మీకు ప్రకటనలు రావు. ఇంకా అవి చదవని ట్యాబులో కనిపించవు." delete_account: "నా ఖాతా తొలగించు" delete_account_confirm: "నిజ్జంగా మీరు మీ ఖాతాను శాస్వతంగా తొలగించాలనుకుంటున్నారా? ఈ చర్య రద్దుచేయలేరు సుమా! " deleted_yourself: "మీ ఖాతా విజయవంతంగా తొలగించబడింది. " @@ -319,8 +316,6 @@ te: warnings_received: "హెచ్చరికలు" messages: all: "అన్నీ" - mine: "నావి" - unread: "చదవని" change_password: success: "(ఈమెయిల్ పంపిన)" in_progress: "(ఈమెయిల్ పంపుతోన్నాం)" @@ -361,10 +356,6 @@ te: ok: "ద్రువపరుచుటకు మీకు ఈమెయిల్ పంపాము" invalid: "దయచేసి చెల్లుబాటులోని ఈమెయిల్ చిరునామా రాయండి" authenticated: "మీ ఈమెయిల్ {{provider}} చేత ద్రువీకరించబడింది" - frequency: - zero: "మీకు వెంటనే ఈమెయిల్ చేసాము, మీరు ఈమెయిల్ విషయం చదవకపోతే. " - one: "గత నిమిషంలో మీరు కనిపించకపోతే మేము ఈమెయిల్ చేస్తాము" - other: "గత {{count}} నిమిషాల్లో మీరు ఇక్కడ కనిపించకపోతేనే మేము ఈమెయిల్ చేస్తాము." name: title: "పేరు" instructions: "మీ పూర్తి పేరు (ఐచ్చికం)" @@ -418,7 +409,6 @@ te: search: "ఆహ్వానాలను వెతకడానికి రాయండి ... " title: "ఆహ్వానాలు" user: "ఆహ్వానించిన సభ్యుడు" - truncated: "తొలి {{count}} ఆహ్వానాలను చూపుతున్నాము." redeemed: "మన్నించిన ఆహ్వానాలు" redeemed_at: "మన్నించిన" pending: "పెండింగులోని ఆహ్వానాలు" @@ -499,8 +489,6 @@ te: last_post: చివరి టపా summary: enabled_description: "మీరు ఈ విషయపు సారాంశము చదువుతున్నారు. ఆసక్తికర టపాలు కమ్యునిటీ ఎంచుకుంటుంది. " - description: "అక్కడ మొత్తం {{count}} జవాబులు ఉన్నాయి" - description_time: "అక్కడ మొత్తం {{count}} జవాబులు ఉన్నాయి. వీటిని చదవడానికి సుమారుగా {{readingTime}} నిమిషాలు పడ్తాయి." enable: 'ఈ విషయాన్ని సంగ్రహించు' disable: 'అన్ని టపాలూ చూపు' deleted_filter: @@ -573,7 +561,6 @@ te: twitter: "ట్విట్టరు" emoji_one: "ఇమెజి వన్" composer: - emoji: "Emoji :smile:" add_warning: "ఇది ఒక అధికారిక హెచ్చరిక" posting_not_on_topic: "ఏ విషయానికి మీరు జవాబివ్వాలనుకుంటున్నారు? " saved_draft_tip: "భద్రం" @@ -598,7 +585,6 @@ te: edit_reason_placeholder: "మీరెందుకు సవరిస్తున్నారు?" show_edit_reason: "(సవరణ కారణం రాయండి)" view_new_post: "మీ కొత్త టపా చూడండి" - saving: "భద్రమవుతోంది..." saved: "భద్రం!" saved_draft: "టపా చిత్తుప్రతి నడుస్తోంది. కొనసాగించుటకు ఎంచుకోండి." uploading: "ఎగుమతవుతోంది..." @@ -625,8 +611,6 @@ te: heading_title: "తలకట్టు" heading_text: "తలకట్టు" hr_title: "అడ్డు గీత" - undo_title: "రద్దు" - redo_title: "తిద్దు" help: "మార్క్ డైన్ సవరణ సహాయం" toggler: "దాచు లేదా చూపు కంపోజరు ఫలకం" admin_options_title: "ఈ విషయానికి ఐచ్చిక సిబ్బంది అమరికలు" @@ -645,7 +629,6 @@ te: total_flagged: "మొత్తం కేతనించిన టపాలు" quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -660,7 +643,6 @@ te: from_my_computer: "నా పరికరం నుండి" from_the_web: "జాలం నుండి" remote_tip: "బొమ్మకు లంకె" - remote_tip_with_attachments: "బొమ్మకు లేదా దస్త్రానికి లంకె ({{authorized_extensions}})" hint: "(మీరు వాటిని ఎడిటరులోకి లాగి వదిలెయ్యటు ద్వారా కూడా ఎగుమతించవచ్చు)" uploading: "ఎగుమతవుతోంది" image_link: "మీ బొమ్మ చూపే లంకె" @@ -680,10 +662,6 @@ te: bulk: reset_read: "రీలోడ్ రీసెట్" delete: "విషయాలు తొలగించు" - dismiss_posts: "టపాలు తుడువు" - dismiss_posts_tooltip: "ఈ విషయాలపే చదవని సంఖ్యను తుడువు, కానీ కొత్తగా వచ్చే టపాలను నా చదవని సంఖ్యలో చూపుటు కొనసాగించు" - dismiss_topics: "విషయాలు తుడువు" - dismiss_topics_tooltip: "కొత్త టపాలు వచ్చినా, నా చదవని జాబితాలో ఈ విషయాలు నుండి చూపుటు ఆపు. " dismiss_new: "కొత్తవి తుడువు" toggle: "విషయాల బహుళ ఎంపికలు అటుఇటుచేయి" actions: "బహుళ చర్యలు" @@ -705,9 +683,6 @@ te: bookmarks: "మీకింకా ఎట్టి పేజీక విషయాలూ లేవు." category: "ఎట్టి {{category}} విషయాలూ లేవు" top: "ఎట్టి అగ్ర విషయాలూ లేవు." - educate: - new: '

    మీ కొత్త విషయాలు ఇక్కడ వస్తాయి.

    అప్రమేయంగా 2 రోజులలోపు సృష్టించిన అన్ని విషయాలూ కొత్తగా భావించబడతాయి మరియు కొత్త ఇండికేటరు తో చూపబడతాయి.

    మీరు దీన్ని మీ అభీష్టాలులో మార్చుకోవచ్చు.

    ' - unread: '

    మీరు చదవని విషయాలు ఇక్కడ కనబడుతాయి.

    అప్రమేయంగా, విషయాలు చదవని వాటిగా పరిశీలించబడతాయి మరియు చదవని వాటి సంఖ్య మీకు చూపబడతాయి 1 మీరు:

    • విషయం సృష్టించినట్లయితే
    • విషయానికి సమాధానం ఇచ్చినట్లయితే
    • విషయం 4 నిమిషాల కంటే ఎక్కువ చదివినట్లయితే

    లేదా మీరు స్పష్టముగా విషయం అమర్చినట్లయితే ప్రతి విషయానికి క్రింది భాగంలో నియంత్రణ ప్రకటన ద్వారా గమనించబడుతుంది లేదా కనిపెడుతూ ఉంటుంది .

    మీరు ఇది మార్చగలరు మీ preferences లో.

    ' bottom: latest: "ఇంకా కొత్త విషయాలు లేవు." hot: "ఇంకా వేడివేడి విషయాలు లేవు." @@ -806,7 +781,6 @@ te: title: "నిశ్శబ్దం" muted: title: "నిశ్శబ్దం" - description: "ఈ ప్రైవేటు సందేశం నుండి మీకు అస్సలు ప్రకటనలు రావు. ఇంకా చదవని సంఖ్య కనిపించదు." actions: recover: "విషయం తొలగింపు రద్దుచేయి" delete: "విషయం తొలగించు" @@ -919,8 +893,6 @@ te: no_value: "లేదు, ఉంచండి" yes_value: "అవును. వదిలేయండి" via_email: "ఈ టపా ఈమెయిల్ ద్వారా వచ్చింది" - wiki: - about: "ఈ టపా వికీ: ప్రాథమిక సభ్యులు దీన్ని సవరించలేరు" archetypes: save: 'భద్రపరుచు ఐచ్చికాలు' controls: @@ -968,16 +940,6 @@ te: bookmark: "పేజీక రద్దు" like: "ఇష్టం రద్దు" vote: "ఓటు రద్దు" - people: - off_topic: "{{icons}} దీన్ని విషయాంతరంగా కేతనించాయి" - spam: "{{icons}} దీన్ని స్పాముగా కేతనించాయి" - spam_with_url: "{{ప్రతీకలు}} స్పామ్ లా కేతనించు" - inappropriate: "{{icons}} దీన్ని అసమంజసంగా కేతనించాయి" - notify_moderators: "{{icons}} దీన్ని నిర్వాహకుల దృష్టికి తెచ్చాయి" - notify_moderators_with_url: "{{icons}} నిర్వాహకుల దృష్టికి తెచ్చారు" - bookmark: "{{icons}} పేజీక ఉంచారు" - like: "{{icons}} ఇష్టపడ్డారు" - vote: "{{icons}} దీనికి ఓటు వేసారు" by_you: off_topic: "మీరు దీన్ని విషయాంతరంగా కేతనించారు" spam: "మీరు దీన్ని స్పాముగా కేతనించారు" @@ -1030,10 +992,6 @@ te: vote: one: "ఒకరు దీనికి ఓటు వేశారు" other: "{{count}} గురు దీనికి ఓటు వేసారు" - edits: - one: 1 సవరణ - other: "{{count}} సవరణలు" - zero: ఎట్టి సవరణలూ లేవు delete: confirm: one: "మీరు నిజ్జంగా ఈ టపాను తొలగించాలనుకుంటున్నారా?" @@ -1110,14 +1068,10 @@ te: title: "కన్నేసారు" tracking: title: "గమనిస్తున్నారు" - regular: - title: "రెగ్యులర్" muted: title: "నిశ్శబ్దం" - description: "ఈ వర్గాల్లో కొత్త విషయాల గురించి మీకు ప్రకటన రాదు. ఇంకా చదవి సంఖ్యలు కనిపించవు." flagging: title: 'మా కమ్యునిటీని నాగరికంగా ఉంచుటలో సహాయానికి ధన్యవాదములు' - private_reminder: 'కేతనాలు ప్రైవేటు. కేవలం సిబ్బందికి మాత్రమే కనిపిస్తాయి' action: 'టపాను కేతనించు' take_action: "చర్య తీసుకో" delete_spammer: "స్పామరును తొలగించు" @@ -1161,7 +1115,6 @@ te: help: "ఈ విషయం మీకు అగ్గుచ్చబడింది. ఇది ఇహ క్రమ వరుసలోనే కనిపిస్తుంది" pinned_globally: title: "సార్వత్రికంగా గుచ్చారు" - help: "ఈ విషయం సార్వత్రికంగా గుచ్చారు; అన్ని వరుసల్లోనూ ఇది అగ్రభాగాన కనిపిస్తుంది." pinned: title: "గుచ్చారు" help: "ఈ విషయం మీకు గుచ్చబడింది. దాని వర్గంలో అది అగ్రభాగాన కనిపిస్తుంది." @@ -1201,23 +1154,9 @@ te: title_in: "వర్గం - {{categoryName}}" help: "వర్గాల వారీగా జట్టు కట్టిన అన్ని విషయాలూ" unread: - title: - zero: "చదవని" - one: "చదవని (1)" - other: "చదవని ({{count}})" help: "మీరు ప్రస్తుతం కన్నేసిన లేదా గమనిస్తున్న చదవని టపాలతో ఉన్న విషయాలు " - lower_title_with_count: - one: "1 చదవని" - other: "{{count}} చదవని" new: - lower_title_with_count: - one: "1 కొత్త " - other: "{{count}} కొత్త" lower_title: "కొత్త" - title: - zero: "కొత్త" - one: "కొత్త (1)" - other: "కొత్త ({{count}})" help: "గత కొద్ది రోజులలో సృష్టించిన టపాలు" posted: title: "నా టపాలు" @@ -1226,10 +1165,6 @@ te: title: "పేజీకలు" help: "మీరు పేజీక ఉంచిన విషయాలు" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" - other: "{{categoryName}} ({{count}})" help: "{{categoryName}} వర్గంలోని కొత్త విషయాలు" top: title: "అగ్ర" @@ -1433,10 +1368,8 @@ te: restore: is_disabled: "సైటు అమరికల్లో రీస్టోరు అచేతనమైంది. " title: "బ్యాకప్ ను రీస్టోరు చేయి" - confirm: "మీరు నిజంగానే ఈ బ్యాకప్ ను రీస్టోరు చేయాలనుకుంటున్నారా?" rollback: title: "డాటాబేసును గత పనిచేసే స్థితికి రోల్ బ్యాక్ చేయి" - confirm: "మీరు నిజంగానే డాటాబేసును గత పనిచేసే స్థితికి రోల్ బ్యాక్ చేయాలనుకుంటున్నారా?" export_csv: user_archive_confirm: "మీరు నిజంగా మీ టపాల దిగుమతి కోరుకుంటున్నారా ?" failed: "ఎగుమతి విఫలమైంది. దయచేసి లాగులు చూడంది. " @@ -1525,13 +1458,9 @@ te: love: name: 'ప్రేమ' description: "ఇష్ఠ బటను రంగు." - wiki: - name: 'వికీ' - description: "వికీ టపాలు వెనుతలంకు ప్రాథమిక రంగు" email: - title: "ఈమెయిల్" settings: "అమరికలు" - all: "అన్నీ" + preview_digest: "డైజెస్టు మునుజూపు" sending_test: "పరీక్షా ఈమెయిల్ పంపుతున్నామ్..." error: "దోషం - %{server_error}" test_error: "టెస్ట్ మెయిల్ పంపడంలో ఒక సమస్య ఉంది.దయచేసి మీ మెయిల్ సెట్టింగ్స్ రెండోసారి తనిఖీ చేసి,మీ హోస్ట్ మెయిల్ కనెక్షన్ నిరోధించుటలేదని నిర్ధారించుకోండి, మరియు తిరిగి ప్రయత్నించండి." @@ -1546,7 +1475,6 @@ te: send_test: "పరీక్షా మెయిల్ పంపారు" sent_test: "పంపారు!" delivery_method: "డెలివరీ పద్దతి" - preview_digest: "డైజెస్టు మునుజూపు" refresh: "తాజాపరుచు" format: "రూపు" html: "హెచ్ టీయంయల్" @@ -1672,9 +1600,6 @@ te: pending: 'రివ్యూ పెండింగులో ఉన్న సభ్యులు' newuser: 'నమ్మకం స్థాయి 0 సభ్యులు (కొత్త సభ్యుడు)' basic: 'నమ్మకపు స్థాయి 1 వినియోగదారులు (ప్రాధమిక వినియోగదారు)' - regular: 'నమ్మకపు స్థాయి 2 వినియోగదారులు (సభ్యులు)' - leader: 'నమ్మకపు స్థాయి 3 వినియోగదారులు (నిత్యం)' - elder: 'నమ్మకపు స్థాయి 4 వినియోగదారులు (నాయకుడు)' staff: "సిబ్బంది" admins: 'అధికారి సభ్యులు' moderators: 'నిర్వాహకులు' @@ -1770,7 +1695,6 @@ te: unlock_trust_level: "నమ్మకపు స్థాయిని వదిలేయి" tl3_requirements: title: "నమ్మకపు స్థాయి 3 అవసరాలు" - table_title: "గత 100 రోజుల్లో:" value_heading: "విలువ" requirement_heading: "అవసరం" visits: "సందర్శనాలు" @@ -1829,7 +1753,6 @@ te: text: 'పాఠ్య క్షేత్రం' confirm: 'ఖాయము' site_text: - none: "సవరణను ప్రారంభించడానికి విషయం రకాన్ని ఎంచుకోండి." title: 'పాఠ్య కాంటెంటు' site_settings: show_overriden: 'ప్రాబల్యం ఉన్న వాటిని మాత్రమే చూపించు' @@ -1908,10 +1831,6 @@ te: sql_error_header: "ప్రశ్నతో దోషం ఉంది." bad_count_warning: header: "హెచ్చరిక!" - grant_count: - zero: "ఏ చిహ్నాలు కేటాయించలేదు." - one: "1 కేటాయించిన చిహ్నం." - other: "%{లెక్క} కేటాయించిన చిహ్నాలు." sample: "నమూనా:" grant: with: %{వినియోగదారు పేరు} @@ -1971,8 +1890,6 @@ te: mark_watching: 'm, w చూసిన విషయం' badges: title: బ్యాడ్జీలు - allow_title: "శీర్షికగా కూడా వాడవచ్చు" - multiple_grant: "పలుమార్లు బహూకరించవచ్చు" more_badges: one: "+%{count} కంటే" other: "+%{count} ఇంకా" @@ -1992,74 +1909,3 @@ te: name: ఇతర posting: name: రాస్తున్నారు - badge: - editor: - name: ఎడిటరు - description: తొలి టపా సవరణ - basic_user: - name: ప్రాథమిక - description: మంజూరు చేసిన అన్ని ఆవశ్యక సామాజిక చర్యలు - member: - name: సభ్యుడు - description: మంజూరు చేసిన ఆహ్వానాలు - regular: - name: రెగ్యులరు - leader: - name: లీడరు - welcome: - name: సుస్వాగతం - description: ఒక ఇష్టాన్ని అందుకున్నారు - autobiographer: - name: ఆత్మకధావాది - description: వినియోగదారు నింపిన ఫ్రొపైల్ సమాచారం - anniversary: - name: వార్షికోత్సవం - description: ఒక సంవత్సరం నుండి చురుకైన సభ్యుడు, కనీసం ఒకసారి టపా చేశాడు - nice_post: - name: మంచి టపా - description: ఒక టపా 10 ఇష్టాలు స్వీకరిస్తే , ఈ చిహ్నం అనేక సార్లు మంజూరు అవుతుంది - good_post: - name: చాలా మంచి టపా - description: ఒక టపా 25 ఇష్టాలు స్వీకరిస్తే , ఈ చిహ్నం అనేక సార్లు మంజూరు అవుతుంది - great_post: - name: బహుమంచి టపా - description: ఒక టపా 50 ఇష్టాలు స్వీకరిస్తే , ఈ చిహ్నం అనేక సార్లు మంజూరు అవుతుంది - nice_topic: - name: మంచి విషయం - description: ఒక విషయం 10 ఇష్టాలు స్వీకరిస్తే , ఈ చిహ్నం అనేక సార్లు మంజూరు అవుతుంది - good_topic: - name: చాలా మంచి విషయం - description: ఒక విషయం 25 ఇష్టాలు స్వీకరిస్తే , ఈ చిహ్నం అనేక సార్లు మంజూరు అవుతుంది - great_topic: - name: బహుమంచి విషయం - description: ఒక విషయం 50 ఇష్టాలు స్వీకరిస్తే , ఈ చిహ్నం అనేక సార్లు మంజూరు అవుతుంది - nice_share: - name: మంచి పంపకం - description: ఒక టపాను 25మంది సభ్యులతో పంచుకున్నారు - good_share: - name: చాలామంచి పంపకం - description: ఒక టపాను 300మంది సభ్యులతో పంచుకున్నారు - great_share: - name: బహుమంచి పంపకం - description: ఒక టపాను 1000 మంది సభ్యులతో పంచుకున్నారు - first_like: - name: తొలి ఇష్టం - description: టపాను ఇష్టపడ్డారు - first_flag: - name: తొలి కేతనం - description: ఒక టపాను కేతనించారు - first_share: - name: తొలి పంపకం - description: ఒక టపాను పంచారు - first_link: - name: తొలి లంకె - description: వేరొక విషయానికి అంతర్గతంగా లంకె కలిపారు - first_quote: - name: తొలి కోట్ - description: ఒక సభ్యుడిని కోట్ చేసారు - read_guidelines: - name: మార్గదర్శకాలు చదువు - description: కమ్యునిటీ మార్గదర్శకాలు చదవండి - reader: - name: చదువరి - description: 100 టపాల కన్నా ఎక్కువ ఉన్న అంశంలో ప్రతి టపా చదవండి diff --git a/config/locales/client.tr_TR.yml b/config/locales/client.tr_TR.yml index 7089f540297..9dead2c81b8 100644 --- a/config/locales/client.tr_TR.yml +++ b/config/locales/client.tr_TR.yml @@ -81,6 +81,8 @@ tr_TR: other: "%{count} ay sonra" x_years: other: "%{count} yıl sonra" + previous_month: 'Önceki Ay' + next_month: 'Sonraki Ay' share: topic: 'bu konunun bağlantısını paylaşın' post: '#%{postNumber} nolu gönderiyi paylaşın' @@ -90,6 +92,9 @@ tr_TR: google+: 'bu bağlantıyı Google+''da paylaşın' email: 'bu bağlantıyı e-posta ile gönderin' action_codes: + split_topic: "bu konuyu ayır %{when}" + invited_user: "%{when} %{who} davet edildi" + removed_user: "%{when} %{who} silindi" autoclosed: enabled: '%{when} kapatıldı' disabled: '%{when} açıldı' @@ -110,6 +115,19 @@ tr_TR: disabled: '%{when} listelenmedi' topic_admin_menu: "konuyla alakalı yönetici işlemleri" emails_are_disabled: "Tüm giden e-postalar yönetici tarafından evrensel olarak devre dışı bırakıldı. Herhangi bir e-posta bildirimi gönderilmeyecek." + s3: + regions: + us_east_1: "US East (N. Virginia)" + us_west_1: "US West (N. California)" + us_west_2: "US West (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "EU (Ireland)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asia Pacific (Singapore)" + ap_southeast_2: "Asia Pacific (Sydney)" + ap_northeast_1: "Asia Pacific (Tokyo)" + ap_northeast_2: "Asia Pacific (Seoul)" + sa_east_1: "South America (Sao Paulo)" edit: 'bu konunun başlığını ve kategorisini düzenleyin' not_implemented: "Bu özellik henüz geliştirilmedi, üzgünüz!" no_value: "Hayır" @@ -141,6 +159,8 @@ tr_TR: more: "Daha fazla" less: "Daha az" never: "asla" + every_30_minutes: "30 dakikada bir" + every_hour: "her saat" daily: "günlük" weekly: "haftalık" every_two_weeks: "her iki haftada bir" @@ -151,6 +171,7 @@ tr_TR: other: "{{count}} karakter" suggested_topics: title: "Önerilen Konular" + pm_title: "Önerilen Mesajlar" about: simple_title: "Hakkında" title: "%{title} Hakkında" @@ -203,6 +224,7 @@ tr_TR: revert: "Eski Haline Getir" failed: "Başarısız oldu" switch_to_anon: "Anonim Ol" + switch_from_anon: "Anonim Modundan Çık" banner: close: "Bu manşeti yoksay." edit: "Bu manşeti düzenle >>" @@ -224,7 +246,7 @@ tr_TR: has_pending_posts: other: "Bu konuda {{count}} sayıda onay bekleyen gönderi var" confirm: "Düzenlemeleri Kaydet" - delete_prompt: "%{username} kullanıcısını silmek istediğinize emin misiniz? Bu işlem kullanıcının tüm gönderilerini silecek, e-posta ve ip adresini engelleyecek." + delete_prompt: "%{username} kullanıcısını silmek istediğinize emin misiniz? Bunu yaparsanız tüm gönderileri silinecek, eposta adresi ve IP adresi bloklanacak." approval: title: "Gönderi Onay Gerektirir" description: "Gönderinizi aldık fakat gösterilmeden önce bir moderatör tarafından onaylanması gerekiyor. Lütfen sabırlı olun." @@ -265,13 +287,25 @@ tr_TR: total_rows: other: "%{count} kullanıcı" groups: + empty: + posts: "Bu grubun üyelerinden mesaj yok." + members: "Bu grupta üye yok." + mentions: "Bu gruptan söz edilmemiş." + messages: "Bu grup için bir mesaj yok." + topics: "Bu grubun üyelerinden konu yok." + add: "Ekle" + selector_placeholder: "Üye ekle" + owner: "sahip" visible: "Grup tüm kullanıcılar tarafından görüntülenebiliyor" title: other: "gruplar" members: "Üyeler" + topics: "Konular" posts: "Gönderiler" + mentions: "Atıflar" + messages: "Mesajlar" alias_levels: - title: "Kimler bu grubu ikinci adı olarak kullanabilir?" + title: "Kimler bu gruba mesaj gönderebilir ve gruptan @bahsedebilir?" nobody: " Hiç Kimse" only_admins: "Sadece Yöneticiler" mods_and_admins: "Sadece Moderatörler ve Yöneticiler" @@ -280,6 +314,16 @@ tr_TR: trust_levels: title: "Eklendiklerinde üyelere otomatik olarak güven seviyesi verilir:" none: "Hiç" + notifications: + watching: + title: "Gözleniyor" + tracking: + title: "Takip ediliyor" + regular: + title: "Normal" + muted: + title: "Susturuldu" + description: "Bu gruptan herhangi yeni konuyla ilgili asla bildirim almayacaksınız" user_action_groups: '1': "Verilen Beğeniler" '2': "Alınan Beğeniler" @@ -289,7 +333,6 @@ tr_TR: '6': "Yanıtlar" '7': "Bahsedenler" '9': "Alıntılar" - '10': "Yıldızlılar" '11': "Düzenlemeler" '12': "Yollanmış ögeler" '13': "Gelen Kutusu" @@ -299,6 +342,7 @@ tr_TR: all_subcategories: "hepsi" no_subcategory: "hiçbiri" category: "Kategori" + category_list: "Kategori ekranı listesi" reorder: title: "Kategorileri Yeniden Sırala" title_long: "Kategori listesini yeniden yapılandır" @@ -353,16 +397,14 @@ tr_TR: invited_by: "Tarafından Davet Edildi" trust_level: "Güven Seviyesi" notifications: "Bildirimler" + statistics: "istatistikler" desktop_notifications: label: "Masaüstü Bildirimleri" not_supported: "Bildirimler bu tarayıcıda desteklenmiyor. Üzgünüz." perm_default: "Bildirimleri Etkinleştirin" perm_denied_btn: "Erişim İzni Reddedildi" - perm_denied_expl: "Bildirimler için gerekli izne sahip değilsiniz. Bildirimleri etkinleştirmek için tarayıcınızı kullanın, işlem tamamlandığında tuşa basın. (Masaüstü: Adres çubuğunda en soldaki simge. Mobil: 'Site Bilgisi'.)" disable: "Bildirimleri Devre Dışı Bırakın" - currently_enabled: "(şu anda etkin)" enable: "Bildirimleri Etkinleştirin" - currently_disabled: "(şu anda devre dışı)" each_browser_note: "Not: Bu ayarı kullandığınız her tarayıcıda değiştirmelisiniz." dismiss_notifications: "Hepsini okunmuş olarak işaretle" dismiss_notifications_tooltip: "Tüm okunmamış bildirileri okunmuş olarak işaretle" @@ -386,7 +428,7 @@ tr_TR: tracked_categories: "Takip edildi" tracked_categories_instructions: "Bu kategorilerdeki tüm yeni konuları otomatik olarak takip edeceksiniz. Okunmamış ve yeni gönderilerin sayısı ilgili konunun yanında belirecek." muted_categories: "Susturuldu" - muted_categories_instructions: "Bu kategorideki yeni konular okunmamışlar sekmenizde belirmeyecek, ve haklarında hiçbir bildirim almayacaksınız." + muted_categories_instructions: "Bu kategorilerdeki yeni konular hakkında herhangi bir bildiri almayacaksınız ve en son gönderilerde belirmeyecekler. " delete_account: "Hesabımı Sil" delete_account_confirm: "Hesabınızı kalıcı olarak silmek istediğinize emin misiniz? Bu işlemi geri alamazsınız!" deleted_yourself: "Hesabınız başarıyla silindi." @@ -396,6 +438,7 @@ tr_TR: users: "Kullanıcılar" muted_users: "Susturuldu" muted_users_instructions: "Bu kullanıcılardan gelen tüm bildirileri kapa." + muted_topics_link: "Sessize alınmış konuları göster" staff_counters: flags_given: "yararlı bayraklar" flagged_posts: "bayraklanan gönderiler" @@ -404,8 +447,15 @@ tr_TR: warnings_received: "uyarılar" messages: all: "Hepsi" - mine: "Benimkiler" - unread: "Okunmamışlar" + inbox: "Gelen Kutusu" + sent: "Gönderildi" + archive: " Arşiv" + groups: "Gruplarım" + bulk_select: "Mesajları seçin" + move_to_inbox: "Gelen kutusuna taşı" + move_to_archive: " Arşiv" + failed_to_move: "Seçilen mesajları taşımak başarısız oldu (muhtemelen ağınız çöktü)" + select_all: "Tümünü seç" change_password: success: "(e-posta gönderildi)" in_progress: "(e-posta yollanıyor)" @@ -450,9 +500,8 @@ tr_TR: ok: "Onay için size e-posta atacağız" invalid: "Lütfen geçerli bir e-posta adresini giriniz" authenticated: "E-posta adresiniz {{provider}} tarafından doğrulanmıştır" + frequency_immediately: "Eğer yollamak üzere olduğumuz şeyi okumadıysanız size direk e-posta yollayacağız." frequency: - zero: "Eğer yollamak üzere olduğumuz şeyi okumadıysanız size direk e-posta yollayacağız." - one: "Sadece son bir dakika içinde sizi görmediysek e-posta yollayacağız." other: "Sadece son {{count}} dakika içinde sizi görmediysek e-posta yollayacağız." name: title: "İsim" @@ -489,8 +538,18 @@ tr_TR: title: "Kullanıcı Kartı Rozeti" website: "Web Sayfası" email_settings: "E-posta" + like_notification_frequency: + title: "Beğenildiğinde bildir" + always: "Her zaman" + never: "Asla" + email_previous_replies: + unless_emailed: "daha önce gönderilmediyse" + always: "her zaman" + never: "asla" email_digests: title: "Burayı ziyaret etmediğim zamanlarda bana yeni şeylerin özetini içeren bir email yolla:" + every_30_minutes: "30 dakikada bir" + every_hour: "saatte bir" daily: "günlük" every_three_days: "her üç günde bir" weekly: "haftalık" @@ -525,7 +584,8 @@ tr_TR: user: "Davet Edilen Kullanıcı" sent: "Gönderildi" none: "Bekleyen davet yok." - truncated: "İlk {{count}} davetler gösteriliyor." + truncated: + other: "ilk {{count}} davet gösteriliyor." redeemed: "Kabul Edilen Davetler" redeemed_tab: "Kabul Edildi" redeemed_tab_with_count: "İtfa edilmiş ({{count}})" @@ -560,6 +620,15 @@ tr_TR: same_as_email: "Şifreniz e-posta adresinizle aynı." ok: "Parolanız uygun gözüküyor." instructions: "En az %{count} karakter." + summary: + title: "Özet" + stats: "İstatistikler" + top_replies: "Başlıca Yanıtları" + more_replies: "Diğer Yanıtları" + top_topics: "Başlıca Konuları" + more_topics: "Diğer Konuları" + top_badges: "Başlıca Rozetleri" + more_badges: "Diğer Rozetleri" associated_accounts: "Girişler" ip_address: title: "Son IP Adresi" @@ -585,11 +654,13 @@ tr_TR: server: "Sunucu Hatası" forbidden: "Erişim Reddedildi" unknown: "Hata" + not_found: "Sayfa Bulunamadı" desc: network: "Lütfen bağlantınızı kontrol edin." network_fixed: "Geri döndü gibi gözüküyor." server: "Hata kodu : {{status}}" forbidden: "Bunu görüntülemeye izniniz yok." + not_found: "Hoppala, uygulama var olmayan bir URL'i yüklemeye çalıştı." unknown: "Bir şeyler ters gitti." buttons: back: "Geri Dönün" @@ -600,8 +671,12 @@ tr_TR: logout: "Çıkış yapıldı." refresh: "Yenile" read_only_mode: - enabled: "Salt-okunur modu etkin. Siteyi gezmeye devam edebilirsiniz fakat etkileşimler çalışmayabilir." + enabled: "Bu site salt okunur modda. Lütfen gezinmeye devam edin, ancak yanıt yazma, beğenme ve diğer aksiyonlar şu an için devre dışı durumda." login_disabled: "Site salt-okunur modda iken oturum açma devre dışı bırakılır ." + logout_disabled: "Site salt okunur modda iken oturum kapatma işlemi yapılamaz." + too_few_topics_and_posts_notice: "Hadi bu tartışmayı başlatalım! Şu anda %{currentTopics} / %{requiredTopics} konu ve %{currentPosts} / %{requiredPosts} gönderi var. Yeni ziyaretçiler okumak ve yanıtlamak için birkaç tartışmaya ihtiyaç duyarlar." + too_few_topics_notice: "Hadi bu tartışmayı başlatalım! Şu anda %{currentTopics} / %{requiredTopics} konu var. Yeni ziyaretçiler okumak ve yanıtlamak için birkaç tartışmaya ihtiyaç duyarlar." + too_few_posts_notice: "Hadi bu tartışmayı başlatalım! Şu anda %{currentPosts} / %{requiredPosts} gönderi var. Yeni ziyaretçiler okumak ve yanıtlamak için birkaç tartışmaya ihtiyaç duyarlar." learn_more: "daha fazlasını öğren..." year: 'yıl' year_desc: 'son 365 günde oluşturulan konular' @@ -617,10 +692,17 @@ tr_TR: last_reply_lowercase: son cevap replies_lowercase: other: cevap + signup_cta: + sign_up: "Üye Ol" + hide_session: "Yarın bana hatırlat" + hide_forever: "hayır teşekkürler" + hidden_for_session: "Tamamdır, yarın tekrar soracağım. İstediğiniz zaman 'Giriş' yaparak da hesap oluşturabilirsiniz." + intro: "Nabersin! heart_eyes: Görüneşe göre tartışmaların keyfini çıkaryorsun, fakat henüz bir hesap almak için kayıt olmamışsın." + value_prop: "Bir hesap oluşturduğunuzda, tam olarak neyi okuyor olduğunuzu hatırlarız, böylece her zaman okumayı bırakmış olduğunuz yere geri gelirsiniz. Ayrıca burada, yeni gönderiler yağıldığında email yoluyla bildirim alırsınız. Ve sevgiyi paylaşmak için gönderileri beğenebilirsiniz. :heartbeat:" summary: enabled_description: "Bu konunun özetini görüntülemektesiniz: topluluğun en çok ilgisini çeken gönderiler" - description: "{{count}} sayıda cevap var." - description_time: "Tahmini okunma süresi {{readingTime}} dakika olan {{count}} sayıda cevap var." + description: "{{replyCount}} adet yanıt var." + description_time: "Tahmini okuma süresi {{readingTime}} dakika olan {{replyCount}} yanıt var." enable: 'Bu Konuyu Özetle.' disable: 'Tüm Gönderileri Göster' deleted_filter: @@ -674,6 +756,9 @@ tr_TR: admin_not_allowed_from_ip_address: "Bu IP adresinden yönetici olarak oturum açamazsınız." resend_activation_email: "Etkinleştirme e-postasını tekrar yollamak için buraya tıklayın. " sent_activation_email_again: "{{currentEmail}} adresine yeni bir etkinleştirme e-postası yolladık. Bu e-postanın size ulaşması bir kaç dakika sürebilir; spam klasörüzü kontrol etmeyi unutmayın." + to_continue: "Lütfen Giriş Yap" + preferences: "Seçeneklerinizi değiştirebilmek için giriş yapmanız gerekiyor." + forgot: "Hesap bilgilerimi hatırlamıyorum" google: title: "Google ile" message: "Google ile kimlik doğrulaması yapılıyor (pop-up engelleyicilerin etkinleştirilmediğinden emin olun)" @@ -683,6 +768,9 @@ tr_TR: twitter: title: "Twitter ile" message: "Twitter ile kimlik doğrulaması yapılıyor (pop-up engelleyicilerin etkinleştirilmediğinden emin olun)" + instagram: + title: "Instagram ile" + message: "Instagram ile kimlik doğrulaması yapılıyor (pop-up engelleyicilerin etkinleştirilmediğinden emin olun)" facebook: title: "Facebook ile" message: "Facebook ile kimlik doğrulaması yapılıyor (pop-up engelleyicilerin etkinleştirilmediğinden emin olun)" @@ -696,15 +784,24 @@ tr_TR: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "dahası..." + options: "Seçenekler" + whisper: "fısıltı" add_warning: "Bu resmi bir uyarıdır." + toggle_whisper: "Fısıldamayı Göster/Gizle" posting_not_on_topic: "Hangi konuyu cevaplamak istiyorsun?" saving_draft_tip: "kaydediliyor..." saved_draft_tip: "kaydedildi" saved_local_draft_tip: "yerele kaydedildi" similar_topics: "Konunuz şunlara çok benziyor..." drafts_offline: "çevrimdışı taslaklar" + group_mentioned: "{{group}} adlı grubu kullanarak, {{count}} kişiye bildirim göndermek üzeresiniz." error: title_missing: "Başlık gerekli" title_too_short: "Başlık en az {{min}} karakter olmalı" @@ -727,7 +824,7 @@ tr_TR: show_edit_reason: "(düzenleme sebebi ekle)" reply_placeholder: "Buraya yazın. Biçimlendirmek için Markdown, BBCode ya da HTML kullanabilirsin. Resimleri sürükleyebilir ya da yapıştırabilirsin." view_new_post: "Yeni gönderinizi görüntüleyin." - saving: "Kaydediliyor..." + saving: "Kaydediliyor" saved: "Kaydedildi!" saved_draft: "Gönderi taslağı işleniyor. Geri almak için seçin. " uploading: "Yükleniyor..." @@ -742,6 +839,7 @@ tr_TR: link_description: "buraya bağlantı açıklamasını girin" link_dialog_title: "Bağlantı ekle" link_optional_text: "opsiyonel başlık" + link_placeholder: "http://example.com \"isteğe bağlı yazı\"" quote_title: "Blok-alıntı" quote_text: "Blok-alıntı" code_title: "Önceden biçimlendirilmiş yazı" @@ -754,10 +852,11 @@ tr_TR: heading_title: "Başlık" heading_text: "Başlık" hr_title: "Yatay Çizgi" - undo_title: "Geri Al" - redo_title: "Tekrarla" help: "Markdown Düzenleme Yardımı" toggler: "yazım alanını gizle veya göster" + modal_ok: "Tamam" + modal_cancel: "İptal" + cant_send_pm: "Üzgünüz, %{username} kullanıcısına mesaj gönderemezsiniz." admin_options_title: "Bu konu için opsiyonel görevli ayarları" auto_close: label: "Başlığı otomatik kapatma zamanı:" @@ -774,11 +873,15 @@ tr_TR: more: "daha eski bildirimleri görüntüle" total_flagged: "tüm bayraklanan gönderiler" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " + posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}, {{username2}} {{description}}

    " + liked_many: + other: "

    {{username}}, {{username2}} ve diğer {{count}} kişi {{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -786,6 +889,8 @@ tr_TR: moved_post: "

    {{username}} taşıdı {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    {{description}} rozeti kazandınız!

    " + group_message_summary: + other: "

    {{group_name}} isimli grubunuzun gelen kutusunda {{count}} adet mesaj var

    " alt: mentioned: "Bahsedildi, şu kişi tarafından" quoted: "Alıntılandı, şu kişi tarafından" @@ -800,8 +905,10 @@ tr_TR: moved_post: "Gönderiniz taşındı, şu kişi tarafından" linked: "Gönderinize bağlantı" granted_badge: "Rozet alındı" + group_message_summary: "Grup gelen kutusundaki mesajlar" popup: mentioned: '{{username}}, "{{topic}}" başlıklı konuda sizden bahsetti - {{site_title}}' + group_mentioned: '{{username}} sizden bahsetti "{{topic}}" - {{site_title}}' quoted: '{{username}}, "{{topic}}" başlıklı konuda sizden alıntı yaptı - {{site_title}}' replied: '{{username}}, "{{topic}}" başlıklı konuda size cevap verdi - {{site_title}}' posted: '{{username}}, "{{topic}}" başlıklı konuya yazdı - {{site_title}}' @@ -813,17 +920,24 @@ tr_TR: from_my_computer: "Kendi cihazımdan" from_the_web: "Webden" remote_tip: "resme bağlantı ver" - remote_tip_with_attachments: "resme ya da dosyaya ({{authorized_extensions}}) bağlantı ver" + remote_tip_with_attachments: "dosya yada imaj linki {{authorized_extensions}}" local_tip: "cihazınızdan resimler seçin" - local_tip_with_attachments: "cihazınızdan resim veya dosyalar seçin ({{authorized_extensions}})" + local_tip_with_attachments: "cihaınızdan imaj yada dosya seçin {{authorized_extensions}}" hint: "(editöre sürekle & bırak yaparak da yükleyebilirsiniz)" hint_for_supported_browsers: "ayrıca resimleri düzenleyiciye sürükleyip bırakabilir ya da yapıştırabilirsiniz" uploading: "Yükleniyor" select_file: "Dosya seçin" image_link: "resminizin yönleneceği bağlantı" search: + sort_by: "Sırala" + relevance: "Alaka" + latest_post: "Son Gönderi" + most_viewed: "En Çok Görüntülenen" + most_liked: "En Çok Beğenilen" select_all: "Tümünü Seç" clear_all: "Tümünü Temizle" + result_count: + other: "\"{{term}}\" için sonuçlar {{count}}" title: "konu, gönderi, kullanıcı veya kategori ara" no_results: "Hiç bir sonuç bulunamadı." no_more_results: "Başka sonuç yok." @@ -842,12 +956,14 @@ tr_TR: current_user: 'kendi kullanıcı sayfana git' topics: bulk: + unlist_topics: "Konuları Listeleme" reset_read: "Okunmuşları Sıfırla" delete: "Konuları Sil" - dismiss_posts: "Gönderileri Yoksay" - dismiss_posts_tooltip: "Bu konulardaki okunmamışların sayısını sıfırla ama yeni gönderiler oluşturulduğunda okunmamışlar listemde göster" - dismiss_topics: "Konuları Yoksay" - dismiss_topics_tooltip: "Bu konularda yeni gönderiler oluşturulunca okunmamış listemde gösterme" + dismiss: "Yoksay" + dismiss_read: "Okumadıklarını yoksay" + dismiss_button: "Yoksay..." + dismiss_tooltip: "Yeni gönderileri görmezden gel yada konuları izlemeyi bırak" + also_dismiss_topics: "Bana, tekrar okunmamış olarak gösterilmemesi için bu konuları izlemeyi bırak." dismiss_new: "Yenileri Yoksay" toggle: "konuların toplu seçimini aç/kapa" actions: "Toplu İşlemler" @@ -869,9 +985,6 @@ tr_TR: category: "{{category}} konusu yok." top: "Popüler bir konu yok." search: "Arama sonuçları yok." - educate: - new: '

    Yeni konularınız burada belirir.

    Varsayılan ayarlarda, son 2 gün içerisinde açılan konular yeni sayılır ve yeni işaretiyle gösterilir.

    Dilerseniz bu seçeneği ayarlar sayfanızdan düzenleyebilirsiniz.

    ' - unread: '

    Okunmamış konularınız burada belirecek.

    Varsayılan ayarlarda, şu durumlarda konular okunmamış sayılır ve okunmamışların sayısı 1 gösterilir:

    • Konuyu oluşturduysanız
    • Konuyu cevapladıysanız
    • Konuyu 4 dakikadan uzun bir süre okuduysanız

    Ya da, konunun altında bulunan bildirim kontrol bölümünden, konuyu Takip Edildi veya Gözlendi diye işaretlediyseniz.

    Bu ayarları ayarlar sayfasından değiştirebilirsiniz.

    ' bottom: latest: "Daha fazla son konu yok." hot: "Daha fazla sıcak bir konu yok." @@ -891,6 +1004,12 @@ tr_TR: create: 'Yeni Konu' create_long: 'Yeni bir konu oluştur' private_message: 'Mesajlaşma başlat' + archive_message: + help: 'Mesajı arşivine taşı' + title: ' Arşiv' + move_to_inbox: + title: 'Gelen kutusuna taşı' + help: 'Mesajı yeniden gelen kutusuna taşı' list: 'Konular' new: 'yeni konu' unread: 'okunmamış' @@ -921,7 +1040,7 @@ tr_TR: options: "Konu Seçenekleri" show_links: "Bu konunun içindeki bağlantıları göster. " toggle_information: "konu ayrıntılarını aç/kapa" - read_more_in_category: "Daha fazlası için {{catLink}} kategorisine göz atabilir ya da {{latestLink}}bilirsiniz." + read_more_in_category: "Daha fazlası için {{catLink}} kategorisine göz atabilir ya da {{latestLink}}yebilirsiniz." read_more: "Daha fazla okumak mı istiyorsunuz? {{catLink}} ya da {{latestLink}}." read_more_MF: "Kalan { UNREAD, plural, =0 {} one { 1 okunmamış } other { # okunmamış } } { NEW, plural, =0 {} one { {BOTH, select, true{ve} false {} other{}} 1 yeni konu} other { {BOTH, select, true{and } false {} other{}} # yeni konu} } var, veya {CATEGORY, select, true { {catLink}} false {{latestLink}} kategorilerindeki diğer {} konulara göz atabilirsiniz }" browse_all_categories: Bütün kategorilere göz at @@ -935,6 +1054,7 @@ tr_TR: auto_close_title: 'Otomatik Kapatma Ayarları' auto_close_save: "Kaydet" auto_close_remove: "Bu Konuyu Otomatik Olarak Kapatma" + auto_close_immediate: "Son konudaki mesaj %{hours} saat olmuş, bu yüzden konu hemen kapanacak" progress: title: konu gidişatı go_top: "en üst" @@ -984,7 +1104,7 @@ tr_TR: description: "Bu mesajlaşmayla ilgili hiç bir bildirim almayacaksınız." muted: title: "Susturuldu" - description: "Bu konu okunmamışlar sekmenizde belirmeyecek, ve hakkında hiç bir bildirim almayacaksınız." + description: "Bu konu en son gönderilerde belirmeyecek, ve hakkında hiçbir bildirim almayacaksınız." actions: recover: "Konuyu Geri Getir" delete: "Konuyu Sil" @@ -1026,25 +1146,22 @@ tr_TR: unpin_until: "Bu konuyu {{categoryLink}} kategorisinin başından kaldır ya da şu zamana kadar bekle: %{until}." pin_note: "Kullanıcılar kendileri için konunun başa tutturulmasını kaldırabilir." pin_validation: "Bu konuyu sabitlemek için bir tarih gerekli." + not_pinned: " {{categoryLink}} kategorisinde başa tutturulan herhangi bir konu yok." already_pinned: - zero: " {{categoryLink}} kategorisinde başa tutturulan herhangi bir konu yok." - one: "Şu an {{categoryLink}} kategorisinde başa tutturulan konular: 1." other: "Şu an {{categoryLink}} kategorisinde başa tutturulan konular: {{count}}." pin_globally: "Şu zamana kadar bu konunun bütün konu listelerinin başında yer almasını sağla" confirm_pin_globally: "Zaten her yerde başa tutturulan {{count}} konunuz var. Çok fazla konuyu başa tutturmak yeni ve anonim kullanıcılara sıkıntı çektirebilir. Bir konuyu daha her yerde başa tutturmak istediğinizden emin misiniz?" unpin_globally: "Bu konuyu tüm konu listelerinin en üstünden kaldır." unpin_globally_until: "Bu konuyu bütün konu listelerinin başından kaldır ya da şu zamana kadar bekle: %{until}." global_pin_note: "Kullanıcılar kendileri için konunun başa tutturulmasını kaldırabilir." + not_pinned_globally: "Her yerde başa tutturulan herhangi bir konu yok." already_pinned_globally: - zero: "Her yerde başa tutturulan herhangi bir konu yok." - one: "Şu an her yerde başa tutturulan konular: 1." other: "Şu an her yerde başa tutturulan konular: {{count}}." make_banner: "Bu konuyu tüm sayfaların en üstünde görünecek şekilde manşetleştir." remove_banner: "Tüm sayfaların en üstünde görünen manşeti kaldır." banner_note: "Kullanıcılar bu manşeti kapatarak yoksayabilirler. Herhangi bir zamanda sadece bir konu manşetlenebilir." - already_banner: - zero: "Manşet konusu yok." - one: "Şu an bir manşet konusu var." + no_banner_exists: "Manşet konusu yok." + banner_exists: "Şu an bir manşet konusu var." inviting: "Davet Ediliyor..." automatically_add_to_groups_optional: "Bu davet şu gruplara erişimi de içerir: (opsiyonel, sadece yöneticiler için)" automatically_add_to_groups_required: "Bu davet şu gruplara erişimi de içerir: (Gerekli, sadece yöneticiler için)" @@ -1056,6 +1173,7 @@ tr_TR: success: "O kullanıcıyı bu mesajlaşmaya davet ettik." error: "Üzgünüz, kullanıcı davet edilirken bir hata oluştu." group_name: "grup adı" + controls: "Konu Kontrolleri" invite_reply: title: 'Davet Et' username_placeholder: "kullanıcıadı" @@ -1140,9 +1258,8 @@ tr_TR: other: "{{count}} Beğeni" has_likes_title: other: "{{count}} kişi bu gönderiyi beğendi" + has_likes_title_only_you: "bu gönderiyi beğendiniz" has_likes_title_you: - zero: "bu gönderiyi beğendiniz" - one: "siz ve diğer 1 kişi bu gönderiyi beğendi" other: "siz ve {{count}} diğer kişi bu gönderiyi beğendi" errors: create: "Üzgünüz, gönderiniz oluşturulurken bir hata oluştu. Lütfen tekrar deneyin." @@ -1163,7 +1280,7 @@ tr_TR: via_email: "bu gönderi e-posta ile iletildi" whisper: "bu gönderi yöneticiler için özel bir fısıltıdır" wiki: - about: "bu gönderi bir wiki; acemi kullanıcılar düzenleyebilir" + about: "bu gönderi bir wiki" archetypes: save: 'Seçenekleri kaydet' controls: @@ -1190,6 +1307,7 @@ tr_TR: revert_to_regular: "Görevli Rengini Kaldır" rebake: "HTML'i Yeniden Yapılandır" unhide: "Gizleme" + change_owner: "sahipliğini değiştir" actions: flag: 'Bayrakla' defer_flags: @@ -1210,17 +1328,14 @@ tr_TR: like: "Beğenini geri al" vote: "Oyunu geri al" people: - off_topic: "{{icons}} konu dışı olarak bayrakladı" - spam: "{{icons}} spam olarak bayrakladı" - spam_with_url: "{{icons}} bu linki spam olarak bayrakladı" - inappropriate: "{{icons}} uygunsuz olarak bayrakladı" - notify_moderators: "{{icons}} bildirim gönderilen moderatörler" - notify_moderators_with_url: "{{icons}} bildirim gönderilen moderatörler" - notify_user: "{{icons}} mesaj yolladı" - notify_user_with_url: "{{icons}} mesaj yolladı" - bookmark: "{{icons}} bunu işaretledi" - like: "{{icons}} bunu beğendi" - vote: "{{icons}} bunun için oyladı" + off_topic: "konu dışı olarak bayrakladı" + spam: "spam olarak bayrakladı" + inappropriate: "uygunsuz olarak bayrakladı" + notify_moderators: "moderatörler bilgilendirdi" + notify_user: "mesaj gönderdi" + bookmark: "işaretledi" + like: "beğendi" + vote: "oyladı" by_you: off_topic: "Bunu konu dışı olarak bayrakladınız" spam: "Bunu spam olarak bayrakladınız" @@ -1264,10 +1379,6 @@ tr_TR: other: "{{count}} kişi bunu beğendi" vote: other: "{{count}} kişi bu gönderiyi oyladı" - edits: - one: 1 düzenleme - other: "{{count}} düzenleme" - zero: hiç bir düzenleme delete: confirm: other: "Tüm bu gönderileri silmek istediğinize emin misiniz?" @@ -1347,19 +1458,18 @@ tr_TR: notifications: watching: title: "Gözleniyor" - description: "Bu kategorilerdeki tüm yeni konuları otomatik olarak gözleyeceksiniz. Tüm yeni gönderi ve konularla ilgili bildiri alacaksınız, ayrıca okunmamış ve yeni gönderilerin sayısı ilgili konunun yanında belirecek." + description: "Bu kategorilerdeki tüm yeni konuları otomatik olarak gözleyeceksiniz. Tüm yeni gönderi ve konular size bildirilecek. Ayrıca, okunmamış ve yeni gönderilerin sayısı ilgili konunun yanında belirecek." tracking: title: "Takip Ediliyor" - description: "Bu kategorilerdeki tüm yeni konuları otomatik olarak takip edeceksiniz. Okunmamış ve yeni gönderilerin sayısı ilgili konunun yanında belirecek." + description: "Bu kategorilerdeki tüm yeni konuları otomatik olarak gözleyeceksiniz. Biri @isim şeklinde sizden bahsederse ya da gönderinize cevap verirse bildirim alacaksınız. Ayrıca, okunmamış ve yeni cevapların sayısı ilgili konunun yanında belirecek." regular: - title: "Standart" + title: "Normal" description: "Birisi @isim şeklinde sizden bahsederse ya da gönderinize cevap verirse bildirim alacaksınız." muted: title: "Susturuldu" - description: "Bu kategorilerdeki yeni konular hakkında herhangi bir bildiri almayacaksınız ve okunmamışlar sekmenizde belirmeyecek. " + description: "Bu kategorilerdeki yeni konular hakkında herhangi bir bildiri almayacaksınız ve en son gönderilerde belirmeyecekler. " flagging: title: 'Topluluğumuzun medeni kalmasına yardımcı olduğunuz için teşekkürler!' - private_reminder: 'bayraklar özeldir, sadece görevlilere gözükür' action: 'Gönderiyi Bayrakla' take_action: "Harekete Geç" notify_action: 'Mesaj' @@ -1371,6 +1481,7 @@ tr_TR: submit_tooltip: "Özel bayrağı gönder" take_action_tooltip: "Topluluğunuzdan daha fazla bayrak beklemek yerine bunu siz hızlıca yaparak eşiğe erişebilirsiniz" cant: "Üzgünüz, şu an bu gönderiyi bayraklayamazsınız." + notify_staff: 'Yetkililere özel olarak bildir' formatted_name: off_topic: "Konu Dışı" inappropriate: "Uygunsuz" @@ -1408,7 +1519,7 @@ tr_TR: help: "Bu konu sizin için başa tutturulmuyor; normal sıralama içerisinde görünecek" pinned_globally: title: "Her Yerde Başa Tutturuldu" - help: "Bu konu her yerde başa tutturuldu; tüm listelerin başında görünecek" + help: "Bu konu her yerde başa tutturuldu; gönderildiği kategori ve en son gönderilerin en üstünde görünecek" pinned: title: "Başa Tutturuldu" help: "Bu konu sizin için başa tutturuldu; kendi kategorisinin en üstünde görünecek" @@ -1448,9 +1559,8 @@ tr_TR: with_topics: "%{filter} konular" with_category: "%{filter} %{category} konular" latest: - title: - zero: "En Son" - one: "En Son (1)" + title: "En son" + title_with_count: other: "En Son ({{count}})" help: "yakın zamanda gönderi alan konular" hot: @@ -1467,22 +1577,18 @@ tr_TR: title_in: "Kategori - {{categoryName}}" help: "kategori bazında tüm konular" unread: - title: - zero: "Okunmamış" - one: "Okunmamış (1)" + title: "Okunmamış" + title_with_count: other: "Okunmamış ({{count}})" help: "okunmamış gönderiler bulunan gözlediğiniz ya da takip ettiğiniz konular" lower_title_with_count: - one: "1 okunmamış" other: "{{count}} okunmamış" new: lower_title_with_count: - one: "1 yeni" other: "{{count}} yeni" lower_title: "yeni" - title: - zero: "Yeni" - one: "Yeni (1)" + title: "Yeni" + title_with_count: other: "Yeni ({{count}}) " help: "son birkaç günde oluşturulmuş konular" posted: @@ -1492,9 +1598,8 @@ tr_TR: title: "İşaretlenenler" help: "işaretlediğiniz konular" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" + title: "{{categoryName}}" + title_with_count: other: "{{categoryName}} ({{count}})" help: "{{categoryName}} kategorisindeki en son konular" top: @@ -1575,6 +1680,7 @@ tr_TR: refresh_report: "Raporu Yenile" start_date: "Başlangıç tarihi" end_date: "Bitiş Tarihi" + groups: "Tüm gruplar" commits: latest_changes: "En son değişiklikler: lütfen sık güncelleyin!" by: "tarafından" @@ -1650,15 +1756,24 @@ tr_TR: delete_confirm: "Grup silinsin mi?" delete_failed: "Grup silinemedi. Bu otomatik oluşturulmuş bir grup ise, yok edilemez." delete_member_confirm: "'%{username}' adlı kullanıcıyı '%{group}' grubundan çıkart?" + delete_owner_confirm: "'%{username}' için sahiplik imtiyazı kaldırılsın mı?" name: "Ad" add: "Ekle" add_members: "Üye ekle" custom: "Özel" + bulk_complete: "Kullanıcılar gruba eklendi." + bulk: "Topluca Gruba Ekle" + bulk_paste: "Kullanıcı adı yada eposta listesini yapıştırın, her satıra bir tane gelecek:" + bulk_select: "(bir grup seçin)" automatic: "Otomatik" automatic_membership_email_domains: "Bu listedeki bir e-posta alan adıyla kaydolan kullanıcılar otomatik olarak bu gruba eklenecekler:" automatic_membership_retroactive: "Varolan kayıtlı kullanıcıları eklemek için aynı e-posta alan adı kuralını uygula" default_title: "Bu gruptaki tüm kullanıcılar için varsayılan başlık" primary_group: "Otomatik olarak ana grup yap" + group_owners: Sahipler + add_owners: Sahiplik ekle + incoming_email: "Özel gelen e-posta adresi" + incoming_email_placeholder: "e-posta adresi girin" api: generate_master: "Ana API Anahtarı Üret" none: "Şu an etkin API anahtarı bulunmuyor." @@ -1732,11 +1847,11 @@ tr_TR: is_disabled: "Geri getirme site ayarlarında devredışı bırakılmış." label: "Geri Yükle" title: "Yedeği geri getir" - confirm: "Yedeği geri getirmek istediğinize emin misiniz?" + confirm: "Bu yedekten geri dönmek istediğinize emin misiniz?" rollback: label: "Geri al" title: "Veritabanını calışan son haline geri al." - confirm: "Veri tabanını çalışan bir önceki versyonuna geri almak istediğinizden emin misiniz?" + confirm: "Veritabanını çalışan son haline döndürmek istediğinize emin misiniz?" export_csv: user_archive_confirm: "Gönderilerinizi indirmek istediğinize emin misiniz ?" success: "Dışarı aktarma başlatıldı, işlem tamamlandığında mesajla bilgilendirileceksiniz." @@ -1787,6 +1902,14 @@ tr_TR: color: "Renk" opacity: "Opaklık" copy: "Kopyala" + email_templates: + title: "E-posta Şablonları" + subject: "Konu" + multiple_subjects: "Bu e-posta şablonunda birden fazla konu mevcut." + body: "İçerik" + none_selected: "Düzenlemeye başlamak için içerik tipi seçin. " + revert: "Değişiklikleri Sıfırla" + revert_confirm: "Değişiklikleri sıfırlamak istediğinize emin misiniz?" css_html: title: "CSS/HTML" long_title: "CSS ve HTML Özelleştirmeleri" @@ -1831,18 +1954,18 @@ tr_TR: love: name: 'sevgi' description: "Beğen butonunun rengi." - wiki: - name: 'wiki' - description: "wiki gönderilerinin arka plan rengi." email: - title: "E-posta" + title: "E-postalar" settings: "Ayarlar" - all: "Hepsi" + templates: "Şablonlar" + preview_digest: "Özeti Önizle" sending_test: "Test e-postası gönderiliyor..." error: "HATA - %{server_error}" test_error: "Test e-postasının gönderilmesinde sorun yaşandı. Lütfen e-posta ayarlarınızı tekrar kontrol edin, yer sağlayıcınızın e-posta bağlantılarını bloke etmediğinden emin olun, ve tekrar deneyin." sent: "Gönderildi" skipped: "Atlandı" + received: "Alındı" + rejected: "Reddedildi" sent_at: "Gönderildiği Zaman" time: "Zaman" user: "Kullanıcı" @@ -1852,7 +1975,6 @@ tr_TR: send_test: "Test E-postası Gönder" sent_test: "gönderildi!" delivery_method: "Gönderme Metodu" - preview_digest: "Özeti Önizle" preview_digest_desc: "Durgun kullanıcılara gönderilen özet e-postaların içeriğini önizle." refresh: "Yenile" format: "Format" @@ -1861,6 +1983,25 @@ tr_TR: last_seen_user: "Son Görülen Kullanıcı:" reply_key: "Cevapla Tuşu" skipped_reason: "Nedeni Atla" + incoming_emails: + from_address: "Gönderen" + to_addresses: "Kime" + cc_addresses: "Cc" + subject: "Konu" + error: "Hata" + none: "Gelen e-posta yok." + modal: + title: "Gelen E-posta Detayları" + error: "Hata" + subject: "Konu" + body: "İçerik" + rejection_message: "Ret E-postası" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Konu..." + error_placeholder: "Hata" logs: none: "Hiç bir kayıt bulunamadı." filters: @@ -1879,6 +2020,7 @@ tr_TR: ip_address: "IP" topic_id: "Konu IDsi" post_id: "Gönderi IDsi" + category_id: "Kategori ID" delete: 'Sil' edit: 'Düzenle' save: 'Kaydet' @@ -1909,6 +2051,7 @@ tr_TR: change_site_setting: "websitesi ayarlarını değiştir" change_site_customization: "websitesinin özelleştirmesini değiştir" delete_site_customization: "websitesinin özelleştirmesini sil" + change_site_text: "site metnini değiştir" suspend_user: "kullanıcıyı uzaklaştır" unsuspend_user: "kullanıcıyı uzaklaştırma" grant_badge: "rozet ver" @@ -1919,6 +2062,16 @@ tr_TR: impersonate: "rolüne gir" anonymize_user: "kullanıcıyı anonimleştir" roll_up: "IP bloklarını topla" + change_category_settings: "kategori ayarlarını değiştir" + delete_category: "kategoriyi sil" + create_category: "kategori oluştur" + block_user: "kullanıcıyı blokla" + unblock_user: "kullanıcı engelini kaldır" + grant_admin: "yönetici yetkisi ver" + revoke_admin: "yönetici yetkisini kaldır" + grant_moderation: "moderasyon yetkisi ver" + revoke_moderation: "moderasyon yetkisini kaldır" + backup_operation: "yedek operasyonu" screened_emails: title: "Taranmış E-postalar" description: "Biri yeni bir hesap oluşturmaya çalıştığında, aşağıdaki e-posta adresleri kontrol edilecek ve kayıt önlenecek veya başka bir aksiyon alınacak." @@ -1983,9 +2136,9 @@ tr_TR: pending: 'Gözden Geçirilmeyi Bekleyen Kullanıcılar' newuser: 'Güven seviyesi 0 (Yeni kullanıcı) olan kullanıcılar' basic: 'Güven seviyesi 1 (Acemi kullanıcı) olan kullanıcılar' - regular: 'Güven seviyesi 2 (Üye) olan kullanıcılar' - leader: 'Güven seviyesi 3 (Müdavim) olan kullanıcılar' - elder: 'Güven seviyesi 4 (Lider) olan kullanıcılar' + member: 'Güven seviyesi 2 (Üye) olan kullanıcılar' + regular: 'Güven seviyesi 3 (Müdavim) olan kullanıcılar' + leader: 'Güven seviyesi 4 (Lider) olan kullanıcılar' staff: "Görevli" admins: 'Yöneticiler' moderators: 'Moderatörler' @@ -2077,6 +2230,8 @@ tr_TR: deactivate_failed: "Kullanıcı deaktive edilirken bir sorun yaşandı." unblock_failed: 'Kullanıcının engeli kaldırılırken bir sorun yaşandı.' block_failed: 'Kullanıcı engellenirken bir sorun yaşandı.' + block_confirm: 'Bu kullanıcıyı bloklamak istediğinize emin misiniz? Bunu yaparsanız yeni başlık ya da gönderi oluşturamayacak.' + block_accept: 'Evet, bu kullanıcıyı blokla' deactivate_explanation: "Deaktive edilmiş bir kullanıcı e-postasını tekrar doğrulamalı." suspended_explanation: "Uzaklaştırılmış kullanıcılar sistemde oturum açamaz." block_explanation: "Engellenmiş bir kullanıcı gönderi oluşturamaz veya konu başlatamaz." @@ -2090,7 +2245,7 @@ tr_TR: unlock_trust_level: "Güvenlik Seviyesi Kilidini Aç" tl3_requirements: title: "Güven Seviyesi 3 için Gerekenler" - table_title: "Son 100 günde:" + table_title: "Son %{time_period} günde" value_heading: "Değer" requirement_heading: "Gereksinim" visits: "Ziyaretler" @@ -2151,8 +2306,15 @@ tr_TR: confirm: 'Onay' dropdown: "Açılır liste" site_text: - none: "Düzenlemeye başlamak için içerik tipi seçin." + description: "Forumunuzdaki herhangi bir metni özelleştirebilirsiniz. Lütfen aşağıda arayarak başlayın: " + search: "Düzenlemek istediğiniz metni arayın" title: 'Yazı İçeriği' + edit: 'düzenle' + revert: "Değişiklikleri Sıfırla" + revert_confirm: "Değişiklikleri sıfırlamak istediğinize emin misiniz?" + go_back: "Aramaya geri dön" + recommended: "İzleyen metni ihtiyaçlarınıza uygun şekilde özelleştimenizi öneririz:" + show_overriden: 'Sadece değiştirdiklerimi göster' site_settings: show_overriden: 'Sadece değiştirdiklerimi göster' title: 'Ayarlar' @@ -2240,9 +2402,8 @@ tr_TR: bad_count_warning: header: "UYARI!" text: "Bazı veriliş örnekleri bulunamıyor. Bu durum, rozet sorgusundan varolmayan kullanıcı IDsi veya gönderi IDsi dönünce gerçekleşir. İleride beklenmedik sonuçlara sebep olabilir - lütfen sorgunuzu tekrar kontrol edin." + no_grant_count: "Verilecek rozet bulunmuyor." grant_count: - zero: "Verilecek rozet bulunmuyor." - one: "1 rozet verilecek." other: "%{count} rozet verilecek." sample: "Örnek:" grant: @@ -2351,9 +2512,9 @@ tr_TR: mark_tracking: 'm, t Konuyu takip et' mark_watching: 'm, w Konuyu gözle' badges: + earned_n_times: + other: "Bu rozet %{count} defa kazanılmış" title: Rozetler - allow_title: "ünvan olarak kullanılabilir" - multiple_grant: "birden fazla kez verilebilir" badge_count: other: "%{count} Rozet" more_badges: @@ -2373,97 +2534,6 @@ tr_TR: name: Diğer posting: name: Gönderiler - badge: - editor: - name: Editör - description: İlk gönderi düzenleme - basic_user: - name: Acemi - description: Tüm temel topluluk işlevleri için hak verildi - member: - name: Üye - description: Davetiye gönderebilme hakkı verildi - regular: - name: Müdavim - description: Konuların isimlerini ve kategorilerini değiştirebilme, follow'lu bağlantı paylaşabilme ve lobiye girebilme hakları verildi - leader: - name: Lider - description: 'Tüm gönderileri düzenleyebilme, konuları başa tutturabilme, kapatabilme, arşivleyebilme, bölebilme ve birleştirebilme hakları verildi ' - welcome: - name: Hoş geldiniz - description: Bir beğeni aldı - autobiographer: - name: Otobiyografi Yazarı - description: Kullanıcı profil bilgilerini doldurmuş - anniversary: - name: Yıldönümü - description: Bir yıldır aktif kullanıcı, en az bir kere gönderi oluşturmuş. - nice_post: - name: Güzel Gönderi - description: Bir gönderiden 10 beğeni alındı. Bu rozet birden fazla defa verilebilir. - good_post: - name: İyi Gönderi - description: Bir gönderiden 25 beğeni alındı. Bu rozet birden fazla defa verilebilir. - great_post: - name: Harika Gönderi - description: Bir gönderiden 50 beğeni alındı. Bu rozet birden fazla defa verilebilir. - nice_topic: - name: Güzel Konu - description: Bir konuda 10 beğeni almış. Bu rozet birden çok kez kazanılabilir. - good_topic: - name: İyi Konu - description: Bir konuda 25 beğeni almış. Bu rozet birden çok kez kazanılabilir. - great_topic: - name: Harika Konu - description: Bir konuda 50 beğeni almış. Bu rozet birden çok kez kazanılabilir. - nice_share: - name: Güzel Paylaşım - description: 25 tekil kullanıcı ile bir gönderiyi paylaşmış - good_share: - name: İyi Paylaşım - description: 300 tekil kullanıcı ile bir gönderiyi paylaşmış - great_share: - name: Harika Paylaşım - description: 1000 tekil kullanıcı ile bir gönderiyi paylaşmış - first_like: - name: İlk beğeni - description: Bir gönderi beğendi - first_flag: - name: İlk Bayrak - description: Bir gönderiyi bayrakladı - promoter: - name: Destekçi - description: Kullanıcı davet etti - campaigner: - name: Katılanlar - description: 3 normal kullanıcı davet etti (Güven seviyesi 1) - champion: - name: Şampiyon - description: 5 kullanıcı davet etti (Güven seviyesi 2) - first_share: - name: İlk paylaşım - description: Bir gönderi paylaştı - first_link: - name: İlk bağlantı - description: Başka bir konuya iç bağlantı eklendi - first_quote: - name: İlk alıntı - description: Bir kullanıcıyı alıntıladı - read_guidelines: - name: Yönergeler okundu - description: Topluluk yönergelerini oku - reader: - name: Okuyucu - description: 100'den fazla gönderiye sahip bir konudaki tüm gönderileri oku - popular_link: - name: Gözde Bağlantı - description: En az 50 kere tıklanmış harici bir bağlantı gönderildi - hot_link: - name: Sıcak Bağlantı - description: En az 300 kere tıklanmış harici bir bağlantı gönderildi - famous_link: - name: Ünlü Bağlantı - description: En az 1000 kere tıklanmış harici bir bağlantı gönderildi google_search: |

    Google'la Ara

    diff --git a/config/locales/client.uk.yml b/config/locales/client.uk.yml index 1c30b782732..70a90f241c0 100644 --- a/config/locales/client.uk.yml +++ b/config/locales/client.uk.yml @@ -212,7 +212,6 @@ uk: members: "Учасники" posts: "Дописи" alias_levels: - title: "Хто може використовувати цю групу як аліас?" nobody: "Ніхто" only_admins: "Лише адміністратори" mods_and_admins: "Лише модератори та адміністратори" @@ -226,7 +225,6 @@ uk: '5': "Відповіді" '7': "Згадки" '9': "Цитати" - '10': "Позначені зірочкою" '11': "Редагування" '12': "Надіслані" '13': "Вхідні" @@ -277,9 +275,7 @@ uk: perm_default: "Ввімкнути сповіщення" perm_denied_btn: "Немає доступу" disable: "Вимкнути сповіщення" - currently_enabled: "(зараз увімкнено)" enable: "Увімкнути сповіщення" - currently_disabled: "(зараз вимкнено)" dismiss_notifications: "Позначити все як прочитане" dismiss_notifications_tooltip: "Позначити всі сповіщення як прочитані" disable_jump_reply: "Не перескакувати до мого допису коли я відповім" @@ -299,7 +295,6 @@ uk: watched_categories: "Відслідковувані" tracked_categories: "Відстежувані" muted_categories: "Ігноровані" - muted_categories_instructions: "Ви не будете отримувати жодних сповіщень про нові теми у цих категоріях, і вони не з'являтимуться у вкладці Непрочитані." delete_account: "Delete My Account" delete_account_confirm: "Are you sure you want to permanently delete your account? This action cannot be undone!" deleted_yourself: "Your account has been deleted successfully." @@ -314,8 +309,6 @@ uk: warnings_received: "попередження" messages: all: "Всі" - mine: "Мої" - unread: "Непрочитані" change_password: success: "(лист надіслано)" in_progress: "(надсилання листа)" @@ -396,7 +389,6 @@ uk: search: "шукати запрошення..." title: "Запрошення" user: "Запрошений користувач" - truncated: "Показано перші {{count}} запрошень." redeemed: "Прийняті запрошення" redeemed_at: "Прийнято" pending: "Запрошення, що очікують" @@ -466,7 +458,6 @@ uk: unmute: Unmute last_post: Останній допис summary: - description: "Тут {{count}} відповідей." enable: 'Підсумувати цю тему' disable: 'Показати всі дописи' deleted_filter: @@ -548,7 +539,6 @@ uk: edit_reason_placeholder: "чому Ви редагуєте допис?" show_edit_reason: "(додати причину редагування)" view_new_post: "Перегляньте свій новий допис." - saving: "Збереження..." saved: "Збережено!" uploading: "Завантаження..." show_preview: 'попередній перегляд »' @@ -573,8 +563,6 @@ uk: heading_title: "Заголовок" heading_text: "Заголовок" hr_title: "Горизонтальна лінія" - undo_title: "Скасувати" - redo_title: "Повернути" help: "Markdown Editing Help" toggler: "показати або сховати панель редагування" admin_options_title: "Необов'язкові налаштування персоналу для цієї теми" @@ -690,7 +678,6 @@ uk: title: "Ігнорувати" muted: title: "Ігнорувати" - description: "Ви ніколи не будете отримувати жодних сповіщень з цієї теми, і вона не буде відображатися у Вашій вкладці \"Непрочитані\"." actions: recover: "Відкликати видалення теми" delete: "Видалити тему" @@ -811,12 +798,6 @@ uk: bookmark: "Скасувати закладку" like: "Скасувати вподобання" vote: "Відкликати голос" - people: - notify_moderators: "Звернули увагу модераторів: {{icons}}" - notify_moderators_with_url: "Звернули увагу модераторів: {{icons}}" - bookmark: "Лишили тут закладку: {{icons}}" - like: "Вподобали це: {{icons}}" - vote: "Проголосували за це: {{icons}}" by_you: off_topic: "Ви поскаржилися на це як на недотичне до теми" spam: "Ви поскаржилися на це як на спам" @@ -825,9 +806,6 @@ uk: bookmark: "Ви лишили тут закладку" like: "Ви це вподобали" vote: "Ви проголосували за цей допис" - edits: - one: '{{count}} редагування' - other: "без редагувань" delete: confirm: one: "Ви впевнені, що хочете видалити цей допис?" @@ -889,8 +867,6 @@ uk: title: "Слідкувати" tracking: title: "Стежити" - regular: - title: "Звичайний" muted: title: "Ігноровані" flagging: @@ -946,28 +922,14 @@ uk: title: "Категорії" title_in: "Категорія - {{categoryName}}" help: "всі теми, згруповані за категоріями" - unread: - title: - one: "Непрочитані ({{count}})" - other: "Непрочитані" new: - lower_title_with_count: - one: "{{count}} new" lower_title: "new" - title: - zero: "Новий" - one: "Нові ({{count}})" - other: "Нові" posted: title: "Мої дописи" help: "теми, в які Ви дописували" bookmarks: title: "Закладки" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} ({{count}})" - other: "{{categoryName}}" help: "Останні теми в категорії {{categoryName}}" top: title: "Top" @@ -1109,10 +1071,8 @@ uk: restore: is_disabled: "Restore is disabled in the site settings." title: "Restore the backup" - confirm: "Are your sure you want to restore this backup?" rollback: title: "Rollback the database to previous working state" - confirm: "Are your sure you want to rollback the database to the previous working state?" customize: title: "Customize" long_title: "Site Customizations" @@ -1155,9 +1115,8 @@ uk: love: description: "Колір кнопки \"Подобається\"." email: - title: "Електронна пошта" settings: "Налаштування" - all: "All" + preview_digest: "Стислий виклад новин" sent: "Sent" skipped: "Skipped" sent_at: "Надіслано" @@ -1169,7 +1128,6 @@ uk: send_test: "Надіслати Тестовий Email" sent_test: "надіслано!" delivery_method: "Спосіб доставки" - preview_digest: "Стислий виклад новин" refresh: "Оновити" format: "Формат" html: "html" @@ -1334,7 +1292,6 @@ uk: trust_level_3_requirements: "Вимоги для Рівня довіри 3" tl3_requirements: title: "Вимоги для Рівня довіри 3" - table_title: "Протягом останніх 100 днів:" value_heading: "Значення" requirement_heading: "Вимога" visits: "Відвідини" @@ -1447,28 +1404,3 @@ uk: name: Спільнота other: name: Інше - badge: - editor: - name: Редактор - basic_user: - description: Надані всі основні функції спільноти - welcome: - name: Ласкаво просимо - autobiographer: - name: Автобіографіст - anniversary: - name: Річниця - nice_topic: - name: Непогана тема - good_topic: - name: Хороша тема - great_topic: - name: Чудова тема - first_link: - name: Перше посилання - first_quote: - name: Перша цитата - read_guidelines: - name: Читати інструкції - reader: - name: Читач diff --git a/config/locales/client.vi.yml b/config/locales/client.vi.yml new file mode 100644 index 00000000000..bc56262eae2 --- /dev/null +++ b/config/locales/client.vi.yml @@ -0,0 +1,2502 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +vi: + js: + number: + format: + separator: "." + delimiter: "," + human: + storage_units: + format: '%n %u' + units: + byte: + other: Byte + gb: GB + kb: KB + mb: MB + tb: TB + short: + thousands: "{{number}}k" + millions: "{{number}}M" + dates: + time: "h:mm a" + long_no_year: "MMM D h:mm a" + long_no_year_no_time: "MMM D" + full_no_year_no_time: "MMMM Do" + long_with_year: "MMM D, YYYY h:mm a" + long_with_year_no_time: "MMM D, YYYY" + full_with_year_no_time: "MMMM Do, YYYY" + long_date_with_year: "MMM D, 'YY LT" + long_date_without_year: "MMM D, LT" + long_date_with_year_without_time: "MMM D, 'YY" + long_date_without_year_with_linebreak: "MMM D
    LT" + long_date_with_year_with_linebreak: "MMM D, 'YY
    LT" + tiny: + half_a_minute: "< 1m" + less_than_x_seconds: + other: "< %{count}s" + x_seconds: + other: "%{count}s" + less_than_x_minutes: + other: "< %{count}m" + x_minutes: + other: "%{count}m" + about_x_hours: + other: "%{count}h" + x_days: + other: "%{count}d" + about_x_years: + other: "%{count}y" + over_x_years: + other: "> %{count}y" + almost_x_years: + other: "%{count}y" + date_month: "MMM D" + date_year: "MMM 'YY" + medium: + x_minutes: + other: "%{count} phút" + x_hours: + other: "%{count} giờ" + x_days: + other: "%{count} ngày" + date_year: "MMM D, 'YY" + medium_with_ago: + x_minutes: + other: " %{count} phút trước" + x_hours: + other: "%{count} giờ trước" + x_days: + other: "%{count} ngày trước" + later: + x_days: + other: "còn %{count} ngày" + x_months: + other: "còn %{count} tháng" + x_years: + other: "còn %{count} năm" + previous_month: 'Tháng Trước' + next_month: 'Tháng Sau' + share: + topic: 'chia sẽ chủ đề này' + post: 'đăng #%{Bài đăng số}' + close: 'đóng lại' + twitter: 'chia sẽ lên Twitter' + facebook: 'chia sẽ lên Facebook' + google+: 'chia sẽ lên Google+' + email: 'Gửi liên kết này qua thư điện tử' + action_codes: + split_topic: "chìa chủ đề này lúc %{when}" + invited_user: "đã mời bởi %{who} %{when}" + removed_user: "loại bỏ bởi %{who} %{when}" + autoclosed: + enabled: 'đóng lúc %{when}' + disabled: 'mở lúc %{when}' + closed: + enabled: 'đóng lúc %{when}' + disabled: 'mở lúc %{when}' + archived: + enabled: 'lưu trữ %{when}' + disabled: 'bỏ lưu trữ %{when}' + pinned: + enabled: 'gắn lúc %{when}' + disabled: 'bỏ gim %{when}' + pinned_globally: + enabled: 'đã gắn toàn trang %{when}' + disabled: 'đã bỏ gắn %{when}' + visible: + enabled: 'đã lưu %{when}' + disabled: 'bỏ lưu %{when}' + topic_admin_menu: "quản lí chủ đề." + emails_are_disabled: "Ban quản trị đã chặn mọi email đang gửi. Sẽ không có bắt kỳ thông báo nào về email được gửi đi." + s3: + regions: + us_east_1: "US East (N. Virginia)" + us_west_1: "US West (N. California)" + us_west_2: "US West (Oregon)" + us_gov_west_1: "AWS GovCloud (US)" + eu_west_1: "EU (Ireland)" + eu_central_1: "EU (Frankfurt)" + ap_southeast_1: "Asia Pacific (Singapore)" + ap_southeast_2: "Asia Pacific (Sydney)" + ap_northeast_1: "Asia Pacific (Tokyo)" + ap_northeast_2: "Asia Pacific (Seoul)" + sa_east_1: "South America (Sao Paulo)" + edit: 'thay đổi tiêu đề và chuyên mục của chủ đề' + not_implemented: "Tính năng này chưa được hoàn thiện hết, xin lỗi!" + no_value: "Không" + yes_value: "Có" + generic_error: "Rất tiếc, đã có lỗi xảy ra." + generic_error_with_reason: "Đã xảy ra lỗi: %{error}" + sign_up: "Đăng ký" + log_in: "Đăng nhập" + age: "Độ tuổi" + joined: "Đã tham gia" + admin_title: "Quản trị" + flags_title: "Báo cáo" + show_more: "hiện thêm" + show_help: "lựa chọn" + links: "Liên kết" + links_lowercase: + other: "liên kết" + faq: "FAQ" + guidelines: "Hướng dẫn" + privacy_policy: "Chính sách riêng tư" + privacy: "Sự riêng tư" + terms_of_service: "Điều khoản dịch vụ" + mobile_view: "Xem ở chế độ di động" + desktop_view: "Xem ở chế độ máy tính" + you: "Bạn" + or: "hoặc" + now: "ngay lúc này" + read_more: 'đọc thêm' + more: "Nhiều hơn" + less: "Ít hơn" + never: "không bao giờ" + daily: "hàng ngày" + weekly: "hàng tuần" + every_two_weeks: "mỗi hai tuần" + every_three_days: "ba ngày một" + max_of_count: "tối đa của {{count}}" + alternation: "hoặc" + character_count: + other: "{{count}} ký tự" + suggested_topics: + title: "Chủ đề tương tự" + pm_title: "Tin nhắn gợi ý" + about: + simple_title: "Giới thiệu" + title: "Giới thiệu về %{title}" + stats: "Thống kê của trang" + our_admins: "Các quản trị viên" + our_moderators: "Các điều hành viên" + stat: + all_time: "Từ trước tới nay" + last_7_days: "7 ngày qua" + last_30_days: "30 ngày vừa qua" + like_count: "Lượt thích" + topic_count: "Các chủ đề" + post_count: "Các bài viết" + user_count: "Thành viên mới" + active_user_count: "Thành viên tích cực" + contact: "Contact Us" + contact_info: "Trong trường hợp có bất kỳ sự cố nào ảnh hưởng tới trang này, xin vui lòng liên hệ với chúng tôi theo địa chỉ %{contact_info}." + bookmarked: + title: "Bookmark" + clear_bookmarks: "Clear Bookmarks" + help: + bookmark: "Chọn bài viết đầu tiên của chủ đề cho vào bookmark" + unbookmark: "Chọn để xoá toàn bộ bookmark trong chủ đề này" + bookmarks: + not_logged_in: "rất tiếc, bạn phải đăng nhập để có thể đánh dấu bài viết" + created: "bạn đã đánh dấu bài viết này" + not_bookmarked: "bạn đã đọc bài viết này; nhấp chuột để đánh dấu" + last_read: "đây là bài viết cuối cùng bạn đã đọc; nhấp chuột để đánh dấu" + remove: "Xóa đánh dấu" + confirm_clear: "Bạn có chắc muốn xóa tất cả đánh dấu ở topic này?" + topic_count_latest: + other: "{{count}} chủ đề mới hoặc đã cập nhật." + topic_count_unread: + other: "{{count}} chủ đề chưa đọc." + topic_count_new: + other: "{{count}} chủ đề mới." + click_to_show: "Nhấp chuột để hiển thị." + preview: "xem trước" + cancel: "hủy" + save: "Lưu thay đổi" + saving: "Đang lưu ..." + saved: "Đã lưu!" + upload: "Tải lên" + uploading: "Đang tải lên..." + uploading_filename: "Đang tải lên {{filename}}..." + uploaded: "Đã tải lên!" + enable: "Kích hoạt" + disable: "Vô hiệu hóa" + undo: "Hoàn tác" + revert: "Phục hồi" + failed: "Thất bại" + switch_to_anon: "Chế độ Ẩn danh" + switch_from_anon: "Thoát ẩn danh" + banner: + close: "Xóa biểu ngữ này." + edit: "Sửa banner này >>" + choose_topic: + none_found: "Không tìm thấy chủ đề nào" + title: + search: "Tìm kiếm chủ đề dựa vào tên, url hoặc id:" + placeholder: "viết tiêu đề của chủ đề thảo luận ở đây" + queue: + topic: "Chủ đề" + approve: 'Phê duyệt' + reject: 'Từ chối' + delete_user: 'Xóa tài khoản' + title: "Cần phê duyệt" + none: "Không có bài viết nào để xem trước" + edit: "Sửa" + cancel: "Hủy" + view_pending: "xem bài viết đang chờ xử lý" + has_pending_posts: + other: "Chủ đề này có {{count}} bài viết cần phê chuẩn" + confirm: "Lưu thay đổi" + approval: + title: "Bài viết cần phê duyệt" + description: "Chúng tôi đã nhận được bài viết mới của bạn, nhưng nó cần phải được phê duyệt bởi admin trước khi được hiện. Xin hãy kiên nhẫn." + pending_posts: + other: "Bạn có {{count}} bài viết đang chờ xử lý." + ok: "OK" + user_action: + user_posted_topic: "{{user}} đăng chủ đề" + you_posted_topic: "Bạn đã đăng chủ đề" + user_replied_to_post: "{{user}} đã trả lời tới {{post_number}}" + you_replied_to_post: "Bạn đã trả lời tới {{post_number}}" + user_replied_to_topic: "{{user}} đã trả lời chủ đề" + you_replied_to_topic: "Bạn đã trả lời tới chủ đề" + user_mentioned_user: "{{user}} đã nhắc đến {{another_user}}" + user_mentioned_you: "{{user}} đã nhắc tới bạn" + you_mentioned_user: "Bạn đã đề cập {{another_user}}" + posted_by_user: "Được đăng bởi {{user}}" + posted_by_you: "Được đăng bởi bạn" + sent_by_user: "Đã gửi bởi {{user}}" + sent_by_you: "Đã gửi bởi bạn" + directory: + filter_name: "lọc theo tên đăng nhập" + title: "Thành viên" + likes_given: "Đưa ra" + likes_received: "Đã nhận" + topics_entered: "Được nhập" + topics_entered_long: "Chủ đề được nhập" + time_read: "Thời gian đọc" + topic_count: "Chủ đề" + topic_count_long: "Chủ đề đã được tạo" + post_count: "Trả lời" + post_count_long: "Trả lời đã được đăng" + no_results: "Không tìm thấy kết quả." + days_visited: "Ghé thăm" + days_visited_long: "Ngày đã ghé thăm" + posts_read: "Đọc" + posts_read_long: "Đọc bài viết" + total_rows: + other: "%{count} người dùng" + groups: + empty: + posts: "Không có chủ đề của các thành viên trong nhóm" + members: "Không có thành viên nào trong nhóm" + mentions: "Không có thành viên nào trong nhóm" + messages: "Không có tin nhắn nào trong nhóm" + topics: "Không có chủ đề của các thành viên trong nhóm" + add: "Thêm" + selector_placeholder: "Thêm thành viên" + owner: "chủ" + visible: "Mọi thành viên có thể nhìn thấy nhóm" + title: + other: "các nhóm" + members: "Các thành viên" + posts: "Các bài viết" + alias_levels: + title: "Ai có thể nhắn tin và @mention trong nhóm này?" + nobody: "Không ai cả" + only_admins: "Chỉ các quản trị viên" + mods_and_admins: "Chỉ có người điều hành và ban quản trị" + members_mods_and_admins: "Chỉ có thành viên trong nhóm, ban điều hành, và ban quản trị" + everyone: "Mọi người" + trust_levels: + title: "Cấp độ tin tưởng tự động tăng cho thành viên khi họ thêm:" + none: "Không có gì" + notifications: + watching: + title: "Đang xem" + description: "Bạn sẽ được thông báo khi có bài viết mới trong mỗi tin nhắn, và số lượng trả lời mới sẽ được hiển thị" + tracking: + title: "Đang theo dõi" + description: "Bạn sẽ được thông báo nếu ai đó đề cập đến @tên bạn hoặc trả lời bạn, và số lượng trả lời mới sẽ được hiển thị" + regular: + title: "Bình thường" + description: "Bạn sẽ được thông báo nếu ai đó đề cập đến @tên bạn hoặc trả lời bạn" + muted: + title: "Im lặng" + description: "Bạn sẽ không bao giờ được thông báo về bất cứ chủ đề mới nào trong nhóm này" + user_action_groups: + '1': "Lần thích" + '2': "Lần được thích" + '3': "Chỉ mục" + '4': "Các chủ đề" + '5': "Trả lời" + '6': "Phản hồi" + '7': "Được nhắc đến" + '9': "Lời trích dẫn" + '11': "Biên tập" + '12': "Bài đã gửi" + '13': "Hộp thư" + '14': "Đang chờ xử lý" + categories: + all: "tất cả chuyên mục" + all_subcategories: "Tất cả" + no_subcategory: "không có gì" + category: "Chuyên mục" + category_list: "Hiễn thị danh sách chuyên mục" + reorder: + title: "Sắp xếp lại danh mục" + title_long: "Tổ chức lại danh sách danh mục" + fix_order: "Vị trí cố định" + fix_order_tooltip: "Không phải tất cả danh mục có vị trí duy nhất, điều này có thể dẫn đến kết quả không mong muốn." + save: "Lưu thứ tự" + apply_all: "Áp dụng" + position: "Vị trí" + posts: "Bài viết" + topics: "Chủ đề" + latest: "Mới nhất" + latest_by: "mới nhất bởi" + toggle_ordering: "chuyển lệnh kiểm soát" + subcategories: "Phân loại phụ" + topic_stats: "Số lượng chủ đề mới" + topic_stat_sentence: + other: "%{count} số lượng chủ đề mới tỏng quá khứ %{unit}." + post_stats: "Số lượng bài viết mới" + post_stat_sentence: + other: "%{count} số lượng bài viết mới trong quá khứ %{unit}." + ip_lookup: + title: Tìm kiếm địa chỉ IP + hostname: Hostname + location: Vị trí + location_not_found: (không biết) + organisation: Công ty + phone: Điện thoại + other_accounts: "Tài khoản khác với địa chỉ IP này" + delete_other_accounts: "Xoá %{count}" + username: "tên đăng nhập" + trust_level: "TL" + read_time: "thời gian đọc" + topics_entered: "chủ để đã xem" + post_count: "# bài viết" + confirm_delete_other_accounts: "Bạn có muốn xóa những tài khoản này không?" + user_fields: + none: "(chọn một tùy chọn)" + user: + said: "{{username}}:" + profile: "Tiểu sử" + mute: "Im lặng" + edit: "Tùy chỉnh" + download_archive: "Tải bài viết về" + new_private_message: "Tin nhắn mới" + private_message: "Tin nhắn" + private_messages: "Các tin nhắn" + activity_stream: "Hoạt động" + preferences: "Tùy chỉnh" + expand_profile: "Mở" + bookmarks: "Theo dõi" + bio: "Về tôi" + invited_by: "Được mời bởi" + trust_level: "Độ tin tưởng" + notifications: "Thông báo" + statistics: "Thống kê" + desktop_notifications: + label: "Desktop Notifications" + not_supported: "Xin lỗi. Trình duyệt của bạn không hỗ trợ Notification." + perm_default: "Mở thông báo" + perm_denied_btn: "Không có quyền" + perm_denied_expl: "Bạn đã từ chối nhận thông báo, để nhận lại bạn cần thiết lập trình duyệt." + disable: "Khóa Notification" + enable: "Cho phép Notification" + each_browser_note: "Lưu ý: Bạn phải thay đổi trong cấu hình mỗi trình duyệt bạn sử dụng." + dismiss_notifications: "Đánh dấu đã đọc cho tất cả" + dismiss_notifications_tooltip: "Đánh dấu đã đọc cho tất cả các thông báo chưa đọc" + disable_jump_reply: "Đừng tới bài viết của tôi sau khi tôi trả lời" + dynamic_favicon: "Hiện số chủ đề mới / cập nhật vào biểu tượng trình duyệt" + edit_history_public: "Để thành viên khác xem những sửa chữa bài viết của bạn" + external_links_in_new_tab: "Mở tất cả liên kết bên ngoài trong thẻ mới" + enable_quoting: "Bật chế độ làm nổi bật chữ trong đoạn trích dẫn trả lời" + change: "thay đổi" + moderator: "{{user}} trong ban quản trị" + admin: "{{user}} là người điều hành" + moderator_tooltip: "Thành viên này là MOD" + admin_tooltip: "Thành viên này là admin" + blocked_tooltip: "Tài khoản này bị khóa" + suspended_notice: "Thành viên này bị đình chỉ cho đến ngày {{date}}. " + suspended_reason: "Lý do: " + github_profile: "Github" + mailing_list_mode: "Gửi email cho tôi mỗi bài viết mới (trừ khi tôi tắt chủ đề hoặc chuyên mục)" + watched_categories: "Xem" + watched_categories_instructions: "Bạn sẽ tự động xem tất cả các chủ đề mới trong các chuyên mục này. Bạn sẽ được thông báo về tất các các bài viết mới, và một số các bài viết mới cũng sẽ xuất hiện ở chủ đề kế tiếp." + tracked_categories: "Theo dõi" + tracked_categories_instructions: "Bạn sẽ tự động theo dõi tất cả các chủ đề trong các chuyên mục này. Một số bài viết mới sẽ xuất hiện ở chủ đề kế tiếp." + muted_categories: "Im lặng" + muted_categories_instructions: "Bạn sẽ không bao giờ được thông báo về bất cứ điều gì về các chủ đề mới trong các chuyên mục này, và chúng sẽ không hiển thị mới nhất" + delete_account: "Xoá Tài khoản của tôi" + delete_account_confirm: "Bạn có chắc chắn muốn xóa vĩnh viễn tài khoản của bạn? Hành động này không thể được hoàn tác!" + deleted_yourself: "Tài khoản của bạn đã được xóa thành công." + delete_yourself_not_allowed: "Bạn không thể xóa tài khoản của bạn ngay bây giờ. Liên lạc với admin để làm xóa tài khoản cho bạn." + unread_message_count: "Tin nhắn" + admin_delete: "Xoá" + users: "Thành viên" + muted_users: "Im lặng" + muted_users_instructions: "Ngăn chặn tất cả các thông báo từ những thành viên." + muted_topics_link: "Hiển thị chủ đề Im Lặng" + staff_counters: + flags_given: "cờ hữu ích" + flagged_posts: "bài viết gắn cờ" + deleted_posts: "bài viết bị xoá" + suspensions: "đình chỉ" + warnings_received: "cảnh báo" + messages: + all: "Tất cả" + inbox: "Hộp thư" + sent: "Đã gửi" + archive: "Lưu Trữ" + groups: "Nhóm của tôi" + bulk_select: "Chọn tin nhắn" + move_to_inbox: "Chuyển sang hộp thư" + move_to_archive: "Lưu trữ" + failed_to_move: "Lỗi khi chuyển các tin nhắn đã chọn (có thể do lỗi mạng)" + select_all: "Chọn tất cả" + change_password: + success: "(email đã gửi)" + in_progress: "(đang gửi email)" + error: "(lỗi)" + action: "Gửi lại mật khẩu tới email" + set_password: "Nhập Mật khẩu" + change_about: + title: "Thay đổi thông tin về tôi" + error: "Có lỗi khi thay đổi giá trị này." + change_username: + title: "Thay Username" + confirm: "Nếu bạn thay đổi tên đăng nhập, tất cả những câu nói của bạn ở bài viết trước và @tên bạn sẽ được đề cập sẽ bị phá vỡ. Bạn có chắc bạn muốn tiếp tục không?" + taken: "Xin lỗi, đã có username này." + error: "Có lỗi trong khi thay đổi username của bạn." + invalid: "Username này không thích hợp. Nó chỉ chứa các ký tự là chữ cái và chữ số. " + change_email: + title: "Thay đổi Email" + taken: "Xin lỗi, email này không dùng được. " + error: "Có lỗi xảy ra khi thay đổi email của bạn. Có thể địa chỉ email đã được sử dụng ?" + success: "Chúng tôi đã gửi email tới địa chỉ đó. Vui lòng làm theo chỉ dẫn để xác nhận lại." + change_avatar: + title: "Đổi ảnh đại diện" + gravatar: "dựa trên Gravatar" + gravatar_title: "Đổi ảnh đại diện của bạn trên website Gravatar" + refresh_gravatar_title: "Làm mới Gravatar của bạn" + letter_based: "Hệ thống xác định ảnh đại diện" + uploaded_avatar: "Chính sửa hình ảnh" + uploaded_avatar_empty: "Thêm một ảnh chỉnh sửa" + upload_title: "Upload hình ảnh của bạn" + upload_picture: "Úp hình" + image_is_not_a_square: "Cảnh báo: chúng tôi đã cắt hình ảnh của bạn; chiều rộng và chiều cao không bằng nhau." + cache_notice: "Hình hồ sở của bạn đã thay đổi thành công nhưng có thể thỉnh thoảng xuất hiện ảnh cũ bởi cache của trình duyệt." + change_profile_background: + title: "Hình nền trang hồ sơ" + instructions: "Hình nền trang hồ sơ sẽ ở giữa và có chiều rộng mặc định là 850px." + change_card_background: + title: "Hình nền Card" + instructions: "Hình nền sẽ ở giữa và có chiều rộng mặc định là 590px." + email: + title: "Email" + instructions: "Không bao giờ công khai" + ok: "Chúng tôi sẽ gửi thư điện tử xác nhận đến cho bạn" + invalid: "Vùi lòng nhập một thư điện tử hợp lệ" + authenticated: "Thư điện tử của bạn đã được xác nhận bởi {{provider}}" + frequency_immediately: "Chúng tôi sẽ gửi email cho bạn ngay lập tức nếu bạn đã chưa đọc những điều chúng tôi đã gửi cho bạn qua email." + frequency: + other: "Chúng tôi sẽ chỉ gửi email cho bạn nếu chúng tôi đã không nhìn thấy bạn trong {{count}} phút cuối." + name: + title: "Tên" + instructions: "Tên đầy đủ của bạn (tùy chọn)" + instructions_required: "Tên đầy đủ của bạn" + too_short: "Tên của bạn quá ngắn" + ok: "Tên của bạn có vẻ ổn" + username: + title: "Username" + instructions: "Duy nhất, không khoảng trắng" + short_instructions: "Mọi người có thể nhắc tới bạn bằng @{{username}}" + available: "Tên đăng nhập của bạn có sẵn" + global_match: "Email đúng với username đã được đăng ký" + global_mismatch: "Đã đăng ký rồi. Thử {{suggestion}}?" + not_available: "Chưa có sẵn. Thử {{suggestion}}?" + too_short: "Tên đăng nhập của bạn quá ngắn" + too_long: "Tên đăng nhập của bạn quá dài" + checking: "Đang kiểm tra username sẵn sàng để sử dụng...." + enter_email: 'Đã tìm được tên đăng nhập. Điền thư điện tử phù hợp.' + prefilled: "Thư điện tử trủng với tên đăng nhập này." + locale: + title: "Ngôn ngữ hiển thị" + instructions: "Ngôn ngữ hiển thị sẽ thay đổi khi bạn tải lại trang" + default: "(mặc định)" + password_confirmation: + title: "Nhập lại Password" + last_posted: "Bài viết cuối cùng" + last_emailed: "Đã email lần cuối" + last_seen: "được thấy" + created: "Đã tham gia" + log_out: "Log Out" + location: "Vị trí" + card_badge: + title: "Huy hiệu của thẻ thành viên" + website: "Web Site" + email_settings: "Email" + email_digests: + title: "Khi tôi không truy cập, gửi email gợi ý những cái mới cho tôi:" + daily: "hàng ngày" + every_three_days: "ba ngày một" + weekly: "hàng tuần" + every_two_weeks: "hai tuần một" + email_direct: "Gửi cho tôi một email khi có người trích dẫn, trả lời cho bài viết của tôi, đề cập đến @username của tôi, hoặc mời tôi đến một chủ đề" + email_private_messages: "Gửi cho tôi email khi có ai đó nhắn tin cho tôi" + email_always: "Gửi email thông báo cho tôi mỗi khi tôi kích hoạt trên website này" + other_settings: "Khác" + categories_settings: "Chuyên mục" + new_topic_duration: + label: "Để ý tới chủ đề mới khi" + not_viewed: "Tôi chưa từng xem họ" + last_here: "tạo ra kể từ lần cuối tôi ở đây" + after_1_day: "được tạo ngày hôm qua" + after_2_days: "được tạo 2 ngày trước" + after_1_week: "được tạo tuần trước" + after_2_weeks: "được tạo 2 tuần trước" + auto_track_topics: "Tự động theo dõi các chủ đề tôi tạo" + auto_track_options: + never: "không bao giờ" + immediately: "ngay lập tức" + after_30_seconds: "sau 30 giây" + after_1_minute: "sau 1 phút" + after_2_minutes: "sau 2 phút" + after_3_minutes: "sau 3 phút" + after_4_minutes: "sau 4 phút" + after_5_minutes: "sau 5 phút" + after_10_minutes: "sau 10 phút" + invited: + search: "gõ để tìm kiếm thư mời " + title: "Lời mời" + user: "User được mời" + sent: "Đã gửi" + none: "Không có thư mời nào đang chờ để hiển thị" + truncated: + other: "Hiện {{count}} thư mời đầu tiên" + redeemed: "Lời mời bù lại" + redeemed_tab: "Làm lại" + redeemed_tab_with_count: "Làm lại ({{count}})" + redeemed_at: "Nhận giải" + pending: "Lời mời tạm hoãn" + pending_tab: "Đang treo" + pending_tab_with_count: "Đang xử lý ({{count}})" + topics_entered: "Bài viết được xem " + posts_read_count: "Đọc bài viết" + expired: "Thư mời này đã hết hạn." + rescind: "Xoá" + rescinded: "Lời mời bị xóa" + reinvite: "Mời lại" + reinvited: "Gửi lại lời mời" + time_read: "Đọc thời gian" + days_visited: "Số ngày đã thăm" + account_age_days: "Thời gian của tài khoản theo ngày" + create: "Gửi một lời mời" + generate_link: "Chép liên kết Mời" + generated_link_message: '

    Liên kết thư mời được tạo thành công!

    Liên kết thư mời chỉ hợp lệ cho email này: %{invitedEmail}

    ' + bulk_invite: + none: "Bạn đã mời ai ở đây chưa. Bạn có thể mời một hoặc một nhóm bằng tải lên hàng loạt file mời." + text: "Mời hàng loạt bằng file" + uploading: "Uploading..." + success: "Tải lên thành công, bạn sẽ được thông báo qua tin nhắn khi quá trình hoàn tất." + error: "Có lỗi xảy ra khi upload '{{filename}}': {{message}}" + password: + title: "Mật khẩu" + too_short: "Mật khẩu của bạn quá ngắn." + common: "Mật khẩu quá đơn giản, rất dễ bị đoán ra" + same_as_username: "Mật khẩu của bạn trùng với tên đăng nhập." + same_as_email: "Mật khẩu của bạn trùng với email của bạn." + ok: "Mật khẩu của bạn có vẻ ổn." + instructions: "Ít nhất %{count} ký tự" + summary: + title: "Tóm tắt" + stats: "Thống kê" + top_replies: "Top trả lời" + more_replies: "Thêm trả lời" + top_topics: "Top chủ đề" + more_topics: "Thêm chủ đề" + top_badges: "Top huy hiệu" + more_badges: "Thêm huy hiệu" + associated_accounts: "Đăng nhập" + ip_address: + title: "Địa chỉ IP cuối cùng" + registration_ip_address: + title: "Địa chỉ IP đăng ký" + avatar: + title: "Ảnh đại diện" + header_title: "hồ sơ cá nhân, tin nhắn, đánh dấu và sở thích" + title: + title: "Tiêu đề" + filters: + all: "All" + stream: + posted_by: "Đăng bởi" + sent_by: "Gửi bởi" + private_message: "tin nhắn" + the_topic: "chủ đề" + loading: "Đang tải..." + errors: + prev_page: "trong khi cố gắng để tải" + reasons: + network: "Mạng Internet bị lỗi" + server: "Máy chủ đang có vấn đề" + forbidden: "Bạn không thể xem được" + unknown: "Lỗi" + not_found: "Không Tìm Thấy Trang" + desc: + network: "Hãy kiểm tra kết nối của bạn" + network_fixed: "Hình như nó trở lại." + server: "Mã lỗi : {{status}}" + forbidden: "Bạn không được cho phép để xem mục này" + not_found: "Oops, ứng dụng đang tải đường dẫn không tồn tại" + unknown: "Có một lỗi gì đó đang xảy ra" + buttons: + back: "Quay trở lại" + again: "Thử lại" + fixed: "Load lại trang" + close: "Đóng lại" + assets_changed_confirm: "Website đã được cập nhật bản mới. Bạn có thể làm mới lại trang để có thể sử dụng bản mới được cập nhật" + logout: "Bạn đã đăng xuất" + refresh: "Tải lại" + read_only_mode: + enabled: "Website đang ở chế độ chỉ đọc, bạn có thể duyệt xem nhưng không thể trả lời, likes, hay thực hiện các hành động khác." + login_disabled: "Chức năng Đăng nhập đã bị tắt khi website trong trạng thái chỉ đọc" + too_few_topics_and_posts_notice: "Hãy bắt đầu thảo luận! Hiện có %{currentTopics} / %{requiredTopics} chủ đề và %{currentPosts} / %{requiredPosts} bài viết. Khách ghé thăm cần một số chủ đề để đọc và trả lời." + too_few_topics_notice: "Hãy bắt đầu thảo luận! Hiện có %{currentTopics} / %{requiredTopics} chủ đề. Khách ghé thăm cần một số chủ đề để đọc và trả lời." + too_few_posts_notice: "Hãy bắt đầu thảo luận! Hiện có %{currentPosts} / %{requiredPosts} bài viết. Khách ghé thăm cần một số chủ đề để đọc và trả lời." + learn_more: "tìm hiểu thêm..." + year: 'năm' + year_desc: 'chủ đề được tạo ra trong 365 ngày qua' + month: 'tháng' + month_desc: 'chủ đề được tạo ra trong 30 ngày qua' + week: 'tuần' + week_desc: 'chủ đề được tạo ra trong 7 ngày qua' + day: 'ngày' + first_post: Bài viết đầu tiên + mute: Im lặng + unmute: Bỏ im lặng + last_post: Bài viết cuối cùng + last_reply_lowercase: trả lời cuối cùng + replies_lowercase: + other: trả lời + signup_cta: + sign_up: "Đăng ký" + hide_session: "Nhắc vào ngày mai" + hide_forever: "không, cảm ơn" + hidden_for_session: "OK, Tôi sẽ hỏi bạn vào ngày mai. Bạn có thể luôn luôn sử dụng chức năng đăng nhập để tạo tài khoản." + intro: "Xin chào! :heart_eyes: Có vẻ như bạn đang thích thú để thảo luận, nhưng bạn chưa đăng nhập." + value_prop: "Khi bạn tạo tài khoản, website nhớ chính xác những gì bạn đã đọc, vì vậy bạn sẽ luôn trở lại đúng nơi đã rời đi. Bạn cũng có thể nhận thông báo ở đây hoặc qua email mỗi khi có bài viết mới. Bạn cũng có thể like bài viết để chia sẻ cảm xúc của mình. :heartbeat:" + summary: + enabled_description: "Bạn đang xem một bản tóm tắt của chủ đề này: các bài viết thú vị nhất được xác định bởi cộng đồng." + enable: 'Tóm tắt lại chủ đề' + disable: 'HIển thị tất cả các bài viết' + deleted_filter: + enabled_description: "Chủ để này có chứa các bài viết bị xoá, chúng đã bị ẩn đi" + disabled_description: "Xoá các bài viết trong các chủ để được hiển thị" + enable: "Ẩn các bài viết bị xoá" + disable: "Xem các bài viết bị xoá" + private_message_info: + title: "Tin nhắn" + invite: "Mời người khác..." + remove_allowed_user: "Bạn thực sự muốn xóa {{name}} từ tin nhắn này?" + email: 'Email' + username: 'Username' + last_seen: 'Đã xem' + created: 'Tạo bởi' + created_lowercase: 'ngày tạo' + trust_level: 'Độ tin tưởng' + search_hint: 'username, email or IP address' + create_account: + title: "Tạo tài khoản mới" + failed: "Có gì đó không đúng, có thể email này đã được đăng ký, thử liên kết quên mật khẩu" + forgot_password: + title: "Đặt lại mật khẩu" + action: "Tôi đã quên mật khẩu của tôi" + invite: "Điền vào username của bạn hoặc địa chỉ email và chúng tôi sẽ gửi bạn email để khởi tạo lại mật khẩu" + reset: "Tạo lại mật khẩu" + complete_username: "Nếu một tài khoản phù hợp với tên thành viên % {username} , bạn sẽ nhận được một email với hướng dẫn về cách đặt lại mật khẩu của bạn trong thời gian ngắn." + complete_email: "Nếu một trận đấu tài khoản % {email} , bạn sẽ nhận được một email với hướng dẫn về cách đặt lại mật khẩu của bạn trong thời gian ngắn." + complete_username_found: "Chúng tôi tìm thấy một tài khoản phù hợp với tên thành viên % {username} , bạn sẽ nhận được một email với hướng dẫn về cách đặt lại mật khẩu của bạn trong thời gian ngắn." + complete_email_found: "Chúng tôi tìm thấy một tài khoản phù hợp với % {email} , bạn sẽ nhận được một email với hướng dẫn về cách đặt lại mật khẩu của bạn trong thời gian ngắn." + complete_username_not_found: "Không có tài khoản phù hợp với tên thành viên % {username} " + complete_email_not_found: "Không tìm thấy tài khoản nào tương ứng với %{email}" + login: + title: "Đăng nhập" + username: "Thành viên" + password: "Mật khẩu" + email_placeholder: "Email hoặc tên đăng nhập " + caps_lock_warning: "Phím Caps Lock đang được bật" + error: "Không xác định được lỗi" + rate_limit: "Xin đợi trước khi đăng nhập lại lần nữa." + blank_username_or_password: "Bạn phải nhập email hoặc username, và mật khẩu" + reset_password: 'Khởi tạo mật khẩu' + logging_in: "Đăng nhập..." + or: "Hoặc" + authenticating: "Đang xác thực..." + awaiting_confirmation: "Tài khoản của bạn đang đợi kích hoạt, sử dụng liên kết quên mật khẩu trong trường hợp kích hoạt ở 1 email khác." + awaiting_approval: "Tài khoản của bạn chưa được chấp nhận bới thành viên. Bạn sẽ được gửi một email khi được chấp thuận " + requires_invite: "Xin lỗi, bạn phải được mời để tham gia diễn đàn" + not_activated: "Bạn không thể đăng nhập. Chúng tôi đã gửi trước email kích hoạt cho bạn tại {{sentTo}}. Vui lòng làm theo hướng dẫn trong email để kích hoạt tài khoản của bạn." + not_allowed_from_ip_address: "Bạn không thể đăng nhập từ địa chỉ IP này" + admin_not_allowed_from_ip_address: "Bạn không thể đăng nhập với quyền quản trị từ địa chỉ IP đó." + resend_activation_email: "Bấm đây để gửi lại email kích hoạt" + sent_activation_email_again: "Chúng tôi gửi email kích hoạt tới cho bạn ở {{currentEmail}}. Nó sẽ mất vài phút để đến; bạn nhớ check cả hồm thư spam nhe. " + to_continue: "Vui lòng đăng nhập" + preferences: "Bạn cần phải đăng nhập để thay đổi cài đặt tài khoản." + forgot: "Tôi không thể nhớ lại chi tiết tài khoản của tôi." + google: + title: "với Google " + message: "Chứng thực với Google (Bạn hãy chắc chắn là chặn popup không bật)" + google_oauth2: + title: "với Google" + message: "Chứng thực với Google (chắc chắn rằng cửa sổ pop up blocker không được kích hoạt)" + twitter: + title: "với Twitter" + message: "Chứng thực với Twitter(hãy chắc chắn là chăn pop up không bật)" + facebook: + title: "với Facebook" + message: "Chứng thực với Facebook(chắc chắn là chặn pop up không bật)" + yahoo: + title: "với Yahoo" + message: "Chứng thực với Yahoo (Chắc chắn chặn pop up không bật)" + github: + title: "với GitHub" + message: "Chứng thực với GitHub (chắc chắn chặn popup không bật)" + apple_international: "Apple/International" + google: "Google" + twitter: "Twitter" + emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' + composer: + emoji: "Emoji :)" + more_emoji: "thêm..." + options: "Lựa chọn" + whisper: "nói chuyện" + add_warning: "Đây là một cảnh báo chính thức" + toggle_whisper: "Chuyển chế độ Nói chuyện" + posting_not_on_topic: "Bài viết nào bạn muốn trả lời " + saving_draft_tip: "đang lưu..." + saved_draft_tip: "Đã lưu" + saved_local_draft_tip: "Đã lưu locally" + similar_topics: "Bài viết của bạn tương tự với " + drafts_offline: "Nháp offline" + group_mentioned: "Bằng cách sử dụng {{group}}, bạn có thể thông báo tới {{count}} người." + error: + title_missing: "Tiêu đề là bắt buộc" + title_too_short: "Tiêu để phải có ít nhất {{min}} ký tự" + title_too_long: "Tiêu đề có tối đa {{max}} ký tự" + post_missing: "Bài viết không được bỏ trắng" + post_length: "Bài viết phải có ít nhất {{min}} ký tự" + try_like: 'Các bạn đã thử các nút ?' + category_missing: "Bạn phải chọn một phân loại" + save_edit: "Lưu chỉnh sửa" + reply_original: "Trả lời cho bài viết gốc" + reply_here: "Trả lời đây " + reply: "Trả lời " + cancel: "Huỷ" + create_topic: "Tạo chủ đề" + create_pm: "Tin nhắn" + title: "Hoặc nhất Ctrl+Enter" + users_placeholder: "Thêm thành viên " + title_placeholder: "Tóm tắt lại thảo luận này trong một câu ngắn gọn" + edit_reason_placeholder: "Tại sao bạn sửa" + show_edit_reason: "(thêm lý do sửa)" + reply_placeholder: "Gõ ở đây. Sử dụng Markdown, BBCode, hoặc HTML để định dạng. Kéo hoặc dán ảnh." + view_new_post: "Xem bài đăng mới của bạn. " + saving: "Đang lưu" + saved: "Đã lưu" + saved_draft: "Bài nháp đang lưu. Chọn để tiếp tục." + uploading: "Đang đăng " + show_preview: 'Xem trước »' + hide_preview: '«ẩn xem trước' + quote_post_title: "Trích dẫn cả bài viết" + bold_title: "In đậm" + bold_text: "chữ in đậm" + italic_title: "Nhấn mạnh" + italic_text: "văn bản nhấn mạnh" + link_title: "Liên kết" + link_description: "Nhập mô tả liên kết ở đây" + link_dialog_title: "Chèn liên kết" + link_optional_text: "tiêu đề tùy chọn" + link_placeholder: "http://example.com \"chữ tuỳ chọn\"" + quote_title: "Trích dẫn" + quote_text: "Trích dẫn" + code_title: "Văn bản định dạng trước" + code_text: "lùi đầu dòng bằng 4 dấu cách" + upload_title: "Tải lên" + upload_description: "Nhập mô tả tải lên ở đây" + olist_title: "Danh sách kiểu số" + ulist_title: "Danh sách kiểu ký hiệu" + list_item: "Danh sách các mục" + heading_title: "Tiêu đề" + heading_text: "Tiêu đề" + hr_title: "Căn ngang" + help: "Trợ giúp soạn thảo bằng Markdown" + toggler: "ẩn hoặc hiển thị bảng điều khiển soạn thảo" + modal_ok: "OK" + modal_cancel: "Hủy" + cant_send_pm: "Xin lỗi, bạn không thể gởi tin nhắn đến %{username}." + admin_options_title: "Tùy chọn quản trị viên cho chủ đề này" + auto_close: + label: "Thời gian tự khóa chủ đề:" + error: "Vui lòng nhập một giá trị hợp lệ." + based_on_last_post: "Không đóng cho đến khi bài viết cuối cùng trong chủ đề này trở thành bài cũ" + all: + examples: 'Nhập giờ (định dạng 24h), thời gian chính xác ( vd: 17:30) hoặc thời gian kèm ngày tháng (2013-11-22 14:00).' + limited: + units: "(# của giờ)" + examples: 'Nhập số giờ ( theo định dạng 24h)' + notifications: + title: "thông báo của @name nhắc đến, trả lời bài của bạn và chủ đề, tin nhắn, vv" + none: "Không thể tải các thông báo tại thời điểm này." + more: "xem thông báo cũ hơn" + total_flagged: "tổng số bài viết gắn cờ" + mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " + quoted: "

    {{username}} {{description}}

    " + replied: "

    {{username}} {{description}}

    " + edited: "

    {{username}} {{description}}

    " + liked: "

    {{username}} {{description}}

    " + private_message: "

    {{username}} {{description}}

    " + invited_to_private_message: "

    {{username}} {{description}}

    " + invited_to_topic: "

    {{username}} {{description}}

    " + invitee_accepted: "

    {{username}} chấp nhận lời mời của bạn

    " + moved_post: "

    {{username}} chuyển {{description}}

    " + linked: "

    {{username}} {{description}}

    " + granted_badge: "

    Thu được '{{description}}'

    " + group_message_summary: + other: "

    {{count}} tin nhắn trong {{group_name}} của bạn

    " + alt: + mentioned: "Được nhắc đến bởi" + quoted: "Trích dẫn bởi" + replied: "Đã trả lời" + posted: "Đăng bởi" + edited: "Bài viết của bạn được sửa bởi" + liked: "Bạn đã like bài viết" + private_message: "Tin nhắn riêng từ" + invited_to_private_message: "Lời mời thảo luận riêng từ" + invited_to_topic: "Lời mời tham gia chủ đề từ" + invitee_accepted: "Lời mời được chấp nhận bởi" + moved_post: "Bài viết của bạn đã được di chuyển bởi" + linked: "Liên kết đến bài viết của bạn" + granted_badge: "Cấp huy hiệu" + group_message_summary: "Tin nhắn trong hộp thư đến" + popup: + mentioned: '{{username}} nhắc đến bạn trong "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} nhắc đến bạn trong "{{topic}}" - {{site_title}}' + quoted: '{{username}} trích lời bạn trong "{{topic}}" - {{site_title}}' + replied: '{{username}} trả lời cho bạn trong "{{topic}}" - {{site_title}}' + posted: '{{username}} gửi bài trong "{{topic}}" - {{site_title}}' + private_message: '{{username}} đã gửi cho bạn một tin nhắn trong "{{topic}}" - {{site_title}}' + linked: '{{username}} liên quan đến bài viết của bạn từ "{{topic}}" - {{site_title}}' + upload_selector: + title: "Thêm một ảnh" + title_with_attachments: "Thêm một ảnh hoặc tệp tin" + from_my_computer: "Từ thiết bị của tôi" + from_the_web: "Từ Web" + remote_tip: "đường dẫn tới hình ảnh" + remote_tip_with_attachments: "chọn ảnh hoặc file {{authorized_extensions}}" + local_tip: "chọn hình từ thiết bị của bạn" + local_tip_with_attachments: "chọn ảnh hoặc file {{authorized_extensions}} từ thiết bị của bạn" + hint: "(Bạn cũng có thể kéo & thả vào trình soạn thảo để tải chúng lên)" + hint_for_supported_browsers: "bạn có thể kéo và thả ảnh vào trình soan thảo này" + uploading: "Đang tải lên" + select_file: "Chọn Tài liệu" + image_link: "liên kết hình ảnh của bạn sẽ trỏ đến" + search: + sort_by: "Sắp xếp theo" + relevance: "Độ phù hợp" + latest_post: "Bài viết mới nhất" + most_viewed: "Xem nhiều nhất" + most_liked: "Like nhiều nhất" + select_all: "Chọn tất cả" + clear_all: "Xóa tất cả" + result_count: + other: "{{count}} kết quả cho \"{{term}}\"" + title: "tìm kiếm chủ đề, bài viết, tài khoản hoặc các danh mục" + no_results: "Không tìm thấy kết quả." + no_more_results: "Không tìm thấy kết quả" + search_help: Giúp đỡ tìm kiếm + searching: "Đang tìm ..." + post_format: "#{{post_number}} bởi {{username}}" + context: + user: "Tìm bài viết của @{{username}}" + category: "Tìm danh mục \"{{category}}\"" + topic: "Tìm trong chủ đề này" + private_messages: "Tìm tin nhắn" + hamburger_menu: "đi đến danh sách chủ đề hoặc danh mục khác" + new_item: "mới" + go_back: 'quay trở lại' + not_logged_in_user: 'Trang cá nhân với tóm tắt các hoạt động và cấu hình' + current_user: 'đi đến trang cá nhân của bạn' + topics: + bulk: + unlist_topics: "Chủ đề không công khai" + reset_read: "Đặt lại lượt đọc" + delete: "Xóa chủ đề" + dismiss: "Bỏ qua" + dismiss_read: "Bỏ qua tất cả thư chưa đọc" + dismiss_button: "Bỏ qua..." + dismiss_tooltip: "Bỏ qua chỉ bài viết mới hoặc ngừng theo dõi chủ đề" + also_dismiss_topics: "Ngừng theo dõi các chủ đề này để không hiển thị lại là chủ đề chưa đọc" + dismiss_new: "Bỏ " + toggle: "chuyển sang chọn chủ đề theo lô" + actions: "Hành động theo lô" + change_category: "Chuyển chuyên mục" + close_topics: "Đóng các chủ đề" + archive_topics: "Chủ đề Lưu trữ" + notification_level: "Thay đổi cấp độ thông báo" + choose_new_category: "Chọn chuyên mục mới cho chủ đề này:" + selected: + other: "Bạn đã chọn {{count}} chủ đề" + none: + unread: "Bạn không có chủ đề nào chưa đọc." + new: "Bạn không có chủ đề mới nào." + read: "Bạn vẫn chưa đọc bất kì chủ đề nào." + posted: "Bạn vẫn chưa đăng bài trong bất kì một chủ đề nào" + latest: "Chán quá. Chẳng có chủ đề mới nào hết trơn." + hot: "Không có chủ đề nào nổi bật." + bookmarks: "Bạn chưa chủ đề nào được đánh dấu." + category: "Không có chủ đề nào trong {{category}} ." + top: "Không có chủ đề top." + search: "Không có kết quả tìm kiếm." + bottom: + latest: "Không còn thêm chủ đề nào nữa." + hot: "Không còn của đề nổi bật nào nữa." + posted: "Ở đây không có thêm chủ đề nào được đăng." + read: "Không còn thêm chủ đề chưa đọc nào nữa." + new: "Không còn thêm chủ đề mới nào nữa." + unread: "Không còn thêm chủ đề chưa đọc nào nữa." + category: "Không còn thêm chủ đề nào trong {{category}} ." + top: "Không còn của đề top nào nữa." + bookmarks: "Không còn thêm chủ đề được đánh dấu nào nữa." + search: "Không có thêm kết quả tìm kiếm nào nữa." + topic: + unsubscribe: + stop_notifications: "Từ bây giờ bạn sẽ không nhận thông báo từ {{title}}" + change_notification_state: "Tình trạn thông báo của bạn là" + filter_to: "{{post_count}} bài đăng trong chủ đề" + create: 'Chủ đề Mới' + create_long: 'Tạo một Chủ đề mới' + private_message: 'Bắt đầu một thông điệp' + archive_message: + help: 'Chuyển tin nhắn sang lưu trữ' + title: 'Lưu trữ' + move_to_inbox: + title: 'Chuyển sang hộp thư' + help: 'Chuyển tin nhắn trở lại hộp thư' + list: 'Chủ đề' + new: 'chủ đề mới' + unread: 'chưa đọc' + new_topics: + other: '{{count}} chủ đề mới.' + unread_topics: + other: '{{count}} chủ đề chưa đọc.' + title: 'Chủ đề' + invalid_access: + title: "Chủ đề này là riêng tư" + description: "Xin lỗi, bạn không có quyền truy cập vào chủ đề đó!" + login_required: "Bạn cần phải đăng nhập để xem chủ đề đó" + server_error: + title: "Tải chủ đề thất bại" + description: "Xin lỗi, chúng tôi không thể tải chủ đề, có thể do kết nối có vấn đề. Xin hãy thử lại. Nếu vấn đề còn xuất hiện, hãy cho chúng tôi biết" + not_found: + title: "Không tìm thấy chủ đề" + description: "Xin lỗi, chúng tôi không thể tìm thấy chủ đề đó. Có lẽ nó đã bị loại bởi mod?" + total_unread_posts: + other: "Bạn có {{number}} bài đăng chưa đọc trong chủ đề này" + unread_posts: + other: "bạn có {{number}} bài đăng củ chưa đọc trong chủ đề này" + new_posts: + other: "có {{count}} bài đăng mới trong chủ đề này từ lần đọc cuối" + likes: + other: "có {{count}} thích trong chủ để này" + back_to_list: "Quay lại danh sách chủ đề" + options: "Các lựa chọn chủ đề" + show_links: "Hiển thị liên kết trong chủ đề này" + toggle_information: "chuyển đổi các chi tiết chủ để" + read_more_in_category: "Muốn đọc nữa? Xem qua các chủ đề khác trong {{catLink}} hoặc {{latestLink}}" + read_more: "Muốn đọc nữa? {{catLink}} hoặc {{latestLink}}" + read_more_MF: "Có { UNREAD, plural, =0 {} one { is 1 unread } other { are # unread } } { NEW, plural, =0 {} one { {BOTH, select, true{and } false {is } other{}} 1 new topic} other { {BOTH, select, true{and } false {are } other{}} # new topics} } remaining, or {CATEGORY, select, true {browse other topics in {catLink}} false {{latestLink}} other {}}" + browse_all_categories: Duyệt tất cả các hạng mục + view_latest_topics: xem các chủ đề mới nhất + suggest_create_topic: Tại sao không tạo một chủ đề mới? + jump_reply_up: nhảy đến những trả lời trước đó + jump_reply_down: nhảy tới những trả lời sau đó + deleted: "Chủ đề này đã bị xóa" + auto_close_notice: "Chủ đề này sẽ tự động đóng %{timeLeft}." + auto_close_notice_based_on_last_post: "Chủ đề này sẽ đóng %{duration} sau trả lời cuối cùng." + auto_close_title: 'Tự động-Đóng các Cài đặt' + auto_close_save: "Lưu" + auto_close_remove: "Đừng Tự Động-Đóng Chủ Đề Này" + auto_close_immediate: "Bài viết cuối cùng trong chủ đề đã xảy ra %{hours} giờ qua, vì vậy chủ đề sẽ tự động đóng." + progress: + title: tiến trình của chủ đề + go_top: "trên cùng" + go_bottom: "dưới cùng" + go: "đi tới" + jump_bottom: "nhảy tới bài viết cuối cùng" + jump_bottom_with_number: "nhảy tới bài viết %{post_number}" + total: tổng số bài viết + current: bài viết hiện tại + position: "bài viết %{current} trong %{total}" + notifications: + reasons: + '3_6': 'Bạn sẽ nhận được các thông báo bởi vì bạn đang xem chuyên mục nàyotification' + '3_5': 'Bạn sẽ nhận được các thông báo bởi vì bạn đã bắt đầu xem chủ đề này một cách tự động' + '3_2': 'Bạn sẽ nhận được các thông báo bởi vì bạn đang xem chủ đề này' + '3_1': 'Bạn sẽ được nhận thông báo bởi bạn đã tạo chủ để này.' + '3': 'Bạn sẽ nhận được các thông báo bởi vì bạn đang xem chủ đề này' + '2_8': 'Bạn sẽ nhận được thông báo bởi vì bạn đang theo dõi chuyên mục này.' + '2_4': 'Bạn sẽ nhận được các thông báo bởi vì bạn đã đăng một trả lời vào chủ đề này' + '2_2': 'Bạn sẽ nhận được các thông báo bởi vì bạn đang theo dõi chủ đề này.' + '2': 'Bạn sẽ nhận được các thông báo bởi vì bạn đọc chủ đề này ' + '1_2': 'Bạn sẽ được thông báo nếu ai đó đề cập đến @tên bạn hoặc trả lời bạn' + '1': 'Bạn sẽ được thông báo nếu ai đó đề cập đến @tên bạn hoặc trả lời bạn' + '0_7': 'Bạn đang bỏ qua tất cả các thông báo trong chuyên mục này' + '0_2': 'Bạn đang bỏ qua tất cả các thông báo trong chủ đề này' + '0': 'Bạn đang bỏ qua tất cả các thông báo trong chủ đề này' + watching_pm: + title: "Đang xem" + description: "Bạn sẽ được thông báo về từng trả lời mới trong tin nhắn này, và một số trả lời mới sẽ được hiển thị" + watching: + title: "Dang theo dõi" + description: "Bạn sẽ được thông báo về từng trả lời mới trong tin nhắn này, và một số trả lời mới sẽ được hiển thị" + tracking_pm: + title: "Đang theo dõi" + description: "Một số trả lời mới sẽ được hiển thị trong tin nhắn này. Bạn sẽ được thông báo nếu ai đó đề cập đến @tên của bạn hoặc trả lời bạn" + tracking: + title: "Đang theo dõi" + description: "Một số trả lời mới sẽ được hiển thị trong chủ đề này. Bạn sẽ được thông báo nếu ai đó đề cập đến @tên của bạn hoặc trả lời bạn" + regular: + title: "Bình thường" + description: "Bạn sẽ được thông báo nếu ai đó đề cập đến @tên bạn hoặc trả lời bạn" + regular_pm: + title: "Bình thường" + description: "Bạn sẽ được thông báo nếu ai đó đề cập đến @tên bạn hoặc trả lời bạn" + muted_pm: + title: "Im lặng" + description: "Bạn sẽ không bao giờ được thông báo về bất cứ điều gì về tin nhắn này. " + muted: + title: "Im lặng" + description: "Bạn sẽ không nhận được bất kỳ thông báo nào trong chủ đề này, và chúng sẽ không hiển thị là mới nhất." + actions: + recover: "Không-Xóa Chủ Đề Này" + delete: "Xóa-Chủ Đề Này" + open: "Mở Chủ Đề" + close: "Đóng Chủ Đề" + multi_select: "Chọn Bài Viết..." + auto_close: "Tự Động Đóng..." + pin: "Ghim Chủ Đề..." + unpin: "Bỏ-Ghim Chủ Đề..." + unarchive: "Chủ đề Không Lưu Trữ" + archive: "Chủ Đề Lưu Trữ" + invisible: "Make Unlisted" + visible: "Make Listed" + reset_read: "Đặt lại dữ liệu đọc" + feature: + pin: "Ghim Chủ Đề" + unpin: "Bỏ-Ghim Chủ Đề" + pin_globally: "Ghim Chủ Đề Tổng Thể" + make_banner: "Banner chủ đề" + remove_banner: "Bỏ banner chủ đề" + reply: + title: 'Trả lời' + help: 'bắt đầu soạn một trả lời mới cho chủ đề này' + clear_pin: + title: "Xóa ghim" + help: "Xóa trạng thái ghim của chủ đề này để nó không còn xuất hiện trên cùng danh sách chủ đề của bạn" + share: + title: 'Chia sẻ' + help: 'Chia sẻ một liên kết đến chủ đề này' + flag_topic: + title: 'Gắn cờ' + help: 'đánh dấu riêng tư chủ đề này cho sự chú ý hoặc gửi một thông báo riêng về nó' + success_message: 'Bạn đã đánh dấu thành công chủ đề này' + feature_topic: + title: "Đề cao chủ đề này" + pin: "Làm cho chủ đề này xuất hiện trên top của chuyên mục {{categoryLink}}" + confirm_pin: "Bạn đã có {{count}} chủ đề được ghim. Qúa nhiều chủ đề được ghim có thể là một trở ngại cho những thành viên mới và thành viên ẩn danh. Bạn có chắc chắn muốn ghim chủ đề khác trong chuyên mục này?" + unpin: "Xóa chủ đề này từ phần trên cùng của chủ đề {{categoryLink}}" + unpin_until: "Gỡ bỏ chủ đề này khỏi top của chuyên mục {{categoryLink}} và đợi cho đến %{until}." + pin_note: "Người dùng có thể bỏ ghim chủ đề riêng cho mình" + pin_validation: "Ngày được yêu câu để gắn chủ đề này" + not_pinned: "Không có chủ đề được ghim trong {{categoryLink}}." + already_pinned: + other: "Chủ đề gần đây được ghim trong {{categoryLink}}: {{count}}" + pin_globally: "Làm cho chủ đề này xuất hiện trên top của tất cả các chủ đề" + confirm_pin_globally: "Bạn đã có {{count}} chủ đề được ghim. Ghim quá nhiều chủ đề có thể là trở ngại cho những thành viên mới và ẩn danh. Bạn có chắc chắn muốn ghim chủ đề khác?" + unpin_globally: "Bỏ chủ đề này khỏi phần trên cùng của danh sách tất cả các chủ đề" + unpin_globally_until: "Gỡ bỏ chủ đề này khỏi top của danh sách tất cả các chủ đề và đợi cho đến %{until}." + global_pin_note: "Người dùng có thể bỏ ghim chủ đề riêng cho mình" + not_pinned_globally: "Không có chủ đề nào được ghim." + already_pinned_globally: + other: "Chủ đề gần đây được ghim trong: {{count}}" + make_banner: "Đặt chủ đề này là một banner xuất hiện trên top của tất cả các trang." + remove_banner: "Gỡ bỏ banner xuất hiện trên top của tất cả các trang." + banner_note: "Người dùng có thể bỏ qua banner này bằng cách đóng nó. Chỉ một chủ đề có thể được đặt là banner tại một thời điểm." + no_banner_exists: "Không có chủ đề banner nào." + banner_exists: "Có is đang là chủ đề banner." + inviting: "Đang mời..." + automatically_add_to_groups_optional: "Lời mời này cũng bao gồm quyền truy cập vào các nhóm: (optional, admin only)" + automatically_add_to_groups_required: "Lời mời này cũng bao gồm quyền truy cập vào các nhóm: (Required, admin only)" + invite_private: + title: 'Mời thảo luận' + email_or_username: "Email hoặc username người được mời" + email_or_username_placeholder: "địa chỉ thư điện tử hoặc tên người dùng" + action: "Mời" + success: "Chúng tôi đã mời người đó tham gia thảo luận này." + error: "Xin lỗi, có lỗi khi mời người dùng này." + group_name: "Nhóm tên" + controls: "Topic Controls" + invite_reply: + title: 'Mời' + username_placeholder: "tên người dùng" + action: 'Gửi Lời Mời' + help: 'mời người khác tham gia chủ đề thông qua email hoặc thông báo' + to_forum: "Chúng tôi sẽ gửi một email tóm tắt cho phép bạn của bạn gia nhập trực tiệp bằng cách nhấp chuột vào một đường dẫn, không cần phải đăng nhập." + sso_enabled: "Nhập tên đăng nhập hoặc địa chỉ email của người mà bạn muốn mời vào chủ đề này." + to_topic_blank: "Nhập tên đăng nhập hoặc địa chỉ email của người bạn muốn mời đến chủ đề này." + to_topic_email: "Bạn vừa điền địa chỉ email, website sẽ gửi lời mời cho phép bạn bè của bạn có thể trả lời chủ đề này." + to_topic_username: "Bạn vừa điền tên thành viên, website sẽ gửi thông báo kèm theo lời mời họ tham gia chủ đề này." + to_username: "Điền tên thành viên bạn muốn mời, website sẽ gửi thông báo kèm theo lời mời họ tham gia chủ đề này." + email_placeholder: 'name@example.com' + success_email: "Website vừa gửi lời mời tới {{emailOrUsername}} và sẽ thông báo cho bạn khi lời mời đó được chấp nhận. Kiểm tra tab lời mời trên trang tài khoản để theo dõi lời mời của bạn." + success_username: "Website đã mời người đó tham gia thảo luận này." + error: "Xin lỗi, chúng tôi không thể mời người đó. Có lẽ họ đã được mời? (giới hạn lời mời)" + login_reply: 'Đăng nhập để trả lời' + filters: + n_posts: + other: "{{count}} bài viết" + cancel: "Bỏ đièu kiện lọc" + split_topic: + title: "Di chuyển tới Chủ đề mới" + action: "di chuyển tới chủ đề mới" + topic_name: "Tên chủ đề mới" + error: "Có lỗi khi di chuyển bài viết tới chủ đề mới." + instructions: + other: "Bạn muốn tạo chủ đề mới và phổ biến nó với {{count}} bài viết đã chọn." + merge_topic: + title: "Di chuyển tới chủ đề đang tồn tại" + action: "di chuyển tới chủ đề đang tồn tại" + error: "Có lỗi khi di chuyển bài viết đến chủ đề này." + instructions: + other: "Hãy chọn chủ đề bạn muốn di chuyển {{count}} bài viết này tới." + change_owner: + title: "Chuyển chủ sở hữu bài viết" + action: "chuyển chủ sở hữu" + error: "Có lỗi xảy ra khi thay đổi quyền sở hữu của các bài viết." + label: "Chủ sở hữ mới của Bài viết" + placeholder: "tên đăng nhập của chủ sở hữu mới" + instructions: + other: "Hãy chọn chủ sở hữu mới cho {{count}} bài viết của {{old_user}}." + instructions_warn: "Lưu ý rằng bất kỳ thông báo nào về bài viết này sẽ không được chuyển giao cho thành viên mới trở về trước.
    Cảnh báo: Hiện không có dữ liệu bài viết phụ thuộc được chuyển giao cho thành viên mới. Hãy thận trọng!" + change_timestamp: + title: "Đổi Timestamp" + action: "đổi timestamp" + invalid_timestamp: "Timestamp không thể trong tương lai." + error: "Có lỗi khi thay đổi timestamp của chủ đề." + instructions: "Hãy chọn dòng thời gian mới cho chủ đề, các bài viết trong chủ đề sẽ được cập nhật để có sự khác biệt cùng một lúc." + multi_select: + select: 'chọn' + selected: 'đã chọn ({{count}})' + select_replies: 'chọn + trả lời' + delete: xóa lựa chọn + cancel: hủy lựa chọn + select_all: chọn tất cả + deselect_all: bỏ chọn tất cả + description: + other: Bạn đã chọn {{count}} bài viết. + post: + reply: " {{replyAvatar}} {{usernameLink}}" + reply_topic: " {{link}}" + quote_reply: "trả lời trích dẫn" + edit: "Đang sửa {{link}} {{replyAvatar}} {{username}}" + edit_reason: "Lý do: " + post_number: "bài viết {{number}}" + last_edited_on: "đã sửa bài viết lần cuối lúc" + reply_as_new_topic: "Trả lời như là liên kết đến Chủ đề" + continue_discussion: "Tiếp tục thảo luận từ {{postLink}}:" + follow_quote: "đến bài viết trích dẫn" + show_full: "Hiển thị đầy đủ bài viết" + show_hidden: 'Xem nội dung ẩn' + deleted_by_author: + other: "(bài viết theo tác giả sẽ được xóa tự động sau %{count} giờ, trừ khi đã đánh dấu)" + expand_collapse: "mở/đóng" + gap: + other: "xem {{count}} trả lời bị ẩn" + more_links: "hơn {{count}}..." + unread: "Bài viết chưa đọc" + has_replies: + other: "{{count}} Trả lời" + has_likes: + other: "{{count}} Thích" + has_likes_title: + other: "{{count}} người thích bài viết này" + has_likes_title_only_you: "bạn đã like bài viết này" + has_likes_title_you: + other: "bạn và {{count}} người khác đã like bài viết này" + errors: + create: "Xin lỗi, có lỗi xảy ra khi tạo bài viết của bạn. Vui lòng thử lại." + edit: "Xin lỗi, có lỗi xảy ra khi sửa bài viết của bạn. Vui lòng thử lại." + upload: "Xin lỗi, có lỗi xảy ra khi tải lên tập tin này. Vui lòng thử lại." + attachment_too_large: "Xin lỗi, tập tin của bạn tải lên quá lớn (kích thước tối đa là {{max_size_kb}}kb)." + file_too_large: "Xin lỗi, tập tin của bạn tải lên quá lớn (kích thước tối đa là {{max_size_kb}}kb)" + too_many_uploads: "Xin lỗi, bạn chỉ có thể tải lên 1 file cùng 1 lúc." + too_many_dragged_and_dropped_files: "Xin lỗi, bạn chỉ có thể kéo và thả 10 tập tin cùng lúc." + upload_not_authorized: "Xin lỗi, tập tin của bạn tải lên chưa được cho phép (định dạng cho phép: {{authorized_extensions}})." + image_upload_not_allowed_for_new_user: "Xin lỗi, tài khoản mới không thể tải lên ảnh." + attachment_upload_not_allowed_for_new_user: "Xin lỗi, tài khoản mới không thể tải lên đính kèm." + attachment_download_requires_login: "Xin lỗi, bạn cần đăng nhập để tải về đính kèm." + abandon: + confirm: "Bạn có chắc muốn bỏ bài viết của bạn?" + no_value: "Không, giữ lại" + yes_value: "Đồng ý, bỏ" + via_email: "bài viết này đăng qua email" + whisper: "bài viết này là lời nhắn từ điều hành viên" + wiki: + about: "bài viết này là wiki" + archetypes: + save: 'Lưu lựa chọn' + controls: + reply: "bắt đầu soản trả lời cho bài viết này" + like: "like bài viết này" + has_liked: "bạn đã like bài viết này" + undo_like: "hủy like" + edit: "sửa bài viết này" + edit_anonymous: "Xin lỗi, nhưng bạn cần đăng nhập để sửa bài viết này." + flag: "đánh dấu bài viết này để tạo chú ý hoặc gửi một thông báo riêng về nó" + delete: "xóa bài viết này" + undelete: "hủy xóa bài viết này" + share: "chia sẻ liên kết đến bài viết này" + more: "Thêm" + delete_replies: + confirm: + other: "Bạn muốn xóa {{count}} trả lời cho bài viết này?" + yes_value: "Đồng ý, xóa những trả lời" + no_value: "Không, chỉ xóa chủ đề" + admin: "quản lý bài viết" + wiki: "Tạo Wiki" + unwiki: "Xóa Wiki" + convert_to_moderator: "Thêm màu Nhân viên" + revert_to_regular: "Xóa màu Nhân viên" + rebake: "Tạo lại HTML" + unhide: "Bỏ ẩn" + change_owner: "Đổi chủ sở hữu" + actions: + flag: 'Gắn cờ' + defer_flags: + other: "Đánh dấu hoãn" + it_too: + off_topic: "Gắn cờ nó" + spam: "Gắn cờ nó" + inappropriate: "Gắn cờ nó" + custom_flag: "Gắn cờ nó" + bookmark: "Đánh dấu nó" + like: "Thích nó" + vote: "Bịnh chọn nó" + undo: + off_topic: "Hủy gắn cờ" + spam: "Hủy gắn cờ" + inappropriate: "Hủy gắn cờ" + bookmark: "Hủy đánh dấu" + like: "Hủy like" + vote: "Hủy bình chọn" + by_you: + off_topic: "Bạn đã đánh dấu cái nfay là chủ đề đóng" + spam: "Bạn đã đánh dấu cái này là rác" + inappropriate: "Bạn đã đánh dấu cái này là không phù hợp" + notify_moderators: "Bạn đã đánh dấu cái này cho điều tiết" + notify_user: "Bạn đã gửi một tin nhắn đến người dùng này" + bookmark: "Bạn đã đánh dấu bài viết này" + like: "Bạn đã thích cái này" + vote: "Bạn đã bình chọn cho bài viết này" + by_you_and_others: + off_topic: + other: "Bạn và {{count}} người khác đã đánh dấu đây là chủ đề đóng" + spam: + other: "Bạn và {{count}} người khác gắn cờ nó là rác" + inappropriate: + other: "Bạn và {{count}} other người khác đã đánh dấu nó là không phù hợp" + notify_moderators: + other: "Bạn và {{count}} người khác gắn cờ nó là điều tiết" + notify_user: + other: "Bạn và {{count}} người khác đã gửi một tin nhắn đến người dùng này" + bookmark: + other: "Bạn và {{count}} người khác đã đánh dấu bài viết này" + like: + other: "Bạn và {{count}} người khác đã thích cái này" + vote: + other: "Bạn và {{count}} nười khác đã bình chọn cho bài viết này" + by_others: + off_topic: + other: "{{count}} người đã đánh dấu nó là chủ đề đóng" + spam: + other: "{{count}} người khác đánh dấu là rác" + inappropriate: + other: "{{count}} người khác đã đánh dấu là không phù hợp" + notify_moderators: + other: "{{count}} người đã đánh dấu để chờ duyệt" + notify_user: + other: "{{count}} gửi tin nhắn đến người dùng này" + bookmark: + other: "{{count}} người đã đánh dấu bài viết này" + like: + other: "{count}} người đã thích cái này" + vote: + other: "{{count}} người đã bình chọn cho bài viết này" + delete: + confirm: + other: "Bạn muốn xóa những bài viết này?" + revisions: + controls: + first: "Sửa đổi đầu tiên" + previous: "Sửa đổi trước" + next: "Sửa đổi tiếp theo" + last: "Sửa đổi gần nhất" + hide: "Ẩn sửa đổi" + show: "Hiện sửa đổi" + comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" + displays: + inline: + button: ' HTML' + side_by_side: + button: ' HTML' + side_by_side_markdown: + button: ' Thô' + category: + can: 'can…' + none: '(không danh mục)' + all: 'Tất cả danh mục' + choose: 'Chọn chuyên mục…' + edit: 'sửa' + edit_long: "Sửa" + view: 'Xem Chủ đề trong Danh mục' + general: 'Chung' + settings: 'Cấu hình' + topic_template: "Mẫu Chủ đề" + delete: 'Xóa chuyên mục' + create: 'Chuyên mục mới' + create_long: 'Tạo Chủ đề mới' + save: 'Lưu chuyên mục' + slug: 'Đường dẫn chuyên mục' + slug_placeholder: '(Tùy chọn) các từ sử dụng trong url' + creation_error: Có lỗi xảy ra khi tạo chuyên mục + save_error: Có lỗi xảy ra khi lưu chuyên mục + name: "Tên chuyên mục" + description: "Mô tả" + topic: "chủ đề chuyên mục" + logo: "Logo của chuyên mục" + background_image: "Ảnh nền của chuyên mục" + badge_colors: "Màu huy hiệu" + background_color: "Màu nền" + foreground_color: "Màu mặt trước" + name_placeholder: "Tối đa một hoặc hai từ" + color_placeholder: "Bất cứ màu nào" + delete_confirm: "Bạn có chắc sẽ xóa chuyên mục này chứ?" + delete_error: "Có lỗi xảy ra khi xóa chuyên mục này" + list: "Danh sách chuyên mục" + no_description: "Hãy thêm mô tả cho chuyên mục này" + change_in_category_topic: "Sửa mô tả" + already_used: 'Màu này đã được dùng bởi chuyên mục khác' + security: "Bảo mật" + special_warning: "Cảnh báo: Đây là chuyên mục có sẵn nên bạn không thể chỉnh sửa các thiết lập bảo mật. Nếu bạn muốn sử dụng chuyên mục này, hãy xóa nó thay vì tái sử dụng." + images: "Hình ảnh" + auto_close_label: "Tự động khóa chủ đề sau:" + auto_close_units: "giờ" + email_in: "Tùy chỉnh địa chỉ nhận thư điện tử " + email_in_allow_strangers: "Nhận thư điện tử từ người gửi vô danh không tài khoản" + email_in_disabled: "Tạo chủ đề mới thông qua email đã được tắt trong thiết lập. Để bật tính năng này, " + email_in_disabled_click: 'kích hoạt thiết lập thư điện tử' + suppress_from_homepage: "Ngăn chặn chuyên mục này hiển thị trên trang chủ." + allow_badges_label: "Cho phép thưởng huy hiệu trong chuyên mục này" + edit_permissions: "Sửa quyền" + add_permission: "Thêm quyền" + this_year: "năm nay" + position: "vị trí" + default_position: "vị trí mặc định" + position_disabled: "Chuyên mục sẽ được hiển thị theo thứ tự hoạt động. Để kiểm soát thứ tự chuyên mục trong danh sách, " + position_disabled_click: 'bật thiết lập "cố định vị trí chuyên mục".' + parent: "Danh mục cha" + notifications: + watching: + title: "Theo dõi" + description: "Bạn sẽ tự động xem tất cả các chủ đề mới trong các chuyên mục này. Bạn sẽ được thông báo về tất các các chủ đề mới, và một số bài viết mới sẽ được hiển thị." + tracking: + title: "Đang theo dõi" + description: "Bạn sẽ tự động theo dõi tất cả các chủ đề mới trong các chuyên mục này. Bạn sẽ được thông báo nếu ai đó đề cập đến @tên của bạn hoặc trả lời bạn, và một số bài viết mới sẽ được hiển thị." + regular: + title: "Bình thường" + description: "Bạn sẽ được thông báo nếu ai đó đề cập đến @tên bạn hoặc trả lời bạn" + muted: + title: "Im lặng" + description: "Bạn sẽ không nhận được thông báo về bất cứ chủ đề mới nào trong các chuyên mục này, và chúng sẽ không hiển thị là mới nhất." + flagging: + title: 'Cám ơn bạn đã giúp phát triển cộng đồng!' + action: 'Đánh dấu Bài viết' + take_action: "Thực hiện" + notify_action: 'Tin nhắn' + delete_spammer: "Xóa người Spam" + delete_confirm: "Bạn đang định xóa %{posts} bài đăng và %{topics} chủ đề từ người dùng này, loại tài khoản, ngăn đăng ký từ địa chỉ IP %{ip_address} của họ, và thêm địa chỉ email %{email} vào danh sách chặn vĩnh viễn. Bạn có chắc người dùng này thật sự là một spammer?" + yes_delete_spammer: "Có, xóa người spam" + ip_address_missing: "(N/A)" + hidden_email_address: "(ẩn)" + submit_tooltip: "Đánh dấu riêng tư" + take_action_tooltip: "Tiếp cận ngưỡng đánh dấu ngay lập tức, thay vì đợi cộng đồng" + cant: "Xin lỗi, bạn không thể đánh dấu bài viết lúc này." + formatted_name: + off_topic: "Nó là sai chủ đề" + inappropriate: "Không phù hợp" + spam: "Nó là rác" + custom_placeholder_notify_user: "Phải hảo tâm và mang tính xây dựng." + custom_placeholder_notify_moderators: "Hãy cho chúng tôi biết cụ thể những gì bạn quan tâm, và cung cấp các liên kết hoặc ví dụ liên quan nếu có thể." + custom_message: + at_least: "điền ít nhất {{n}} ký tự" + more: "còn {{n}}" + left: "{{n}} còn lại" + flagging_topic: + title: "Cám ơn bạn đã giúp phát triển cộng đồng!" + action: "Gắn cờ Chủ đề" + notify_action: "Tin nhắn" + topic_map: + title: "Tóm tắt Chủ đề" + participants_title: "Poster thường xuyên" + links_title: "Liên kết phổ biến" + links_shown: "hiện tất cả {{totalLinks}} liên kết..." + clicks: + other: "%{count} nhấp chuột" + topic_statuses: + warning: + help: "Đây là một cảnh báo chính thức." + bookmarked: + help: "Bạn đã đánh dấu chủ đề này" + locked: + help: "Chủ đề đã đóng; không cho phép trả lời mới" + archived: + help: "Chủ đề này đã được lưu trữ, bạn không thể sửa đổi nữa" + locked_and_archived: + help: "Chủ đề này đã đóng và lưu trữ, không cho phép trả lời mới và sửa đổi nữa" + unpinned: + title: "Hủy gắn" + help: "Chủ đề này không còn được ghim nữa, nó sẽ hiển thị theo thứ tự thông thường" + pinned_globally: + title: "Ghim toàn trang" + help: "Chủ đề này được ghim toàn trang, nó sẽ hiển thị ở trên cùng các chủ đề mới và trong chuyên mục" + pinned: + title: "Gắn" + help: "Chủ đề này đã được ghim, nó sẽ hiển thị ở trên cùng chuyên mục" + invisible: + help: "Chủ đề này ẩn, nó sẽ không hiển thị trong danh sách chủ đề, và chỉ có thể truy cập thông qua liên kết trực tiếp" + posts: "Bài viết" + posts_lowercase: "bài viết" + posts_long: "Có {{number}} bài đăng trong chủ đề này" + posts_likes_MF: | + Chủ đề này có {count, plural, one {1 reply} other {# replies}} {ratio, select, + low {with a high like to post ratio} + med {with a very high like to post ratio} + high {with an extremely high like to post ratio} + other {}} + original_post: "Bài viết gốc" + views: "Lượt xem" + views_lowercase: + other: "lượt xem" + replies: "Trả lời" + views_long: "chủ đề đã được xem {{number}} lần" + activity: "Hoạt động" + likes: "Lượt thích" + likes_lowercase: + other: "lượt thích" + likes_long: "Có {{number}} thích trong chủ đề này" + users: "Người dùng" + users_lowercase: + other: "người dùng" + category_title: "Danh mục" + history: "Lịch sử" + changed_by: "bởi {{author}}" + raw_email: + title: "Email gốc" + not_available: "Không sẵn sàng!" + categories_list: "Danh sách Danh mục" + filters: + with_topics: "%{filter} chủ đề" + with_category: "%{filter} %{category} chủ đề" + latest: + title: "Mới nhất" + title_with_count: + other: "Mới nhất ({{count}})" + help: "chủ đề với bài viết gần nhất" + hot: + title: "Nổi bật" + help: "chọn các chủ đề nóng nhất" + read: + title: "Đọc" + help: "chủ đề bạn đã đọc, theo thứ tự bạn đọc lần cuối cùng" + search: + title: "Tìm kiếm" + help: "tìm trong tất cả chủ đề" + categories: + title: "Danh mục" + title_in: "Danh mục - {{categoryName}}" + help: "tất cả các chủ đề được nhóm theo chuyên mục" + unread: + title: "Chưa đọc" + title_with_count: + other: "Chưa đọc ({{count}})" + help: "chủ đề bạn đang xem hoặc theo dõi có bài viết chưa đọc" + lower_title_with_count: + other: "{{count}} chưa đọc" + new: + lower_title_with_count: + other: "{{count}} mới" + lower_title: "mới" + title: "Mới" + title_with_count: + other: "Mới ({{count}})" + help: "chủ đề đã tạo cách đây vài ngày" + posted: + title: "Bài viết của tôi" + help: "chủ đề của bạn đã được đăng trong" + bookmarks: + title: "Đánh dấu" + help: "chủ để của bạn đã được đánh dấu" + category: + title: "{{categoryName}}" + title_with_count: + other: "{{categoryName}} ({{count}})" + help: "Những chủ đề mới nhất trong chuyên mục{{categoryName}} " + top: + title: "Trên" + help: "Các chủ đề tích cực nhất trong năm, tháng, tuần, hoặc ngày trước" + all: + title: "Từ trước tới nay" + yearly: + title: "Hàng năm" + quarterly: + title: "Hàng quý" + monthly: + title: "Hàng tháng" + weekly: + title: "Hàng tuần" + daily: + title: "Hàng ngày" + all_time: "Từ trước tới nay" + this_year: "Năm" + this_quarter: "Quý" + this_month: "Tháng" + this_week: "Tuần" + today: "Ngày" + other_periods: "xem top" + browser_update: 'Không may, trình duyệt của bạn quá cũ để website hoạt động. Hãy nâng cấp trình duyệt của bạn.' + permission_types: + full: "Tạo / Trả lời / Xem" + create_post: "Trả lời / Xem" + readonly: "Xem" + admin_js: + type_to_filter: "gõ để lọc..." + admin: + title: 'Quản trị Diễn đàn' + moderator: 'Điều hành' + dashboard: + title: "Bảng điều khiển" + last_updated: "Bảng điều khiển cập nhật gần nhất:" + version: "Phiên bản" + up_to_date: "Bạn đã cập nhật phiên bản mới nhất" + critical_available: "Bản cập nhật quan trọng sẵn sằng." + updates_available: "Cập nhật đang sẵng sàng" + please_upgrade: "Vui lòng cập nhật!" + no_check_performed: "Kiểm tra phiên bản mới đã không được thực hiện, đảm bảo rằng Sidekiq đang chạy." + stale_data: "Kiểm tra phiên bản mới đã không được thực hiện gần đây, đảm bảo rằng Sidekiq đang chạy." + version_check_pending: "Hình như bạn mới nâng cấp, thật tuyệt!" + installed_version: "Đã cài đặt" + latest_version: "Mới nhất" + problems_found: "Tìm thấy vấn đề với bản cài đặt Discourse của bạn:" + last_checked: "Kiểm tra lần cuối" + refresh_problems: "Làm mới" + no_problems: "Không phát hiện vấn đề" + moderators: 'Điều hành:' + admins: 'Quản trị:' + blocked: 'Đã khóa:' + suspended: 'Đã tạm khóa:' + private_messages_short: "Tin nhắn" + private_messages_title: "Tin nhắn" + mobile_title: "Điện thoại" + space_free: "{{size}} trống" + uploads: "tải lên" + backups: "sao lưu" + traffic_short: "Băng thông" + traffic: "Application web requests" + page_views: "API Requests" + page_views_short: "API Requests" + show_traffic_report: "Xem chi tiết Báo cáo Lưu lượng" + reports: + today: "Hôm nay" + yesterday: "Hôm qua" + last_7_days: "7 Ngày gần nhất" + last_30_days: "30 Ngày gần nhất" + all_time: "Từ trước tới nay" + 7_days_ago: "7 Ngày trước" + 30_days_ago: "30 Ngày trước" + all: "Tất cả" + view_table: "bảng" + view_chart: "biểu đồ bar" + refresh_report: "Làm mới báo cáo" + start_date: "Từ ngày" + end_date: "Đến ngày" + groups: "Các nhóm" + commits: + latest_changes: "Thay đổi cuối: vui lòng cập nhật thường xuyên!" + by: "bởi" + flags: + title: "Gắn cờ" + old: "Cũ" + active: "Kích hoạt" + agree: "Đồng ý" + agree_title: "Xác nhận đánh dấu này hợp lệ và chính xác" + agree_flag_modal_title: "Đồng ý và..." + agree_flag_hide_post: "Đồng ý (ẩn bài viết + gửi PM)" + agree_flag_hide_post_title: "Ẩn bài viết này và tự động gửi tin nhắn đến người dùng hối thúc họ sửa nó" + agree_flag_restore_post: "Đồng ý (khôi phục bài viết)" + agree_flag_restore_post_title: "Khôi phục bài viết này" + agree_flag: "Đống ý với cờ này" + agree_flag_title: "Đồng ý với cờ này và giữ bài viết không thay đổi" + defer_flag: "Hoãn" + defer_flag_title: "Xóa cờ này; nó yêu cầu không có hành động nào vào thời điểm này." + delete: "Xóa" + delete_title: "Xóa bài viết đánh dấu này đề cập đến." + delete_post_defer_flag: "Xóa bài viết và Hoãn đánh dấu" + delete_post_defer_flag_title: "Xóa bài viết; nếu là bài viết đầu tiên, xóa chủ đề này" + delete_post_agree_flag: "Xóa bài viết và Đồng ý với cờ" + delete_post_agree_flag_title: "Xóa bài viết; nếu là bài viết đầu tiên, xóa chủ đề này" + delete_flag_modal_title: "Xóa và..." + delete_spammer: "Xóa người Spam" + delete_spammer_title: "Xóa người dùng này và tất cả bài viết à chủ để của người dùng này." + disagree_flag_unhide_post: "Không đồng ý (ẩn bài viết)" + disagree_flag_unhide_post_title: "Loại bỏ bất kỳ đánh dấu nào khỏi bài viết này và làm cho bài viết hiển thị trở lại" + disagree_flag: "Không đồng ý" + disagree_flag_title: "Từ chối đánh dấu này là không hợp lệ hoặc chính xác" + clear_topic_flags: "Hoàn tất" + clear_topic_flags_title: "Chủ đề đã được xem xét vấn đề và giải quyết, click để loại bỏ đánh dấu." + more: "(thêm trả lời...)" + dispositions: + agreed: "đồng ý" + disagreed: "không đồng ý" + deferred: "hoãn" + flagged_by: "Gắn cờ bởi" + resolved_by: "Xử lý bởi" + took_action: "Thực hiện" + system: "Hệ thống" + error: "Có lỗi xảy ra" + reply_message: "Trả lời " + no_results: "Không được gắn cờ" + topic_flagged: "Chủ đề này đã được đánh dấu." + visit_topic: "Tới chủ đề để thực hiện" + was_edited: "Bài viết đã được chỉnh sửa sau khi đánh dấu đầu tiên" + previous_flags_count: "Bài viết này đã được đánh dấu {{count}} lần." + summary: + action_type_3: + other: "sai chủ đề x{{count}}" + action_type_4: + other: "Không phù hợp x{{count}}" + action_type_6: + other: "tùy chỉnh x{{count}}" + action_type_7: + other: "tùy chỉnh x{{count}}" + action_type_8: + other: "spam x{{count}}" + groups: + primary: "Nhóm Chính" + no_primary: "(không có nhóm chính)" + title: "Nhóm" + edit: "Sửa nhóm" + refresh: "Làm mới" + new: "Mới" + selector_placeholder: "nhập tên tài khoản" + name_placeholder: "Tên nhóm, không khoản trắng, cùng luật với tên tài khoản" + about: "Chỉnh sửa nhóm thành viên và tên của bạn ở đây" + group_members: "Nhóm thành viên" + delete: "Xóa" + delete_confirm: "Xóa nhóm này?" + delete_failed: "Không thể xóa nhóm. Nếu đây là một nhóm tự động, nó không thể hủy bỏ." + delete_member_confirm: "Loại bỏ '%{username}' khỏi nhóm '%{group}'?" + delete_owner_confirm: "Loại bỏ quyền sở hữu của '%{username}'?" + name: "Tên" + add: "Thêm" + add_members: "Thêm thành viên" + custom: "Tùy biến" + bulk_complete: "Các thành viên đã được thêm vào nhóm." + bulk: "Thêm vào nhóm theo lô" + bulk_paste: "Dán danh sách username hoặc email, mỗi mục một dòng:" + bulk_select: "(chọn nhóm)" + automatic: "Tự động" + automatic_membership_email_domains: "Các thành viên đã đăng ký với đuôi email khớp với một trong danh sách này sẽ được tự động thêm vào nhóm:" + automatic_membership_retroactive: "Áp dụng quy tắc đuôi email tương tự để thêm thành viên đăng ký hiện tại" + default_title: "Tên mặc định cho tất cả các thành viên trong nhóm này" + primary_group: "Tự động cài là nhóm chính" + group_owners: Chủ sở hữu + add_owners: Thêm chủ sở hữu + incoming_email: "Tùy chỉnh địa chỉ email đến" + incoming_email_placeholder: "điền địa chỉ email" + api: + generate_master: "Tạo Master API Key" + none: "Không có API keys nào kích hoạt lúc này." + user: "Thành viên" + title: "API" + key: "API Key" + generate: "Khởi tạo" + regenerate: "Khởi tạo lại" + revoke: "Thu hồi" + confirm_regen: "Bạn muốn thay API Key hiện tại bằng cái mới?" + confirm_revoke: "Bạn có chắc chắn muốn hủy bỏ khóa đó?" + info_html: "Khóa API cho phép bạn tạo và cập nhật chủ đề sử dụng JSON." + all_users: "Tất cả Thành viên" + note_html: "Giữ khóa nào bảo mật, tất cả tài khoản có thể dùng khóa này để tạo bài viết với bất kỳ tài khoản nào." + plugins: + title: "Plugin" + installed: "Đã cài Plugin" + name: "Tên" + none_installed: "Bạn chưa cài plugin nào." + version: "Phiên bản" + enabled: "Kích hoạt" + is_enabled: "Có" + not_enabled: "Không" + change_settings: "Đổi Cấu hình" + change_settings_short: "Cấu hình" + howto: "Plugin cài như thế nào?" + backups: + title: "Bản sao lưu" + menu: + backups: "Bản sao lưu" + logs: "Log" + none: "Chưa có bản sao lưu." + read_only: + enable: + title: "Kích hoạt chế độ chỉ xem" + label: "Kích hoạt chế độ chỉ xem" + confirm: "Bạn muốn kích hoạt chế chộ chỉ xem?" + disable: + title: "Hủy chế độ chỉ xem này" + label: "Hủy chế độ chỉ xem" + logs: + none: "Chưa có log..." + columns: + filename: "Tên tập tin" + size: "Kích thước" + upload: + label: "Tải lên" + title: "Tải lên bản sao lưu cho phiên bản này" + uploading: "Đang tải lên..." + success: "'{{filename}}' đã tải lên thành công." + error: "Có lõi trong quá trình tải lên '{{filename}}': {{message}}" + operations: + is_running: "Tác vụ đang chạy..." + failed: "{{operation}} Thấy bại. Vui lòng xem log." + cancel: + label: "Hủy" + title: "Hủy tác vụ hiện tại" + confirm: "Bạn muốn hủy tác vụ hiện tại?" + backup: + label: "Sao lưu" + title: "Tạo bản sao lưu" + confirm: "Bạn muốn bắt đầu một bản sao lưu mới?" + without_uploads: "Đúng (không bao gồm những tập tin)" + download: + label: "Tải xuống" + title: "Tải xuống bản sao lưu này" + destroy: + title: "Xóa bản sao lưu này" + confirm: "Bạn muốn hủy bản sao lưu này?" + restore: + is_disabled: "Khôi phục đã bị cấm sử dụng trong cấu hình trang." + label: "Khôi phục" + title: "Khôi phục lại sao lưu này" + rollback: + label: "Rollback" + title: "Đưa csdl về trạng thái làm việc trước" + export_csv: + user_archive_confirm: "Bạn có chắc chắn muốn download các bài viết của mình?" + success: "Export đang được khởi tạo, bạn sẽ nhận được tin nhắn thông báo khi quá trình hoàn tất." + failed: "Xuất lỗi. Vui lòng kiểm tra log." + rate_limit_error: "Bài viết có thể tải về 1 lần mỗi này, vui lòng thử lại vào ngày mai." + button_text: "Xuất" + button_title: + user: "Xuất danh sách người dùng đầy đủ với định dạng CSV." + staff_action: "Xuất đầy đủ log hành động của nhân viên với định dạng CSV." + screened_email: "Export danh sách email theo định dạng CSV." + screened_ip: "Export danh sách IP theo định dạng CSV." + screened_url: "Export danh sách URL theo định dạng CSV." + export_json: + button_text: "Xuất" + invite: + button_text: "Gửi Lời Mời" + button_title: "Gửi Lời Mời" + customize: + title: "Tùy biến" + long_title: "Tùy biến trang" + css: "CSS" + header: "Header" + top: "Trên" + footer: "Footer" + embedded_css: "Nhúng CSS" + head_tag: + text: "" + title: "HTML sẻ thêm trước thẻ " + body_tag: + text: "" + title: "HTML sẽ thêm trước thẻ " + override_default: "Không bao gồm style sheet chuẩn" + enabled: "Cho phép?" + preview: "xem trước" + undo_preview: "xóa xem trước" + rescue_preview: "default style" + explain_preview: "Xem website với stylesheet tùy chỉnh" + explain_undo_preview: "Quay trở lại với kiểu tùy chỉnh stylesheet hiện tại" + explain_rescue_preview: "Xem website với stylesheet mặc định" + save: "Lưu" + new: "Mới" + new_style: "Style mới" + import: "Nhập" + import_title: "Chọn một file hoặc paste chữ." + delete: "Xóa" + delete_confirm: "Xóa tùy biến này?" + about: "Chỉnh sửa CSS và HTML header trên trang. Thêm tùy biến để bắt đầu." + color: "Màu sắc" + opacity: "Độ mờ" + copy: "Sao chép" + email_templates: + title: "Email Templates" + subject: "Chủ đề" + multiple_subjects: "Email template này có nhiều chủ đề." + body: "Nội dung" + none_selected: "Chọn email template để bắt đầu chỉnh sửa." + revert: "Hoàn nguyên thay đổi" + revert_confirm: "Bạn có chắc chắn muốn hoàn nguyên các thay đổi?" + css_html: + title: "CSS/HTML" + long_title: "Tùy biến CSS và HTML" + colors: + title: "Màu sắc" + long_title: "Bảng màu" + about: "Chỉnh " + new_name: "Bản màu mới" + copy_name_prefix: "Bản sao của" + delete_confirm: "Xóa bảng màu này?" + undo: "hoàn tác" + undo_title: "Hoàn tác thay đổi của bạn vơ" + revert: "phục hồi" + revert_title: "Thiết lập lại màu về mặc định của Discourse." + primary: + name: 'chính' + description: 'Hầu hết chữ, biểu tượng, và viền.' + secondary: + name: 'cấp hai' + description: 'Màu nền, và màu chữ của một vài nút.' + tertiary: + name: 'cấp ba' + description: 'Liên kết, một và nút, thông báo, và màu nhấn.' + quaternary: + name: "chia bốn" + description: "Liên kết điều hướng." + header_background: + name: "nền header" + description: "Màu nền header của trang." + header_primary: + name: "header chính" + description: "Chữ và icon trong header của website." + highlight: + name: 'highlight' + description: 'Màu nền của các thành phần được đánh dấu trên trang, như là bài viết và chủ đề.' + danger: + name: 'nguy hiểm' + description: 'Màu đánh dấu cho thao tác xóa bài viết và chủ đề.' + success: + name: 'thành công' + description: 'Sử dụng để chỉ một thao tác đã thành công.' + love: + name: 'đáng yêu' + description: "Màu của nút like" + email: + title: "Emails" + settings: "Cấu hình" + templates: "Templates" + preview_digest: "Xem trước tập san" + sending_test: "Đang gửi Email test..." + error: "LỖI - %{server_error}" + test_error: "Có vấn đề khi gửi email test. Vui lòng kiểm tra lại cấu hình email của bạn, chắc chắn host mail của bạn không bị khóa kết nối, và thử lại." + sent: "Đã gửi" + skipped: "Đã bỏ qua" + received: "Đã nhận" + rejected: "Từ chối" + sent_at: "Đã gửi vào lúc" + time: "Thời gian" + user: "Thành viên" + email_type: "Loại Email" + to_address: "Đến Địa chỉ" + test_email_address: "địa chỉ email để test" + send_test: "Gửi Email test" + sent_test: "đã gửi!" + delivery_method: "Phương thức chuyển giao" + preview_digest_desc: "Xem trước nội dung của tập san email đã gửi cho các thành viên không hoạt động." + refresh: "Tải lại" + format: "Định dạng" + html: "html" + text: "text" + last_seen_user: "Người dùng cuối:" + reply_key: "Key phản hồi" + skipped_reason: "Bỏ qua Lý do" + incoming_emails: + from_address: "Từ" + to_addresses: "Tới" + cc_addresses: "Cc" + subject: "Chủ đề" + error: "Lỗi" + none: "Không tìm tháy các email đến." + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "Chủ đề..." + error_placeholder: "Lỗi" + logs: + none: "Không tìm thấy log." + filters: + title: "Lọc" + user_placeholder: "tên người dùng" + address_placeholder: "name@example.com" + type_placeholder: "tập san, đăng ký..." + reply_key_placeholder: "key phản hồi" + skipped_reason_placeholder: "lý do" + logs: + title: "Log" + action: "Hành động" + created_at: "Đã tạo" + last_match_at: "Khớp lần cuối" + match_count: "Khớp" + ip_address: "IP" + topic_id: "ID Chủ đề" + post_id: "ID Bài viết" + category_id: "ID Danh mục" + delete: 'Xoá' + edit: 'Sửa' + save: 'Lưu' + screened_actions: + block: "khóa" + do_nothing: "không làm gì" + staff_actions: + title: "Staff Actions" + instructions: "Click username và thực hiện lọc danh sách, click ảnh hồ sơ để đến trang thành viên." + clear_filters: "Hiện thị mọi thứ" + staff_user: "Tài khoản Nhân viên" + target_user: "Target User" + subject: "Chủ đề" + when: "Khi" + context: "Ngữ cảnh" + details: "Chi tiết" + previous_value: "Trước" + new_value: "Mới" + diff: "So sánh" + show: "Hiển thị" + modal_title: "Chi tiết" + no_previous: "Không có giá trị trước đó." + deleted: "Không có giá trị mới, bản ghi đã được xóa." + actions: + delete_user: "xóa người dùng" + change_trust_level: "thay đổi cấp tin cậy" + change_username: "thay đổi username" + change_site_setting: "thay đổi cấu hình trang" + change_site_customization: "thay đổi tùy biến trang" + delete_site_customization: "xóa tùy biến trang" + change_site_text: "thay đổi chữ trên website" + suspend_user: "tạm khóa thành viên" + unsuspend_user: "hủy tạm khóa thành viên" + grant_badge: "cấp huy hiệu" + revoke_badge: "hủy bỏ huy hiệu" + check_email: "kiểm tra email" + delete_topic: "xóa chủ đề" + delete_post: "xóa bài viết" + impersonate: "mạo danh" + anonymize_user: "thành viên ẩn danh" + roll_up: "cuộn lên khối IP" + change_category_settings: "thay đổi cấu hình danh mục" + delete_category: "xóa danh mục" + create_category: "tạo danh mục" + block_user: "khóa tài khoản" + unblock_user: "mở khóa tài khoản" + grant_admin: "cấp quản trị" + revoke_admin: "hủy bỏ quản trị" + grant_moderation: "cấp điều hành" + revoke_moderation: "hủy bỏ điều hành" + screened_emails: + title: "Screened Emails" + description: "Khi ai đó cố gắng tạo tài khoản mới, các địa chỉ email sau sẽ được kiểm tra và đăng ký sẽ bị chặn, hoặc một số hành động khác được thực hiện." + email: "Địa chỉ Email" + actions: + allow: "Cho phép" + screened_urls: + title: "Screened URLs" + description: "Các URL được liệt kê ở đây được sử dụng trong các bài viết của người dùng đã được xác định là spammer." + url: "URL" + domain: "Tên miền" + screened_ips: + title: "Screened IPs" + description: 'Các địa chỉ IP đã được xem, sử dụng "Cho phép" để tạo danh sách trắng các địa chỉ.' + delete_confirm: "Bạn có chắc chắn muốn xóa quy tắc cho %{ip_address}?" + roll_up_confirm: "Bạn có chắc chắn muốn cuộn các địa chỉ IP thông thường vào các mạng con?" + rolled_up_some_subnets: "Cuộn thành công các IP cấm vào các mạng con: %{subnets}." + rolled_up_no_subnet: "Không có gì để cuộn lên." + actions: + block: "Khóa" + do_nothing: "Cho phép" + allow_admin: "Cho phép Quản trị" + form: + label: "Mới:" + ip_address: "Địa chỉ IP" + add: "Thêm" + filter: "Tìm kiếm" + roll_up: + text: "Cuộn lên" + title: "Tạo mạng con mới các entry cấm nếu có ít nhất 'min_ban_entries_for_roll_up' entry." + logster: + title: "Log lỗi" + impersonate: + title: "Mạo danh" + help: "Sử dụng công cụ này để mạo danh một tài khoản thành viên cho mục đích gỡ lỗi, bạn sẽ phải đăng xuất sau khi hoàn tất." + not_found: "Không tìm thấy người dùng này." + invalid: "Xin lỗi, bạn không thể mạo danh tài khoản đó." + users: + title: 'Tài khoản' + create: 'Thêm tài khoản Quản trị' + last_emailed: "Email trước đây" + not_found: "Xin lỗi, username không tồn tại trong hệ thống." + id_not_found: "Xin lỗi, id người dùng không tồn tại trong hệ thống." + active: "Kích hoạt" + show_emails: "Hiện địa chỉ Email" + nav: + new: "Mới" + active: "Kích hoạt" + pending: "Đang chờ xử lý" + staff: 'Nhân viên' + suspended: 'Đã tạm khóa' + blocked: 'Đã khóa' + suspect: 'Nghi ngờ' + approved: "Đã duyệt?" + approved_selected: + other: "duyệt tài khoản ({{count}})" + reject_selected: + other: "từ chối tài khoản ({{count}})" + titles: + active: 'Thành viên kích hoạt' + new: 'Thành viên mới' + pending: 'Hoãn Xem xét Tài khoản' + newuser: 'Tài khoản ở Cấp độ Tin tưởng 0 (Tài khoản mới)' + basic: 'Tài khoản ở Cấp độ Tin tưởng 1 (Tài khoản Cơ bản)' + member: 'Tài khoản ở Độ tin cậy mức 2 (Member)' + regular: 'Tài khoản ở Độ tin cậy mức 3 (Regular)' + leader: 'Tài khoản ở Độ tin cậy mức 4 (Leader)' + staff: "Nhân viên" + admins: 'Tài khoản Quản trị' + moderators: 'Điều hành viên' + blocked: 'Tài khoản Khóa' + suspended: 'Tài khoản Tạm khóa' + suspect: 'Tài khoản đáng ngờ' + reject_successful: + other: "Từ chối thành công %{count} tài khoản." + reject_failures: + other: "Từ chối thất bại %{count} tài khoản." + not_verified: "Chưa xác thực" + check_email: + title: "Khám phá email của tài khoản này" + text: "Hiển thị" + user: + suspend_failed: "Có gì đó đã sai khi đình chỉ tài khoản này {{error}}" + unsuspend_failed: "Có gì đó sai khi gỡ bỏ đình chỉ tài khoản này {{error}}" + suspend_duration: "Tài khoản này sẽ bị đình chỉ bao lâu?" + suspend_duration_units: "(ngày)" + suspend_reason_label: "Tại sao bạn bị đình chỉ? Dòng chữ hiển thị cho tất cả mọi người sẽ hiển thị trên trang hồ sơ tài khoản của người dùng này, và sẽ hiển thị cho thành viên khi họ đăng nhập, hãy viết ngắn." + suspend_reason: "Lý do" + suspended_by: "Tạm khóa bởi" + delete_all_posts: "Xóa tất cả bài viết" + delete_all_posts_confirm: "Bạn có chắc chắn muốn xóa %{posts} bài viết và %{topics} chủ đề?" + suspend: "Tạm khóa" + unsuspend: "Đã mở khóa" + suspended: "Đã tạm khóa?" + moderator: "Mod?" + admin: "Quản trị?" + blocked: "Đã khóa?" + staged: "Cấp bậc?" + show_admin_profile: "Quản trị" + edit_title: "Sửa Tiêu đề" + save_title: "Lưu Tiêu đề" + refresh_browsers: "Bắt buộc làm mới trình duyệt" + refresh_browsers_message: "Tin nhắn đã gửi cho tất cả người dùng!" + show_public_profile: "Hiển thị hồ sơ công khai" + impersonate: 'Mạo danh' + ip_lookup: "Tìm kiếm địa chỉ IP" + log_out: "Đăng suất" + logged_out: "Thành viên đã đăng xuất trên tất cả thiết bị" + revoke_admin: 'Thu hồi quản trị' + grant_admin: 'Cấp quản trị' + revoke_moderation: 'Thu hồi điều hành' + grant_moderation: 'Cấp điều hành' + unblock: 'Mở khóa' + block: 'Khóa' + reputation: Danh tiếng + permissions: Quyền + activity: Hoạt động + like_count: Đã like / Nhận + last_100_days: 'trong 100 ngày gần đây' + private_topics_count: Chủ đề riêng tư + posts_read_count: Đọc bài viết + post_count: Bài đăng đã được tạo + topics_entered: Chủ để đã xem + flags_given_count: Đã đánh dấu + flags_received_count: Flags Received + warnings_received_count: Đã nhận Cảnh báo + flags_given_received_count: 'Đã đánh dấu / Nhận' + approve: 'Duyệt' + approved_by: "duyệt bởi" + approve_success: "Thành viên được duyệt và đã gửi email hướng đẫn kích hoạt." + approve_bulk_success: "Thành công! Tất cả thành viên đã chọn được duyệt và thông báo." + time_read: "Thời gian đọc" + anonymize: "Tài khoản Nặc danh" + anonymize_confirm: "Bạn CHĂC CHẮN muốn xóa tài khoản nặc danh này? Nó sẽ thay đổi tên đăng nhập và email, và xóa tất cả thông tin trong hồ sơ." + anonymize_yes: "Đồng ý, đây là tài khoản nặc danh." + anonymize_failed: "Có vấn đề với những tài khoản nặc danh." + delete: "Xóa thành viên" + delete_forbidden_because_staff: "Admin và mod không thể xóa." + delete_posts_forbidden_because_staff: "Không thể xóa tất cả bài viết của quản trị và điều hành viên." + delete_forbidden: + other: "Không thể xóa tài khoản nếu họ có bài viết, hãy xóa tất cả các bài viết trước khi xóa tài khoản. (Không thể xóa các bài viết cũ hơn %{count} ngày.)" + cant_delete_all_posts: + other: "Không thể xóa tất cả các bài viết, một số bài viết cũ hơn %{count} ngày. (Thiết lập delete_user_max_post_age.)" + cant_delete_all_too_many_posts: + other: "Không thể xóa tất cả các bài viết do tài khoản có hơn %{count} bài viết. (delete_all_posts_max)" + delete_confirm: "Bạn CHẮC CHẮN muốn xóa thành viên này? Nó là vĩnh viễn!" + delete_and_block: "Xóa và khóa email này và địa chỉ IP" + delete_dont_block: "Chỉ xóa" + deleted: "Thành viên này đã bị xóa" + delete_failed: "Có lỗi trong quá trình xóa thành viên này. Chắc chắn rằng tất cả bài viết đã được xóa trước khi xóa thành viên." + send_activation_email: "Gửi email kích hoạt" + activation_email_sent: "Email kích hoạt đã được gửi." + send_activation_email_failed: "Có vấn đề khi gửi lại email kích hoạt. %{error}" + activate: "Kích hoạt tài khoản" + activate_failed: "Có vấn đề khi kích hoạt thành viên này." + deactivate_account: "Vô hiệu hóa Tài khoản" + deactivate_failed: "Có vấn đề khi bỏ kích hoạt thành viên này." + unblock_failed: 'Có vẫn đề khi gỡ khóa thành viên này.' + block_failed: 'Có vấn đề khi khóa thành viên này.' + block_confirm: 'Bạn có chắc chắn muốn chặn người dùng này? Họ sẽ không thể tạo bất kỳ chủ đề hoặc bài viết mới nào.' + block_accept: 'Có, chặn người dùng này' + deactivate_explanation: "Tài khoản chờ kích hoạt phải xác thực email của họ." + suspended_explanation: "Tài khoản tạm khóa không thể đăng nhập." + block_explanation: "Tài khoản bị khóa không thể đăng bài hoặc tạo chủ đề." + stage_explanation: "Người dùng có cấp bậc chỉ có thể gửi bài qua email trong các chủ đề cụ thể." + trust_level_change_failed: "Có lỗi xảy ra khi thay đổi mức độ tin tưởng của tài khoản." + suspend_modal_title: "Tạm khóa Thành viên" + trust_level_2_users: "Độ tin cậy tài khoản mức 2" + trust_level_3_requirements: "Độ tin cậy bắt buộc mức 3" + trust_level_locked_tip: "mức độ tin cậy đang khóa, hệ thống sẽ không thể thăng hoặc giáng chức người dùng" + trust_level_unlocked_tip: "độ tin cậy đang được mở, hệ thống có thể thăng hoặc giáng chức người dùng" + lock_trust_level: "Khóa Cấp độ Tin tưởng" + unlock_trust_level: "Mở khóa độ tin cậy" + tl3_requirements: + title: "Yêu cầu Cấp độ tin tưởng 3" + table_title: "Trong %{time_period} ngày qua:" + value_heading: "Giá trị" + requirement_heading: "Yêu cầu" + visits: "Lượt xem" + days: "ngày" + topics_replied_to: "Topics Replied To" + topics_viewed: "Đã xem chủ đề" + topics_viewed_all_time: "Đã xem chủ đề (mọi lúc)" + posts_read: "Đọc bài viết" + posts_read_all_time: "Đọc bài viết (mọi lúc)" + flagged_posts: "Đã gắn cờ Bài viết" + flagged_by_users: "Users Who Flagged" + likes_given: "Lượt Likes" + likes_received: "Likes Đã Nhận" + likes_received_days: "Like nhận được: ngày độc nhất" + likes_received_users: "Like nhận được: tài khoản độc nhất" + qualifies: "Đủ điều kiện cho độ tin cậy mức 3." + does_not_qualify: "Không đủ điều kiện cho độ tin cậy mức 3." + will_be_promoted: "Sẽ sớm được thăng chức." + will_be_demoted: "Sẽ sớm bị giáng chức." + on_grace_period: "Hiện đang trong khoảng thời gian gia hạn thăng chức, sẽ không thể giáng chức." + locked_will_not_be_promoted: "Mức độ tin cậy đang khóa, sẽ không thể thăng chức." + locked_will_not_be_demoted: "Mức độ tin cậy đang khóa, sẽ không thể giáng chức." + sso: + title: "Single Sign On" + external_id: "ID Bên ngoài" + external_username: "Tên đăng nhập" + external_name: "Tên" + external_email: "Email" + external_avatar_url: "URL Ảnh đại diện" + user_fields: + title: "Trường tài khoản" + help: "Thêm trường dữ liệu cho người dùng nhập." + create: "Tạo trường tài khoản" + untitled: "Không có tiêu đề" + name: "Tên Trường" + type: "Loại Trường" + description: "Trường mô tả" + save: "Lưu" + edit: "Sửa" + delete: "Xoá" + cancel: "Hủy" + delete_confirm: "Bạn muốn xóa trường thành viên?" + options: "Lựa chọn" + required: + title: "Bắt buộc lúc đăng ký?" + enabled: "bắt buộc" + disabled: "không bắt buộc" + editable: + title: "Có thể chỉnh sửa sau khi đăng ký?" + enabled: "có thể chỉnh sửa" + disabled: "không thể chỉnh sửa" + show_on_profile: + title: "Hiển thị trong hồ sơ công khai" + enabled: "hiển thị trong hồ sơ" + disabled: "không hiển thị trong hồ sơ" + field_types: + text: 'Nội dung chữ' + confirm: 'Xác nhận' + dropdown: "Xổ xuống" + site_text: + description: "Bạn có thể tùy chỉnh bất kỳ nội dung nào trên diễn đàn. Hãy bắt đầu bằng cách tìm kiếm dưới đây:" + search: "Tìm kiếm nội dung bạn muốn sửa" + title: 'Nội Dung Chữ' + edit: 'sửa' + revert: "Hoàn nguyên thay đổi" + revert_confirm: "Bạn có chắc chắn muốn hoàn nguyên các thay đổi?" + go_back: "Quay lại tìm kiếm" + recommended: "Bạn nên tùy biến các nội dung sau đây cho phù hợp với nhu cầu:" + show_overriden: 'Chỉ hiển thị chỗ ghi đè' + site_settings: + show_overriden: 'Chỉ hiện thị đã ghi đè' + title: 'Xác lập' + reset: 'trạng thái đầu' + none: 'không có gì' + no_results: "Không tìm thấy kết quả." + clear_filter: "Xóa" + add_url: "thêm URL" + add_host: "thêm host" + categories: + all_results: 'Tất cả' + required: 'Bắt buộc' + basic: 'Cài đặt cơ bản' + users: 'Thành viên' + posting: 'Đang đăng bài' + email: 'Email' + files: 'Tập tin' + trust: 'Độ tin tưởng' + security: 'Bảo mật' + onebox: "Onebox" + seo: 'SEO' + spam: 'Rác' + rate_limits: 'Rate Limits' + developer: 'Nhà phát triển' + embedding: "Embedding" + legal: "Legal" + uncategorized: 'Khác' + backups: "Sao lưu" + login: "Đăng nhập" + plugins: "Plugins" + user_preferences: "Tùy chỉnh Tài khoản" + badges: + title: Huy hiệu + new_badge: Thêm huy hiệu + new: Mới + name: Tên + badge: Huy hiệu + display_name: Tên Hiển thị + description: Mô tả + badge_type: Kiểu huy hiệu + badge_grouping: Nhóm + badge_groupings: + modal_title: Nhóm huy hiệu + granted_by: Cấp bởi + granted_at: Cấp lúc + reason_help: (Liên kết đến bài viết hoặc chủ đề) + save: Lưu + delete: Xóa + delete_confirm: Bạn có chắc chắn muốn xóa huy hiệu này? + revoke: Thu hồi + reason: Lý do + expand: Mở rộng … + revoke_confirm: Bạn có chắc chắn muốn thu hồi huy hiệu này? + edit_badges: Sửa huy hiệu + grant_badge: Cấp huy hiệu + granted_badges: Cấp huy hiệu + grant: Cấp + no_user_badges: "%{name} chưa được cấp bất kỳ huy hiệu nào." + no_badges: Không có huy hiệu có thể được cấp. + none_selected: "Chọn một huy hiệu để bắt đầu" + allow_title: Cho phép huy hiệu được sử dụng như là tên + multiple_grant: Có thể được cấp nhiều lần + listable: Hiện huy hiệu trên trang huy hiệu công khai + enabled: Bật huy hiệu + icon: Biểu tượng + image: Hình ảnh + icon_help: "Sử dụng Font Awesome class hoặc URL của ảnh" + query: Truy vấn huy hiệu (SQL) + target_posts: Truy vấn bài viết mục tiêu + auto_revoke: Chạy truy vấn hủy bỏ hàng ngày + show_posts: Hiện bài viết được cấp huy hiệu trên trang huy hiệu + trigger: Phát động + trigger_type: + none: "Cập nhật hàng ngày" + post_revision: "Khi người dùng sửa hoặc tạo bài viết" + trust_level_change: "Khi người dùng thay đổi mức độ tin cậy" + user_change: "Khi người dùng được sửa hoặc được tạo" + preview: + link_text: "Xem trước cấp huy hiệu" + plan_text: "Xem trước kế hoạch truy vấn" + modal_title: "Xem trước truy vấn huy hiệu" + sql_error_header: "Có lỗi xảy ra với truy vấn." + error_help: "Xem các liên kết sau đây để trợ giúp các truy vấn huy hiệu." + bad_count_warning: + header: "CẢNH BÁO!" + text: "Thiếu mẫu cấp độ huy hiệu, điều này xảy ra khi truy vấn huy hiệu trả về IDs tài khoản hoặc IDs bài viết không tồn tại. Điều này có thể gây ra kết quả bất ngờ sau này - hãy kiểm tra lại truy vấn của bạn lần nữa." + no_grant_count: "Không có huy hiệu nào được gán." + grant_count: + other: "%{count} huy hiệu đã được gán." + sample: "Ví dụ:" + grant: + with: %{username} + with_post: %{username} for post in %{link} + with_post_time: %{username} viết bài trong %{link} lúc %{time} + with_time: %{username} lúc %{time} + emoji: + title: "Emoji" + help: "Thêm emoji mới có sẵn cho tất cả mọi người. (MẸO: kéo & thả nhiều file cùng lúc)" + add: "Thêm emoji mới" + name: "Tên" + image: "Hình ảnh" + delete_confirm: "Bạn có chắc chắn muốn xóa emoji :%{name}:?" + embedding: + get_started: "Nếu bạn muốn nhúng Discourse trên một website khác, bắt đầu bằng cách thêm host." + confirm_delete: "Bạn muốn xóa host này?" + sample: "Sử dụng mã HTML sau vào website để tạo và nhúng các chủ đề. Thay thế REPLACE_ME với Canonical URL của trang bạn muốn nhúng." + title: "Nhúng" + host: "Cho phép Host" + edit: "sửa" + category: "Đăng vào Danh mục" + add_host: "Thêm Host" + settings: "Thiết lập nhúng" + feed_settings: "Cấu hình Feed" + feed_description: "Cung cấp RSS/ATOM cho website để cải thiện khả năng Discourse import nội dung của bạn." + crawling_settings: "Cấu hình Crawler" + crawling_description: "Khi Discourse tạo chủ đề cho các bài viết của bạn, nếu không có RSS/ATOM thì hệ thống sẽ thử phân tích nội dung HTML. Đôi khi có thể gặp khó khăn khi trích xuất nội dung, vì vậy hệ thống cung cấp khả năng chỉ định quy tắc CSS để giúp quá trình trích xuất dễ dàng hơn." + embed_by_username: "Tên thành viên để tạo chủ đề" + embed_post_limit: "Số lượng tối đa bài viết được nhúng" + embed_username_key_from_feed: "Key to pull discourse username from feed" + embed_truncate: "Cắt ngắn các bài viết được nhúng" + embed_whitelist_selector: "Bộ chọn các thành phần CSS được hỗ trợ khi nhúng" + embed_blacklist_selector: "CSS selector for elements that are removed from embeds" + feed_polling_enabled: "Nhập bài viết bằng RSS/ATOM" + feed_polling_url: "URL của RSS/ATOM để thu thập" + save: "Lưu thiết lập nhúng" + permalink: + title: "Liên kết cố định" + url: "URL" + topic_id: "ID Chủ đề" + topic_title: "Chủ đề" + post_id: "ID Bài viết" + post_title: "Bài viết" + category_id: "ID Danh mục" + category_title: "Danh mục" + external_url: "URL Bên ngoài" + delete_confirm: Bạn có chắc chắn muốn xóa liên kết tĩnh này? + form: + label: "Mới:" + add: "Thêm" + filter: "Tìm kiếm (URL hoặc External URL)" + lightbox: + download: "tải" + search_help: + title: 'Tìm giúp đỡ' + keyboard_shortcuts_help: + title: 'Phím tắt' + jump_to: + title: 'Chuyển đến' + home: 'g, h Trang chủ' + latest: 'g, l Cuối cùng' + new: 'g, n Mới' + unread: 'g, u Chưa đọc' + categories: 'g, c Danh mục' + top: 'g, t Trên' + bookmarks: 'g, b Đánh dấu' + profile: 'g, p Hồ sơ' + messages: 'g, m Tin nhắn' + navigation: + title: 'Điều hướng' + jump: '# Đến bài viết #' + back: 'u Quay lại' + up_down: 'k/j Move selection ↑ ↓' + open: 'o or Enter Mở chủ để đã chọn' + next_prev: 'shift+j/shift+k Next/previous section' + application: + title: 'Ứng dụng' + create: 'c Tạo mới chủ đề' + notifications: 'n Mở thông báo' + hamburger_menu: '= Mở menu mobile' + user_profile_menu: 'p Mở trình đơn thành viên' + show_incoming_updated_topics: '. Show updated topics' + search: '/ Tìm kiếm' + help: '? Mở trợ giúp bàn phím' + dismiss_new_posts: 'x, r Dismiss New/Posts' + dismiss_topics: 'x, t Bỏ qua bài viết' + log_out: 'shift+z shift+z Đăng xuất' + actions: + title: 'Hành động' + bookmark_topic: 'f Chuyển chủ đề đánh dấu' + pin_unpin_topic: 'shift+p Pin/Unpin bài viết' + share_topic: 'shift+s Chia sẻ bài viết' + share_post: 's Chia sẻ bài viết' + reply_as_new_topic: 't Trả lời như là một liên kết đến bài viết' + reply_topic: 'shift+r Trả lời bài viết' + reply_post: 'r Trả lời bài viết' + quote_post: 'q Trích dẫn bài viết' + like: 'l Thích bài viết' + flag: '! Đánh dấu bài viết' + bookmark: 'b Đánh dấu bài viết' + edit: 'e Sửa bài viết' + delete: 'd Xóa bài viết' + mark_muted: 'm, m Mute topic' + mark_regular: 'm, r Chủ đề thông thường (mặc định)' + mark_tracking: 'm, t Theo dõi chủ đề' + mark_watching: 'm, w theo dõi chủ đề' + badges: + earned_n_times: + other: "Đạt được huy hiệu này %{count} lần" + title: Huy hiệu + badge_count: + other: "%{count} Huy hiệu" + more_badges: + other: "+%{count} Thêm" + granted: + other: "%{count} được cấp" + select_badge_for_title: Chọn huy hiệu để sử dụng như là tên + none: "" + badge_grouping: + getting_started: + name: Bắt đầu + community: + name: Cộng đồng + trust_level: + name: Độ tin cậy + other: + name: Khác + posting: + name: Đang đăng bài + google_search: | +

    Tìm kiếm với Google

    +

    +

    +

    diff --git a/config/locales/client.zh_CN.yml b/config/locales/client.zh_CN.yml index 540d6654c54..a05c3ce697f 100644 --- a/config/locales/client.zh_CN.yml +++ b/config/locales/client.zh_CN.yml @@ -58,7 +58,7 @@ zh_CN: almost_x_years: other: "近%{count}年" date_month: "MMMDo" - date_year: "YY-MM-D" + date_year: "YY年MMM" medium: x_minutes: other: "%{count}分钟" @@ -81,6 +81,8 @@ zh_CN: other: "%{count}月后" x_years: other: "%{count}年后" + previous_month: '上个月' + next_month: '下个月' share: topic: '分享本主题的链接' post: '#%{postNumber} 楼' @@ -91,6 +93,8 @@ zh_CN: email: '用电子邮件发送这个链接' action_codes: split_topic: "于%{when}分割了该主题" + invited_user: "于%{when}邀请%{who}" + removed_user: "于%{when}移除%{who}" autoclosed: enabled: '于%{when}关闭' disabled: '于%{when}开启' @@ -111,6 +115,19 @@ zh_CN: disabled: '于%{when}移除出列表' topic_admin_menu: "主题管理操作" emails_are_disabled: "所有的出站邮件已经被管理员全局禁用。将不发送任何邮件提醒。" + s3: + regions: + us_east_1: "美国东部(N. Virginia)" + us_west_1: "美国西部(N. California)" + us_west_2: "美国西部(Oregon)" + us_gov_west_1: "AWS GovCloud(美国)" + eu_west_1: "欧洲(Ireland)" + eu_central_1: "欧洲(Frankfurt)" + ap_southeast_1: "亚洲太平洋(Singapore)" + ap_southeast_2: "亚洲太平洋(Sydney)" + ap_northeast_1: "亚洲太平洋(Tokyo)" + ap_northeast_2: "亚洲太平洋(Seoul)" + sa_east_1: "南美(Sao Paulo)" edit: '编辑本主题的标题和分类' not_implemented: "非常抱歉,此功能暂时尚未实现!" no_value: "否" @@ -142,22 +159,25 @@ zh_CN: more: "更多" less: "更少" never: "从未" + every_30_minutes: "每半小时" + every_hour: "每小时" daily: "每天" weekly: "每周" every_two_weeks: "每两周" every_three_days: "每三天" - max_of_count: "最多 {{count}}" + max_of_count: "不超过 {{count}}" alternation: "或" character_count: other: "%{count} 个字符" suggested_topics: title: "推荐主题" + pm_title: "推荐消息" about: simple_title: "关于" title: "关于%{title}" stats: "站点统计" - our_admins: "我们的管理员们" - our_moderators: "我们的版主们" + our_admins: "我们的管理员" + our_moderators: "我们的版主" stat: all_time: "所有时间内" last_7_days: "7 天以内" @@ -168,7 +188,7 @@ zh_CN: user_count: "新用户" active_user_count: "活跃用户" contact: "联系我们" - contact_info: "在遇到影响站点的重大错误或者紧急事件时,请通过 %{contact_info} 联系我们。" + contact_info: "当有重大或者紧急事件时,请通过 %{contact_info} 联系我们。" bookmarked: title: "书签" clear_bookmarks: "删除书签" @@ -183,7 +203,7 @@ zh_CN: remove: "删除书签" confirm_clear: "你确定要删除该主题的所有书签吗?" topic_count_latest: - other: "{{count}} 个新主题或更新的主题。" + other: "{{count}} 个近期的主题或更新的主题。" topic_count_unread: other: "{{count}} 未读主题。" topic_count_new: @@ -200,18 +220,18 @@ zh_CN: uploaded: "上传完成!" enable: "启用" disable: "禁用" - undo: "重做" + undo: "重置" revert: "撤销" failed: "失败" switch_to_anon: "匿名模式" switch_from_anon: "退出匿名模式" banner: close: "隐藏横幅。" - edit: "编辑横幅>>" + edit: "编辑该横幅 >>" choose_topic: none_found: "没有找到主题。" title: - search: "通过名称、URL 或者 ID,搜索主题:" + search: "通过名称、URL 或者 ID 搜索主题:" placeholder: "在此输入主题标题" queue: topic: "主题:" @@ -226,7 +246,7 @@ zh_CN: has_pending_posts: other: "这个主题有 {{count}} 个帖子等待审核" confirm: "保存修改" - delete_prompt: "你确定要删除%{username}?这将删除他们的所有帖子并封禁这个邮箱和 IP 地址。" + delete_prompt: "你确定要删除%{username}吗?这将删除他们的所有帖子并封禁这个邮箱和 IP 地址。" approval: title: "帖子需要审核" description: "我们已经保存了你的帖子,不过帖子需要由管理员先审核才能显示。请耐心。" @@ -267,13 +287,25 @@ zh_CN: total_rows: other: "%{count} 位用户" groups: + empty: + posts: "此小组的成员没有发表过帖子。" + members: "此小组没有成员。" + mentions: "此小组没有被提及过。" + messages: "此小组没有发送过消息。" + topics: "此小组的成员没有发表过主题。" + add: "添加" + selector_placeholder: "添加成员" + owner: "所有者" visible: "群组对所有用户可见" title: other: "群组" members: "成员" + topics: "主题" posts: "帖子" + mentions: "提及" + messages: "消息" alias_levels: - title: "谁能把组名作为别名?" + title: "谁能给这个小组发送消息和@提醒?" nobody: "无人" only_admins: "仅管理员" mods_and_admins: "仅版主与管理员" @@ -282,6 +314,19 @@ zh_CN: trust_levels: title: "当这些用户加入时,信任等级将自动赋予给他们:" none: "无" + notifications: + watching: + title: "关注" + description: "你将会在该消息中的每个新帖子发布后收到通知,并且会显示新回复数量。" + tracking: + title: "追踪" + description: "你会在别人@你或回复你时收到通知,并且新帖数量也将在这些主题后显示。" + regular: + title: "普通" + description: "如果某人@你或者回复你,你将收到通知。" + muted: + title: "忽略" + description: "你不会收到组内关于新主题中的任何通知。" user_action_groups: '1': "给赞" '2': "被赞" @@ -291,7 +336,6 @@ zh_CN: '6': "回应" '7': "提到" '9': "引用" - '10': "星标" '11': "编辑" '12': "发送条目" '13': "收件箱" @@ -301,6 +345,7 @@ zh_CN: all_subcategories: "全部" no_subcategory: "无" category: "分类" + category_list: "显示分类列表" reorder: title: "重排序分类" title_long: "重新排序分类列表" @@ -355,16 +400,15 @@ zh_CN: invited_by: "邀请者为" trust_level: "用户级别" notifications: "通知" + statistics: "统计" desktop_notifications: label: "桌面通知" not_supported: "通知功能暂不支持该浏览器。抱歉。" perm_default: "启用通知" perm_denied_btn: "拒绝授权" - perm_denied_expl: "你拒绝了通知权限。在你的浏览器中允许启用通知,然后再点击按钮。(桌面:点击最左边的图标。移动设备:“站点设置”。)" + perm_denied_expl: "你拒绝了通知提醒的权限。设置浏览器允许通知提醒。" disable: "禁用通知" - currently_enabled: "(目前已启用)" enable: "启用通知" - currently_disabled: "(目前已禁用)" each_browser_note: "注意:你必须在任何你使用的浏览器中更改这项设置。" dismiss_notifications: "标记所有为已读" dismiss_notifications_tooltip: "标记所有未读通知为已读" @@ -388,7 +432,7 @@ zh_CN: tracked_categories: "已追踪" tracked_categories_instructions: "你将会自动追踪这些分类中的所有新主题。新帖数量将在每个主题后显示。" muted_categories: "已屏蔽" - muted_categories_instructions: "你不会收到这些分类的新主题的任何通知,他们也不会出现在你的未读标签中。" + muted_categories_instructions: "你不会收到这些分类中的任何新主题通知,并且他们将不会出现在最新列表中。" delete_account: "删除我的帐号" delete_account_confirm: "你真的要永久删除自己的账号吗?删除之后无法恢复!" deleted_yourself: "你的帐号已被成功删除。" @@ -398,16 +442,25 @@ zh_CN: users: "用户" muted_users: "忽略" muted_users_instructions: "禁止任何关于这些用户的通知。" + muted_topics_link: "显示已忽略的主题" + automatically_unpin_topics: "当我完整阅读了主题时自动解除置顶。" staff_counters: - flags_given: "有效标记" - flagged_posts: "被报告的帖子" - deleted_posts: "删除的帖子" + flags_given: "有用的标记" + flagged_posts: "被标记的帖子" + deleted_posts: "已删除的帖子" suspensions: "禁用的" warnings_received: "警告" messages: all: "所有" - mine: "我的" - unread: "未读" + inbox: "收件箱" + sent: "已发送" + archive: "存档" + groups: "我的小组" + bulk_select: "选择消息" + move_to_inbox: "移动到收件箱" + move_to_archive: "存档" + failed_to_move: "移动选中消息失败(可能你的网络出问题了)" + select_all: "全选" change_password: success: "(电子邮件已发送)" in_progress: "(正在发送电子邮件)" @@ -439,7 +492,7 @@ zh_CN: upload_title: "上传图片" upload_picture: "上传图片" image_is_not_a_square: "注意:我们已经裁剪了你的图片;它不是正方形的。" - cache_notice: "你已经成功地改变了你的个人头像,但是鉴于浏览器缓存可能要一段时间才能生效。" + cache_notice: "你已经成功地修改了你的个人头像,但是鉴于浏览器缓存可能需要一段时间才会生效。" change_profile_background: title: "个人资料背景" instructions: "个人资料背景将被居中,且默认宽度为 850px。" @@ -452,21 +505,20 @@ zh_CN: ok: "我们将邮件跟你确认" invalid: "请填写正确的电子邮箱地址" authenticated: "你的电子邮箱已经被 {{provider}} 验证了。" + frequency_immediately: "如果你没有阅读过我们想寄给你的内容,我们会立即发送电子邮件给你。" frequency: - zero: "如果你没有阅读过我们想寄给你的内容,我们会立即发送电子邮件给你。" - one: "如果你很久都没有出现了,我们才会发送电子邮件给你。" other: "我们只会在你最近 {{count}} 分钟内没有访问时才会发送电子邮件给你。" name: - title: "名字" - instructions: "你的全名(可选)" + title: "昵称" + instructions: "你的昵称(可选)" instructions_required: "你的全名" - too_short: "你设置的名字太短了" - ok: "你的名字符合要求" + too_short: "你设置的昵称太短了" + ok: "你的昵称符合要求" username: title: "用户名" instructions: "唯一,没有空格,简短" short_instructions: "其他人可以用 @{{username}} 来提及你" - available: "你的用户名可用" + available: "你可以用这个用户名" global_match: "电子邮箱与注册用户名相匹配" global_mismatch: "已被注册。试试 {{suggestion}} ?" not_available: "不可用。试试 {{suggestion}} ?" @@ -491,17 +543,34 @@ zh_CN: title: "用户资料徽章" website: "网站" email_settings: "电子邮箱" + like_notification_frequency: + title: "通知用户赞的消息" + always: "始终" + first_time_and_daily: "每天第一个被赞帖子" + first_time: "第一个被赞的帖子" + never: "从不" + email_previous_replies: + title: "包括邮件底下的以前的回复" + unless_emailed: "除非曾经发送过" + always: "总是" + never: "从不" email_digests: title: "当我不访问时,向我的邮箱发送最新信息:" + every_30_minutes: "每半小时" + every_hour: "每小时" daily: "每天" every_three_days: "每三天" weekly: "每周" every_two_weeks: "每两周" + include_tl0_in_digests: "在摘要邮件中包含新用户的帖子" + email_in_reply_to: "在邮件中包含回复的摘要文本" email_direct: "当有人引用我、回复我的帖子,@提及你或邀请你至主题时发送一封邮件给我" email_private_messages: "当有人给发消息给我时发送一封邮件给我" email_always: "即使我在论坛中活跃时也发送电子邮件提醒给我" other_settings: "其它" categories_settings: "分类" + enable_mailing_list: + other: "你确定你想收到每一个新帖子的邮件吗?

    每天你大约会收到 {{count}} 封邮件。" new_topic_duration: label: "近期主题的条件:" not_viewed: "我还没有浏览它们" @@ -527,7 +596,8 @@ zh_CN: user: "邀请用户" sent: "已发送" none: "没有未接受状态的邀请。" - truncated: "只显示前 {{count}} 个邀请。" + truncated: + other: "只显示前·{{count}}个邀请。" redeemed: "确认邀请" redeemed_tab: "已确认" redeemed_tab_with_count: "已确认({{count}})" @@ -562,6 +632,31 @@ zh_CN: same_as_email: "你的密码与电子邮箱相同。" ok: "你设置的密码符合要求。" instructions: "至少需要 %{count} 个字符。" + summary: + title: "概要" + stats: "统计" + time_read: "阅读时间" + topic_count: + other: "创建的主题" + post_count: + other: "创建的帖子" + likes_given: + other: "给赞" + likes_received: + other: "被赞" + days_visited: + other: "访问天数" + posts_read: + other: "阅读过的帖子" + top_replies: "热门回复" + no_replies: "暂无回复。" + more_replies: "更多回复" + top_topics: "热门帖子" + no_topics: "暂无主题。" + more_topics: "更多主题" + top_badges: "热门勋章" + no_badges: "暂无徽章。" + more_badges: "更多徽章" associated_accounts: "登录" ip_address: title: "最后使用的 IP 地址" @@ -587,26 +682,34 @@ zh_CN: server: "服务器错误" forbidden: "访问被阻止" unknown: "错误" + not_found: "没有找到网页" desc: network: "请检查你的网络连接。" network_fixed: "似乎恢复正常了。" server: "错误代码:{{status}}" forbidden: "你没有权限读这个。" + not_found: "噢!程式要加载的URL并不存在。" unknown: "出错了。" buttons: back: "返回" again: "再试一次" fixed: "载入页面" close: "关闭" - assets_changed_confirm: "此网页刚刚更新. 刷新查看新版本?" + assets_changed_confirm: "网站刚刚更新了。刷新使用新版本?" logout: "你已登出。" refresh: "刷新" read_only_mode: - enabled: "只读模式已启用。你可以继续浏览这个站点但是无法进行交互操作。" + enabled: "站点正处于只读模式。你可以继续浏览,但是回复、赞和其他操作暂时被禁用。" login_disabled: "只读模式下不允许登录。" + logout_disabled: "站点在只读模式下无法登出。" too_few_topics_and_posts_notice: "让我们开始讨论!目前有 %{currentTopics} / %{requiredTopics} 个主题和 %{currentPosts} / %{requiredPosts} 个帖子。新访客需要能够阅读和回复一些讨论。" too_few_topics_notice: "让我们开始讨论!目前有 %{currentTopics} / %{requiredTopics} 个主题。新访客需要能够阅读和回复一些讨论。" too_few_posts_notice: "让我们开始讨论!目前有 %{currentPosts} / %{requiredPosts} 个帖子。新访客需要能够阅读和回复一些讨论。" + logs_error_rate_notice: + reached: "%{timestamp}:目前的错误率 %{rate} 已经达到了站点设置中的 %{siteSettingRate}。" + exceeded: "%{timestamp}:目前的错误率 %{rate} 已经超出了站点设置中的 %{siteSettingRate}。" + rate: + other: "%{count} 错误/%{duration}" learn_more: "了解更多..." year: '年' year_desc: '365 天以前创建的主题' @@ -625,27 +728,19 @@ zh_CN: signup_cta: sign_up: "注册" hide_session: "明天提醒我" - hide_forever: "不,谢谢" + hide_forever: "不了" hidden_for_session: "好的,我会在明天提醒你。不过你任何时候都可以使用“登录”来创建账户。" intro: "你好!:heart_eyes: 看起来你挺喜欢这个讨论,但是你还没有注册账户。" - value_prop: "当你创建了账户,我们能准确地追踪你的阅读进度,所以你能够在下一次访问时知道你读过了什么。你也可以收到网页和邮件通知,特别是有新帖子的时候。并且你可以赞任何帖子来分享你的感谢。:heartbeat:" - methods: - sso: "注册很容易:你只要在主站点建立一个账户。" - only_email: "注册很容易:只需要一个邮箱和密码。" - only_other: "使用%{provider}的账号注册。" - one_and_email: "使用%{provider}的账号,或者邮箱和密码来注册。" - multiple_no_email: "注册很容易:使用我们提供的 %{count} 种第三方登录方式。" - multiple: "注册很容易:使用我们提供的 %{count} 种第三方登录方式,或是邮箱和密码。" - unknown: "不支持的登录方法" + value_prop: "当你创建了账户,我们能准确地追踪你的阅读进度,所以你能够在下一次访问时回到你上次阅读到的地方。你也可以在有新帖子的时候收到网页和邮件通知。并且你可以赞任何帖子来分享你的感谢。:heartbeat:" summary: enabled_description: "你正在查看这个主题的概括版本:由社群认定的最有意思的帖子。" - description: "有 {{count}} 个回复。" - description_time: "主题有 {{count}} 个回复,大约要花 {{readingTime}} 分钟阅读。" + description: "有 {{replyCount}} 个回复。" + description_time: "有 {{replyCount}} 个回复,大约要花 {{readingTime}} 分钟阅读。" enable: '概括本主题' disable: '显示所有帖子' deleted_filter: enabled_description: "这个主题包含已删除的帖子,他们已经被隐藏。" - disabled_description: "主题中被删除的帖子已显示。" + disabled_description: "显示了主题中已删除的帖子。" enable: "隐藏已删除的帖子" disable: "显示已删除的帖子" private_message_info: @@ -694,6 +789,9 @@ zh_CN: admin_not_allowed_from_ip_address: "你不能从这个 IP 地址以管理员身份登录。" resend_activation_email: "点击此处重新发送激活邮件。" sent_activation_email_again: "我们在 {{currentEmail}} 又发送了一封激活邮件给你,邮件送达可能需要几分钟;请检查一下你邮箱的垃圾邮件文件夹。" + to_continue: "请先登录" + preferences: "你需要登录才能更改用户设置。" + forgot: "我记不得账号详情了" google: title: "使用 Google 帐号登录" message: "正使用 Google 帐号验证登录(请确保浏览器没有禁止弹出窗口)" @@ -703,6 +801,9 @@ zh_CN: twitter: title: "使用 Twitter 帐号登录" message: "正使用 Twitter 帐号验证登录(请确保浏览器没有禁止弹出窗口)" + instagram: + title: "用 Instagram 登录" + message: "使用 Instagram 帐号验证登录(请确保浏览器没有禁止弹出窗口)" facebook: title: "使用 Facebook 帐号登录" message: "正使用 Facebook 帐号验证登录(请确保浏览器没有禁止弹出窗口)" @@ -716,8 +817,13 @@ zh_CN: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + emoji: "Emoji :)" + more_emoji: "更多…" options: "选项" whisper: "密语" add_warning: "这是一个正式的警告。" @@ -728,6 +834,7 @@ zh_CN: saved_local_draft_tip: "已本地保存" similar_topics: "你的主题有些类似于..." drafts_offline: "离线草稿" + group_mentioned: "使用{{group}},你可以通知{{count}}人。" error: title_missing: "缺少标题" title_too_short: "标题太短,至少 {{min}} 个字符" @@ -750,7 +857,7 @@ zh_CN: show_edit_reason: "(添加编辑理由)" reply_placeholder: "正文。使用 Markdown、BBCode 或 HTML 格式化内容。拖拽或粘贴图片。" view_new_post: "浏览你的新帖子。" - saving: "保存中..." + saving: "保存中" saved: "已保存!" saved_draft: "帖子还没写完,点击继续" uploading: "上传中..." @@ -765,6 +872,7 @@ zh_CN: link_description: "在此输入链接描述" link_dialog_title: "插入链接" link_optional_text: "可选标题" + link_placeholder: "http://example.com \"可选文字\"" quote_title: "引用" quote_text: "引用" code_title: "预格式化文本" @@ -777,10 +885,11 @@ zh_CN: heading_title: "标题" heading_text: "标题头" hr_title: "分割线" - undo_title: "撤销" - redo_title: "重做" help: "Markdown 编辑帮助" toggler: "隐藏或显示编辑面板" + modal_ok: "确认" + modal_cancel: "取消" + cant_send_pm: "抱歉,你不能向 %{username} 发送私信。" admin_options_title: "本主题可选设置" auto_close: label: "自动关闭主题时间:" @@ -795,13 +904,17 @@ zh_CN: title: "使用@名字提及到你,回复你的帖子和主题,消息等等的通知消息" none: "现在无法载入通知" more: "浏览以前的通知" - total_flagged: "被报告帖子的总数" + total_flagged: "被标记帖子的总数" mentioned: "

    {{username}} {{description}}

    " + group_mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " + liked_2: "

    {{username}}、{{username2}} {{description}}

    " + liked_many: + other: "

    {{username}}、{{username2}}和其他 {{count}} 人{{description}}

    " private_message: "

    {{username}} {{description}}

    " invited_to_private_message: "

    {{username}} {{description}}

    " invited_to_topic: "

    {{username}} {{description}}

    " @@ -809,6 +922,8 @@ zh_CN: moved_post: "

    {{username}} 移动了 {{description}}

    " linked: "

    {{username}} {{description}}

    " granted_badge: "

    获得“{{description}}”

    " + group_message_summary: + other: "

    {{count}} 条消息在你的{{group_name}}组内的收件箱中

    " alt: mentioned: "被提及" quoted: "被引用" @@ -823,8 +938,10 @@ zh_CN: moved_post: "你的帖子被移动自" linked: "链接至你的帖子" granted_badge: "勋章授予" + group_message_summary: "在群组收件箱中的消息" popup: mentioned: '{{username}}在“{{topic}}”提到了你 - {{site_title}}' + group_mentioned: '{{username}}在“{{topic}}”提到了你 - {{site_title}}' quoted: '{{username}}在“{{topic}}”引用了你的帖子 - {{site_title}}' replied: '{{username}}在“{{topic}}”回复了你 - {{site_title}}' posted: '{{username}}在“{{topic}}”中发布了帖子 - {{site_title}}' @@ -836,9 +953,9 @@ zh_CN: from_my_computer: "来自我的设备" from_the_web: "来自网络" remote_tip: "图片链接" - remote_tip_with_attachments: "图片或文件链接({{authorized_extensions}})" + remote_tip_with_attachments: "链接到图片或文件 {{authorized_extensions}}" local_tip: "从你的设备中选择图片" - local_tip_with_attachments: "从你的设备中选择图片或文件({{authorized_extensions}})" + local_tip_with_attachments: "从你的设备 {{authorized_extensions}} 选择图片或文件" hint: "(你也可以通过拖放至编辑器的方式来上传)" hint_for_supported_browsers: "你也可以通过拖放或复制粘帖至编辑器" uploading: "上传中" @@ -872,12 +989,14 @@ zh_CN: current_user: '去你的用户页面' topics: bulk: + unlist_topics: "未在列表上的主题" reset_read: "设为未读" delete: "删除主题" - dismiss_posts: "忽略帖子" - dismiss_posts_tooltip: "清除这些帖子的未读计数但当有新帖子时在我的未读列表中继续显示他们" - dismiss_topics: "忽略主题" - dismiss_topics_tooltip: "停止当有新帖子时在我的未读列表中显示这些主题" + dismiss: "忽略" + dismiss_read: "忽略所有未读" + dismiss_button: "忽略..." + dismiss_tooltip: "仅忽略新帖子或停止跟踪主题" + also_dismiss_topics: "停止跟踪这些主题它们将不再作为未读给我显示" dismiss_new: "设为已读" toggle: "切换批量选择" actions: "批量操作" @@ -889,7 +1008,7 @@ zh_CN: selected: other: "你已经选择了 {{count}}个主题" none: - unread: "你没有未阅主题。" + unread: "你没有未读主题。" new: "你没有新主题可读。" read: "你尚未阅读任何主题。" posted: "你尚未在任何主题中发帖。" @@ -900,8 +1019,8 @@ zh_CN: top: "没有最佳主题。" search: "没有搜索结果。" educate: - new: '

    近期的主题将在这里显示。

    默认情况下,近两天创建的主题是近期主题,并会显示一个的标识。

    你可以在你的设置中改变这一行为。

    ' - unread: '

    这里是你的未读主题。

    默认情况下,下述主题将被认为是未读的,并会显示未读数目:1 如果你:

    • 创建了该主题
    • 回复了该主题
    • 阅读该主题超过 4 分钟

    或者你在主题底部的通知控制中选择了追踪或监视。

    你可以改变你的用户设置

    ' + new: '

    这里显示了对于你的近期主题。

    默认情况下,下述主题将被放在近期中。如果他们是这 2 天内创建的,还会显示一个近期标志。

    访问你的用户设置修改。

    ' + unread: '

    这里显示了你的未读主题。

    默认情况下,下述主题会被放在未读中。并且会在旁边显示未读的数量1。如果你:

    • 创建了该主题
    • 回复了该主题
    • 阅读该主题超过 4 分钟

    或者你在主题底部的通知控制中选择了追踪或监视。

    访问你的用户设置修改未读设置。

    ' bottom: latest: "没有更多主题可看了。" hot: "没有更多热门主题可看了。" @@ -919,8 +1038,14 @@ zh_CN: change_notification_state: "您现在的提醒状态是" filter_to: "本主题中的 {{post_count}} 帖" create: '新主题' - create_long: '创建一个新主题' + create_long: '创作新主题' private_message: '发送消息' + archive_message: + help: '移动消息到存档' + title: '存档' + move_to_inbox: + title: '移动到收件箱' + help: '移动消息到收件箱' list: '主题' new: '新主题' unread: '未读' @@ -951,7 +1076,7 @@ zh_CN: options: "主题选项" show_links: "显示此主题中的链接" toggle_information: "切换主题详细" - read_more_in_category: "想阅读更多内容?浏览 {{catLink}} 或 {{latestLink}} 里的其它主题。" + read_more_in_category: "想阅读更多内容?浏览 {{catLink}}或{{latestLink}}里的其它主题。" read_more: "想阅读更多内容?{{catLink}} 或 {{latestLink}}。" read_more_MF: "还有 { UNREAD, plural, =0 {} one { 1 个未读主题} other { # 个未读主题 } } { NEW, plural, =0 {} one { {BOTH, select, true{和 } false {} other{}} 1 个新主题} other { {BOTH, select, true{和 } false {} other{}} # 个新主题} }可以阅读,或者{CATEGORY, select, true {浏览{catLink}中的其他主题} false {{latestLink}} other {}}" browse_all_categories: 浏览所有分类 @@ -965,6 +1090,7 @@ zh_CN: auto_close_title: '自动关闭设置' auto_close_save: "保存" auto_close_remove: "不要自动关闭该主题" + auto_close_immediate: "主题中的上个帖子是 %{hours} 小时前发出的,所以主题将会立即关闭。" progress: title: 主题进度 go_top: "顶部" @@ -985,7 +1111,7 @@ zh_CN: '2_8': '因为你在追踪此分类,所以你将收到相关通知。' '2_4': '因为你在此主题内发表了回复,所以你将收到相关通知。' '2_2': '因为你在追踪此主题,所以你将收到相关通知。' - '2': '因为你阅读了此主题,所以你将收到相关通知。' + '2': '因为你阅读了该主题,所以你将收到相关通知。' '1_2': '如果某人@你或者回复你,你将收到通知。' '1': '如果某人@你或者回复你,你将收到通知。' '0_7': '你将忽略关于此分类的所有通知。' @@ -1010,11 +1136,11 @@ zh_CN: title: "普通" description: "如果某人@你或者回复你,你将收到通知。" muted_pm: - title: "防打扰" + title: "忽略" description: "你不会收到关于此消息的任何通知。" muted: - title: "防打扰" - description: "你不会收到关于此主题的任何通知,也不会在你的未阅选项卡中显示。" + title: "忽略" + description: "你将不会再收到这个主题的任何通知,也不会出现在最新列表中。" actions: recover: "撤销删除主题" delete: "删除主题" @@ -1045,36 +1171,33 @@ zh_CN: title: '分享' help: '分享一个到本帖的链接' flag_topic: - title: '报告' - help: '私下报告本帖以引起注意或者发送一条匿名通知' - success_message: '你已成功报告本帖。' + title: '标记' + help: '私下标记本帖以引起注意或者发送一条匿名通知' + success_message: '你已经成功标记该主题。' feature_topic: - title: "设为精华主题" + title: "聚焦该主题" pin: "将该主题置于{{categoryLink}}分类最上方至" confirm_pin: "你已经有了{{count}}个置顶主题。太多的置顶主题可能会困扰新用户和访客。你确定想要在该分类再置顶一个主题么?" unpin: "从{{categoryLink}}分类最上方移除主题。" unpin_until: "从{{categoryLink}}分类最上方移除主题或者延迟至%{until}。" pin_note: "用户可以给自己解除置顶主题。" pin_validation: "置顶该主题需要一个日期。" + not_pinned: "{{categoryLink}}没有置顶主题。" already_pinned: - zero: "{{categoryLink}}没有置顶主题。" - one: "现在置顶在{{categoryLink}}分类的主题:1。" - other: "现在置顶在{{categoryLink}}分类的主题:{{count}}。" + other: "现在置顶在{{categoryLink}}分类的主题:{{count}}" pin_globally: "将主题置于所有主题列表最上方至" confirm_pin_globally: "你已经有了{{count}}个全局置顶主题。太多的置顶主题可能会困扰新用户和访客。你确定想要再全局置顶一个主题么?" unpin_globally: "将主题从所有主题列表的最上方移除。" unpin_globally_until: "从所有主题列表最上方移除主题或者延迟至%{until}。" global_pin_note: "用户可以自己解除主题状态。" + not_pinned_globally: "没有全局置顶的主题。" already_pinned_globally: - zero: "没有全局置顶的主题。" - one: "现在全局置顶的主题:1。" - other: "现在全局置顶的主题:{{count}}。" + other: "现在全局置顶的主题:{{count}}" make_banner: "将主题置为所有页面顶端的横幅主题。" remove_banner: "移除所有页面顶端的横幅主题。" banner_note: "用户能点击关闭隐藏横幅。一次只能有一个横幅主题。" - already_banner: - zero: "没有横幅主题。" - one: "当前有一个横幅主题。" + no_banner_exists: "没有横幅主题。" + banner_exists: "当前有一个横幅主题。" inviting: "邀请中..." automatically_add_to_groups_optional: "这个邀请也包括了这些群组的权限:(可选,仅管理员)" automatically_add_to_groups_required: "这个邀请也包括了访问这些群组的权限:(可选,仅管理员)" @@ -1086,6 +1209,7 @@ zh_CN: success: "我们已经邀请了该用户加入这个消息交流。" error: "抱歉,在邀请该用户时发生了错误。" group_name: "群组名" + controls: "主题控制" invite_reply: title: ' 邀请' username_placeholder: "用户名" @@ -1158,7 +1282,7 @@ zh_CN: show_full: "显示所有帖子" show_hidden: '查看隐蔽内容' deleted_by_author: - other: "(帖子被作者撤销,如无标记,将在 %{count} 小时后被自动删除)" + other: "(帖子被作者撤销,如过没有标记,将在 %{count} 小时后被自动删除)" expand_collapse: "展开/折叠" gap: other: "查看 {{count}} 个隐藏回复" @@ -1170,9 +1294,8 @@ zh_CN: other: "{{count}} 赞" has_likes_title: other: "{{count}} 人赞了该贴" + has_likes_title_only_you: "你赞了该贴" has_likes_title_you: - zero: "你赞了该贴" - one: "你和其他 1 人赞了该贴" other: "你和其他 {{count}} 人赞了该贴" errors: create: "抱歉,在创建你的帖子时发生了错误。请重试。" @@ -1193,82 +1316,81 @@ zh_CN: via_email: "通过电子邮件发送的帖子" whisper: "这个帖子是只对版主可见的密语" wiki: - about: "这个帖子是维基;基础用户能编辑它" + about: "这个帖子是维基" archetypes: save: '保存选项' + few_likes_left: "感谢你的赞!你今天只能再多赞几次了。" controls: reply: "开始给本帖撰写回复" - like: "赞本帖" + like: "点个赞" has_liked: "你已经赞了本帖" undo_like: "撤销赞" edit: "编辑本帖" edit_anonymous: "抱歉,但是你需要登录后才能编辑该贴。" - flag: "私下报告本帖以提醒管理人员关注或发送私信通知" + flag: "私下标记本帖以提醒管理人员关注或发送私信通知" delete: "删除本帖" undelete: "恢复本帖" share: "分享一个到本帖的链接" more: "更多" delete_replies: confirm: - other: "你也想要删除 {{count}} 个直接回复这个帖子的回复么?" - yes_value: "是,删除回复" + other: "你也想要删除 {{count}} 个回复这个帖子的相关帖子么?" + yes_value: "是,一并删除相关回复" no_value: "否,仅删除该帖" admin: "帖子管理" wiki: "使其成为维基帖子" unwiki: "使其成为普通帖子" - convert_to_moderator: "增加职员颜色" - revert_to_regular: "移除职员颜色" + convert_to_moderator: "添加管理人员颜色标识" + revert_to_regular: "移除管理人员颜色标识" rebake: "重建 HTML" unhide: "显示" + change_owner: "更改所有权" actions: - flag: '报告' + flag: '标记' defer_flags: - other: "推迟的标记" + other: "推迟处理标记" it_too: - off_topic: "同时报告" - spam: "同时报告" - inappropriate: "同时报告" - custom_flag: "同时报告" + off_topic: "一起标记" + spam: "一起标记" + inappropriate: "一起标记" + custom_flag: "一起标记" bookmark: "同时添加书签" like: "赞" vote: "同时投票支持" undo: - off_topic: "撤销报告" - spam: "撤销报告" - inappropriate: "撤销报告" + off_topic: "撤回标记" + spam: "撤回报告" + inappropriate: "撤回报告" bookmark: "撤销书签" like: "撤销赞" vote: "撤销投票" people: - off_topic: "{{icons}} 标记为偏离主题" - spam: "{{icons}} 标记为垃圾" - spam_with_url: "{{icons}} 标记为垃圾信息" - inappropriate: "{{icons}} 标记此为不当内容" - notify_moderators: "{{icons}} 向版主报告它" - notify_moderators_with_url: "{{icons}} 通知了版主" - notify_user: "{{icons}} 发送了一个消息" - notify_user_with_url: "{{icons}} 发送了一个消息" - bookmark: "{{icons}} 对它做了书签" - like: "{{icons}} 赞了它" - vote: "{{icons}} 对它投票" + off_topic: "标记为偏离主题" + spam: "标记为垃圾信息" + inappropriate: "标记为不当内容" + notify_moderators: "通知版主" + notify_user: "发送消息" + bookmark: "书签收藏" + like: "赞了它" + vote: "已给本帖投票" by_you: - off_topic: "你报告它偏离主题" - spam: "你报告它为垃圾信息" - inappropriate: "你报告它为不当内容" - notify_moderators: "你向版主报告了它" + off_topic: "你标记其偏离了主题" + spam: "你标记其为垃圾信息" + inappropriate: "你标记其为不当内容" + notify_moderators: "你标记了本帖要求管理人员处理" notify_user: "你已经发了一个消息给该用户" bookmark: "你对该帖做了书签" like: "你赞了它" vote: "你对该帖投票支持" by_you_and_others: off_topic: - other: "你和其他 {{count}} 人报告它偏离主题" + other: "你和其他 {{count}} 人标记其偏离主题" spam: - other: "你和其他 {{count}} 人报告它为垃圾信息" + other: "你和其他 {{count}} 人标记其为垃圾信息" inappropriate: - other: "你和其他 {{count}} 人报告它为不当内容" + other: "你和其他 {{count}} 人标记其为不当内容" notify_moderators: - other: "你和其他 {{count}} 人报告它需要审核" + other: "你和其他 {{count}} 人标记了本帖要求管理人员处理" notify_user: other: "你和 {{count}} 个其他用户发了一个消息给该用户" bookmark: @@ -1279,13 +1401,13 @@ zh_CN: other: "你和其他 {{count}} 人支持这个帖子" by_others: off_topic: - other: "{{count}} 人报告它偏离主题" + other: "{{count}} 人标记其偏离主题" spam: - other: "{{count}} 人报告它为垃圾信息" + other: "{{count}} 人标记其为垃圾信息" inappropriate: - other: "{{count}} 人报告它为不当内容" + other: "{{count}} 人标记其为不当内容" notify_moderators: - other: "{{count}} 人报告它需要修改" + other: "{{count}} 人标记本帖要求管理人员处理" notify_user: other: "{{count}} 人给这个用户发送了消息" bookmark: @@ -1294,10 +1416,6 @@ zh_CN: other: "{{count}} 人赞了这个帖子" vote: other: "{{count}} 人支持这个帖子" - edits: - one: 1 次编辑 - other: "{{count}} 次编辑" - zero: 未编辑 delete: confirm: other: "你确定要删除这些帖子吗?" @@ -1309,6 +1427,7 @@ zh_CN: last: "最新版" hide: "隐藏版本历史" show: "显示版本历史" + revert: "回退至该版本" comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" displays: inline: @@ -1377,20 +1496,19 @@ zh_CN: notifications: watching: title: "关注" - description: "你将会自动监视这些分类中的所有新主题。你将会收到新帖子和新主题发布的通知,并且新帖数量也将在这些主题后显示。" + description: "你将会自动监视这些分类中的所有新主题。你会收到每个主题中的新帖子通知,并且新帖数量也将在每个主题后显示。" tracking: title: "追踪" - description: "你将会自动追踪这些分类中的所有新主题。新帖数量将在这些主题后显示。" + description: "你将会自动追踪这些分类中的所有新主题。你会在别人@你或回复你的帖子时才会收到通知,并且新帖数量也将在这些主题后显示。" regular: - title: "常规" + title: "普通" description: "如果某人@你或者回复你,你将收到通知。" muted: title: "免打扰" - description: "你不会收到这些分类中的任何新主题通知,并且他们将不会出现在你的未读列表中。" + description: "你不会收到这些分类中的任何新主题通知,并且他们将不会出现在最新列表中。" flagging: - title: '感谢帮助社群远离邪恶!' - private_reminder: '标记是不公开的,只有职员才可以见到' - action: '报告帖子' + title: '感谢你帮助我们建设文明社群!' + action: '标记帖子' take_action: "立即执行" notify_action: '消息' delete_spammer: "删除垃圾发布者" @@ -1400,7 +1518,8 @@ zh_CN: hidden_email_address: "(隐藏)" submit_tooltip: "提交私有标记" take_action_tooltip: "立即采取标记到达限制值时的措施,而不是等待更多的社群标记" - cant: "抱歉,当前你不能报告本帖。" + cant: "抱歉,现在你不能标记本帖。" + notify_staff: '私下通知管理人员' formatted_name: off_topic: "偏题" inappropriate: "不合适" @@ -1412,12 +1531,12 @@ zh_CN: more: "还差 {{n}} 个..." left: "还剩下 {{n}}" flagging_topic: - title: "感谢帮助社群远离邪恶!" - action: "报告帖子" + title: "感谢你帮助我们建设文明社群!" + action: "标记帖子" notify_action: "消息" topic_map: title: "主题概要" - participants_title: "频繁发帖者" + participants_title: "主要发帖者" links_title: "热门链接" links_shown: "显示所有 {{totalLinks}} 个链接..." clicks: @@ -1438,7 +1557,7 @@ zh_CN: help: "主题已经解除置顶;它将以默认顺序显示" pinned_globally: title: "全局置顶" - help: "本主题已置顶;它将始终显示在它所属分类的顶部" + help: "本主题已全局置顶;它始终会在最新列表以及它所属的分类中置顶" pinned: title: "置顶" help: "本主题已置顶;它将始终显示在它所属分类的顶部" @@ -1478,9 +1597,8 @@ zh_CN: with_topics: "%{filter}主题" with_category: "%{category}的%{filter}主题" latest: - title: - zero: "最新" - one: "最新(1)" + title: "最新" + title_with_count: other: "最新({{count}})" help: "最新发布的帖子" hot: @@ -1497,22 +1615,18 @@ zh_CN: title_in: "分类 - {{categoryName}}" help: "归属于不同分类的所有主题" unread: - title: - zero: "未读" - one: "1 个未读主题" - other: "{{count}} 个未读主题" + title: "未读" + title_with_count: + other: "未读({{count}})" help: "你正在监视或追踪的主题中有未阅帖子的主题" lower_title_with_count: - one: "1 条未读" other: "{{count}} 条未读" new: lower_title_with_count: - one: "1 近期" other: "{{count}} 近期" lower_title: "近期" - title: - zero: "近期" - one: "近期(1)" + title: "近期" + title_with_count: other: "近期({{count}})" help: "最近几天创建的主题" posted: @@ -1522,9 +1636,8 @@ zh_CN: title: "书签" help: "你标上书签的主题" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}}(1)" + title: "{{categoryName}}" + title_with_count: other: "{{categoryName}}({{count}})" help: "在 {{categoryName}} 分类中热门的主题" top: @@ -1605,52 +1718,53 @@ zh_CN: refresh_report: "刷新报告" start_date: "开始日期" end_date: "结束日期" + groups: "所有群组" commits: latest_changes: "最近的更新:请经常升级!" by: "来自" flags: - title: "报告" - old: "旧的" + title: "标记" + old: "历史" active: "待处理" - agree: "已批准" + agree: "确认标记" agree_title: "确认这个标记有效且正确" - agree_flag_modal_title: "批准并..." - agree_flag_hide_post: "批准(隐藏并发送私信)" + agree_flag_modal_title: "确认标记并执行..." + agree_flag_hide_post: "确认标记(隐藏帖子并发送私信)" agree_flag_hide_post_title: "隐藏帖子并自动发送消息要求用户修改" agree_flag_restore_post: "同意 (还原帖子)" agree_flag_restore_post_title: "还原这篇帖子" - agree_flag: "批准这个标记" - agree_flag_title: "批准这个标记并且保持帖子不变" - defer_flag: "推迟" + agree_flag: "确认标记" + agree_flag_title: "确认标记,不对帖子进行操作" + defer_flag: "推迟处理" defer_flag_title: "移除标记;这次不处理。" delete: "删除" delete_title: "删除标记指向的帖子。" - delete_post_defer_flag: "删除帖子并推迟标记" + delete_post_defer_flag: "删除帖子并推迟处理标记" delete_post_defer_flag_title: "删除此帖;如果这是这个主题内的第一篇帖子则删除主题" - delete_post_agree_flag: "删除帖子并批准此标记" + delete_post_agree_flag: "删除帖子并确认标记" delete_post_agree_flag_title: "删除此帖;如果这是这个主题内的第一篇帖子则删除主题" delete_flag_modal_title: "删除并..." delete_spammer: "删除垃圾发布者" delete_spammer_title: "移除该用户及其的所有帖子和主题。" - disagree_flag_unhide_post: "不批准(不隐藏帖子)" - disagree_flag_unhide_post_title: "清除此帖的任何报告,并使其重新可见" - disagree_flag: "不批准" - disagree_flag_title: "拒绝这个报告,无效或不正确" + disagree_flag_unhide_post: "否决(显示帖子)" + disagree_flag_unhide_post_title: "删除此帖的所有标记并使其重新可见" + disagree_flag: "否决" + disagree_flag_title: "否却该标记(该标记无效或不正确)" clear_topic_flags: "完成" - clear_topic_flags_title: "这个主题已被调查且提案已被解决。单击完成以删除报告。" + clear_topic_flags_title: "主题的问题已经已被调查且提案已被解决。单击完成以删除报告。" more: "(更多回复...)" dispositions: - agreed: "已批准" - disagreed: "未批准" - deferred: "推迟" - flagged_by: "报告者为" + agreed: "已确认" + disagreed: "被否决" + deferred: "已推迟" + flagged_by: "标记者" resolved_by: "已解决,被" took_action: "立即执行" system: "系统" error: "出错了" reply_message: "回复" - no_results: "没有报告" - topic_flagged: "这个主题已被报告。" + no_results: "当前没有标记。" + topic_flagged: "主题已经被标记。" visit_topic: "浏览主题才能操作" was_edited: "帖子在第一次标记后被编辑" previous_flags_count: "这篇帖子已经被标示了 {{count}} 次。" @@ -1680,15 +1794,24 @@ zh_CN: delete_confirm: "删除这个小组吗?" delete_failed: "无法删除小组。如果该小组是自动生成的,则不可删除。" delete_member_confirm: "从群组“%{group}”中移除“%{username}”?" + delete_owner_confirm: "移除'%{username}'的权限?" name: "名字" add: "添加" add_members: "添加成员" custom: "定制" + bulk_complete: "用户已被添加到小组。" + bulk: "批量添加到小组" + bulk_paste: "粘贴用户名或email列表,一行一个:" + bulk_select: "(选择一个小组)" automatic: "自动" automatic_membership_email_domains: "用户注册时邮箱域名若与列表完全匹配则自动添加至这个群组:" automatic_membership_retroactive: "应用同样的邮件域名规则添加已经注册的用户" default_title: "群组内所有用户的默认头衔" primary_group: "自动设置为主要群组" + group_owners: 所有者 + add_owners: 添加所有者 + incoming_email: "自定义进站电子邮件地址" + incoming_email_placeholder: "输入邮箱地址" api: generate_master: "生成主 API 密钥" none: "当前没有可用的 API 密钥。" @@ -1762,7 +1885,7 @@ zh_CN: is_disabled: "站点设置中禁用了恢复功能。" label: "恢复" title: "恢复该备份" - confirm: "你确定要重置该备份吗?" + confirm: "你确定要从该备份中恢复吗?" rollback: label: "回滚" title: "将数据库回滚到之前的工作状态" @@ -1775,7 +1898,7 @@ zh_CN: button_text: "导出" button_title: user: "以CSV格式导出所有用户列表" - staff_action: "以CSV格式导出所有职员操作历史记录" + staff_action: "以CSV格式导出所有管理人员操作历史记录" screened_email: "以 CSV 格式导出所有已显示的电子邮件列表。" screened_ip: "以 CSV 格式导出所有已显示的IP地址列表。" screened_url: "以 CSV 格式导出所有已显示的URL列表。" @@ -1817,6 +1940,14 @@ zh_CN: color: "颜色" opacity: "透明度" copy: "复制" + email_templates: + title: "邮件模板" + subject: "主题" + multiple_subjects: "这个邮件模板包括多个主题。" + body: "内容" + none_selected: "选择一个邮件模板开始编辑。" + revert: "撤销更变" + revert_confirm: "你确定要撤销你的更变吗?" css_html: title: "CSS/HTML" long_title: "自定义 CSS 和 HTML" @@ -1827,7 +1958,7 @@ zh_CN: new_name: "新的颜色方案" copy_name_prefix: "复制于" delete_confirm: "删除这个颜色方案?" - undo: "重做" + undo: "重置" undo_title: "撤销你对这个颜色的编辑至上一次保存的状态。" revert: "撤销" revert_title: "重置这个颜色至 Discourse 的默认颜色方案" @@ -1861,18 +1992,18 @@ zh_CN: love: name: '赞' description: "赞按钮的颜色。" - wiki: - name: '维基编辑' - description: "维基帖子的背景颜色" email: - title: "电子邮件" + title: "邮件" settings: "设置" - all: "所有" + templates: "模板" + preview_digest: "预览" sending_test: "发送测试邮件..." error: "错误 - %{server_error}" test_error: "发送测试邮件时遇到问题。请再检查一遍邮件设置,确认你的主机没有封锁邮件链接,然后重试。" sent: "已发送" skipped: "跳过" + received: "收到" + rejected: "拒绝" sent_at: "发送时间" time: "时间" user: "用户" @@ -1882,7 +2013,6 @@ zh_CN: send_test: "发送测试电子邮件" sent_test: "已发送!" delivery_method: "发送方式" - preview_digest: "预览" preview_digest_desc: "预览发送给不活跃用户的摘要邮件内容。" refresh: "刷新" format: "格式" @@ -1891,6 +2021,26 @@ zh_CN: last_seen_user: "用户最后登录时间:" reply_key: "回复关键字" skipped_reason: "跳过理由" + incoming_emails: + from_address: "来自" + to_addresses: "发至" + cc_addresses: "抄送" + subject: "主题" + error: "错误" + none: "没有找到进站邮件。" + modal: + title: "进站邮件详情" + error: "错误" + headers: "头部" + subject: "主题" + body: "内容" + rejection_message: "拒绝邮件" + filters: + from_placeholder: "from@example.com" + to_placeholder: "to@example.com" + cc_placeholder: "cc@example.com" + subject_placeholder: "主题..." + error_placeholder: "错误" logs: none: "未发现日志。" filters: @@ -1909,6 +2059,7 @@ zh_CN: ip_address: "IP" topic_id: "主题 ID" post_id: "帖子 ID" + category_id: "分类 ID" delete: '删除' edit: '编辑' save: '保存' @@ -1939,6 +2090,7 @@ zh_CN: change_site_setting: "更改站点设置" change_site_customization: "更改站点自定义" delete_site_customization: "删除站点自定义" + change_site_text: "更改站点文字" suspend_user: "封禁用户" unsuspend_user: "解禁用户" grant_badge: "授予徽章" @@ -1949,6 +2101,16 @@ zh_CN: impersonate: "检视" anonymize_user: "匿名用户" roll_up: "回退 IP 封禁" + change_category_settings: "更改分类设置" + delete_category: "删除分类" + create_category: "创建分类" + block_user: "封禁用户" + unblock_user: "解封用户" + grant_admin: "授予管理员权限" + revoke_admin: "撤销管理员权限" + grant_moderation: "授予版主权限" + revoke_moderation: "撤销版主权限" + backup_operation: "备份操作" screened_emails: title: "被屏蔽的邮件地址" description: "当有人试图用以下邮件地址注册时,将受到阻止或其它系统操作。" @@ -1998,7 +2160,7 @@ zh_CN: new: "新建" active: "活跃" pending: "待定" - staff: '职员' + staff: '管理人员' suspended: '禁止登录' blocked: '禁止参与讨论' suspect: '怀疑' @@ -2013,10 +2175,10 @@ zh_CN: pending: '等待审核用户' newuser: '信用等级为0的用户(新用户)' basic: '信用等级为1的用户(基本用户)' - regular: '信用等级为2的用户(成员)' - leader: '信用等级为3的用户(常规)' - elder: '信用等级为4的用户(领导)' - staff: "职员" + member: '信用等级为2的用户(成员)' + regular: '信用等级为3的用户(活跃)' + leader: '信用等级为4的用户(资深)' + staff: "管理人员" admins: '管理员' moderators: '版主' blocked: '被封用户' @@ -2046,6 +2208,7 @@ zh_CN: moderator: "版主?" admin: "管理员?" blocked: "已封?" + staged: "暂存?" show_admin_profile: "管理员" edit_title: "编辑头衔" save_title: "保存头衔" @@ -2071,8 +2234,8 @@ zh_CN: posts_read_count: 已阅帖子数量 post_count: 创建的帖子数量 topics_entered: 已查看的主题数量 - flags_given_count: 所做报告数量 - flags_received_count: 收到报告数量 + flags_given_count: 提交标记数量 + flags_received_count: 被他人标记数量 warnings_received_count: 收到警告 flags_given_received_count: '给出的标记 / 收到的标记' approve: '批准' @@ -2107,22 +2270,25 @@ zh_CN: deactivate_failed: "在停用用户帐号时发生了错误。" unblock_failed: '在解除用户帐号封禁时发生了错误。' block_failed: '在封禁用户帐号时发生了错误。' + block_confirm: '你确定要封禁用户吗?他们将没有办法创建任何主题或者帖子。' + block_accept: '是的,封禁用户' deactivate_explanation: "已停用的用户必须重新验证他们的电子邮件。" suspended_explanation: "一个被封禁的用户不能登录。" block_explanation: "被封禁的用户不能发表主题或者评论。" + stage_explanation: "暂存用户只能通过邮件在特定主题内发表帖子。" trust_level_change_failed: "改变用户等级时出现了一个问题。" suspend_modal_title: "被禁用户" trust_level_2_users: "二级信任等级用户" - trust_level_3_requirements: "三级信任等级需求" + trust_level_3_requirements: "信任等级 3 要求" trust_level_locked_tip: "信任等级已经被锁定,系统将不会升降用户的信任等级" trust_level_unlocked_tip: "信任等级已经解锁,系统将自动升降用户的信任等级" lock_trust_level: "锁定信任等级" unlock_trust_level: "解锁信任等级" tl3_requirements: - title: "3 级信任等级的需求" - table_title: "在过去的 100 天中:" - value_heading: "价值" - requirement_heading: "需求" + title: "信任等级 3 的要求" + table_title: "在最近%{time_period}天:" + value_heading: "当前" + requirement_heading: "要求" visits: "访问" days: "天数" topics_replied_to: "回复的主题" @@ -2130,17 +2296,17 @@ zh_CN: topics_viewed_all_time: "已阅的主题 (全部)" posts_read: "已读帖子" posts_read_all_time: "已读的帖子 (全部)" - flagged_posts: "被报告的帖子" - flagged_by_users: "标记的用户" + flagged_posts: "被标记的帖子" + flagged_by_users: "标记其的用户" likes_given: "给出的赞" likes_received: "收到的赞" - likes_received_days: "收到的赞:每天" + likes_received_days: "收到的赞:独立天数" likes_received_users: "收到的赞:每用户" - qualifies: "符合等级3的信用度" - does_not_qualify: "未符合等级3的信用度" + qualifies: "符合信任等级3要求" + does_not_qualify: "不符合信任等级3要求" will_be_promoted: "将在近期被提升。" will_be_demoted: "将在近期被降级。" - on_grace_period: "目前在升级优惠阶段,将不会被降级。" + on_grace_period: "目前在升级宽限期,不会被降级。" locked_will_not_be_promoted: "信任等级被锁定。将不再被提升。" locked_will_not_be_demoted: "信任等级被锁定。将不再被降级。" sso: @@ -2181,8 +2347,15 @@ zh_CN: confirm: '确认' dropdown: "下拉菜单" site_text: - none: "选择一个内容类型开始编辑。" + description: "你可以自定义论坛的任意文本。请按以下搜索:" + search: "搜索你想要编辑的文本" title: '文本内容' + edit: '编辑' + revert: "撤销更变" + revert_confirm: "你确定要撤销你的更变吗?" + go_back: "返回搜索" + recommended: "我们建议自定义以下文本以符合你的需求:" + show_overriden: '只显示修改过的' site_settings: show_overriden: '只显示修改过的' title: '设置' @@ -2222,6 +2395,7 @@ zh_CN: badge: 徽章 display_name: 显示名称 description: 描述 + long_description: 详情 badge_type: 徽章分类 badge_grouping: 群组 badge_groupings: @@ -2240,7 +2414,7 @@ zh_CN: grant_badge: 授予徽章 granted_badges: 已授予的徽章 grant: 授予 - no_user_badges: "%{name} 尚未被授予徽章。" + no_user_badges: "%{name}尚未被授予任何徽章。" no_badges: 没有可供授予的徽章。 none_selected: "选择一个徽章开始" allow_title: 允许将徽章用作头衔 @@ -2262,7 +2436,7 @@ zh_CN: trust_level_change: "当用户信任等级改变时" user_change: "当用户被编辑或创建时" preview: - link_text: "预览授予的徽章" + link_text: "预览将授予的徽章" plan_text: "预览查询计划" modal_title: "徽章查询预览" sql_error_header: "查询时出错。" @@ -2270,9 +2444,8 @@ zh_CN: bad_count_warning: header: "警告!" text: "有授予的样本消失。这在徽章查询返回用户 ID 或者帖子 ID 不存在的时候发生。这可能导致未预期的结果发生——请再次检查你的查询。" + no_grant_count: "没有徽章可以被授予。" grant_count: - zero: "没有徽章可以被授予。" - one: "已授予 1 个徽章。" other: "已授予 %{count} 个徽章。" sample: "样本:" grant: @@ -2284,7 +2457,7 @@ zh_CN: title: "Emoji" help: "增加所有人可用的 emoji。(高端技巧:一次性拖进多个文件)" add: "增加新的 Emoji" - name: "姓名" + name: "名称" image: "图片" delete_confirm: "你确定要删除 :%{name}: emoji 么?" embedding: @@ -2372,7 +2545,7 @@ zh_CN: reply_post: 'r 回复帖子' quote_post: 'q 引用帖子' like: 'l 赞帖子' - flag: '! 报告帖子' + flag: '! 标记帖子' bookmark: 'b 给帖子添加书签' edit: 'e 编辑帖子' delete: 'd 删除帖子' @@ -2381,6 +2554,10 @@ zh_CN: mark_tracking: 'm 然后 t 追踪主题' mark_watching: 'm 然后 w 关注主题' badges: + earned_n_times: + other: "授予徽章 %{count} 次" + granted_on: "授予于%{date}" + others_count: "其他有该徽章的人(%{count})" title: 徽章 allow_title: "能用作头衔" multiple_grant: "能被授予多次" @@ -2403,97 +2580,6 @@ zh_CN: name: 其它 posting: name: 发帖 - badge: - editor: - name: 编辑 - description: 首个帖子编辑 - basic_user: - name: 基础 - description: 授予所有常用社群功能 - member: - name: 成员 - description: 已授予邀请权限 - regular: - name: 常规 - description: 已授予重分类、重命名、跟踪链接和贵宾室 - leader: - name: 领导 - description: 已授予 全局编辑、固定、关闭、存档、分割和合并 - welcome: - name: 欢迎 - description: 得到一个赞 - autobiographer: - name: 自传作者 - description: 已填写用户资料信息 - anniversary: - name: 年度纪念日 - description: 一年活跃用户,至少发了一个帖子 - nice_post: - name: 不错的帖子 - description: 一个帖子收到 10 个赞。这个徽章可以被授予多次 - good_post: - name: 实用的帖子 - description: 一个帖子收到 25 个赞。这个徽章可以被授予多次 - great_post: - name: 非常棒的帖子 - description: 一个帖子收到 50 个赞。这个徽章可以被授予多次 - nice_topic: - name: 好的主题 - description: 一个帖子收到 10 个赞。这个徽章可以被授予多次 - good_topic: - name: 不错的主题 - description: 一个帖子收到 25 个赞。这个徽章可以被授予多次 - great_topic: - name: 很棒的主题 - description: 一个帖子收到 50 个赞。这个徽章可以被授予多次 - nice_share: - name: 分享得很好 - description: 分享了一个有 25 个独立访问者的帖子 - good_share: - name: 分享得不错 - description: 分享了一个有 300 个独立访问者的帖子 - great_share: - name: 分享得很好 - description: 分享了一个有 1000 个独立访问者的帖子 - first_like: - name: 首个赞 - description: 已赞了一个帖子 - first_flag: - name: 首个标记 - description: 标记帖子 - promoter: - name: 推广 - description: 已邀请了 1 个用户 - campaigner: - name: 资深推广 - description: 邀请3个基础用户(信任等级1) - champion: - name: 元老推广 - description: 邀请5个会员(信任等级2) - first_share: - name: 首次分享 - description: 已分享了一个帖子 - first_link: - name: 首个链接 - description: 已经添加了一个内部链接至另一个主题 - first_quote: - name: 第一次引用 - description: 引用了一个用户 - read_guidelines: - name: 阅读指引 - description: 阅读社群指引 - reader: - name: 读者 - description: 阅读一个超过 100 个帖子的主题中的每一个帖子 - popular_link: - name: 流行链接 - description: 发布了超过 50 次点击的外部链接 - hot_link: - name: 热门链接 - description: 发布了超过 300 次点击的外部链接 - famous_link: - name: 著名链接 - description: 发布了超过 1000 次点击的外部链接 google_search: |

    用 Google 搜索

    diff --git a/config/locales/client.zh_TW.yml b/config/locales/client.zh_TW.yml index 092068234b1..03b74dc0de0 100644 --- a/config/locales/client.zh_TW.yml +++ b/config/locales/client.zh_TW.yml @@ -8,6 +8,9 @@ zh_TW: js: number: + format: + separator: "." + delimiter: "," human: storage_units: format: '%n %u' @@ -18,12 +21,17 @@ zh_TW: kb: KB mb: MB tb: TB + short: + thousands: "{{number}} 千" + millions: "{{number}} 百萬" dates: time: "h:mm" long_no_year: "MMM D h:mm a" long_no_year_no_time: "MMM D" + full_no_year_no_time: "MMMM Do" long_with_year: "YYYY MMM D h:mm a" long_with_year_no_time: "YYYY MMM D" + full_with_year_no_time: "YYYY MMMM Do" long_date_with_year: "'YY MMM D LT" long_date_without_year: "MMM D, LT" long_date_with_year_without_time: "'YY MMM D" @@ -73,6 +81,8 @@ zh_TW: other: "%{count} 個月後" x_years: other: "%{count} 年後" + previous_month: '上個月' + next_month: '下個月' share: topic: '在此話題內分享連結' post: '文章 #%{postNumber}' @@ -81,6 +91,23 @@ zh_TW: facebook: '在 Facebook 分享此連結' google+: '在 Google+ 分享此連結' email: '以電子郵件分享此連結' + action_codes: + split_topic: "於 %{when} 切分此討論話題" + autoclosed: + enabled: '於 %{when} 關閉' + disabled: '於 %{when} 開啟' + closed: + enabled: '於 %{when} 關閉' + disabled: '於 %{when} 開啟' + archived: + enabled: '於 %{when} 封存' + disabled: '於 %{when} 解除封存' + pinned: + enabled: '於 %{when} 置頂' + disabled: '於 %{when} 解除置頂' + pinned_globally: + enabled: '於 %{when} 全局置頂' + disabled: '於 %{when} 解除置頂' topic_admin_menu: "討論話題管理員操作" emails_are_disabled: "管理員已經停用了所有外寄郵件功能。通知信件都不會寄出。" edit: '編輯此討論話題的標題與分類' @@ -96,6 +123,7 @@ zh_TW: admin_title: "管理員" flags_title: "投訴" show_more: "顯示更多" + show_help: "選項" links: "連結" links_lowercase: other: "鏈結" @@ -167,6 +195,7 @@ zh_TW: saved: "儲存完畢!" upload: "上傳" uploading: "正在上傳..." + uploading_filename: "{{filename}} 上傳中..." uploaded: "上傳完畢!" enable: "啟用" disable: "停用" @@ -174,8 +203,10 @@ zh_TW: revert: "回復" failed: "失敗" switch_to_anon: "匿名模式" + switch_from_anon: "登出匿名模式" banner: close: "關閉此橫幅" + edit: "編輯此橫幅 >>" choose_topic: none_found: "未找到任何討論話題。" title: @@ -191,8 +222,9 @@ zh_TW: edit: "編輯" cancel: "取消" view_pending: "觀看等待審核的貼文" + has_pending_posts: + other: "本主題仍有 {{count}}篇貼文等待審核" confirm: "儲存變更" - delete_prompt: "您確定要刪除 %{username} 這個帳號嗎?這會同時將該帳號的所有貼文一併刪除,並封鎖他的電子郵件與 IP。" approval: title: "貼文需等待審核" description: "貼文已經送出,但必須等待管理者審核過後才會出現在板上,請耐心等候。" @@ -233,20 +265,31 @@ zh_TW: total_rows: other: "%{count} 用戶" groups: + add: "新增" + selector_placeholder: "新增成員" + owner: "擁有者" visible: "群組可被所有用戶看到" title: other: "群組" members: "成員" + topics: "主題" posts: "文章" + messages: "訊息" alias_levels: - title: "誰能用此群組作為別名?" + title: "誰可以在這個群組發送訊息和使用@提到" nobody: "沒有" only_admins: "只有管理員" mods_and_admins: "只有板主以及管理員" members_mods_and_admins: "只有群組成員、板主以及管理員" everyone: "所有人" trust_levels: + title: "當這些成員加入時自動提升信任等級:" none: "無" + notifications: + watching: + title: "關注" + regular: + title: "一般" user_action_groups: '1': "已按讚" '2': "已收到的讚" @@ -256,7 +299,6 @@ zh_TW: '6': "回應" '7': "提到" '9': "引用" - '10': "收藏" '11': "編輯" '12': "送出的項目" '13': "收件匣" @@ -266,6 +308,13 @@ zh_TW: all_subcategories: "所有" no_subcategory: "無" category: "分類" + reorder: + title: "重新排序分類" + title_long: "重新排序分類列表" + fix_order: "固定位置" + fix_order_tooltip: "並非所有的分類皆有唯一的位置參數, 可能會有出乎意料之外的結果." + save: "儲存順序" + position: "位置" posts: "貼文" topics: "標題" latest: "最近" @@ -293,6 +342,8 @@ zh_TW: topics_entered: "已閱讀的討論話題" post_count: "# 文章" confirm_delete_other_accounts: "你確定要刪除這些帳號?" + user_fields: + none: "(選擇一個選項)" user: said: "{{username}}:" profile: "基本資料" @@ -316,9 +367,7 @@ zh_TW: perm_default: "啟用桌面通知" perm_denied_btn: "權限被拒絕" disable: "停用通知" - currently_enabled: "(當前已啟用)" enable: "啟用通知" - currently_disabled: "(當前已關閉)" dismiss_notifications: "全部標記為已讀" dismiss_notifications_tooltip: "標記所有未讀通知為已讀" disable_jump_reply: "不要在回覆之後直接跳到我的文章" @@ -339,7 +388,6 @@ zh_TW: watched_categories: "關注" tracked_categories: "追蹤" muted_categories: "靜音" - muted_categories_instructions: "你將不會收到此分類的新討論話題通知,以及不會出現在未讀欄內。" delete_account: "刪除我的帳號" delete_account_confirm: "你真的要刪除帳號嗎?此動作不能被還原!" deleted_yourself: "你的帳號已成功刪除" @@ -357,8 +405,9 @@ zh_TW: warnings_received: "警告" messages: all: "全部" - mine: "我的" - unread: "未讀" + archive: "封存" + groups: "我的群組" + move_to_archive: "封存" change_password: success: "( 寄出的郵件 )" in_progress: "( 正在傳送郵件 )" @@ -367,6 +416,7 @@ zh_TW: set_password: "設定密碼" change_about: title: "修改關於我" + error: "變更值時發生錯誤。" change_username: title: "修改用戶名稱" confirm: "如果你修改了你的用戶名稱,之前引用你的文章或以 @用戶名稱 提到你的連結都將失效,你確定要修改嗎?" @@ -401,10 +451,6 @@ zh_TW: ok: "我們將寄一封確認郵件給您。" invalid: "請輸入有效的電子郵件地址。" authenticated: "你的 Email 已由 {{provider}} 驗證完成。" - frequency: - zero: "如果您沒有閱讀過重要通知,我們會立即發送電子郵件給您。" - one: "我們只會在您 1 分鐘內沒有活動時,才會寄送電郵通知給您。" - other: "我們只會在您 {{count}} 分鐘內沒有活動時,才會寄送電郵通知給您。" name: title: "名稱" instructions: "您的全名 (選填)。" @@ -474,7 +520,6 @@ zh_TW: title: "邀請" user: "受邀請的用戶" sent: "送出" - truncated: "顯示前 {{count}} 個邀請。" redeemed: "已接受的邀請" redeemed_at: "接受日期" pending: "尚未接受的邀請" @@ -528,6 +573,7 @@ zh_TW: server: "伺服器錯誤" forbidden: "拒絕存取" unknown: "錯誤" + not_found: "找不到頁面" desc: network: "請檢查你的網絡連線。" network_fixed: "似乎沒有問題了" @@ -543,7 +589,6 @@ zh_TW: logout: "已登出" refresh: "重新整理" read_only_mode: - enabled: "管理員開啟了唯讀模式。你可以繼續瀏覽網站,但一些互動功能可能無法使用。" login_disabled: "在唯讀模式下不能登入" learn_more: "進一步了解..." year: '年' @@ -560,10 +605,10 @@ zh_TW: last_reply_lowercase: 最新回覆 replies_lowercase: other: 回覆 + signup_cta: + sign_up: "註冊" summary: enabled_description: "你正在檢視此討論話題的摘要:在這個社群裡最熱門的文章。" - description: "共有 {{count}} 個回覆。" - description_time: "共有 {{count}} 個回覆,大約需要 {{readingTime}} 分鐘閱讀。" enable: '以摘要檢視此討論話題' disable: '顯示所有文章' deleted_filter: @@ -602,6 +647,7 @@ zh_TW: email_placeholder: "電子郵件地址或用戶名稱" caps_lock_warning: "大寫鎖定中" error: "未知的錯誤" + rate_limit: "嘗試重新登入前請先等待" blank_username_or_password: "請輸入你的電子郵件或者用戶名稱,以及密碼。" reset_password: '重設密碼' logging_in: "登入中..." @@ -615,6 +661,7 @@ zh_TW: admin_not_allowed_from_ip_address: "你無法透過此 IP 登入成為管理員。" resend_activation_email: "按這裡重新寄出啟用帳號的電子郵件。" sent_activation_email_again: "我們已經將啟用帳號的電子郵件寄至 {{currentEmail}},你可能幾分鐘後才會收到,如果一直沒收到,請檢查垃圾郵件資料夾。" + to_continue: "請登入" google: title: "使用 Google 帳號" message: "使用 Google 帳號認証 (請確定你的網頁瀏覽器未阻擋彈出視窗)" @@ -637,9 +684,16 @@ zh_TW: google: "Google" twitter: "Twitter" emoji_one: "Emoji One" + shortcut_modifier_key: + shift: 'Shift' + ctrl: 'Ctrl' + alt: 'Alt' composer: - emoji: "Emoji :smile:" + more_emoji: "更多..." + options: "選項" + whisper: "密談" add_warning: "這是正式警告。" + toggle_whisper: "切換密談" posting_not_on_topic: "你想要回覆哪個討論話題?" saving_draft_tip: "正在儲存..." saved_draft_tip: "儲存完畢" @@ -666,7 +720,7 @@ zh_TW: edit_reason_placeholder: "你為什麼做編輯?" show_edit_reason: "(請加入編輯原因)" view_new_post: "檢視你的新文章。" - saving: "正在儲存..." + saving: "正在儲存" saved: "儲存完畢!" saved_draft: "草稿待完成,點擊繼續。" uploading: "正在上傳..." @@ -693,10 +747,11 @@ zh_TW: heading_title: "標頭" heading_text: "標頭" hr_title: "分隔線" - undo_title: "復原" - redo_title: "重做" help: "Markdown 編輯說明" toggler: "隱藏或顯示編輯面板" + modal_ok: "確定" + modal_cancel: "取消" + cant_send_pm: "抱歉,你不能向 %{username} 發送訊息。" admin_options_title: "此討論話題可選用之工作人員設定選項" auto_close: label: "自動關閉主題時間:" @@ -715,7 +770,6 @@ zh_TW: mentioned: "

    {{username}} {{description}}

    " quoted: "

    {{username}} {{description}}

    " replied: "

    {{username}} {{description}}

    " - posted: "

    {{username}} {{description}}

    " edited: "

    {{username}} {{description}}

    " liked: "

    {{username}} {{description}}

    " private_message: "

    {{username}} {{description}}

    " @@ -732,14 +786,17 @@ zh_TW: from_my_computer: "從我的電腦" from_the_web: "從網站" remote_tip: "圖片連結" - remote_tip_with_attachments: "圖片或文件連結 ({{authorized_extensions}})" hint: "(你也可以將檔案拖放至編輯器直接上傳)" uploading: "正在上傳" select_file: "選取檔案" image_link: "連結你的圖片將指向" search: + sort_by: "排序" + select_all: "選擇全部" + clear_all: "清除全部" title: "搜尋討論話題、文章、用戶或分類" no_results: "未找到任何結果。" + no_more_results: "沒有找到更多的結果。" search_help: 搜尋幫助 searching: "正在搜尋..." post_format: "#{{post_number}} {{username}}" @@ -747,6 +804,8 @@ zh_TW: user: "搜尋 @{{username}} 的文章" category: "搜尋 \"{{category}}\" 分類" topic: "搜尋此討論話題" + private_messages: "搜尋訊息" + new_item: "新增" go_back: '返回' not_logged_in_user: '用戶頁面包含目前活動及喜好的總結' current_user: '到你的用戶頁面' @@ -754,10 +813,6 @@ zh_TW: bulk: reset_read: "重設閱讀" delete: "刪除討論話題" - dismiss_posts: "已讀文章" - dismiss_posts_tooltip: "標記此討論話題內未讀文章為已讀" - dismiss_topics: "已讀討論話題" - dismiss_topics_tooltip: "停止顯示這個討論話題在我的未讀清單" dismiss_new: "設定新文章為已讀" toggle: "批量切換選擇討論話題" actions: "批量操作" @@ -778,9 +833,6 @@ zh_TW: bookmarks: "您目前沒有加入書籤的討論話題。" category: "沒有 {{category}} 的討論話題。" top: "沒有精選討論話題。" - educate: - new: '

    你的新討論話題會出現在這裡。

    預設上,2 天內新增的討論話題會被當成新的,並會出現 此一標籤。

    你可以在偏好設定中修改設定。

    ' - unread: '

    你的未讀討論話題會出現在這裡。

    預設上,以下話題會被標示成未讀話題,並且未讀文章數量 1 會顯示:

    • 建立新的討論話題
    • 回覆討論話題
    • 閱讀討論話題超過 4 分鐘

    或若透過討論話題下面的通知設定追蹤或觀察。

    你可以在偏好設定中修改設定。

    ' bottom: latest: "已經沒有其它最近的討論話題了。" hot: "已經沒有其它熱門的討論話題了。" @@ -796,6 +848,8 @@ zh_TW: create: '新討論話題' create_long: '建立新討論話題' private_message: '發送訊息' + archive_message: + title: '封存' list: '討論話題' new: '新討論話題' unread: '未讀' @@ -844,6 +898,7 @@ zh_TW: go_top: "頂部" go_bottom: "底部" go: "前往" + jump_bottom: "跳至最後一則帖子" jump_bottom_with_number: "跳至第 %{post_number} 篇文章" total: 所有文章 current: 目前的文章 @@ -879,7 +934,6 @@ zh_TW: description: "你將不會再收到關於此訊息的通知。" muted: title: "靜音" - description: "你將不會收到任何關於此討論話題的通知,此討論話題也不會出現在你的未讀分頁裡。" actions: recover: "復原已刪除的討論話題" delete: "刪除討論話題" @@ -916,8 +970,7 @@ zh_TW: feature_topic: title: "擁有這個話題" unpin: "取消此主題在{{categoryLink}}類別的置頂狀態" - already_banner: - zero: "沒有頂置的話題。" + not_pinned: "沒有主題被釘選在 {{categoryLink}} ." inviting: "正在邀請..." automatically_add_to_groups_optional: "邀請時同時加入以下群組: (選填, 此為管理員設定)" automatically_add_to_groups_required: "邀請時同時加入以下群組: (必填, 此為管理員設定)" @@ -1001,8 +1054,7 @@ zh_TW: other: "{{count}} 個讚" has_likes_title: other: "{{count}} 個使用者對此文章讚好" - has_likes_title_you: - zero: "你已按讚" + has_likes_title_only_you: "你已按讚" errors: create: "抱歉,建立你的文章時發生錯誤,請再試一次。" edit: "抱歉,編輯你的文章時發生錯誤,請再試一次。" @@ -1020,8 +1072,7 @@ zh_TW: no_value: "否" yes_value: "是" via_email: "本文章透過電子郵件送達" - wiki: - about: "這篇文章設定為 wiki,一般用戶可以編輯它" + whisper: "這文章是版主私人密談" archetypes: save: '儲存選項' controls: @@ -1068,17 +1119,11 @@ zh_TW: like: "撤回讚" vote: "撤回投票" people: - off_topic: "{{icons}} 標示為偏離主題" - spam: "{{icons}} 標示為垃圾文章" - spam_with_url: "{{icons}} 投訴 此為 spam" - inappropriate: "{{icons}} 標示為不適內容" - notify_moderators: "{{icons}} 已通知板主" - notify_moderators_with_url: "{{icons}} 已通知板主" - notify_user: "{{icons}} 已送出訊息" - notify_user_with_url: "{{icons}} 已送出 訊息" - bookmark: "{{icons}} 已加上書籤" - like: "{{icons}} 已按讚" - vote: "{{icons}} 已投票支持" + off_topic: "投訴為離題內容" + spam: "投訴為垃圾內容" + inappropriate: "投訴為不當內容" + notify_moderators: "已通知的版主" + notify_user: "已送出一則訊息" by_you: off_topic: "你已投訴此文章偏離討論話題" spam: "你已投訴此文章為垃圾" @@ -1122,10 +1167,6 @@ zh_TW: other: "{{count}} 人對此按讚" vote: other: "{{count}} 人已投票給此文章" - edits: - one: 1 edit - other: "編輯過 {{count}} 次" - zero: no edits delete: confirm: other: "你確定要刪除這些文章?" @@ -1158,9 +1199,10 @@ zh_TW: view: '檢視分類裡的討論話題' general: '一般' settings: '設定' - topic_template: "主題模板" + topic_template: "主題範本" delete: '刪除分類' create: '新分類' + create_long: '建立新的分類' save: '儲存分類' slug: '分類目錄' slug_placeholder: '(選填) 在 url 加上虛線' @@ -1209,10 +1251,8 @@ zh_TW: title: "一般" muted: title: "靜音" - description: "你將不會收到這些分類中的新討論話題通知,它們也不會出現在你的未讀欄內。" flagging: title: '感謝幫助社群遠離邪惡!' - private_reminder: '標記是不公開的,只有 工作人員才可看到' action: '投訴文章' take_action: "執行動作" notify_action: '訊息' @@ -1259,7 +1299,6 @@ zh_TW: help: "此討論話題已取消置頂,將會以預設順序顯示。" pinned_globally: title: "全區置頂" - help: "此討論話題已全區置頂,將顯示在所有討論話題列表的最上方" pinned: title: "已釘選" help: "此討論話題已置頂,將顯示在它所屬分類話題列表的最上方" @@ -1268,6 +1307,12 @@ zh_TW: posts: "文章" posts_lowercase: "文章" posts_long: "此討論話題有 {{number}} 篇文章" + posts_likes_MF: | + This topic has {count, plural, one {1 reply} other {# replies}} {ratio, select, + low {with a high like to post ratio} + med {with a very high like to post ratio} + high {with an extremely high like to post ratio} + other {}} original_post: "原始文章" views: "觀看" views_lowercase: @@ -1293,10 +1338,9 @@ zh_TW: with_topics: "%{filter} 討論話題" with_category: "%{filter} %{category} 討論話題" latest: - title: - zero: "最新主題" - one: "最新主題 (1)" - other: "最新主題 ({{count}})" + title: "最新" + title_with_count: + other: "最新 ({{count}})" help: "最近的討論話題" hot: title: "熱門" @@ -1312,23 +1356,14 @@ zh_TW: title_in: "分類 - {{categoryName}}" help: "所有討論話題以分類區分" unread: - title: - zero: "未讀" - one: "未讀 (1)" + title: "未讀" + title_with_count: other: "未讀 ({{count}})" help: "你所關注或追蹤的討論話題有未讀文章" lower_title_with_count: - one: "1 個未讀" other: "{{count}} 個未讀" new: - lower_title_with_count: - one: "1 個新話題" - other: "{{count}} 個新話題" lower_title: "新話題" - title: - zero: "新討論話題" - one: "新討論話題 (1)" - other: "新討論話題 ({{count}})" help: "最近幾天建立的主題" posted: title: "我的文章" @@ -1337,9 +1372,8 @@ zh_TW: title: "書籤" help: "你加進書籤的討論話題" category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" + title: "{{categoryName}}" + title_with_count: other: "{{categoryName}} ({{count}})" help: "{{categoryName}} 分類最近的討論話題" top: @@ -1397,13 +1431,14 @@ zh_TW: suspended: '已停權:' private_messages_short: "訊息" private_messages_title: "訊息" + mobile_title: "行動裝置" space_free: "{{size}} 可用空間" uploads: "上傳" backups: "備份檔" traffic_short: "流量" traffic: "網頁應用程式請求數" - page_views: "API Requests" - page_views_short: "API Requests" + page_views: "API 請求數量" + page_views_short: "API 請求數量" show_traffic_report: "顯示詳細的流量報表" reports: today: "今天" @@ -1576,11 +1611,9 @@ zh_TW: is_disabled: "此站設定已關閉復原" label: "還原" title: "復原備份" - confirm: "你確定要復原備份嗎?" rollback: label: "回溯" title: "回溯資料庫到以前的工作階段" - confirm: "你確定要回溯資料庫到以前的工作階段?" export_csv: user_archive_confirm: "你確定要下載你的文章嗎?" success: "開始匯出,處理完畢後將以私人訊息通知你。" @@ -1631,6 +1664,14 @@ zh_TW: color: "顏色" opacity: "不透明度" copy: "複製" + email_templates: + title: "電子郵件範本" + subject: "主旨" + multiple_subjects: "這個電子郵件範本有多重主旨." + body: "內容" + none_selected: "選擇一個電子郵件範本開始編輯" + revert: "恢復變更" + revert_confirm: "你確定要恢復這個變更?" css_html: title: "CSS/HTML" long_title: "CSS 與 HTML 客製化" @@ -1675,13 +1716,10 @@ zh_TW: love: name: '愛' description: "按讚按鈕的顏色" - wiki: - name: '共筆' - description: "共筆文章的背景顏色" email: - title: "電郵" + title: "電子郵件" settings: "設定" - all: "所有" + preview_digest: "預覽文摘" sending_test: "傳送測試郵件" error: "錯誤 - %{server_error}" test_error: "發送測試電子郵件時遇到錯誤。請檢查你輸入的電子郵件地址,並確認網路提供者沒有封鎖郵件的發送,然後再試一次。" @@ -1696,7 +1734,6 @@ zh_TW: send_test: "送出測試Email" sent_test: "已送出!" delivery_method: "傳送方式" - preview_digest: "預覽文摘" refresh: "重新整理" format: "格式" html: "html" @@ -1704,6 +1741,12 @@ zh_TW: last_seen_user: "最近出現的用戶:" reply_key: "回覆金鑰" skipped_reason: "跳過原因" + incoming_emails: + error: "錯誤" + modal: + error: "錯誤" + filters: + error_placeholder: "錯誤" logs: none: "找不到記錄。" filters: @@ -1722,6 +1765,7 @@ zh_TW: ip_address: "IP" topic_id: "討論話題 ID" post_id: "文章 ID" + category_id: "分類 ID" delete: '刪除' edit: '編輯' save: '儲存' @@ -1761,6 +1805,15 @@ zh_TW: delete_post: "刪除文章" impersonate: "檢視" anonymize_user: "匿名用戶" + change_category_settings: "變更分類設定" + delete_category: "刪除分類" + create_category: "建立分類" + block_user: "封鎖用戶" + unblock_user: "解除封鎖" + grant_admin: "授予管理員權限" + revoke_admin: "撤銷管理員權限" + grant_moderation: "授予板主權限" + revoke_moderation: "撤銷板主權限" screened_emails: title: "過濾的電子郵件地址" description: "以下的電子郵件地址將無法用來建立新用戶。" @@ -1824,9 +1877,6 @@ zh_TW: pending: '等待審核的用戶' newuser: '信任等級 0 的用戶 ( 新用戶 )' basic: '信任等級 1 的用戶 ( 初級用戶 )' - regular: '信任等級 2 的使用者(成員)' - leader: '信任等級 3 的使用者(正規)' - elder: '信任等級 4 的使用者(領導者)' staff: "管理員" admins: '管理員' moderators: '板主' @@ -1931,7 +1981,6 @@ zh_TW: unlock_trust_level: "解鎖信任等級" tl3_requirements: title: "信任等級 3 之條件" - table_title: "在過去100天內:" value_heading: "價值" requirement_heading: "要求" visits: "訪問" @@ -1992,8 +2041,12 @@ zh_TW: confirm: '確認' dropdown: "下拉" site_text: - none: "選擇一個內容類別開始編輯" title: '文字內容' + edit: '編輯' + revert: "恢復變更" + revert_confirm: "你確定要撤回這個改動?" + go_back: "回到搜尋" + show_overriden: '只顯示修改過的項目' site_settings: show_overriden: '只顯示修改過的項目' title: '設定' @@ -2081,10 +2134,6 @@ zh_TW: bad_count_warning: header: "警告 !" text: "查詢結果沒有授予徽章的樣本;當查詢結果回傳的使用者 ID 或文章 ID 不存在時此問題有可能發生。如此可能會發生未預期的結果 ―― 請再次檢查您的 SQL 語法。" - grant_count: - zero: "沒有指定徽章。" - one: "指定了 1 個徽章。" - other: "指定了 %{count} 個徽章。" sample: "樣本:" grant: with: %{username} @@ -2103,9 +2152,12 @@ zh_TW: title: "嵌入" host: "允許的主機" edit: "編輯" + category: "張貼到分類" add_host: "新增主機" settings: "嵌入設定" crawling_settings: "爬蟲設定" + feed_polling_enabled: "匯入帖子藉由 RSS/ATOM" + save: "儲存崁入設定" permalink: title: "固定連結" url: "網址" @@ -2136,6 +2188,7 @@ zh_TW: categories: 'g, c 分類' top: 'g, t 頂端' bookmarks: 'g, b 書籤' + profile: 'g, p 個人檔案' messages: 'g, m 私人訊息' navigation: title: '導航' @@ -2177,8 +2230,6 @@ zh_TW: mark_watching: 'm, w 關注討論話題' badges: title: 徽章 - allow_title: "允許使用它作為稱號" - multiple_grant: "可以多次授予" badge_count: other: "%{count} 徽章" more_badges: @@ -2198,85 +2249,3 @@ zh_TW: name: 其他 posting: name: 文章 - badge: - editor: - name: 編輯 - description: 首篇文章編輯 - basic_user: - name: 初級 - description: 取得所有基本社群功能 - member: - name: 成員 - description: 取得邀請功能 - regular: - name: 常客 - description: 取得重新分類、重新命名、連結跟隨(無 nofollow 屬性)、貴賓室功能 - leader: - name: 領袖 - description: 取得全域編輯、置頂、關閉、封存、分割、合併討論話題功能 - welcome: - name: 歡迎 - description: 收到一個讚 - autobiographer: - name: 自我介紹 - description: 填寫用戶個人 資料 - anniversary: - name: 周年紀念日 - description: 一年中的活躍使用者,至少發表一次 - nice_post: - name: 好文章 - description: 一篇文章收到 10 個讚。此徽章可多次獲得。 - good_post: - name: 棒文章 - description: 一篇文章收到 25 個讚。此徽章可多次獲得。 - great_post: - name: 神文章 - description: 一篇文章收到 50 個讚。此徽章可多次獲得。 - nice_topic: - name: 好話題 - description: 一篇討論話題獲得 10 個讚。本徽章可以多次取得。 - good_topic: - name: 棒話題 - description: 一篇討論話題獲得 25 個讚。本徽章可以多次取得。 - great_topic: - name: 神話題 - description: 一篇討論話題獲得 50 個讚。本徽章可以多次取得。 - nice_share: - name: 好分享 - description: 分享一篇文章給 25 位不同的訪客 - good_share: - name: 棒分享 - description: 分享一篇文章給 300 位不同的訪客 - great_share: - name: 神分享 - description: 分享一篇文章給 1000 位不同的訪客 - first_like: - name: 首次讚好 - description: 給此貼文按讚 - first_flag: - name: 首次標記 - description: 標記文章 - promoter: - name: 推手 - description: 已邀請一位用戶 - campaigner: - name: 說客 - champion: - name: 鬥士 - first_share: - name: 首個分享 - description: 分享文章 - first_link: - name: 首次連結 - description: 其他討論話題含內部連結 - first_quote: - name: 首先引用 - description: 標記使用者 - read_guidelines: - name: 觀看守則 - description: 觀看社群守則 - reader: - name: 讀者 - description: 觀看每個超過100篇文章的討論話題 - popular_link: - name: 熱門連結 diff --git a/config/locales/plurals.rb b/config/locales/plurals.rb index 8a13eda06e6..6ab9d3dc5a4 100644 --- a/config/locales/plurals.rb +++ b/config/locales/plurals.rb @@ -79,7 +79,7 @@ :ps => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :pt => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :pt_BR => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, - :ro => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : n == 0 ? :few : :other } } } }, + :ro => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : n == 0 || ((n % 100) >= 1 && (n % 100) <= 19) ? :few : :other } } } }, :ru => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : :other } } } }, :se => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } }, :sh => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } }, @@ -113,4 +113,3 @@ :zh_TW => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :zu => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } } } - diff --git a/config/locales/server.ar.yml b/config/locales/server.ar.yml index 74f2f6b7269..c4e3d193866 100644 --- a/config/locales/server.ar.yml +++ b/config/locales/server.ar.yml @@ -7,38 +7,62 @@ ar: dates: - short_date_no_year: "يوم شهر" - short_date: "يوم شهر سنة" - long_date: "شهر يوم، سنه ساعة :دقائق" - title: "ديسكورس" - topics: "عناوين" - posts: "منشورات" - loading: "تحميل" - powered_by_html: 'مدعوم من ديسكورس ,لتفعيل أفضل رؤية مع جافاسكربت' + short_date_no_year: "D MMM" + short_date: "D MMM، YYYY" + long_date: "D MMMM, YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%d-%m-%Y" + short_no_year: "%-d %B" + date_only: "%-d %B، %Y" + date: + month_names: [null, كانون الثاني, شباط, آذار, نيسان, آيار, حزيران, تموز, أب, أيلول, تشرين الأول, تشرين الثاني, كانون الأول] + <<: *datetime_formats + title: "دسكورس" + topics: "المواضيع" + posts: "منشورات." + loading: "يحمّل" + powered_by_html: 'تدعمه دسكورس ، يفضّل عرضه وجافاسكرِبت مفعّل' log_in: "تسجيل الدخول" - via: "%{username} من موقع %{site_name}" - is_reserved: "محجوز" - purge_reason: "حذف آلي للحسابات المهجوره وغير النشطه " - disable_remote_images_download_reason: "لقد تم تعطيل تحميل الصور عن بعد بسبب عدم وجود مساحة كافية" + purge_reason: "حُذف آليا باعتباره حسابا إما مهجورا أو غير منشّطا" + disable_remote_images_download_reason: "عُطّل تنزيل الصور عن بعد بسبب نفاذ مساحة القرص الحرّة." anonymous: "مجهول" - errors: + emails: + incoming: + default_subject: "رسالة ورادة من %{email}" + show_trimmed_content: "اظهر محتوى أقل" + errors: + empty_email_error: "يحدث عندما يكون البريد المستلم فارغ" + no_message_id_error: "يحدث عندما لا يحتوي البريد على 'Message-Id' في العنوان" + no_body_detected_error: "يحدث عندما لا نستطيع اقتباس المحتوى و لا يوجد مرفق ." + inactive_user_error: "يحدث عندما يكون المرسل غير نشط " + blocked_user_error: "يحدث عندما يكون المرسل محظور" + bad_destination_address: "يحدع عندما لا يكون اي من عنوان البريد االكتروني في حقول To/Cc/Bcc تتطابق مع كون البريد القادم" + strangers_not_allowed_error: "يحدث عندما يحاول المستخدم انشاء موضوع جديد في قسم هو ليس عضواً فيه" + insufficient_trust_level_error: "يحدث عندما يحاول مستخدم انشاء موضوع جديد في قسم و تكون درجه ثقه المستخدم اقل من القسم المطلوب " + reply_user_not_matching_error: "يحدث عندما ياتي الرد من عنوان بريد ألكتروني مختلف من الذي أرسل اليه ألاشعار " + topic_not_found_error: "يحدث عندما يصل رد لموضوع تم حذفه" + topic_closed_error: "يحدث عندما يصل رد لموضوع تم اغلاقه " + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "إنها محددة بعدد حروف %{max} حرف; لقد أدخلت %{length}." - invalid_boolean: "قيمة منطقية غير صحيحة" - taken: "تم حجزه من قبل " - accepted: يجب أن تُقبل - blank: لا يمكن جعله فارغا - present: يجب أن يكون فارغ - confirmation: "ليست مطابقة ل %{attribute}" - empty: لا يمكن جعله فارغا + invalid_boolean: "قيمة منطقية غير صالحة." + taken: "أُخذ بالفعل" + accepted: يجب أن تُقبل. + blank: لا يمكن جعله فارغا. + present: يجب أن يكون فارغ. + confirmation: "ليست مطابقة ل %{attribute}." + empty: لا يمكن جعله فارغا. equal_to: يجب أن تكون مساوي لـ %{count} - even: يجب أن يكون زوجي - exclusion: محجوز + even: يجب أن يكون العدد زوجي. + exclusion: محجوز. greater_than: يجب أن تكون أكبر من %{count} greater_than_or_equal_to: يجب أن تكون أكبر من أو تساوي %{count} + has_already_been_used: "مستخدم بالفعل " inclusion: غير متضمن في القائمة invalid: غير صالح + is_invalid: "غير صالح ، حاول ان تضع وصف اكثر" less_than: يجب أن يكون أقل من %{count} less_than_or_equal_to: يجب أن تكون أقل من أو تساوي %{count} not_a_number: ليس عدد @@ -71,7 +95,7 @@ ar: other: طول خاطئ (يجب أن يكون %{count} حروف) other_than: "يجب أن تكون غير %{count}" template: - body: 'هناك مشاكل بالحقول التالية ' + body: 'حدثت مشاكل مع الحقول الآتية:' header: zero: لا أخطاء تمنع هذا %{model} من الحفظ one: خطأ واحد منع هذا %{model} من الحفظ @@ -80,103 +104,131 @@ ar: many: أخطاء كثيرة تمنع هذا %{model} من الحفظ other: '%{count} أخطاء منعت هذا %{model} من الحفظ' embed: - load_from_remote: "هناك خطأ في تحميل هذا المنشور." + load_from_remote: "حدث خطأ في تحميل المنشور." site_settings: min_username_length_exists: "لا يمكنك تعيين الحد الأدنى لطول اسم المستخدم أعلى من أقصر اسم المستخدم." - min_username_length_range: "لا يمكنك تعيين الحد الأدنى أعلى من الحد الأقصى." + min_username_length_range: "لا يمكن أن تكون القيمة الدنيا أكبر من العليا." max_username_length_exists: "لا يمكنك تعيين الحد الأقصى لطول اسم المستخدم أدنى من أطول اسم المستخدم." - max_username_length_range: "لا يمكنك تعيين الحد الأقصى أقل من الحد الأدنى." + max_username_length_range: "لا يمكن أن تكون القيمة العليا أصغر من الدنيا." default_categories_already_selected: "لا يمكنك تحديد فئة تستخدم في قائمة أخرى." - s3_upload_bucket_is_required: "لا يمكنك تفعيل الملفات المرفوعة إلى S3 إلا إذا أتممت 's3_upload_bucket'." + s3_upload_bucket_is_required: "لا يمكنك تفعيل الرفع إلى S3 حتّى توفّر 's3_upload_bucket'." bulk_invite: - file_should_be_csv: "الملف المرفوع يجب أن يكون بنسق وامتداد txt أو csv" + file_should_be_csv: "على نسق الملف الملف المرفوع أن يكون إمّا csv أو txt." backup: - operation_already_running: "هناك عملية قيد العمل حاليا. لا يمكن بدء مهمة جديدة في الوقت الحالي " - backup_file_should_be_tar_gz: "ملف الاحتياط يجب أن يكون أرشيف .tar.gz." - not_enough_space_on_disk: "ليست هناك مساحة كافية على القرص لتحميل هذه النسخة الاحتياطية" - not_logged_in: "يجب عليك تسجيل الدخول لفعل هذا." + operation_already_running: "ثمّة عملية تجري حاليا. لا يمكنك بدء مهمة جديدة الآن." + backup_file_should_be_tar_gz: "على الملف الاحتياطي أن يكون أرشيف \"‎.tar.gz\"." + not_enough_space_on_disk: "ليس ثمّة مساحة كافية على القرص لرفع النسخة الاحتياطية هذه." + not_logged_in: "عليك تسجيل الدخول لفعل ذلك." not_found: "تعذر العثور على رابط العنوان المطلوب" invalid_access: "لا تمتلك صلاحيات لعرض المطلوب " - read_only_mode_enabled: "الموقع في وضع القراءة فقط . تم تعطيل التفاعلات " + read_only_mode_enabled: "الموقع في وضع القراءة فقط. عُطّلت التفاعلات." + reading_time: "وقت القراءة" + likes: "الإعجابات" too_many_replies: - zero: "نحن نعتذر، لكن الأعضاء الجدد مقيدين مؤقتا بـعدم الرد في نفس الموضوع." - one: "نحن نعتذر، لكن الأعضاء الجدد مقيدين مؤقتا بـرد واحد في نفس الموضوع." - two: "نحن نعتذر، لكن الأعضاء الجدد مقيدين مؤقتا بـردّين في نفس الموضوع." - few: "نحن نعتذر، لكن الأعضاء الجدد مقيدين مؤقتا بـردود قليلة في نفس الموضوع." - many: "نحن نعتذر، لكن الأعضاء الجدد مقيدين مؤقتا بـردود كثيرة في نفس الموضوع." - other: "نحن نعتذر، لكن الأعضاء الجدد مقيدين مؤقتا بـ%{count} ردود في نفس الموضوع." + zero: "يمكن للأعضاء الجدد الرد كما يحلو لهم في كل موضوع." + one: "آسفون، فلا يمكن للأعضاء الجدد سوى الرد مرة واحدة في نفس الموضوع." + two: "آسفون، فلا يمكن للأعضاء الجدد سوى الرد مرتين في نفس الموضوع." + few: "آسفون، فلا يمكن للأعضاء الجدد سوى الرد %{count} مرات في نفس الموضوع." + many: "آسفون، فلا يمكن للأعضاء الجدد سوى الرد %{count} مرة في نفس الموضوع." + other: "آسفون، فلا يمكن للأعضاء الجدد سوى الرد %{count} مرة في نفس الموضوع." embed: - start_discussion: "إبدأ نقاش" - continue: "الاستمرار في هذا النقاش" + start_discussion: "ابدأ نقاشا" + continue: "تابع النقاش" more_replies: - zero: "لا يوجد رد إضافي" - one: "رد واحد إضافي" - two: "ردّين إضافيين" - few: "ردود قليلة إضافية" - many: "ردود كثيرة إضافية" - other: "%{count} ردود إضافية" - loading: "تحميل النقاش" + zero: "لا ردود أخرى" + one: "رد واحد آخر" + two: "ردّان آخران" + few: "%{count} ردود أخرى" + many: "%{count} ردا آخر" + other: "%{count} رد آخر" + loading: "يحمّل النقاش..." permalink: "الرابط الثابت" imported_from: "هذا موضوع نقاش مصاحب للمدخل الأصلي على %{link}" - in_reply_to: "{اسم المستخدم}%" + in_reply_to: "◀ %{username}" replies: - zero: "لا يوجد رد" + zero: "لا ردود" one: "رد واحد" - two: "ردّين" - few: "ردود قليلة" - many: "ردود كثيرة" - other: "%{count} ردود" + two: "ردّان" + few: "%{count} ردود" + many: "%{count} ردا" + other: "%{count} رد" + no_mentions_allowed: "عذراً، لا يمكنك تنبيه أعضاء آخرين." too_many_mentions: - zero: "عذراً، لا يمكنكم تنويه مستخدمين آخرين." - one: "عذراً، يمكنك فقط تنويه مستخدم واحد في هذا المنشور." - other: "عذرا, يمكنك تذكير %{count} مستخدمين فقط في المشاركة." + zero: "عذرا, لا يمكنك تنبيه أي عضو آخر في مشاركة." + one: "عذراً، يمكنك تنبيه عضو آخر واحد فقط في مشاركة." + two: "عذراً، يمكنك تنبيه عضوان آخران فقط في مشاركة." + few: "عذرا, يمكنك تنبيه %{count} أعضاء آخرين فقط في مشاركة." + many: "عذرا, يمكنك تنبيه %{count} عضواً آخراً فقط في مشاركة." + other: "عذرا, يمكنك تنبيه %{count} عضو فقط في مشاركة." + no_mentions_allowed_newuser: "عذرا, الأعضاء الجدد لا يمكنهم تنبيه الأعضاء الآخرين." too_many_mentions_newuser: - zero: "عذرا, المستخدمون الجدد لا يمكنهم تذكير المستخدمين الأخرين." - one: "عذرا, المستخدمون الجدد يمكنهم تذكير مستخدم واحد أخر فقط في المشاركة." - other: "عذرا, المستخدمون الجدد يمكنهم تذكير %{count} مستخجمين فقط في المشاركة." + zero: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه %{count} عضو في المشاركة ." + one: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه عضو واحد فقط في المشاركة ." + two: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه %{count} عضوين فقط في المشاركة ." + few: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه %{count} أعضاء في المشاركة ." + many: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه %{count} عضو في المشاركة ." + other: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه %{count} عضو في المشاركة ." + no_images_allowed: "آسفون، لا يمكن للمستخدمين الجدد وضع صور في المنشورات." too_many_images: - zero: "عذراً. الأعضاء الجدد لا يمكنهم وضع الصور في المنشورات." - one: "عذراً. الأعضاء الجدد يمكنهم وضع صورة واحدة فقط في المنشور." - other: "عذرا, المستخدمون الجدد يمكنهم وضع %{count} صور فقط في المشاركة." + zero: "يمكن للمستخدمين الجدد وضع أيّ عدد من الصور في أي منشور." + one: "آسفون، يمكن للمستخدمين الجدد وضع صورة واحدة فقط في كل منشور." + two: "آسفون، يمكن للمستخدمين الجدد وضع صورتين فقط في كل منشور." + few: "آسفون، يمكن للمستخدمين الجدد وضع %{count} صور فقط في كل منشور." + many: "آسفون، يمكن للمستخدمين الجدد وضع %{count} صورة فقط في كل منشور." + other: "آسفون، يمكن للمستخدمين الجدد وضع %{count} صورة فقط في كل منشور." + no_attachments_allowed: "آسفون، لا يمكن للمستخدمين الجدد إرفاق ملفات إلى المنشورات." too_many_attachments: - zero: "عذراً. الأعضاء الجدد لا يمكنهم وضع مرفقات في المنشورات." - one: "عذراً. الأعضاء الجدد يمكنهم وضع مرفق واحد فقط في المنشور." - other: "عذرا, المستخدمون الجدد يمكنهم وضع %{count} مرفقات فقط في المشاركة." + zero: "يمكن للمستخدمين الجدد إرفاق أيّ عدد من الملفات إلى أي منشور." + one: "آسفون، يمكن للمستخدمين الجدد إرفاق ملف واحد فقط إلى كل منشور." + two: "آسفون، يمكن للمستخدمين الجدد إرفاق ملفين فقط إلى كل منشور." + few: "آسفون، يمكن للمستخدمين الجدد إرفاق %{count} ملفات فقط إلى كل منشور." + many: "آسفون، يمكن للمستخدمين الجدد إرفاق %{count} ملفا فقط إلى كل منشور." + other: "آسفون، يمكن للمستخدمين الجدد إرفاق %{count} ملف فقط إلى كل منشور." + no_links_allowed: "آسفون، لا يمكن للمستخدمين الجدد وضع روابط في المنشورات." too_many_links: - zero: "عذراً. الأعضاء الجدد لا يمكنهم وضع الروابط في المنشورات." - one: "عذراً. الأعضاء الجدد يمكنهم وضع رابط واحد فقط في المنشور." - other: "عذرا, المستخدمون الجدد يمكنهم وضع %{count} روابط فقط في المشاركة." + zero: "يمكن للمستخدمين الجدد وضع أيّ عدد من الروابط في أي منشور." + one: "آسفون، يمكن للمستخدمين الجدد وضع رابطا واحدا فقط في كل منشور." + two: "آسفون، يمكن للمستخدمين الجدد وضع رابطين فقط في كل منشور." + few: "آسفون، يمكن للمستخدمين الجدد وضع %{count} روابط فقط في كل منشور." + many: "آسفون، يمكن للمستخدمين الجدد وضع %{count} رابطا فقط في كل منشور." + other: "آسفون، يمكن للمستخدمين الجدد وضع %{count} رابط فقط في كل منشور." spamming_host: "عذرا لا يمكنك مشاركة رابط لهذا المضيف." - user_is_suspended: "المستخدمون الموقوفون لا يسمح لهم بالمشاركة." - topic_not_found: "هناك خطأ. ربما هذا الموضوع أغلق أو حذف وأنت تبحث عنه." + user_is_suspended: "ليس مسموحا للمستخدمين المعلّقة عضويتهم النشر." + topic_not_found: "حدث خطب ما. قد يكون الموضوع أُغلق أو حُذف وأنت تشاهده؟" just_posted_that: "هذا مماثل لما شاركته مؤخرا" has_already_been_used: "هو مستخدم بالفعل" invalid_characters: "يحتوي احرف غير صالحة " is_invalid: "غير صالح حاول ان تضع وصف اكثر" next_page: "الصفحة التالية ←" prev_page: "→ الصفحة السابقة " - page_num: "الصفحة رقم %{num}" + page_num: "الصفحة %{num}" home_title: "الصفحة الرئيسية " - topics_in_category: "المواضيع في '%{category}' الفئة" + topics_in_category: "المواضيع في فئة '%{category}'" rss_posts_in_topic: "مغذي RSS لـ'%{topic}'" - rss_topics_in_category: "مغذي RSS للمواضيع في '%{category}' الفئة" - author_wrote: "كتب %{author} :" - num_posts: "تعليق " - num_participants: "المشاركين" - read_full_topic: "قراءة العنوان كامل" + rss_topics_in_category: "مغذي RSS للمواضيع في فئة '%{category}'" + author_wrote: "كتب %{author}:" + num_posts: "المنشورات:" + num_participants: "المشاركون:" + read_full_topic: "اقرأ كامل الموضوع" private_message_abbrev: "رسالة" rss_description: latest: "آخر المواضيع" hot: "عناوين ساخنة" + top: "أفضل المواضيع" posts: "اخر المشاركات " - too_late_to_edit: "تم انشاء هذا التعليق منذ فترة وليس بالامكان تعديله او حذفه" + too_late_to_edit: "أُنشئ المنشور منذ فترة طويلة جدا، لذا تعديله أو حذفه لم يعد ممكنا." + revert_version_same: "ألاصدار الحالي يتطابق مع نفس ألاصدار الذي تحاول استرجاعه ." excerpt_image: "صورة" queue: delete_reason: "حذف عبر طابور مشاركة معتدل" groups: errors: can_not_modify_automatic: "لا يمكنك تعديل مجموعة تلقائية" - member_already_exist: " '%{username}' هو بالفعل عضو في هذه المجموع" + member_already_exist: " '%{username}' هو عضو في هذه المجموعة بالفعل." + invalid_domain: "'%{domain}' ليس نطاقا صالحا." + invalid_incoming_email: "'%{email_in}' ليس عنوان بريد الكتروني صالح ." + email_already_used_in_group: "'%{email}' مستخدم من قبل المجموعه '%{group_name}'. " + email_already_used_in_category: "'%{email}' مستخدم من قبل القسم '%{category_name}'." default_names: everyone: "الجميع" admins: "المسؤولين" @@ -189,12 +241,12 @@ ar: trust_level_4: "مستوى_الثقة_4" education: until_posts: - zero: "لا يوجد مشاركات" - one: "مشاركة واحدة" - two: "مشاركتين" - few: "مشاركات قليلة" - many: "مشاركات كثيرة" - other: "%{count} مشاركات" + zero: "لا منشورات" + one: "منشور واحد" + two: "منشوران" + few: "%{count} منشورات" + many: "%{count} منشورا" + other: "%{count} منشور" new-topic: | مرحبا بك في %{site_name} — **شكرا لك لأجل بدء محادثه جديدة!** @@ -206,15 +258,15 @@ ar: لمعلومات أكثر ، [انظر المبادئ التوجيهية مجتمعنا] (/guidelines). وهذه اللوحة ستظهر لك لأول مرة فقط %{education_posts_text}. new-reply: | - مرحباً بك في %{site_name} — **شكراً للمساهمة**! + مرحباً بك في %{site_name} — **شكراً لمشاركتك**! -هل يُحسن ردّك المحادثة في جانب معين؟ - -كن طيبا مع أصدقاءك أعضاء المجتمع. + -كن لطيفا مع أصدقاءك أعضاء المجتمع. - -نرحب بالنقد البناء, ولكن انتقاد الأفكار لا الناس! + -نرحب بالنقد البناء، ولكن انتقد الأفكار ولا تنتقد الأشخاص! - للمزيد, [انظر ارشادات المجتمع](/guidelines). هذه اللوحة ستظهر فقط لأول %{education_posts_text} لك. + للمزيد, [انظر إرشادات المجتمع](/guidelines). هذه اللوحة ستظهر فقط لأول %{education_posts_text} لك. avatar: | ### ماذا عن صورة لحسابك؟ @@ -253,41 +305,39 @@ ar: user_profile: bio_raw: "معلومات عنّي" errors: - messages: - is_invalid: "غير صالح حاول ان تضع وصف اكثر" - has_already_been_used: "مستخدم بالفعل " models: topic: attributes: base: - warning_requires_pm: "يمكنك ارفاق تحذيرات في الرسائل الخاصة فقط " - too_many_users: "يمكنك ارسال التحذيرات لمستخدم واحد فقط في نفس الوقت" - cant_send_pm: "عذرا، لا يمكنك إرسال رسالة خاصة لهذا المستخدم." - no_user_selected: "يجب تحديد مستخدم موجود " + warning_requires_pm: "يمكنك إرفاق التحذيرات إلى الرسائل الخاصة فقط." + too_many_users: "يمكنك إرسال التحذيرات إلى مستخدم واحد كل مرة." + cant_send_pm: "آسفون، لا يمكنك إرسال رسالة خاصة إلى هذا المستخدم." + no_user_selected: "عليك تحديد مستخدم صالح." user: attributes: password: - common: "كلمة المرور هذه ضعيفة وهي من اكثر 10000 كلمة مرور مستخدمة يرجى استخدام كلمة مرور اكثر امنا" - same_as_username: "كلمة المرور هي نفس اسم المستخدم. يرجى أختيار كلمة مرور أخرى أكثر امناً" - same_as_email: "كلمة المرور هي نفس عنوان البريد الألكتروني الخاص بك. يرجى أختيار كلمة مرور أخرى أكثر أماناً" + common: "هي واحدة من أكثر 10000 كلمة مرور شائعة. من فضلك استخدم كلمة مرور آمنة أكثر." + same_as_username: "هي نفس اسم المستخدم. من فضلك استخدم كلمة مرور آمنة أكثر." + same_as_email: "هي نفس بريدك الإلكتروني. من فضلك استخدم كلمة مرور آمنة أكثر." ip_address: signup_not_allowed: "التسجيل غير مسموح من هذا الحساب." color_scheme_color: attributes: hex: - invalid: "هذا اللون غير صالح" + invalid: "ليس لونا صالحا" + <<: *errors user_profile: no_info_me: "
    مجال المعلومات عني لملف تعريفك فارغ حاليا، هل تريد أن تملأه؟
    " no_info_other: "
    %{name} لم يدخلوا أي شيء في مجال المعلومات عني لملفهم بعد
    " vip_category_name: "استراحة" - vip_category_description: "الفئة مخصصة للأعضاء ذوي مستوى الثقة 3 أو أعلى." + vip_category_description: "فئة خاصة للمستخدمين ذوي مستوى الثقة 3 فأعلى." meta_category_name: "موقع التغذية الإرتجاعية" - meta_category_description: "نقاش حول هذا الموقع, كيفية تنظيمه والعمل عليه أكثر وكيف يمكننا تحسينه." - staff_category_name: "الإدارة" + meta_category_description: "النقاش حول هذا الموقع، وتنظيمه، وكيفية عمله وطرق تطويره." + staff_category_name: "الطاقم" staff_category_description: "فئة مخصصة للنقاش في مواضيع الإدارة. المواضيع مرئية فقط للأدارة وللمشرفين." assets_topic_body: "هذا الموضوع مشاهد بشكل دائم للأعضاء فقط . ولحفظ الصورة والملف استخدم موقع التصميم. لا تقوم بحذفها\n\n\nكيف يكون العمل هنا.\n\n1. الرد على الموضوع.\n\n2. رفع كل الصور التي تود أن تستخدمها في الشعار." lounge_welcome: - title: "مرحبا بك في الاستراحة." + title: "مرحبا بك في الاستراحة" body: |2 تهانينا! :confetti_ball: @@ -310,14 +360,16 @@ ar: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: - topic_prefix: "عن الفئة %{category}." - replace_paragraph: "[استبدل هذا الفقرة الأولى بوصف قصير لفئتك الجديدة. سيظهر هذا التوجيه في منطقة اختيار الفئة, لذا حاول أن تبقيها أقل من 200 حرف. حتى عند تحريرك لهذا النص أو إنشائك لموضوع, هذه الفئة لن تظهر على صفحة الفئات.]" - post_template: "%{replace_paragraph}\n\nاستخدم الفقرات التالي لوصف طويل, إضافة لإنشاء أي فئة قواعد أو توجيهات.\n\nبعض الأشياء تؤخذ بعين الإعتبار في أسفل أي ردود لنقاش:\n\n- لما هذا الفئة؟لماذا يختار الناس هذه الفئة لمواضيعهم؟\n\n- كيف تختلف الفئات الأخرى عن التي لدينا؟\n\n- هل نحتاج هذه الفئة؟\n\n- هل يجب أن ندمج هذه مع فئة أخرى, أو تقسم إلى أكثر من قئة ؟\n" + topic_prefix: "عن فئة %{category}." + replace_paragraph: "(قم بإستبدال هذة القطعة بإختصار عن التصنيف الجديد. هذا الدليل سوف يظهر في منطقة إختيار التصنيف, لذا حاول ان تبقيها اقل من 200 حرف. ** حتي تقوم بتعديل هذا الوصف أو تقوم ب إضافة مقال, هذا التصنيف لن يظهر في صفحة التصنيفات**)" + post_template: "%{replace_paragraph}\n\nإستخدم الفقرات الآتية لوضع وصف أطول ، أو لإنشاء تعليمات أو قوانيناً لفئة جديدة :\n\n- لماذا يجب على الأعضاء والزوار استخدام هذه الفئة ؟ ولم انشئت ؟\n\n- ما هو الاختلاف بين هذه الفئة والفئات الأخرى الموجودة في الموقع ؟\n\n- ما هي النقاط الأساسية والعامة التي يجب أن تحتويه المواضيع في هذه الفئة ؟\n\n- هل نحتاج حقا إلى هذه الفئة ؟ وهل نستطيع دمجها مع فئة رئيسية أو فئة فرعية أخرى ؟\n" errors: uncategorized_parent: "غير مصنف لا يمكن أن يكون فئة الأم" self_parent: "الفئة الفرعية لا يمكن ان تكون كالفئة الرئيسية." depth: "لا يمكنك تضمين فئة فرعية تحت فئة فرعية اخرى" - email_in_already_exist: "البريد الإلكتروني الوارد '%{email_in}' مستخدم حاليا للفئة '%{category_name}'." + invalid_email_in: "'%{email_in}' ليس عنوان بريد الكتروني صالح ." + email_already_used_in_group: "'%{email}' مستخدم من قبل المجموعه '%{group_name}'. " + email_already_used_in_category: "'%{email}' مستخدم من قبل القسم '%{category_name}'." cannot_delete: uncategorized: "لايمكن حذف الغير مصنف" has_subcategories: "لايمكن حذف هذه الفئة لأنها تحتوي على فئات فرعية " @@ -329,80 +381,92 @@ ar: many: "لا يمكنك حذف هذه الفئة ﻷن لها مواضيع كثيرة.أقدم موضوع هو %{topic_link}." other: "لا يمكنك حذف هذه الفئة ﻷن لها %{count} مواضيع.أقدم موضوع هو %{topic_link}." topic_exists_no_oldest: "لايمكن حذف هذه الفئة لعدد المواضيع التي تحتويه. عدد المواضيع %{count}." + uncategorized_description: "المواضيع التي لا تحتاج للتصنيف , او لا تتناسق مع اي تصنفيات اخرى موجوده" trust_levels: newuser: title: "مستخدم جديد " basic: title: "مستخدم أساسي" - regular: + member: title: "عضو" - leader: + regular: title: "منتظم" - elder: + leader: title: "قائد" change_failed_explanation: "حاولت تخفيض رتبة %{user_name} إلى '%{new_trust_level}'. أيضا مستوى الثقة لهم حاليا '%{current_trust_level}'. %{user_name} سيبقى في '%{current_trust_level}' - إذا رغبت في تخفيض رتبة عضو أنظر لمستوى الثقة أولاً." rate_limiter: - slow_down: "لقد أنجزت هذا العمل مرات كثيرة، حاول مجددا." + slow_down: "لقد قمت بهذا الإجراء عدّة مرات. فحاول مجددا لاحقا." too_many_requests: "لدينا حد يومي لعدد المرات التي يمكن للعمل أن ينجز بها. رجاءا انتظر %{time_left} قبل المحاولة مجدداً." + by_type: + first_day_replies_per_day: "لقد وصلت للعدد الأقصى للردود التي يمكن للعضو الجديد إنشائها في يومهم الأول. رجاء انتظر %{time_left} قبل المحاولة مجددا." + first_day_topics_per_day: "لقد وصلت للعدد الأقصى للمواضيع التي يمكن للعضو الجديد إنشائها في يومهم الأول. رجاء انتظر %{time_left} قبل المحاولة مجددا." + create_topic: "أنت تنشأ مواضيع بسرعة عالية. رجاء انتظر %{time_left} قبل المحاولة مجددا." + create_post: "أنت ترد بسرعة عالية. رجاء انتظر %{time_left} قبل المحاولة مجددا." + delete_post: "أنت تقوم بمسح المنشورات بسرعه عاليه . الرجاء الانتظار %{time_left} قبل المحاوله مجدداً" + topics_per_day: "لقد وصلت للعدد الأقصى للمواضيع الجديدة اليوم. رجاء انتظر %{time_left} قبل المحاولة مجددا." + pms_per_day: "لقد وصلت للعدد الأقصى للرسائل اليوم. رجاء انتظر %{time_left} قبل المحاولة مجددا." + create_like: "لقد وصلت للعدد الأقصى للإعجابات اليوم. رجاء انتظر %{time_left} قبل المحاولة مجددا." + create_bookmark: "لقد وصلت للعدد الأقصى للتفضيلات اليوم. رجاء انتظر %{time_left} قبل المحاولة مجددا." + edit_post: "لقد وصلت للعدد الأقصى للتعديلات اليوم. رجاء انتظر %{time_left} قبل المحاولة مجددا." hours: - zero: "1 ساعة" - one: "1 ساعة" - two: "%{count} ساعة" + zero: "أقل من ساعة" + one: "ساعة واحدة" + two: "ساعتان" few: "%{count} ساعات" - many: "%{count} ساعات" - other: "%{count} ساعات" + many: "%{count} ساعة" + other: "%{count} ساعة" minutes: - zero: "1 دقيقة" - one: "1 دقيقة" - two: "%{count} دقيقة" + zero: "أقل من دقيقة" + one: "دقيقة واحدة" + two: "دقيقتان" few: "%{count} دقائق" - many: "%{count} دقائق" - other: "%{count} دقائق" + many: "%{count} دقيقة" + other: "%{count} دقيقة" seconds: - zero: "1 ثانية" - one: "1 ثانية" - two: "%{count} ثواني" - few: "%{count} ثواني" - many: "%{count} ثواني" - other: "%{count} ثواني" + zero: "أقل من ثانية" + one: "ثانية واحدة" + two: "ثانيتان" + few: "%{count} ثوان" + many: "%{count} ثانية" + other: "%{count} ثانية" datetime: distance_in_words: - half_a_minute: "< 1 دقيقة" + half_a_minute: "< 1دق" less_than_x_seconds: - zero: "< صفر ثانية" - one: "< ثانية واحدة" - two: "< ثانيتان" - few: "< ثواني قليلة" - many: "< ثواني كثيرة" - other: "< %{count} ثوان" + zero: "< %{count}ث" + one: "< %{count}ث" + two: "< %{count}ث" + few: "< %{count}ث" + many: "< %{count}ث" + other: "< %{count}ث" x_seconds: - zero: "1ث" - one: "1ث" - two: "ث {count}%" - few: "ث {count}%" - many: "ث {count}%" - other: "ث {count}%" + zero: "%{count}ث" + one: "%{count}ث" + two: "%{count}ث" + few: "%{count}ث" + many: "%{count}ث" + other: "%{count}ث" less_than_x_minutes: - zero: "< 1د" - one: "< 1د" - two: "< %{count} د" - few: "< %{count} د" - many: "< %{count} د" - other: "< %{count} د" + zero: "< %{count}دق" + one: "< %{count}دق" + two: "< %{count}دق" + few: "< %{count}دق" + many: "< %{count}دق" + other: "< %{count}دق" x_minutes: - zero: "1د" - one: "1د" - two: "%{count} د" - few: "%{count} د" - many: "%{count} د" - other: "%{count} د" + zero: "%{count}دق" + one: "%{count}دق" + two: "%{count}دق" + few: "%{count}دق" + many: "%{count}دق" + other: "%{count}دق" about_x_hours: - zero: "0 ساعة " - one: "ساعة واحدة" - two: "ساعتان" - few: "ساعات قليلة" - many: "ساعات كثيرة" - other: "%{count}ساعة" + zero: "%{count}س" + one: "%{count}س" + two: "%{count}س" + few: "%{count}س" + many: "%{count}س" + other: "%{count}س" x_days: zero: "0 يوم " one: "يوم واحد" @@ -446,132 +510,136 @@ ar: many: "س %{count}" other: "س %{count}" distance_in_words_verbose: - half_a_minute: "الأن" + half_a_minute: "منذ لحظات" less_than_x_seconds: - zero: "الآن" - one: "الآن" - two: "الآن" - few: "الآن" - many: "الآن" - other: "الآن" + zero: "منذ لحظات" + one: "منذ لحظات" + two: "منذ لحظات" + few: "منذ لحظات" + many: "منذ لحظات" + other: "منذ لحظات" x_seconds: - zero: "1 ثانية مضت" - one: "1 ثانية مضت" - two: "%{count} ثواني مضت" - few: "%{count} ثواني مضت" - many: "%{count} ثواني مضت" - other: "%{count} ثواني مضت" + zero: "قبل لحظات" + one: "قبل ثانية واحدة" + two: "قبل ثانيتين" + few: "قبل %{count} ثوان" + many: "قبل %{count} ثانية" + other: "قبل %{count} ثانية" less_than_x_minutes: - zero: "أقل من 1 دقيقة مضت" - one: "أقل من 1دقيقة مضت" - two: "أقل من %{count} دقيقتين مضت" - few: "أقل من %{count} دقائق مضت" - many: "أقل من %{count} دقائق مضت" - other: "أقل من %{count} دقائق مضت" + zero: "قبل لحظات" + one: "قبل أقل من دقيقة" + two: "قبل أقل من دقيقتين" + few: "قبل أقل من %{count} دقائق" + many: "قبل أقل من %{count} دقيقة" + other: "قبل أقل من %{count} دقيقة" x_minutes: - zero: "1 دقيقة مضت" - one: "1 دقيقة مضت" - two: "%{count} دقائق مضت" - few: "%{count} دقائق مضت" - many: "%{count} دقائق مضت" - other: "%{count} دقائق مضت" + zero: "قبل أقل من دقيقة" + one: "قبل دقيقة واحدة" + two: "قبل دقيقتين" + few: "قبل %{count} دقائق" + many: "قبل %{count} دقيقة" + other: "قبل %{count} دقيقة" about_x_hours: - zero: "1 ساعة مضت" - one: "1 ساعة مضت" - two: "%{count} ساعات مضت" - few: "%{count} ساعات مضت" - many: "%{count} ساعات مضت" - other: "%{count} ساعات مضت" + zero: "قبل أقل من ساعة" + one: "قبل ساعة واحدة" + two: "قبل ساعتين" + few: "قبل %{count} ساعات" + many: "قبل %{count} ساعة" + other: "قبل %{count} ساعة" x_days: - zero: "1 يوم مضى" - one: "1 يوم مضى" - two: "%{count} أيام مضت" - few: "%{count} أيام مضت" - many: "%{count} أيام مضت" - other: "%{count} أيام مضت" + zero: "قبل أقل من يوم" + one: "قبل يوم واحد" + two: "قبل يومين" + few: "قبل %{count} أيام" + many: "قبل %{count} يوما" + other: "قبل %{count} يوم" about_x_months: - zero: "حوالي 1 شهر مضى" - one: "حوالي 1 شهر مضى" - two: "حوالي %{count} أشهر مضت" - few: "حوالي %{count} أشهر مضت" - many: "حوالي %{count} أشهر مضت" - other: "حوالي %{count} أشهر مضت" + zero: "قبل حوالي أقل من شهر" + one: "قبل حوالي شهر واحد" + two: "قبل حوالي شهرين" + few: "قبل حوالي %{count} أشهر" + many: "قبل حوالي %{count} شهرا" + other: "قبل حوالي %{count} شهر" x_months: - zero: "1 شهر مضى" - one: "1 شهر مضى" - two: "%{count} أشهر مضىت" - few: "%{count} أشهر مضىت" - many: "%{count} أشهر مضىت" - other: "%{count} أشهر مضىت" + zero: "قبل أقل من شهر" + one: "قبل شهر واحد" + two: "قبل شهرين" + few: "قبل %{count} أشهر" + many: "قبل %{count} شهرا" + other: "قبل %{count} شهر" about_x_years: - zero: "حوالي 1 سنة مضت" - one: "حوالي 1 سنة مضت" - two: "حوالي %{count} سنوات مضت" - few: "حوالي %{count} سنوات مضت" - many: "حوالي %{count} سنوات مضت" - other: "حوالي %{count} سنوات مضت" + zero: "قبل حوالي أقل من سنة" + one: "قبل حوالي سنة واحدة" + two: "قبل حوالي سنتين" + few: "قبل حوالي %{count} سنوات" + many: "قبل حوالي %{count} سنة" + other: "قبل حوالي %{count} سنة" over_x_years: - zero: "منذ 1 سنة مضت" - one: "منذ 1 سنة مضت" - two: "منذ %{count} سنوات مضت" - few: "منذ %{count} سنوات مضت" - many: "منذ %{count} سنوات مضت" - other: "منذ %{count} سنوات مضت" + zero: "قبل أكثر من أقل من سنة" + one: "قبل أكثر من سنة واحد" + two: "قبل أكثر من سنتين" + few: "قبل أكثر من %{count} سنوات" + many: "قبل أكثر من %{count} سنة" + other: "قبل أكثر من %{count} سنة" almost_x_years: - zero: "تقريبا 1 سنة مضت" - one: "تقريبا 1 سنة مضت" - two: "تقريبا %{count} سنتين مضت" - few: "تقريبا %{count} سنوات مضت" - many: "تقريبا %{count} سنوات مضت" - other: "تقريبا %{count} سنوات مضت" + zero: "قبل حوالي أقل من سنة" + one: "قبل حوالي سنة واحدة" + two: "قبل حوالي سنتين" + few: "قبل حوالي %{count} سنوات" + many: "قبل حوالي %{count} سنة" + other: "قبل حوالي %{count} سنة" password_reset: - no_token: "عذراً , رابط تغيير كلمة المرور قديم . رجاءً أعد عملية إسترجاع كلمة المرور ." - choose_new: "يرجى اختيار كلمة مرور جديدة" - choose: "يرجى أختيار كلمة مرور" - update: 'تحديث كلمة المرور' + no_token: "آسفون، رابط تغيير كلمة المرور قديم جدا. انقر زر \"تسجيل الدخول\" واختر \"نسيت كلمة مروري\" لنرسل لك رابطا آخر." + choose_new: "من فضلك اختر كلمة مرور جديدة" + choose: "من فضلك اختر كلمة مرور" + update: 'حدّث كلمة المرور' save: 'تعين كلمة المرور' title: 'إعادة تعين كلمة المرور' - success: "تم تغير كلمة المرور بنجاح ويمكنك تسجيل الدخول الأن " - success_unapproved: "تم تغير كلمة المرور بنجاح." - continue: "الاستمرار لـ %{site_name}" + success: "غُيّرت كلمة مرورك بنجاح ونحن الآن قد سجلنا الدخول." + success_unapproved: "غُيّرت كلمة مرورك بنجاح." + continue: "تابع إلى %{site_name}" change_email: - confirmed: "تم تحديث بريدك اﻹلكتروني" - please_continue: "الاستمرار لـ %{site_name}" - error: "حدث خطأ عند تغير بريدك الإلكتروني. ربما يكون هذا البريد الإلكتروني قد أستوخدم من قبل ؟" + confirmed: "حُدّث بريدك الإلكتروني." + please_continue: "تابع إلى %{site_name}" + error: "حدث خطأ في تغيير عنوان بريدك الإلكتروني. لربما يكون العنوان مستخدما بالفعل." + already_done: "نأسف عنوان التاكيد هدا لم يعد صالحا بعد الان. ربما تم تغيير بريدك بالفعل؟" + authorizing_old: + title: "شكرا لك لتاكيدك عنوان بريدك الحالي." + description: "نحن الان نقوم بمراسله عنوانك الجديد للتأكيد." activation: - action: "أضغط هنا لتفعيل حسابك" - already_done: "رابط تأكيد الحساب لم يعد صالحاً , ربما الحساب نشط ؟" - please_continue: "تأكيد حسابك الجديد : جاري توجيهك إلى الصفحة الرئيسية ." - continue_button: "الاستمرار لـ %{site_name}" + action: "انقر هنا لتنشيط حسابك." + already_done: "آسفون، لم يعد رابط تأكيد الحساب صالحا. لربما يكون الحساب نشطا بالفعل." + please_continue: "أُكّد حسابك الجديد، سيُعاد توجيهك إلى الصفحة الرئيسية." + continue_button: "تابع إلى %{site_name}" welcome_to: "مرحبا بك في %{site_name}!" approval_required: "يجب على المشرف أن يقبل حسابك الجديد قبل أن تستطيع الدخول لهذا المنتدى. سوف تتلقى بريد إلكتروني عندما يتم قبول حسابك." - missing_session: "نحن لا نستطيع أن نتحقق أن حسابك قد تمّ إنشاءه ، يرجى التأكد بإن ملفات تعريف الاتباط ** الملفات المؤقته مفعّله لديك ** cookies ." + missing_session: "يتعذّر علينا معرفة إن كان حسابك قد أُنشئ أم لا، من فضلك تحقّق من أن الكعكات/الكوكيز مفعّلة." post_action_types: off_topic: title: 'خارج الموضوع' description: 'لا صلة للمشاركة بالنقاش الحالي على النحو المحدد بواسطة العنوان والمشاركة الأولى، وربما ينبغي نقلها لمكان أخر.' long_form: 'أبلغ أن هذا خارج الموضوع.' spam: - title: 'بريد مزعج' - description: 'هذه المشاركة هي إعلان. ليست مفيدة أو مناسبة للموضوع الحالي، ولكنه نوع ترويجي.' - long_form: 'تبليغ على أنه مزعج' - email_title: '"%{title}" تم الأبلاغ على أنه بريد مزعج' + title: 'سخام' + description: 'هذا المنشور إعلان. المنشور ليس مفيد أو مرتبط بالموضوع الحالي، ولكنّه ترويجي فقط.' + long_form: 'علّم هذا على أنّه سخام' + email_title: '"%{title}" عُلّم على أنّه سخام' email_body: "%{link}\n\n%{message}" inappropriate: title: 'غير مناسب' description: 'هذه المشاركة تشمل محتوى أي شخص عاقل سيعتبره عدواني، أو مسيئ، أو انتهاك لـمبادئ مجتمعنا التوجيهية.' long_form: 'ترفع علم هذا عن صورة غير ملائمة' notify_user: - title: 'رسالة @{{username}}' - description: 'هذه المشاركة تحتوي بعض الأشياء التي أريد أن أتكلم مع هذا الشخص حولها مباشرة وسرا. لا يمكنك عمل تبليغ.' + title: 'أرسل رسالة إلى @{{username}}' + description: 'أود الحديث مع هذا الشخص مباشرة وعلى انفراد عن هذا المنشور.' long_form: 'العضو أرسل' email_title: 'مشاركتك في "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "شيء آخر " - description: 'تتطلب هذه الوظيفة الاهتمام مشرف لسبب آخر غير المذكورة اعلاه.' - long_form: 'علم هذا لتنبيه المراقب' - email_title: 'المشاركة "%{title}" تتطلب موافقة المشرف' + description: 'يحتاج هذا المنشور إجراء من الطاقم لسبب آخر لم يُذكر أعلاه.' + long_form: ' بَلِّغ عن هذا لتنبيه الطاقم ' + email_title: 'المنشور في "%{title}" يتطلب تنبيه الطاقم.' email_body: "%{link}\n\n%{message}" bookmark: title: 'المفضلة' @@ -596,7 +664,7 @@ ar: long_form: 'ترفع علم هذا عن صورة غير ملائمة' notify_moderators: title: "شيء آخر " - description: 'هذا الموضوع يتطلب اهتمام مشرف عام يعتمد على دليل التوجيهات, TOS, أو لسبب أخر غير مذكور أعلاه.' + description: 'هذا الموضوع يتطلب اهتمام الطاقم العام معتمداً على التوجيهات, شروط الخدمة, أو لسبب آخر لم يذكر أعلاه.' long_form: 'علم هذا لتنبيه المراقب' email_title: 'الموضوع "%{title}" يتطلب موافقة المشرف' email_body: "%{link}\n\n%{message}" @@ -632,6 +700,10 @@ ar: title: "الأعضاء جدد" xaxis: "يوم" yaxis: "عدد الأعضاء الجدد" + profile_views: + title: "مشاهدات ملف تعريف العضو" + xaxis: "يوم" + yaxis: "عدد مشاهدات ملف تعريف العضو" topics: title: "المواضيع" xaxis: "اليوم" @@ -783,37 +855,7 @@ ar: consumer_email_warning: "موقعك مهيئ لاستخدام Gmail (أو مستهلك خدمة بريد إلكتروني أخر) لإرسال بريد إلكتروني. حدود Gmail كمية رسائل البريد الإلكتروني التي يمكنك إرسالها. فكر باستخدام مزود خدمة بريد إلكتروني مثل mandrill.com لضمان أهداف البريد الإلكتروني." site_contact_username_warning: "أدخل اسم حسابات الأعضاء العاملين الودودين لإرسال رسالة مهمة آليا من تحديث site_contact_username في إعدادات الموقع." notification_email_warning: "رسائل التنبية البريدية لم تكن مرسلة من عنوان بريدي صالح على مجالك؛ توصيل البريد سيكون غير منتظم ولايمكن الاعتماد عليها. الرجاء وضع رسائل التنبية في عنوان بريدي صالح في إعدادات الموقع Site Settings." - content_types: - education_new_reply: - title: "مستخدم جديد للتعليم: الردود الأولى" - description: "ينبثق الدليل بطريقه اوتوماتيكيه فوق المؤلف عندما يبدا المستخدمون الجدد بكتابه اول ردين جديدين لهم " - education_new_topic: - title: "مستخدم جديد للتعليم: موضوعات الأولى" - description: "ينبثق الدليل بطريقه اوتوماتيكيه للمؤلف عندما يبدا المستخدمون الجدد بكتابه اول ردين جديدين لهم " - usage_tips: - title: "توجيه مستخدم الجديد" - description: "الإرشادات والمعلومات الأساسية للمستخدمين الجدد. " - welcome_user: - title: "مرحباً: عضو جديد" - description: "هذه الرسالة تُرسل تلقائيًا لجميع أعضائنا الجدد حال اشتراكهم" - welcome_invite: - title: "مرحباً: عضو مدعو" - description: "ترسل رسالة أليا لكل الأعضاء المدعوين حديثا عندما يقبلون دعوة من عضو أخر مشارك." - login_required_welcome_message: - title: "مطلوب لتسجيل الدخول : رسالة ترحيب" - description: "رسالة الترحيب التي تظهر للأعضاء المسجلين خروجهم عندما يفعلون إعداد \"تسجيل الدخول مطلوب\"" - login_required: - title: "مطلوب لتسجيل الدخول : الصفحة الرئيسية" - description: "النص الظاهر للأعضاء الغير مصرح بهم عند الحاجة لتسجيل الدخول للموقع." - head: - title: "عنوان HTML رئيسي " - description: "HTML الذي سيدرج داخل علامات ." - top: - title: "أعلى الصفحة" - description: "HTML التي ستكون مضافة في الأعلى لكل صفحة ( بعد رأس الصفحة، أو قبل الملاحة أو عنوان الموضوع)." - bottom: - title: "أسفل الصفحة" - description: "HTML التي ستضاف قبل علامة ." + subfolder_ends_in_slash: "إعدادات المجلدات الداخلية خاطئ;ال DISCOURSE_RELATIVE_URL_ROOT يجب ان تنتهي ب سلاش." site_settings: censored_words: "الكلمات التي ستستبدل تلقائيا مع ■■■■" delete_old_hidden_posts: "سيتم حذف الوظائف المخفية تلقائيًا إذا زادت مدة الإخفاء أكثر من 30 يومًا" @@ -828,7 +870,6 @@ ar: min_private_message_title_length: "الحد الأدنى المسموح به لطول عنوان لرسالة في الأحرف" min_search_term_length: "الحد الأدنى الصالح لطول مصطلح في الأحرف" allow_uncategorized_topics: "اسمح بتصميم النقاشات من غير فئات. تحذير: اذا كان هناك نقاشات غير مصنفه، يجب عليك تصنيفها قبل اغلاق هذا " - uncategorized_description: "الوصف للفئة غير المصنفة. اتركه فارغا لعدم الوصف." allow_duplicate_topic_titles: "اسمح بالمواضيع المماثلة والعناوين المكررة." unique_posts_mins: "كمية الدقائق التي يمكن للعضو قبلها إنشاء مشاركة مع نفس المحتوى مجددا" educate_until_posts: "عندما يبدا المستخدم كتابه منشورهم الاول.، اظهر انبثاق لوحه تعليمات المستخدم الجديد في المؤلف" @@ -841,7 +882,7 @@ ar: download_remote_images_to_local: "تحويل الصور البعيدة إلى صور محلية بواسطة تحميلها؛ بإستثناء الصور التالفة" download_remote_images_threshold: "ادني مساحه للقرص ضروربه لتحميل الصور البعيده محليا ( في المئه) " disabled_image_download_domains: "الصور البعيدة لن يتم تنزيلها من هذا المجال. قائمة Pipe-delimited." - ninja_edit_window: "ل(n) ثواني بعد النشر، التعديل الذي سيتم لن يصنع نسخه جديده في القائمه التاريخيه للمنشورات" + editing_grace_period: "خلال (n) ثواني بعد نشر المشاركة ، التعديل لن يقوم بانشاء نسخة جديدة في السجل الخاص بالتعديل ." post_edit_time_limit: "الكاتب يتستطيع تعديل و مسح مشاركته لعده (n) دقائق بعد النشر. اضبطه للعدد0 للابد" edit_history_visible_to_public: "اسمح لاي شخص ان يرى النسخ السابقه للمنشورات المعدله. عندما يتم تعطيلها.،فقط اعضاء فريق العمل يمكنهم رؤيتها " delete_removed_posts_after: "المشاركات التي تم إزالتها عن طريق الكتاب سيتم مسحها اوتوماتيكياً بعد(n) ساعات ة. اذا تم ضبطها علي 0، سيتم مسح المشاركه فوراً" @@ -871,7 +912,7 @@ ar: summary_likes_required: "الحد الأدنى للإعجابات في الموضوع قبل \"تلخيص هذا الموضوع\" مفعل." summary_percent_filter: "عندما يضغط المستخدم على \"تلخيص هذا الموضوع\"، يظهر أعلى % o المشاركات." summary_max_results: "الحد الأقصى للمشاركات العائدة بـ 'ملخص هذا الموضوع'" - enable_private_messages: "يسمح مستوى الثقة 1 للمستخدمين بإنشاء والرد على الرسائل" + enable_private_messages: "يسمح مستوى الثقة 1 (قابل للتغيير من خيار ادنى مستويات الثقة لارسال الرسائل ) للمستخدمين بإنشاء والرد على الرسائل" enable_long_polling: "ناقل الرسالة المستخدم للاشعارات يمكن أن يستخدم التصويت الطويل." long_polling_base_url: "قاعدة URL تستخدم للتصويت الطويل (عندما CDN يخدم المحتوى الديناميكي, تأكد لتعيين هذا لسحب الأصل) eg: http://origin.site.com" long_polling_interval: "المدة الزمنية التي سينتظرها الخادم قبل الرد على العملاء في حالة عدم وجود أية بيانات لارسالها (للأعضاء المسجلين فقط)" @@ -890,9 +931,10 @@ ar: notify_mods_when_user_blocked: "إذا تم حظر المستخدم تلقائيا، وإرسال رسالة الى جميع المشرفين." flag_sockpuppets: "إذا رد أحد المستخدمين جديد إلى موضوع من عنوان IP نفسه باسم المستخدم الجديد الذي بدأ هذا الموضوع، علم كل من مناصبهم كدعاية المحتملين." traditional_markdown_linebreaks: "استعمل السطور التالفه التقليديه في Markdown, التي تتطلب مساحتين بيضاوين للسطور التالفه" - allow_html_tables: "السماح للجداول لتكون مُدخلة بـMarkdown بإستخدام علامات HTML, و TABLE, THEAD, TD, TR, TH تكون قائمة بيضاء (تتطلب إعادة انشاء كامل لكل المشاركات القديمة التي تحتوي على جداول)" + allow_html_tables: "كل الجداول يجب ان تدخل ب لغة ال HTML مثال TABLE , THEAD , TD , TR , TH سوف يأوذن لهم ( تتطلب مراجعة لكل المقالات القديمة )" post_undo_action_window_mins: "عدد الدقائق التي يسمح فيها للأعضاء بالتراجع عن آخر إجراءاتهم على المنشور (إعجاب، اشارة، إلخ...)" must_approve_users: "يجب أن الموظفين يوافق على جميع حسابات المستخدم الجديدة قبل أن يتم السماح لهم للوصول إلى الموقع. تحذير: تمكين هذا لموقع الحية إلغاء وصول المستخدمين الحاليين غير الموظفين!" + pending_users_reminder_delay: "نبه المشرفين إذا وجد اعضاء ينتظرون الموافقة لمدة اطول من الساعات ، قم بوضع الخيار -1 لايقاف التنبيهات ." ga_tracking_code: "تحليلات Google (ga.js) تتعقب رمز الشيفرة، مثال: UA-12345678-9; انظر http://google.com/analytics" ga_domain_name: "تحليلات Google (ga.js) تتعقب اسم المجال، مثال: mysite.com; انظر http://google.com/analytics" ga_universal_tracking_code: "تحليلات Google العالمية (analytics.js) تتعقب رمز الشيفرة، مثال: UA-12345678-9; انظر http://google.com/analytics" @@ -901,6 +943,7 @@ ar: enable_noscript_support: "فعل دعم محرك بحث webcrawler عبر علامة غير نصية." allow_moderators_to_create_categories: "السماح للمشرفين إنشاء قسم جديد" cors_origins: "اسمح بالأصول للطلبات عبر المنشأ (CORS). كل أصل يجب أن يتضمن http:// أو https://. متغير env لـ DISCOURSE_ENABLE_CORS يجب أن يعين إلى true ليعمل CORS." + use_admin_ip_whitelist: "المدير فقط يمكنه تسجيل الدخول إذا كانت عناوين IP لهم معرفة في قائمة IP المحجوبة. (المدير > السجلات > IP المحجوبة)" top_menu: "حدد الأدوات التي تظهر في ملاحة الصفحة الرئيسية، وما ترتيبها. مثال الأخير|الجديد|غير مقروء|فئات|أعلى|مقروء|مشارك|مفضلات" post_menu: "تحديد العناصر التي تظهر في القائمة آخر، وبأي ترتيب. مثال مثل | تحرير | العلم | حذف | سهم | المرجعية | الرد" post_menu_hidden_items: "عناصر القائمة لإخفاء افتراضيا في القائمة آخر ما لم يتم النقر على القطع التوسع جرا." @@ -912,15 +955,15 @@ ar: suppress_reply_directly_above: "لا تظهر للتوسع في الرد لعلى وظيفة عندما يكون هناك سوى رد واحد مباشرة فوق هذا المنصب." suppress_reply_when_quoting: "لا تظهر للتوسع في الرد لعلى وظيفة عندما يكون هناك سوى رد واحد مباشرة فوق هذا المنصب." max_reply_history: "الحد الأقصى لعدد الردود على توسيع عند توسيع في الرد ل" - experimental_reply_expansion: "إخفاء ردود المتوسطة عند توسيع ردا على (تجريبي)" topics_per_period_in_top_summary: "عدد من أهم الموضوعات هو مبين في موجز أعلى الافتراضية المواضيع." topics_per_period_in_top_page: "عدد من أهم الموضوعات هو مبين في موجز أعلى الافتراضية المواضيع." redirect_users_to_top_page: "إعادة توجيه تلقائيا للمستخدمين الجدد وغائبة لمدة طويلة إلى أعلى الصفحة." + top_page_default_timeframe: "الوقت المثبت علي الصفحة الأكثر مشاهدة." show_email_on_profile: "إظهار بريدك المستخدم على صفحته الشخصية (مرئية فقط لأنفسهم والموظفين)" email_token_valid_hours: "نسيت كلمه السر/ تنشيط رموز الحساب صالحه ل(n) ساعات" email_token_grace_period_hours: "نسيت كلمه السر/ تنشيط رموز الحساب لا تزال صالحة لفترة سماح بالـ(n) ساعات بعد استبدالها." - enable_badges: "تفعيل نظام الشارات." - enable_whispers: "اسمح لمستخدمين باجراء محادثه سريه مع الطاقم " + enable_badges: "تفعيل نظام الأوسمة." + enable_whispers: "السماح للموظفين الخصوصين التواصل ضمن موضوع.(تجريبي)" allow_index_in_robots_txt: "تحديد في ملف robots.txt أن يسمح هذا الموقع ليتم فهرستها من قبل محركات البحث على شبكة الإنترنت." email_domains_blacklist: "قائمة pipe-delimited المجالات البريد الإلكتروني الذي لا يسمح للمستخدمين تسجيل حسابات مع. مثال: mailinator.com | trashmail.net" email_domains_whitelist: "قائمة pipe-delimited من مجالات البريد الإلكتروني التي يجب على المستخدمين تسجيل حسابات مع. تحذير: لن يسمح للمستخدمين مع مجالات البريد الإلكتروني الأخرى غير المذكورة هنا!" @@ -938,6 +981,7 @@ ar: max_username_length: "الحد الأعلى لطول اسم العضو في الأحرف." reserved_usernames: "الأعضاء الغير مسموح لها بالتسجيل." min_password_length: "أقل طول لكلمة المرور" + min_admin_password_length: "أقل طول مسموح به للكلمه مرور بالنسبه لاداري" block_common_passwords: "لا تسمح لكلمات المرور المسجلة في قائمة كلمات المرور الشائعةز" enable_sso: " اسمح تسجيل دخول واحد عبر موقع خارجي(تحذير :عنوان بريد المستخدم *يجب* ان يتم التحقق من صحته عبر الموقع الخارجي)" enable_sso_provider: "تنفيذ مزود بروتوكول Discourse SSO على نقطة نهاية /session/sso_provider, يتطلب sso_secret لتعينها" @@ -958,6 +1002,9 @@ ar: enable_twitter_logins: "تفعيل مصادقة تويتر , يطلب : twitter_consumer_key و twitter_consumer_secret" twitter_consumer_key: "مفتاح المستهلك للمصادقة تويتر، مسجلة في http://dev.twitter.com" twitter_consumer_secret: "مفتاح المستهلك للمصادقة تويتر، مسجلة في http://dev.twitter.com" + enable_instagram_logins: "تفعيل تسجيل الدخول عن طريق الانستغرام , يتطلب instagram_consumer_key و instagram_consumer_secret" + instagram_consumer_key: "مفتاح الاستخدام لتوثيق الانستغرام " + instagram_consumer_secret: "استخدم توثيق انستغرام السري " enable_facebook_logins: "تمكين مصادقة الفيسبوك، يتطلب facebook_app_id وfacebook_app_secret" facebook_app_id: "التطبيق معرف للمصادقة الفيسبوك، مسجلة في https://developers.facebook.com/apps" facebook_app_secret: "التطبيق معرف للمصادقة الفيسبوك، مسجلة في https://developers.facebook.com/apps" @@ -970,6 +1017,9 @@ ar: backup_frequency: "كمية النسخ الإحتياطية المتكررة التي أنشأناها، في اليوم." enable_s3_backups: "تحميل النسخ الاحتياطي لS3 عند اكتماله. هام: يتطلب اعتماد S3 صالحة دخلت في إعدادات الملفات." s3_backup_bucket: "الرفع عن بعد لإجراء نسخ إحتياطية. تحذير : تأكد من أنه رفع خاص." + s3_disable_cleanup: "عطل النسخ الاحتياطيه المحذوفه من S3 عندما يتم حذفها محلياً" + backup_time_of_day: "الوقت الذي يجب ان تأخد النسخ الاحتياطية فيه." + backup_with_uploads: "إضافة التحميلات ل النسخ الإحتياطية. إلغاء هذة الخاصية سوف تؤدي إلى أخذ نسخ إحتياطية من قاعدة البيانات فقط." active_user_rate_limit_secs: "كيف في كثير من الأحيان نقوم بتحديث حقل 'last_seen_at، في ثوان" verbose_localization: "شاهد تلميحات الترجمة الممتدة في واجهة المستخدم." previous_visit_timeout_hours: "متى زيارة تستمر قبل أن تنظر فيه الزيارة \"السابقة، في ساعات" @@ -1001,6 +1051,8 @@ ar: avatar_sizes: "قائمة أحجام الرمزية إنشاؤه تلقائيا." external_system_avatars_enabled: "استخدم خدمات الهه النظام الخارجي " external_system_avatars_url: "عنوان URL لخدمة الصور الرمزية النظام الخارجي. الاستعمال المسموح بها {username} {first_letter} {color} {size}" + default_opengraph_image_url: "عنوان رابط صورة ال اوبن جراف الثابتة" + allow_all_attachments_for_group_messages: "اسمح بجميع ملحقات البريد للرسائل الجماعيه " enable_flash_video_onebox: "تمكين التضمين من swf و FLV (أدوبي فلاش) وصلات في مربع واحد. تحذير: قد يعرض المخاطر الأمنية." default_invitee_trust_level: "مستوى الثقة الإفتراضي (0-4) للأعضاء المدعوين." default_trust_level: "مستوى الثقة الإفتراضي (0-4) للأعضاء المدعوين.تحذير! التغيرات ستضعك تحت خطر البريد الغير هام." @@ -1014,19 +1066,14 @@ ar: tl2_requires_likes_received: "كمية الإعجابات التي يجب على العضو إرسالها قبل ترقيته لمستوى الثقة 2." tl2_requires_likes_given: "كمية الإعجابات التي يجب على العضو جمعها قبل ترقيته لمستوى الثقة 2." tl2_requires_topic_reply_count: "كمية مواضيع العضو التي يجب الرد عليها قبل الترقية لمستوى الثقة 2." - tl3_requires_days_visited: "أقل عدد من الأيام التي يجب على المستخدم زيارة الموقع في آخر مئةيوم للتأهل لمستوى الثقة 3. (0 حتى 100)" - tl3_requires_topics_replied_to: "أقل عدد من المواضيع التي يجب على المستخدم الرد عليها في آخر 100 يوم للتأهل لمستوى الثقة 3. (0 أو أكثر)" - tl3_requires_topics_viewed: "نسبة الموضوعات التي تم إنشاؤها في آخر 100 يوم، تجعل المستخدم مؤهلًا لعرضه للترقية إلى مستوى الثقة الثالث3 . (من 0 الى 100)" - tl3_requires_posts_read: "النسبه المئويه للمنشورات التي تم انشاءها في اخر 100 يوم ,التي يحتاج المستخدم لمعينتها تؤهله للترقيه للمستوي الثقه 3. (0 الي 100)" tl3_requires_topics_viewed_all_time: "أقل عدد من المواضيع التي يجب على المستخدم مشاهدتها للتأهل لمستوى الثقة 3." tl3_requires_posts_read_all_time: "أقل عدد من المشاركات يجب على المستحدم قرائتها للتأهل لمستوى الثقة 3 ." - tl3_requires_max_flagged: "يجب علي المستخدم عدم الحصول علي اكثر من x مشاركات مؤشره من x مستخدمين مختلفين في اخر 100 يوم لليترقى للمستوي 3 من الثقه , عندما x تساوي قيمه (صفر او اكثر)" tl3_promotion_min_duration: "أقل عدد من الأيام التي تكون الترقية إلى مستوى الثقة 3 قد أنتهت قبل عودة المستخدم لمستوى الثقة 2." - tl3_requires_likes_given: "أقل عدد من الإعجابات التي يجب أن تُمنح في آخر 100 يوم للتأهل لمستوى الثقة 3." - tl3_requires_likes_received: "أقل عدد من الإعجابات التي يجب أن تُتلقى في آخر 100 يوم للتأهل لمستوى الثقة 3." tl3_links_no_follow: "لا تحذف rel=nofollow من روابط المشاركة بواسطة أعضاء مستوى الثقة 3." min_trust_to_create_topic: "أدنى مستوى ثقة مطلوب لإنشاء موضوع جديد." min_trust_to_edit_wiki_post: "الحد الأدنى لمستوى الثقة المطلوب لتعديل مشاركة معلمة كويكي." + min_trust_to_allow_self_wiki: "الحد الادنى لمستوى ثقه المطلوب لأستحقاق مستخدم مشنور wiki" + min_trust_to_send_messages: "المستوي الأدني المطلوب لإرسال رسالة خاصة" newuser_max_links: "عدد الروابط التي يمكن للمستخدم الجديد إضافتها للمشاركة." newuser_max_images: "عدد الصور التي يمكن للمستخدم الجديد إضافتها للمشاركة." newuser_max_attachments: "عدد المرفقات التي يمكن للمستخدم الجديد إضافتها للمشاركة." @@ -1040,11 +1087,12 @@ ar: title_max_word_length: "الحد الأقصى المسموح لطول كلمة، بالأحرف، في عنوان الموضوع." title_min_entropy: "أدنى إنتروبي (حروف فريدة، عدد غير إنجليزي للكثير) مطلوب لعنوان الموضوع." body_min_entropy: "أدنى إنتروبي (حروف فريدة، عدد غير إنجليزي للكثير) مطلوب لصلب المشاركة." + allow_uppercase_posts: "السماح بكتابة الاحرف الانجليزية الكبيرة في عنوان الموضوع او نص المشاركة ." title_fancy_entities: "تحويل أحرف ASCII مشتركة لكائنات HTML في عناوين الموضوع، ala SmartyPants http://daringfireball.net/projects/smartypants/" min_title_similar_length: "الحد الأدنى لطول العنوان قبل أن يتم البحث عن مواضيع مشابهة." min_body_similar_length: "الحد الادنى لطول المشاركة قبل أن يتم البحث عن مواضيع مشابه." category_colors: "قائمة قيمة الألوان الست عشرية مسموحة في الفئات." - category_style: "النمط المرئي لفئة الشارات." + category_style: "النمط المرئي لفئة الأوسمة." max_image_size_kb: "الحجم الاقص لتحميل صوره بالكيلو بايت.هذا يجب ضبطه في nginx (client_max_body_size) /اباتشي او البروكسي" max_attachment_size_kb: "أقصى حجم لتحميل المرفقات الملفات بالكيلوبايت. وهذا يجب أن يتم تكوينه في nginx (client_max_body_size) / أباتشي أو الوكيل. " authorized_extensions: "قائمة بالملفات المسموح رفعها (أستخدم '*' للسماح لجميع الأنواع)" @@ -1069,6 +1117,7 @@ ar: white_listed_spam_host_domains: "قائمة النطاقات المستثناة من اختبار مضيف البريد المزعج. لن يتم تقييد المستخدمين الجدد من إنشاء المشاركات مع الروابط إلى هذه النطاقات." staff_like_weight: "كم عدد مرات الترجيح الاضافيه لمنح اعجابات الطاقم " topic_view_duration_hours: "احسب عدد المواضيع التي تمت مشاهدتها مره واحده عبر ip/مستخدم كل N ساعات" + user_profile_view_duration_hours: "احسب عدد ملفات التعريف للعضو التي تمت مشاهدتها مرة لكل IP/عضو في N ساعات." levenshtein_distance_spammer_emails: "عند ربط رسائل البريد الإلكتروني spammer، الأرقام والحروف تختلف التي ستبقى تسمح بربط غامض." max_new_accounts_per_registration_ip: "اذا كان هناك بالفعل (N) مستوي ثقه الحسابات 0 من هذا IP ( و لم يكن عضو في الطاقم او TL2 او اعلى), توقف عن قبول تسجيلات الدخول الجديده من هذا IP" min_ban_entries_for_roll_up: "When clicking the Roll up button, will create a new subnet ban entry if there are at least (N) entries." @@ -1086,6 +1135,10 @@ ar: disable_emails: "منع Discourse من إرسال أي نوع من رسائل البريد الإلكتروني" strip_images_from_short_emails: "شريط الصور من البريد الإلكتروني لها حجم أقل من 2800 بايت" short_email_length: "طول أقصر بريد الكتروني بـ Bytes." + display_name_on_email_from: "أعرض الاسماء كاملة في البريد الالكتروني من المجال." + unsubscribe_via_email: "أسمح للمستخدمين بالغاء الاشتراك لرسائل البريد الالكتروني عن طريق أرسال بريد الكتروني يحتوي على 'unsubscribe' في العنوان او محتوى البريد" + unsubscribe_via_email_footer: "أرفق رابط الغاء الاشتراك الى اخر البريد المرسل " + delete_email_logs_after_days: "حذف سجل البريد بعد (ن) يوم. 0 لحفظ السجل للابد" pop3_polling_enabled: "تصويت عبرPOP3 لردود البريد الإلكتروني." pop3_polling_ssl: "أستخدم SSL عند الأتصال بمخدم POP3.(مُستحسن)" pop3_polling_period_mins: "الفترة دقائق بين التحقق من حساب POP3 للبريد الإلكتروني. ملاحظة : تتطلب إعادة تشغيل." @@ -1112,7 +1165,6 @@ ar: automatically_download_gravatars: "تحميل Gravatars للأعضاء عند تغيرهم البريد الإلكتروني الخاص بهم أو عند إنشائهم لحساب آخر." digest_topics: "العدد الاقصي من المواضيع لعرضها في مضمون البريد الإلكتروني " digest_min_excerpt_length: "الحد الادني من مشاركه مقتطفات خلاصه البريد الاكتروني,في الشخصيات" - suppress_digest_email_after_days: "احفظ خلاصه الرسائل الالكترونيه للمستخدمين الذين لم تتم رويتهم في الموقع لاكثر من (N) ايام" disable_digest_emails: "عطل ملخص رسائل البريد الإلكتروني لكل الأعضاء." detect_custom_avatars: "سواء او لا تفقد اذا كان المستخدم قام بتحميل صور شخصيه مخصصه" max_daily_gravatar_crawls: "العدد الاقصي من مرات Dicourse سوف يتفقد Gravatar لصور رمزيه مخصصه في اليوم" @@ -1122,15 +1174,18 @@ ar: allow_anonymous_posting: "اسمح للمستخدمين ان يغيروا لوضع المخفي" anonymous_posting_min_trust_level: "أدنى مستوى ثقة للسماح بنشر مشاركات مجهولة." anonymous_account_duration_minutes: "للحمايه الهويه اصنع حساب مجهول كل n دقائق لكل مستخدم.\nمثال:اذا ضبط 600 , بعد انقضي 600 دقيقه من اخر منشور و غير المستخدم للمجهول.تم انشاء حساب مجهول." + hide_user_profiles_from_public: "قم بإلغاء الصفحة الشخصية و حقيبة المستخدم و بطاقة المستخدم للمستخدمين المجهولين" allow_profile_backgrounds: "اسمح للأعضاء برفع خلفيات ملف التعريف." - sequential_replies_threshold: "عدد مشاركات عضو في صف واحد في موضوع قبل يجري تذكير حول الردود متسلسلة كثيرة جداً." + sequential_replies_threshold: "عدد المشاركات التي يجب على المستخدم انشاءها في عمود في الموضوع الواحد قبل ان يتم تنبيه بكثره الردود المتتاليه ." enable_mobile_theme: "اجهزه الموبايل تستخدم ثيم مناسب للجوال,امكانيه التحويل للموقع الكامل .الغي هذا اذا اردت استخدام انماط سريعه الاستجابه" dominating_topic_minimum_percent: "ما هي النسبه المئويه للمشاركات التي يجب علي المستخدم عملها في الموضوع قبل تلقيه لتنبيه عن خروجه لنطاق الموضوع" + disable_avatar_education_message: "عطل الرسالة التعليمية لتغيير الصورة الرمزية." daily_performance_report: "تحليل سجلات NGINX يومي ونشر موضوع \"قاقم فقط\" مع التفاصيل" - suppress_uncategorized_badge: "لا تظهر الشارة للمواضيع غير المصنفة في قائمة الموضوع." - permalink_normalizations: "يتم تطبيق التعابير القياسية قبل مطابقة صور الروابط الثابتة، على سبيل المثال: /(\\/topic.*)\\?.*/\\1 سوف تقطع الاستعلامات من الموضوع. التنسيق هو : التعبير القياسي+النص المستخدم \\ إلخ.. للوصول للقطع" + suppress_uncategorized_badge: "لا تظهر الوسام للمواضيع غير المصنفة في قائمة الموضوع." global_notice: "اعرض تنبيه, شعار عام طارئ ملاحظه لكل الزوار, غير الفراغ لاخفاء(HTML مسموح)" disable_edit_notifications: "لتعطيل تحرير الاشعارات بواسطة العضو النظام عندما يكون نشطاً 'download_remote_images_to_local'." + automatically_unpin_topics: "تلقائياً قم بنزع الدبوس عندا يصل المستخدم إلي نهاية الصفحه" + read_time_word_count: "عداد الكلمات للدقيقه لحساب الوقت المقدر للقراءه " full_name_required: "الإسم الكامل مطلوب وهو ضروري لإكمال الحساب " enable_names: "عرض الاسم الكامل للعضو , بطاقة العضو , ورسائل البريد الالكتروني , تعطيل عرض الاسم في اي مكان " display_name_on_posts: "عرض الاسم الكامل للعضو على التعليقات بالاضافة الى @username." @@ -1147,27 +1202,29 @@ ar: embed_username_key_from_feed: "مفتاح لسحب اسم مستخدم discourse من المغذي." embed_truncate: "اقتطاع الوظائف المدمجة." embed_post_limit: "أقصى عدد للمشاركات المضمنة." + embed_username_required: "إسم المستخدم مطلوب لإضافة مقالة" embed_whitelist_selector: "منتقي CSS للعناصر التي تسمح في التضمينات." embed_blacklist_selector: "منتقي CSS للعناصر التي حذفت من التضمينات." notify_about_flags_after: "اذا كانت هناك علامه انه لم يتم تاتعامل معه بعد هذه الساعات, ارسال رساله الي جهه الاتصال_بريده الالكتروني. اضبط 0 للتعطيل" enable_cdn_js_debugging: "السماح/logs لعرض أخطاء المناسبة عن طريق إضافة تتضمن تحليل عرض كل شبيبة." show_create_topics_notice: "إذا كان الموقع يحتوي على أقل من 5 مواضيع عامة , إظهار إشعار مطالبة المسؤولين إنشاء بعض المواضيع." delete_drafts_older_than_n_days: حذف المسودات مضى عليها أكثر من (ن) يوما. - show_logout_in_header: "عرض تسجيل الخروج في القائمة المنسدلة للمستخدم في رأس الصفحة." - vacuum_db_days: "شغل التحليل الكامل للمساحة لاستعادة مساحة DB بعد الهجرات (ضع 0 للإغلاق)" prevent_anons_from_downloading_files: "امنع المستخدمين المجهولين من تحميل المرفقات. تحذير:سوف تمنع اي شخص ليس لديه صوره موقع اصول نشره كمرفقات من العمل." slug_generation_method: "اختر طريقه توليد سبيكه . 'مشفره' سوف تقوم بتوليد سلسله مئويه مشفره.'لاشي' سوف يعطل السبيكه" enable_emoji: "تمكين الرموز التعبيرية " emoji_set: "كيف تريد أن تكون الرموز التعبيرية الخاصة بك؟" enforce_square_emoji: "أجبر نسبة جانب المربع لكل الرموز التعبيرية." - approve_post_count: "كمية مشاركات العضو الجديد التي يجب أن تتم الموافقة عليها" + approve_post_count: "عدد المنشورات للمستخدم الجديد او الاساسي يجب ان تتم الموافقه عليه " approve_unless_trust_level: "مشاركات للأعضاء أدنى من مستوى الثقة هذا يجب أن تتم الموافقة عليها." notify_about_queued_posts_after: "اذا كان هناك مشاركات تنتظر ليتم معينتها لاكثر من هذه الساعات, سوف يتم ارسال بريد الكتروني لبريد الاتصال . اختر 0 لتعطيل هذه الرسائل" default_email_digest_frequency: "عدد المرات التي يتلقى الأعضاء فيها ملخص لبريدهم الإلكتروني إفتراضيا." default_email_private_messages: "أرسل بريد إلكتروني عندما يراسل شخص ما العضو إفتراضيا." default_email_direct: "ارسل بريد الكتروني عندما يقوم احدهم بالرد/الاقتباس الي/ذكر او دعوه مستخدم افتراضيا" default_email_mailing_list_mode: "ارسل بريد إلكتروني لكل مشاركة جديدة افتراضيا." + disable_mailing_list_mode: "عدم السماح للمستخدمين بتفعيل خيار المراسله الجماعيه" default_email_always: "أرسل إشعار بريد إلكتروني حتى عندما يكون العضو متاح إفتراضيا." + default_email_previous_replies: "ارفق الردود السابقه في رسائل البريد افتراضياً" + default_email_in_reply_to: "ارفق مقتبسات الرد على المنشور في رسائل البريد افتراضياً" default_other_new_topic_duration_minutes: "الشروط العالمية الافتراضية لموضوع يعتبر جديد." default_other_auto_track_topics_after_msecs: "الوقت العالمي الافتراضي قبل الموضوع متعقب آليا." default_other_external_links_in_new_tab: "أفتح الروابط الخارجية في تبويب جديد إفتراضيا." @@ -1175,6 +1232,8 @@ ar: default_other_dynamic_favicon: "إعرض عدد المواضيع الجديدة/الحديثة في أيقونة المتصفح إفتراضيا." default_other_disable_jump_reply: "لا تتجاوز إلى مشاركة الضو بعد ردهم إفتراضيا." default_other_edit_history_public: "أنشئ مشاركة المراجعات العامة إفتراضيا." + default_other_like_notification_frequency: "أشعر المستخدمين بالاستحسان على المشورات افتراضياً" + default_topics_automatic_unpin: "تلقائياً قم إزالة تثبيت المواضيع عندما يصل العضو إلى الأسفل \"إفتراضيا\"." default_categories_watching: "قائمة الفئات التي تشاهد إفتراضيا." default_categories_tracking: "قائمة الفئات التي تتابع إفتراضيا." default_categories_muted: "قائمة الفئات التي توضع صامتة إفتراضيا." @@ -1193,6 +1252,7 @@ ar: invalid_string_max: "يجب ان لا تكون الاحرف اكثر من %{max} " invalid_reply_by_email_address: "القيمة يجب أن تحتوي '%{reply_key}' وتختلف عن إشعار البريد الإلكتروني." notification_types: + group_mentioned: "%{group_name} ذكرت في %{link}" mentioned: "%{display_username} ذكرك في %{link}" liked: "%{display_username} أعجب بمشاركتك في %{link}" replied: "%{display_username} رد على مشاركتك في %{link}" @@ -1202,7 +1262,6 @@ ar: moved_post: "%{display_username} نقل مشاركتك إلى %{link}" private_message: "%{display_username} أرسل لك رسالة: %{link}" invited_to_private_message: "%{display_username} دعاك لرسالة: %{link}" - invited_to_topic: "%{display_username} دعاك لموضوع: %{link}" invitee_accepted: "%{display_username} قبل دعوتك" linked: "%{display_username} ربطك في %{link}" granted_badge: "كسبت %{link}" @@ -1212,11 +1271,6 @@ ar: category: 'فئات' topic: 'نتائج ' user: 'مستخدمين ' - sso: - not_found: "لا تستطيع البحث او انشاء حساب جديد , راجع ادارة الموقع " - account_not_approved: "الحساب بإنتظار الموافقة , ستتلقى إشعار بالبريد الكتروني بعد الموافقة " - unknown_error: "حدث خطأ أثناء تحديث المعلومات، راجع إدارة الموقع" - timeout_expired: "انتهى وقت الجلسة , يرجى تسجيل الدخول مرة اخرى " original_poster: "المشاركات الأصلية " most_posts: "معظم المشاركات" most_recent_poster: "معظم المشاركات الاخيرة " @@ -1306,7 +1360,7 @@ ar: incorrect_username_email_or_password: "اسم المستخدم او كلمة المرور او البريد الالكتروني غير صحيح" wait_approval: "شكرًا على التسجيل. سيتم إبلاغك عندما تتم عملية الموافقة على حسابك." active: "حسابك مفعل وجاهز للاستخدام." - activate_email: "لقد انتهيت تقريبا! لقد ارسلنا رساله تفعيل الي %{email} .الرجاء اتباع التعليمات في الرساله لتفعيل حسابك.

    اذا لم تصلك, تفقد مجلد البيد الغير هام, او حاول تسجيل الدخول مره اخرى للرسال بريد تفعيل اخر. .

    " + activate_email: "انتهيت تقريبا! تم ارسال رسالة تفعيل لبريدك : %{email} رجاءا اتبع التعليمات المرفقة في الرسالة لتفعيل حسابك.

    اذا لم تصلك رسالة التفعيل، تفقد مجلد البريد الغير هام، أو حاول تسجيل الدخول مرة أخرى لإرسال رسالة تفعيل أخرى.

    " not_activated: "لا يمكنك تسجيل الدخول حتى الان. أرسلنا رسالة تنشيط لك. يرجى اتباع التعليمات الواردة في البريد الإلكتروني لتفعيل حسابك" not_allowed_from_ip_address: "ﻻ يمكنك تسجيل الدخول كـ %{username} من هذا الـIP" admin_not_allowed_from_ip_address: "لا يمكنك تسجيل الدخول كمدير من خلال هذا العنوان الرقمي - IP." @@ -1331,16 +1385,25 @@ ar: characters: "يجب ان تحتوي الارقام والاحرف الصغيرة فقط " unique: "يجب أن يكون فريدا" blank: "يجب أن يكون موجود" - must_begin_with_alphanumeric: "يجب البدء بحرف أو رقم أو _" - must_end_with_alphanumeric: "يجب الإنتهاء بحرف أو رقم أو _" + must_end_with_alphanumeric: "يجب أن ينتهي برقم أو حرف " must_not_contain_two_special_chars_in_seq: "يجب أن لا يحتوي على تسلسل من 2 أو رموز خاصة (.-_)" - must_not_contain_confusing_suffix: "يجب أن لا تحتوي على ملحقة مربكة مثل : json. أو png. الخ." + must_not_end_with_confusing_suffix: "يجب أن لا ينتهي ب صيغ معقده كــ .json أو .png" email: not_allowed: "بريد الكتروني غير مسموح . يرجى استخدام بريد الكتروني آخر " blocked: "غير مسموح" ip_address: blocked: "لا يُسمح بتسجيل جديد من عنوان ip الخاص بك " max_new_accounts_per_registration_ip: "وفقًا لعنوان IP الخاص بك فقد تم حظر التسجيل (لقد وصلت للحد الأقصى المسموح به) تواصل مع أحد المشرفين." + flags_reminder: + subject_template: + zero: "لا يوجد تبليغات تنتظر التعامل معها" + one: "تبليغ 1 ينتظر التعامل معها" + two: "تبليغان ينتظران التعامل معها" + few: "%{count} تبليغات تنتظر التعامل معها" + many: "%{count} تبليغات تنتظر التعامل معها" + other: "%{count} تبليغات تنتظر التعامل معها" + unsubscribe_mailer: + subject_template: "اكد انك لا تريد استقبال بريد الكتروني من %{site_title} بعد ألان" invite_mailer: subject_template: "%{invitee_name} دعاك إلى '%{topic_title}' على %{site_domain_name}" text_body_template: | @@ -1384,95 +1447,10 @@ ar: (إذا انتهت مدة صلاحية الرابط أعلاه، اختر "نسيت كلمة المرور" عند تسجيل الدخول مع عنوان البريد الإلكتروني الخاص بك.) test_mailer: subject_template: "[%{site_name}] بريد الكتروني بهدف الاختبار" - text_body_template: | - هذا بريد إختبار إلكتروني من - - [**%{base_url}**][0] - - أهداف البريد معقدة. هنا بعض الأشياء المهمة يجب عليك مراجعتها أولا: - - - كن *متأكد* لوضع `إشعارات البريد الإلكتروني` من: عنوان صحيح في إعدادات موقعك. **النطاق المخصص في أو "من" عنوان رسائل البريد الإلكتروني التي أرسلتها سيتم التحقق تجاه مجال بريدك الإلكتروني**. - - - معرفة كيفية عرض المصدر الخام للبريد الإلكتروني في عميل بريدك , لذا يمكنك البحث في رؤوس صفحات البريد الإلكتروني للأدلة المهمة. في Gmail, خيار "إظهار الأصلية" في القائمة المنسدلة في أعلى اليمين لكل بريد إلكتروني. - - - **مهم جدا:** هل الـ ISP الخاص بك له سجل DNS عكسي مدخل لربط أسماء النطاقات وعناوين IP التي أرسلت بريد منها؟ [اختبر سجل PTR العكسي][2] هنا. إذا كان ISP الخاص بك لم يدخل سجل مؤشر DNS العكسي المناسب, من غير المحتمل جدا تسليم أي من بريدك الإلكتروني. - - - هل مجالك لـ[سجل SPF][8] صحيح؟ [أختبر سجل SPF الخاص بك][1] هنا. لاحظ أن TXT هو نوع سجل رسمي صحيح لـSPF. - - - Iهل مجالك لـ [DKIM سجل][3] صحيح؟ هذا سيحسن بشكل كبير أهداف البريد الإلكتروني. [أختبر سجل DKIM الخاص بك][7] هنا. - - - إذا شغلت خادم البريد الخاص بك, راجع للتأكد من IPs لخادم بريدك [ليست في أي قوائم سوداء][4]. أيضا تحقق من إرسال تأكيد مضيف كامل التأهيل الذي يحل في DNS في رسالته الترحيبية. إذا كان لا, سيسبب رفض بريدك الإلكتروني من عدة خدمات. - - (الطريقة *السهلة* هي إنشاء حساب مجاني في [Mandrill][md] أو [Mailgun][mg] أو [Mailjet][mj], التي لديها عطاء مجاني والبريد مجاني والخطط وستكون جيدة للإتصالات القصيرة. لا تزال بحاجة لإعداد سجلات SPF و DKIM في DNS الخاص بك, رغم ذلك!) - - نأمل منك أن يلقي إختبار أهداف البريد الإلكتروني الموافقة! - - حظ جيد, - - أصدقائك في [Discourse](http://www.discourse.org) - - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: https://www.mailjet.com/pricing new_version_mailer: subject_template: "[%{site_name}] يوجد اصدار جديد , تحديث متوفر" - text_body_template: | - نسخة جديدة من [Discourse](http://www.discourse.org) متوفرة. - - نسختك: %{installed_version} - النسخة الجديدة: **%{new_version}** - - ربما تريد أن: - - - ما الجدي في [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - التحديث من متصفحك من [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - زيارة [meta.discourse.org](http://meta.discourse.org) للأخبار, والمناقشة, ودعم Discourse. new_version_mailer_with_notes: subject_template: "[%{site_name}] التحديث متوفر" - text_body_template: | - نسخة جديدة من [Discourse](http://www.discourse.org) متوفرة. - - نسختك: %{installed_version} - النسخة الجديدة: **%{new_version}** - - ربما تريد أن: - - - ما الجدي في [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - التحديث من متصفحك من [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - زيارة [meta.discourse.org](http://meta.discourse.org) للأخبار, والمناقشة, ودعم Discourse. - - ### ملاحظات الإصدارة - - %{notes} - flags_reminder: - flags_were_submitted: - zero: "لم ترسل تبليغات خلال الساعات الماضية." - one: "هذه التبليغات أرسلت خلال ساعة مضت." - two: "هذه التبليغات أرسلت خلال ساعتان مضتا." - few: "هذه التبليغات أرسلت خلال %{count} ساعات مضت." - many: "هذه التبليغات أرسلت خلال %{count} ساعات مضت." - other: "هذه التبليغات أرسلت خلال %{count} ساعات مضت." - please_review: "يرجى مراجعة ذلك " - post_number: "مشاركة" - how_to_disable: 'يمكنك تعطيل أو تغيير تكرار تذكير البريد الإلكتروني عبر "إشعار حول الإعلامات بعد" الإعدادات.' - subject_template: - zero: "لا يوجد تبليغات تنتظر التعامل معها" - one: "تبليغ 1 ينتظر التعامل معها" - two: "تبليغان ينتظران التعامل معها" - few: "%{count} تبليغات تنتظر التعامل معها" - many: "%{count} تبليغات تنتظر التعامل معها" - other: "%{count} تبليغات تنتظر التعامل معها" queued_posts_reminder: subject_template: zero: "[%{site_name}] %{count} المشاركات التي تنتظر معينتها" @@ -1514,101 +1492,6 @@ ar: أيضا, إذا اختفت المشاركة مرة ثانية, ستظل مخفية حتى يتم التعامل معها من قبل الموظفين وربما يكون هناك مزيد من العمل, بما في ذلك من الممكن أن يعلق حسابك. لمزيد من الإرشادات، يرجى الرجوع لموقعنا[دليل المجتمع](%{base_url}/guidelines). - usage_tips: - text_body_template: | - هنا بعض الخطوات السريعة لتبدأ: - - ##قراءة - - لقراءة المزيد, **استمر بالتمرير لأسفل!** - - الردود الجديدة والمواضيع الجديدة ونحو ذلك, ستظهر تلقائياً -دون الحاجة لتحديث الصفحة. - - ## التصفح - - -للبحث, صفحة المستخدم الخاصة بك, أو القائمة , استخدم **أيقونة الأزرار في الجزء العلوي الأيمن**. - - -اختيار عنوان موضوع سيأخذك دائماً الى **الرد التالي غير المقروء ** في الموضوع. - للدخول أول أو آخر الموضوع, اختر رقم الرد أو آخِر تاريخ. - - - - - عند قراءة موضوع, اختر شريط التقدم من الزر الأيمن لعناصر تحكم في التنقل كاملة. انتقل للأعلى بسرعة باختيار عنوان الموضوع. أضغط ? للحصول على قائمة باختصارات لوحة المفاتيح السريعة جدا. - - - - ## الرد - - - للرد على **الموضوع بشكل عام**, استخدم في الجزء السفلي جدا من الموضوع. - - - للرد على **شخص مخصص**, استخدم على مشاركاتهم. - - - للرد **بموضوع جديد**, استخدم إلى يمين المشاركة. كلا المواضيع القديمة والجديدة سيرتبطون مع بعضهم تلقائيا. - - لإدخال إقتباس, حدد النص الذي تريد إقتباسه, ثم أضغط أي زر رد. كرر للإقتباسات المتعددة! - - - - لإشعار شخص عن ردك, أشر بأسمائهم. أكتب `@` للبدء باختيار اسم العضو. - - - - لاستخدام [معيار الرسوم التعبيرية](http://www.emoji.codes/), أكتب فقط `:` لوصلها بالاسم, أو استخدم الوجوه التقليدية الضاحكة `;)` - - - - لتوليد اختصار لرابط, ألصقه في السطر بمفرده: - - - - ## التفاعل - - هناك أزرار التفاعل في أسفل كل مشاركة: - - - - لتسمح لشخص ما تعرفه الذي تستمتع وتقدر مشاركاتهم, استخدم زر **إعجاب** . شارك ما يعجبك! - - اذا رايت خطأ في منشور شخص ما .قم بتعديله شخصيا, أو [العاملون لدينا](%{base_url}/about), أعرف حول ذلك بزر **التبليغ** . يمكنك أيضا **مشاركة** رابط لمشاركة, أو **تفضيل** ليكون مرجع لك لاحقا على صفحة العضو. - - - ##تنبيهات - - - عندما يرد عليك احد,اقتبس منشورك,او ذكر اسم المستخدم خاصتك, هنالك رقم سوف يظهر فورا في الجزء العلوي الايمن من الصفحه. استعمله لتصل **لتنبيهاتك** - - - - - - لا تخف اذا نسيت ردا-سوف يصلك بريد الكتروني بكل التنبيهات التي وصلتك عندما كنت بعيدا. - - - ##تفضيلاتك - - - كل المواضيع في اقل من **يومين مضت** تعتبر جديدة. - - - اي موضوع كنت **شاركت فيه بنشاط**(بصنعه,الردود, او القراءه لفتره ممتده ) سوفي تعقب تلقائيا. - - - سوف ترى مؤشر الرقم الجديد الغير مقروى و الازرق بعد هذا الموضوع مباشره: - - - - - يمكنك تغيير إشعاراتك لأي موضوع عبر لوحة التحكم بالإشعارات في أسفل الموضوع. - - - - يمكنك أيضا تعيين حالة الإشعار لكل فئة, إذا أردت أن ترى كل موضوع جديد في فئة خاصة. - - لتغيير أي من هذه الإعدادات, أنظر [تفضيلات المستخدم الخاصة بك](%{base_url}/my/preferences). - - ## ثقة المجتمع - - يمكنك المشاركة هنا, ومع مرور الوقت ستكسب ثقة المجتمع, كن عضو صالح, وسيتم رفع قيود العضو الجديد. لترفع [مستوى الثقة] بما فيه الكفاية (https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), عليك اكتساب قدرات جديدة لمساعدتنا في إدارة مجتمعنا معا. welcome_user: subject_template: "مرحبا بك في %{site_name}!" text_body_template: | @@ -1678,20 +1561,16 @@ ar: csv_export_succeeded: subject_template: "اكتمل تصدير البيانات" text_body_template: | - تصدير البيانات الخاصة بك بنجاح! :dvd: + صُدِّرَت بياناتك بنجاح ! :dvd: %{file_name} (%{file_size}) - رابط التحميل أعلاه ستكون صالحة لمدة 48 ساعة. + رابط التحميل أعلاه سيكون صالحاً لمدة 48 ساعة. csv_export_failed: subject_template: "فشل تصدير البيانات" text_body_template: "نحن آسفون، لكنه فشل تصدير البيانات الخاصة بك. يرجى التحقق من السجلات أو اتصل بأحد المشرفين." - email_reject_trust_level: - subject_template: "[%{site_name}] بريد الكتروني -- غير موثوق" - text_body_template: "نحن آسفون ، ولكن رسالة البريد الإلكتروني إلى %{destination} (titled %{former_title}) لا تعمل. \n\nحسابك لا يمتلك مستوى الثقة المطلوب للنشر مواضيع جديدة إلى عنوان البريد الإلكتروني. إذا كنت تعتقد أن هذا الخطأ، اتصل بأعضاء المشرفين.\n" email_reject_no_account: subject_template: "[%{site_name}] بريد الكتروني -- حساب غير معروف" - text_body_template: "نحن آسفون ، ولكن رسالة البريد الإلكتروني إلى %{destination} (titled %{former_title}) لا تعمل. \n\nليس هنالك حساب عضو يمتلك هذا البريد الالكتروني. حاول أن ترسل من بريد الكتروني مختلف، أو أتصل بـ أحد المشرفين.\n\n" email_reject_empty: subject_template: "[%{site_name}] بريد الكتروني -- بدون محتوى" text_body_template: |2 @@ -1706,36 +1585,23 @@ ar: email_reject_invalid_access: subject_template: "[%{site_name}] بريد الكتروني -- غير صالح" text_body_template: "نحن آسفون ، ولكن رسالة البريد الإلكتروني إلى %{destination} (titled %{former_title}) لا تعمل. \n\nحسابك لا يمتلك الصلاحيات لنشر مواضيع جديدة في تلك الفئة. إذا كنت تعتقد أن هذا الخطأ، اتصل بالاعضاء المشرفين.\n" - email_reject_post_error: - subject_template: "[%{site_name}] بريد الكتروني -- خطأ المشاركة" - text_body_template: | - نحن آسفون ، ولكن رسالة البريد الإلكتروني إلى %{destination} (titled %{former_title}) لا تعمل. - - بعض الأسباب المحتملة هي: التنسيق المعقد، رسالة كبيرة جدا، رسالة صغيرة جدا. يرجى المحاولة مرة أخرى، أو الرد عبر الموقع الإلكتروني إذا استمر هذا الوضع. - email_reject_post_error_specified: - subject_template: "[%{site_name}] بريد الكتروني -- خطأ المشاركة" - text_body_template: "نحن آسفون ، ولكن رسالة البريد الإلكتروني إلى %{destination} (titled %{former_title}) لا تعمل. \n\nالسبب:\n\n%{post_error}\n\nاذا كنت تستطيع تصحيح المشكلة، يرجى المحاولة لاحقاً.\n" + email_reject_strangers_not_allowed: + subject_template: "مشاكل البريد ألالكتروني [%{site_name}] -- دخول غير صالح" + email_reject_invalid_post: + subject_template: "مشاكل البريد ألالكتروني [%{site_name}] -- مشكله في النشر " + email_reject_invalid_post_specified: + subject_template: "مشاكل البريد ألالكتروني [%{site_name}] -- مشكله في النشر " email_reject_reply_key: subject_template: "[%{site_name}] بريد الكتروني -- مفتاح رد غير معروف" - text_body_template: "نحن آسفون ، ولكن رسالة البريد الإلكتروني إلى %{destination} (titled %{former_title}) لا تعمل. \n\nمفتاح الرد المُقدم غير صالح أو غير معروف، لذلك نحن لا نعرف ما هو هذا البريد الإلكتروني للرد عليه. أتصل بالأعضاء المشرفين.\n" - email_reject_destination: - subject_template: "[%{site_name}] بريد الكتروني -- عنوان غير معروف" - text_body_template: "نحن آسفون ، ولكن رسالة البريد الإلكتروني إلى %{destination} (titled %{former_title}) لا تعمل. \n\nلم يتم التعرف على أي من العناوين. الرجاء التأكد من أن عنوان الموقع هو في To: line (not Cc: or Bcc:)، والتي انت تقوم بإرسالها إلى عنوان البريد الإلكتروني الصحيح المقدمة من الاعضاء المشرفين.\n" email_reject_topic_not_found: subject_template: "[%{site_name}] بريد الكتروني -- موضوع غير موجود" - text_body_template: "نحن آسفون ، ولكن رسالة البريد الإلكتروني إلى %{destination} (titled %{former_title}) لا تعمل. \n\nالموضوع الذي تريد الرد عليه لم يعد موجودا، وربما تم حذفه؟ إذا كنت تعتقد أن هذا خطأ، اتصل أحد الاعضاء المشرفين. \n" email_reject_topic_closed: subject_template: "[%{site_name}] بريد الكتروني -- موضوع مغلق" text_body_template: "نحن آسفون ، ولكن رسالة البريد الإلكتروني إلى %{destination} (titled %{former_title}) لا تعمل. \n\nالموضوع الذي تريد الرد عليه مغلق حاليا والتي لم تعد تقبل ردود. إذا كنت تعتقد أن هذا خطأ، اتصل أحد الأعضاء المشرفين.\n" email_reject_auto_generated: subject_template: "[%{site_name}] بريد الكتروني -- توليد رد آلي" - text_body_template: "نحن آسفون ، ولكن رسالة البريد الإلكتروني إلى %{destination} (titled %{former_title}) لا تعمل. \n\n بريدك الإلكتروني عُلّم كـ\"مولد تلقائي\"، وهو ما لا يمكن قبوله. إذا كنت تعتقد أن هذا خطأ، اتصل أحد الاعضاء المشرفين.\n" email_error_notification: subject_template: "[%{site_name}] بريد الكتروني -- خطأ مصادقة POP" - text_body_template: | - خطأ في المصادقة عند استطلاع الرسائل من خادم POP . - - من فضلك تأكد من تكوين إعدادات خادم POP من[إعدادات الموقع](%{base_url}/admin/site_settings/category/email). too_many_spam_flags: subject_template: "حساب جديد مقفول" text_body_template: | @@ -1746,31 +1612,10 @@ ar: للمعلومات الاضافيه.الرجاء مراجعه [قوانين مجتمعنا] (%{base_url}/guidelines). blocked_by_staff: subject_template: "الحساب مُعطل" - text_body_template: | - مرحبا, - - هذه رسالة تلقائية من %{site_name} أن أحيطكم علما بأن تم حظر الحساب الخاص بك عن طريق الطاقم - لمزيد من الإرشادات، يرجى الرجوع إلى موقعنا على [community guidelines](%{base_url}/guidelines). user_automatically_blocked: subject_template: "العضو الجديد %{username} تم حجبه بسبب تبليغات عليه في المجتمع" - text_body_template: | - هذه رسالة تلقائية. - - المستخدم الجديد [%{username}](%{base_url}%{user_url})تم حظره تلقائيا بسبب عدة بالغات من عدة مستخدمين %{username}'s post(s). - - رجاءًا [استعراض البلاغات](%{base_url}/admin/flags).إذا تم حظر %{username} بشكل خاطئ من المشاركة، أنقر فوق رفع الحظر [صفحة الإدارة](%{base_url}%{user_url}). - - يمكن تغيير هذا الحد من اعدادات الموقع `block_new_user` . spam_post_blocked: subject_template: "العضو الجديد %{username} تم حجب مشاركاته بسبب تكرار الروابط " - text_body_template: | - هذه رسالة تلقائية. - - عضو جديد [%{username}](%{base_url}%{user_url}) حاول إنشاء المشاركات متعددة مع روابط إلى %{domains},ولكن هذه المشاركات تم حظرها لتجنب البريد المزعج. المستخدم لا يزال قادراً على أنشاء مشاركات جديدة التي لم تصل إلى %{domains}. - - من فضلك [review the user](%{base_url}%{user_url}). - - هذا يمكن تعديلها عن طريق `` newuser_spam_host_threshold` وإعدادات موقع white_listed_spam_host_domains`. unblocked: subject_template: "الحساب مُفعل " text_body_template: |+ @@ -1794,10 +1639,6 @@ ar: download_remote_images_disabled: subject_template: "الغاء تفعيل تحميل الصور عن بعد " text_body_template: "تم تعطيل الإعداد 'download_remote_images_to_local' لأنه تم الوصول إلى حد مساحة القرص في 'download_remote_images_threshold'." - unsubscribe_link: | - لإلغاء الاشتراك من هذه الرسائل، قم بزيارة [user preferences](%{user_preferences_url}). - - لإيقاف تلقي إشعارات حول هذا الموضوع بالذات، [click here](%{unsubscribe_url}). subject_re: "اعادة " subject_pm: "[مسائًا]" user_notifications: @@ -1805,42 +1646,26 @@ ar: unsubscribe: title: "غير مشترك " description: "لست مهتما في تلقي هذه الرسائل الالكترونيه؟ لا مشكله! اضغط تحت ليتم الغاء اشتركك فورا:" - reply_by_email: "للاستجابه, رد علي هذه الرساله او قم بزياره%{base_url}%{url}% في متصفحك" - visit_link_to_respond: "للرد، قم بزيارة %{base_url}%{url} في متصفحك." posted_by: "مشاركة بواسطة %{username} على %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} دعاك لرسالة '%{topic_title}'" - text_body_template: |2 - - %{username} دعوتك إلى رسالة - - > **%{topic_title}** - > - > %{topic_excerpt} - - at - - > %{site_title} -- %{site_description} - - يرجى زيارة هذا الرابط لعرض الرسالة: %{base_url}%{url} - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} دعوتك للموضوع '%{topic_title}'" - text_body_template: |2 - - %{username} دعوتك للنقاش - - > **%{topic_title}** - > - > %{topic_excerpt} - - at - - > %{site_title} -- %{site_description} - - الرجاء زيارة هذا الرابط لعرض الرسالة: %{base_url}%{url} + user_invited_to_private_message_pm_staged: + subject_template: "[%{site_name}] %{username} دعاك للرسالة '%{topic_title}'" user_replied: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_replied_pm: + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1850,6 +1675,8 @@ ar: user_quoted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1859,6 +1686,19 @@ ar: user_mentioned: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1868,6 +1708,8 @@ ar: user_posted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1877,10 +1719,20 @@ ar: user_posted_pm: subject_template: "[%{site_name}] [مساءً] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} + --- + %{respond_instructions} + user_posted_pm_staged: + subject_template: "%{optional_re}%{topic_title}" + text_body_template: |2 + + %{message} + --- %{respond_instructions} digest: @@ -1923,11 +1775,6 @@ ar: انقر على الرابط التالي لاختيار كلمة مرور لحسابك الجديد: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] تأكيد البريد الإلكتروني الجديد " - text_body_template: | - قم بتاكيد عنوان بريدك الالكتروني لـ %{site_name} عن طريق الضغط علي الرابط التالي: - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "قد وافقت على %{site_name}!" text_body_template: | @@ -1947,14 +1794,14 @@ ar: signup: subject_template: "[%{site_name}] تأكيد حسابك الجديد " text_body_template: | - مرحبا بكم في %{site_name}! + أهلا وسهلا بك في %{site_name}! + + أُنقر على الرابط التالي لتأكيد وتفعيل حسابك الجديد : - انقر على الرابط التالي لتأكيد وتفعيل حسابك الجديد: %{base_url}/users/activate-account/%{email_token} - إذا كان الرابط أعلاه غير قابلة للنقر، حاول نسخ ولصقه في شريط العناوين في مستعرض ويب الخاص بك. + إذا كان الرابط أعلاه غير قابل للنقر، حاول نسخه ولصقه في شريط العناوين في متصفح الويب عندك. page_not_found: - title: "الصفحة المطلوبة غير موجودة او ليس لديك صلاحيات لرؤيتها " popular_topics: "شعبي " recent_topics: "الأخيرة" see_more: "المزيد" @@ -1979,8 +1826,6 @@ ar: images: too_large: "نعتذر، الصورة الذي تريد رفعها كبيرة جداً ( الحد الاقصى هو %{max_size_kb} كيلوبايت )،يرجى اعادة تغيير حجمها ثم حاول مرة اخرى." size_not_found: "نعتذر، لكننا لا يمكن تحديد حجم الصورة. ربما صورتك تالفة؟" - avatar: - missing: "عذرا، صورة العرض التي اخترتها ليست متوفرة على الخادم، هل تستطيع رفعها مرة أخرى ؟" flag_reason: sockpuppet: "عضو جديد إنشاء موضوع , وعضو أخر جديد في نفس عنوان IP . شاهد flag_sockpuppets إعداد الموقع" spam_hosts: "حاول هذا العضو الجديد إنشاء مشاركات متعددة لها روابط بنفس المجال. شاهد newuser_spam_host_threshold إعداد الموقع." @@ -2012,9 +1857,7 @@ ar: تعديل محتويات المنشور الاول في هذا الموضوع %{page_name} page. guidelines_topic: title: "الأسئلة الشائعة/توجيهات" - body: "\n\n## [هذا مكان راقي للنقاشات العامة](#الراقي)\nالرجاء التعامل في هذا المنتدى بنفس الاحترام الذي يكون في حديقة عامة، نحن أيضًا مجتمع مشارك للمصدر و mdahs ؛ المكان هنا لتبادل المهارات والمعرفة والاهتمامات عبر الحوارات.\n\nهذه ليست شروط صارمة و سريعة، مجرد مساعده لحفظ حقوق الأشخاص في مجتمعنا، استخدام هذه المبادئ والتوجيهات يساعد في الحفاظ على الجتمع جيدًا للنقاشات الراقية.\n\n\n\n## [تحسين النقاشات](#تحسين)\n\nساعدنا على جعل هذا المكان جيد للمناقشة، من خلال العمل الدائم لتحسين المناقشات ببعض الطرق، مهما كانت صغيرة، اذا لم تكن متأكدًا أن ما تكتبه سيضيف قيمة، فكر فيما ستكتبه وحاول مرة أخرى في وقت لاحق.\n\nالموضوعات التي تتم مناقشتها هنا مهمة بالنسبة لنا، ونريد منك أن تناقشها كما لو أنها مهمة بالنسبة لك، احترم الموضوعات والاشخاص، حتى لو لم تكن متفقًا مع بعض ما يقال.\n\nأحد طرق تحسين النقاش هو اكتشاف ما يجري، يرجى قضاء بعض الوقت في تصفح المواضيع هنا قبل الرد أو نشر موضوعك، لتكون لديك فرصة افضل في تلبية حاجات الآخرين اللذين يشاركونك اهتماماتك.\n\n\n\n## [تقبل الآخرين، حتى لو كنت غير متفق](#تقبل)\n\nقد ترغب في الرد على من اختلفت معهم، هذا جيد/ ولكن تذكر، انتقد الافكار وليس الأشخاص، يرجى تجنب :\n\n* الاهانة.\n* Ad hominem attacks.\n* الرد على اسلوب المنشور بدلا من المضمون الفعلي.\n* لا تحتسب المتناقضات.\nبدلا من ذلك، وفر الأدلة البينة التي تعمل على تحسين المحادثة.\n\n\n\n## [مشاركاتكم](#شارك)\n\nالمحادثات التي تكون لدينا متناغمة مع الجميع، ساعدونا في التأثير على مستقبل المجتمع، عن طريق مناقشة ما يجعل لهذا المنتدى أهمية و mdash ؛ وتجنب غير ذلك.\n\nيوفر النقاش\ - \ الأدوات التي تمكن الجميع من معرفة أفضل (واسوأ) المشاركات: كالمفضلة، العلامات المرجعية، الاعجابات، البلاغات، الردود، التعديلات، وما الى ذلك. استخدمها لتحسين تجربة الجميع.\nدعونا نحاول ترك المكان أفضل مما كان.\n\n\n\n## [اذا رأيت مشكلة، بلّغ عنها ](#الابلاغ-عن-المشاكل)\n\nالمشرفون لديهم سلطة خاصة، وهم مسؤولون عن هذا المنتدى، ولكن حتى أنتم بمساعدتكم، يستطيع المشرفون تسيير المجتمع، ليس عمال النظافة أو الشرطة.\n\nعندما ترى سلوك سيئ، لا ترد عليه، وتشجع السلوك السيئ بالاعتراف به، وتستهلك طاقتك، قم بالإبلاغ عنه، اذا وصلت بلاغات بما فيه الكفاية، سيتم اتخاذ الإجراءات اللازمة، اما تلقائيا، أو عن طريق مشرف.\n\nمن أجل الحفاظ على سلامة المجتمع، المشرفين لديهم الحق في إزالة اي محتوى أو حذف أي حساب لأي سبب في اي وقت، المشرفون لا يتابعون جميع المنشورات الجديدة بأي شكل كان، المشرفون ومشغلوا الموقع لا يتحملون أية مسؤولية عن اي محتو يتم نشره بواسطة المجتمع.\n\n\n\n## [دائما كن محترما](#محترم)\n\nلا شيء يخرب المحادثة الجيدة، مثل الوقاحة:\n\n* كم محترمًا، لا تنشر أي شيء تهجمي، أو خطاب كراهية.\n* ابق المجتمع نظيفا، لا تنشر أي شيء فاحش أو جنسي صريح.\n* احترم الآخرين، لا تضايق أو تحزن شخص، لا تنتحل شخصية أحد آخر، أو تنشر معلوماتهم الخاصة.\n* احترم منتدانا، لا تعمل ازعاجا - spam - أو تخرب أو خلاف ذك في المنتدى.\n\nهذه المصطلحات ليست محددة مع تعريف دقيق و mdahs ؛ عليك تجنب ظهور اي من هذه الأشياء. اذا كنت غير مقتنع، أسال نفسك ما ذا سيكون شعورك اذا نشرت على الصفحة الاولى في صحيفة نيويورك تايمز.\nهذا منتدى عام، ومؤشرات محركات البحث تحتوي هذه النقاشات، حافظ على اللغة، الروابط والصور الآمنة للعائلة والاصدقاء.\n\n\n\ - \n## [حافظ عليه مرتبا](#المحافظة-على-الترتيب)\n\nأبذل مزيدا من الجهد في وضع الأمور في مكانها المناسب، حتى نتمكن من قضاء المزيد من الوقت في المناقشات ونقلل من التنظيف، هكذا:\n\n* لا تبدأ موضوع في قسم غير مناسب.\n* لا تنشر نفس المشاركة في مواضيع متعددة.\n* لا ترد ردودا دون محتوى مناسب.\n* لا تحول مسار الموضوع من المنتصف. \n* لا توقع مشاركاتك أو mdash؛ كل منشوراتك مرتبطة بمعلومات ملفك الشخصي.\n\nبدلا من كتابة \"+1\" أو كتابة \" نتفق عليه \"، استخدم زر أعجبني، من أخذ المواضيع لمواضيع مختلفة جذريا، استخدم ردا برابط الموضوع مرتبط .\n\n\n\n## [انشر فقط شيء تملكه](#سرقة)\nلا تستيطع نشر أي شيء رقمي يملكه شخص آخر دون إذن، لا تستطيع نشر وصف، رابط ، أو سرقة ممتلكات شخص ما الفكرية(البرامج والفيديو والصوت والصور)، أو انتهاك اي قانون آخر.\n\n\n\n## [بدعم منك](#دعم)\n\nيتم تشغيل هذا الموقع من قِبل [friendly local staff](/about) وأنت، و المجتمع، إذا كان لديك اي أسئلة أخرى حول كيف تعمل الأشياء هنا، افتح موضوع جديد في [site feedback category](/c/site-feedback)وأُدعنا للمناقشة! إذا كان هناك أي قضية حرجة أو حاجة ماسة لم يتم التعامل معها بموضوع ميت أو أو بلاغ، اتصل بنا عبر [staff page] (/about).\n\n\n\n## [شروط الخدمة](#شروط-الخدمة)\n\nنعم، الكلام القانوني ممل، ولكن يجب أن نحمي أنفسنا و ndahs ؛ من الاشخاص الغير ودودين، لدينا [Terms of Service](/tos) وصف لك (ولنا) السلوك والحقوق ذات الصلة بالمحتوى والخصوصية، لاستخدام هذه الخدمة، يجب أن توافق على التزامك بالشروط والقوانين[TOS](/tos).\n" + body: "\n\n## [هذا مكان راقي للنقاشات العامة](#الراقي)\nالرجاء التعامل في هذا المنتدى بنفس الاحترام الذي يكون في حديقة عامة، نحن أيضًا مجتمع مشارك للمصدر و — المكان هنا لتبادل المهارات والمعرفة والاهتمامات عبر الحوارات.\n\nهذه ليست شروط صارمة و سريعة، مجرد مساعده لحفظ حقوق الأشخاص في مجتمعنا، استخدام هذه المبادئ والتوجيهات يساعد في الحفاظ على الجتمع جيدًا للنقاشات الراقية.\n\n\n\n## [تحسين النقاشات](#تحسين)\n\nساعدنا على جعل هذا المكان جيد للمناقشة، من خلال العمل الدائم لتحسين المناقشات ببعض الطرق، مهما كانت صغيرة، اذا لم تكن متأكدًا أن ما تكتبه سيضيف قيمة، فكر فيما ستكتبه وحاول مرة أخرى في وقت لاحق.\n\nالموضوعات التي تتم مناقشتها هنا مهمة بالنسبة لنا، ونريد منك أن تناقشها كما لو أنها مهمة بالنسبة لك، احترم الموضوعات والاشخاص، حتى لو لم تكن متفقًا مع بعض ما يقال.\n\nأحد طرق تحسين النقاش هو اكتشاف ما يجري، يرجى قضاء بعض الوقت في تصفح المواضيع هنا قبل الرد أو نشر موضوعك، لتكون لديك فرصة افضل في تلبية حاجات الآخرين اللذين يشاركونك اهتماماتك.\n\n\n\n## [تقبل الآخرين، حتى لو كنت غير متفق](#تقبل)\n\nقد ترغب في الرد على من اختلفت معهم، هذا جيد/ ولكن تذكر، انتقد الافكار وليس الأشخاص، يرجى تجنب :\n\n* الاهانة.\n* الشخصنة : انتقاد الشخص لا الفكرة .\n* الرد على اسلوب المنشور بدلا من المضمون الفعلي.\n* لا تحتسب المتناقضات.\nبدلا من ذلك، وفر الأدلة البينة التي تعمل على تحسين المحادثة.\n\n\n\n## [مشاركاتكم](#شارك)\n\nالمحادثات التي تكون لدينا متناغمة مع الجميع، ساعدونا في التأثير على مستقبل المجتمع، عن طريق مناقشة ما يجعل لهذا المنتدى أهمية و — وتجنب غير ذلك.\n\nيوفر النقاش الأدوات التي تمكن الجميع من معرفة أفضل (واسوأ) المشاركات: كالمفضلة، العلامات المرجعية، الاعجابات، البلاغات، الردود، التعديلات، وما الى ذلك. استخدمها لتحسين تجربة الجميع.\nدعونا نحاول ترك المكان أفضل مما كان.\n\n\n\n## [اذا رأيت مشكلة، بلّغ عنها ](#الابلاغ-عن-المشاكل)\n\nالمشرفون لديهم سلطة خاصة، وهم مسؤولون عن هذا المنتدى، ولكن حتى أنتم بمساعدتكم، يستطيع المشرفون تسيير المجتمع، ليس عمال النظافة أو الشرطة.\n\nعندما ترى سلوك سيئ، لا ترد عليه، وتشجع السلوك السيئ بالاعتراف به، وتستهلك طاقتك، قم بالإبلاغ عنه، اذا وصلت بلاغات بما فيه الكفاية، سيتم اتخاذ الإجراءات اللازمة، اما تلقائيا، أو عن طريق مشرف.\n\nمن أجل الحفاظ على سلامة المجتمع، المشرفين لديهم الحق في إزالة اي محتوى أو حذف أي حساب لأي سبب في اي وقت، المشرفون لا يتابعون جميع المنشورات الجديدة بأي شكل كان، المشرفون ومشغلوا الموقع لا يتحملون أية مسؤولية عن اي محتو يتم نشره بواسطة المجتمع.\n\n\n\n## [دائما كن محترما](#محترم)\n\nلا شيء يخرب المحادثة الجيدة، مثل الوقاحة:\n\n* كم محترمًا، لا تنشر أي شيء تهجمي، أو خطاب كراهية.\n* ابق المجتمع نظيفا، لا تنشر أي شيء فاحش أو جنسي صريح.\n* احترم الآخرين، لا تضايق أو تحزن شخص، لا تنتحل شخصية أحد آخر، أو تنشر معلوماتهم الخاصة.\n* احترم منتدانا، لا تعمل ازعاجا - spam - أو تخرب أو خلاف ذك في المنتدى.\n\nهذه المصطلحات ليست محددة مع تعريف دقيق و — عليك تجنب ظهور اي من هذه الأشياء. اذا كنت غير مقتنع، أسال نفسك ما ذا سيكون شعورك اذا نشرت على الصفحة الاولى في صحيفة نيويورك تايمز.\nهذا منتدى عام، ومؤشرات محركات البحث تحتوي هذه النقاشات، حافظ على اللغة، الروابط والصور الآمنة للعائلة والاصدقاء.\n\n\n\n## [حافظ عليه مرتبا](#المحافظة-على-الترتيب)\n\nأبذل مزيدا من الجهد في وضع الأمور في مكانها المناسب، حتى نتمكن من قضاء المزيد من الوقت في المناقشات ونقلل من التنظيف، هكذا:\n\n* لا تبدأ موضوع في قسم غير مناسب.\n* لا تنشر نفس المشاركة في مواضيع متعددة.\n* لا ترد ردودا دون محتوى مناسب.\n* لا تحول مسار الموضوع من المنتصف. \n* لا توقع مشاركاتك أو — كل منشوراتك مرتبطة بمعلومات ملفك الشخصي.\n\nبدلا من كتابة \"+1\" أو كتابة \" نتفق عليه \"، استخدم زر أعجبني، من أخذ المواضيع لمواضيع مختلفة جذريا، استخدم ردا برابط الموضوع مرتبط .\n\n\n\n## [انشر فقط شيء تملكه](#سرقة)\nلا تستيطع نشر أي شيء رقمي يملكه شخص آخر دون إذن، لا تستطيع نشر وصف، رابط ، أو سرقة ممتلكات شخص ما الفكرية(البرامج والفيديو والصوت والصور)، أو انتهاك اي قانون آخر.\n\n\n\n## [بدعم منك](#دعم)\n\nيتم تشغيل هذا الموقع من قِبل [friendly local staff](/about) وأنت، و المجتمع، إذا كان لديك اي أسئلة أخرى حول كيف تعمل الأشياء هنا، افتح موضوع جديد في [site feedback category](/c/site-feedback)وأُدعنا للمناقشة! إذا كان هناك أي قضية حرجة أو حاجة ماسة لم يتم التعامل معها بموضوع ميت أو أو بلاغ، اتصل بنا عبر [staff page] (/about).\n\n\n\n## [شروط الخدمة](#شروط-الخدمة)\n\nنعم، الكلام القانوني ممل، ولكن يجب أن نحمي أنفسنا و – من الاشخاص الغير ودودين، لدينا [Terms of Service](/tos) وصف لك (ولنا) السلوك والحقوق ذات الصلة بالمحتوى والخصوصية، لاستخدام هذه الخدمة، يجب أن توافق على التزامك بالشروط والقوانين[TOS](/tos).\n" tos_topic: title: "شروط الخدمة" body: | @@ -2154,86 +1997,7 @@ ar: متأقلم أصلا مع [ شروط خدمة WordPress](http://en.wordpress.com/tos/). privacy_topic: title: "سياسة الخصوصية" - body: "\n\n## [ما هي البيانات التي نقوم بجمعها؟](#جمع)\n\nنحن نجمع معلومات عنك عندما تسجل في موقعنا، وعندما تشارك في المنتدى عن طريق القراءة أو الكتابة، ونقوم بتقييم ما تم مشاركته هنا .\n\n\nيمكنك زيارة موقعنا بدون تسجيل، ولكن عند التسجيل في موقعنا، سيطلب منك ادخال اسمك وعنوان بريدك الالكتروني، وسيتم التحقق من بريدك الالكتروني بإرسال رسالة الى بريدك الالكتروني تحتوي على رابط خاص، عند الضغط على هذا الرابط، نحن سنعرف أنك مالك البريد الالكتروني المتحكم فيه.\n\nعندما تقوم بالتسجيل في موقعنا والنشر، سنقوم بتسجيل عنوان IP الذي نشرت منه، أيضا قد تحتفظ سجلات الخادم عناوين IP جميع الطلبات من الخادم.\n\n\n\n## [في ماذا نستخدم المعلومات الخاصة بك؟](#استخدام)\n\nيمكننا استخدام المعلومات التي نجمعها عنك بإحدى الطرق التالية:\n\n* لتخصيص تجربتك و mdahs؛ المعلومات الخاصة بك تساعدنا على الاستجابة بشكل أفضل لاحتياجاتك الفردية.\n* لتحسين موقعنا و mdash ؛ نسعى باستمرار لتحسين ما يعرضه الموقع استنادًا الى المعلومات والتغذية الراجعة - الملاحظات - التي نتلقاها منك.\n* لتحسين خدمة العملاء و mdash ؛ المعلومات الخاصة بك تساعدنا على الاستجابة بشكل أكثر فعالية لطلبات الدعم وخدمة العملاء.\n* لإرسال رسائل البريد الالكتروني الدورية و mdash ؛ سنستخدم عنوان البريد الالكتروني الذي وفرته لنا لإرسال معلومات إليك، الاشعارات التي تطلبها حول التحديثات في المواضيع، أو الاستجابة لاسم المستخدم الخاص بك، كالرد على الاستفسارات، او الطلبات أو اسئلة اخرى.\n\n\n\n## [كيف نقوم بحماية معلوماتك ؟](#حماية)\n\nنقوم بتطبيق مجموعة من الإجراءات الأمنية للمحافظة على أمن وسلامة معلوماتك الشخصية، عندما تقوم بإرسال أو إدخال أو الدخول لمعلوماتك الشخصية.\n\ - \n\n\n## [ما هي سياسة الاحتفاظ بالبيانات الخاصة بك ؟](#الاحتفاظ-بالبيانات)\n\nسوف نبذل جهونا بإخلاص للتالي :\n\n* الاحتفاظ بسجلات عناوين IP لجميع الطلبات لهذا الخادم لمدة لا تزيد عن 90 يومًا.\n* الاحتفاظ بعناوين IP الخاصة بالمستخدمين المسجلين ومنشوراتهم لمدة لا تزيد عن 5 سنوات.\n\n\n\n## [هل نستخدم الكعكات - cookies - ملفات تعريف الارتباط ؟ ](#كعكات)\n\nنعم، الكعكات هي عبارة عن ملفات صغيرة يقوم الموقع أو مزود الخدمة بنقلها الى القرص الصلب لحاسبك من خلال متصفحك (اذا سمحتم بذلك)، هذه الكعكات تعرف الموقع على متصفحك، فن كان لديك حساب مسجل، سيتم ربطه مع حسابك.\n\nنحن نستخدم ملفات تعريف الارتباط - cookies - لفهم وحفظ التفضيلات الخاصة بك للزيارات في المستقبل، وجمع البيانات العامة حول حركة المرور والتفاعل في الموقع حتى نتمكن من تقديم تجربة وأدوات افضل في المستقبل، نحن قد نتعاقد مع مقدمي خدمات من الطرف الثالث لمساعدتنا في تحسين فهمنا لزوار الموقع، مقدمي الخدمات لا يسمح لهم بإستخدام المعلومات التي تم جمعها نيابة عنا، إلّا لمساعدتنا في سلوكنا وتحسين أعمالنا.\n\n\n\n## [هل نقوم بالإفصاح عن أي معلومات لأطراف خارجية؟](#إفصاح)\n\nنحن لا نبيع، ولا نتاجر أو ننقل المعلومات الشخصية الى أطراف خارجية. وهذا لا يشمل الطرف الخاجية الموثوق بها والتي تساعد في تشغيل موقعنا، واجراء أعمالنا، أو تقديم الخدمات لكم، طالما أن تلك الأطراف موافقة للحفاظ على سرية المعلومات، يجوز لنا الافراج عن معوماتك الشخصية عندما نرى أنه هو المناسب للإمتثال للقانون، مع فرض سياسة موقعنا، أو حماية حقوقنا أو حقوق الآخرين، أو حقوق الملكية، أو السلامة. ومع ذلك، يمكننا تقديم معلومات الزائرين دون تحديد الهوية، الى أطراف أخرى للتسويق والاعلان،\ - \ أو غيرها من الاستخدامات.\n\n\n\n## [روابط الطرف الثالث](#الطرف-الثالث)\n\nأحيانًا، نفترض، أنه عند وجود مواقع طرف ثالث تقجم خدمات أو منتجات على موقعنا، كان لدى مواقع الطرف الثالث هذه، سياسات خصوصية منفصلة ومستقلة، لن يكون لدينا أية مسؤولية عن محتوى وأنشطة هذه المواقع المرتبطة، ومع ذلك، نحن نسعى إلى حماية موقعنا وسلامته، ونرحب بأي ملاحظات حول هذه المواقع. \n\n\n\n## [الالتزام بقانون حماية خصوصية الأطفال على الانترنت ](#coppa)\n\nموقعنا والمنتجات والخدمات موجهه للأشخاص اللذين لا تقل أعمارهم عن 13 سنة، إذا كان هذا الخادم في الولايات المتحدة الأمريكية، من شروط COPPA\n ([Children's Online Privacy Protection Act](https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act))\nعدم استخدم هذا الموقع.\n\n\n\n## [سياسة الخصوصية على الانترنت](#متصل)\n\nتنطبق سياسة الخصوصية على الانترنت فقط على المعلومات التي يتم جمعها من خلال موقعنا، ولاتنطبق على المعلومات التي يتم جمعها أثناء عدم الاتصال.\n\n\n\n## [الموافقة](#الموافقة)\n\nبإستخدام موقعنا، أنت توافق على سياسة الخصوصية لموقعنا.\n\n\n\n## [تغييرات على سياسة الخصوصية](#تغييرات)\n\nإذا قمنا بتغيير سياسة الخصوصية، سوف نقوم بنشر هذه التغييرات في هذه الصفحة.\n\nهذه الوثيقة هي نسخة من CC-BY-SA تم تحديثها في 31 مايو عام 2013م .\n" - static: - search_help: | -

    نصائح

    -

    -

      -
    • العناوين المتطابقة لها أولوية وحركة; عند الشك, ابحث عن العناوين
    • -
    • وحيد, الكلمات الغير مألوفة ستعطي أفضل نتائج
    • -
    • جرب البحث ضمن فئة خاصة, موضوع, أو عضو
    • -
    -

    -

    الخيارات

    -

    - - - - - - - -
    order:viewsorder:latestorder:likes
    status:openstatus:closedstatus:archivedstatus:norepliesstatus:single_user
    category:foouser:foogroup:foobadge:foo
    in:likesin:postedin:watchingin:trackingin:private
    in:bookmarksin:first
    posts_count:nummin_age:daysmax_age:days
    -

    -

    - rainbows category:parks status:open order:latestسيبحث عن المواضيع المحتوية كلمة "rainbows" في الفئة "parks" التي لم تغلق أو تؤرشف, رتبت بتاريخ أخر المشاركة. -

    - badges: - long_descriptions: - autobiographer: | - منحت هذه الشارة لتعبئتك صفحة المستخدم الشخصية واختيار صورة شخصية. السماح للمجتمع معرفة المزيد حولك وماذاترغب يجعل المجتمع أكثر ارتباطاً - first_like: | - منحت هذه الشارة لك لإعجابك للمرة الأولى بالمشاركة بواسطة :heart: button. الإعجاب بالمشاركات وسيلة رائعة تسمح لرفاقك في المجتمع معرفة أن المشاركة كانت مثيرة للاهتمام ومفيدة وجيدة، أو ممتعة. شارك ما يعجبك! - first_link: | - منحت لك هذه الشارة لأنك قمت أول مرة بوضع رابط لموضوع آخر في الردود. المواضيع المترابطة تساعد القراء المتابعين على إيجاد المواضيع المتعلقة بحوارهم ، ويظهر الصلة بين المواضيع. - first_quote: |+ - منحت هذه الشارة لإقتباسك المرة الأولى منشورًا في ردك. نقلًا عن الأجزاء ذات الصلة من المنشورات السابقة في ردودك يساعد على إبقاء المناقشات مرتكزة وحول موضوع المنشور. - - first_share: | - منحت هذه الشارة لمشاركتك لأول مرة رابط الرد أو المنشور باستعمال زر المشاركة. مشاركة الروابط وسيلة رائعة لإظهار النقاشات المهمة للآخرين وتنمية المجتمع الخاص بك. - read_guidelines: | - منحت هذه الشارة لأنك قرأت مبادئ و توجيهات المجتمع . اتباع هذه المبادئ والتوجيهات البسيطة تساعد على بناء مجتمع آمن وممتع دائمًا. - reader: | - منحت هذه الشارة لقراءتك موضوع طويل. القراءة أمر اساسي، القراءة عن كثب تساعدك على متابعة الحوار و كتابة ردود أفضل ومتكاملة. - editor: | - منحت هذه الشارة لتحريرك مشاركتك، لا تترد في تحرير مشاركاتك في أي وقت لتحسينها، وإصلاح الأخطاء الصغيرة، أو إضافة شئ نسيته. - first_flag: | - منحت هذه الشارة لتبليغك عن منشور، و التبليغ ذو أهمية بالغة لصحة مجتمعك، اذا لاحظت أي منشور يتطلب متابعة المشرف رجاءًا لا تتردد في الابلاغ عنه - يمكنك أيضًا استخدام مربع الابلاغ لإرسال رسالة الى المستخدمين الآخرين. - nice_share: | - منحت هذه الشارة لزيارة 25 شخصاً لرابط المشاركة الذي نشرته، عمل رائع ! مشاركة روابط النقاشات المثيرة للاهتمام مع أصدقاءك وسيلة ممتازة لتنمية مجتمعنا. - welcome: | - منحت هذه الشارة لأنك تلقيت علامة الإعجاب الأولى على منشورك، لقد وجد رفاقك أن منشورك مثيرٌ للاهتمام وممتعا، أو مفيدًا ! - anniversary: | - منحت هذه الشارة لأنك كنت عضوًا لمدة سنة، لقد نشرت منشورًا واحدًا على الأقل في هذه السنة. شكرًا لمساهمتك في مجتمعنا ! - good_share: | - منحت هذه الشارة لمشاركتك رابط المنشور الذي زاره 300 زائر، نجاح باهر! لقد عرضت نقاشًا مهما لـالكثير من الأشخاص الجدد وساعدت على تنمية مجتمعنا. - great_share: | - منحت هذه الشارة لمشاركتك رابط المنشور الذي زاره 100زائر، عمل رائع! لقد شجعت على مناقشة مهمة لجمهور جديد ضخم لهذا المجتمع وساعدت على تنميته بشكل كبير. - nice_post: | - هذه الشارة تمنح لوجود رد حصل على 10 إعجابات. عمل جميل! - nice_topic: | - هذه الشارة تمنح لوجود رد حصل على 10 إعجابات. عمل جميل! - good_post: | - هذه الشارة تمنح لوجود رد حصل على 25 إعجاب. عمل جيد! - good_topic: | - هذه الشارة تمنح لوجود رد حصل على 25 إعجاب. عمل جيد! - great_post: | - هذه الشارة تمنح لوجود رد حصل على 50 إعجاب. ياللعجب! - great_topic: | - هذه الشارة تمنح لوجود رد حصل على 50 إعجاب. ياللعجب! - basic: | - منحت هذه الشارة لأنك وصلت مستوى الثقة الأول 1 ، شكرًا لتعليقاتك وقراءتك عدد من المواضيع لتتعرف على مجتمعنا، وقد تم رفع جميع قيود المستخدم الجديد عنك، و مُنحت الامكانيات الأسياسة في المجتمع، مثل الرسائل الشخصية، و الإبلاغ، و تحرير الويكي والقدرة على نشر الصور والروابط المتعددة. - member: | - منحت هذه الشارة لأنك وصلت مستوى الثقة الثاني 2، شكرًا لمشاركتك لأسابيع منذ انضمامك لمجتعنا، يمكنك الآن إرسال دعوات للأعضاء من صفحتك الشخصية أو من المواضيع، إنشاء مجموعة الرسائل، وإعطاء علامات إعجاب أكثر في اليوم الواحد. - regular: |+ - يتم منح هذه الشارة عندما تصل لمستوى الثقة 3. شكرا لكونك جزءا منضبطاً من مجتمعنا على مدى أشهر، أحد القراء الأكثر نشاطا ومساهمة معتمدا، لما يجعل هذا المجتمع عظيم. يمكنك الآن إعادة تصنيف وإعادة تسمية الموضوعات، والوصول إلى الاستراحة الخاصة وأقدر على الإعلام بالبريد المزعج، وغيرها كثير من الإعجابات لكل يوم. - - leader: | - هذه الشارة تمنح لك عندما تصل للمرحلة 4. أنت قائد في هذا المجتمع مرشح من الطاقم كمثال جيد في المجتمع في أقوالك وأفعالك. لديك القدرة على تعديل كل المشاركات، إدارة المواضيع بالتثبيت والإغلاق والتقسيم والدمج والأرشفة والعديد من الإعجابات كل يوم. + body: "\n\n## [ما هي البيانات التي نقوم بجمعها؟](#جمع)\n\nنحن نجمع معلومات عنك عندما تسجل في موقعنا، وعندما تشارك في المنتدى عن طريق القراءة أو الكتابة، ونقوم بتقييم ما تم مشاركته هنا .\n\n\nيمكنك زيارة موقعنا بدون تسجيل، ولكن عند التسجيل في موقعنا، سيطلب منك ادخال اسمك وعنوان بريدك الالكتروني، وسيتم التحقق من بريدك الالكتروني بإرسال رسالة الى بريدك الالكتروني تحتوي على رابط خاص، عند الضغط على هذا الرابط، نحن سنعرف أنك مالك البريد الالكتروني المتحكم فيه.\n\nعندما تقوم بالتسجيل في موقعنا والنشر، سنقوم بتسجيل عنوان IP الذي نشرت منه، أيضا قد تحتفظ سجلات الخادم عناوين IP جميع الطلبات من الخادم.\n\n\n\n## [في ماذا نستخدم المعلومات الخاصة بك؟](#استخدام)\n\nيمكننا استخدام المعلومات التي نجمعها عنك بإحدى الطرق التالية:\n\n* لتخصيص تجربتك و mdahs؛ المعلومات الخاصة بك تساعدنا على الاستجابة بشكل أفضل لاحتياجاتك الفردية.\n* لتحسين موقعنا و mdash ؛ نسعى باستمرار لتحسين ما يعرضه الموقع استنادًا الى المعلومات والتغذية الراجعة - الملاحظات - التي نتلقاها منك.\n* لتحسين خدمة العملاء و mdash ؛ المعلومات الخاصة بك تساعدنا على الاستجابة بشكل أكثر فعالية لطلبات الدعم وخدمة العملاء.\n* لإرسال رسائل البريد الالكتروني الدورية و mdash ؛ سنستخدم عنوان البريد الالكتروني الذي وفرته لنا لإرسال معلومات إليك، الاشعارات التي تطلبها حول التحديثات في المواضيع، أو الاستجابة لاسم المستخدم الخاص بك، كالرد على الاستفسارات، او الطلبات أو اسئلة اخرى.\n\n\n\n## [كيف نقوم بحماية معلوماتك ؟](#حماية)\n\nنقوم بتطبيق مجموعة من الإجراءات الأمنية للمحافظة على أمن وسلامة معلوماتك الشخصية، عندما تقوم بإرسال أو إدخال أو الدخول لمعلوماتك الشخصية.\n\n\n\n## [ما هي سياسة الاحتفاظ بالبيانات الخاصة بك ؟](#الاحتفاظ-بالبيانات)\n\nسوف نبذل جهونا بإخلاص للتالي :\n\n* الاحتفاظ بسجلات عناوين IP لجميع الطلبات لهذا الخادم لمدة لا تزيد عن 90 يومًا.\n* الاحتفاظ بعناوين IP الخاصة بالمستخدمين المسجلين ومنشوراتهم لمدة لا تزيد عن 5 سنوات.\n\n\n\n## [هل نستخدم الكعكات - cookies - ملفات تعريف الارتباط ؟ ](#كعكات)\n\nنعم، الكعكات هي عبارة عن ملفات صغيرة يقوم الموقع أو مزود الخدمة بنقلها الى القرص الصلب لحاسبك من خلال متصفحك (اذا سمحتم بذلك)، هذه الكعكات تعرف الموقع على متصفحك، فن كان لديك حساب مسجل، سيتم ربطه مع حسابك.\n\nنحن نستخدم ملفات تعريف الارتباط - cookies - لفهم وحفظ التفضيلات الخاصة بك للزيارات في المستقبل، وجمع البيانات العامة حول حركة المرور والتفاعل في الموقع حتى نتمكن من تقديم تجربة وأدوات افضل في المستقبل، نحن قد نتعاقد مع مقدمي خدمات من الطرف الثالث لمساعدتنا في تحسين فهمنا لزوار الموقع، مقدمي الخدمات لا يسمح لهم بإستخدام المعلومات التي تم جمعها نيابة عنا، إلّا لمساعدتنا في سلوكنا وتحسين أعمالنا.\n\n\n\n## [هل نقوم بالإفصاح عن أي معلومات لأطراف خارجية؟](#إفصاح)\n\nنحن لا نبيع، ولا نتاجر أو ننقل المعلومات الشخصية الى أطراف خارجية. وهذا لا يشمل الطرف الخاجية الموثوق بها والتي تساعد في تشغيل موقعنا، واجراء أعمالنا، أو تقديم الخدمات لكم، طالما أن تلك الأطراف موافقة للحفاظ على سرية المعلومات، يجوز لنا الافراج عن معوماتك الشخصية عندما نرى أنه هو المناسب للإمتثال للقانون، مع فرض سياسة موقعنا، أو حماية حقوقنا أو حقوق الآخرين، أو حقوق الملكية، أو السلامة. ومع ذلك، يمكننا تقديم معلومات الزائرين دون تحديد الهوية، الى أطراف أخرى للتسويق والاعلان، أو غيرها من الاستخدامات.\n\n\n\n## [روابط الطرف الثالث](#الطرف-الثالث)\n\nأحيانًا، نفترض، أنه عند وجود مواقع طرف ثالث تقجم خدمات أو منتجات على موقعنا، كان لدى مواقع الطرف الثالث هذه، سياسات خصوصية منفصلة ومستقلة، لن يكون لدينا أية مسؤولية عن محتوى وأنشطة هذه المواقع المرتبطة، ومع ذلك، نحن نسعى إلى حماية موقعنا وسلامته، ونرحب بأي ملاحظات حول هذه المواقع. \n\n\n\n## [الالتزام بقانون حماية خصوصية الأطفال على الانترنت ](#coppa)\n\nموقعنا والمنتجات والخدمات موجهه للأشخاص اللذين لا تقل أعمارهم عن 13 سنة، إذا كان هذا الخادم في الولايات المتحدة الأمريكية، من شروط COPPA\n ([Children's Online Privacy Protection Act](https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act))\nعدم استخدم هذا الموقع.\n\n\n\n## [سياسة الخصوصية على الانترنت](#متصل)\n\nتنطبق سياسة الخصوصية على الانترنت فقط على المعلومات التي يتم جمعها من خلال موقعنا، ولاتنطبق على المعلومات التي يتم جمعها أثناء عدم الاتصال.\n\n\n\n## [الموافقة](#الموافقة)\n\nبإستخدام موقعنا، أنت توافق على سياسة الخصوصية لموقعنا.\n\n\n\n## [تغييرات على سياسة الخصوصية](#تغييرات)\n\nإذا قمنا بتغيير سياسة الخصوصية، سوف نقوم بنشر هذه التغييرات في هذه الصفحة.\n\nهذه الوثيقة هي نسخة من CC-BY-SA تم تحديثها في 31 مايو عام 2013م .\n" admin_login: success: "البريد أُرسل" error: "خطأ!" @@ -2244,3 +2008,8 @@ ar: performance_report: initial_post_raw: 'هذا الموضوع يحتوي على معلومات الاداء اليومي للموقع ' initial_topic_title: التبليغ عن اداء الموقع + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.bs_BA.yml b/config/locales/server.bs_BA.yml index a0ac846100d..dab422bd42d 100644 --- a/config/locales/server.bs_BA.yml +++ b/config/locales/server.bs_BA.yml @@ -16,11 +16,9 @@ bs_BA: loading: "Loading" powered_by_html: 'Powered by Discourse, best viewed with JavaScript enabled' log_in: "Log In" - via: "%{username} via %{site_name}" - is_reserved: "is reserved" purge_reason: "Automatically deleted due to being old and unverified" disable_remote_images_download_reason: "Remote images download was disabled because there wasn't enough disk space available." - errors: + errors: &errors messages: too_long_validation: "is limited to %{max} characters; you entered %{length}." invalid_boolean: "Invalid boolean." @@ -42,26 +40,6 @@ bs_BA: permalink: "Permalink" imported_from: "This is a companion discussion topic for the original entry at %{link}" in_reply_to: "▶ %{username}" - too_many_mentions: - zero: "Sorry, you can't mention other users." - one: "Sorry, you can only mention one other user in a post." - other: "Sorry, you can only mention %{count} users in a post." - too_many_mentions_newuser: - zero: "Sorry, new users can't mention other users." - one: "Sorry, new users can only mention one other user in a post." - other: "Sorry, new users can only mention %{count} users in a post." - too_many_images: - zero: "Sorry, new users can't put images in posts." - one: "Sorry, new users can only put one image in a post." - other: "Sorry, new users can only put %{count} images in a post." - too_many_attachments: - zero: "Sorry, new users can't put attachments in posts." - one: "Sorry, new users can only put one attachment in a post." - other: "Sorry, new users can only put %{count} attachments in a post." - too_many_links: - zero: "Sorry, new users can't put links in posts." - one: "Sorry, new users can only put one link in a post." - other: "Sorry, new users can only put %{count} links in a post." spamming_host: "Sorry you cannot post a link to that host." user_is_suspended: "Suspended users are not allowed to post." just_posted_that: "is too similar to what you recently posted" @@ -150,9 +128,6 @@ bs_BA: user_profile: bio_raw: "O Meni" errors: - messages: - is_invalid: "nije validno; pokušaj sa malo više opisa" - has_already_been_used: "već se koristi" models: topic: attributes: @@ -169,6 +144,7 @@ bs_BA: attributes: hex: invalid: "is not a valid color" + <<: *errors user_profile: no_info_me: "
    the About Me field of your profile is currently blank, would you like to fill it out?
    " no_info_other: "
    %{name} hasn't entered anything in the About Me field of their profile yet
    " @@ -203,8 +179,6 @@ bs_BA: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "About the %{category} category" - replace_paragraph: "[Replace this first paragraph with a short description of your new category. This guidance will appear in the category selection area, so try to keep it below 200 characters. Until you edit this text or create topics, this category won't appear on the categories page.]" - post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, as well as to establish any category guidelines or rules.\n\nSome things to consider in any discussion replies below:\n\n- What is this category for? Why should people select this category for their topic?\n\n- How is this different than the other categories we already have?\n\n- Do we need this category?\n\n- Should we merge this with another category, or split it into more categories?\n" errors: uncategorized_parent: "Uncategorized can't have a parent category" self_parent: "A subcategory's parent cannot be itself" @@ -218,15 +192,8 @@ bs_BA: title: "novi korisnik" basic: title: "korisnik" - regular: - title: "član" - leader: - title: "pokretač" - elder: - title: "vođa" change_failed_explanation: "You attempted to demote %{user_name} to '%{new_trust_level}'. However their trust level is already '%{current_trust_level}'. %{user_name} will remain at '%{current_trust_level}' - if you wish to demote user lock trust level first" rate_limiter: - slow_down: "You have performed this action too many times, try again later" too_many_requests: "We have a daily limit on how many times that action can be taken. Please wait %{time_left} before trying again." datetime: distance_in_words: @@ -266,16 +233,11 @@ bs_BA: description: 'Ovaj post sadrži tekst koji je uvredljiv i pogrdan. I kao takav kosi se sa našim pravilima korišćenja.' long_form: 'opomeni kao neprikladno' notify_user: - title: 'Obavijesti {{username}}' - description: 'Ovaj post sadrži materijal o kojem želim da raspravljam sa osobom direktno, privatno i bez opomene.' long_form: 'korisnik obavješten' email_title: 'Tvoj post u temi "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Obavijesti Moderatore" - description: 'Ovaj post treba prijaviti moderatoru jer se kosi sa pravilima korišćenja, ili drugim razlogom ne navedenim gore.' - long_form: 'obavješten moderator' - email_title: 'Postu u temi "%{title}" treba pažnju moderatora' email_body: "%{link}\n\n%{message}" bookmark: title: 'Sačuvaj' @@ -300,7 +262,6 @@ bs_BA: long_form: 'opomenuto kao neprikladno' notify_moderators: title: "Obavijesti Moderatore" - description: 'Ovu temu treba prijaviti moderatoru jer se kosi sa pravilima korišćenja, ili drugim razlogom ne navedenim gore.' long_form: 'moderator obaviješten' email_title: 'Ova tema "%{title}" treba pažnju moderatora' email_body: "%{link}\n\n%{message}" @@ -424,37 +385,6 @@ bs_BA: consumer_email_warning: "Your site is configured to use Gmail (or another consumer email service) to send email. Gmail limits how many emails you can send. Consider using an email service provider like mandrill.com to ensure email deliverability." site_contact_username_warning: "The site_contact_username setting is blank. Please update it in the Site Settings. Set it to the username of an admin user who should be the sender of system messages." notification_email_warning: "The notification_email setting is blank. Please update it in the Site Settings." - content_types: - education_new_reply: - title: "New User Education: First Replies" - description: "Pop up just-in-time guidance automatically displayed above the composer when new users begin typing their first two new replies." - education_new_topic: - title: "New User Education: First Topics" - description: "Pop up just-in-time guidance automatically displayed above the composer when new users begin typing their first two new topics." - usage_tips: - title: "New User Guidance" - description: "Guidance and essential information for new users." - welcome_user: - title: "Welcome: New User" - description: "A private message automatically sent to all new users when they sign up." - welcome_invite: - title: "Welcome: Invited User" - description: "A private message automatically sent to all new invited users when they accept the invitation from another user to participate." - login_required_welcome_message: - title: "Login Required: Welcome Message" - description: "Welcome message that is displayed to logged out users when the 'login required' setting is enabled." - login_required: - title: "Login Required: Homepage" - description: "The text displayed for unauthorized users when login is required on the site." - head: - title: "HTML head" - description: "HTML that will be inserted inside the tags." - top: - title: "Top of the pages" - description: "HTML that will be added at the top of every page (after the header, before the navigation or the topic title)." - bottom: - title: "Bottom of the pages" - description: "HTML that will be added at the bottom of every page." site_settings: censored_words: "Words that will be automatically replaced with ■■■■" delete_old_hidden_posts: "Auto-delete any hidden posts that stay hidden for more than 30 days." @@ -467,7 +397,6 @@ bs_BA: max_topic_title_length: "Maximum allowed topic title length in characters" min_private_message_title_length: "Minimum allowed title length for a private message in characters" min_search_term_length: "Minimum valid search term length in characters" - uncategorized_description: "The description of the uncategorized category. Leave blank for no description." allow_duplicate_topic_titles: "Allow topics with identical, duplicate titles." unique_posts_mins: "How many minutes before a user can make a post with the same content again" educate_until_posts: "When the user starts typing their first (n) new posts, show the pop-up new user education panel in the composer." @@ -479,7 +408,6 @@ bs_BA: download_remote_images_to_local: "Convert remote images to local images by downloading them; this prevents broken images." download_remote_images_threshold: "Minimum disk space necessary to download remote images locally (in percent)" disabled_image_download_domains: "Remote images will never be downloaded from these domains. Pipe-delimited list." - ninja_edit_window: "For (n) seconds after posting, editing will not create a new version in the post history." post_edit_time_limit: "The author can edit or delete their post for (n) minutes after posting. Set to 0 for forever." edit_history_visible_to_public: "Allow everyone to see previous versions of an edited post. When disabled, only staff members can view." delete_removed_posts_after: "Posts removed by the author will be automatically deleted after (n) hours. If set to 0, posts will be deleted immediately." @@ -501,7 +429,6 @@ bs_BA: summary_posts_required: "Minimum posts in a topic before 'Summarize This Topic' is enabled" summary_likes_required: "Minimum likes in a topic before 'Summarize This Topic' is enabled" summary_percent_filter: "When a user clicks 'Summarize This Topic', show the top % of posts" - enable_private_messages: "Allow trust level 1 users to create private messages and reply to private messages" enable_long_polling: "Message bus used for notification can use long polling" long_polling_interval: "Interval before a new long poll is issued in milliseconds " polling_interval: "How often should logged in user clients poll in milliseconds" @@ -615,16 +542,9 @@ bs_BA: tl2_requires_likes_received: "How many likes a user must receive before promotion to trust level 2." tl2_requires_likes_given: "How many likes a user must cast before promotion to trust level 2." tl2_requires_topic_reply_count: "How many topics user must reply to before promotion to trust level 2." - tl3_requires_days_visited: "Minimum number of days that a user needs to have visited the site in the last 100 days to qualify for promotion to trust level 3. (0 to 100)" - tl3_requires_topics_replied_to: "Minimum number of topics a user needs to have replied to in the last 100 days to qualify for promotion to trust level 3. (0 or higher)" - tl3_requires_topics_viewed: "The percentage of topics created in the last 100 days that a user needs to have viewed to qualify for promotion to trust level 3. (0 to 100)" - tl3_requires_posts_read: "The percentage of posts created in the last 100 days that a user needs to have viewed to qualify for promotion to trust level 3. (0 to 100)" tl3_requires_topics_viewed_all_time: "The minimum total number of topics a user must have viewed to qualify for trust level 3." tl3_requires_posts_read_all_time: "The minimum total number of posts a user must have read to qualify for trust level 3." - tl3_requires_max_flagged: "User must not have had more than x posts flagged by x different users in the last 100 days to qualify for promotion to trust level 3, where x is this setting's value. (0 or higher)" tl3_promotion_min_duration: "The minimum number of days that a promotion to trust level 3 lasts before a user can be demoted back to trust level 2." - tl3_requires_likes_given: "The minimum number of likes that must be given in the last 100 days to qualify for promotion to trust level 3." - tl3_requires_likes_received: "The minimum number of likes that must be received in the last 100 days to qualify for promotion to trust level 3." tl3_links_no_follow: "Do not remove rel=nofollow from links posted by trust level 3 users." min_trust_to_create_topic: "The minimum trust level required to create a new topic." min_trust_to_edit_wiki_post: "The minimum trust level required to edit post marked as wiki." @@ -694,7 +614,6 @@ bs_BA: max_daily_gravatar_crawls: "Maximum number of times Discourse will check Gravatar for custom avatars in a day" public_user_custom_fields: "A whitelist of custom fields for a user that can be shown publically." allow_profile_backgrounds: "Allow users to upload profile backgrounds." - sequential_replies_threshold: "Number posts a user has to make in a row in a topic before being reminded about too many sequential replies. " enable_mobile_theme: "Mobile devices use a mobile-friendly theme, with the ability to switch to the full site. Disable this if you want to use a custom stylesheet that is fully responsive." dominating_topic_minimum_percent: "What percentage of posts a user has to make in a topic before being reminded about overly dominating a topic." suppress_uncategorized_badge: "Don't show the badge for uncategorized topics in topic lists." @@ -718,7 +637,6 @@ bs_BA: notify_about_flags_after: "If there are flags that haven't been handled after this many hours, send an email to the contact_email. Set to 0 to disable." enable_cdn_js_debugging: "Allow /logs to display proper errors by adding crossorigin permissions on all js includes." show_create_topics_notice: "If the site has fewer than 5 public topics, show a notice asking admins to create some topics." - vacuum_db_days: "Run VACUUM FULL ANALYZE to reclaim DB space after migrations (set to 0 to disable)" prevent_anons_from_downloading_files: "Prevent anonymous users from downloading files. WARNING: this will prevent any site assets posted as attachments from working." errors: invalid_email: "Invalid email address." @@ -837,56 +755,10 @@ bs_BA: subject_template: "Set password for your %{site_name} account" test_mailer: subject_template: "[%{site_name}] Email Deliverability Test" - text_body_template: | - This is a test email from - - [**%{base_url}**][0] - - Email deliverability is complicated. Here are a few important things you should check first: - - - Be *sure* to set the `notification email` from: address correctly in your site settings. **The domain specified in the "from" address of the emails you send is the domain your email will be validated against**. - - - Know how to view the raw source of the email in your mail client, so you can examine email headers for important clues. in Gmail, it is the "show original" option in the drop-down menu at the top right of each mail. - - - **IMPORTANT:** Does your ISP have a reverse DNS record entered to associate the domain names and IP addresses you send mail from? [Test your Reverse PTR record][2] here. If your ISP does not enter the proper reverse DNS pointer record, it's very unlikely any of your email will be delivered. - - - Is your domain's [SPF record][8] correct? [Test your SPF record][1] here. Note that TXT is the correct official record type for SPF. - - - Is your domain's [DKIM record][3] correct? This will significantly improve email deliverability. [Test your DKIM record][7] here. - - - If you run your own mail server, check to make sure the IPs of your mail server are [not on any email blacklists][4]. Also verify that it is definitely sending a fully-qualified hostname that resolves in DNS in its HELO message. If not, this will cause your email to be rejected by many mail services. - - (The *easy* way is to create a free account on [Mandrill][md] or [Mailgun][mg] or [Mailjet][mj], which have free generous free mailing plans and will be fine for small communities. You'll still need to set up the SPF and DKIM records in your DNS, though!) - - We hope you received this email deliverability test OK! - - Good luck, - - Your friends at [Discourse](http://www.discourse.org) - - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [5]: %{base_url}/unsubscribe - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: http://www.mailjet.com/pricing - - ---- - - There should be an unsubscribe footer on every email you send, so let's mock one up. This email was sent by Name of Company, 55 Main Street, Anytown, USA 12345. If you would like to opt out of future emails, [click here to unsubscribe][5]. new_version_mailer: subject_template: "[%{site_name}] New Discourse version, update available" new_version_mailer_with_notes: subject_template: "[%{site_name}] update available" - flags_reminder: - please_review: "Please review them." - post_number: "post" - how_to_disable: 'Disable this email by changing the
    notify_about_flags_after
    setting to 0.' flag_reasons: off_topic: "Your post was flagged as **off-topic**: the community thinks it does not fit into the topic, as currently defined by the title and the first post." inappropriate: "Your post was flagged as **inappropriate**: the community thinks it is offensive, abusive, or a violation of [the community guidelines](/guidelines)." @@ -996,56 +868,16 @@ bs_BA: csv_export_failed: subject_template: "Export failed" text_body_template: "The export has failed. Please check the logs." - email_reject_trust_level: - subject_template: "Email issue -- Insufficient Trust Level" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - Your account does not have the required trust level to post new topics to this email address. If you believe this is in error, contact a staff member. email_reject_no_account: subject_template: "Email issue -- No Account" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - There is no known account with this email address. Try sending from a different email address, or contact a staff member. email_reject_empty: subject_template: "Email issue -- No Content" email_reject_parsing: subject_template: "Email issue -- Content unrecognized" - email_reject_post_error: - subject_template: "Email issue -- Posting error" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - Some possible causes are: complex formatting, message too large, message too small. Please try again, or post via the website if this continues. - email_reject_post_error_specified: - subject_template: "Email issue -- Posting error" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - Reason: - - %{post_error} - - If you can correct the problem, please try again. email_reject_reply_key: subject_template: "Email issue -- Bad Reply Key" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - The provided reply key is invalid or unknown, so we don't know what this email is in reply to. Contact a staff member. - email_reject_destination: - subject_template: "Email issue -- Bad Destination Address(es)" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - None of the destination addresses are recognized by the forum. Please make sure that the forum is in the To: line (not CC or BCC), and that you are sending to the email address provided by the forum administrators. email_error_notification: subject_template: "Email issue -- POP authentication error" - text_body_template: | - There has been an authentication error while polling mails from the POP server. - - Please make sure you have properly configured the POP credentials in [the site settings](%{base_url}/admin/site_settings/category/email). too_many_spam_flags: subject_template: "New account blocked" text_body_template: | @@ -1058,32 +890,10 @@ bs_BA: For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines). blocked_by_staff: subject_template: "Account blocked" - text_body_template: | - Hello, - - This is an automated message from %{site_name} to inform you that your account has been blocked by a staff member. - - For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines). user_automatically_blocked: subject_template: "New user %{username} blocked due to community flags" - text_body_template: | - This is an automated message. - - The new user [%{username}](%{base_url}%{user_url}) was automatically blocked because multiple users flagged %{username}'s post(s). - - Please [review the flags](%{base_url}/admin/flags). If %{username} was incorrectly blocked from posting, click the unblock button on [the admin page for this user](%{base_url}%{user_url}). - - This threshold can be changed via the `block_new_user` site settings. spam_post_blocked: subject_template: "New user %{username} posts blocked due to repeated links" - text_body_template: | - This is an automated message. - - The new user [%{username}](%{base_url}%{user_url}) tried to create multiple posts with links to %{domains}, but those posts were blocked to avoid spam. The user is still able to create new posts that do not link to %{domains}. - - Please [review the user](%{base_url}%{user_url}). - - This can be modified via the `newuser_spam_host_threshold` and `white_listed_spam_host_domains` site settings. unblocked: subject_template: "Account unblocked" text_body_template: | @@ -1107,60 +917,19 @@ bs_BA: unsubscribe: title: "Odjavi se" description: "Niste zainteresovani za ove email-e? Nema problema! Kliknite ovdje da se odjavite:" - reply_by_email: "Da odgovorite, reply to this email or visit %{base_url}%{url} in your browser." - visit_link_to_respond: "Da odgovorite, posjetite %{base_url}%{url} u vašem browseru." posted_by: "Odgovoreno %{username} dana %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} invited you to a private message '%{topic_title}'" - text_body_template: | - %{username} invited you to a private message '%{topic_title}' on %{site_name}: - - Please visit this link to view the topic: %{base_url}%{url} user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "Ukratko šta se dešavalo na %{site_link} od vaše zadnje posjete %{last_seen_at}." subject_template: "[%{site_name}] Pregled za %{date}" @@ -1198,12 +967,6 @@ bs_BA: Kliknite na link ispod da kreirate šifru za vaš nalog: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Potvrdite vaš novi email" - text_body_template: | - Confirm your new email address for %{site_name} by clicking on the following link: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "You've been approved on %{site_name}!" text_body_template: | @@ -1230,7 +993,6 @@ bs_BA: Ako link iznad ne može da se klikne onda ga kopirajte i ubacite u vaš internet pretraživač. page_not_found: - title: "Strana koju tražite je nepostojeća ili privatna." popular_topics: "Popularne" recent_topics: "Nove" see_more: "Više" @@ -1284,3 +1046,6 @@ bs_BA: title: "Terms of Service" privacy_topic: title: "Privacy Policy" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.cs.yml b/config/locales/server.cs.yml index 1a9c46a5603..ab1be99c652 100644 --- a/config/locales/server.cs.yml +++ b/config/locales/server.cs.yml @@ -10,17 +10,24 @@ cs: short_date_no_year: "D. MMM" short_date: "D. MMM, YYYY" long_date: "D. MMMM YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%-d. %-m. %Y" + short_no_year: "%-d. %B" + date_only: "%-d %B %Y" + date: + month_names: [null, ledna, února, března, dubna, května, června, července, srpna, září, října, listopadu, prosince] + <<: *datetime_formats title: "Discourse" topics: "Témata" posts: "příspěvky" loading: "Nahrávám" powered_by_html: 'Systém běží na Discourse, nejlépe funguje se zapnutým JavaScriptem' log_in: "Přihlásit se" - via: "%{username} přes %{site_name}" - is_reserved: "je rezervováno" + purge_reason: "Automaticky smazán jako opuštěný, neaktivovaný účet" disable_remote_images_download_reason: "Stahování obrázků z cizích serverů bylo vypnuto protože na disku není dostatek místa." anonymous: "Anonymní" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "je limitováno na %{max} znaků; zadali jste %{length}." @@ -36,8 +43,10 @@ cs: exclusion: je rezervováno greater_than: musí být větší než %{count} greater_than_or_equal_to: musí být větší nebo rovno %{count} + has_already_been_used: "již byl použit" inclusion: není zahrnutý v seznamu invalid: je neplatný + is_invalid: "je neplatný; zkus být trochu více popisný" less_than: musí být menší než %{count} less_than_or_equal_to: musí být menší nebo roven %{count} not_a_number: není číslo @@ -45,6 +54,7 @@ cs: odd: musí být lichý record_invalid: 'Ověření selhalo: %{errors}' restrict_dependent_destroy: + one: "Nelze odstranit záznam, protože závisející %{record} existuje" many: "Nemůžu smazat záznam protože na něm závisí %{record}." too_long: one: je příliš dlouhý ( maximálně %{count} znak) @@ -61,8 +71,18 @@ cs: other_than: "musí být jiný než %{count}" template: body: 'Nastaly problémy s následujícími poli: ' + header: + one: 1 chyba zamezila uložení modelu %{model} + few: '%{count} chyb zamezilo uložení modelu %{model}' + other: '%{count} chyb zamezilo uložení modelu %{model}' embed: load_from_remote: "Při načítání příspěvku nastala chyba." + site_settings: + min_username_length_exists: "Nemůžeš nastavit minimální délku uživatelského jména delší než je nejkratší uživatelské jméno." + min_username_length_range: "Nemůžeš nastavit minimum nad maximum." + max_username_length_exists: "Nemůžeš nastavit délku maximální uživatelského jména kratší než je nejdelší uživatelské jméno. " + max_username_length_range: "Nemůžeš nastavit maximum pod minimum." + default_categories_already_selected: "Nemůžeš vybrat kategorii používanou v jiném seznamu." bulk_invite: file_should_be_csv: "Nahraný soubrou by měl být ve formátu csv nebo txt." backup: @@ -91,26 +111,6 @@ cs: one: "1 reakce" few: "%{count} reakce" other: "%{count} reakcí" - too_many_mentions: - zero: "Bohužel, nemůžete zmiňovat ostatní uživatele." - one: "Bohužel, můžete zmínit jen jednoho uživatele v jednom příspěvku." - other: "Bohužel, můžete zmínit jen %{count} uživatelů v jednom příspěvku." - too_many_mentions_newuser: - zero: "Bohužel, návštěvníci nemohou zmiňovat ostatní uživatele." - one: "Bohužel, návštěvníci mohou zmínit jen jednoho uživatele v jednom příspěvku." - other: "Bohužel, návštěvníci mohou zmínit jen %{count} uživatelů v jednom příspěvku." - too_many_images: - zero: "Bohužel, návštěvníci nemohou vkládat obrázky do příspěvků." - one: "Bohužel, návštěvníci mohou do jednoho příspěvku vložit jen jeden obrázek." - other: "Bohužel, návštěvníci mohou do jednoho příspěvku vložit maximálně %{count} obrázků." - too_many_attachments: - zero: "Bohužel, noví uživatelé nemohou do příspěvků vkládat přílohy." - one: "Bohužel, noví uživatelé smějí do příspěvku vložit jen jednu přílohu." - other: "Bohužel, noví uživatelé smějí do příspěvku vložit jen %{count} příloh." - too_many_links: - zero: "Bohužel, návštěvníci nemohou vkládat odkazy do příspěvků." - one: "Bohužel, návštěvníci mohou do jednoho příspěvku vložit jen jeden odkaz." - other: "Bohužel, návštěvníci mohou do jednoho příspěvku vložit maximálně %{count} odkazů." spamming_host: "Bohužel, na tento server nemůžete odkazovat." user_is_suspended: "Vyloučení uživatelé nemohou přidávat příspěvky." just_posted_that: "je příliš podobný vašemu příspěvku z poslední doby" @@ -189,9 +189,6 @@ cs: user_profile: bio_raw: "O mně" errors: - messages: - is_invalid: "je neplatné; zkuste se vyjádřit více popisně" - has_already_been_used: "je již použito" models: topic: attributes: @@ -212,6 +209,7 @@ cs: attributes: hex: invalid: "není platná barva" + <<: *errors user_profile: no_info_me: "
    Pole 'o mně' je v tuto chvíli prázdné, nechcete si ho vyplnit?
    " no_info_other: "
    %{name} o sobě zatím žádné informace nevyplnil
    " @@ -225,8 +223,6 @@ cs: title: "Vítejte v Redakci" category: topic_prefix: "Definice kategorie pro %{category}" - replace_paragraph: "[Nahraďte tento první odstavec krátkých popisem nové kategorie. Zkuste se vejít do 200 znaků.]" - post_template: "%{replace_paragraph}\\\n\\\nPoužijte toto místo níže pro delší popis a stanovení pravidel diskuze!\n" errors: uncategorized_parent: "„Bez kategorie“ nemůže mít nadřazenou kategorii" self_parent: "Nadřazená kategorie nemůže zároveň být podkategorie" @@ -244,14 +240,9 @@ cs: title: "nový uživatel" basic: title: "základní uživatel" - regular: + member: title: "člen" - leader: - title: "normální" - elder: - title: "vůdce" rate_limiter: - slow_down: "Provedli jste tuhle akci moooockrát, zkuste to později" too_many_requests: "Děláte tuto akci příliš často. Prosím počkejte %{time_left} a zkuste to znovu." hours: one: "1 hodina" @@ -392,15 +383,10 @@ cs: title: 'Nevhodné' long_form: 'nahlášeno jako nevhodné' notify_user: - title: 'Zpráva @{{username}}' - description: 'Tato zpráva obsahuje něco o čem bych s autorem rád mluvil přímo a soukromě. Nevytvoří varování moderátorům.' email_title: 'Váš příspěvek v „%{title}“' email_body: "%{link}\\\n\\\n%{message}\n" notify_moderators: title: "Něco jiného" - description: 'Tento příspěvek vyžaduje pozornost moderátor z důvodů nevypsaných výše.' - long_form: 'nahlášeno moderátorům' - email_title: 'Příspěvek v tématu "%{title}" vyžaduje pozornost moderátora' email_body: "%{link}\\\n\\\n%{message}\n" bookmark: title: 'Záložka' @@ -425,7 +411,6 @@ cs: long_form: 'nahlášeno jako nevhodné' notify_moderators: title: "Něco jiného" - description: 'Toto téma vyžaduje pozornost moderátorů na základě pravidel komunity, pravidel použítí, nebo z jiného výše neuvedeného důvodu.' long_form: 'nahlášeno moderátorům' email_title: 'The topic "%{title}" requires moderator attention' email_body: "%{link}\\\n\\\n%{message}\n" @@ -456,6 +441,8 @@ cs: title: "Noví uživatelé" xaxis: "Den" yaxis: "Počet nových uživatelů" + profile_views: + xaxis: "Den" topics: title: "Témata" xaxis: "Den" @@ -536,6 +523,10 @@ cs: title: "Celkem" xaxis: "Den" yaxis: "Celkem API požadavků" + page_view_logged_in_mobile_reqs: + xaxis: "Den" + page_view_anon_mobile_reqs: + xaxis: "Den" http_background_reqs: title: "Pozadí" xaxis: "Den" @@ -559,6 +550,14 @@ cs: title: "Celkem" xaxis: "Den" yaxis: "Celkem požadavků" + time_to_first_response: + xaxis: "Den" + topics_with_no_response: + xaxis: "Den" + yaxis: "Celkem" + mobile_visits: + xaxis: "Den" + yaxis: "Počet návštěv" dashboard: rails_env_warning: "Váš server běží v módu %{env}." ruby_version_warning: "You are running a version of Ruby 2.0.0 that is known to have problems. Upgrade to patch level 247 or later." @@ -573,34 +572,6 @@ cs: image_magick_warning: 'Server je nakonfigurován, aby vytvářel náhledy velkých obrázků, ale není nainstalován ImageMagick. Nainstalujte ImageMagick pomocí vašeho oblíbeného balíčkovače, nebo navštivte web ImageMagick pro stažení aktuální verze.' contact_email_invalid: "Kontaktní email je neplatný. Prosím, aktualizujte položku contact_email v Nastavení webu." consumer_email_warning: "Váš web je nastaven, aby používal Gmail (nebo jinou uživatelskou emailovou službu) k odesílání emailů. Gmail limituje počet emailů, které můžete odeslat. Zvažte použití jiného emailového poskytovatele, jako je třeba mandrill.com k zajištění doručitelnosti emailů." - content_types: - education_new_reply: - title: "Školení nového uživatele: První odpovědi" - description: "Návod, který se automaticky zobrazí ve vyskakovacím okně nad editorem zpráv, když uživatelé píšou první dvě nové odpovědi." - education_new_topic: - title: "Školení nového uživatele: První témata" - description: "Návod, který se automaticky zobrazí ve vyskakovacím okně nad editorem zpráv, když uživatelé zakládají první dvě nová témata." - usage_tips: - title: "Příručka pro nové uživatele" - welcome_user: - title: "Uvítání: Nový uživatel" - welcome_invite: - title: "Uvítání: Pozvaný uživatel" - login_required_welcome_message: - title: "Vyžadováno přihlášení: Uvítací zpráva" - description: "Uvítací zpráva, která je zobrazena nepřihlášeným uživatelům, je-li zapnuto nastavení 'vyžadovat přihlášení'." - login_required: - title: "Vyžadováno přihlášení: Úvodní stránka" - description: "Text, který se zobrazí nepřihlášených uživatelům na webu, je-li přihlášení vyžadováno." - head: - title: "HTML hlavička" - description: "HTML that will be inserted inside the tags." - top: - title: "Vršek stránky" - description: "HTML přidané na vršek každé stránky (za hlavičku, ale před navigaci a před název tématu)." - bottom: - title: "Patička stránky" - description: "HTML, které bude přidáno před tag " site_settings: default_locale: "Výchozí jazyk této Discourse instance (kód ve formátu ISO 639-1)" allow_user_locale: "Povolit uživatelům nastavit si jazyk fóra" @@ -737,6 +708,8 @@ cs: subject_template: "Zálohování selhalo." csv_export_succeeded: subject_template: "Exportování dat dokončeno" + csv_export_failed: + subject_template: "Exportování dat selhalo" too_many_spam_flags: subject_template: "Účet zablokován" blocked_by_staff: @@ -763,64 +736,27 @@ cs: unsubscribe: title: "Odhlásit z odběru emailů" description: "Nechcete již od nás dostávat emaily? Žádný problém! Klikněte na odkaz níže pro okamžité odhlášení z odběru emailů:" - reply_by_email: "Pro odpověd stačí odepsat na tento email, nebo navštivte %{base_url}%{url} ve vašem prohlížeči." - visit_link_to_respond: "Pro odpověď navštive %{base_url}%{url} ve vašem prohlížeči." posted_by: "Zaslal uživatel %{username} dne %{post_date}" + user_invited_to_private_message_pm: + subject_template: "[%{site_name}] %{username} Vás pozval do konverzace '%{topic_title}'" user_replied: subject_template: "[%{site_name}] %{username} vás citoval v '%{topic_title}'" - text_body_template: | - %{username} vás citoval v '%{topic_title}' na %{site_name}: - - --- - %{message} - - --- - Prosím navšivte tento odkaz, chcete-li odpovědět: %{base_url}%{url} user_quoted: subject_template: "[%{site_name}] %{username} vás citoval v '%{topic_title}'" - text_body_template: | - %{username} vás citoval v '%{topic_title}' na %{site_name}: - - --- - %{message} - - --- - Prosím navšivte tento odkaz, chcete-li odpovědět: %{base_url}%{url} user_mentioned: subject_template: "[%{site_name}] %{username} vás citoval v '%{topic_title}'" - text_body_template: | - %{username} vás citoval v '%{topic_title}' na %{site_name}: - - --- - %{message} - - --- - Prosím navšivte tento odkaz, chcete-li odpovědět: %{base_url}%{url} user_posted: subject_template: "[%{site_name}] %{username} vás citoval v '%{topic_title}'" - text_body_template: | - %{username} vás citoval v '%{topic_title}' na %{site_name}: - - --- - %{message} - - --- - Prosím navšivte tento odkaz, chcete-li odpovědět: %{base_url}%{url} user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{username} vás citoval v '%{topic_title}' na %{site_name}: - - --- - %{message} - - --- - Prosím navšivte tento odkaz, chcete-li odpovědět: %{base_url}%{url} digest: new_activity: "Nová aktivita ve vašich tématech a příspěvcích:" + top_topics: "Populární příspěvky" + other_new_topics: "Populární témata" click_here: "klikněte zde" from: "souhrn z %{site_name}" read_more: "Číst dále" + more_topics_category: "Více nových témat:" forgot_password: subject_template: "[%{site_name}] Obnovení hesla" text_body_template: | @@ -839,12 +775,8 @@ cs: Click the following link to choose a password: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Potvrďte vaši novou emailovou adresu" - text_body_template: | - Potvrďte vaši novou emailovou adresu pro %{site_name} kliknutím na následující odkaz: - - %{base_url}/users/authorize-email/%{email_token} + admin_login: + subject_template: "[%{site_name}] Přihlášení" signup_after_approval: subject_template: "Byli jste schváleni na %{site_name}!" signup: @@ -856,7 +788,6 @@ cs: Pokud tento odkaz nefunguje, zkuste ho zkopírovat a vložit přes schránku do adresního řádku vaše webového prohlížeče. page_not_found: - title: "Stránka, kterou žádáte, na tomto diskuzním fóru neexistuje. Možná vám můžeme pomoci ji najít, nebo poradit jiné téma, které se vám může líbit:" popular_topics: "Populární" recent_topics: "Nedávné" see_more: "Více" @@ -901,3 +832,12 @@ cs: title: "Podmínky používání" privacy_topic: title: "Ochrana soukromí" + admin_login: + success: "E-mail odeslán" + error: "Chyba!" + submit_button: "Odeslat e-mail" + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.da.yml b/config/locales/server.da.yml index 042e41c36ff..13389dddef2 100644 --- a/config/locales/server.da.yml +++ b/config/locales/server.da.yml @@ -10,18 +10,24 @@ da: short_date_no_year: "D MMM" short_date: "D MMM, YYYY" long_date: "MMMM D, YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%d-%m--%Y" + short_no_year: "%-d. %B" + date_only: "%-d. %B, %Y" + date: + month_names: [null, Januar, Februar, Marts, April, Maj, Juni, Juli, August, September, Oktober, November, December] + <<: *datetime_formats title: "Discourse" topics: "Emner" posts: "indlæg" loading: "Indlæser" powered_by_html: 'Siden er lavet med Discourse, opleves bedst med JavaScript slået til' log_in: "Log ind" - via: "%{username} via %{site_name}" - is_reserved: "er reservet" purge_reason: "Automatisk slettet som forladt, ikke aktiveret, konto" disable_remote_images_download_reason: "Fjerndownload af billeder deaktiveret grundet utilstrækkelig diskplads" anonymous: "Anonym" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "er begrænset til %{max} tegn; du har brugt %{length}." @@ -37,8 +43,10 @@ da: exclusion: er reserveret greater_than: skal være større end %{count} greater_than_or_equal_to: skal være større eller lig med %{count} + has_already_been_used: "er allerede blevet brugt" inclusion: er ikke inkluderet i listen invalid: er ikke gyldig + is_invalid: "er ugyldig; prøv at være mere beskrivende" less_than: skal være mindre end %{count} less_than_or_equal_to: skal være mindre end eller lig med %{count} not_a_number: er ikke et nummer @@ -60,8 +68,18 @@ da: other_than: "skal være andet end %{count}" template: body: 'Der var problemer med følgende felter:' + header: + one: Een fejl forhindrede denne %{model} for at gemme. + other: '%{count} fejl forhindrede denne %{model} i at gemme.' embed: load_from_remote: "Der opstod en fejl ved indlæsningen af dette indlæg." + site_settings: + min_username_length_exists: "Du kan ikke sætte minimumslængden for brugernavne over det korteste eksisterende brugernavn." + min_username_length_range: "Du kan ikke sætte minimum til mere end maksimum." + max_username_length_exists: "Du kan ikke sætte maksimumlængden for brugernavne under det længste eksisterende brugernavn." + max_username_length_range: "Du kan ikke sætte maksimum til mindre end minimum." + default_categories_already_selected: "Du kan ikke vælge en kategori der er brugt i en anden liste." + s3_upload_bucket_is_required: "Du kan ikke oploade til S3 med mindre du har angivet 's3_upload_bucket'." bulk_invite: file_should_be_csv: "Den uploadede fil skal være i .csv eller .txt format." backup: @@ -88,26 +106,6 @@ da: replies: one: "1 svar" other: "%{count} svar" - too_many_mentions: - zero: "Beklager, du kan ikke nævne andre brugere." - one: "Beklager, du kan kun nævne én anden bruger i et indlæg." - other: "Beklager, du kan kun nævne %{count} andre brugere i et indlæg." - too_many_mentions_newuser: - zero: "Beklager, nye brugere kan ikke nævne andre brugere." - one: "Beklager, nye brugere kan kun nævne én anden bruger i et indlæg." - other: "Beklager, nye brugere kan kun nævne %{count} andre brugere i et indlæg." - too_many_images: - zero: "Beklager, nye brugere kan ikke indsætte billeder i indlæg." - one: "Beklager, nye brugere kan kun indsætte ét billede i et indlæg." - other: "Beklager, nye brugere kan kun indsætte %{count} billeder i et indlæg." - too_many_attachments: - zero: "Beklager, nye brugere kan ikke vedhæfte filer til et indlæg." - one: "Beklager, nye brugere kan kun vedhæfte én fil til et indlæg." - other: "Beklager, nye brugere kan kun vedhæfte %{count} filer til et indlæg." - too_many_links: - zero: "Beklager, nye brugere kan ikke indsætte links i indlæg." - one: "Beklager, nye brugere kan kun indsætte ét link i et indlæg." - other: "Beklager, nye brugere kan kun indsætte %{count} links i et indlæg." spamming_host: "Beklager, du kan ikke indsætte et link til det pågældende domæne." user_is_suspended: "Suspenderede brugere tilllades ikke at oprette indlæg." topic_not_found: "Der er gået noget galt. Måske er emnet blevet lukket eller slettet mens du kiggede på det?" @@ -133,6 +131,8 @@ da: posts: "Seneste indlæg" too_late_to_edit: "Dette indlæg er gammelt og kan ikke længere redigeres eller slettes." excerpt_image: "billede" + queue: + delete_reason: "Slettet via køen til moderation af indlæg." groups: errors: can_not_modify_automatic: "Du kan ikke modificere en automatisk gruppe" @@ -163,6 +163,14 @@ da: - Det er godt med kritik, men husk at kritisere *ideer*, ikke personer. For flere tips, [se vores retningslinier](/guidelines). Denne boks dukker kun op for dine første %{education_posts_text}. + avatar: | + ### Hvad med et billede til din konto? + + Du har oprettet et par emner og svar, men dit avatar er ikke så unik som du er -- det er bare et bogstav. + + Har du overvejet at **[gå til din brugerprofil](%{profile_path})** og uploade et billede, der repræsenterer dig? + + Det er lettere at følge diskussioner og finde interessant mennesker i samtaler, hvor alle har en unik avatar! dominating_topic: | ### Lad andre deltage i samtalen @@ -190,9 +198,6 @@ da: user_profile: bio_raw: "Om mig" errors: - messages: - is_invalid: "er ugyldig; prøv at være lidt mere beskrivende" - has_already_been_used: "er allerede blevet brugt" models: topic: attributes: @@ -213,11 +218,13 @@ da: attributes: hex: invalid: "er ikke en gyldig fave" + <<: *errors user_profile: no_info_me: "
    “Om mig” feltet på din profil er pt. tomt, ønsker du at udfylde det?
    " no_info_other: "
    %{name} har ikke skrevet noget i “Om mig”-feltet endnu
    " vip_category_name: "Lounge" vip_category_description: "En ekslusiv kategori der kun er tilgængelig for medlemmer med tillidsniveu 3 eller højere." + meta_category_name: "Site Feedback" meta_category_description: "Diskussion om dette site, hvordan det er indrettet, hvordan det virker og hvordan vi kan forbedre det." staff_category_name: "Staff" staff_category_description: "Privat gruppe for staff diskussioner. Emner er kun synlige for administratorer og moderatorer." @@ -225,8 +232,6 @@ da: title: "Velkommen i loungen" category: topic_prefix: "Kategoridefinition for %{category}" - replace_paragraph: "[Erstat det første afsnit med en kort beskrivelse af din nye kategori. Denne tekst vises i området til valg af kategori, så prøv at holde den på under 200 tegn. Indtil du redigerer denne tekst eller opretter emner vil denne kategori ikke optræde på kategorisiden.]" - post_template: "%{replace_paragraph}\n\nBrug de følgende afsnit til en længere beskrivelse samt til at fastlægge retningslinjer eller regler for kategorien.\n\nNogle ting som du kan overveje i svarene nedenfor:\n\n- Hvad er kategorien beregnet til? Hvorfor skal folk vælge denne kategori til deres emne?\n\n- Hvordan er den anderledes end de andre kategorier vi allerede har?\n\n- Har vi behov for denne kategori?\n\n- Skal vi kombinere denne kategori med en anden kategori eller dele den op i flere kategorier?\n" errors: uncategorized_parent: "Ukategoriserede kan ikke have en overordnede kategori" self_parent: "En underkategori kan ikke være sin egen overordnede kategori." @@ -234,21 +239,21 @@ da: cannot_delete: uncategorized: "Kan ikke slette Ukategoriseret" has_subcategories: "Kan ikke slette denne kategori, fordi den har under kategorier." + topic_exists: + one: "Kan ikke slette denne kategori, da den indeholder et emne. Ældste emne er %{topic_link}" + other: "Kan ikke slette denne kategori, da den indeholder %{count} emner. Ældste emne er %{topic_link}" topic_exists_no_oldest: "Kan ikke slette denne kategori fordi antallet af emner er %{count}" trust_levels: newuser: title: "ny bruger" basic: title: "basis-bruger" - regular: - title: "medlem" - leader: - title: "stamgæst" - elder: - title: "leder" rate_limiter: - slow_down: "Du har forsøgt denne handling for ofte, prøv igen senere" + slow_down: "Du har udført denne handling for mange gange, prøv igen senere" too_many_requests: "Vi har en daglig grænse for hvor mange gange den pågældende handling kan udføres. Vent venligst %{time_left} før du prøver igen." + by_type: + create_topic: "Du opretter emner for hurtigt. Vent venligst %{time_left} før du prøver igen." + create_post: "Du svarer for hurtigt. Vent venligst %{time_left} før du prøver igen." hours: one: "1 time" other: "%{count} timer" @@ -330,6 +335,7 @@ da: one: "næsten 1 år siden" other: "næsten %{count} år siden" password_reset: + no_token: "Beklager, dit kodeords-reset link er udløbet. Vælg 'Log ind' knappen og brug 'Jeg har glemt mit kodeord' for at få et nyt link." choose_new: "Vælg et nyt kodeord" choose: "Vælg et kodeord" update: 'opdatér kodeord' @@ -343,11 +349,13 @@ da: please_continue: "Fortsæt til %{site_name}" error: "Der opstod en fejl under opdateringen af din e-mail-adresse. Måske er adressen allerede i brug?" activation: + action: "Klik her for at aktivere din konto" already_done: "Beklager, dette bekræftelses-link er ikke længere gyldigt. Måske er din konto allerede aktiv?" please_continue: "Din nye konto er bekræftet; du bliver nu ledt til forsiden." continue_button: "Fortsæt til %{site_name}" welcome_to: "Velkommen til %{site_name}!" approval_required: "En moderator skal godkende din nye konto før du kan tilgå forummet. Du får en e-mail, når din konto er godkendt!" + missing_session: "Vi kan ikke se, om din konto blev oprettet, se venligst om du har aktiveret cookies." post_action_types: off_topic: title: 'Uden for emnet' @@ -364,13 +372,11 @@ da: description: 'Dette indlæg har indhold som en rimelig person ville opfatte som stødende, udtryk for misbrug eller som et brud på vores sammenholds retningslinjer.' long_form: 'markerede dette som stødende' notify_user: - description: 'Dette indlæg indeholder noget jeg gerne vil drøfte direkte og privat med vedkommende, Bliver ikke markeret.' + long_form: 'sendt besked til brugeren' email_title: 'Dit indlæg i "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Noget andet" - description: 'Dette indlæg kræver moderatorernes opmærksomhed baseret på en anden grund som ikke er nævnt ovenfor.' - email_title: 'Et indlæg i "%{title}" kræver moderatorernes opmærksomhed' email_body: "%{link}\n\n%{message}" bookmark: title: 'Bogmærk' @@ -394,12 +400,17 @@ da: long_form: 'markeret upassende' notify_moderators: title: "Noget andet" + long_form: 'markerede dette til gennemsyn' email_title: 'Emnet "%{title}" kræver moderator-opmærksomhed' email_body: "%{link}\n\n%{message}" + flagging: + you_must_edit: '

    Dit indlæg er blevet markeret af fællesskabet. Se dine beskeder.

    ' + user_must_edit: '

    Dette indlæg er blevet markert af fællesskabet, og er midlertidigt skjult.

    ' archetypes: regular: title: "Almindeligt emne" banner: + title: "Banneremne" message: make: "Dette emne er nu et banner-emne. Det optræder i toppen af alle sider indtil brugeren fjerner det." remove: "Dette emne er ikke mere et banner-emne. Det optræder ikke længere i toppen af alle sider." @@ -424,6 +435,10 @@ da: title: "Nye brugere" xaxis: "Dag" yaxis: "Antal nye brugere" + profile_views: + title: "Bruger Profil Visninger" + xaxis: "Dag" + yaxis: "Antag sete brugerprofiler" topics: title: "Emner" xaxis: "Dag" @@ -494,18 +509,27 @@ da: page_view_anon_reqs: title: "Anonym" xaxis: "Dag" + yaxis: "Anonyme API-Forespørgsler" page_view_logged_in_reqs: title: "Logget ind" xaxis: "Dag" + yaxis: "Indloggede API-forespørgsler" page_view_crawler_reqs: + title: "Web Crawlers" xaxis: "Dag" + yaxis: "Web Crawler API-forespørgsler" page_view_total_reqs: title: "Total" xaxis: "Dag" + yaxis: "Totale API-forespørgsler" page_view_logged_in_mobile_reqs: + title: "Indloggede API-forespørgsler" xaxis: "Dag" + yaxis: "Mobile indloggede API-forespørgsler" page_view_anon_mobile_reqs: + title: "Anonyme API-forespørgsler" xaxis: "Dag" + yaxis: "Mobile anonyme API-forepørgsler" http_background_reqs: title: "Baggrund" xaxis: "Dag" @@ -527,7 +551,9 @@ da: xaxis: "Dag" yaxis: "Total" mobile_visits: + title: "Brugerbesøg" xaxis: "Dag" + yaxis: "Antal besøg" dashboard: rails_env_warning: "Din server kører i %{env}-tilstand." ruby_version_warning: "Du kører en version af Ruby 2.0.0 som har kendte problemer. Opgradér til patch-level 247 eller senere." @@ -541,34 +567,6 @@ da: s3_config_warning: 'Serveren er konfigureret til at uploade filer til s3, men mindst én af følgende indstillinger er ikke angivet: s3_access_key_id, s3_secret_access_key eller s3_upload_bucket. Gå til indstillinger og opdatér indstillingerne. Se "How to set up image uploads to S3?" for mere information.' image_magick_warning: 'Serveren er konfigureret til at lave thumbnails af store billeder, men ImageMagick er ikke installeret. Installér ImageMagick med din foretrukne package manager eller download den seneste udgave.' consumer_email_warning: "Dit site er konfigureret til at bruge Gmail (eller en anden offentlig e-mail-tjeneste) til at sende e-mail. Gmail har en grænse for, hvor mange mails du kan sende. Overvej at bruge en e-mail-udbyder som mandrill.com for at sikre at din mail bliver leveret." - content_types: - education_new_reply: - title: "Uddannelse af nye brugere: Første svar" - description: "Automatisk hjælp som vises over editoren når nye brugere begynder at skrive deres første to svar." - education_new_topic: - title: "Uddannelse af nye brugere: Første emner" - description: "Automatisk hjælp som vises over editoren når nye brugere begynder at skrive deres første to emner." - usage_tips: - title: "Tips til nye brugere" - description: "Vejledning og vigtig information til nye brugere." - welcome_user: - title: "Velkomst: Ny bruger" - welcome_invite: - title: "Velkomst: Inviteret bruger" - login_required_welcome_message: - title: "Log ind påkrævet: Velkomstbesked" - description: "Velkomstbesked som vises til anonyme brugere når indstillingen 'log ind påkrævet' er aktiveret." - login_required: - title: "Log ind påkrævet: Hjemmeside" - description: "Teksten som vises til anonyme brugere når login er påkrævet på sitet." - head: - title: "HTML head" - description: "HTML som indsættes i -tags" - top: - title: "Toppen af siderne" - description: "HTML som vises i toppen af alle sider (efter headeren, før navgationen eller emnetitlen)" - bottom: - title: "Bunden af siderne" site_settings: default_locale: "Standardsproget for denne Discourse-instans (ISO 639-1 kode)." min_post_length: "Minimumlængde tilladt for indlæg i tegn" @@ -608,11 +606,16 @@ da: github_client_secret: "Client secret til Github-login, oprettes på at https://github.com/settings/applications." active_user_rate_limit_secs: "Hvor ofte vi opdaterer feltet 'last_seen_at', i sekunder." previous_visit_timeout_hours: "Hvor lang tid et besøg varer før vi regner det med i det 'forrige' besøg, i timer." + max_likes_per_day: "Maksimalt antal likes per bruger per dag." clean_orphan_uploads_grace_period_hours: "Grace-periode (i timer) før et forældreløst upload bliver fjernet." purge_deleted_uploads_grace_period_days: "Grace-periode (i dage) før et slettet upload bliver fjernet." + tl2_requires_likes_received: "Hvor mange likes en bruger skal modtage inden forfremmelse til tillidsniveau 2." + tl2_requires_likes_given: "Hvor mange likes en bruger skal give inden forfremmelse til tillidsniveau 2." min_trust_to_create_topic: "Det mindste tillidsniveau der skal til for at oprette et nyt emne." title_fancy_entities: "Omdan almindelige ASCII-tegn i emnetitler til fancy HTML-entities, i stil med SmartyPants http://daringfireball.net/projects/smartypants/" title_prettify: "Undgå hyppige tastefejl i titlen, inklusive overforbrug af store bogstaver, første bogstav med småt, gentagne ! og ?, ekstra . i slutningen, etc." + topic_post_like_heat_low: "Når forholdet likes:indlæg overstiger dette tal, bliver antal indlæg let fremhævet." + topic_post_like_heat_medium: "Når forholdet likes:indlæg overstiger dette tal, bliver antal indlæg moderat fremhævet." faq_url: "Hvis du hoster en FAQ et andet sted kan du indtaste den fulde URL her." tos_url: "Hvis du hoster dine forretningsbetingelser et andet sted kan du indtaste den fulde URL her." privacy_policy_url: "Hvis du hoster din privatlivspolitik et andet sted kan du indtaste den fulde URL her." @@ -624,6 +627,21 @@ da: enable_mobile_theme: "Mobile enheder bruger et mobilvenligt tema, med mulighed for at skifte til det fulde site. Deaktivér dette hvis du ønsker at anvende et brugerdefineret stylesheet som er fuldstændigt responsivt." short_progress_text_threshold: "Når antallet af indlæg overstiger dette tal viser statuslinjen kun det aktuelle indlægsnummer. Hvis du ændrer bredden af statuslinjen kan det være nødvendigt at opdatere denne værdi." default_code_lang: "Standard syntax highlighting som bruges i GitHub kodeblokke (lang-auto, ruby, python etc.)." + default_email_digest_frequency: "Hvor ofte brugerne som standard modtager e-mail-sammendrag. " + default_email_private_messages: "Send som standard en email når nogen sender brugeren en besked." + default_email_direct: "Send som standard en email når nogen citerer/svarer/nævner/inviterer brugeren." + default_email_mailing_list_mode: "Send som standard en email for hvert nyt indlæg." + default_email_always: "Send som standard en email-notifikation selv hvis brugeren er aktiv." + default_other_new_topic_duration_minutes: "Global standardkriterium for hvornår et emne regnes for nyt." + default_other_auto_track_topics_after_msecs: "Globalt standardtidsrum før et emne automatisk spores. " + default_other_external_links_in_new_tab: "Åbn som standard links på et nyt faneblad." + default_other_enable_quoting: "Slå som standard \"svar på den markerede tekst\" til." + default_other_dynamic_favicon: "Vis som standard nyt / opdateret emnetal på browserikon" + default_other_disable_jump_reply: "Spring ikke som standard til det nye indlæg efter brugeren har svaret" + default_other_edit_history_public: "Offentliggør som standard rettelser til indlæg." + default_categories_watching: "Liste over kategorier der som standard overvåges." + default_categories_tracking: "Liste over kategorier der som standard følges." + default_categories_muted: "Liste over kategorier der som standard ignoreres." notification_types: mentioned: "%{display_username} nævnte dig i %{link}" liked: "%{display_username} synes om dit indlæg i %{link}" @@ -642,6 +660,8 @@ da: most_posts: "Flest indlæg" most_recent_poster: "Seneste forfatter" frequent_poster: "Hyppig forfatter" + redirected_to_top_reasons: + new_user: "Velkommen til fællesskabet! Dette er de seneste mest populære emner." topic_statuses: archived_enabled: "Dette emne er nu arkiveret. Det er frosset fast og kan ikke ændres på nogen måde." archived_disabled: "Dette emne er nu ikke længere arkiveret. Det er ikke længere frosset fast, og kan ændres." @@ -676,8 +696,6 @@ da: subject_template: "[%{site_name}] test af e-mail-udsendelse" new_version_mailer_with_notes: subject_template: "[%{site_name}] Opdateringer er tilgængelige" - flags_reminder: - post_number: "indlæg" system_messages: post_hidden: subject_template: "Indlæg skjult på grund af feedback fra brugerne" @@ -705,61 +723,29 @@ da: Der er nye brugere, som afventer godkendelse (eller afvisning) før de kan tilgå dette forum. [Gennemgå dem venligst på administrationssiden](%{base_url}/admin/users/list/pending). + download_remote_images_disabled: + subject_template: "Download af eksterne billeder er slået fra" + text_body_template: "Indstillingen `download_remote_images_to_local` blev slået fra fordi grænsen for bug af diskplads i `download_remote_images_threshold` blev nået." + subject_re: "Re:" user_notifications: previous_discussion: "Forrige svar" unsubscribe: title: "Frameld" description: "Ønsker du ikke at modtage disse e-mails? Intet problem! Klik herunder for at framelde med det samme:" - reply_by_email: "For at svare kan du svare på denne e-mail eller gå til %{base_url}%{url} i din browser." - visit_link_to_respond: "For at svare kan du gå til %{base_url}%{url} i din browser." posted_by: "Oprettet af %{username} den %{post_date}" user_replied: subject_template: "[%{site_name}] %{username} svarede på dit indlæg i emnet '%{topic_title}'" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{username} citerede dig i emnet '%{topic_title}'" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{subject_prefix}%{username} skrev et indlæg i emnet '%{topic_title}'" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "Et kort resume af %{site_link} siden dit sidste besøg %{last_seen_at}" + subject_template: "Sammenfatning af [%{site_name}]" new_activity: "Ny aktivitet på dine emner og indlæg:" top_topics: "Populære emner" other_new_topics: "Populære emner" @@ -767,6 +753,7 @@ da: click_here: "klik her" from: "%{site_name} opsummering" read_more: "Læs mere" + more_topics_category: "Flere nye emner: " forgot_password: subject_template: "[%{site_name}] Nulstil kodeord" text_body_template: | @@ -786,15 +773,12 @@ da: Klik på følgende for at vælge et kodeord.: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Bekræft din nye e-mail-adresse" - text_body_template: | - Bekræft din nye e-mail-adresse på %{site_name} ved at klikke på følgende link: - - %{base_url}/users/authorize-email/%{email_token} + account_created: + subject_template: "[%{site_name}] Din nye konto" signup_after_approval: subject_template: "Du er blevet godkendt på %{site_name}!" signup: + subject_template: "[%{site_name}] Bekræft din nye konto" text_body_template: | Velkommen til %{site_name}! @@ -803,23 +787,38 @@ da: Hvis linket ikke virker, så prøv at kopiere hele linket ind i adressefeltet på din web browser. page_not_found: - title: "Den side du efterspurgte findes ikke. Måske kan vi hjælpe dig med at finde den, eller et andet lignende emne:" popular_topics: "Populære" recent_topics: "Nye" see_more: "Flere" search_title: "Søg på denne side" search_google: "Google" + terms_of_service: + title: "Vilkår" + signup_form_message: 'Jeg har læst og accepterer vilkårene.' deleted: 'slettet' upload: unauthorized: "Beklager, filen, som du forsøger at uploade er ikke autoriseret (autoriserede filendelser: %{authorized_extensions})." pasted_image_filename: "Indsat billede" + file_missing: "Du skal angive en fil til overførsel." + attachments: + too_large: "Beklager, men den fil du prøver at overføre er for stor (maksimumstørelsen er %{max_size_kb}KB)" images: + too_large: "Beklager, men billedet som du forsøger at uploade er for stort (den maksimale størrelse er %{max_size_kb}KB). Gør det venligst mindre og prøv igen." size_not_found: "Beklager, men vi kunne ikke fastslå billedets størrelse. Måske er dit billede ødelagt?" flag_reason: sockpuppet: "En ny bruger oprettede et emne, og en anden ny bruger med den samme IP-adresse svarede på det. Se indstillingen af flag_sockpuppets." email_log: anonymous_user: "Brugeren er anonym" seen_recently: "Bruger har været logget på for nyligt" + post_not_found: "Kan ikke finde et indlæg med id %{post_id}" + notification_already_read: "Den notifikation som denne email handler om er allerede læst" + post_deleted: "indlægget er blevet slettet af forfatteren" + user_suspended: "brugeren blev suspenderet" + already_read: "brugeren har allerede læst dette indlæg" + message_blank: "beskeden er tom" + message_to_blank: "message.to er tom" + text_part_body_blank: "text_part.body er tom" + body_blank: "brødtekst er tom" about: "Om" guidelines: "Retningslinjer" privacy: "Privatliv" @@ -827,10 +826,60 @@ da: csv_export: boolean_yes: "Ja" boolean_no: "Nej" + static_topic_first_reply: | + Rediger det første indlæg i dette emne for at ændre indholdet af siden %{page_name} guidelines_topic: title: "FAQ/Retningslinjer" + tos_topic: + title: "Vilkår" + badges: + editor: + name: Redaktør + description: Rettet første indlæg + basic_user: + name: Basis + member: + name: Medlem + regular: + name: Regulær + leader: + name: Leder + welcome: + name: Velkommen + description: Modtog et like + autobiographer: + name: Selvbiograf + anniversary: + name: Jubilæum + nice_post: + name: Fint svar + description: Modtog 10 likes på et svar + good_post: + name: Godt svar + great_post: + name: Rigtigt godt svar + nice_topic: + name: Fint emne + good_topic: + name: Godt emne + admired: + name: Beundret + crazy_in_love: + name: Vildt forelsket + thank_you: + name: Tak + gives_back: + name: Giver tilbage + empathetic: + name: Empatisk + description: Har 500 likede indlæg og givet 1000 likes admin_login: success: "Email sendt" error: "Fejl!" email_input: "Admin email" submit_button: "Send email" + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml index bbd860d3490..f27f9348958 100644 --- a/config/locales/server.de.yml +++ b/config/locales/server.de.yml @@ -10,18 +10,41 @@ de: short_date_no_year: "DD. MMM" short_date: "DD. MMM YYYY" long_date: "DD. MMMM YYYY, H:mm" + datetime_formats: &datetime_formats + formats: + short: "%d.%m.%Y" + short_no_year: "%-d. %B" + date_only: "%-d. %B %Y" + date: + month_names: [null, Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember] + <<: *datetime_formats title: "Discourse" topics: "Themen" posts: "Beiträge" loading: "Wird geladen" powered_by_html: 'Basiert auf Discourse, funktioniert am besten mit aktiviertem JavaScript' log_in: "Anmelden" - via: "%{username} via %{site_name}" - is_reserved: "ist reserviert" purge_reason: "Stillgelegtes, nicht aktives Konto wurde automatisch gelöscht." disable_remote_images_download_reason: "Der Download von Bildern wurde deaktiviert, weil nicht mehr genug Plattenplatz vorhanden war." anonymous: "Anonym" - errors: + emails: + incoming: + default_subject: "Eingehende E-Mail von %{email}" + show_trimmed_content: "Zeige gekürzten Inhalt" + errors: + empty_email_error: "Passiert wenn die empfangene E-Mail leer war." + no_message_id_error: "Passiert wenn in der E-Mail die Kopfzeile 'Message-Id' fehlt." + auto_generated_email_error: "Passiert wenn die Kopfzeile 'precedence' folgendes enthält: list, junk, bulk oder auto_reply, oder eine der anderen Kopfzeilen enthält: auto-submitted, auto-replied oder auto-generated." + no_body_detected_error: "Passiert wenn kein Inhalt extrahiert werden konnte und keine Anhänge vorhanden waren." + inactive_user_error: "Passiert wenn der Sender nicht aktiv ist." + blocked_user_error: "Passiert wenn der Sender geblockt wurde." + bad_destination_address: "Passiert wenn keine der E-Mail Adressen in den Feldern To/Cc/Bcc zu einer konfigurierten eingehenden E-Mail Adresse passt." + strangers_not_allowed_error: "Passiert wenn ein Nutzer versuchte ein neues Thema in einer Kategorie ohne Mitgliedschaft zu erstellen." + insufficient_trust_level_error: "Passiert wenn ein Nutzer versuchte ein neues Thema in einer Kategorie zu erstellen, ohne die erforderliche Vertrauensstufe dafür zu haben." + reply_user_not_matching_error: "Passiert wenn die Adresse der Antwort E-Mail von der Adresse abweicht, an die gesendet wurde." + topic_not_found_error: "Passiert wenn eine Antwort eintraf aber das verbundene Thema gelöscht wurde." + topic_closed_error: "Passiert wenn eine Antwort eintraf aber das verbundene Thema geschlossen wurde." + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "darf höchstens %{max} Zeichen lang sein; du hast %{length} eingegeben." @@ -37,8 +60,10 @@ de: exclusion: ist reserviert greater_than: muss größer als %{count} sein greater_than_or_equal_to: muss größer oder gleich %{count} sein + has_already_been_used: "wird bereits verwendet" inclusion: ist nicht in der Liste enthalten invalid: ist ungültig + is_invalid: "ist ungültig; bitte sei ein wenig deutlicher" less_than: muss weniger als %{count} sein less_than_or_equal_to: muss weniger oder gleich %{count} sein not_a_number: ist keine Zahl @@ -69,6 +94,9 @@ de: min_username_length_exists: "Die minimale Länge für den Benutzernamen kann nicht höher sein als der kürzeste Benutzername." min_username_length_range: "Du kannst das Minimum nicht höher setzen als das Maximum." max_username_length_exists: "Die maximale Länge für den Benutzernamen kann nicht kürzer sein als der längste Benutzername." + max_username_length_range: "Das Maximum darf nicht kleiner als das Minimum sein." + default_categories_already_selected: "Du kannst keine Kategorie auswählen, welche bereits in einer anderen Liste benutzt wird. " + s3_upload_bucket_is_required: "Uploads auf Amazon S3 können nicht aktiviert werden, bevor der 's3_upload_bucket' eingetragen wurde." bulk_invite: file_should_be_csv: "Die hochgeladene Datei sollte im CSV oder TXT Format vorliegen." backup: @@ -79,6 +107,8 @@ de: not_found: "Die angeforderte URL oder Ressource konnte nicht gefunden werden." invalid_access: "Du hast nicht die Erlaubnis, die angeforderte Ressource zu betrachten." read_only_mode_enabled: "Die Seite befindet sich im Nur-Lesen Modus. Änderungen sind deaktiviert." + reading_time: "Lesezeit" + likes: "Likes" too_many_replies: one: "Entschuldigung, aber neue Benutzer sind vorübergehend auf eine Antwort pro Thema beschränkt." other: "Entschuldigung, aber neue Benutzer sind vorübergehend auf %{count} Antworten pro Thema beschränkt." @@ -95,33 +125,33 @@ de: replies: one: "1 Antwort" other: "%{count} Antworten" + no_mentions_allowed: "Entschuldigung, du kannst keine Benutzer erwähnen." too_many_mentions: - zero: "Entschuldigung, du kannst keine anderen Nutzer erwähnen." - one: "Entschuldigung, du kannst nur einen anderen Nutzer in Deinem Beitrag erwähnen." - other: "Entschuldigung, du kannst nur %{count} Nutzer in einem Beitrag erwähnen." + one: "Entschuldigung, du kannst nur einen anderen Benutzer in einem Beitrag erwähnen." + other: "Entschuldigung, du kannst nur %{count} Benutzer in einem Beitrag erwähnen." + no_mentions_allowed_newuser: "Entschuldigung, neue Benutzer können andere Nutzer nicht erwähnen." too_many_mentions_newuser: - zero: "Entschuldigung, neue Benutzer können andere Nutzer nicht erwähnen." - one: "Entschuldige, neue Benutzer können nur einen anderen Nutzer in einem Beitrag erwähnen." - other: "Entschuldige, neue Benutzer können nur %{count} Nutzer in einem Beitrag erwähnen." + one: "Entschuldige, neue Benutzer können nur einen anderen Benutzer in einem Beitrag erwähnen." + other: "Entschuldige, neue Benutzer können nur %{count} Benutzer in einem Beitrag erwähnen." + no_images_allowed: "Entschuldige, neue Benutzer können Beiträgen keine Bilder hinzufügen." too_many_images: - zero: "Entschuldige, neue Benutzer können Beiträgen keine Bilder hinzufügen." one: "Entschuldige, neue Benutzer können Beiträgen höchstens ein Bild hinzufügen." other: "Entschuldige, neue Benutzer können Beiträgen höchstens %{count} Bilder hinzufügen." + no_attachments_allowed: "Entschuldige, neue Benutzer können Beiträgen keine Dateien hinzufügen." too_many_attachments: - zero: "Entschuldige, neue Benutzer können Beiträgen keine Dateien hinzufügen." one: "Entschuldige, neue Benutzer können Beiträgen höchstens eine Datei hinzufügen." other: "Entschuldige, neue Benutzer können Beiträgen höchstens %{count} Dateien hinzufügen." + no_links_allowed: "Entschuldige, neue Benutzer können Beiträgen keine Links hinzufügen." too_many_links: - zero: "Entschuldige, neue Benutzer können Beiträgen keine Links hinzufügen." one: "Entschuldige, neue Benutzer können Beiträgen höchstens einen Link hinzufügen." other: "Entschuldige, neue Benutzer können Beiträgen höchstens %{count} Links hinzufügen." spamming_host: "Entschuldigung, du kannst keine Links zu diesem Webserver posten." user_is_suspended: "Gesperrte Benutzer dürfen keine Beiträge schreiben." topic_not_found: "Etwas ist schief gelaufen. Wurde das Thema eventuell geschlossen oder gelöscht, während du es angeschaut hast?" just_posted_that: "ist einer einer vor Kurzem von dir geschriebenen Nachricht zu ähnlich" - has_already_been_used: "wird bereits verwendet" + has_already_been_used: "wurde bereits verwendet" invalid_characters: "enthält ungültige Zeichen" - is_invalid: "ist ungültig; bitte ein wenig anschaulicher" + is_invalid: "ist ungültig; bitte sei ein wenig deutlicher" next_page: "nächste Seite →" prev_page: "← vorherige Seite" page_num: "Seite %{num}" @@ -137,8 +167,13 @@ de: rss_description: latest: "Aktuelle Themen" hot: "Beliebte Themen" + top: "Die besten Themen" posts: "Letzte Beiträge" + private_posts: "Neueste private Nachricht" + group_posts: "Letzte Beiträge von %(Gruppen_name)" + group_mentions: "Neueste Nennungen von %{group_name}" too_late_to_edit: "Dieser Beitrag wurde vor zu langer Zeit erstellt. Er kann nicht mehr bearbeitet oder gelöscht werden." + revert_version_same: "Die aktuelle Version entspricht der Version, zu der du zurückkehren möchtest." excerpt_image: "Bild" queue: delete_reason: "Aus der Moderations-Warteschlange für Beiträge gelöscht" @@ -146,6 +181,10 @@ de: errors: can_not_modify_automatic: "Du kannst eine automatisch verwaltete Gruppe nicht verändern." member_already_exist: "'%{username}' ist bereits Mitglied dieser Gruppe." + invalid_domain: "'%{domain}' ist keine gültige Domain." + invalid_incoming_email: "'%{email}' ist keine gültige E-Mail Adresse." + email_already_used_in_group: "'%{email}' wird bereits von der Gruppe '%{group_name}' verwendet." + email_already_used_in_category: "'%{email}' wird bereits von der Kategorie '%{category_name}' verwendet." default_names: everyone: "jeder" admins: "admins" @@ -169,7 +208,7 @@ de: - Verwende gebräuchliche, gut definierte Wörter, damit dein Thema *gefunden* werden kann. Wähle eine Kategorie, um es mit ähnlichen Themen zu gruppieren. - Für mehr Tips, [siehe unsere Community-Richtlinien](/guidelines). Dieses Panel wird nur bei deinen ersten %{education_posts_text} angezeigt. + Mehr Tipps findest du in [unseren Community-Richtlinien](/guidelines). Dieses Panel wird nur bei deinen ersten %{education_posts_text} angezeigt. new-reply: | Willkommen bei %{site_name} — **Danke für deinen Beitrag zum Thema!** @@ -180,6 +219,14 @@ de: - Kritik ist in Ordnung, aber bitte kritisiere nur *Ideen*, nicht Menschen. Beachte bitte auch [unsere Richtlinien](/guidelines). Dieser Hilfetext wird nur bei deinen ersten %{education_posts_text} Beiträgen angezeigt. + avatar: | + ### Wie wäre es mit einem Bild für Deinen Account? + + Du hast schon einige Themen und Antworten geschrieben, aber Dein Profilbild ist nicht so einzigartig, wie Du es bist -- es ist nur ein Buchstabe. + + Vielleicht schaust Du mal in **[Dein Benutzerprofil](%{profile_path})** und lädst dort ein Bild hoch, das etwas über Dich aussagt? + + Es ist einfacher, Diskussionen zu folgen und interessante Leute zu finden, wenn jeder ein eindeutiges Profilbild hat! sequential_replies: | ### Bitte antworte mehreren Beiträge gleichzeitig @@ -215,9 +262,6 @@ de: user_profile: bio_raw: "Über mich" errors: - messages: - is_invalid: "ist ungültig; versuche ein wenig mehr zu erklären" - has_already_been_used: "wird bereits verwendet" models: topic: attributes: @@ -238,6 +282,7 @@ de: attributes: hex: invalid: "ist keine gültige Farbe" + <<: *errors user_profile: no_info_me: "
    Das 'Über mich'-Feld deines Profils ist aktuell leer, möchtest du es ausfüllen?
    " no_info_other: "
    %{name} hat noch nichts in das 'Über mich'-Feld des Nutzerprofils eingetragen
    " @@ -253,13 +298,15 @@ de: body: "\nGratuliere! :confetti_ball:\n\nWenn du dieses Thema sehen kannst, wurdest du vor Kurzem zum **Stammgast** (Vertrauensstufe 3) befördert.\n \nDu kannst nun …\n\n* den Titel eines jeden Themas ändern\n* Themen in andere Kategorien verschieben\n* Links veröffentlichen, die von Suchmaschinen weiterverfolgt werden (das automatische [nofollow](http://de.wikipedia.org/wiki/Nofollow) wird entfernt)\n* auf die private Lounge-Kategorie zugreifen, die für Benutzer mit Vertrauensstufe 3 oder höher sichtbar ist\n\nHier ist die [aktuelle Liste aller Stammgäste](/badges/3/regular). Vergiss nicht, hallo zu sagen!\n\nVielen Dank dafür, dass du ein wichtiger Teil dieser Community bist!\n\n(Wenn du mehr über Vertrauensstufen wissen möchtest, kannst du [dieses Thema lesen][trust]. Beachte bitte, dass nur jene Mitglieder Stammgäste bleiben, die auch im Laufe der Zeit die Anforderungen erfüllen.)\n\n[trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924\n" category: topic_prefix: "Über die Kategorie %{category}" - replace_paragraph: "[Ersetze den ersten Absatz mit einer kurzen Beschreibung deiner neuen Kategorie. Bitte benutze weniger als 200 Zeichen.]" - post_template: "%{replace_paragraph}\n\nBenutze den folgenden Platz für eine ausführliche Beschreibung sowie für Regeln und zur Diskussion!" + replace_paragraph: "(Ersetze diesen ersten Absatz mit einer kurzen Beschreibung deiner neuen Kategorie. Diese Richtlinie wird in der Kategorienauswahl angezeigt, versuche also weniger als 200 Zeichen zu benutzen. **Bis du diese Beschreibung geändert oder Themen angelegt hast, wird diese Kategorie nicht auf der Kategorie-Seite angezeigt.**)" + post_template: "%{replace_paragraph}\n\nBenutze die folgenden Abschnitte für eine ausführlichere Beschreibung oder um Richtlinien oder Regeln für diese Kategorie festzulegen:\n\n- Warum sollten Benutzer diese Kategorie nutzen? Wofür ist sie gedacht?\n\n- Wie genau unterscheidet sie sich von den Kategorien, die es bereits gibt?\n\n- Welche Themen sollte diese Kategorie im Allgemeinen beinhalten?\n\n- Brauchen wir diese Kategorie? Können wie sie mit einer anderen Kategorie oder Unter-Kategorie zusammenführen?\n" errors: uncategorized_parent: "Die \"unkategorisiert\" Kategorie kann keine Elternkategorie haben." self_parent: "Eine Kategorie kann nicht sich selbst untergeordnet werden." depth: "Unterkategorien können nicht ineinander verschachtelt werden." - email_in_already_exist: "Die E-Mail-Adresse '%{email_in}' für eingehende Themen wird bereits von der Kategorie '%{category_name}' verwendet." + invalid_email_in: "'%{email}' ist keine gültige E-Mail Adresse." + email_already_used_in_group: "'%{email}' wird bereits von der Gruppe '%{group_name}' verwendet." + email_already_used_in_category: "'%{email}' wird bereits von der Kategorie '%{category_name}' verwendet." cannot_delete: uncategorized: "Die \"unkategorisiert\" Kategorie kann nicht gelöscht werden." has_subcategories: "Diese Kategorie kann nicht gelöscht werden, weil sie Unterkategorien besitzt." @@ -267,21 +314,36 @@ de: one: "Diese Kategorie kann nicht gelöscht werden, weil sie ein Thema enthält. Das Thema ist %{topic_link}." other: "Diese Kategorie kann nicht gelöscht werden, weil sie %{count} Themen enthält. Das älteste Thema ist %{topic_link}." topic_exists_no_oldest: "Diese Kategorie kann nicht gelöscht werden, weil sie #{category.topic_count} Themen enthält." + uncategorized_description: "Themen welche keine Kategorie benötigen oder in keine existierende Kategorie passen." trust_levels: newuser: title: "Neuer Benutzer" basic: title: "Anwärter" - regular: + member: title: "Mitglied" - leader: + regular: title: "Stammgast" - elder: + leader: title: "Anführer" change_failed_explanation: "Du wolltest %{user_name} auf '%{new_trust_level}' zurückstufen. Die Vertrauensstufe ist jedoch bereits '%{current_trust_level}'. %{user_name} verbleibt auf '%{current_trust_level}'. Wenn du den Benutzer zurückstufen möchtest, musst du zuerst seine Vertrauensstufe sperren." rate_limiter: - slow_down: "Du hast diese Aktion zu oft durchgeführt. Versuch es später wieder. " + slow_down: "Du hast diese Aktion zu oft durchgeführt. Versuche es später wieder." too_many_requests: "Diese Aktion kann nur ein begrenztes Mal pro Tag durchgeführt werden. Bitte warte %{time_left} bis zum nächsten Versuch." + by_type: + first_day_replies_per_day: "Du hast die maximale Anzahl an Antworten erreicht, die ein neuer Benutzer am ersten Tag erstellen kann. Bitte warte %{time_left}, bis Du es wieder versuchst." + first_day_topics_per_day: "Du hast die maximale Anzahl an Themen erreicht, die ein neuer Benutzer am ersten Tag erstellen kann. Bitte warte %{time_left}, bis Du es wieder versuchst." + create_topic: "Du erstellst zu schnell zu viele Themen hintereinander. Bitte warte %{time_left}, bis Du es wieder versuchst." + create_post: "Du antwortest zu schnell. Bitte warte %{time_left}, bis Du es wieder versuchst." + delete_post: "Du löschst zu schnell Beiträge. Bitte warte %{time_left}, bis Du es wieder versuchst." + topics_per_day: "Du hast die maximale Anzahl an neuen Themen für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." + pms_per_day: "Du hast die maximale Anzahl an Nachrichten für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." + create_like: "Du hast die maximale Anzahl „Gefällt mir“ für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." + create_bookmark: "Du hast die maximale Anzahl an Lesezeichen für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." + edit_post: "Du hast die maximale Anzahl an Änderungen für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." + live_post_counts: "Du forderst die Live-Anzahl der Antworten zu schnell an. Bitte warte %{time_left}, bis Du es wieder versuchst." + unsubscribe_via_email: "Du hast die maximale Anzahl an Abbestell-E-Mails für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." + topic_invitations_per_day: "Du hast die maximale Zahl an neuen Thema-Einladungen für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." hours: one: "1 Stunde" other: "%{count} Stunden" @@ -363,19 +425,26 @@ de: one: "vor fast einem Jahr" other: "vor fast %{count} Jahren" password_reset: + no_token: "Entschuldige, aber der Link zum Zurücksetzen des Passworts ist zu alt. Wähle 'Ich habe mein Passwort vergessen' um einen neuen Link zu erhalten." choose_new: "Bitte wähle ein neues Passwort" choose: "Bitte wähle ein Passwort" update: 'Passwort aktualisieren' save: 'Passwort festlegen' title: 'Passwort zurücksetzen' - success: "Dein Passwort wurde erfolgreich geändert, du bist nun angemeldet." - success_unapproved: "Dein Passwort wurde erfolgreich verändert." + success: "Dein Passwort wurde erfolgreich geändert, und du bist nun angemeldet." + success_unapproved: "Dein Passwort wurde erfolgreich geändert." continue: "Weiter zu %{site_name}" change_email: confirmed: "Deine E-Mail-Adresse wurde aktualisiert." please_continue: "Weiter zu %{site_name}" - error: "Es gab einen Fehler beim Ändern deiner Mailadresse. Wird diese Adresse bereits genutzt?" + error: "Es gab einen Fehler beim Ändern deiner E-Mail-Adresse. Wird diese Adresse bereits genutzt?" + error_staged: "Es gab einen Fehler beim Ändern deiner E-Mail-Adresse. Die Adresse wird bereits von einem vorbereiteten Benutzer verwendet." + already_done: "Entschuldige, dieser Bestätigungs-Link ist nicht mehr gültig. Ist die E-Mail-Adresse bereits geändert?" + authorizing_old: + title: "Vielen Dank für die Bestätigung deiner aktuellen E-Mail-Adresse" + description: "Wir senden dir jetzt eine Bestätigungs-E-Mail an deine neue Adresse." activation: + action: "Klicke hier, um deinen Account zu aktivieren" already_done: "Entschuldige, dieser Link zur Aktivierung des Benutzerkontos ist nicht mehr gültig. Ist dein Konto schon aktiviert?" please_continue: "Dein neues Konto ist jetzt bestätigt; du wirst auf die Startseite weitergeleitet." continue_button: "Weiter zu %{site_name}" @@ -398,16 +467,16 @@ de: description: 'Dieser Beitrag enthält Inhalte, die eine vernünftige Person als anstößig, beleidigend oder unsere Richtlinien verletzend auffassen würde.' long_form: 'dies als unangemessen gemeldet' notify_user: - title: 'Nachricht an {{username}}' - description: 'Dieser Beitrag enthält etwas, worüber ich mit dem Autor direkt und persönlich reden möchte. Wird nicht gemeldet.' + title: 'Schreibe @{{username}} eine Nachricht' + description: 'Ich möchte mit dieser Person direkt und persönlich über ihren Beitrag reden.' long_form: 'angeschriebener Benutzer' email_title: 'Dein Beitrag in „%{title}“' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Irgendetwas anderes" - description: 'Auf diesen Beitrag sollte aus einem anderen Grund ein Moderator aufmerksam gemacht werden.' + description: 'Auf diesen Beitrag sollte aus einem oben nicht aufgeführten Grund ein Moderator aufmerksam gemacht werden.' long_form: 'hat dies den Moderatoren gemeldet' - email_title: 'Der Beitrag "%{title}" sollte von einem Moderator begutachtet werden' + email_title: 'Ein Beitrag in "%{title}" sollte von einem Moderator begutachtet werden' email_body: "%{link}\n\n%{message}" bookmark: title: 'Lesezeichen' @@ -416,7 +485,7 @@ de: like: title: 'Gefällt mir' description: 'Dieser Beitrag gefällt mir' - long_form: 'dies gefällt mit' + long_form: 'hat dies gefallen' vote: title: 'Abstimmung' description: 'Stimme für diesen Beitrag' @@ -432,7 +501,7 @@ de: long_form: 'als unangemessen gemeldet' notify_moderators: title: "Irgendetwas anderes" - description: 'Dieses Thema muss von einem Moderator begutachtet werden, da es entweder nicht mit den Richtlinien oder den Nutzungsbedingungen in Einklang zu bringen ist, oder aus sonstigen oben nicht genannten Gründen.' + description: 'Dieser Beitrag muss von einem Mitarbeiter begutachtet werden, da er entweder nicht mit den Richtlinien oder den Nutzungsbedingungen in Einklang zu bringen ist, oder aus sonstigen oben nicht genannten Gründen.' long_form: ' hast dies den Moderatoren gemeldet' email_title: 'Das Thema "%{title}" benötigt die Aufmerksamkeit eines Moderators' email_body: "%{link}\n\n%{message}" @@ -449,12 +518,12 @@ de: remove: "Dieses Thema ist jetzt kein Banner mehr. Es wird nicht mehr auf jeder Seite ganz oben angezeigt." unsubscribed: title: 'Abo abbestellt' - description: "Dein Abo wurde abbestellt. Wir werden Dich nicht wieder kontaktieren!" + description: "Dein Abo wurde abbestellt. Wir werden dich nicht wieder kontaktieren!" oops: "Bitte klicke unten, falls du das nicht tun wolltest." error: "Beim Löschen des Abonnements trat ein Fehler auf." preferences_link: "Du kannst den Empfang von Zusammenfassungen per E-Mail auch in deinen Profil-Einstellungen deaktivieren." different_user_description: "Die Zusammenfassung wurde einem anderen als dem momentan angemeldeten Benutzer geschickt. Bitte melde dich ab und versuche es erneut." - not_found_description: "Entschuldige, wir konnten dein Abo nicht abbestellen. Möglicherweise ist der Link aus deiner Mail veraltet." + not_found_description: "Entschuldige, wir konnten dein Abo nicht abbestellen. Möglicherweise ist der Link aus deiner E-Mail veraltet." resubscribe: action: "Abo wieder aufnehmen" title: "Abo wieder aufgenommen!" @@ -468,9 +537,13 @@ de: title: "Neue Benutzer" xaxis: "Tag" yaxis: "Anzahl neuer Nutzer" + profile_views: + title: "Profilaufrufe" + xaxis: "Tag" + yaxis: "Anzahl der angezeigten Benutzerprofile" topics: title: "Themen" - xaxis: "Day" + xaxis: "Tag" yaxis: "Anzahl neuer Themen" posts: title: "Beiträge" @@ -558,6 +631,7 @@ de: page_view_anon_mobile_reqs: title: "Anonyme API-Anfrangen" xaxis: "Tag" + yaxis: "Mobile anonyme API Anfragen" http_background_reqs: title: "Hintergrund" xaxis: "Tag" @@ -599,7 +673,8 @@ de: ruby_version_warning: "Du verwendest eine Version von Ruby 2.0.0, die für Probleme bekannt ist. Aktualisiere auf Patchlevel 247 oder höher." host_names_warning: "Deine config/database.yml-Datei verwendet localhost als Hostname. Trage hier den Hostnamen deiner Webseite ein." gc_warning: 'Dein Server verwendet die Standardparameter für Rubys Garbage-Collector, die nicht optimal sind. Lese dieses Thema über Performanzeinstellungen (en): Tuning Ruby and Rails for Discourse.' - sidekiq_warning: 'Sidekiq läuft nicht. Viele Aufgaben, wie zum Beispiel das Versenden von Mails, werden asynchron durch Sidekiq ausgeführt. Stelle sicher, dass mindestens eine Sidekiq-Prozess läuft. Mehr über Sidekiq erfährst du hier (en).' + sidekiq_warning: 'Sidekiq läuft nicht. Viele Aufgaben, wie zum Beispiel das Versenden von E-Mails, werden asynchron durch Sidekiq ausgeführt. Stelle sicher, dass mindestens eine Sidekiq-Prozess läuft. Mehr über Sidekiq erfährst du hier (en).' + queue_size_warning: 'Eine hohe Anzahl an Aufgaben (%{queue_size}) befindet sich in der Warteschlange. Dies könnte auf ein Problem mit Sidekiq hinweisen oder du musst zusätzliche Sidekiq Worker starten.' memory_warning: 'Dein Server läuft mit weniger als 1 GB Hauptspeicher. Mindestens 1 GB Hauptspeicher werden empfohlen.' google_oauth2_config_warning: 'Der Server ist für Anmeldung und Login mit Google OAuth2 (enable_google_oauth2_logins) konfiguriert, aber die Client-ID und das Client-Gemeheimnis sind nicht gesetzt. Trage diese in den Einstellung ein. Eine Anleitung zu diesem Thema findest du hier.' facebook_config_warning: 'Der Server erlaubt die Anmeldung mit Facebook (enable_facebook_logins), aber die App ID und der Geheimcode sind nicht gesetzt. Besuche die Einstellungen um die fehlenden Einträge hinzuzufügen. Besuche den Leitfaden um mehr zu erfahren.' @@ -608,50 +683,25 @@ de: s3_config_warning: 'Der Server wurde konfiguriert um Dateien nach s3 hochzuladen, aber mindestens der folgenden Einstellungen fehlt: s3_access_key_id, s3_secret_access_key oder s3_upload_bucket. Besuche die Einstellungen um die fehlenden Einträge hinzuzufügen. Besuche "How to set up image uploads to S3?" um mehr zu erfahren.' s3_backup_config_warning: 'Der Server ist so konfiguriert, dass Datensicherungen auf S3 geladen werden, aber mindestens einer der folgenden Einstellungen: s3_access_key_id, s3_secret_access_key or s3_backup_bucket ist nicht festgelegt. Gehe Sie zu den Seiteneinstellungen und aktualisieren Sie die Einstellungen. Siehe "Wie konfiguriere ich das Hochladen von Bildern zu S3?" um mehr darüber zu erfahren.' image_magick_warning: 'Der Server wurde konfiguriert um Vorschaubilder von grossen Bildern zu erstellen, aber ImageMagick ist nicht installiertd. Installiere ImageMagick mit deinem bevorzugten Packetmanager oder besuche um das aktuelle Paket herunterzuladen.' + failing_emails_warning: "%{num_failed_jobs} E-Mails konnten nicht versendet werden. Überprüfe deine app.yml und stelle sicher, dass die E-Mail Servereinstellungen korrekt gesetzt sind. \nSieh dir hier die nicht versendeten E-Mails an." default_logo_warning: "Richte das Logo für deine Seite ein. Konfiguriere dafür logo_url, logo_small_url, und favicon_url unter Website-Einstellungen." contact_email_missing: "Gib eine Kontakt-E-Mail-Adresse an, damit du dringende Meldungen bezüglich deiner Seite erhalten kannst. Trage sie in den Einstellungen ein." contact_email_invalid: "Die Kontakt E-Mail-Adresse ist ungültig. Ändere sie in den Einstellungen." title_nag: "Gib einen Namen für deine Website ein. Aktualisiere dazu den „title“ in den Einstellungen." site_description_missing: "Gib eine kurze Beschreibung deiner Website ein, die in Suchergebnissen angezeigt werden soll. Aktualisiere dazu die „site_description“ in den Einstellungen." - consumer_email_warning: "Deine Seite verwendet Gmail (oder einen anderen für Endkunden gedachten Mailserver) um E-Mails zu versenden. Gmail hat eine Schranke bezüglich des Sendens von E-Mails. Um die E-Mail-Zustellung zu gewährleisten, solltest du die Verwendung eines anderen E-Mail-Diensts in Erwägung ziehen." + consumer_email_warning: "Deine Seite verwendet Gmail (oder einen anderen für Endkunden gedachten Mailserver) um E-Mails zu versenden. Gmail hat eine Schranke bezüglich des Sendens von E-Mails. Um die E-Mail-Zustellung zu gewährleisten, solltest du die Verwendung eines anderen E-Mail-Dienstes in Erwägung ziehen." site_contact_username_warning: "Gib den Namen des Benutzerkontos eines freundlichen Mitarbeiters an, der als Absender für wichtige automatische Nachrichten verwendet wird. Aktualisiere site_contact_username in den Website-Einstellungen." notification_email_warning: "Benachrichtigungs-E-Mails werden nicht von einer gültigen, zu deiner Domain gehörenden E-Mail-Adresse versandt; der E-Mail-Versand wird unberechenbar und unzuverlässig sein. Bitte trage in den Einstellungen unter notification_email eine gültige lokale E-Mail-Adresse ein." - content_types: - education_new_reply: - title: "Hilfe: Erste Beiträge" - description: "Die Hilfe wird automatisch überhalb des Editors eingeblendet, wenn neue Benutzer ihre ersten zwei Beiträge veröffentlichen." - education_new_topic: - title: "Hilfe: Erste Themen" - description: "Die Hilfe wird automatisch überhalb des Editors eingeblendet, wenn neue Benutzer ihre ersten zwei Themen veröffentlichen." - usage_tips: - title: "Leitfaden für neue Benutzer" - description: "Leitfaden und wichtige Informationen für neue Benutzer" - welcome_user: - title: "Willkommen: Neuer Benutzer" - description: "Eine Nachricht, welche automatisch an alle Benutzer gesendet wird welche sich anmelden." - welcome_invite: - title: "Willkommen: Eingeladener Benutzer" - description: "Eine Nachricht welche automatisch an alle eingeladenen Benutzer gesendet wird, wenn diese die Einladung eines anderen Benutzers annehmen." - login_required_welcome_message: - title: "Anmeldung erforderlich: Willkommensnachricht" - description: "Willkommensnachricht welche angezeigt wird wenn der Benutzer nicht angemeldet ist und die Einstellung 'login required' aktiviert ist." - login_required: - title: "Anmeldung erforderlich: Hauptseite" - description: "Der Text welcher nicht angemeldeten Benutzer angezeigt wird, wenn eine Anmeldung erforderlich ist." - head: - title: "HTML-Kopf" - description: "HTML, das zwischen den Tags eingefügt wird." - top: - title: "Oberer Teil der Seiten" - description: "HTML, das am Anfang jeder Seite hinzugefügt wird (Nach dem Header, vor der Navigation oder dem Thementitel)." - bottom: - title: "Unterer Teil der Seiten" - description: "HTML das vor dem Tag eingefügt wird." + subfolder_ends_in_slash: "Deine Installation in einem Pfad ist nicht korrekt, DISCOURSE_RELATIVE_URL_ROOT endet mit einem Schrägstrich." + email_polling_errored_recently: + one: "Beim Abrufen von E-Mails ist in den letzten 24 Stunden ein Fehler aufgetreten. Weitere Informationen findest du im Fehlerprotokoll." + other: "Beim Abrufen von E-Mails sind in den letzten 24 Stunden %{count} Fehler aufgetreten. Weitere Informationen findest du im Fehlerprotokoll." site_settings: censored_words: "Wörter, die automatisch durch ■■■■ ersetzt werden" delete_old_hidden_posts: "Automatisch alle Beiträge löschen, die länger als 30 Tage versteckt bleiben." default_locale: "Die Standardsprache dieser Discourse-Instanz (kodiert in ISO 639-1)." allow_user_locale: "Erlaube Benutzern, ihre eigene Interfacesprache zu wählen" + set_locale_from_accept_language_header: "Sprache der Benutzeroberfläche für anonyme Nutzer an Hand der Spracheinstellung ihres Browsers wählen (EXPERIMENTELL, funktioniert nicht mit Caches für anonyme Nutzer)" min_post_length: "Minimal zulässige Beitragslänge in Zeichen." min_first_post_length: "Minimal zulässige Länge des ersten Beitrags (eines Themas) in Zeichen" min_private_message_post_length: "Minimale zulässige Beitragslänge in Zeichen für Nachrichten" @@ -660,8 +710,8 @@ de: max_topic_title_length: "Maximale zulässige Titellänge von Themen in Zeichen." min_private_message_title_length: "Minimale zulässige Titellänge von Nachrichten in Zeichen." min_search_term_length: "Minimale zulässige Länge der Suche in Zeichen." + search_tokenize_chinese_japanese_korean: "Zwinge die Suche, Chinesisch, Japanisch und Koreanisch zu erkennen, auch wenn die Seite keine dieser Sprachen nutzt" allow_uncategorized_topics: "Erlaube Themen ohne Kategorie zu erstellen. ACHTUNG: Falls es unkategorisierte Themen gibt, musst du sie neu kategorisieren, bevor du diese Option abschaltest." - uncategorized_description: "Beschreibung der Kategorie für unkategorisierte Themen. Leer lassen, wenn keine Beschreibung erwünscht ist." allow_duplicate_topic_titles: "Erlaube Themen mit identischen und doppelten Titeln." unique_posts_mins: "Minuten, nach denen ein Nutzer denselben Inhalt noch einmal posten kann." educate_until_posts: "Zeige das Hilfe-Panel im Editor sobald ein Nutzer einen seiner ersten (n) Beiträge zu schreiben beginnt." @@ -674,7 +724,7 @@ de: download_remote_images_to_local: "Lade eine Kopie von extern gehosteten Bildern herunter und ersetze Links in Beiträgen entsprechend; dies verhindert defekte Bilder." download_remote_images_threshold: "Minimal benötigter freier Festplattenspeicher um externe Bilder lokal herunterzuladen (in Prozent)" disabled_image_download_domains: "Liste von Domänen, von denen verlinkte Bilder niemals heruntergeladen werden sollen." - ninja_edit_window: "Für (n) Sekunden wird nach dem Bearbeiten keine neue Revision im Beitragsverlauf angelegt." + editing_grace_period: "Für (n) Sekunden wird nach dem Bearbeiten keine neue Revision im Beitragsverlauf angelegt." post_edit_time_limit: "Der Verfasser eines Beitrags kann diesen nur für (n) Minuten nach Absenden des Beitrags bearbeiten. 0 deaktiviert diese Beschränkung." edit_history_visible_to_public: "Erlaube jedem, vorherige Versionen eines bearbeiteten Beitrags zu sehen. Wenn deaktiviert sind diese nur für Mitarbeiter sichtbar." delete_removed_posts_after: "Beiträge, die deren Verfasser selbst entfernt hat, werden nach (n) Stunden automatisch gelöscht. Die Beiträge werden sofort gelöscht, wenn dieser Wert auf 0 gesetzt wird." @@ -683,13 +733,20 @@ de: category_featured_topics: "Anzahl der angezeigten Themen je Kategorie auf der Kategorieseite /categories. Nachdem dieser Wert geändert wurde, dauert es bis zu 15 Minuten bis die Kategorieseite aktualisiert ist." show_subcategory_list: "Zeige Liste von Unterkategorien statt einer Liste von Themen wenn eine Kategorie ausgewählt wird." fixed_category_positions: "Falls aktiviert können Kategorien in einer fest vorgegebenen Reihenfolge angeordnet werden. Andernfalls werden Kategorien nach Aktivität sortiert aufgelistet." + fixed_category_positions_on_create: "Wenn aktiviert wird die Kategoriezuordnung beim Erstellen eines Themas erhalten (benötigt fixed_category_positions)." add_rel_nofollow_to_user_content: "Füge mit Ausnahme interner Links allen nutzergenerierten Inhalten 'rel nofollow' hinzu (inkludiert übergeordnete Domains). Die Änderung dieser Einstellung erfordert, dass du sämtliche Markdown-Beiträge aktualisierst." + exclude_rel_nofollow_domains: "Eine Liste von Domains auf welchen das Attribut nofollow nicht auf Links gesetzt werden sollte (tld.com erlaubt auch sub.tld.com). Du solltest mindestens die Top-Level Domain dieser Seite hinzufügen, damit die Crawler der Suchmaschinen all deinen Content indexieren können. Wenn weitere Teile deiner Webseite unter anderen Domains zu finden sind, kannst du diese hier ebenfalls hinzufügen." post_excerpt_maxlength: "Maximale Länge eines Beitrags-Auszuges bzw. -Zusammfassung." post_onebox_maxlength: "Maximale Länge eines Onebox-Discourse-Beitrags in Zeichen." onebox_domains_whitelist: "Liste von Domains, deren Inhalte für Oneboxen erlaubt sind; diese Domains sollten OpenGraph oder oEmbed unterstützen. Teste ihre Kompatibilität unter http://iframely.com/debug" + logo_url: "Das Logo oben links auf deiner Seite sollte eine breite, rechteckige Form haben. Wenn du kein Logo auswählst, wird stattdessen der Seitentitel angezeigt." + digest_logo_url: "Alternatives Logo, welches oben in der E-Mail Kurzfassung angezeigt wird (sollte eine breite, rechteckige Form haben). Wenn du kein Logo auswählst, wird stattdessen das `logo_url` verwendet. " + logo_small_url: "Dein Logo in klein für die obere Linke Seite deiner Webseite, in Form eines rechteckigen Quadrates. Es wird angezeigt, wenn der Nutzer scrollt. Wenn du dieses Feld frei lässt, wird stattdessen ein Home-Symbol angezeigt." + favicon_url: "Das Favicon deiner Seite. Besuche http://en.wikipedia.org/wiki/Favicon um weitere Informationen zu erhalten. Damit das Favicon korrekt über einen CDN-Service funktioniert, muss es eine .png Datei sein." + mobile_logo_url: "Das fixierte Logo in der oberen Linken Hälfte der mobilen Seitenversion. Es sollte eine quadratische Form haben. Wenn du dieses Feld frei lässt, wird `logo_url` benutzt. " apple_touch_icon_url: "Icon für berührungsempfindliche Apple-Geräte. Empfohlene Grösse ist 144px auf 144px." - notification_email: "Die E-Mail-Adresse die als \"From:\" Absender aller wichtiger System-Emails benutzt wird. Die benutzte Domain sollte über korrekte SPF, DKIM und PTR Einträge verfügen, damit Emails sicher zugestellt werden können." - email_custom_headers: "Eine Pipe-getrennte (|) Liste von eigenen Mail Headern" + notification_email: "Die E-Mail-Adresse die als \"From:\" Absender aller wichtiger System-E-Mails benutzt wird. Die benutzte Domain sollte über korrekte SPF, DKIM und PTR Einträge verfügen, damit E-Mails sicher zugestellt werden können." + email_custom_headers: "Eine Pipe-getrennte (|) Liste von eigenen E-Mail Headern" email_subject: "Format der Betreffzeile in Standard-E-Mails. Siehe https://meta.discourse.org/t/customize-subject-format-for-standard-emails/20801" use_https: "Soll die volle URL der Seite (Discourse.base_url) mit http oder https beginnen? AKTIVIERE DIES NICHT BIS HTTPS AUFGESETZT IST UND BEREITS FUNKTIONIERT!" summary_score_threshold: "Mindestpunktzahl, die ein Beitrag benötigt, um in der \"Thema zusammenfassen\"-Ansicht zu erscheinen." @@ -697,7 +754,7 @@ de: summary_likes_required: "Mindestanzahl an \"Gefällt mir\" Wertungen in einem Thema, bevor die \"Thema zusammenfassen\" Funktion aktiviert wird." summary_percent_filter: "Zeige die besten (n)% der Beiträge eines Themas in der \"Thema zusammenfassen\"-Ansicht." summary_max_results: "Maximale Anzahl der sichtbaren Beiträge beim Zusammenfassen von Themen" - enable_private_messages: "Erlaube Benutzern auf Vertrauensstufe 1, Direktnachrichten zu erstellen und zu beantworten." + enable_private_messages: "Erlaube es, Nutzern mit der Vertrauensstufe 1 (konfigurierbar mit der Einstellung min trust to send messages) Nachrichten zu erstellen und auf Nachrichten zu antworten." enable_long_polling: "Nachrichtenbus für Benachrichtigungen kann Long-Polling nutzen." long_polling_base_url: "Basis-URL für Long Polling (wenn zum Ausliefern von dynamischen Inhalten ein CDN verwendet wird, setze es auf Origin Pull), z. B. http://origin.site.com" long_polling_interval: "Wartezeit, bevor der Server auf Clients reagiert, wenn keine Daten gesendet werden müssen (nur für angemeldete Benutzer)" @@ -713,10 +770,13 @@ de: tl4_additional_likes_per_day_multiplier: "Limit für \"Gefällt mir\" für Nutzer auf Vertrauensstufe 4 (Anführer) mit diesem Faktor multiplizieren" num_flags_to_block_new_user: "Verstecke alle Beiträge eines neuen Nutzers und erlaube keine neuen Beiträge mehr, wenn der neue Nutzer die hier angegebene Zahl an Meldungen bezüglich Werbung von num_users_to_block_new_user verschiedenen anderen Nutzern erhalten hat. 0 deaktiviert diese Funktion." num_users_to_block_new_user: "Verstecke alle Beiträge eines neuen Nutzers und erlaube keine neuen Beiträge mehr, wenn der neue Nutzer num_flags_to_block_new_user Meldungen bezüglich Werbung von der hier angegebenen Zahl verschiedener anderer Nutzer erhalten hat. 0 deaktiviert diese Funktion." - notify_mods_when_user_blocked: "Wenn ein Benutzer automatisch gesperrt wird, sende eine Mail an alle Moderatoren." + notify_mods_when_user_blocked: "Wenn ein Benutzer automatisch gesperrt wird, sende eine Nachricht an alle Moderatoren." flag_sockpuppets: "Wenn ein neuer Nutzer auf ein Thema antwortet, das von einem anderen neuen Nutzer aber mit der gleichen IP-Adresse begonnen wurde, markiere beide Beiträge als Werbung." traditional_markdown_linebreaks: "Traditionelle Zeilenumbrüche in Markdown, die zwei nachfolgende Leerzeichen für einen Zeilenumbruch benötigen." + allow_html_tables: "Erlaube es, Tabellen in Markdown mit HTML-Tags einzugeben. TABLE, THEAD, TD, TR, TH werden erlaubt (alle Beiträge mit Tabellen müssen ihr HTML erneuern)" post_undo_action_window_mins: "Minuten, die ein Nutzer hat, um Aktionen auf Beiträgen rückgängig zu machen (Like, Meldung, usw.)." + must_approve_users: "Moderatoren oder Administratoren müssen alle neuen Benutzeraccounts freischalten, bevor diese Zugriff auf die Webseite erhalten. ACHTUNG: Das Aktivieren dieser Option für eine Live-Seite entfernt den Zugriff auch für alle existierenden Benutzer!" + pending_users_reminder_delay: "Benachrichtige die Moderatoren, falls neue Nutzer mehr als so viele Stunden auf ihre Genehmigung gewartet haben. Stelle -1 ein, um diese Benachrichtigungen zu deaktivieren." ga_tracking_code: "Google Analytics Trackingcode, zum Beispiel: UA-12345678-9; siehe http://google.com/analytics" ga_domain_name: "Google Analytics Domänenname, zum Beispiel: mysite.com; siehe http://google.com/analytics" ga_universal_tracking_code: "Google Universal Analytics (analytics.js) tracking code code, beispielsweise: UA-12345678-9; Siehe http://google.com/analytics" @@ -725,6 +785,7 @@ de: enable_noscript_support: "Aktiviere Standard-Suchmaschinen-Webcrawler-Unterstützung durch den noscript-Tag" allow_moderators_to_create_categories: "Erlaube Moderatoren neue Kategorien zu erstellen" cors_origins: "Erlaubte Adressen für Cross-Origin-Requests (CORS). Jede Adresse muss http:// oder https:// enthalten. Die Umgebungsvariable DISCOURSE_ENABLE_CORS muss gesetzt sein, um CORS zu aktivieren." + use_admin_ip_whitelist: "Administratoren können sich nur anmelden, wenn sie von einer IP-Adresse aus zugreifen, welcher unter den vertrauenswürden IP-Adressen gelistet ist (Admin > Logs > Screened Ips)." top_menu: "Bestimme, welche Elemente in der Navigationsleiste der Homepage auftauchen sollen, und in welcher Reihenfolge. Beispiel: latest|new|unread|categories|top|read|posted|bookmarks" post_menu: "Bestimme, welche Funktionen in welcher Reihenfolge im Beitragsmenü auftauchen. Beispiel: like|edit|flag|delete|share|bookmark|reply" post_menu_hidden_items: "Die Einträge im Menü eines Beitrags, die standardmäßig hinter einer erweiterbaren Ellipse versteckt werden sollen." @@ -736,14 +797,15 @@ de: suppress_reply_directly_above: "Verstecke das erweiterbare „Antwort auf“-Feld in einem Beitrag, wenn der beantwortete Beitrag direkt darüber angezeigt wird." suppress_reply_when_quoting: "Verstecke das erweiterbare „Antwort auf“-Feld in einem Beitrag, wenn der Beitrag den beantworteten Beitrag zitiert." max_reply_history: "Maximale Anzahl an Antworten beim Ausklappen von in-reply-to" - experimental_reply_expansion: "Verstecke dazwischenliegende Beiträge, wenn der beantwortete Beitrag erweitert wird (experimentell)." topics_per_period_in_top_summary: "Anzahl der Themen, die in der Top-Themübersicht angezeigt werden." topics_per_period_in_top_page: "Anzahl der Themen, die in der mit \"Mehr zeigen\" erweiterten Top-Themenübersicht angezeigt werden." redirect_users_to_top_page: "Verweise neue und länger abwesende Nutzer automatisch zur Top Übersichtsseite" + top_page_default_timeframe: "Standardzeitfenster für die oberste, angezeigte Seite." show_email_on_profile: "Im Profil die E-Mail-Adresse des Benutzers anzeigen (ist nur für den Benutzer selbst und Mitarbeiter sichtbar)." email_token_valid_hours: "Tokens zur Passwort-Wiederherstellung / Aktivierung eines Kontos sind für (n) Stunden gültig." email_token_grace_period_hours: "Tokens zur Passwort-Wiederherstellung / Aktivierung eines Kontos sind auch nach ihrer Verwendung noch für eine Frist von (n) Stunden gültig." enable_badges: "Abzeichen aktivieren" + enable_whispers: "Erlaube Moderatoren und Administratoren in Beiträgen privat zu kommunizieren (experimentell)" allow_index_in_robots_txt: "Suchmaschinen mittels der robots.txt Datei erlauben, die Seite zu indizieren." email_domains_blacklist: "Eine durch senkrechte Striche getrennte Liste von E-Mail-Domains, die für die Registrierung neuer Konten nicht verwenden werden dürfen. Beispiel: mailinator.com|trashmail.net" email_domains_whitelist: "Eine durch senkrechte Striche getrennte Liste von E-Mail-Domains, die für die Registrierung neuer Konten verwendet werden können. ACHTUNG: Benutzer mit E-Mail-Adressen anderer Domains werden nicht zugelassen!" @@ -759,15 +821,22 @@ de: login_required: "Nur angemeldete Nutzer dürfen Inhalte der Seite lesen, anonyme Zugriffe sind verboten." min_username_length: "Minimale Benutzernamenlänge in Zeichen." max_username_length: "Maximale Benutzernamenlänge in Zeichen." + reserved_usernames: "Benutzernamen, welche für die Registrierung gesperrt werden sollen." min_password_length: "Minimale Länge des Passworts." + min_admin_password_length: "Minimale Passwortlänge für Administratoren." block_common_passwords: "Erlaube kein Passwort unter den 10000 meist verwendeten Passwörter." + enable_sso: "Aktiviere Single Sign-on über eine externe Seite (WARNUNG: DIE E-MAIL ADRESSE DES BENUTZERS *MUSS* VON DER EXTERNEN SEITE VERIFIZIERT WERDEN)." enable_sso_provider: "Aktiviere das Discourse SSO Anbieter Protokoll unter /session/sso_provider; benötigt sso_secret." sso_url: "URL des Single Sign On Endpunkts" sso_secret: "Geheime Zeichenkette die als Schlüssel für die Authentifizierung von SSO-Informationen verwendet wird. Sollte unbedingt 10 Zeichen oder länger sein." + sso_overrides_email: "Überschreibt lokale E-Mail mit E-Mail der externen Site aus SSO Daten (WARNUNG: Diskrepanzen können aufgrund der Normalisierung lokaler E-Mail-Adressen auftreten.)" + sso_overrides_username: "Überschreibt lokalen Benutzernamen mit dem Benutzernamen der externen Seite aus SSO Daten (WARNUNG: Diskrepanzen können aufgrund von Normalisierung von lokalen Benutzernamen auftreten)" + sso_overrides_name: "Überschreibt den vollen Namen des Benutzers mit den Daten von der externen Seite aus dem SSO-Payload bei jedem Login. Außerdem werden lokale Änderungen verhindert." sso_overrides_avatar: "Überschreibt den Avatar des Benutzers mit dem Avatar aus der SSO Payload. Wenn aktiv, dann sollte allow_uploaded_avatars deaktiviert werden." sso_not_approved_url: "Nicht genehmigte SSO-Accounts zu dieser URL weiterleiten" enable_local_logins: "Aktiviere Login mit lokal gespeicherten Benutzernamen und Passwörtern. (Anmerkung: muss aktiviert sein, damit Einladungen funktionieren)" allow_new_registrations: "Erlaube das Registrieren neuer Benutzerkonten. Wird dies deaktiviert, so kann niemand mehr ein neues Konto erstellen." + enable_signup_cta: "Zeige wiederkehrenden Gästen einen Hinweis, dass diese sich Anmelden oder Registrieren sollen." enable_yahoo_logins: "Aktiviere Yahoo Authentifizierung." enable_google_oauth2_logins: "Google Oauth2-Authentifizierung aktivieren. Dies ist der momentan von Google unterstützte Authentifizierungs-Mechanismus. Benötigt Client-ID und Secret." google_oauth2_client_id: "Client-ID deiner Google-Anwendung." @@ -775,6 +844,9 @@ de: enable_twitter_logins: "Aktiviere Twitter Authentifizierung (benötigt twitter_consumer_key und twitter_consumer_secret)." twitter_consumer_key: "Consumer Key für Twitter Authentifizierung, registriert auf http://dev.twitter.com" twitter_consumer_secret: "Consumer Secret für Twitter Authentifizierung, registriert auf http://dev.twitter.com" + enable_instagram_logins: "Authentifizierung mit Instagram aktivieren, benötigt instagram_consumer_key und instagram_consumer_secret" + instagram_consumer_key: "Consumer Key für Authentifizierung mit Instagram" + instagram_consumer_secret: "Consumer Secret für Authentifizierung mit Instagram" enable_facebook_logins: "Aktiviere Facebook Authentifizierung (benötigt facebook_app_id und facebook_app_secret)." facebook_app_id: "App-ID für Facebook Authentifizierung, registriert auf https://developers.facebook.com/apps" facebook_app_secret: "App Secret für Facebook Authentifizierung, registriert auf https://developers.facebook.com/apps" @@ -783,11 +855,19 @@ de: github_client_secret: "Client Secret für Github Authentifizierung, registriert auf https://github.com/settings/applications" allow_restore: "Wiederherstellung zulassen, welche ALLE vorhandenen Daten überschreiben kann! Auf 'false' lassen, sofern Sie nicht planen, eine Sicherung wiederherzustellen." maximum_backups: "Die maximale Anzahl an Sicherungen, die auf dem Server gespeichert werden. Ältere Sicherungen werden automatisch gelöscht." + automatic_backups_enabled: "Automatische Backups aktivieren. Die Backups werden im eingestellten Zeitintervall erstellt." + backup_frequency: "WIe häufig sollen Backups erstellt werden (Angabe in Tagen)?" enable_s3_backups: "Lade fertige Backups zu S3 hoch. WICHTIG: In den Dateien-Einstellungen müssen gültige S3-Kontodaten eingegeben sein." s3_backup_bucket: "Der entfernte Speicherort für Ihre Sicherungen. WARNUNG: Stellen Sie sicher, dass es sich um einen privaten Speicherort handelt." + s3_disable_cleanup: "Deaktiviere das Löschen von Backups aus S3 wenn sie lokal entfernt werden" + backup_time_of_day: "Uhrzeit in UTC, wenn Backups ausgeführt werden sollen." + backup_with_uploads: "Hochgeladene Dateien bei geplanten Backups mit einbeziehen. Wenn diese Einstellung deaktiviert ist, wird nur die Datenbank gesichert." active_user_rate_limit_secs: "Sekunden, nach denen das 'last_seen_at'-Feld aktualisiert wird." verbose_localization: "Erweiterte Lokalisierungstipps in der Benutzeroberfläche anzeigen " previous_visit_timeout_hours: "Stunden, die ein Besuch dauert, bevor er als 'früherer' Besuch gezählt wird." + top_topics_formula_log_views_multiplier: "Wert von Log Ansichten Multiplikator (n) in Top Themen Formel: `log(views_count) * (n) + op_likes_count * 0.5 + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_first_post_likes_multiplier: "Wert für den Multiplikator (n) für die ersten Likes pro Beitrag in der Formel für die besten Beiträge: `log(views_count) * 2 + op_likes_count * (n) + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_least_likes_per_post_multiplier: "Wert für den Multiplikator (n) für die wenigsten Likes pro Beitrag in der Formel für die besten Beiträge: `log(views_count) * 2 + op_likes_count * 0.5 + LEAST(likes_count / posts_count, (n)) + 10 + log(posts_count)`" rate_limit_create_topic: "Nach Erstellen eines Themas muss ein Nutzer (n) Sekunden warten, bevor ein weiteres Thema erstellt werden kann." rate_limit_create_post: "Nach Schreiben eines Beitrags muss ein Nutzer (n) Sekunden warten, bevor ein weiterer Beitrag erstellt werden kann." rate_limit_new_user_create_topic: "Nach Erstellen eines Themas muss ein neuer Nutzer (n) Sekunden warten, bevor ein weiteres Thema erstellt werden kann." @@ -799,7 +879,9 @@ de: max_topics_per_day: "Maximale Anzahl der Themen, die ein Nutzer pro Tag erstellen kann." max_private_messages_per_day: "Maximale Zahl Direktnachrichten, die ein Nutzer pro Tag erstellen kann." max_invites_per_day: "Maximale Zahl an Einladungen, die ein Nutzer pro Tag verschicken kann." - max_topic_invitations_per_day: "Maximale Zahl an Themen-Einladungen, die ein Nutzer pro Tag verschicken kann." + max_topic_invitations_per_day: "Maximale Zahl an Thema-Einladungen, die ein Nutzer pro Tag verschicken kann." + alert_admins_if_errors_per_minute: "Anzahl der Fehler pro Minute, bei der ein Administrator benachrichtigt werden soll. Ein Wert von 0 deaktiviert diese Funktion. Achtung: Benötigt einen Neustart." + alert_admins_if_errors_per_hour: "Anzahl der Fehler pro Stunde, bei der ein Administrator benachrichtigt werden soll. Ein Wert von 0 deaktiviert diese Funktion. Achtung: Benötigt einen Neustart." suggested_topics: "Anzahl der empfohlenen Themen am Ende eines Themas." limit_suggested_to_category: "Zeige nur Themen der aktuellen Kategorie in vorgeschlagenen Themen." clean_up_uploads: "Lösche verwaiste Uploads, um illegales Hosting zu vermeiden. ACHTUNG: du solltest ein Backup deines /uploads-Verzeichnis erstellen, bevor du diese Funktion aktivierst." @@ -812,6 +894,12 @@ de: s3_access_key_id: "The Amazon S3 access key id that will be used to upload images" s3_secret_access_key: "Der geheime Schlüssel von Amazon S3 welcher für das Hochladen verwendet wird" s3_region: "Der Name der Amazon S3 Region welche für das Hochladen verwendet wird" + s3_cdn_url: "Die CDN URL für alle S3 Anlagen (bspw. https://cdn.somewhere.com). ACHTUNG: Nachdem diese Einstellung abgeändert wurde, musst du alle alten Beiträge neu generieren." + avatar_sizes: "Liste der Größe von automatisch generierten Avataren." + external_system_avatars_enabled: "Benutze einen externen Avatar Service" + external_system_avatars_url: "URL des externen Avatar Systems. Erlaubte Ersetzungen sind {username} {first_letter} {color} {size}" + default_opengraph_image_url: "URL des standardmäßigen Open-Graph-Bildes." + allow_all_attachments_for_group_messages: "Erlaube alle E-Mail Anhänge für Gruppen-Nachrichten." enable_flash_video_onebox: "Aktiviere das Einbinden von swf und flv (Adobe Flash) Links in einer Onebox. ACHTUNG: Kann ein Sicherheitsrisiko sein." default_invitee_trust_level: "Standardwert für die Stufe eines eingeladenen Nutzers (0-4)." default_trust_level: "Standardwert für die Vertrauensstufe (0-4) für alle neuen Benutzer. ACHTUNG! Diesen Wert anzuheben kann zu erhöhtem Spam Aufkommen führen!" @@ -825,32 +913,38 @@ de: tl2_requires_likes_received: "Die Anzahl der Likes, die ein Benutzer erhalten muss, bevor er in die Vertrauensstufe 2 befördert wird." tl2_requires_likes_given: "Die Anzahl der Likes, die ein Benutzer vergeben muss, bevor er in die Vertrauensstufe 2 befördert wird." tl2_requires_topic_reply_count: "Die Anzahl der Beiträge, auf die ein Benutzer antworten muss, bevor er in die Vertrauensstufe 2 befördert wird." - tl3_requires_days_visited: "Die Mindestanzahl an Tagen, an denen ein Benutzer in den letzten 100 Tagen die Seite besucht haben muss, um die Vertrauensstufe 3 erreichen zu können. (0 bis 100)" - tl3_requires_topics_replied_to: "Die Mindestanzahl an Themen, auf die ein Benutzer in den letzten 100 Tagen geantwortet haben muss, um die Vertrauensstufe 3 erreichen zu können. (0 oder mehr)" - tl3_requires_topics_viewed: "Prozentualer Anteil aller Themen der letzten 100 Tage, die ein Nutzer mindestens gelesen haben muss, um die Vertrauensstufe Anführer (3) erreichen zu können. (0 bis 100)" - tl3_requires_posts_read: "Prozentualer Anteil aller Beiträge der letzten 100 Tage, die ein Nutzer mindestens gelesen haben muss, um die Vertrauensstufe Anführer (3) erreichen zu können. (0 bis 100)" + tl3_time_period: "Zeitraum für die Bedingungen für Vertrauensstufe 3 (in Tagen)" + tl3_requires_days_visited: "Mindestanzahl von Tagen innerhalb der letzten (tl3 time period) Tage in denen der Nutzer die Seite besucht haben muss, um Vertrauensstufe 3 erreichen zu können. Höher als tl3 time period einstellen, um Beförderungen auf Vertrauensstufe 3 zu deaktivieren. (0 oder mehr)" + tl3_requires_topics_replied_to: "Die Mindestanzahl an Themen, auf die ein Benutzer in den letzten (tl3 time period) Tagen geantwortet haben muss, um die Vertrauensstufe 3 erreichen zu können. (0 oder mehr)" + tl3_requires_topics_viewed: "Prozentualer Anteil aller Themen der letzten (tl3 time period) Tage, die ein Nutzer mindestens gelesen haben muss, um die Vertrauensstufe 3 erreichen zu können. (0 bis 100)" + tl3_requires_posts_read: "Prozentualer Anteil aller Beiträge der letzten (tl3 time period) Tage, die ein Nutzer mindestens gelesen haben muss, um die Vertrauensstufe 3 erreichen zu können. (0 bis 100)" tl3_requires_topics_viewed_all_time: "Mindestanzahl Themen, die ein Nutzer gelesen haben muss, um die Vertrauensstufe Anführer (3) erreichen zu können." tl3_requires_posts_read_all_time: "Mindestanzahl Beiträge, die ein Nutzer gelesen haben muss, um die Vertrauensstufe Anführer (3) erreichen zu können." - tl3_requires_max_flagged: "Um die Vertrauensstufe 3 erhalten zu können dürfen in den letzten 100 Tagen höchstens X Beiträge eines Nutzers von X verschiedenen anderen Nutzern gemeldet worden sein, wobei X diesem Wert entspricht. (0 oder mehr)" + tl3_requires_max_flagged: "Um die Vertrauensstufe 3 erhalten zu können dürfen in den letzten (tl3 time period) Tagen höchstens X Beiträge eines Nutzers von X verschiedenen anderen Nutzern gemeldet worden sein, wobei X diesem Wert entspricht. (0 oder mehr)" tl3_promotion_min_duration: "Mindestanzahl an Tagen, die ein Benutzer auf Vertrauensstufe 3 beförderter Nutzer auf dieser Stufe verbleibt, bevor er automatisch wieder auf Vertrauensstufe 2 heruntergestuft werden kann." - tl3_requires_likes_given: "Die Mindestanzahl an \"Likes\" die Sie in den letzten 100 Tagen gegeben haben müssen um für Vertrauenslevel 3 zu qualifizieren." - tl3_requires_likes_received: "Die Mindestanzahl an \"Likes\" die Sie in den letzten 100 Tagen erhalten haben müssen um für Vertrauenslevel 3 zu qualifizieren." + tl3_requires_likes_given: "Mindestanzahl an Likes die ein Nutzer innerhalb der letzten (tl3 time period) gegeben haben muss, um Vertrauensstufe 3 erreichen zu können." + tl3_requires_likes_received: "Mindestanzahl an Likes die ein Nutzer innerhalb der letzten (tl3 time period) bekommen haben muss, um Vertrauensstufe 3 erreichen zu können." tl3_links_no_follow: "rel=nofollow nicht von Links entfernen, die von Benutzern mit Vertrauensstufe 3 erstellt wurden." min_trust_to_create_topic: "Die minimale Vertrauensstufe wird benötigt um eine neues Thema zu erstellen." min_trust_to_edit_wiki_post: "Die minimal benötigte Vertrauensstufe, um als Wiki markierte Beiträge bearbeiten zu können." + min_trust_to_allow_self_wiki: "Das mindeste Vertrauenslevel, das ein Nutzer haben muss, um einen eigenen Wiki Eintrag zu erstellen." + min_trust_to_send_messages: "Benötigte Vertrauensstufe um neue private Nachrichten erstellen zu dürfen." newuser_max_links: "Maximale Anzahl der Links, die neue Benutzer Beiträgen hinzufügen dürfen." newuser_max_images: "Maximale Anzahl der Bilder, die neue Benutzer Beiträgen hinzufügen dürfen." newuser_max_attachments: "Maximale Anzahl der Dateien, die neue Benutzer Beiträgen hinzufügen dürfen." newuser_max_mentions_per_post: "Maximale Anzahl der @Namens-Erwähnungen, die neue Benutzer in Beiträgen nutzen dürfen." newuser_max_replies_per_topic: "Maximale Anzahl an Antworten, die ein neuer Benutzer in einem einzigen Thema geben darf, bevor jemand auf diese antwortet." max_mentions_per_post: "Maximale Anzahl der @Namens-Erwähnungen, die jemand in einem Beitrag nutzen kann." + max_users_notified_per_group_mention: "Maximale Anzahl an Nutzern die benachrichtigt werden wenn eine Gruppe erwähnt wird (wird die Grenze erreicht, werden keine Nutzer benachrichtigt)" create_thumbnails: "Erzeuge ein Vorschaubild und eine Lightbox für Bilder, die zu groß sind, um in einem Beitrag angezeigt zu werden." email_time_window_mins: "Warte (n) Minuten, bevor Nutzern eine Hinweis-E-Mail geschickt wird, um ihnen Gelegenheit zu geben, ihre Beiträge abschließend bearbeiten zu können." - email_posts_context: "Anzahl der Antworten welche als Konext einer Notifikations-Mail hinzugefügt werden." + private_email_time_window_seconds: "Warte (n) Sekunden, bevor irgendwelche private E-Mail-Benachrichtigungen gesendet werden, um den Nutzern die Möglichkeit zu geben, ihre Beiträge zu bearbeiten und abzuschließen." + email_posts_context: "Anzahl der Antworten, welche als Kontext einer Benachrichtigungs-E-Mail hinzugefügt werden." flush_timings_secs: "Sekunden, nach denen Zeiteinstellungen auf den Server übertragen werden." title_max_word_length: "Maximal erlaubte Wortlänge in Thementiteln, in Zeichen." title_min_entropy: "Für Titel neuer Themen minimal erforderliche Entropie (einzigartige Zeichen)." body_min_entropy: "Für den Text neuer Beiträge minimal erforderliche Entropie (einzigartige Zeichen)." + allow_uppercase_posts: "Beiträge oder Titel von Themen mit ausschließlich Großschreibweise erlauben." title_fancy_entities: "Konvertiere HTML-Entitys in Thementiteln." min_title_similar_length: "Minimale Länge eines Titels, bevor nach ähnlichen Titeln gesucht wird." min_body_similar_length: "Minimale Länge eines Beitragstextes, bevor nach ähnlichen Themen gesucht wird." @@ -864,6 +958,9 @@ de: topic_views_heat_low: "Aufrufe-Feld leicht hervorheben, sobald das Thema so oft gelesen wurde." topic_views_heat_medium: "Aufrufe-Feld mäßig hervorheben, sobald das Thema so oft gelesen wurde." topic_views_heat_high: "Aufrufe-Feld stark hervorheben, sobald das Thema so oft gelesen wurde." + cold_age_days_low: "Aktivitäts-Feld leicht abdunkeln, wenn das Thema N Tage alt ist." + cold_age_days_medium: "Aktivitäts-Feld etwas abdunkeln, wenn das Thema N Tage alt ist." + cold_age_days_high: "Aktivitäts-Feld stark abdunkeln, wenn das Thema N Tage alt ist." history_hours_low: "Bearbeitungs-Symbol leicht hervorheben, wenn der Beitrag innerhalb so vieler Stunden nach Erstellen bearbeitet wird." history_hours_medium: "Bearbeitungs-Symbol mäßig hervorheben, wenn der Beitrag innerhalb so vieler Stunden nach Erstellen bearbeitet wird." history_hours_high: "Bearbeitungs-Symbol stark hervorheben, wenn der Beitrag innerhalb so vieler Stunden nach Erstellen bearbeitet wird." @@ -871,24 +968,36 @@ de: topic_post_like_heat_medium: "Feld für Anzahl der Antworten mäßig hervorheben, wenn das Verhältnis von Likes zu Antworten diesen Wert übersteigt." topic_post_like_heat_high: "Feld für Anzahl der Antworten stark hervorheben, wenn das Verhältnis von Likes zu Antworten diesen Wert übersteigt." faq_url: "Vollständige URL zu einer externen FAQ, welche du gerne verwenden möchtest." - tos_url: "Die vollständige URL zu Deinen extern gehosteten Nutzungsbedingungen, sofern vorhanden." - privacy_policy_url: "Die vollständige URL zu Deinen extern gehosteten Datenschutzrichtlinien, sofern vorhanden." + tos_url: "Die vollständige URL zu deinen extern gehosteten Nutzungsbedingungen, sofern vorhanden." + privacy_policy_url: "Die vollständige URL zu deinen extern gehosteten Datenschutzrichtlinien, sofern vorhanden." newuser_spam_host_threshold: "Die Anzahl welche ein Frischling Beiträge mit Links auf die gleiche Seite innerhalb ihrer `newuser_spam_host_posts` veröffentlichen, bevor der Beitrag als Spam klassifiziert wird." white_listed_spam_host_domains: "Liste von Domänen, die keinem Spam-Host Test unterzogen werden. Neue Benutzer werden niemals daran gehindert, Beiträge mit Links zu diesen Domains zu erstellen." staff_like_weight: "Zusätzlicher Gewichtungsfaktor für \"Gefällt mir\" Wertungen von Mitarbeitern." + topic_view_duration_hours: "Alle N Stunden einen neuen Themenaufruf pro IP/Benutzer zählen." + user_profile_view_duration_hours: "Alle N Stunden einen neuen Profilaufruf pro IP/Benutzer zählen." levenshtein_distance_spammer_emails: "E-Mail-Adressen, die sich um so viele Zeichen unterscheiden, werden beim Vergleich von Adressen von Spam-Nutzern dennoch als identisch betrachtet." max_new_accounts_per_registration_ip: "Keine neuen Registrierungen von einer IP-Adresse annehmen, zu der bereits (n) Benutzerkonten mit Vertrauensstufe 0 (und keine Konten von Mitarbeitern oder mit Vertrauensstufe 2 oder höher) gehören." min_ban_entries_for_roll_up: "Ein Klick auf den \"Zusammenfassen\" Knopf führt (N) oder mehr Sperren zu einer einzelnen Subnetz-Sperre zusammen." max_age_unmatched_emails: "Gefilterte E-Mail-Adressen nach (N) Tagen ohne Treffer löschen." max_age_unmatched_ips: "Gefilterte IP-Adressen nach (N) Tagen ohne Treffer löschen." - num_flaggers_to_close_topic: "Mindestanzahl unabhängiger Mitglieder die ein Thema \"flaggen\" damit es automatisch pausiert wird bis es geprüft wurde." - num_flags_to_close_topic: "Mindestanzahl aktiver \"Flags\" die notwendig sind um ein Thema automatisch zu pausieren bis es geprüft wird." + num_flaggers_to_close_topic: "Mindestzahl unabhängiger Mitglieder, die ein Thema melden, damit es automatisch für eine Prüfung pausiert wird." + num_flags_to_close_topic: "Mindestzahl aktiver Meldungen, die notwendig sind, um ein Thema automatisch für eine Prüfung zu pausieren." auto_respond_to_flag_actions: "Automatische Antwort auf abgearbeitete Meldungen aktivieren." + min_first_post_typing_time: "Minimale Zeit die ein Benutzer mindestens aufwenden muss, um einen Beitrag zu schreiben. Wenn diese Zeit unterschritten wird, wird der Beitrag automatisch in die Warteschlange für freizuschaltende Beiträge verschoben. Setze diesen Wert auf 0 um dieses Verhalten zu deaktivieren (nicht empfohlen)." + auto_block_fast_typers_on_first_post: "Blockiere Benutzer automatisch, welche unterhalb der min_first_post_typing_time liegen." + auto_block_fast_typers_max_trust_level: "Maximales Vertrauenslevel um \"Schnelltipper\" automatisch zu blockieren." + auto_block_first_post_regex: "Regulärer Ausdruck der dafür sorgt dass passende erste Beiträge von Benutzern genehmigt werden müssen. Groß- und Kleinschreibung wird nicht beachtet.\nBeispiel: raging|a[bc]a blockiert alle ersten Beiträge, die raging, aba oder aca beinhalten. Wird nur auf den ersten Beitrag eingewendet." reply_by_email_enabled: "Aktviere das Antworten auf Themen via E-Mail." reply_by_email_address: "Vorlage für die Antwort einer per E-Mail eingehender E-Mail-Adresse, zum Beispiel: %{reply_key}@reply.example.com oder replies+%{reply_key}@example.com" - disable_emails: "Discourse daran hindern, jegliche Art von Emails zu verschicken" + disable_emails: "Discourse daran hindern jegliche E-Mails zu verschicken" strip_images_from_short_emails: "Entferne Bilder aus E-Mails kleiner als 2800 Bytes." short_email_length: "Kurze E-Mail-Länge in Bytes" + display_name_on_email_from: "Zeige vollständige Namen im Absender-Feld von E-Mails" + unsubscribe_via_email: "Erlaube es Benutzern eine E-Mail mit dem Betreff oder Text: \"unsubscribe\" zum abbestellen der E-Mails zu senden." + unsubscribe_via_email_footer: "Hänge einen Link zum Abbestellen ans Ende der E-Mail." + delete_email_logs_after_days: "Lösche E-Mail Logs nach (N) Tagen. 0 um sie für immer zu behalten." + max_emails_per_day_per_user: "Maximale Zahl an E-Mails, die Benutzern gesendet werden. 0 zum Deaktivieren des Limits." + enable_staged_users: "Erstelle automatisch vorbereitete Benutzer, wenn eingehende E-Mails verarbeitet werden." pop3_polling_enabled: "E-Mail-Antworten über POP3 abholen." pop3_polling_ssl: "SSL für die Verbindung zum POP3-Server verwenden. (Empfohlen)" pop3_polling_period_mins: "Intervall in Minuten zum Abholen neuer E-Mails vom POP3-Konto. HINWEIS: benötigt Neustart." @@ -896,10 +1005,11 @@ de: pop3_polling_host: "Der Host für die POP3-Anfrage nach E-Mails." pop3_polling_username: "Der Benutzername für das POP3-Konto zum Abfragen von E-Mails." pop3_polling_password: "Das Passwort für das POP3-Konto zum Abfragen von E-Mails." + log_mail_processing_failures: "Logge Fehler im E-Mail Prozess in http://yoursitename.com/logs" email_in: "Erlaube Benutzern neue Themen per E-Mail (benötigt POP3 polling) zu erstellen. Konfiguriere die Adressen im Reiter „Einstellungen“ für jede Kategorie." - email_in_min_trust: "Minimale Vertrauensstufe um neue Themen per E-Mail posten zu können." + email_in_min_trust: "Minimale Vertrauensstufe um neue Themen per E-Mail erstellen zu können." email_prefix: "Das [label] das für den Betreff von E-Mails genutzt wird. Standardwert ist 'title' wenn dies nicht gesetzt ist." - email_site_title: "Titel der Seite, der als Absender beim Versand von E-Mails verwendet wird. Wenn nicht angegeben wird 'title' verwendet. Verwende diese Einstellung, wenn 'title' spezielle Zeichen enthält, die im Absender-Feld einer Email nicht verwendet werden dürfen." + email_site_title: "Titel der Seite, der als Absender beim Versand von E-Mails verwendet wird. Wenn nicht angegeben wird 'title' verwendet. Verwende diese Einstellung, wenn 'title' spezielle Zeichen enthält, die im Absender-Feld einer E-Mail nicht verwendet werden dürfen." minimum_topics_similar: "Wie viele Themen existieren müssen, bevor beim Erstellen eines neuen Themas eine Liste ähnlicher Themen angezeigt wird." relative_date_duration: "Anzahl von Tagen während derer das Datum eines Beitrags relativ (7T) und nicht absolut (20. Feb) angegeben wird." delete_user_max_post_age: "Verhindere das Löschen von Benutzerkonten, deren erster Beiträg mehr als (x) Tage alt ist." @@ -907,13 +1017,17 @@ de: username_change_period: "Die Anzahl der Tage, die neu registrierte Benutzer Zeit haben, um ihren Benutzernamen zu ändern (0 verbietet Änderungen)." email_editable: "Erlaube Benutzern ihre E-Mail-Adresse nach der Registrierung zu ändern." logout_redirect: "Ziel für Weiterleitung nach einem Logout (z. B.: http://somesite.com/logout)" + allow_uploaded_avatars: "Benutzer können eigene Profilbilder hochladen." + allow_animated_avatars: "Benutzer können animierte Profilbilder (.gif) hochladen und benutzen. ACHTUNG: Rufe den Befehl `avatars:refresh rake` auf nachdem du diese Option verändert hast." allow_animated_thumbnails: "Generiert animierte Vorschaubilder von animierten gifs." default_avatars: "URLs zu Bildern, die als Standard-Avatare verwendet werden sollen, bis neue Nutzer ihren Avatar geändert haben." automatically_download_gravatars: "Avatare von Gravatar herunterladen, wenn ein Nutzer sich registriert oder seine E-Mail-Adresse ändert." digest_topics: "Maximale Anzahl von Themen, die in der E-Mail-Zusammenfassung angezeigt werden." digest_min_excerpt_length: "Minimale Länge des Auszugs aus einem Beitrag in der E-Mail-Zusammenfassung, in Zeichen." - suppress_digest_email_after_days: "Sende keine E-Mail-Zusammenfassungen an Benutzer, die die Seite seit mehr als (n) Tagen nicht mehr besucht haben." + delete_digest_email_after_days: "Keine Zusammenfassungen an Nutzer senden, welche für mehr als (n) Tage nicht auf der Seite aktiv waren." + digest_suppress_categories: "Diese Kategorien in Zusammenfassungs-Mails unterdrücken." disable_digest_emails: "E-Mail-Zusammenfassungen für alle Benutzer deaktivieren." + detect_custom_avatars: "Aktiviere diese Option, um zu überprüfen, ob Benutzer eigene Profilbilder hochgeladen haben." max_daily_gravatar_crawls: "Wie oft pro Tag Discourse höchstens auf Gravatar nach benuterdefinierten Avataren suchen soll." public_user_custom_fields: "Liste selbst definierter Profil-Felder, die öffentlich angezeigt werden dürfen." staff_user_custom_fields: "Liste selbst definierter Profil-Felder, die Mitarbeitern angezeigt werden dürfen." @@ -921,16 +1035,23 @@ de: allow_anonymous_posting: "Nutzern erlauben, in den anonymen Modus zu wechseln" anonymous_posting_min_trust_level: "Kleinste Vertrauensstufe, ab der das Schreiben anonymer Beiträge erlaubt ist" anonymous_account_duration_minutes: "Um die Anonymität der virtuellen anonymen Nutzer zu erhalten, erzeuge ein neues anonymes Konto alle N Minuten je Benutzer. Beispiel: wenn dies auf 600 gesetzt ist wird ein neues anonymes Konto erzeugt, wenn ein Benutzer in den anonymen Modus wechselt UND mindestens 600 Minuten seit der letzten anonymen Nachricht dieses Nutzers vergangen sind." + hide_user_profiles_from_public: "Deaktiviert Benutzerkarten, Nutzerprofile und das Benutzerverzeichnis für anonyme Nutzer." allow_profile_backgrounds: "Erlaube Benutzern Profilhintergründe hochzuladen." - sequential_replies_threshold: "Anzahl von Beiträgen, die ein Benutzer in einem Thema am Stück schreiben darf, bevor er eine Erinnerung bezüglich zu vieler aufeinanderfolgender Antworten erhält." + sequential_replies_threshold: "Anzahl an Beiträgen die ein Nutzer machen muss, um benachrichtigt zu werden, dass er zu viele aufeinanderfolgende Antworten schreibt." enable_mobile_theme: "Mobilgeräte verwenden eine mobile Darstellung mit der Möglichkeit zur vollständigen Seite zu wechseln. Deaktiviere diese Option, wenn du ein eigenes Full-Responsive-Stylesheet verwenden möchtest." dominating_topic_minimum_percent: "Anteil der Nachrichten eines Themas in Prozent, die ein einzelner Nutzer verfassen darf, bevor dieser Nutzer darauf hingewiesen wird, dass er dieses Thema dominiert." + disable_avatar_education_message: "Weise Benutzer nicht darauf hin, dass sie ihren Avatar ändern können" + daily_performance_report: "Analysiere die NGINX-Logs täglich. Poste anschließend eine Zusammenfassung als Beitrag, welcher nur für Moderatoren oder Administratoren zugänglich ist." suppress_uncategorized_badge: "Zeige kein Abzeichen für unkategorisierte Themen in der Themenliste." + permalink_normalizations: "Diesen regulären Ausdruck anwenden, bevor Permalinks verarbeitet werden; Beispiel: /(topic.*)\\?.*/\\1 wird Query-Strings von Themen-Routen entfernen. Format: regulärer Ausdruck + String, benutze \\1 usw. um Teilausdrücke zu verwenden" global_notice: "Zeigt allen Besuchern eine DRINGENDE NOTFALL-NACHRICHT als global sichtbares Banner an. Deaktiviert bei leerer Nachricht. (HTML ist erlaubt.)" disable_edit_notifications: "Unterdrückt Bearbeitungshinweise durch den System-Nutzer, wenn die 'download_remote_images_to_local' Einstellung aktiviert ist." + automatically_unpin_topics: "Themen automatisch loslösen, wenn ein Nutzer das Ende erreicht." + read_time_word_count: "Wörteranzahl pro Minute um die abgeschätzte Lesezeit zu berechnen." full_name_required: "Der voller Name wird für das Benutzerprofil benötigt." enable_names: "Zeigt den vollen Namen eines Benutzers auf dem Profil, der Benutzerkarte und in E-Mails an. Wenn deaktiviert wird der volle Name überall ausgeblendet." display_name_on_posts: "Zeige zusätzlich zum @Benutzernamen auch den vollen Namen des Benutzers bei seinen Beiträgen." + show_time_gap_days: "Wenn zwei Beiträge eine bestimmte Anzahl an Tagen auseinander liegen, zeige die Zeitdifferenz im Beitrag an." invites_per_page: "Anzahl an Einladungen, die auf der Benutzerseite angezeigt werden." short_progress_text_threshold: "Sobald die Anzahl an Beiträgen in einem Thema diese Nummer übersteigt, zeigt der Fortschrittsbalken nur noch die aktuelle Beitragsnummer. Dieser Wert sollte angepasst werden, falls die die Breite des Fortschrittsbalkens verändert wird." default_code_lang: "Standard Syntax Highlighting, dass auf GitHub Code Blöcke angewendet wird. (lang-auto, ruby, python etc.)" @@ -940,22 +1061,46 @@ de: feed_polling_enabled: "NUR WENN EINGEBETTET: Bestimmt, ob Inhalte eines RSS-/ATOM-Feeds als zusätzliche Beiträge dargestellt werden." feed_polling_url: "NUR WENN EINGEBETTET: URL des einzubettenden RSS-/ATOM-Feeds." embed_by_username: "Discourse-Benutzername des Benutzers, der die eingebetteten Themen erstellt." - embed_username_key_from_feed: "Schlüsse, um Discourse-Benutzernamen aus Feed zu ziehen." + embed_username_key_from_feed: "Schlüssel, um Discourse-Benutzernamen aus Feed zu ermitteln." embed_truncate: "Kürze die eingebetteten Beiträge" embed_post_limit: "Maximale Anzahl der Beiträge die eingebettet werden." + embed_username_required: "Der Benutzername ist für die Betragserstellung notwendig" embed_whitelist_selector: "CSS Selektor für Elemente, die in Einbettungen erlaubt sind." embed_blacklist_selector: "CSS Selektor für Elemente, die in Einbettungen entfernt werden." notify_about_flags_after: "Wenn es Markierungen gibt, die nicht nach dieser Anzahl von Stunden behandelt wurden, sende eine E-Mail an contact_email. Setze dies auf 0 um es zu deaktivieren." enable_cdn_js_debugging: "Ermöglicht die Anzeige vollständiger Fehler auf /logs, indem alle eingebetteten JavaScripts Cross-Origin Zugriffsberechtigungen erhalten." show_create_topics_notice: "Administratoren eine Warnmeldung anzeigen, wenn im Forum weniger als 5 öffentlich sichtbare Themen existieren." delete_drafts_older_than_n_days: Lösche Entwürfe, die mehr als (n) Tage alt sind. - vacuum_db_days: "Führe VACUUM FULL ANALYZE aus, um nach Migrationen Speicher in der Datenbank zurückzugewinnen (zum Deaktivieren auf 0 setzen)" + vacuum_db_days: "Führe VACUUM ANALYZE aus, um Datenbankspeicher nach Migrationen zurückzuerhalten (0 um zu deaktivieren)" prevent_anons_from_downloading_files: "Nichtangemeldeten Benutzern das Herunterladen von Anhängen verbieten. WARNUNG: dies verhindert auch das Herunterladen jeglicher Ressourcen für Website-Anpassungen, die als Anhänge gespeichert wurden." + slug_generation_method: "Gib eine Methode an, wie Kürzel in URLs generiert werden sollen. 'encoded' verwendet einen Prozent-Encodierten String, bei 'none' wird kein Kürzel verwendet." enable_emoji: "Aktiviere emoji" - emoji_set: "Wie magst du dein emoji?" + emoji_set: "Welche Emoji sollen es sein?" enforce_square_emoji: "Emojis immer mit quadratischem Seitenverhältnis darstellen." - approve_post_count: "Anzahl Beiträge eines neuen Nutzers, die genehmigt werden müssen" + approve_post_count: "Anzahl der Beiträge eines neuen Nutzers oder Anwärters, die genehmigt werden müssen" approve_unless_trust_level: "Beiträge von Nutzern unterhalb dieser Vertrauensstufe müssen genehmigt werden" + notify_about_queued_posts_after: "Wenn es Beiträge gibt, welche seit mehreren Stunden auf ihre Freischaltung warten, sende eine E-Mail an die Kontaktadresse. Setze diesen Wert auf 0 um das zu deaktivieren." + default_email_digest_frequency: "Lege fest, wie oft die Benutzer eine Zusammenfassung per E-Mail erhalten." + default_include_tl0_in_digests: "Beiträge von neuen Benutzern standardmäßig in E-Mail mit Neuigkeiten einfügen. Nutzer können dies in Ihren Einstellungen anpassen." + default_email_private_messages: "Sende einem Benutzer standardmäßig eine E-Mail, wenn dieser eine Nachricht von einem anderen Benutzer erhält." + default_email_direct: "Aktiviere standardmäßig, dass eine E-Mail versendet wird, sobald ein Benutzer einen anderen Benutzer zitiert / einem anderen Benutzer antwortet / oder einen anderen Benutzer erwähnt bzw. einlädt." + default_email_mailing_list_mode: "Sende standardmäßig eine E-Mail für jeden neuen Beitrag." + disable_mailing_list_mode: "Verhindere, dass Nutzer den Mailinglisten-Modus aktivieren." + default_email_always: "Aktiviert den E-Mail Versand an Nutzer, auch wenn diese gerade auf der Webseite aktiv sind. " + default_email_previous_replies: "Standardmäßig vorhergehende Antworten in E-Mails einschließen." + default_email_in_reply_to: "Standardmäßig einen Anriss des Beitrags, auf den geantwortet wurde, in E-Mails mit einschließen." + default_other_new_topic_duration_minutes: "Zeit wie lange ein Thema als \"Neu\" markiert werden soll. " + default_other_auto_track_topics_after_msecs: "Zeit bevor ein Thema automatisch verfolg wird. " + default_other_external_links_in_new_tab: "Öffne externe Links standardmäßig in einem neuen Tab." + default_other_enable_quoting: "Aktiviere standardmäßig die Zitat-Antwort Funktion für hervorgehobenen Text." + default_other_dynamic_favicon: "Zeige standardmäßig die Anzahl von neuen und geänderten Beiträgen im Browser-Symbol an." + default_other_disable_jump_reply: "Springe standardmäßig nicht zum neusten Beitrag des Users, wenn dieser geantwortet hat." + default_other_edit_history_public: "Zeige standardmäßig die Beitragshistorie öffentlich an." + default_other_like_notification_frequency: "Nutzer standardmäßig bei Likes benachrichtigen." + default_topics_automatic_unpin: "Standardmäßig Themen automatisch loslösen, wenn ein Nutzer das Ende erreicht." + default_categories_watching: "Liste der standardmäßig beobachteten Kategorien." + default_categories_tracking: "Liste der standardmäßig gefolgten Kategorien." + default_categories_muted: "Liste der standardmäßig stummgeschalteten Kategorien." errors: invalid_email: "Ungültige E-Mail-Ad­res­se" invalid_username: "Es gibt keinen Benutzer mit diesem Nutzernamen." @@ -970,7 +1115,12 @@ de: invalid_string_min: "Muss mindestens %{min} Zeichen lang sein." invalid_string_max: "Darf nicht länger als %{max} Zeichen sein." invalid_reply_by_email_address: "Adresse muss '%{reply_key}' enthalten und sich von der Benachrichtigungs E-Mail-Adresse unterscheiden." + pop3_polling_host_is_empty: "Du musst einen 'POP3 Abfrage Host' definieren, um POP3 Abfragen zu aktivieren." + pop3_polling_username_is_empty: "Du musst einen 'POP3 Abfrage Nutzername' definieren, um POP3 Abfragen zu aktivieren." + pop3_polling_password_is_empty: "Du must ein 'POP3 Abfrage Passwort' definieren, um POP3 Abfragen zu aktivieren." + pop3_polling_authentication_failed: "POP3 Authentifizierung ist fehlgeschlagen. Bitte überprüfe die POP3 Anmeldedaten." notification_types: + group_mentioned: "%{group_name} wurde auf %{link} erwähnt" mentioned: "%{display_username} hat Dich in %{link} erwähnt." liked: "%{display_username} gefällt deinen Beitrag in %{link}." replied: "%{display_username} hat auf deinen Beitrag in %{link} geantwortet." @@ -980,7 +1130,6 @@ de: moved_post: "%{display_username} hat deinen Beitrag nach %{link} verschoben." private_message: "%{display_username} hat Dir eine Nachricht geschickt: %{link}" invited_to_private_message: "%{display_username} hat dich zu einer Unterhaltung eingeladen: %{link}" - invited_to_topic: "%{display_username} hat dich in ein Thema eingeladen: %{link}" invitee_accepted: "%{display_username} hat deine Einladung angenommen." linked: "%{display_username} hat dich auf %{link} verlinkt" granted_badge: "Sie haben %{link} verdient" @@ -990,11 +1139,6 @@ de: category: 'Kategorien' topic: 'Ergebnisse' user: 'Benutzer' - sso: - not_found: "Konto kann nicht gefunden oder erstellt werden, kontaktiere den Administrator." - account_not_approved: "Das Konto wartet auf seine Überprüfung. Du bekommst eine E-Mail Benachrichtigung, wenn es überprüft wurde." - unknown_error: "Die Informationen konnten nicht aktualisiert werden, kontaktiere den Administrator." - timeout_expired: "Zeitüberschreitung beim Login. Bitte versuche dich erneut einzuloggen." original_poster: "Autor des ersten Beitrags" most_posts: "Autor der meisten Beiträge" most_recent_poster: "Autor des jüngsten Beitrags" @@ -1006,6 +1150,9 @@ de: new_topic_moderator_post: one: "Ein Beitrag wurde in ein neues Thema verschoben: %{topic_link}" other: "%{count} Beiträge wurden in ein neues Thema verschoben: %{topic_link}" + existing_topic_moderator_post: + one: "Ein Beitrag wurde in ein neues Thema verschoben: %{topic_link}" + other: "%{count} Beiträge wurden in ein neues Thema verschoben: %{topic_link}" change_owner: post_revision_text: "Eigentümer geändert von %{old_user} zu %{new_user}" deleted_user: "ein gelöschter Benutzer" @@ -1046,7 +1193,7 @@ de: visible_disabled: "Das Thema ist jetzt ungelistet. Es wird nicht mehr in der Themenliste angezeigt. Dieses Thema kann nur mit einem direkten Link erreicht werden." login: not_approved: "Dein Benutzerkonto wurde noch nicht genehmigt. Du wirst per E-Mail benachrichtigt, sobald dies geschehen ist." - incorrect_username_email_or_password: "Benutzername, Mailadresse oder Passwort falsch" + incorrect_username_email_or_password: "Benutzername, E-Mail-Adresse oder Passwort falsch" wait_approval: "Danke fürs Registrieren. Wir werden dich benachrichtigen, sobald dein Benutzerkonto freigeschaltet wurde." active: "Dein Konto ist nun freigeschaltet und einsatzbereit." activate_email: "

    Fast fertig! Eine E-Mail mit einem Aktivierungscode wurde an Deine E-Mail-Adresse %{email} gesendet.
    Dort findest du die Anleitung, um deinen Zugang zu aktivieren.

    Solltest du die Mail nicht vorfinden, kontrolliere bitte auch den Spamverdachts-Ordner. Gegebenenfalls kannst du dir von hier eine weitere Aktivierungs-E-Mail zusenden lassen.

    " @@ -1062,9 +1209,11 @@ de: omniauth_error_unknown: "Während des Anmeldens ist etwas schief gelaufen, bitte versuche es noch einmal." new_registrations_disabled: "Leider können derzeit keine neuen Konten registriert werden." password_too_long: "Passwörter sind beschränkt auf 200 Zeichen." + email_too_long: "Die von dir eingegebene E-Mail-Adresse ist zu lang. E-Mail-Adressen dürfen maximal 254 Zeichen lang sein und Domain-Namen maximal 253 Zeichen." reserved_username: "Der Benutzername ist nicht erlaubt." missing_user_field: "Sie haben nicht alle Benutzerfelder ausgefüllt" close_window: "Authentifizierung abgeschlossen. Schließe das Fenster um fortzufahren." + already_logged_in: "Hoppla, es sieht so aus als ob du versuchst die Einladung für einen anderen Benutzer zu akzeptieren. Wenn du nicht %{current_user} bist, melde dich bitte ab und versuch es erneut." user: no_accounts_associated: "Es sind keine Konten zugeordnet" username: @@ -1073,11 +1222,28 @@ de: characters: "darf nur aus Zahlen und Buchstaben bestehen" unique: "muss eindeutig sein" blank: "muss angegeben werden" + must_not_contain_two_special_chars_in_seq: "muss keine Reihenfolge von 2 oder mehr Sonderzeichen (.-_) haben" + must_not_end_with_confusing_suffix: "Darf nicht mit einem Suffix wie json, png, etc. enden." email: - not_allowed: "ist für diesen Mailprovider nicht erlaubt. Bitte verwende eine andere Mailadresse." + not_allowed: "ist für diesen E-Mail-Provider nicht erlaubt. Bitte verwende eine andere E-Mail-Adresse." blocked: "ist nicht erlaubt." ip_address: - blocked: "Von Deiner IP Adresse aus ist es nicht erlaub sich zu registrieren." + blocked: "Neue Registrierungen sind von deiner IP-Adresse aus nicht erlaubt." + max_new_accounts_per_registration_ip: "Weitere Registrierungen sind von deiner IP-Adresse aus nicht gestattet (limit erreicht). Kontaktiere einen Administrator mit dem Problem damit er dir helfen kann." + flags_reminder: + subject_template: + one: "Eine Markierung wartet auf Bearbeitung" + other: "%{count} Markierungen warten auf Bearbeitung" + unsubscribe_mailer: + subject_template: "Bestätige, dass du nicht länger E-Mail-Updates von %{site_title} erhalten möchtest" + text_body_template: | + Jemand (wahrscheinlich du?) hat angefragt, nicht länger E-Mail-Updates von %{site_domain_name} auf dieser Adresse zu erhalten. + Wenn du nicht länger Benachrichtigungen erhalten möchtest, dann klicke bitte diesen Link: + + %{confirm_unsubscribe_link} + + + Wenn du weiterhin E-Mail-Updates erhalten möchtest, dann kannst du diese E-Mail ignorieren. invite_mailer: subject_template: "%{invitee_name} hat dich zum Thema '%{topic_title}' auf %{site_domain_name} eingeladen" text_body_template: | @@ -1110,26 +1276,32 @@ de: Dies ist eine Einladung von einem vertrauenswürdigen Benutzer. Du brauchst dich daher nicht anzumelden. invite_password_instructions: subject_template: "Lege ein Passwort für dein %{site_name}-Konto fest" + text_body_template: | + Schön, dass du die Einladung zu %{site_name} angenommen hast -- Willkommen! + + Klicke hier um jetzt dein Passwort festzulegen: + %{base_url}/users/password-reset/%{email_token} + + (Wenn der Link abgelaufen ist, wähle "Passwort vergessen" aus, wenn du dich mit deiner E-Mail-Adresse einloggen möchtest.) test_mailer: - subject_template: "[%{site_name}] Test der Mailzustellbarkeit" + subject_template: "[%{site_name}] Test der E-Mail-Zustellbarkeit" new_version_mailer: subject_template: "[%{site_name}] Neue Discourse Version, Update verfügbar" new_version_mailer_with_notes: subject_template: "[%{site_name}] Update verfügbar" - flags_reminder: - flags_were_submitted: - one: "Folgende Markierungen wurden währen der letzten Stunden vorgenommen." - other: "Folgende Markierungen wurden währen der letzten %{count} Stunden vorgenommen." - please_review: "Bitte überprüfe sie." - post_number: "Beitrag" - how_to_disable: 'Die Benachrichtungen für markierte Beiträge kann deaktiviert oder in ihrer Häufigkeit geändert werden mittels des Wertes unter "notify about flags after".' + queued_posts_reminder: subject_template: - one: "Eine Markierung wartet auf Bearbeitung" - other: "%{count} Markierungen warten auf Bearbeitung" + one: "[%{site_name}] %{count} auf Freischaltung wartender Beitrag." + other: "[%{site_name}] %{count} auf Freischaltung wartende Beiträge." + text_body_template: | + Hallo, + + es gibt ein paar Beiträge von Nutzern, welche auf deine Freischaltung warten. + [Du kannst sie hier Freischalten oder Ablehnen](%{base_url}/queued-posts). flag_reasons: off_topic: "Dein Beitrag wurde als **Thema verfehlt** gemeldet: Die Community glaubt, dass er nicht zum Thema passt, wie es durch den Titel und den ersten Beitrag definiert wurde." inappropriate: "Dein Beitrag wurde als **unangemessen** gemeldet: die Community glaubt, dass er anstößig oder beleidigend ist oder einen Verstoß gegen [die Community Richtlinien](/guidelines) darstellt." - spam: "Dein Beitrag wurde als **Spam** geflaggt: Die Community denkt, dass es sich um Werbung handelt und nicht nützlich oder für das Diskussionsthema relevant ist." + spam: "Dein Beitrag wurde als **Spam** gemeldet: Die Community denkt, dass es sich um Werbung handelt, zu werblich in seiner Art und nicht nützlich oder für das Diskussionsthema relevant ist." notify_moderators: "Die Community denkt, dass etwas an deinem Beitrag das Eingreifen eines Moderator erfordert." flags_dispositions: agreed: "Danke, dass du uns Bescheid gegeben hast. Wir sind auch der Meinung, dass es ein Problem gibt und sehen uns das an." @@ -1137,9 +1309,24 @@ de: disagreed: "Danke für deine Meldung. Wir sehen uns das an." deferred: "Danke für deine Meldung. Wir sehen uns das an." deferred_and_deleted: "Danke für deine Meldung. Wir haben den Beitrag entfernt." + temporarily_closed_due_to_flags: "Dieses Thema ist vorrübergehend geschlossen. Mehrere User haben dieses Thema gemeldet. " system_messages: post_hidden: subject_template: "Beitrag wegen Meldungen aus der Community versteckt" + text_body_template: | + Hallo, + + dies ist eine automatische Nachricht von %{site_name}, um dich darüber zu informieren, dass dein Beitrag verborgen worden ist. + + %{base_url}%{url} + + %{flag_reason} + + Mehrere Mitglieder der Gemeinschaft haben deinen Beitrag gemeldet, bevor er verborgen wurde. Du solltest also deinen Beitrag gemäß deren Rückmeldungen überarbeiten. **Du kannst deinen Beitrag nach %{edit_delay} Minuten ändern; danach wird er automatisch wieder erscheinen.** + + Falls dein Beitrag jedoch ein weiteres Mal von der Gemeinschaft gemeldet und verborgen wird, bleibt der Beitrag verborgen, bis ein Mitglied des Teams dies ändert – in diesem Fall können auch weitere Konsequenzen folgen, bis hin zu einer möglichen Sperrung deines Accounts. + + Für weitere Orientierungshilfe wirf bitte einen Blick in unsere [Community-Richtlinien](%{base_url}/guidelines). welcome_user: subject_template: "Willkommen bei %{site_name}!" text_body_template: | @@ -1176,6 +1363,7 @@ de: [prefs]: %{user_preferences_url} backup_succeeded: subject_template: "Sicherung erfolgreich abgeschlossen" + text_body_template: "Backup erfolgreich erstellt.\nBesuche [admin > backup section](%{base_url}/admin/backups) um das neue Backup herunterzuladen." backup_failed: subject_template: "Sicherung fehlgeschlagen" text_body_template: | @@ -1201,7 +1389,7 @@ de: ``` bulk_invite_succeeded: subject_template: "Masseneinladung von Benutzern erfolgreich verarbeitet" - text_body_template: "Deine Masseneinladung von Benutzern wurde erfolgreich verarbeitet, insgesamt wurden %{sent} Einladungen E-per Mail verschickt." + text_body_template: "Deine Masseneinladung von Benutzern wurde erfolgreich verarbeitet, insgesamt wurden %{sent} Einladungen per E-Mail verschickt." bulk_invite_failed: subject_template: "Bei der Verarbeitung der Masseneinladung von Benutzern sind Fehler aufgetreten" text_body_template: | @@ -1223,67 +1411,82 @@ de: csv_export_failed: subject_template: "Datenexport fehlgeschlagen" text_body_template: "Entschuldigung, beim Exportieren deiner Daten trat ein Fehler auf. Bitte kontaktiere einen Mitarbeiter oder sieh in die Logs." - email_reject_trust_level: - subject_template: "[%{site_name}] E-Mail-Problem -- Ungenügende Vertrauensstufe" + email_reject_insufficient_trust_level: + subject_template: "[%{site_name}] E-Mail-Problem -- Unzureichende Vertrauensstufe" text_body_template: | - Es tut uns leid, aber deine E-Mail-Nachricht an %{destination} (Titel: %{former_title}) hat nicht funktioniert. + Es tut uns leid, aber das Senden deiner E-Mail-Nachricht an %{destination} (betitelt mit %{former_title}) hat nicht funktioniert. - Du hast nicht die notwendige Vertrauensstufe, um neue Themen über diese E-Mail-Adresse zu erstellen. Wenn du glaubst, dass das ein Irrtum ist, dann kontaktiere einen Mitarbeiter. + Dein Benutzerkonto hat nicht die benötigte Vertrauensstufe, um neue Themen an diese E-Mail-Adresse zu senden. Wenn du glaubst, dass dies ein Fehler ist, dann kontaktiere bitte einen Mitarbeiter. + email_reject_inactive_user: + subject_template: "[%{site_name}] E-Mail-Problem -- Inaktiver Nutzer" + text_body_template: | + Es tut uns leid, aber das Senden deiner E-Mail-Nachricht an %{destination} (betitelt mit %{former_title}) hat nicht funktioniert. + + Dein mit dieser E-Mail-Adresse assoziiertes Benutzerkonto ist nicht aktiviert. Bitte aktiviere dein Konto bevor du E-Mails sendest. + email_reject_reply_user_not_matching: + subject_template: "[%{site_name}] E-Mail-Problem -- Antwortender Nutzer stimmt nicht überein" + text_body_template: | + Es tut uns leid, aber deine E-Mail-Nachricht an %{destination} (mit dem Titel %{former_title}) hat nicht funktioniert. + + Deine Antwort wurde von einer anderen E-Mail-Adresse versandt als wir erwartet haben, weshalb wir nicht sicher wissen ob das die gleiche Person ist. Probiere eine andere Absende-Adresse oder wende dich an einen Mitarbeiter. email_reject_no_account: subject_template: "[%{site_name}] E-Mail-Problem -- Unbekanntes Konto" text_body_template: | - Es tut uns leid, aber deine E-Mail-Nachricht an %{destination} (Titel: %{former_title}) konnte nicht verarbeitet werden! + Es tut uns leid, aber deine E-Mail-Nachricht an %{destination} (mit dem Titel %{former_title}) hat nicht funktioniert. - Es ist kein Konto mit dieser E-Mail-Adresse bekannt. Versuche die Nachricht von einer anderen, im Forum registrierten E-Mail-Adresse zu verschicken oder kontaktiere einen Mitarbeiter. + Wir konnten keinen Account finden, der zu deiner E-Mail-Adresse passt. Probiere eine andere Absende-Adresse oder wende dich an einen Mitarbeiter. email_reject_empty: subject_template: "[%{site_name}] E-Mail-Problem -- Kein Inhalt" + text_body_template: | + Tut uns leid, aber deine E-Mail an %{destination} mit dem Betreff (titled %{former_title}) hat nicht funktioniert. + + Wir haben in deiner E-Mail keinen Inhalt feststellen können. + + Wenn du diese E-Mail bekommst, obwohl deine E-Mail Inhalt enthalten hat, versuche es erneut mit weniger Formatierung. email_reject_parsing: subject_template: "[%{site_name}] E-Mail-Problem -- Inhalt nicht erkannt" + text_body_template: | + Entschuldigung, aber deine E-Mail-Nachricht an %{destination} mit dem Titel (titled %{former_title}) konnte nicht zugestellt werden. + + Wir konnten keinen Inhalt in deiner E-Mail feststellen. **Versichere dich, dass du den Inhalt oberhalb der erhaltenen E-Mail eingegeben hast** -- Eingebettete Antworten können wir nicht verarbeiten. email_reject_invalid_access: subject_template: "[%{site_name}] E-Mail-Problem -- Nicht erlaubt" text_body_template: | Es tut uns leid, aber deine E-Mail-Nachricht an %{destination} (Titel: %{former_title}) hat nicht funktioniert. Dein Nutzerkonto verfügt nicht über die nötigen Rechte, um in dieser Kategorie ein neues Thema anzulegen. Wenn du glaubst, dass dies ein Irrtum ist, nimm bitte Kontakt mit einem unserer Mitarbeiter auf. - email_reject_post_error: - subject_template: "[%{site_name}] E-Mail-Problem -- Fehler beim Posten" + email_reject_strangers_not_allowed: + subject_template: "[%{site_name}] E-Mail-Problem -- Zugriff nicht erlaubt" text_body_template: | - Es tut uns leid, aber deine E-Mail-Nachricht an %{destination} (Titel: %{former_title}) hat nicht funktioniert. + Es tut uns leid, aber deine E-Mail-Nachricht an %{destination} (mit dem Titel %{former_title}) hat nicht funktioniert. - Mögliche Gründe sind: komplexe Formatierung, Nachricht zu lang oder zu kurz. Bitte versuche es erneut oder erstelle deinen Beitrag auf der Website, wenn der Fehler weiterhin auftritt. - email_reject_post_error_specified: - subject_template: "[%{site_name}] E-Mail-Problem -- Fehler beim Posten" + Die Kategorie, an die du diese E-Mail gesendet hast, erlaubt nur Antworten von Nutzern mit gültigem Konto und bekannter E-Mail-Adresse. Wenn du glaubst, dass dies ein Fehler ist, wende dich bitte an einen Mitarbeiter. + email_reject_invalid_post: + subject_template: "[%{site_name}] E-Mail-Problem -- Ungültiger Beitrag" text_body_template: | - Es tut uns leid, aber deine E-Mail-Nachricht an %{destination} (Titel: %{former_title}) hat nicht funktioniert. + Es tut uns leid, aber deine E-Mail-Nachricht an %{destination} (mit dem Titel %{former_title}) hat nicht funktioniert. - Grund: - - %{post_error} - - Bitte versuch es erneut, wenn du das Problem beheben kannst. + Mögliche Gründe sind komplizierte Formatierung und zu lange oder kurze Nachrichten. Bitte versuche es erneut oder schreibe deinen Beitrag über die Website. + email_reject_invalid_post_specified: + subject_template: "[%{site_name}] E-Mail-Problem -- Ungültiger Beitrag" email_reject_reply_key: subject_template: "[%{site_name}] E-Mail-Problem -- Unbekannter Antwort-Schlüssel" - text_body_template: | - Es tut uns leid, aber die E-Mail-Nachricht an %{destination} (Titel: „%{former_title}“) hat nicht geklappt. - Der angegebene Antwort-Schlüssel ist ungültig oder unbekannt. Wir wissen daher nicht auf welchen Beitrag diese E-Mail antwortet. Kontaktiere einen Mitarbeiter. - email_reject_destination: - subject_template: "[%{site_name}] E-Mail Problem -- Unbekannte An:-Adresse" + email_reject_topic_not_found: + subject_template: "[%{site_name}] E-Mail Problem -- Thema nicht gefunden" text_body_template: | Entschuldigung, aber mit deiner E-Mail-Nachricht an %{destination} (Titel: %{former_title}) gab es ein Problem. - Keine der Empfänger-Adressen ist uns bekannt. Bitte stelle sicher, dass die Ziel-Adresse in einer "An:" Zeile steht (nicht "Cc:" oder "Bcc:") und dass du die E-Mail an die richtige Adresse schickst, die dir von unseren Mitarbeitern genannt wurde. - email_reject_topic_not_found: - subject_template: "[%{site_name}] E-Mail Problem -- Thema nicht gefunden" + Das Thema existiert nicht mehr -- vielleicht wurde es gelöscht? Wenn du glaubst, dass dies ein Irrtum ist, nimm bitte Kontakt mit einem unserer Mitarbeiter auf. email_reject_topic_closed: subject_template: "[%{site_name}] E-Mail Problem -- Thema geschlossen" + text_body_template: | + Entschuldigung, aber mit deiner E-Mail-Nachricht an %{destination} (Titel: %{former_title}) gab es ein Problem. + + Das Thema ist uns nicht bekannt oder es wurde gelöscht bzw. geschlossen. Wenn du glaubst, dass dies ein Irrtum ist, nimm bitte Kontakt mit einem unserer Mitarbeiter auf. email_reject_auto_generated: - subject_template: "[%{site_name}] E-Mail Problem -- Automatisch erzeugte Antwort" + subject_template: "[%{site_name}] E-Mail-Problem -- Automatisch erzeugte Antwort" email_error_notification: subject_template: "[%{site_name}] E-Mail-Problem -- POP-Authentifizierungsfehler" - text_body_template: | - Es gab einen Authentifizierungsfehler beim Abrufen von Mails vom POP-Server. - - Bitte stelle sicher, dass du die POP-Zugangsdaten in [den Seiteneinstellungen](%{base_url}/admin/site_settings/category/email) korrekt konfiguriert hast. too_many_spam_flags: subject_template: "Neues Benutzerkonto gesperrt" text_body_template: | @@ -1296,32 +1499,10 @@ de: Weitere Hilfe findest du in unserer [Richtlinien](%{base_url}/guidelines). blocked_by_staff: subject_template: "Benutzerkonto gesperrt" - text_body_template: | - Hallo, - - dies ist eine automatisch erzeugte Nachricht von %{site_name}, um dich darüber zu informieren, dass dein Benutzerkonto durch einen Mitarbeiter gesperrt wurde. - - Weitere Informationen hierzu findest du in unseren [Richtlinien](%{base_url}/guidelines). user_automatically_blocked: subject_template: "Neuer Benutzer %{username} wegen Gemeinschaftsrichtlinien blockiert." - text_body_template: | - Dies ist eine automatische Nachricht. - - Der neue Benutzer [%{username}](%{base_url}%{user_url}) wurde automatisch gesperrt, da mehrere Benutzer die Beiträge von %{username} gemeldet haben. - - Bitte [überprüfe die Meldungen](%{base_url}/admin/flags). Falls %{username} fälschlicherweise gesperrt wurde, drücke den 'Entsperren'-Knopf auf der [Administrationsseite für den Benutzer](%{base_url}%{user_url}). - - Der Schwellwert kann über die Seiteneinstellung `block_new_user` angepasst werden. spam_post_blocked: subject_template: "Beiträge des neuen Benutzers ${username} wegen mehrfacher Verlinkung blockiert" - text_body_template: | - Dies ist eine automatische Nachricht. - - Der neue Benutzer [%{username}](%{base_url}%{user_url}) hat versucht mehrere Beiträge mit Links zu %{domains} zu erstellen. Diese Beiträge wurden aber blockiert, um Spam zu vermeiden. Der Benutzer kann immer noch neue Beiträge erstellen, die nicht auf %{domains} verlinken. - - Bitte [überprüfe den Benutzer](%{base_url}%{user_url}). - - Dieses Verhalten kann durch die Seiteneinstellungen `newuser_spam_host_threshold` und `white_listed_spam_host_domains` geändert werden. unblocked: subject_template: "Blockierung des Kontos aufgehoben" text_body_template: | @@ -1341,91 +1522,32 @@ de: download_remote_images_disabled: subject_template: "Download von externen Bildern deaktiviert" text_body_template: "Die `download_remote_images_to_local` Einstellung wurde deaktiviert, da das Speicherplatz Limit von `download_remote_images_threshold` erreicht wurde." + unsubscribe_link: | + Um keine Benachrichtigungen mehr zu diesem Thema zu erhalten, bitte [hier klicken](%{unsubscribe_url}). Du kannst den Empfang von Benachrichtigungen per E-Mail auch in deinen [Profil-Eigenschaften](%{user_preferences_url}) deaktivieren + unsubscribe_via_email_link: | + oder [hier klicken](mailto:reply@%{hostname}?subject=unsubscribe) um per E-Mail abzubestellen. subject_re: "Re: " subject_pm: "[PN]" user_notifications: previous_discussion: "Vorangehende Antworten" unsubscribe: - title: "Mails Abbestellen" - description: "Nicht interessiert an diesen Mails? Kein Problem! Klicke unten um Dich abzumelden:" - reply_by_email: "Um zu Antworten, antworte auf diese Email oder besuche %{base_url}%{url} in deinem Browser." - visit_link_to_respond: "Um zu Antworten, besuche %{base_url}%{url} in deinem Browser." + title: "Abbestellen" + description: "Nicht interessiert an diesen E.Mails? Kein Problem! Klicke unten um dich abzumelden:" posted_by: "Erstellt von %{username} am %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} hat dich zur Unterhaltung '%{topic_title}' eingeladen" - text_body_template: |2 - - %{username} hat dich zur Unterhaltung - - > **%{topic_title}** - > - > %{topic_excerpt} - - bei - - > %{site_title} -- %{site_description} - - eingeladen. Bitte besuche diesen Link um die Unterhaltung zu lesen: %{base_url}%{url} - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} hat dich zum Thema '%{topic_title}' eingeladen" - text_body_template: |2 - - %{username} hat dich zum Thema - - > **%{topic_title}** - > - > %{topic_excerpt} - - bei - - > %{site_title} -- %{site_description} - - eingeladen. Bitte besuche diesen Link um das Thema zu lesen: %{base_url}%{url} user_replied: subject_template: "[%{site_name}] %{username} hat auf deinen Beitrag '%{topic_title}' geantwortet" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{username} hat Dich in '%{topic_title}' zitiert" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{username} hat Dich in '%{topic_title}' erwähnt" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" user_posted: subject_template: "[%{site_name}] %{subject_prefix}%{username} hat auf '%{topic_title}' geantwortet" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "Eine kurze Zusammenfassung von %{site_link} seit deinem letzten Besuch am %{last_seen_at}" subject_template: "[%{site_name}] Übersicht" @@ -1458,6 +1580,11 @@ de: %{base_url}/users/password-reset/%{email_token} admin_login: subject_template: "[%{site_name}] Anmeldung" + text_body_template: | + Jemand hat versucht sich in deinen Account auf [%{site_name}](%{base_url}) einzuloggen. + Wenn dieser Loginversuch nicht von dir stammt, kannst du diese E-Mail ignorieren. + Klicke hier, um dich einzuloggen: + %{base_url}/users/admin-login/%{email_token} account_created: subject_template: "[%{site_name}] Dein neues Konto" text_body_template: | @@ -1465,12 +1592,6 @@ de: Klicke auf den folgenden Link, um ein Passwort für dein neues Konto festzulegen: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Bestätige deine neue Mailadresse" - text_body_template: | - Um deine Mailadresse auf %{site_name} zu bestätigen, klicke auf den folgenden Link: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "You've been approved on %{site_name}!" text_body_template: | @@ -1491,6 +1612,7 @@ de: (Wenn du als neuer Benutzer unter vier Augen mit einem unserer [Mitarbeiter](%{base_url}/about) reden möchtest, antworte einfach auf diese Nachricht.) signup: + subject_template: "[%{site_name}] Bestätige deinen neuen Account" text_body_template: | Willkommen bei %{site_name}! @@ -1499,7 +1621,6 @@ de: Wenn dieser Link nicht klickbar ist, kopiere ihn in die Adresszeile deines Web-Browsers. page_not_found: - title: "Die angeforderte Seite existiert nicht oder ist privat." popular_topics: "Beliebt" recent_topics: "Aktuell" see_more: "Mehr" @@ -1518,6 +1639,7 @@ de: unauthorized: "Entschuldigung, die Datei die du hochladen möchtest ist nicht erlaubt (erlaubte Dateiendungen sind: %{authorized_extensions})." pasted_image_filename: "Hinzugefügtes Bild" store_failure: "Hochladen von #%{upload_id} für Benutzer #%{user_id} ist fehlgeschlagen." + file_missing: "Bitte wähle eine Datei zum Hochladen aus. " attachments: too_large: "Entschuldigung, die Datei die du hochladen möchtest, ist zu groß (maximale Dateigröße ist %{max_size_kb}KB)." images: @@ -1532,11 +1654,12 @@ de: suspended_not_pm: "Benutzer ist gesperrt, keine Nachricht" seen_recently: "Benutzer war kürzlich online" post_not_found: "Kann Beitrag mit ID %{post_id} nicht finden" - notification_already_read: "Die Benachrichtigung dieser Mail wurde bereits gelesen" + notification_already_read: "Die Benachrichtigung zu dieser E-Mail wurde bereits gelesen" topic_nil: "post.topic is nil" post_deleted: "Beitrag wurde vom Autor entfernt" user_suspended: "Benutzer wurde gesperrt" already_read: "Benutzer hat diesen Beitrag bereits gelesen" + exceeded_limit: "max_emails_per_day_per_user überschritten" message_blank: "Nachricht ist leer" message_to_blank: "message.to ist leer" text_part_body_blank: "text_part.body ist leer" @@ -1558,8 +1681,29 @@ de: title: "Nutzungsbedingungen" privacy_topic: title: "Datenschutzrichtlinie" + badges: + basic_user: + description: Ermöglicht das Nutzen aller wesentlichen Community-Funktionen + member: + description: Ermöglicht das Versenden von Einladungen, Gruppen-Nachrichten, mehr Likes + regular: + description: Ermöglicht verschieben und umbenennen von Themen, veröffentlichen verfolgbarer Links, Aktivierung der Wiki-Funktion, mehr Likes + leader: + description: Ermöglicht bearbeiten aller Beiträge, anheften, schließen, archivieren, aufteilen und zusammenfügen von Themen, mehr Likes admin_login: success: "E-Mail gesendet" error: "Fehler!" email_input: "Administrator-E-Mail" submit_button: "E-Mail senden" + discourse_hub: + access_token_problem: "Gib das hier an einen Administrator weiter: Bitte aktualisieren Sie die Seiteneinstellungen für den korrekten discourse_org_access_key." + performance_report: + initial_post_raw: Dieser Beitrag enthält tägliche performance Berichte deiner Seite. + initial_topic_title: Berichte zur Webseitengeschwindigkeit + topic_invite: + user_exists: "Entschuldige, dieser Benutzer ist bereits eingeladen worden. Du kannst einen Nutzer nur einmal zu einem Thema einladen." + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index dfad400495d..596f22cf024 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -20,17 +20,21 @@ en: short_date: "D MMM, YYYY" long_date: "MMMM D, YYYY h:mma" - datetime: &datetime - month_names: - [~, January, February, March, April, May, June, July, August, September, October, November, December] + datetime_formats: &datetime_formats formats: + # Format directives: http://ruby-doc.org/core-2.2.0/Time.html#method-i-strftime short: "%m-%d-%Y" + # Format directives: http://ruby-doc.org/core-2.2.0/Time.html#method-i-strftime short_no_year: "%B %-d" + # Format directives: http://ruby-doc.org/core-2.2.0/Time.html#method-i-strftime date_only: "%B %-d, %Y" date: - <<: *datetime + # Do not remove the brackets and commas and do not translate the first month name. It should be "null". + month_names: + [~, January, February, March, April, May, June, July, August, September, October, November, December] + <<: *datetime_formats time: - <<: *datetime + <<: *datetime_formats title: "Discourse" topics: "Topics" @@ -39,13 +43,28 @@ en: powered_by_html: 'Powered by Discourse, best viewed with JavaScript enabled' log_in: "Log In" - via: "%{username} via %{site_name}" - is_reserved: "is reserved" - purge_reason: "Automatically deleted as abandoned, unactivated account" disable_remote_images_download_reason: "Remote images download was disabled because there wasn't enough disk space available." anonymous: "Anonymous" + emails: + incoming: + default_subject: "Incoming email from %{email}" + show_trimmed_content: "Show trimmed content" + errors: + empty_email_error: "Happens when the raw mail we received was blank." + no_message_id_error: "Happens when the mail has no 'Message-Id' header." + auto_generated_email_error: "Happens when the 'precedence' header is set to: list, junk, bulk or auto_reply, or when any other header contains: auto-submitted, auto-replied or auto-generated." + no_body_detected_error: "Happens when we couldn't extract a body and there was no attachments." + inactive_user_error: "Happens when the sender is not active." + blocked_user_error: "Happens when the sender has been blocked." + bad_destination_address: "Happens when none of the email addresses in To/Cc/Bcc fields matched a configured incoming email address." + strangers_not_allowed_error: "Happens when a user tried to create a new topic in a category they're not a member of." + insufficient_trust_level_error: "Happens when a user tried to create a new topic in a category they don't have the required trust level for." + reply_user_not_matching_error: "Happens when a reply came in from a different email address the notification was sent to." + topic_not_found_error: "Happens when a reply came in but the related topic has been deleted." + topic_closed_error: "Happens when a reply came in but the related topic has been closed." + errors: &errors format: ! '%{attribute} %{message}' messages: @@ -62,8 +81,10 @@ en: exclusion: is reserved greater_than: must be greater than %{count} greater_than_or_equal_to: must be greater than or equal to %{count} + has_already_been_used: "has already been used" inclusion: is not included in the list invalid: is invalid + is_invalid: "is invalid; try to be a little more descriptive" less_than: must be less than %{count} less_than_or_equal_to: must be less than or equal to %{count} not_a_number: is not a number @@ -101,9 +122,6 @@ en: activemodel: errors: <<: *errors - activerecord: - errors: - <<: *errors bulk_invite: file_should_be_csv: "The uploaded file should be of csv or txt format." @@ -118,6 +136,9 @@ en: invalid_access: "You are not permitted to view the requested resource." read_only_mode_enabled: "The site is in read only mode. Interactions are disabled." + reading_time: "Reading time" + likes: "Likes" + too_many_replies: one: "We're sorry, but new users are temporarily limited to 1 reply in the same topic." other: "We're sorry, but new users are temporarily limited to %{count} replies in the same topic." @@ -137,26 +158,27 @@ en: one: "1 reply" other: "%{count} replies" + no_mentions_allowed: "Sorry, you can't mention other users." too_many_mentions: - zero: "Sorry, you can't mention other users." one: "Sorry, you can only mention one other user in a post." other: "Sorry, you can only mention %{count} users in a post." + no_mentions_allowed_newuser: "Sorry, new users can't mention other users." too_many_mentions_newuser: - zero: "Sorry, new users can't mention other users." one: "Sorry, new users can only mention one other user in a post." other: "Sorry, new users can only mention %{count} users in a post." + no_images_allowed: "Sorry, new users can't put images in posts." too_many_images: - zero: "Sorry, new users can't put images in posts." one: "Sorry, new users can only put one image in a post." other: "Sorry, new users can only put %{count} images in a post." + no_attachments_allowed: "Sorry, new users can't put attachments in posts." too_many_attachments: - zero: "Sorry, new users can't put attachments in posts." one: "Sorry, new users can only put one attachment in a post." other: "Sorry, new users can only put %{count} attachments in a post." + no_links_allowed: "Sorry, new users can't put links in posts." too_many_links: - zero: "Sorry, new users can't put links in posts." one: "Sorry, new users can only put one link in a post." other: "Sorry, new users can only put %{count} links in a post." + spamming_host: "Sorry you cannot post a link to that host." user_is_suspended: "Suspended users are not allowed to post." topic_not_found: "Something has gone wrong. Perhaps this topic was closed or deleted while you were looking at it?" @@ -180,8 +202,15 @@ en: rss_description: latest: "Latest topics" hot: "Hot topics" + top: "Top topics" posts: "Latest posts" + private_posts: "Latest private messages" + group_posts: "Latest posts from %{group_name}" + group_mentions: "Latest mentions from %{group_name}" + user_posts: "Latest posts by @%{username}" + user_topics: "Latest topics by @%{username}" too_late_to_edit: "That post was created too long ago. It can no longer be edited or deleted." + revert_version_same: "The current version is same as the version you are trying to revert to." excerpt_image: "image" @@ -192,6 +221,10 @@ en: errors: can_not_modify_automatic: "You can not modify an automatic group" member_already_exist: "'%{username}' is already a member of this group." + invalid_domain: "'%{domain}' is not a valid domain." + invalid_incoming_email: "'%{email}' is not a valid email address." + email_already_used_in_group: "'%{email}' is already used by the group '%{group_name}'." + email_already_used_in_category: "'%{email}' is already used by the category '%{category_name}'." default_names: everyone: "everyone" admins: "admins" @@ -280,9 +313,7 @@ en: user: ip_address: "" errors: - messages: - is_invalid: "is invalid; try to be a little more descriptive" - has_already_been_used: "has already been used" + <<: *errors models: topic: attributes: @@ -346,13 +377,15 @@ en: category: topic_prefix: "About the %{category} category" - replace_paragraph: "[Replace this first paragraph with a short description of your new category. This guidance will appear in the category selection area, so try to keep it below 200 characters. Until you edit this text or create topics, this category won't appear on the categories page.]" - post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, as well as to establish any category guidelines or rules.\n\nSome things to consider in any discussion replies below:\n\n- What is this category for? Why should people select this category for their topic?\n\n- How is this different than the other categories we already have?\n\n- Do we need this category?\n\n- Should we merge this with another category, or split it into more categories?\n" + replace_paragraph: "(Replace this first paragraph with a brief description of your new category. This guidance will appear in the category selection area, so try to keep it below 200 characters. **Until you edit this description or create topics, this category won't appear on the categories page.**)" + post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, or to establish category guidelines or rules:\n\n- Why should people use this category? What is it for?\n\n- How exactly is this different than the other categories we already have?\n\n- What should topics in this category generally contain?\n\n- Do we need this category? Can we merge with another category, or subcategory?\n" errors: uncategorized_parent: "Uncategorized can't have a parent category" self_parent: "A subcategory's parent cannot be itself" depth: "You can't nest a subcategory under another" - email_in_already_exist: "Incoming email address '%{email_in}' is already in use for '%{category_name}' category." + invalid_email_in: "'%{email}' is not a valid email address." + email_already_used_in_group: "'%{email}' is already used by the group '%{group_name}'." + email_already_used_in_category: "'%{email}' is already used by the category '%{category_name}'." cannot_delete: uncategorized: "Can't delete Uncategorized" has_subcategories: "Can't delete this category because it has sub-categories." @@ -360,23 +393,39 @@ en: one: "Can't delete this category because is has 1 topic. Oldest topic is %{topic_link}." other: "Can't delete this category because it has %{count} topics. Oldest topic is %{topic_link}." topic_exists_no_oldest: "Can't delete this category because topic count is %{count}." + uncategorized_description: "Topics that don't need a category, or don't fit into any other existing category." trust_levels: newuser: title: "new user" basic: title: "basic user" - regular: + member: title: "member" - leader: + regular: title: "regular" - elder: + leader: title: "leader" change_failed_explanation: "You attempted to demote %{user_name} to '%{new_trust_level}'. However their trust level is already '%{current_trust_level}'. %{user_name} will remain at '%{current_trust_level}' - if you wish to demote user lock trust level first" rate_limiter: - slow_down: "You have performed this action too many times, try again later" + slow_down: "You have performed this action too many times, try again later." too_many_requests: "We have a daily limit on how many times that action can be taken. Please wait %{time_left} before trying again." + by_type: + first_day_replies_per_day: "You've reached the maximum number of replies a new user can create on their first day. Please wait %{time_left} before trying again." + first_day_topics_per_day: "You've reached the maximum number of topics a new user can create on their first day. Please wait %{time_left} before trying again." + create_topic: "You're creating topics too quickly. Please wait %{time_left} before trying again." + create_post: "You're replying too quickly. Please wait %{time_left} before trying again." + delete_post: "You're deleting posts too quickly. Please wait %{time_left} before trying again." + topics_per_day: "You've reached the maximum number of new topics today. Please wait %{time_left} before trying again." + pms_per_day: "You've reached the maximum number of messages today. Please wait %{time_left} before trying again." + create_like: "You've reached the maximum number of likes today. Please wait %{time_left} before trying again." + create_bookmark: "You've reached the maximum number of bookmarks today. Please wait %{time_left} before trying again." + edit_post: "You've reached the maximun number of edits today. Please wait %{time_left} before trying again." + live_post_counts: "You've asking for live post counts too quickly. Please wait %{time_left} before trying again." + unsubscribe_via_email: "You've reached the maximum number of unsubscribe via email today. Please wait %{time_left} before trying again." + topic_invitations_per_day: "You've reached the maximum number of topic invitations today. Please wait %{time_left} before trying again." + hours: one: "1 hour" other: "%{count} hours" @@ -475,6 +524,11 @@ en: confirmed: "Your email has been updated." please_continue: "Continue to %{site_name}" error: "There was an error changing your email address. Perhaps the address is already in use?" + error_staged: "There was an error changing your email address. The address is already in use by a staged user." + already_done: "Sorry, this confirmation link is no longer valid. Perhaps your email was already changed?" + authorizing_old: + title: "Thanks for confirming your current email address" + description: "We're now emailing your new address for confirmation." activation: action: "Click here to activate your account" @@ -500,16 +554,16 @@ en: description: 'This post contains content that a reasonable person would consider offensive, abusive, or a violation of our community guidelines.' long_form: 'flagged this as inappropriate' notify_user: - title: 'Message @{{username}}' - description: 'This post contains something I want to talk to this person directly and privately about. Does not cast a flag.' + title: 'Send @{{username}} a message' + description: 'I want to talk to this person directly and privately about their post.' long_form: 'messaged user' email_title: 'Your post in "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Something Else" - description: 'This post requires moderator attention for another reason not listed above.' - long_form: 'flagged this for moderator attention' - email_title: 'A post in "%{title}" requires moderator attention' + description: 'This post requires staff attention for another reason not listed above.' + long_form: 'flagged this for staff attention' + email_title: 'A post in "%{title}" requires staff attention' email_body: "%{link}\n\n%{message}" bookmark: title: 'Bookmark' @@ -535,7 +589,7 @@ en: long_form: 'flagged this as inappropriate' notify_moderators: title: "Something Else" - description: 'This topic requires general moderator attention based on the guidelines, TOS, or for another reason not listed above.' + description: 'This topic requires general staff attention based on the guidelines, TOS, or for another reason not listed above.' long_form: 'flagged this for moderator attention' email_title: 'The topic "%{title}" requires moderator attention' email_body: "%{link}\n\n%{message}" @@ -576,6 +630,10 @@ en: title: "New Users" xaxis: "Day" yaxis: "Number of new users" + profile_views: + title: "User Profile Views" + xaxis: "Day" + yaxis: "Number of user profiles viewed" topics: title: "Topics" xaxis: "Day" @@ -728,44 +786,17 @@ en: consumer_email_warning: "Your site is configured to use Gmail (or another consumer email service) to send email. Gmail limits how many emails you can send. Consider using an email service provider like mandrill.com to ensure email deliverability." site_contact_username_warning: "Enter the name of a friendly staff user account to send important automated messages from. Update site_contact_username in Site Settings." notification_email_warning: "Notification emails are not being sent from a valid email address on your domain; email delivery will be erratic and unreliable. Please set notification_email to a valid local email address in Site Settings." - - content_types: - education_new_reply: - title: "New User Education: First Replies" - description: "Pop up just-in-time guidance automatically displayed above the composer when new users begin typing their first two new replies." - education_new_topic: - title: "New User Education: First Topics" - description: "Pop up just-in-time guidance automatically displayed above the composer when new users begin typing their first two new topics." - usage_tips: - title: "New User Guidance" - description: "Guidance and essential information for new users." - welcome_user: - title: "Welcome: New User" - description: "A message automatically sent to all new users when they sign up." - welcome_invite: - title: "Welcome: Invited User" - description: "A message automatically sent to all new invited users when they accept the invitation from another user to participate." - login_required_welcome_message: - title: "Login Required: Welcome Message" - description: "Welcome message that is displayed to logged out users when the 'login required' setting is enabled." - login_required: - title: "Login Required: Homepage" - description: "The text displayed for unauthorized users when login is required on the site." - head: - title: "HTML head" - description: "HTML that will be inserted inside the tags." - top: - title: "Top of the pages" - description: "HTML that will be added at the top of every page (after the header, before the navigation or the topic title)." - bottom: - title: "Bottom of the pages" - description: "HTML that will be added before the tag." + subfolder_ends_in_slash: "Your subfolder setup is incorrect; the DISCOURSE_RELATIVE_URL_ROOT ends in a slash." + email_polling_errored_recently: + one: "Email polling has generated an error in the past 24 hours. Look at the logs for more details." + other: "Email polling has generated %{count} errors in the past 24 hours. Look at the logs for more details." site_settings: censored_words: "Words that will be automatically replaced with ■■■■" delete_old_hidden_posts: "Auto-delete any hidden posts that stay hidden for more than 30 days." default_locale: "The default language of this Discourse instance (ISO 639-1 Code)" allow_user_locale: "Allow users to choose their own language interface preference" + set_locale_from_accept_language_header: "set interface language for anonymous users from their web browser's language headers. (EXPERIMENTAL, does not work with anonymous cache)" min_post_length: "Minimum allowed post length in characters" min_first_post_length: "Minimum allowed first post (topic body) length in characters" min_private_message_post_length: "Minimum allowed post length in characters for messages" @@ -774,8 +805,8 @@ en: max_topic_title_length: "Maximum allowed topic title length in characters" min_private_message_title_length: "Minimum allowed title length for a message in characters" min_search_term_length: "Minimum valid search term length in characters" + search_tokenize_chinese_japanese_korean: "Force search to tokenize Chinese/Japanese/Korean even on non CJK sites" allow_uncategorized_topics: "Allow topics to be created without a category. WARNING: If there are any uncategorized topics, you must recategorize them before turning this off." - uncategorized_description: "The description of the uncategorized category. Leave blank for no description." allow_duplicate_topic_titles: "Allow topics with identical, duplicate titles." unique_posts_mins: "How many minutes before a user can make a post with the same content again" educate_until_posts: "When the user starts typing their first (n) new posts, show the pop-up new user education panel in the composer." @@ -788,7 +819,7 @@ en: download_remote_images_to_local: "Convert remote images to local images by downloading them; this prevents broken images." download_remote_images_threshold: "Minimum disk space necessary to download remote images locally (in percent)" disabled_image_download_domains: "Remote images will never be downloaded from these domains. Pipe-delimited list." - ninja_edit_window: "For (n) seconds after posting, editing will not create a new version in the post history." + editing_grace_period: "For (n) seconds after posting, editing will not create a new version in the post history." post_edit_time_limit: "The author can edit or delete their post for (n) minutes after posting. Set to 0 for forever." edit_history_visible_to_public: "Allow everyone to see previous versions of an edited post. When disabled, only staff members can view." delete_removed_posts_after: "Posts removed by the author will be automatically deleted after (n) hours. If set to 0, posts will be deleted immediately." @@ -822,7 +853,7 @@ en: summary_percent_filter: "When a user clicks 'Summarize This Topic', show the top % of posts" summary_max_results: "Maximum posts returned by 'Summary This Topic'" - enable_private_messages: "Allow trust level 1 users to create messages and reply to messages" + enable_private_messages: "Allow trust level 1 (configurable via min trust level to send messages) users to create messages and reply to messages" enable_long_polling: "Message bus used for notification can use long polling" long_polling_base_url: "Base URL used for long polling (when a CDN is serving dynamic content, be sure to set this to origin pull) eg: http://origin.site.com" @@ -847,9 +878,10 @@ en: flag_sockpuppets: "If a new user replies to a topic from the same IP address as the new user who started the topic, flag both of their posts as potential spam." traditional_markdown_linebreaks: "Use traditional linebreaks in Markdown, which require two trailing spaces for a linebreak." - allow_html_tables: "Allow tables to be entered in Markdown using HTML tags, TABLE, THEAD, TD, TR, TH are whitelisted (requires full rebake on all old posts containing tables)" + allow_html_tables: "Allow tables to be entered in Markdown using HTML tags. TABLE, THEAD, TD, TR, TH will be whitelisted (requires full rebake on all old posts containing tables)" post_undo_action_window_mins: "Number of minutes users are allowed to undo recent actions on a post (like, flag, etc)." must_approve_users: "Staff must approve all new user accounts before they are allowed to access the site. WARNING: enabling this for a live site will revoke access for existing non-staff users!" + pending_users_reminder_delay: "Notify moderators if new users have been waiting for approval for longer than this many hours. Set to -1 to disable notifications." ga_tracking_code: "Google analytics (ga.js) tracking code code, eg: UA-12345678-9; see http://google.com/analytics" ga_domain_name: "Google analytics (ga.js) domain name, eg: mysite.com; see http://google.com/analytics" ga_universal_tracking_code: "Google Universal Analytics (analytics.js) tracking code code, eg: UA-12345678-9; see http://google.com/analytics" @@ -858,6 +890,7 @@ en: enable_noscript_support: "Enable standard webcrawler search engine support via the noscript tag" allow_moderators_to_create_categories: "Allow moderators to create new categories" cors_origins: "Allowed origins for cross-origin requests (CORS). Each origin must include http:// or https://. The DISCOURSE_ENABLE_CORS env variable must be set to true to enable CORS." + use_admin_ip_whitelist: "Admins can only log in if they are at an IP address defined in the Screened IPs list (Admin > Logs > Screened Ips)." top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|new|unread|categories|top|read|posted|bookmarks" post_menu: "Determine which items appear on the post menu, and in what order. Example like|edit|flag|delete|share|bookmark|reply" post_menu_hidden_items: "The menu items to hide by default in the post menu unless an expansion ellipsis is clicked on." @@ -869,12 +902,10 @@ en: suppress_reply_directly_above: "Don't show the expandable in-reply-to on a post when there is only a single reply directly above this post." suppress_reply_when_quoting: "Don't show the expandable in-reply-to on a post when post quotes reply." max_reply_history: "Maximum number of replies to expand when expanding in-reply-to" - - experimental_reply_expansion: "Hide intermediate replies when expanding a reply to (experimental)" - topics_per_period_in_top_summary: "Number of top topics shown in the default top topics summary." topics_per_period_in_top_page: "Number of top topics shown on the expanded 'Show More' top topics." redirect_users_to_top_page: "Automatically redirect new and long absent users to the top page." + top_page_default_timeframe: "Default timeframe for the top view page." show_email_on_profile: "Show a user's email on their profile (only visible to themselves and staff)" email_token_valid_hours: "Forgot password / activate account tokens are valid for (n) hours." @@ -907,6 +938,7 @@ en: reserved_usernames: "Usernames for which signup is not allowed." min_password_length: "Minimum password length." + min_admin_password_length: "Minimum password length for Admin." block_common_passwords: "Don't allow passwords that are in the 10,000 most common passwords." enable_sso: "Enable single sign on via an external site (WARNING: USERS' EMAIL ADDRESSES *MUST* BE VALIDATED BY THE EXTERNAL SITE!)" @@ -932,6 +964,10 @@ en: twitter_consumer_key: "Consumer key for Twitter authentication, registered at http://dev.twitter.com" twitter_consumer_secret: "Consumer secret for Twitter authentication, registered at http://dev.twitter.com" + enable_instagram_logins: "Enable Instagram authentication, requires instagram_consumer_key and instagram_consumer_secret" + instagram_consumer_key: "Consumer key for Instagram authentication" + instagram_consumer_secret: "Consumer secret Instagram authentication" + enable_facebook_logins: "Enable Facebook authentication, requires facebook_app_id and facebook_app_secret" facebook_app_id: "App id for Facebook authentication, registered at https://developers.facebook.com/apps" facebook_app_secret: "App secret for Facebook authentication, registered at https://developers.facebook.com/apps" @@ -946,11 +982,18 @@ en: backup_frequency: "How frequently we create a site backup, in days." enable_s3_backups: "Upload backups to S3 when complete. IMPORTANT: requires valid S3 credentials entered in Files settings." s3_backup_bucket: "The remote bucket to hold backups. WARNING: Make sure it is a private bucket." + s3_disable_cleanup: "Disable the removal of backups from S3 when removed locally." + backup_time_of_day: "Time of day UTC when the backup should occur." + backup_with_uploads: "Include uploads in scheduled backups. Disabling this will only backup the database." active_user_rate_limit_secs: "How frequently we update the 'last_seen_at' field, in seconds" verbose_localization: "Show extended localization tips in the UI" previous_visit_timeout_hours: "How long a visit lasts before we consider it the 'previous' visit, in hours" + top_topics_formula_log_views_multiplier: "value of log views multiplier (n) in top topics formula: `log(views_count) * (n) + op_likes_count * 0.5 + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_first_post_likes_multiplier: "value of first post likes multiplier (n) in top topics formula: `log(views_count) * 2 + op_likes_count * (n) + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_least_likes_per_post_multiplier: "value of least likes per post multiplier (n) in top topics formula: `log(views_count) * 2 + op_likes_count * 0.5 + LEAST(likes_count / posts_count, (n)) + 10 + log(posts_count)`" + rate_limit_create_topic: "After creating a topic, users must wait (n) seconds before creating another topic." rate_limit_create_post: "After posting, users must wait (n) seconds before creating another post." rate_limit_new_user_create_topic: "After creating a topic, new users must wait (n) seconds before creating another topic." @@ -965,6 +1008,9 @@ en: max_invites_per_day: "Maximum number of invites a user can send per day." max_topic_invitations_per_day: "Maximum number of topic invitations a user can send per day." + alert_admins_if_errors_per_minute: "Number of errors per minute in order to trigger an admin alert. A value of 0 disables this feature. NOTE: requires restart." + alert_admins_if_errors_per_hour: "Number of errors per hour in order to trigger an admin alert. A value of 0 disables this feature. NOTE: requires restart." + suggested_topics: "Number of suggested topics shown at the bottom of a topic." limit_suggested_to_category: "Only show topics from the current category in suggested topics." @@ -985,6 +1031,10 @@ en: external_system_avatars_enabled: "Use external system avatars service." external_system_avatars_url: "URL of the external system avatars service. Allowed substitions are {username} {first_letter} {color} {size}" + default_opengraph_image_url: "URL of the default opengraph image." + + allow_all_attachments_for_group_messages: "Allow all email attachments for group messages." + enable_flash_video_onebox: "Enable embedding of swf and flv (Adobe Flash) links in oneboxes. WARNING: may introduce security risks." default_invitee_trust_level: "Default trust level (0-4) for invited users." @@ -1002,37 +1052,45 @@ en: tl2_requires_likes_given: "How many likes a user must cast before promotion to trust level 2." tl2_requires_topic_reply_count: "How many topics user must reply to before promotion to trust level 2." - tl3_requires_days_visited: "Minimum number of days that a user needs to have visited the site in the last 100 days to qualify for promotion to trust level 3. (0 to 100)" - tl3_requires_topics_replied_to: "Minimum number of topics a user needs to have replied to in the last 100 days to qualify for promotion to trust level 3. (0 or higher)" - tl3_requires_topics_viewed: "The percentage of topics created in the last 100 days that a user needs to have viewed to qualify for promotion to trust level 3. (0 to 100)" - tl3_requires_posts_read: "The percentage of posts created in the last 100 days that a user needs to have viewed to qualify for promotion to trust level 3. (0 to 100)" + tl3_time_period: "Trust Level 3 requirements time period (in days)" + tl3_requires_days_visited: "Minimum number of days that a user needs to have visited the site in the last (tl3 time period) days to qualify for promotion to trust level 3. Set higher than tl3 time period to disable promotions to tl3. (0 or higher)" + tl3_requires_topics_replied_to: "Minimum number of topics a user needs to have replied to in the last (tl3 time period) days to qualify for promotion to trust level 3. (0 or higher)" + tl3_requires_topics_viewed: "The percentage of topics created in the last (tl3 time period) days that a user needs to have viewed to qualify for promotion to trust level 3. (0 to 100)" + tl3_requires_posts_read: "The percentage of posts created in the last (tl3 time period) days that a user needs to have viewed to qualify for promotion to trust level 3. (0 to 100)" tl3_requires_topics_viewed_all_time: "The minimum total number of topics a user must have viewed to qualify for trust level 3." tl3_requires_posts_read_all_time: "The minimum total number of posts a user must have read to qualify for trust level 3." - tl3_requires_max_flagged: "User must not have had more than x posts flagged by x different users in the last 100 days to qualify for promotion to trust level 3, where x is this setting's value. (0 or higher)" + tl3_requires_max_flagged: "User must not have had more than x posts flagged by x different users in the last (tl3 time period) days to qualify for promotion to trust level 3, where x is this setting's value. (0 or higher)" tl3_promotion_min_duration: "The minimum number of days that a promotion to trust level 3 lasts before a user can be demoted back to trust level 2." - tl3_requires_likes_given: "The minimum number of likes that must be given in the last 100 days to qualify for promotion to trust level 3." - tl3_requires_likes_received: "The minimum number of likes that must be received in the last 100 days to qualify for promotion to trust level 3." + tl3_requires_likes_given: "The minimum number of likes that must be given in the last (tl3 time period) days to qualify for promotion to trust level 3." + tl3_requires_likes_received: "The minimum number of likes that must be received in the last (tl3 time period) days to qualify for promotion to trust level 3." tl3_links_no_follow: "Do not remove rel=nofollow from links posted by trust level 3 users." min_trust_to_create_topic: "The minimum trust level required to create a new topic." min_trust_to_edit_wiki_post: "The minimum trust level required to edit post marked as wiki." + min_trust_to_allow_self_wiki: "The minimum trust level required to make user's own post wiki." + + min_trust_to_send_messages: "The minimum trust level required to create new private messages." + newuser_max_links: "How many links a new user can add to a post." newuser_max_images: "How many images a new user can add to a post." newuser_max_attachments: "How many attachments a new user can add to a post." newuser_max_mentions_per_post: "Maximum number of @name notifications a new user can use in a post." newuser_max_replies_per_topic: "Maximum number of replies a new user can make in a single topic until someone replies to them." max_mentions_per_post: "Maximum number of @name notifications anyone can use in a post." + max_users_notified_per_group_mention: "Maximum number of users that may recieve a notification if a group is mentioned (if threshold is met no notifications will be raised)" create_thumbnails: "Create thumbnails and lightbox images that are too large to fit in a post." email_time_window_mins: "Wait (n) minutes before sending any notification emails, to give users a chance to edit and finalize their posts." + private_email_time_window_seconds: "Wait (n) seconds before sending any private notification emails, to give users a chance to edit and finalize their messages." email_posts_context: "How many prior replies to include as context in notification emails." flush_timings_secs: "How frequently we flush timing data to the server, in seconds." title_max_word_length: "The maximum allowed word length, in characters, in a topic title." title_min_entropy: "The minimum entropy (unique characters, non-english count for more) required for a topic title." body_min_entropy: "The minimum entropy (unique characters, non-english count for more) required for a post body." + allow_uppercase_posts: "Allow all caps in a topic title or a post body." title_fancy_entities: "Convert common ASCII characters to fancy HTML entities in topic titles, ala SmartyPants http://daringfireball.net/projects/smartypants/" @@ -1074,6 +1132,7 @@ en: white_listed_spam_host_domains: "A list of domains excluded from spam host testing. New users will never be restricted from creating posts with links to these domains." staff_like_weight: "How much extra weighting factor to give staff likes." topic_view_duration_hours: "Count a new topic view once per IP/User every N hours" + user_profile_view_duration_hours: "Count a new user profile view once per IP/User every N hours" levenshtein_distance_spammer_emails: "When matching spammer emails, number of characters difference that will still allow a fuzzy match." max_new_accounts_per_registration_ip: "If there are already (n) trust level 0 accounts from this IP (and none is a staff member or at TL2 or higher), stop accepting new signups from that IP." @@ -1099,7 +1158,16 @@ en: strip_images_from_short_emails: "Strip images from emails having size less than 2800 Bytes" short_email_length: "Short email length in Bytes" + display_name_on_email_from: "Display full names on email from fields" + unsubscribe_via_email: "Allow users to unsubscribe from emails by sending an email with 'unsubscribe' in the subject or body" + unsubscribe_via_email_footer: "Attach an unsubscribe link to the footer of sent emails" + + delete_email_logs_after_days: "Delete email logs after (N) days. 0 to keep indefinitely" + max_emails_per_day_per_user: "Maximum number of emails to send users per day. 0 to disable the limit" + enable_staged_users: "Automatically create staged users when processing incoming emails." + + manual_polling_enabled: "Push emails using the API for email replies." pop3_polling_enabled: "Poll via POP3 for email replies." pop3_polling_ssl: "Use SSL while connecting to the POP3 server. (Recommended)" pop3_polling_period_mins: "The period in minutes between checking the POP3 account for email. NOTE: requires restart." @@ -1129,7 +1197,8 @@ en: automatically_download_gravatars: "Download Gravatars for users upon account creation or email change." digest_topics: "The maximum number of topics to display in the email digest." digest_min_excerpt_length: "Minimum post excerpt in the email digest, in characters." - suppress_digest_email_after_days: "Suppress digest emails for users not seen on the site for more than (n) days." + delete_digest_email_after_days: "Suppress digest emails for users not seen on the site for more than (n) days." + digest_suppress_categories: "Suppress these categories from digest emails." disable_digest_emails: "Disable digest emails for all users." detect_custom_avatars: "Whether or not to check that users have uploaded custom profile pictures." @@ -1141,24 +1210,32 @@ en: anonymous_posting_min_trust_level: "Minimum trust level required to enable anonymous posting" anonymous_account_duration_minutes: "To protect anonymity create a new anonymous account every N minutes for each user. Example: if set to 600, as soon as 600 minutes elapse from last post AND user switches to anon, a new anonymous account is created." + hide_user_profiles_from_public: "Disable user cards, user profiles and user directory for anonymous users." + allow_profile_backgrounds: "Allow users to upload profile backgrounds." - sequential_replies_threshold: "Number posts a user has to make in a row in a topic before being reminded about too many sequential replies. " + sequential_replies_threshold: "Number of posts a user has to make in a row in a topic before being reminded about too many sequential replies." enable_mobile_theme: "Mobile devices use a mobile-friendly theme, with the ability to switch to the full site. Disable this if you want to use a custom stylesheet that is fully responsive." dominating_topic_minimum_percent: "What percentage of posts a user has to make in a topic before being reminded about overly dominating a topic." + disable_avatar_education_message: "Disable education message for changing avatar." + daily_performance_report: "Analyze NGINX logs daily and post a Staff Only topic with details" suppress_uncategorized_badge: "Don't show the badge for uncategorized topics in topic lists." - permalink_normalizations: "Apply the following regex before matching permalinks, for example: /(\\/topic.*)\\?.*/\\1 will strip query strings from topic routes. Format is regex+string use \\1 etc. to access captures" + permalink_normalizations: "Apply the following regex before matching permalinks, for example: /(topic.*)\\?.*/\\1 will strip query strings from topic routes. Format is regex+string use \\1 etc. to access captures" global_notice: "Display an URGENT, EMERGENCY global banner notice to all visitors, change to blank to hide it (HTML allowed)." disable_edit_notifications: "Disables edit notifications by the system user when 'download_remote_images_to_local' is active." + automatically_unpin_topics: "Automatically unpin topics when the user reaches the bottom." + + read_time_word_count: "Word count per minute for calculating estimated reading time." + full_name_required: "Full name is a required field of a user's profile." enable_names: "Show the user's full name on their profile, user card, and emails. Disable to hide full name everywhere." display_name_on_posts: "Show a user's full name on their posts in addition to their @username." @@ -1176,6 +1253,7 @@ en: embed_username_key_from_feed: "Key to pull discourse username from feed." embed_truncate: "Truncate the embedded posts." embed_post_limit: "Maximum number of posts to embed." + embed_username_required: "The username for topic creation is required." embed_whitelist_selector: "CSS selector for elements that are allowed in embeds." embed_blacklist_selector: "CSS selector for elements that are removed from embeds." notify_about_flags_after: "If there are flags that haven't been handled after this many hours, send an email to the contact_email. Set to 0 to disable." @@ -1184,9 +1262,7 @@ en: delete_drafts_older_than_n_days: Delete drafts older than (n) days. - show_logout_in_header: "Show log out in user dropdown in header" - - vacuum_db_days: "Run VACUUM FULL ANALYZE to reclaim DB space after migrations (set to 0 to disable)" + vacuum_db_days: "Run VACUUM ANALYZE to reclaim DB space after migrations (set to 0 to disable)" prevent_anons_from_downloading_files: "Prevent anonymous users from downloading attachments. WARNING: this will prevent any non-image site assets posted as attachments from working." @@ -1196,15 +1272,20 @@ en: emoji_set: "How would you like your emoji?" enforce_square_emoji: "Force a square aspect ratio to all emojis." - approve_post_count: "The amount of posts from a new user that must be approved" + approve_post_count: "The amount of posts from a new or basic user that must be approved" approve_unless_trust_level: "Posts for users below this trust level must be approved" notify_about_queued_posts_after: "If there are posts that have been waiting to be reviewed for more than this many hours, an email will be sent to the contact email. Set to 0 to disable these emails." default_email_digest_frequency: "How often users receive digest emails by default." + default_include_tl0_in_digests: "Include posts from new users in digest emails by default. Users can change this in their preferences." default_email_private_messages: "Send an email when someone messages the user by default." default_email_direct: "Send an email when someone quotes/replies to/mentions or invites the user by default." default_email_mailing_list_mode: "Send an email for every new post by default." + disable_mailing_list_mode: "Disallow users from enabling mailing list mode." default_email_always: "Send an email notification even when the user is active by default." + default_email_previous_replies: "Include previous replies in emails by default." + + default_email_in_reply_to: "Include excerpt of replied to post in emails by default." default_other_new_topic_duration_minutes: "Global default condition for which a topic is considered new." default_other_auto_track_topics_after_msecs: "Global default time before a topic is automatically tracked." @@ -1214,6 +1295,10 @@ en: default_other_disable_jump_reply: "Don't jump to user's post after they reply by default." default_other_edit_history_public: "Make the post revisions public by default." + default_other_like_notification_frequency: "Notify users on likes by default" + + default_topics_automatic_unpin: "Automatically unpin topics when the user reaches the bottom by default." + default_categories_watching: "List of categories that are watched by default." default_categories_tracking: "List of categories that are tracked by default." default_categories_muted: "List of categories that are muted by default." @@ -1232,8 +1317,16 @@ en: invalid_string_min: "Must be at least %{min} characters." invalid_string_max: "Must be no more than %{max} characters." invalid_reply_by_email_address: "Value must contain '%{reply_key}' and be different from the notification email." + pop3_polling_host_is_empty: "You must set a 'pop3 polling host' before enabling POP3 polling." + pop3_polling_username_is_empty: "You must set a 'pop3 polling username' before enabling POP3 polling." + pop3_polling_password_is_empty: "You must set a 'pop3 polling password' before enabling POP3 polling." + pop3_polling_authentication_failed: "POP3 authentication failed. Please verify your pop3 credentials." + reply_by_email_address_is_empty: "You must set a 'reply by email address' before enabling reply by email." + email_polling_disabled: "You must enable either manual or POP3 polling before enabling reply by email." + user_locale_not_enabled: "You must first enable 'allow user locale' before enabling this setting." notification_types: + group_mentioned: "%{group_name} was mentioned in %{link}" mentioned: "%{display_username} mentioned you in %{link}" liked: "%{display_username} liked your post in %{link}" replied: "%{display_username} replied to your post in %{link}" @@ -1243,7 +1336,7 @@ en: moved_post: "%{display_username} moved your post to %{link}" private_message: "%{display_username} sent you a message: %{link}" invited_to_private_message: "%{display_username} invited you to a message: %{link}" - invited_to_topic: "%{display_username} invited you to a topic: %{link}" + invited_to_topic: "%{display_username} invited you to %{link}" invitee_accepted: "%{display_username} accepted your invitation" linked: "%{display_username} linked you in %{link}" granted_badge: "You earned %{link}" @@ -1256,10 +1349,10 @@ en: user: 'Users' sso: - not_found: "Unable to lookup or create account, contact site admin" - account_not_approved: "Account is pending approval, you will receive an email notification once approved" - unknown_error: "Error updating information, contact site admin" - timeout_expired: "Account login timed out, please try logging in again" + not_found: "Your account couldn't be found. Please contact the site's administrator." + account_not_approved: "Your account is pending approval. You will receive an email notification when you are approved." + unknown_error: "There is a problem with your account. Please contact the site's administrator." + timeout_expired: "Account login timed out, please try logging in again." original_poster: "Original Poster" most_posts: "Most Posts" @@ -1341,6 +1434,7 @@ en: reserved_username: "That username is not allowed." missing_user_field: "You have not completed all the user fields" close_window: "Authentication is complete. Close this window to continue." + already_logged_in: "Oops, looks like you are attempting to accept an invitation for another user. If you are not %{current_user}, please log out and try again." user: no_accounts_associated: "No accounts associated" @@ -1350,10 +1444,10 @@ en: characters: "must only include numbers, letters and underscores" unique: "must be unique" blank: "must be present" - must_begin_with_alphanumeric: "must begin with a letter or number or an underscore" - must_end_with_alphanumeric: "must end with a letter or number or an underscore" + must_begin_with_alphanumeric_or_underscore: "must begin with a letter, a number or an underscore" + must_end_with_alphanumeric: "must end with a letter or a number" must_not_contain_two_special_chars_in_seq: "must not contain a sequence of 2 or more special chars (.-_)" - must_not_contain_confusing_suffix: "must not contain a confusing suffix like .json or .png etc." + must_not_end_with_confusing_suffix: "must not end with a confusing suffix like .json or .png etc." email: not_allowed: "is not allowed from that email provider. Please use another email address." blocked: "is not allowed." @@ -1361,6 +1455,25 @@ en: blocked: "New registrations are not allowed from your IP address." max_new_accounts_per_registration_ip: "New registrations are not allowed from your IP address (maximum limit reached). Contact a staff member." + flags_reminder: + flags_were_submitted: + one: "Flags were submitted over 1 hour ago. Please review them." + other: "Flags were submitted over %{count} hours ago. Please review them." + subject_template: + one: "1 flag waiting to be handled" + other: "%{count} flags waiting to be handled" + + unsubscribe_mailer: + subject_template: "Confirm you no longer want to receive email updates from %{site_title}" + text_body_template: | + Someone (possibly you?) requested to no longer send email updates from %{site_domain_name} to this address. + If you with to confirm this, please click this link: + + %{confirm_unsubscribe_link} + + + If you want to continue receiving email updates, you may ignore this email. + invite_mailer: subject_template: "%{invitee_name} invited you to '%{topic_title}' on %{site_domain_name}" text_body_template: | @@ -1426,7 +1539,9 @@ en: - If you run your own mail server, check to make sure the IPs of your mail server are [not on any email blacklists][4]. Also verify that it is definitely sending a fully-qualified hostname that resolves in DNS in its HELO message. If not, this will cause your email to be rejected by many mail services. - (The *easy* way is to create a free account on [Mandrill][md] or [Mailgun][mg] or [Mailjet][mj], which have free generous free mailing plans and will be fine for small communities. You'll still need to set up the SPF and DKIM records in your DNS, though!) + - We highly recommend you **send a test email to [mail-tester.com][mt]** to verify that all the above is working correctly. + + (The *easy* way is to create a free account on [SendGrid][sg], [SparkPost][sp], [Mailgun][mg] or [Mailjet][mj], which have free generous free mailing plans and will be fine for small communities. You'll still need to set up the SPF and DKIM records in your DNS, though!) We hope you received this email deliverability test OK! @@ -1441,20 +1556,20 @@ en: [4]: http://whatismyipaddress.com/blacklist-check [7]: http://dkimcore.org/tools/dkimrecordcheck.html [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com + [sg]: https://sendgrid.com/ + [sp]: https://www.sparkpost.com/ [mg]: http://www.mailgun.com/ [mj]: https://www.mailjet.com/pricing + [mt]: http://www.mail-tester.com/ new_version_mailer: subject_template: "[%{site_name}] New Discourse version, update available" text_body_template: | - A new version of [Discourse](http://www.discourse.org) is available. + Hooray, a new version of [Discourse](http://www.discourse.org) is available! Your version: %{installed_version} New version: **%{new_version}** - You may want to: - - See what's new in the [GitHub changelog](https://github.com/discourse/discourse/commits/master). - Upgrade from your browser at [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). @@ -1464,13 +1579,11 @@ en: new_version_mailer_with_notes: subject_template: "[%{site_name}] update available" text_body_template: | - A new version of [Discourse](http://www.discourse.org) is available. + Hooray, a new version of [Discourse](http://www.discourse.org) is available! Your version: %{installed_version} New version: **%{new_version}** - You may want to: - - See what's new in the [GitHub changelog](https://github.com/discourse/discourse/commits/master). - Upgrade from your browser at [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). @@ -1481,17 +1594,6 @@ en: %{notes} - flags_reminder: - flags_were_submitted: - one: "These flags were submitted over 1 hour ago." - other: "These flags were submitted over %{count} hours ago." - please_review: "Please review them." - post_number: "post" - how_to_disable: 'You can disable or change the frequency of this email reminder via the "notify about flags after" setting.' - subject_template: - one: "1 flag waiting to be handled" - other: "%{count} flags waiting to be handled" - queued_posts_reminder: subject_template: one: "[%{site_name}] 1 post waiting to be reviewed" @@ -1564,7 +1666,15 @@ en: - To reply with **a new topic**, use to the right of the post. Both old and new topics will be automatically linked together. - To insert a quote, select the text you wish to quote, then press any Reply button. Repeat for multiple quotes! + Your reply can be formatted using simple HTML, BBCode, or [Markdown](http://commonmark.org/help/): + + This is **bold**. + This is bold. + This is [b]bold[/b]. + + Want to learn Markdown? [Take our fun 10 minute interactive tutorial!](http://commonmark.org/help/tutorial/) + + To insert a quote, select the text you wish to quote, then press any Reply button. Repeat for multiple quotes. @@ -1716,19 +1826,47 @@ en: subject_template: "Data export failed" text_body_template: "We're sorry, but your data export failed. Please check the logs or contact a staff member." - email_reject_trust_level: + email_reject_insufficient_trust_level: subject_template: "[%{site_name}] Email issue -- Insufficient Trust Level" text_body_template: | We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. Your account does not have the required trust level to post new topics to this email address. If you believe this is in error, contact a staff member. + email_reject_user_not_found: + subject_template: "[%{site_name}] Email issue -- User Not Found" + text_body_template: | + We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. + + Your reply was sent from an unknown email address. Try sending from another email address, or contact a staff member. + + email_reject_inactive_user: + subject_template: "[%{site_name}] Email issue -- Inactive User" + text_body_template: | + We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. + + Your account associated with this email address is not activated. Please activate your account before sending emails in. + + email_reject_blocked_user: + subject_template: "[%{site_name}] Email issue -- Blocked User" + text_body_template: | + We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. + + Your account associated with this email address has been blocked. + + email_reject_reply_user_not_matching: + subject_template: "[%{site_name}] Email issue -- Reply User Not Matching" + text_body_template: | + We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. + + Your reply was sent from a different email address than the one we expected, so we're not sure if this is the same person. Try sending from another email address, or contact a staff member. + email_reject_no_account: subject_template: "[%{site_name}] Email issue -- Unknown Account" text_body_template: | We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - There is no known user account with this email address. Try sending from a different email address, or contact a staff member. + We can't find any accounts that match your email address. Try sending from a different email address, or contact a staff member. email_reject_empty: subject_template: "[%{site_name}] Email issue -- No Content" @@ -1753,14 +1891,21 @@ en: Your account does not have the privileges to post new topics in that category. If you believe this is in error, contact a staff member. - email_reject_post_error: + email_reject_strangers_not_allowed: + subject_template: "[%{site_name}] Email issue -- Invalid Access" + text_body_template: | + We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. + + The category you sent this email to only allows replies from users with valid accounts and known email addresses. If you believe this is in error, contact a staff member. + + email_reject_invalid_post: subject_template: "[%{site_name}] Email issue -- Posting error" text_body_template: | We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. Some possible causes are: complex formatting, message too large, message too small. Please try again, or post via the website if this continues. - email_reject_post_error_specified: + email_reject_invalid_post_specified: subject_template: "[%{site_name}] Email issue -- Posting error" text_body_template: | We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. @@ -1771,26 +1916,41 @@ en: If you can correct the problem, please try again. + email_reject_rate_limit_specified: + subject_template: "[%{site_name}] Email issue -- Rate limited" + text_body_template: | + We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. + + Reason: %{rate_limit_description} + + email_reject_invalid_post_action: + subject_template: "[%{site_name}] Email issue -- Invalid Post Action" + text_body_template: | + We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. + + The Post Action was not recognized. Please try again, or post via the website if this continues. + + email_reject_reply_key: subject_template: "[%{site_name}] Email issue -- Unknown Reply Key" text_body_template: | We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - The provided reply key is invalid or unknown, so we don't know what this email is in reply to. Contact a staff member. + The reply key in the email is invalid or unknown, so we can't figure out what this email is in reply to. Contact a staff member. - email_reject_destination: + email_reject_bad_destination_address: subject_template: "[%{site_name}] Email issue -- Unknown To: Address" text_body_template: | We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - None of the destination addresses are recognized. Please make sure that the site address is in the To: line (not Cc: or Bcc:), and that you are sending to the correct email address provided by staff. + None of the destination email addresses are recognized. Please make sure that you are sending to the correct email address provided by staff. email_reject_topic_not_found: subject_template: "[%{site_name}] Email issue -- Topic Not Found" text_body_template: | We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - The topic you are replying to no longer exists, perhaps it was deleted? If you believe this is in error, contact a staff member. + The topic you are replying to no longer exists -- perhaps it was deleted? If you believe this is in error, contact a staff member. email_reject_topic_closed: subject_template: "[%{site_name}] Email issue -- Topic Closed" @@ -1804,15 +1964,17 @@ en: text_body_template: | We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - Your email was marked as "auto generated", which we can't accept. If you believe this is in error, contact a staff member. + Your email was marked as "auto generated", which means it was automatically created by a computer instead of being typed by a human; we can't accept those kinds of emails. If you believe this is in error, contact a staff member. email_error_notification: subject_template: "[%{site_name}] Email issue -- POP authentication error" text_body_template: | - There has been an authentication error while polling mails from the POP server. + Unfortunately, there was an authentication error while polling mails from the POP server. Please make sure you have properly configured the POP credentials in [the site settings](%{base_url}/admin/site_settings/category/email). + If there is a web UI for the POP email account, you may need to log in on the web and check your settings there. + too_many_spam_flags: subject_template: "New account blocked" text_body_template: | @@ -1831,6 +1993,10 @@ en: This is an automated message from %{site_name} to inform you that your account has been blocked by a staff member. + Please be aware that you will not be able to create new replies or topics until unblocked by a staff member. + + If you have questions regarding this block, please contact a [staff members](%{base_url}/about). + For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines). user_automatically_blocked: @@ -1838,9 +2004,9 @@ en: text_body_template: | This is an automated message. - The new user [%{username}](%{base_url}%{user_url}) was automatically blocked because multiple users flagged %{username}'s post(s). + The new user [%{username}](%{user_url}) was automatically blocked because multiple users flagged %{username}'s post(s). - Please [review the flags](%{base_url}/admin/flags). If %{username} was incorrectly blocked from posting, click the unblock button on [the admin page for this user](%{base_url}%{user_url}). + Please [review the flags](%{base_url}/admin/flags). If %{username} was incorrectly blocked from posting, click the unblock button on [the admin page for this user](%{user_url}). This threshold can be changed via the `block_new_user` site settings. @@ -1849,9 +2015,9 @@ en: text_body_template: | This is an automated message. - The new user [%{username}](%{base_url}%{user_url}) tried to create multiple posts with links to %{domains}, but those posts were blocked to avoid spam. The user is still able to create new posts that do not link to %{domains}. + The new user [%{username}](%{user_url}) tried to create multiple posts with links to %{domains}, but those posts were blocked to avoid spam. The user is still able to create new posts that do not link to %{domains}. - Please [review the user](%{base_url}%{user_url}). + Please [review the user](%{user_url}). This can be modified via the `newuser_spam_host_threshold` and `white_listed_spam_host_domains` site settings. @@ -1878,59 +2044,102 @@ en: text_body_template: "The `download_remote_images_to_local` setting was disabled because the disk space limit at `download_remote_images_threshold` was reached." unsubscribe_link: | - To unsubscribe from these emails, visit your [user preferences](%{user_preferences_url}). + To stop receiving notifications for this particular topic, [click here](%{unsubscribe_url}). To unsubscribe from these emails, change your [user preferences](%{user_preferences_url}) - To stop receiving notifications about this particular topic, [click here](%{unsubscribe_url}). + unsubscribe_via_email_link: | + or, [click here](mailto:reply@%{hostname}?subject=unsubscribe) to unsubscribe via email. subject_re: "Re: " subject_pm: "[PM] " user_notifications: previous_discussion: "Previous Replies" + reached_limit: + one: "WARNING: you reached the limit of daily emails. Further email notifications will be suppressed." + other: "WARNING: you reached the limit of %{count} daily emails. Further email notifications will be suppressed." + in_reply_to: "In Reply To" unsubscribe: title: "Unsubscribe" description: "Not interested in getting these emails? No problem! Click below to unsubscribe instantly:" - reply_by_email: "To respond, reply to this email or visit %{base_url}%{url} in your browser." - visit_link_to_respond: "To respond, visit %{base_url}%{url} in your browser." + header_instructions: '' + reply_by_email: "[Visit Topic](%{base_url}%{url}) or reply to this email to respond" + reply_by_email_pm: "[Visit Message](%{base_url}%{url}) or reply to this email to respond" + only_reply_by_email: "Reply to this email to respond" + visit_link_to_respond: "[Visit Topic](%{base_url}%{url}) to respond" + visit_link_to_respond_pm: "[Visit Message](%{base_url}%{url}) to respond" posted_by: "Posted by %{username} on %{post_date}" + invited_to_private_message_body: | + %{username} invited you to a message + + > **%{topic_title}** + > + > %{topic_excerpt} + + at + + > %{site_title} -- %{site_description} + + invited_to_topic_body: | + %{username} invited you to a discussion + + > **%{topic_title}** + > + > %{topic_excerpt} + + at + + > %{site_title} -- %{site_description} + user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} invited you to a message '%{topic_title}'" text_body_template: | + %{header_instructions} - %{username} invited you to a message + %{message} - > **%{topic_title}** - > - > %{topic_excerpt} + --- + %{respond_instructions} - at + user_invited_to_private_message_pm_staged: + subject_template: "[%{site_name}] %{username} invited you to a message '%{topic_title}'" + text_body_template: | + %{header_instructions} - > %{site_title} -- %{site_description} + %{message} - Please visit this link to view the message: %{base_url}%{url} + --- + %{respond_instructions} user_invited_to_topic: - subject_template: "[%{site_name}] %{username} invited you to a topic '%{topic_title}'" + subject_template: "[%{site_name}] %{username} invited you to '%{topic_title}'" text_body_template: | + %{header_instructions} - %{username} invited you to a discussion + %{message} - > **%{topic_title}** - > - > %{topic_excerpt} - - at - - > %{site_title} -- %{site_description} - - Please visit this link to view the message: %{base_url}%{url} + --- + %{respond_instructions} user_replied: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + + user_replied_pm: + subject_template: "[%{site_name}] [PM] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1941,6 +2150,20 @@ en: user_quoted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + + user_linked: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1951,6 +2174,20 @@ en: user_mentioned: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1961,6 +2198,8 @@ en: user_posted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1971,6 +2210,8 @@ en: user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1978,6 +2219,15 @@ en: --- %{respond_instructions} + user_posted_pm_staged: + subject_template: "%{optional_re}%{topic_title}" + text_body_template: | + + %{message} + + --- + %{respond_instructions} + digest: why: "A brief summary of %{site_link} since your last visit on %{last_seen_at}" subject_template: "[%{site_name}] Digest" @@ -2029,13 +2279,35 @@ en: Click the following link to choose a password for your new account: %{base_url}/users/password-reset/%{email_token} - authorize_email: + confirm_new_email: subject_template: "[%{site_name}] Confirm your new email address" text_body_template: | Confirm your new email address for %{site_name} by clicking on the following link: %{base_url}/users/authorize-email/%{email_token} + confirm_old_email: + subject_template: "[%{site_name}] Confirm your current email address" + text_body_template: | + Before we can change your email address, we need you to confirm that you control + the current email account. After you complete this step, we will have you confirm + the new email address. + + Confirm your current email address for %{site_name} by clicking on the following link: + + %{base_url}/users/authorize-email/%{email_token} + + notify_old_email: + subject_template: "[%{site_name}] Your email address has been changed" + text_body_template: | + This is an automated message to let you know that your email address for + %{site_name} has been changed. If this was done in error, please contact + a site administrator. + + Your email address has been changed to: + + %{new_email} + signup_after_approval: subject_template: "You've been approved on %{site_name}!" text_body_template: | @@ -2067,7 +2339,7 @@ en: If the above link is not clickable, try copying and pasting it into the address bar of your web browser. page_not_found: - title: "The page you requested doesn't exist or is private." + title: "Oops! That page doesn’t exist or is private." popular_topics: "Popular" recent_topics: "Recent" see_more: "More" @@ -2098,7 +2370,7 @@ en: size_not_found: "Sorry, but we couldn't determine the size of the image. Maybe your image is corrupted?" avatar: - missing: "Sorry, but the avatar you have selected is not present on the server. Can you try uploading it again?" + missing: "Sorry, we can't find any avatar associated with that email address. Can you try uploading it again?" flag_reason: sockpuppet: "A new user created a topic, and another new user at the same IP address replied. See the flag_sockpuppets site setting." @@ -2115,6 +2387,7 @@ en: post_deleted: "post was deleted by the author" user_suspended: "user was suspended" already_read: "user has already read this post" + exceeded_limit: "Exceeded max_emails_per_day_per_user" message_blank: "message is blank" message_to_blank: "message.to is blank" text_part_body_blank: "text_part.body is blank" @@ -2478,65 +2751,214 @@ en: status:openstatus:closedstatus:archivedstatus:norepliesstatus:single_user category:foouser:foogroup:foobadge:foo in:likesin:postedin:watchingin:trackingin:private - in:bookmarksin:first - posts_count:nummin_age:daysmax_age:days + in:bookmarksin:firstin:pinnedin:unpinned + posts_count:numbefore:days or dateafter:days or date

    +

    Examples

    - rainbows category:parks status:open order:latest will search for topics containing the word "rainbows" in the category "parks" that are not closed or archived, ordered by date of last post. +

      +
    • rainbows category:parks status:open order:latest will search for topics containing the word "rainbows" in the category "parks" that are not closed or archived, ordered by date of last post.
    • +
    • rainbows category:"parks and gardens" in:bookmarks will search for topics containing the word "rainbows" in the category "parks and gardens" that are bookmarked by you.
    • +

    badges: - long_descriptions: - autobiographer: | - This badge is granted for filling out your user profile and selecting a profile picture. Letting the community know more about who you are and what you're interested in makes for a better, more connected community. - first_like: | - This badge is granted the first time you like a post using the :heart: button. Liking posts is a great way to let your fellow community members know that what they posted was interesting, useful, cool, or fun. Share the love! - first_link: | - This badge is granted the first time you place a link to another topic in a reply. Linking topics helps fellow readers find interesting related conversations, by showing connections between topics in both directions. - first_quote: | - This badge is granted the first time you quote a post in your reply. Quoting relevant sections of earlier posts in your reply helps keep discussions focused and on topic. - first_share: | - This badge is granted the first time you share a link to a reply or topic using the share button. Sharing links is a great way to show off interesting discussions with the rest of the world and grow your community. - read_guidelines: | - This badge is granted for reading the community guidelines. Following and sharing these simple guidelines helps build a safe, fun, and sustainable community. - reader: | - This badge is granted for reading a long topic. Reading is fundamental. Reading closely helps you follow the conversation and leads to better, more complete replies. - editor: | - This badge is granted for editing your post. Don't hesitate to edit your posts any time to improve them, fix small mistakes, or add anything you forgot. - first_flag: | - This badge is granted for flagging a post. Flagging is critical to the health of your community. If you notice any posts that require moderator attention please - do not hesitate to flag. You may also use the flagging dialog to send messages to fellow users. - nice_share: | - This badge is granted for sharing a link to a post that's visited by 25 outside visitors. Nice job! Sharing links to interesting discussions with friends is an excellent way to grow our community. - welcome: | + editor: + name: Editor + description: First post edit + long_description: | + This badge is granted the first time you edit one of your posts. While you won't be able to edit your posts forever, editing is always a good idea — you can improve your posts, fix small mistakes, or add anything you missed when you originally posted. Edit to make your posts even better! + basic_user: + name: Basic + description: Granted all essential community functions + long_description: | + This badge is granted when you reach trust level 1. Thanks for sticking around a little while and reading a few topics to learn what our community is about. Your new user restrictions have been lifted; you've been granted all essential community abilities, such as personal messaging, flagging, wiki editing, and the ability to post multiple images and links. + member: + name: Member + description: Granted invitations, group messaging, more likes + long_description: | + This badge is granted when you reach trust level 2. Thanks for participating over a period of weeks to truly join our community. You can now send invitations from your user page or individual topics, create group personal messages, and have a few more likes per day. + regular: + name: Regular + description: Granted recategorize, rename, followed links, wiki, more likes + long_description: | + This badge is granted when you reach trust level 3. Thanks for being a regular part of our community over a period of months. You're now one of the most active readers, and a reliable contributor that makes our community great. You can now recategorize and rename topics, take advantage of more powerful spam flags, access a private lounge area, and you'll also get lots more likes per day. + leader: + name: Leader + description: Granted global edit, pin, close, archive, split and merge, more likes + long_description: | + This badge is granted when you reach trust level 4. You're a leader in this community as selected by staff, and you set a positive example for the rest of the community in your actions and words here. You have the ability to edit all posts, take common topic moderator actions such as pin, close, unlist, archive, split, and merge, and you have tons of likes per day. + welcome: + name: Welcome + description: Received a like + long_description: | This badge is granted when you receive your first like on a post. Congratulations, you've posted something that your fellow community members found interesting, cool, or useful! - anniversary: | - This badge is granted when you've been a member for a year with at least one post in that year. Thanks for sticking around and contributing to our community! - good_share: | - This badge is granted for sharing a link to a post that's visited by 300 outside visitors. Good work! You've shown off an interesting discussion to a lot of new people and helped us grow. - great_share: | - This badge is granted for sharing a link to a post that's visited by 100 outside visitors. Wow! You've promoted an interesting discussion to a huge new audience for this community, and helped us grow in a big way. - nice_post: | - This badge is granted for creating a reply that gets 10 likes. Nice job! - nice_topic: | - This badge is granted for creating a topic that gets 10 likes. Nice job! - good_post: | - This badge is granted for creating a reply that gets 25 likes. Good work! - good_topic: | - This badge is granted for creating a topic that gets 25 likes. Good work! - great_post: | - This badge is granted for creating a post that gets 50 likes. Wow! - great_topic: | - This badge is granted for creating a reply that gets 50 likes. Wow! - basic: | - This badge is granted when you reach trust level 1. Thanks for sticking around a little while and reading a few topics to learn what our community is about. Your new user restrictions have been lifted, and you've been granted all essential community abilities, such as personal messaging, flagging, wiki editing, and the ability to post images and multiple links. - member: | - This badge is granted when you reach trust level 2. Thanks for participating over a period of weeks to more join our community. You can now send personal invitations from your user page or individual topics, create group messages, and a few more likes per day. - regular: | - This badge is granted when you reach trust level 3. Thanks for being a regular part of our community over a period of months, one of the most active readers and a reliable contributor to what makes this community great. You can now recategorize and rename topics, access a private lounge area, more powerful spam flags, and lots more likes per day. - leader: | - This badge is granted when you reach trust level 4. You're a leader in this community as selected by staff, and set a positive example for the community in your deeds and words. You have the ability to edit all posts, take topic moderator actions such as pin, close, unlist, archive, split, and merge, and tons of likes per day. + autobiographer: + name: Autobiographer + description: Filled out profile information + long_description: | + This badge is granted for filling out your user profile and selecting a profile picture. Letting the community know a bit more about who you are and what you're interested in makes for a better, more connected community. Join us! + anniversary: + name: Anniversary + description: Active member for a year, posted at least once + long_description: | + This badge is granted when you've been a member for a year with at least one post in that year. Thank you for sticking around and contributing to our community. We couldn't do it without you. + nice_post: + name: Nice Reply + description: Received 10 likes on a reply + long_description: | + This badge is granted when your reply gets 10 likes. Your reply really made an impression on the community and helped move the conversation forward! + good_post: + name: Good Reply + description: Received 25 likes on a reply + long_description: | + This badge is granted when your reply gets 25 likes. Your reply was exceptional and made the conversation a whole lot better for everyone! + great_post: + name: Great Reply + description: Received 50 likes on a reply + long_description: | + This badge is granted when your reply gets 50 likes. Wow! Your reply was inspiring, fascinating, hilarious, or insightful and the community loved it. + nice_topic: + name: Nice Topic + description: Received 10 likes on a topic + long_description: | + This badge is granted when your topic gets 10 likes. Hey, you started an interesting conversation that the community enjoyed! + good_topic: + name: Good Topic + description: Received 25 likes on a topic + long_description: | + This badge is granted when your topic gets 25 likes. You launched a vibrant conversation that the community rallied around and loved! + great_topic: + name: Great Topic + description: Received 50 likes on a topic + long_description: | + This badge is granted when your topic gets 50 likes. You kicked off a fascinating conversation and the community enjoyed the dynamic discussion that resulted! + nice_share: + name: Nice Share + description: Shared a post with 25 unique visitors + long_description: | + This badge is granted for sharing a link that was clicked by 25 outside visitors. Thanks for spreading the word about our discussions, and this community. + good_share: + name: Good Share + description: Shared a post with 300 unique visitors + long_description: | + This badge is granted for sharing a link that was clicked by 300 outside visitors. Good work! You've shown off a great discussion to a bunch of new people and helped this community grow. + great_share: + name: Great Share + description: Shared a post with 1000 unique visitors + long_description: | + This badge is granted for sharing a link that was clicked by 1000 outside visitors. Wow! You've promoted an interesting discussion to a huge new audience, and helped us grow our community in a big way! + first_like: + name: First Like + description: Liked a post + long_description: | + This badge is granted the first time you like a post using the :heart: button. Liking posts is a great way to let your fellow community members know that what they posted was interesting, useful, cool, or fun. Share the love! + first_flag: + name: First Flag + description: Flagged a post + long_description: | + This badge is granted the first time you flag a post. Flagging is how we all help keep this a clean, well lit place for everyone. If you notice any posts that require moderator attention for any reason please don't hesitate to flag. You can also flag to send personal messages to fellow users if you see an issue with their post. If you see a problem, :flag_black: flag it! + promoter: + name: Promoter + description: Invited a user + long_description: | + This badge is granted when you invite someone to join the community via the invite button on your user page, or at the bottom of a topic. Inviting friends who might be interested in specific discussions is an great way to introduce new people to our community, so thanks! + campaigner: + name: Campaigner + description: Invited 3 basic users + long_description: | + This badge is granted when you've invited 3 people who subsequently spent enough time on the site to become basic users. A vibrant community needs a regular infusion of newcomers who regularly participate and add new voices to the conversationss. + champion: + name: Champion + description: Invited 5 members + long_description: | + This badge is granted when you've invited 5 people who subsequently spent enough time on the site to become full members. Wow! Thanks for expanding the diversity of our community with new members! + first_share: + name: First Share + description: Shared a post + long_description: | + This badge is granted the first time you share a link to a reply or topic using the share button. Sharing links is a great way to show off interesting discussions with the rest of the world and grow your community. + first_link: + name: First Link + description: Added a link to another topic + long_description: | + This badge is granted the first time you add a link to another topic. Linking topics helps fellow readers find interesting related conversations, by showing the connections between topics in both directions. Link freely! + first_quote: + name: First Quote + description: Quoted a post + long_description: | + This badge is granted the first time you quote a post in your reply. Quoting relevant sections of earlier posts in your reply helps keep discussions focused and on topic. And it's easy: you can quickly quote by highlighting a section of any post and using the Quote Reply button that appears near the selection. Quote generously! + read_guidelines: + name: Read Guidelines + description: Read the community guidelines + long_description: | + This badge is granted for reading the community guidelines. Following and sharing these simple guidelines helps build a safe, fun, and sustainable community for everyone. Always remember there's another human being, one very much like yourself, on the other side of that screen. Be nice! + reader: + name: Reader + description: Read every reply in a topic with more than 100 replies + long_description: | + This badge is granted the first time you read a long topic with more than 100 replies. Reading a conversation closely helps you follow the discussion, understand different viewpoints, and leads to more interesting conversations. The more you read, the better the conversation gets. As we like to say, Reading is Fundamental! :slight_smile: + popular_link: + name: Popular Link + description: Posted an external link with 50 clicks + long_description: | + This badge is granted when a link you shared gets 50 clicks. Thanks for posting a useful link that added interesting context to the conversation! + hot_link: + name: Hot Link + description: Posted an external link with 300 clicks + long_description: | + This badge is granted when a link you shared gets 300 clicks. Thanks for posting a fascinating link that drove the conversation forward and illuminated the discussion! + famous_link: + name: Famous Link + description: Posted an external link with 1000 clicks + long_description: | + This badge is granted when a link you shared gets 1000 clicks. Wow! You posted a link that significantly improved the conversation by addding essential detail, context, and information. Great work! + appreciated: + name: Appreciated + description: Received 1 like on 20 posts + long_description: | + This badge is granted when you receive at least one like on 20 different posts. The community is enjoying your contributions to the conversations here! + respected: + name: Respected + description: Received 2 likes on 100 posts + long_description: | + This badge is granted when you receive at least 2 likes on 100 different posts. The community is growing to respect your many contributions to the conversations here. + admired: + name: Admired + description: Received 5 likes on 300 posts + long_description: | + This badge is granted when you receive at least 5 likes on 300 different posts. Wow! The community admires your frequent, high quality contributions to the conversations here. + out_of_love: + name: Out of Love + description: Used 50 likes in a day + long_description: | + This badge is granted when you use all 50 of your daily likes. Remembering to take a moment and like the posts you enjoy and appreciate encourages your fellow community members to create even more great discussions in the future. + higher_love: + name: Higher Love + description: Used 50 likes in a day 5 times + long_description: | + This badge is granted when you use all 50 of your daily likes for 5 days. Thanks for taking the time actively encouraging the best conversations every day! + crazy_in_love: + name: Crazy in Love + description: Used 50 likes in a day 20 times + long_description: | + This badge is granted when you use all 50 of your daily likes for 20 days. Wow! You're a model of regularly encouraging your fellow community members! + thank_you: + name: Thank You + description: Has 20 liked posts and gave 10 likes + long_description: | + This badge is granted when you've received 20 likes on your posts and have given 10 or more likes in return. When someone likes your posts, you find the time to like what other people are posting in return. + gives_back: + name: Gives Back + description: Has 100 liked posts and gave 100 likes + long_description: | + This badge is granted when you've received 100 likes and have given 100 or more likes in return. Thanks for paying it forward, and liking in return! + empathetic: + name: Empathetic + description: Has 500 liked posts and gave 1000 likes + long_description: | + This badge is granted when you've received 500 likes and have given 1000 or more likes in return. Wow! You're a model of generosity and mutual love :two_hearts:. admin_login: success: "Email Sent" @@ -2550,3 +2972,6 @@ en: performance_report: initial_post_raw: This topic includes daily performance reports for your site. initial_topic_title: Website performance reports + + topic_invite: + user_exists: "Sorry, that user has already been invited. You may only invite a user to a topic once." diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml index 385334271f4..2265a587b22 100644 --- a/config/locales/server.es.yml +++ b/config/locales/server.es.yml @@ -10,18 +10,41 @@ es: short_date_no_year: "D MMM" short_date: "D MMM, YYYY" long_date: "D MMMM, YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%d-%m-%Y" + short_no_year: "%-d %B" + date_only: "%-d %B, %Y" + date: + month_names: [null, Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre] + <<: *datetime_formats title: "Discourse" topics: "Temas" posts: "posts" loading: "Cargando" powered_by_html: 'Funciona gracias a Discourse, se ve mejor con JavaScript activado' log_in: "Iniciar sesión" - via: "%{username} vía %{site_name}" - is_reserved: "está reservado" purge_reason: "Eliminada automáticamente como cuenta abandonada, sin activar" disable_remote_images_download_reason: "La descarga de imágenes remotas se desactivó porque no había suficiente espacio disponible en disco." anonymous: "Anónimos" - errors: + emails: + incoming: + default_subject: "Email entrante desde %{email}" + show_trimmed_content: "Mostrar contenido recortado" + errors: + empty_email_error: "Sucede cuando el texto en bruto del email que recibimos está en blanco." + no_message_id_error: "Sucede cuando el email no tiene Id del mensaje en el encabezado." + auto_generated_email_error: "Sucede cuando la 'prioridad' en el encabezado está establecida en: lista, basura, en masa o auto_respuesta, o cuando algún otro encabezado contiene: auto-enviado, auto-respondido o auto-generado." + no_body_detected_error: "Sucede cuando no podemos extraer el cuerpo del mensaje y no hay archivos adjuntos." + inactive_user_error: "Sucede cuando el emisor no está activo." + blocked_user_error: "Sucede cuando el emisor ha sido bloqueado." + bad_destination_address: "Sucede cuando ninguna de las direcciones de email en los campos Para/Cc/Bcc coincide con un email configurado como dirección de correo entrante." + strangers_not_allowed_error: "Sucede cuando un usuario intentó crear un nuevo tema en una categoría de la que no forma parte." + insufficient_trust_level_error: "Sucede cuando un usuario intentó crear un nuevo tema en una categoría para la que no tiene el nivel de confianza requerido." + reply_user_not_matching_error: "Sucede cuando una respuesta vino de una dirección de email diferente a la que fue enviada la notificación." + topic_not_found_error: "Sucede cuando entró una respuesta pero el tema relacionado ha sido eliminado." + topic_closed_error: "Sucede cuando entró una respuesta pero el tema relacionado ha sido cerrado. " + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "está limitado a %{max} caracteres; has introducido %{length}." @@ -37,8 +60,10 @@ es: exclusion: está reservado greater_than: debe ser más grande que %{count} greater_than_or_equal_to: debe ser igual o más grande que %{count} + has_already_been_used: "ya se está utilizando" inclusion: no está incluido en la lista invalid: no es válido + is_invalid: "no es válido; intenta ser más descriptivo" less_than: debe ser menor que %{count} less_than_or_equal_to: debe ser menor o igual que %{count} not_a_number: no es un número @@ -82,6 +107,8 @@ es: not_found: "No se ha podido encontrar la URL o recurso solicitado." invalid_access: "No tienes permiso para ver el recurso solicitado." read_only_mode_enabled: "El sitio está en modo sólo lectura. Las interacciones están deshabilitadas." + reading_time: "Tiempo de lectura" + likes: "Me gusta" too_many_replies: one: "Lo sentimos, pero los usuarios nuevos están limitados a 1 respuesta en el mismo tema." other: "Lo sentimos, pero los usuarios nuevos están limitados a %{count} respuestas en el mismo tema." @@ -98,29 +125,29 @@ es: replies: one: "1 respuesta" other: "%{count} respuestas" + no_mentions_allowed: "Lo sentimos, pero no puedes mencionar a otros usuarios." too_many_mentions: - zero: "Lo sentimos, pero no puedes mencionar a otros usuarios." - one: "Lo sentimos, pero solo puedes mencionar a un usuario en un post." + one: "Lo sentimos, solo puedes mencionar a un usuario en un post." other: "Lo sentimos, pero solo puedes mencionar a %{count} usuarios en un post." + no_mentions_allowed_newuser: "Lo sentimos, pero los usuarios nuevos no pueden mencionar a otros usuarios." too_many_mentions_newuser: - zero: "Lo sentimos, pero los usuarios nuevos no pueden mencionar a otros usuarios." one: "Lo sentimos, pero los usuarios nuevos solo pueden mencionar a un usuario en un post." other: "Lo sentimos, pero los usuarios nuevos solo pueden mencionar a %{count} usuarios en un post." + no_images_allowed: "Lo sentimos, pero los usuarios nuevos no pueden poner imágenes en los mensajes." too_many_images: - zero: "Lo sentimos, pero los usuarios nuevos no pueden poner imágenes en posts." one: "Lo sentimos, pero los usuarios nuevos solo pueden poner una imagen por post." other: "Lo sentimos, los nuevos usuarios solo pueden poner %{count} imágenes en un post." + no_attachments_allowed: "Lo sentimos, los usuarios nuevos no pueden adjuntar archivos en posts." too_many_attachments: - zero: "Lo sentimos, los usuarios nuevos no pueden adjuntar archivos en posts." one: "Lo sentimos, los usuarios nuevos solo pueden adjuntar un archivo por post" other: "Lo sentimos, los usuarios nuevos solo pueden adjuntar %{count} archivos por post." + no_links_allowed: "Lo sentimos, los nuevos usuarios no pueden poner enlaces en los posts." too_many_links: - zero: "Lo sentimos, los nuevos usuarios no pueden poner enlaces en los posts." one: "Lo sentimos, los nuevos usuarios solo pueden poner un link en un post." other: "Lo sentimos, los nuevos usuarios solo pueden poner %{count} enlaces en un post." spamming_host: "Lo sentimos, no puedes publicar un enlace a esa web." user_is_suspended: "A los usuarios suspendidos no se les permite publicar." - topic_not_found: "Algo ha salido mal. Tal vez este tema fue cerrado o eliminado mientras estabas mirando en él?" + topic_not_found: "Algo ha salido mal. ¿Tal vez este tema ha sido cerrado o eliminado mientras estabas lo estabas mirando?" just_posted_that: "es demasiado parecido a lo que has publicado recientemente" has_already_been_used: "ya ha sido utilizado" invalid_characters: "contiene caracteres no válidos" @@ -139,9 +166,14 @@ es: private_message_abbrev: "Msj" rss_description: latest: "Temas recientes" - hot: "Temas calientes" + hot: "Temas candentes" + top: "Top temas" posts: "Últimos posts" + private_posts: "Últimos mensajes privados" + group_posts: "Últimos posts de %{group_name}" + group_mentions: "Últimas menciones de %{group_name}" too_late_to_edit: "Ese post fue publicado hace demasiado tiempo. No puede ser editado ni eliminado." + revert_version_same: "La versión actual es la misma que la versión a la que intentas volver." excerpt_image: "imagen" queue: delete_reason: "Eliminado vía moderación" @@ -149,6 +181,10 @@ es: errors: can_not_modify_automatic: "No puedes modificar un grupo automático" member_already_exist: "'%{username}' ya es miembro de este grupo." + invalid_domain: "'%{domain}' no es un dominio válido." + invalid_incoming_email: "'%{email}' no es una dirección de email válida." + email_already_used_in_group: "'%{email}' ya está siendo utilizado por el grupo '%{group_name}'." + email_already_used_in_category: "'%{email}' ya está siendo utilizado por la categoría '%{category_name}'." default_names: everyone: "todos" admins: "administradores" @@ -203,11 +239,11 @@ es: En vez de añadir otra respuesta, por favor, considera editar tus respuestas previas o visitar otros temas. reviving_old_topic: | - ### ¿Resucitar este tema? + ### ¿Revivir este tema? La última respuesta a este tema fue hace %{days} días. Tu post reactivará el tema subiéndolo a las primeras posiciones de la lista y notificará a aquellos involucrados en la conversación previa. - ¿Estás seguro de que quieres continuar esta antigua conversación? + ¿Estás seguro de que quieres continuar esta conversación antigua? activerecord: attributes: category: @@ -217,9 +253,6 @@ es: user_profile: bio_raw: "Sobre mí" errors: - messages: - is_invalid: "no es válido; intenta ser un poco más descriptivo" - has_already_been_used: "ya ha sido utilizado" models: topic: attributes: @@ -240,6 +273,7 @@ es: attributes: hex: invalid: "no es un color válido" + <<: *errors user_profile: no_info_me: "
    El campo 'Sobre mí' de tu perfil está vacío, ¿Te gustaría completarlo?
    " no_info_other: "
    %{name} no has completado aún el campo 'Sobre mí' de tu perfil
    " @@ -275,13 +309,15 @@ es: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Definición de la categoría %{category}" - replace_paragraph: "[Reemplaza el primer párrafo con una descripción corta de tu nueva categoría. Esta guía aparecerá en el área de selección de categoría, por lo que trata de mantenerla por debajo de los 200 caracteres.]" - post_template: "%{replace_paragraph}\n\nUtiliza los siguientes párrafos para dar una descripción más larga y también para establecer cualquier norma o recomendación para esta categoría.\n\nAlgunos aspectos a tener en consideración en cualquier respuesta:\n\n- ¿Para que es esta categoría? ¿Por qué deben que seleccionar esta categoría como tema?\n\n- ¿Qué diferencia esta categoría de las demas?\n\n- ¿Es necesaria esta categoría?\n\n- ¿Deberíamos unir esta categoría con otra o dividirla en varias?\n" + replace_paragraph: "(Sustituye este primer párrafo con una descripción breve de tu nueva categoría. Esta descripción aparecerá en el área de selección de categoría, por ello, intenta que sea inferior a 200 caracteres. **Hasta que edites esta descripción o se creen temas, esta categoría no aparecerá en la página de categorías.**)" + post_template: "%{replace_paragraph}\n\nUtiliza los siguientes párrafos para una descripción más detallada, o establece las directrices o reglas de la categoría::\n\n- ¿Para qué podrían usar los usuarios esta categoría? ¿De qué trata?\n\n- ¿Cómo se distingue de otras categorías existentes?\n\n- ¿Qué temas debería contener esta categoría normalmente?\n\n- ¿Necesitamos esta categoría? ¿Podría agruparse o converger con otra categoría o subcategoría?\n" errors: uncategorized_parent: "Sin categoría no puede tener categoría primaria" self_parent: "La categoría primaria de una subcategoría no puede ser ella misma." depth: "No se puede anidar una subcategoría debajo de otra" - email_in_already_exist: "La dirección de email entrante '%{email_in}' ya está en uso para la categoría '%{category_name}'." + invalid_email_in: "'%{email}' no es una dirección de email válida." + email_already_used_in_group: "'%{email}' ya está siendo utilizado por el grupo '%{group_name}'." + email_already_used_in_category: "'%{email}' ya está siendo utilizado por la categoría '%{category_name}'." cannot_delete: uncategorized: "Sin categoría no se puede eliminar" has_subcategories: "No se puede eliminar esta categoría porque tiene sub-categorías." @@ -289,21 +325,36 @@ es: one: "No se puede eliminar esta categoría porque tiene 1 tema. El más antiguo es %{topic_link}." other: "No se puede eliminar esta categoría porque tiene %{count} temas. El tema más antiguo es %{topic_link}." topic_exists_no_oldest: "No se puede eliminar esta categoría porque el contador de temas está en %{count}." + uncategorized_description: "Debates que no necesitan una categoría, o bien no encajan en alguna de las categorías existentes." trust_levels: newuser: title: "nuevo usuario" basic: title: "usuario básico" - regular: + member: title: "miembro" + regular: + title: "regular" leader: - title: "habitual" - elder: title: "líder" change_failed_explanation: "Trataste de degradar a %{user_name} a '%{new_trust_level}'. Sin embargo su nivel de confianza ya es '%{current_trust_level}'. %{user_name} va a permanecer en '%{current_trust_level}' - si deseas degradar al usuario primero bloquea su nivel de confianza." rate_limiter: - slow_down: "Has realizado esta acción demasiadas veces, inténtalo de nuevo más tarde" + slow_down: "Has realizado esta acción muchas veces, inténtalo de nuevo más tarde." too_many_requests: "Estas haciendo eso demasiado a menudo. Por favor espera %{time_left} antes de intentarlo de nuevo." + by_type: + first_day_replies_per_day: "Has llegado al límite de respuestas que un nuevo usuario puede crear en su primer día. Por favor, espera %{time_left} antes de intentarlo de nuevo." + first_day_topics_per_day: "Has llegado al límite de temas que un nuevo usuario puede crear en su primer día. Por favor, espera %{time_left} antes de intentarlo de nuevo." + create_topic: "Estás creando temas demasiado rápido. Por favor, espera %{time_left} antes de intentarlo de nuevo." + create_post: "Estás respondiendo demasiado rápido. Por favor, espera %{time_left} antes de intentarlo de nuevo." + delete_post: "Estás eliminando posts demasiado rápido. Por favor espera %{time_left} antes de intentarlo de nuevo." + topics_per_day: "Has llegado al límite de nuevos temas de hoy. Por favor, espera %{time_left} antes de intentarlo de nuevo." + pms_per_day: "Has llegado al límite de mensajes de hoy. Por favor, espera %{time_left} antes de intentarlo de nuevo." + create_like: "Has llegado al límite de Me gusta de hoy. Por favor, espera %{time_left} antes de intentarlo de nuevo." + create_bookmark: "Has llegado al límite de marcadores de hoy. Por favor, espera %{time_left} antes de intentarlo de nuevo." + edit_post: "Has llegado al límite de ediciones de hoy. Por favor, espera %{time_left} antes de intentarlo de nuevo." + live_post_counts: "Estás solicitando actualizaciones de posts demasiado rápido. Por favor, espera %{time_left} antes de intentarlo de nuevo." + unsubscribe_via_email: "Has alcanzado el máximo de bajas de suscripción vía email por hoy. Por favor espera %{time_left} antes de intentarlo de nuevo." + topic_invitations_per_day: "Has alcanzado el máximo de invitaciones a temas por hoy. Por favor, espera %{time_left} antes de intentarlo de nuevo." hours: one: "1 hora" other: "%{count} horas" @@ -398,6 +449,11 @@ es: confirmed: "Tu email ha sido actualizado." please_continue: "Continuar a %{site_name}" error: "Hubo un problema cambiando tu dirección de email. ¿Quizás la dirección ya está en uso?" + error_staged: "Hubo un error al cambiar tu email. La dirección ya está en uso por un usuario provisional." + already_done: "Lo sentimos, este enlace de confirmación ya no es válido. ¿Quizá tu email ya fue cambiado?" + authorizing_old: + title: "Gracias por confirmar tu dirección de correo actual" + description: "Te enviaremos un email a tu nueva dirección para confirmar." activation: action: "Haz clic aquí para activar tu cuenta" already_done: "Lo sentimos, este link de confirmación de cuenta ya no es válido. ¿Quizás tu cuenta ya está activa?" @@ -422,16 +478,16 @@ es: description: 'Este post contiene contenido que una persona sensata podría considerar ofensivo, abusivo o que viola nuestras directrices de comunidad.' long_form: 'reportado como inapropiado' notify_user: - title: 'Notificar por mensaje a @{{username}}' - description: 'Este post contiene algo que yo quiero hablar con esta persona directa y privadamente. No se marca como bandera.' + title: 'Enviar un mensaje a @{{username}}' + description: 'Quiero hablar con esta persona de forma directa y privada sobre su mensaje.' long_form: 'usuario notificado vía mensaje' email_title: 'Tu publicación en "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Notificar a los moderadores" - description: 'Este post requiere la atención de un moderador por otra razón distinta a las mencionadas arriba.' - long_form: 'reportado para atención de los moderadores' - email_title: 'Un post en "%{title}" requiere la atención de un moderador' + description: 'Este mensaje requiere la atención del equipo de moderación por una razón no especificada arriba.' + long_form: 'reportó esto' + email_title: 'Un mensaje en "%{title}" requiere atención del staf' email_body: "%{link}\n\n%{message}" bookmark: title: 'Marcador' @@ -456,7 +512,7 @@ es: long_form: 'marcado como inapropiado' notify_moderators: title: "Notificar a los moderadores" - description: 'Este tema requiere la atención de un moderador, en base a nuestras directrices, CDS, o por otra razón distinta a las mencionadas.' + description: 'Este tema requiere atención del equipo de moderación basándose en las pautas de la comunidad o los Términos y condiciones, o por otra razón no especificada arriba.' long_form: 'reportado para atención de los moderadores' email_title: 'El tema "%{title}" requiere la atención de un moderador' email_body: "%{link}\n\n%{message}" @@ -492,6 +548,10 @@ es: title: "Nuevos usuarios" xaxis: "Día" yaxis: "Número de usuarios nuevos" + profile_views: + title: "Visitas a perfil de usuario" + xaxis: "Día" + yaxis: "Número de perfiles de usuario vistos" topics: title: "Temas nuevos" xaxis: "Día" @@ -643,42 +703,16 @@ es: consumer_email_warning: "Tu sitio está configurado para Utilizar Gmail (u otro servicio de email de consumidor) para enviar email. Gmail limita la cantidad de emails que puedes enviar. Considera usar un proveedor de servicio email como mandrill.com para asegurarte la entrega de los emails." site_contact_username_warning: "Introduce el nombre de un administrador o moderador simpático desde el cual se enviarán mensajes automáticos importantes. Actualiza site_contact_username en Ajustes del sitio." notification_email_warning: "Las notificaciones por email no están siendo enviadas desde una dirección de correo electrónico válida en tu dominio; la entrega de emails será errática y poco fiable. Por favor, establece para notification_email una dirección de correo electrónico local válida en Ajustes del sitio." - content_types: - education_new_reply: - title: "Educación de nuevo usuario: primeras respuestas" - description: "Un mensaje emergente de guia 'justo a tiempo' aparecerá automáticamente sobre el compositor cuando nuevos usuarios empiecen ingresar sus dos primeras respuestas." - education_new_topic: - title: "Educación de nuevo usuario: primeros temas" - description: "Un mensaje emergente de guia 'justo a tiempo' aparecerá automáticamente sobre el compositor cuando nuevos usuarios empiecen ingresar sus dos primeras respuestas." - usage_tips: - title: "Consejos para nuevos usuarios" - description: "Guía e información esencial para los nuevos usarios." - welcome_user: - title: "Bienvenido: nuevo usuario" - description: "Un mensaje que se enviará automáticamente a todos los nuevos usuarios cuando se registren." - welcome_invite: - title: "Bienvenido: usuario invitado" - description: "Un mensaje que se enviará automáticamente a todos los nuevos usuarios invitados cuando acepten la invitación de otro usuario." - login_required_welcome_message: - title: "Registro requerido: mensaje de bienvenida" - description: "El mensaje de bienvenida que se muestra a los usuarios que han salido cuando la configuración de 'login required' está activada." - login_required: - title: "Registro Requerido: Homepage" - description: "El texto mostrado para usuarios no autorizados cuando el registro es requerido en el sitio." - head: - title: "HTML head" - description: "HTML que va a ser insertado dentro de las etiquetas" - top: - title: "Encabezado de página" - description: "HTML que va a ser añadido encima de cada página (después del header, y antes de la navegación o el título del tema)." - bottom: - title: "Pie de página" - description: "HTML que será añadido antes de la etiqueta " + subfolder_ends_in_slash: "La configuación del subdirectorio no es correcta; el campo DISCOURSE_RELATIVE_URL_ROOT termina con una barra." + email_polling_errored_recently: + one: "El email polling ha generado un error en las pasadas 24 horas. Mira en los logs para más detalles." + other: "El email polling ha generado %{count} errores en las pasadas 24 horas. Mira en los logs para más detalles." site_settings: censored_words: "Las palabras serán reemplazadas con ■■■■" delete_old_hidden_posts: "Auto-borrar cualquier post que se quede oculto por mas de 30 días." default_locale: "El idioma por defecto de Discourse (ISO 639-1 Code)" allow_user_locale: "Permitir que los usuarios escojan su propio idioma para la interfaz" + set_locale_from_accept_language_header: "Establece el lenguaje de la interfaz para usuarios anónimos desde el lenguaje declarado por su navegador web. (EXPERIMENTAL, no funciona con caché anónimo)" min_post_length: "Extensión mínima de los posts, en número de caracteres" min_first_post_length: "Extensión mínima permitida en el primer mensaje (cuerpo del tema) en caracteres" min_private_message_post_length: "Extensión mínima de los posts en los mensajes, en número de caracteres" @@ -687,8 +721,8 @@ es: max_topic_title_length: "Extensión máxima del título de los temas, en número de caracteres" min_private_message_title_length: "Extensión mínima del título de los temas en mensajes, en número de caracteres" min_search_term_length: "Extensión mínima de una búsqueda válida, en número de caracteres" + search_tokenize_chinese_japanese_korean: "Forzar la búsqueda a tokenizar Chino/Japonés/Coreano incluso en sitios que no basados en esos idiomas" allow_uncategorized_topics: "Permitir la creación de temas sin categoría. AVISO: Si ya hay algún tema sin categoría, debes recategorizarlo antes de activar esta opción." - uncategorized_description: "La descripción de la categoría Sin categoría. Déjalo en blanco para no añadir descripción." allow_duplicate_topic_titles: "Permitir temas con títulos idénticos, duplicados." unique_posts_mins: "¿Cuántos minutos deben pasar antes de que un usuario pueda publicar el mismo contenido de nuevo?" educate_until_posts: "Cuando el usuario comienza a escribir su primer o primeros (n) posts, mostrar un pop-up con el panel de consejos para nuevos usuarios en el editor." @@ -701,7 +735,7 @@ es: download_remote_images_to_local: "Convertir imágenes remotas a imágenes locales descargándolas; esto previene imágenes rotas." download_remote_images_threshold: "Mínimo espacio en disco necesario para descargar imágenes remotas de forma local (porcentaje)" disabled_image_download_domains: "Las imágenes remotas que provengan de estos dominios no serán descargadas. Lista delimitada por barras." - ninja_edit_window: "Durante (n) segundos después de publicar un post, se puede editar ese post sin crear una nueva versión en el historial." + editing_grace_period: "Durante (n) segundos después de publicar un post, se puede editar ese post sin crear una nueva versión en el historial." post_edit_time_limit: "El autor puede editar o eliminar su post durante (n) minutos después de publicarlo. Pon un 0 para que pueda hacerlo siempre." edit_history_visible_to_public: "Permitir a todos ver las versiones previas de un post editado. Si se deshabilita, solo los miembros del staff podrán verlas." delete_removed_posts_after: "Los posts borrados por su autor serán automáticamente eliminados después de (n) horas. Si se establece este valor a 0, los posts serán eliminados automáticamente." @@ -731,7 +765,7 @@ es: summary_likes_required: "Mínimo de \"me gusta\" en un tema para habilitar 'Resumen de este tema'" summary_percent_filter: "Cuando un usuario hace clic en 'Resumen de este tema', se muestra el n % mejores posts" summary_max_results: "Máximo de posts devueltos en \"Resumen de este tema\"" - enable_private_messages: "Permitir a los usuarios de nivel de confianza 1 crear y responder mensajes" + enable_private_messages: "Permitir a los usuarios de nivel 1 (configurable vía nivel de confianza para enviar mensajes) crear y responder mensajes" enable_long_polling: "Los mensajes usados para notificaciones pueden usar el long polling" long_polling_base_url: "URL base usada para el 'long polling' (cuando un CDN esta sirviendo contenido dinámico, asegúrate de ajustar esto al 'pull' de origen) ejemplo: http://origin.site.com" long_polling_interval: "Cantidad de tiempo que el servidor debe de esperar antes de responder a los clientes que no hay datos enviados (solamente usuarios con sesión iniciada)." @@ -750,9 +784,10 @@ es: notify_mods_when_user_blocked: "Si un usuario es bloqueado automáticamente, enviar un mensaje a todos los moderadores." flag_sockpuppets: "Si un nuevo usuario responde a un tema desde la misma dirección de IP que el nuevo usuario que inició el tema, reportar los posts de los dos como spam en potencia." traditional_markdown_linebreaks: "Utiliza saltos de línea tradicionales en Markdown, que requieren dos espacios al final para un salto de línea." - allow_html_tables: "Permitir la inserción de tablas en Markdown usando etiquetas HTML como TABLE, THEAD, TD, TR o TH (requiere un rebake completo para todos los posts antiguos que contengan tablas)" + allow_html_tables: "Permitir la inserción de tablas en Markdown usando etiquetas HTML. Se permitirá usar TABLE, THEAD, TD, TR o TH (requiere un rebake completo para los posts antiguos que contengan tablas)" post_undo_action_window_mins: "Número de minutos durante los cuales los usuarios pueden deshacer sus acciones recientes en un post (me gusta, reportes, etc)." must_approve_users: "Los miembros administración deben aprobar todas las nuevas cuentas antes de que se les permita el acceso al sitio. AVISO: ¡habilitar esta opción en un sitio activo revocará el acceso a los usuarios que no sean moderadores o admin!" + pending_users_reminder_delay: "Notificar a los moderadores si hay nuevos usuarios que hayan estado esperando aprbación durante más estas horas. Usa -1 para desactivar estas notificaciones." ga_tracking_code: "Código de Google Analytics, ej: UA-12345678-9; visita http://google.com/analytics" ga_domain_name: "El nombre de dominio especificado en Google Analytics (ga.js). Ejemplo: misitio.com; ver en http://google.com/analytics" ga_universal_tracking_code: "Código de seguimiento de Google Universal Analytics (analytics.js), ejemplo: UA-12345678-9; visita http://google.com/analytics" @@ -761,6 +796,7 @@ es: enable_noscript_support: "Habilitar el soporte de motor de búsqueda estándar webcrawler mediante la etiqueta noscript" allow_moderators_to_create_categories: "Permitir a los moderadores crear nuevas categorías" cors_origins: "Orígenes permitidos para las cross-origin requests (CORS). Cada origen debe incluir http:// or https://. La variable env DISCOURSE_ENABLE_CORS debe establecerse a verdadero para activar CORS." + use_admin_ip_whitelist: "Los admins solo pueden iniciar sesión si están en una dirección IP definida en la lista de Screened IPs (Admin > Logs > Screened Ips)." top_menu: "Determinar que items aparecen en la navegación de la home y en qué orden. Ejemplo latest|new|unread|categories|top|read|posted|bookmarks" post_menu: "Determina qué elementos aparecen en el menú de un post y en qué orden. Ejemplo: like|edit|flag|delete|share|bookmark|reply" post_menu_hidden_items: "Los elementos del menú a ocultar por defecto en el menú de cada post a menos que se haga clic en el botón para expandir las opciones." @@ -772,15 +808,15 @@ es: suppress_reply_directly_above: "No mostrar el en-respuesta-a desplegable en un post cuando solo hay una sola respuesta justo encima del post." suppress_reply_when_quoting: "No mostrar el desplegable en-respuesta-a en un post cuando el post cite la respuesta." max_reply_history: "Número máximo de respuestas a mostrar al expandir en-respuesta-a" - experimental_reply_expansion: "Ocultar respuestas intermedias cuando se expande una respuesta (experimental)" topics_per_period_in_top_summary: "Número de mejores temas mostrados en el resumen de mejores temas." topics_per_period_in_top_page: "Número de mejores temas mostrados en la vista expandida al clicar en 'ver más'." redirect_users_to_top_page: "Redirigir automáticamente a los nuevos usuarios y a los ausentes de larga duración a la página de mejores temas." + top_page_default_timeframe: "Período de tiempo por defecto para la página de temas top" show_email_on_profile: "Mostrar el e-mail los usuarios en su perfil (solamente visibles para ellos mismos y el staff)" email_token_valid_hours: "Los tokens para restablecer contraseña olvidada / activar cuenta son válidos durante (n) horas." email_token_grace_period_hours: "Los tokens para restablecer contraseña olvidada / activar cuenta son válidos durante (n) horas de periodo de gracia, después de ser redimidos." enable_badges: "Activar el sistema de distintivos" - enable_whispers: "Permitir a los usuarios enviar susurros a los moderadores" + enable_whispers: "Permitir al staff comunicarse privadamente en los temas. (experimental)" allow_index_in_robots_txt: "Especificar en robots.txt que este sitio puede ser indexado por los motores de búsqueda web." email_domains_blacklist: "Una lista de dominios de correo electrónico con los que los usuarios no se podrán registrar. Ejemplo: mailinator.com|trashmail.net" email_domains_whitelist: "Una lista de dominios de email con los que los usuarios DEBERÁN registrar sus cuentas. AVISO: ¡los usuarios con un email con diferente dominio a los listados no estarán permitidos!" @@ -798,6 +834,7 @@ es: max_username_length: "Longitud máxima del nombre de usuario en caracteres." reserved_usernames: "Nombres de usuario no permitidos en el registro." min_password_length: "Longitud mínima de contraseña." + min_admin_password_length: "Longitud mínima de la contraseña para un Admin." block_common_passwords: "No permitir contraseñas que están entre las 10.000 más comunes." enable_sso: "Activar single sign on a través de un sitio externo (AVISO: ¡LAS DIRECCIONES DE EMAIL SERÁN VALIDADAS POR EL SITIO EXTERNO!)" enable_sso_provider: "Implementar el protocolo del proveedor de SSO de Discourse en el endpoint /session/sso_provider requiere establecer un sso_secret" @@ -818,6 +855,9 @@ es: enable_twitter_logins: "Activar autenticación por Twitter, requiere una twitter_consumer_key y un twitter_consumer_secret" twitter_consumer_key: "Comsumer key para autenticación por Twitter, registrado en http://dev.twitter.com" twitter_consumer_secret: "Comsumer secret para autenticación por Twitter, registrado en http://dev.twitter.com" + enable_instagram_logins: "Activar la autenticación por Instagram, requiere instagram_consumer_key y instagram_consumer_secret" + instagram_consumer_key: "Consumer key para autenticación por Instagram" + instagram_consumer_secret: "Consumer secret para autenticación por Instagram" enable_facebook_logins: "Activar autenticación por Facebook, requiere una facebook_app_id y un facebook_app_secret" facebook_app_id: "App id para la autenticación por Facebook, registrado en https://developers.facebook.com/apps" facebook_app_secret: "App secret para autenticación por Facebook, registrado en https://developers.facebook.com/apps" @@ -830,9 +870,15 @@ es: backup_frequency: "Con qué frecuencia, en días, crearemos un backup del sitio." enable_s3_backups: "Sube copias de seguridad a S3 cuando complete. IMPORTANTE: requiere credenciales validas de S3 puestas Archivos configuración." s3_backup_bucket: "El bucket remoto para mantener copias de seguridad. AVISO: Asegúrate de que es un bucket privado." + s3_disable_cleanup: "Desactivar el eliminado de backups de S3 cuando se eliminen de forma local." + backup_time_of_day: "Hora UTC del día cuando debería ejecutarse el backup." + backup_with_uploads: "Incluir archivos adjuntos en los backups programados. Desactivando esta opción tan solo se ejecutará una copia de seguridad de la base de datos." active_user_rate_limit_secs: "Con qué frecuencia actualizaremos el campo 'last_seen_at', en segundos" verbose_localization: "Mostrar sugerencias de localización extendida en la interface de usuario " previous_visit_timeout_hours: "Cuanto tiempo debe pasar antes de que una visita sea considerada la 'visita previa', en horas" + top_topics_formula_log_views_multiplier: "valor del multiplicador de visitas (n) en la fórmula de temas top: `log(views_count) * (n) + op_likes_count * 0.5 + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_first_post_likes_multiplier: "valor del multiplicador de me gusta en el primer post (n) en la fórmula de temas top:: `log(views_count) * 2 + op_likes_count * (n) + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_least_likes_per_post_multiplier: "valor del multiplicador de me gusta por post (n) en la fórmula de temas top: `log(views_count) * 2 + op_likes_count * 0.5 + LEAST(likes_count / posts_count, (n)) + 10 + log(posts_count)`" rate_limit_create_topic: "Después de crear un tema, los usuarios deben esperar (n) segundos antes de crear otro tema." rate_limit_create_post: "Después de publicar un post, los usuarios deben esperar (n) segundos antes de crear otro post." rate_limit_new_user_create_topic: "Después de crear un tema, los nuevos usuarios deben esperar (n) segundos antes de crear otro tema." @@ -845,6 +891,8 @@ es: max_private_messages_per_day: "Máximo número de mensajes por usuario y día." max_invites_per_day: "Máximo número de invitaciones que un usuario puede enviar al día." max_topic_invitations_per_day: "Máximo número de invitaciones a un tema que un usuario puede enviar por día." + alert_admins_if_errors_per_minute: "Número de errores por minuto que activa la alerta a administración. Un valor de 0 desactiva esta funcionalidad. NOTA: requiere reiniciar la instancia." + alert_admins_if_errors_per_hour: "Número de errores por hora que activa la alerta a administración. Un valor de 0 desactiva esta funcionalidad. NOTA: requiere reiniciar la instancia." suggested_topics: "Número de temas sugeridos mostrados al pie del tema." limit_suggested_to_category: "Solo mostrar temas de la categoría actual en los temas sugeridos." clean_up_uploads: "Eliminar subidas huérfanas sin referencia para prevenir hosting ilegal. AVISO: antes de habilitar esta opción quizá quieres hacer un backup de tu directorio de /uploads" @@ -861,6 +909,8 @@ es: avatar_sizes: "Lista de tamaños de avatar generados automáticamente." external_system_avatars_enabled: "Usar un servicio externo para los avatares." external_system_avatars_url: "Dirección URL del servicio externo para los avatares. Sustituciones permitidas: {username} {first_letter} {color} {size}" + default_opengraph_image_url: "URL de la imagen opengraph por defecto." + allow_all_attachments_for_group_messages: "Permitir todos los archivos adjuntos de email para los mensajes a grupos." enable_flash_video_onebox: "Habilitar el embebido de enlaces swf y flv (Adobe Flash) en formato Onebox. AVISO: podría introducir riesgos de seguridad." default_invitee_trust_level: "Nivel de confianza por defecto (0-4) para usuarios invitados." default_trust_level: "Nivel de confianza por defecto (0-4) para los nuevos usuarios. ¡AVISO! Cambiar esto puede resultar en riesgo por spam." @@ -874,32 +924,38 @@ es: tl2_requires_likes_received: "¿Cuántos 'me gusta' un usuario debe de recibir antes de promoverlo a nivel de confianza 2?" tl2_requires_likes_given: "¿Cuántos 'me gusta' un usuario debe de dar antes de promoverlo a nivel de confianza 2?" tl2_requires_topic_reply_count: "¿Cuántos temas un usuario debe de contestar antes de promoverlo a nivel de confianza 2?" - tl3_requires_days_visited: "El número mínimo de días que un usuario necesito haber visitado el sitio en los últimos 100 días para calificar a promoción de nivel de confianza 3. (0 a 100)" - tl3_requires_topics_replied_to: "El número mínimo de temas que un usuario necesito haber respondido en los últimos 100 días para calificar a promoción de nivel de confianza 3. (0 o superior)." - tl3_requires_topics_viewed: "El porcentaje de temas creados en los últimos 100 días que un usuario necesito haber visto para calificar a promoción de nivel de confianza 3. (0 a 100)" - tl3_requires_posts_read: "El porcentaje de posts creados en los últimos 100 días que un usuario necesito haber visto para calificar a promoción de nivel de confianza 3. (0 a 100)" + tl3_time_period: "Período de tiempo (en días) para los requisitos de nivel de confianza 3" + tl3_requires_days_visited: "Mínimo número de días que un usuario necesita haber visitado el sitio en los últimos (tl3 time period) días para poder ser promocionado a nivel de confianza 3. Establece un valor superior para desactivar la posibilidad de subir a nivel de confianza 3. (0 o más)" + tl3_requires_topics_replied_to: "Mínimo número de temas que un usuario necesita haber respondido en los últimos (tl3 time period) días para poder ser promocionado a nivel de confianza 3. (0 o más)" + tl3_requires_topics_viewed: "Porcentaje de temas creados en los últimos (tl3 time period) días para que un usuario sea tenido en cuenta para promocionar a nivel de confianza 3. (0 a 100)" + tl3_requires_posts_read: "El porcentaje de posts creados en los últimos (tl3 time period) días para que un usuario sea tenido en cuenta para promocionar a nivel de confianza 3. (0 a 100)" tl3_requires_topics_viewed_all_time: "El número total mínimo de temas que un usuario debió de haber visto para calificar a promoción de nivel de confianza 3." tl3_requires_posts_read_all_time: "El número mínimo total de posts que un usuario debió de haber leído para calificar a nivel de confianza 3." - tl3_requires_max_flagged: "El usuario no debió de haber tenido mas de x posts reportados por más de x diferentes usuarios en los últimos 100 días para calificar a promoción de nivel de confianza 3, donde x es el valor de configuración. (0 o superior)." + tl3_requires_max_flagged: "El usuario no debe haber tenido más de x posts reportados por x diferentes usuarios en los últimos (tl3 time period) días para poder ser promocionado a nivel de confianza 3, donde x es el valor de esta opción. (0 o más)" tl3_promotion_min_duration: "El número mínimo de días que una promoción de nivel de confianza 3 dura antes que el usuario pueda ser degradado de vuelta a nivel de confianza 2." - tl3_requires_likes_given: "El número mínimo de 'me gusta' que deben de ser dados en los últimos 100 días para calificar a promoción de nivel de confianza 3." - tl3_requires_likes_received: "El número mínimo de 'me gusta' que debió haber recibido en los últimos 100 días para calificar a promoción de nivel de confianza 3." + tl3_requires_likes_given: "El mínimo número de me gusta que un usuario debe dar en los últimos (tl3 time period) días para promocionar a nivel de confianza 3." + tl3_requires_likes_received: "El mínimo número de me gusta que un usuario debe recibir en los últimos (tl3 time period) días para promocionar a nivel de confianza 3." tl3_links_no_follow: "No remover rel=nofollow de los enlaces publicados por usuarios con nivel de confianza 3." min_trust_to_create_topic: "El mínimo nivel de confianza requerido para crear un nuevo tema." min_trust_to_edit_wiki_post: "El mínimo nivel de confianza requerido para editar un post marcado como wiki." + min_trust_to_allow_self_wiki: "El mínimo nivel de confianza requerido para que un usuario convierta sus propios posts a wiki." + min_trust_to_send_messages: "Mínimo nivel de confianza requerido para crear nuevos mensajes directos." newuser_max_links: "Cuántos enlaces puede un nuevo usuario añadir a un post." newuser_max_images: "Cuántas imágenes puede un nuevo usuario añadir a un post." newuser_max_attachments: "Cuántos adjuntos puede un nuevo usuario añadir a un post." newuser_max_mentions_per_post: "Máximo número de menciones a @usuarios que un nuevo usuario puede usar en un post." newuser_max_replies_per_topic: "Máximo número de respuestas que un nuevo usuario puede realizar en el mismo tema antes de que alguien responda a su vez a alguna de ellas." max_mentions_per_post: "Máximo número de menciones a @usuarios que alguien puede usar en un post." + max_users_notified_per_group_mention: "Número de usuarios máximos que serán notificados si un grupo es mencionado (si se llega al límite no se mandarán más invitaciones)" create_thumbnails: "Crear miniaturas de imágenes y lightbox cuando estas son demasiado grandes para encajar en un post." email_time_window_mins: "Esperar (n) minutos antes de enviar cualquier email de notificación, para dar a los usuarios margen con el que editar y finalizar sus posts." + private_email_time_window_seconds: "Espera (n) segundos antes de enviar cualquier email de notificación, para dar a los usuarios margen con el que editar y finalizar sus mensajes." email_posts_context: "Cuántas respuestas previas se incluirán como contexto en los emails de notificación." flush_timings_secs: "Cuán frecuente, en segundos, se alinean los datos de sincronización con el servidor." title_max_word_length: "La longitud máxima permitida de una palabra, en caracteres, en el título del tema." title_min_entropy: "La mínima entropía permitida (caracteres únicos) requerida para el título de un tema." body_min_entropy: "La mínima entropía permitida (caracteres únicos) requerida para el cuerpo de un post." + allow_uppercase_posts: "Permite todas mayúsculas en el título de un tema o en el cuerpo del mensaje" title_fancy_entities: "Convertir caracteres ASCII comunes en entidades HTML de adorno en el título de los temas, como SmartyPants http://daringfireball.net/projects/smartypants/" min_title_similar_length: "La extensión mínima que un título debe tener antes de revisar temas similares." min_body_similar_length: "La extensión mínima que el cuerpo de un post debe tener antes de revisar temas similares." @@ -929,6 +985,7 @@ es: white_listed_spam_host_domains: "Una lista de dominios a excluir de las pruebas de spam. A los nuevos usuarios no se les restringirá la posibilidad de crear posts con enlaces a estos dominios." staff_like_weight: "Qué ponderación extra otorgan los me gusta provenientes de los miembros del Staff." topic_view_duration_hours: "Contar una visita a un nuevo tema por IP/Usuario cada N horas" + user_profile_view_duration_hours: "Contar una nueva visita de perfil por IP/Usuario cada N horas" levenshtein_distance_spammer_emails: "Al revisar coincidencias por correos electrónicos de spammers, qué número de caracteres permiten una coincidencia parcial." max_new_accounts_per_registration_ip: "Si ya hay (n) cuentas con nivel de confianza 0 desde esta IP (y ninguna es de un miembro del staff o de nivel de confianza 2 o más), prohibir nuevos registros desde esa IP." min_ban_entries_for_roll_up: "Al hacer clic en el botón Agrupar, se crea un nuevo rango de entradas para banear si hay al menos (N) entradas." @@ -946,6 +1003,13 @@ es: disable_emails: "Impedir que Discourse envié cualquier tipo de e-mail." strip_images_from_short_emails: "Remover imágenes de e-mails que tengan un tamaño menor a 2800 Bytes" short_email_length: "e-mail corto longitud en Bytes" + display_name_on_email_from: "Mostrar nombres completos en los campos de remitente de emails" + unsubscribe_via_email: "Permitir a los usuarios darse de baja de los emails respondiendo con el texto 'unsubscribe' en el asunto o el cuerpo del mensaje" + unsubscribe_via_email_footer: "Adjuntar un enlace para darse de baja al pie de los emails enviados" + delete_email_logs_after_days: "Eliminar logs de email después de (N) días. Si es 0 permanecerán de forma indefinida." + max_emails_per_day_per_user: "Máximo número de emails a enviar a los usuarios por día. Establece 0 para desactivar el límite" + enable_staged_users: "Crear cuentas provisionales automáticamente al procesar emails entrantes." + manual_polling_enabled: "Lanza emails usando la API para las respuestas por email." pop3_polling_enabled: "Poll vía POP3 para respuestas de e-mail." pop3_polling_ssl: "Usar SSL mientras se conecta al servidor POP3. (Recomendado)" pop3_polling_period_mins: "El período en minutos entre revisiones de correo de la cuenta POP3. NOTA: requiere reiniciar." @@ -972,7 +1036,8 @@ es: automatically_download_gravatars: "Descargar Gravatars para usuarios cuando se creen una cuenta o cambien el email." digest_topics: "El número máximo de temas a mostrar en el resumen por email." digest_min_excerpt_length: "La extensión mínima, en caracteres, del extracto de un post en el resumen por email." - suppress_digest_email_after_days: "Suprimir los emails de resumen para aquellos usuarios que no han visto el sitio desde más de (n) días." + delete_digest_email_after_days: "Omitir los emails de resumen para usuarios que no hayan visto el sitio después de (n) días." + digest_suppress_categories: "Ocultar estas categorías de los emails de resumen." disable_digest_emails: "Inhabilitar e-mails de resumen para todos los usuarios." detect_custom_avatars: "Verificar o no que los usuarios han subido una imagen de perfil." max_daily_gravatar_crawls: "Máximo número de veces que Discourse comprobará Gravatar en busca de avatares personalizados en un día" @@ -982,51 +1047,60 @@ es: allow_anonymous_posting: "Permitir a los usuarios cambiar a modo anónimo" anonymous_posting_min_trust_level: "Nivel de confianza mínimo requerido para activar el modo anónimo" anonymous_account_duration_minutes: "Para proteger el anonimato, crear una nueva cuenta anónima cada N minutos para cada usuario. Ejemplo: si se establece en 600, tan pronto como pasen 600 minutos desde el último post Y el usuario cambie a anónimo, se creará una nueva cuenta anónima." + hide_user_profiles_from_public: "Desactiva las tarjetas de usuario, los perfiles y el directorio de usuarios para usuarios anónimos." allow_profile_backgrounds: "Permitir a los usuarios subir sus propios fondos de perfil personalizados." - sequential_replies_threshold: "Número de posts consecutivos que un usuario publicará en un mismo tema hasta mostrarle un recordatorio sobre demasiadas repuestas seguidas." + sequential_replies_threshold: "Número de mensajes que un usuario tiene que publicar seguidos antes de que se le recuerde sobre demasiadas respuestas consecutivas." enable_mobile_theme: "Los dispositivos móviles utilizan un tema adaptado, con la habilidad de cambiar al estilo de sitio completo. Deshabilita esta opción si quieres utilizar una plantilla personalizada que sea completamente adaptable." dominating_topic_minimum_percent: "Qué porcentaje de posts tiene que publicar un usuario en un mismo tema hasta mostrarle un recordatorio acerca de dominar en demasía un tema." + disable_avatar_education_message: "Desactivar mensaje incentivador para que los usuarios se cambien su foto de perfil." daily_performance_report: "Analizar registros de NGINX diariamente y publicar un tema para Administradores con los detalles" suppress_uncategorized_badge: "No mostrar la etiqueta de los temas sin categoría en la lista de temas." + permalink_normalizations: "Aplicar la siguiente expresión regular antes de los enlaces, por ejemplo: /(topic.*)\\?.*/\\1 despojará las cadenas de consulta de las rutas de los temas. El formato es regex+string usa \\1 etc. para acceder a capturas" global_notice: "Mostrar una noticia de URGENCIA o EMERGENCIA para todos los visitantes, deja este campo en blanco para ocultarla (se puede utilizar código HTML)" disable_edit_notifications: "Inhabilitar editar notificaciones por el usuario system cuando 'download_remote_images_to_local' este activo." - full_name_required: "Su nombre completo es un campo obligatorio de un perfil de usuario." + automatically_unpin_topics: "Quitar destacado automáticamente cuando el usuario llega al final del tema." + read_time_word_count: "Número de palabras por minuto para calcular el tiempo de lectura estimado." + full_name_required: "El nombre completo es un campo obligatorio del perfil de usuario." enable_names: "Mostrar el nombre completo del usuario en su perfil, tarjeta de usuario y emails. Desactiva esta opción para ocultar el nombre completo en todas partes." display_name_on_posts: "Mostrar el nombre completo de un usuario en sus posts, además de su @usuario." show_time_gap_days: "Si entre dos publicaciones han pasado este número de días, mostrar el lapso de tiempo en el tema." invites_per_page: "Número de invitaciones por defecto mostradas en la página de perfil del usuario." short_progress_text_threshold: "Después de que un número de posts en un tema alcance esta cifra, la barra de progreso sólo mostrará el número del post actual. Si cambias el ancho de la barra de progreso, deberías revisar este valor." default_code_lang: "Lenguaje de programación por defecto para aplicar el resaltado de la sintaxis en los bloques de código de GitHub (lang-auto, ruby, python etc.)" - warn_reviving_old_topic_age: "Cuando alguien publica en un tema cuya última respuesta fue hace este número de días o más, se le mostrará un aviso para desalentar el hecho de resucitar una antigua discusión. Deshabilita esta opción introduciendo el valor 0." + warn_reviving_old_topic_age: "Cuando alguien publica en un tema cuya última respuesta fue hace este número de días o más, se le mostrará un aviso para desalentar el hecho de revivir una antigua discusión. Deshabilita esta opción introduciendo el valor 0." autohighlight_all_code: "Forzar el resaltado de código a los bloques de código preformateado cuando no se especifique el lenguaje del código." - highlighted_languages: "Incluye reglas resaltadas de sintaxis. (Advertencia: incluyendo demasiadas lenguages puede afectar al rendimiento) ver: https://highlightjs.org/static/demo/ para una demostración" + highlighted_languages: "Incluye reglas resaltadas de sintaxis. (Advertencia: incluyendo demasiados lenguajes puede afectar al rendimiento) ver: https://highlightjs.org/static/demo/ para una demostración" feed_polling_enabled: "SOLO PARA EMBEBER: embeber feeds RSS/ATOM como posts." feed_polling_url: "SOLO PARA EMBEBER: URL de los feeds RSS/ATOM a embeber." embed_by_username: "Nombre de usuario en Discourse del que crea los temas embebidos." embed_username_key_from_feed: "Clave para extraer el nombre de usuario en Discourse desde el feed." embed_truncate: "Truncar los posts embebidos." embed_post_limit: "Número máximo de posts a embeber." + embed_username_required: "Se requiere el nombre de usuario para la creación de temas." embed_whitelist_selector: "Selector CSS para los elementos que están permitidos en los embebidos." embed_blacklist_selector: "Selector CSS para los elementos que están eliminados desde los embebidos." notify_about_flags_after: "Si hay reportes que no han sido revisados después de este número de horas, enviar un correo electrónico al contact_email. Deshabilita esta opción introduciendo el valor 0." enable_cdn_js_debugging: "Permitir /logs mostrar los errores correctamente, añadiendo permisos crossorigin en todas las inclusiones de js" show_create_topics_notice: "Si el sitio tiene menos de 5 temas abiertos al público, mostrar un aviso pidiendo a los administradores crear más temas." delete_drafts_older_than_n_days: Eliminar borradores de más de (n) días de antigüedad. - show_logout_in_header: "Mostrar el botón para cerrar sesión en el desplegable de la cabecera" - vacuum_db_days: "Correr VACUUM FULL ANALYZE para reclamar espacio en la base de datos después de las migraciones. (Poner en 0 para inhabilitar)" + vacuum_db_days: "Ejecutar VACUUM ANALYZE para reclamar espacio en la base de datos después de las migraciones. (Poner en 0 para inhabilitar)" prevent_anons_from_downloading_files: "Impedir que los usuarios anónimos descarguen archivos. ADVERTENCIA: Esto impedirá que funcione cualquier recurso del sitio publicado como adjunto." slug_generation_method: "Elegir un método de generación de slug. 'encoded' generará cadenas con código porciento. 'none' hara que no se genere slug." enable_emoji: "Habilitar emoji" emoji_set: "¿De qué tipo os gustan los emoji?" enforce_square_emoji: "Forzar una relación de aspecto cuadrada para todos los emojis." - approve_post_count: "La cantidad de posts de un nuevo usuario que deben ser aprobados" + approve_post_count: "La cantidad de posts que deben ser aprobados de usuarios nuevos o de nivel básico" approve_unless_trust_level: "Los posts de usuarios con un nivel de confianza inferior a este deberán ser aprobados" notify_about_queued_posts_after: "Si hay posts esperando a ser revisados por este número de horas, se enviará un email al correo de contacto. Establece este valor a 0 para desactivar estos emails." default_email_digest_frequency: "Frecuencia por defecto con la que se reciben los emails resumen." + default_include_tl0_in_digests: "Incluir posts de nuevos usuarios en los emails de resumen por defecto. Los usuarios pueden cambiar esto en sus preferencias." default_email_private_messages: "Enviar un email cuando alguien envíe un mensaje al usuario por defecto." default_email_direct: "Enviar un email cuando alguien cite/responda/mencione o invite al usuario por defecto." default_email_mailing_list_mode: "Enviar un email por cada nuevo post por defecto." + disable_mailing_list_mode: "No permitir a los usuarios que activen el modo lista de correo." default_email_always: "Enviar una notificación por email aunque el usuario esté activo por defecto." + default_email_previous_replies: "Incluir por defecto respuestas previas en los emails." + default_email_in_reply_to: "Incluir por defecto un extracto del post al que se ha respondido en los emails." default_other_new_topic_duration_minutes: "Condición por defecto para que un tema sea considerado nuevo" default_other_auto_track_topics_after_msecs: "Tiempo por defecto hasta que un tema sea seguido automáticamente." default_other_external_links_in_new_tab: "Abrir enlaces externos en una nueva pestaña por defecto." @@ -1034,6 +1108,8 @@ es: default_other_dynamic_favicon: "Mostrar temas nuevos/actualizados en el icono del navegador por defecto" default_other_disable_jump_reply: "No ir a un nuevo post tras publicarlo por defecto" default_other_edit_history_public: "Hacer la lista de ediciones pública por defecto." + default_other_like_notification_frequency: "Notificar a los usuarios de los me gusta por defecto" + default_topics_automatic_unpin: "Quitar destacado automáticamente cuando el usuario llega al final del tema." default_categories_watching: "Lista de categorías que están vigiladas por defecto." default_categories_tracking: "Lista de categorías que están seguidas por defecto" default_categories_muted: "Lista de categorías que están silenciadas por defecto." @@ -1051,7 +1127,13 @@ es: invalid_string_min: "Debe contener como mínimo %{min} caracteres. " invalid_string_max: "No debe exceder los %{max} caracteres. " invalid_reply_by_email_address: "El valor debe contener '%{reply_key}' y debe ser diferente del email de notificación." + pop3_polling_host_is_empty: "Debes establecer un host de 'pop3 polling' antes de activar el polling POP3." + pop3_polling_username_is_empty: "Debes establecer un usuario de 'pop3 polling' antes de activar el polling POP3." + pop3_polling_password_is_empty: "Debes establecer una contraseña de 'pop3 polling' antes de activar el polling POP3." + pop3_polling_authentication_failed: "La autenticación POP3 falló. Por favor, verifica tus credenciales pop3." + reply_by_email_address_is_empty: "Debes establecer el campo 'reply by email address' antes de activar respuesta por email." notification_types: + group_mentioned: "%{group_name} ha sido mencionado en %{link}" mentioned: "%{display_username} te ha mencionado en %{link}" liked: "%{display_username} le ha gustado tu post en %{link}" replied: "%{display_username} ha contestado tu post en %{link}" @@ -1061,7 +1143,7 @@ es: moved_post: "%{display_username} ha movido tu post a %{link}" private_message: "%{display_username} te ha enviado un mensaje: %{link}" invited_to_private_message: "%{display_username} te ha invitado a un hilo de mensajes: %{link}" - invited_to_topic: "%{display_username} te ha invitado a un tema: %{link}" + invited_to_topic: "%{display_username} te invitó a %{link}" invitee_accepted: "%{display_username} ha aceptado tu invitación" linked: "%{display_username} te enlazó en %{link}" granted_badge: "Obtuviste %{link}" @@ -1071,11 +1153,6 @@ es: category: 'Categorías' topic: 'Resultados' user: 'Usuarios' - sso: - not_found: "No se puede buscar o crear cuenta, contacta al administrador del sitio" - account_not_approved: "La cuenta está pendiente de aprobación, recibirás una notificación por email cuando se apruebe" - unknown_error: "Error al actualizar la información, contacta al administrador del sitio" - timeout_expired: "Se agotó el tiempo de espera para el inicio de sesión, por favor, intenta iniciar sesión de nuevo" original_poster: "Autor original" most_posts: "Con más posts" most_recent_poster: "Autor más reciente" @@ -1150,6 +1227,7 @@ es: reserved_username: "Ese nombre de usuario no está permitido." missing_user_field: "No has completado todos los campos de usuario" close_window: "Autenticación completa. Cierra esta ventana para continuar." + already_logged_in: "Ups, parece que estás intentando aceptar una invitación dirigida a otro usuariol. Si no eres %{current_user}, por favor cierra sesión e inténtalo de nuevo." user: no_accounts_associated: "No hay cuentas relacionadas." username: @@ -1158,16 +1236,33 @@ es: characters: "solo debe incluir números y letras" unique: "debe ser único" blank: "debe estar presente" - must_begin_with_alphanumeric: "debe empezar con una letra, número o guión bajo" - must_end_with_alphanumeric: "debe terminar con una letra, número o guión bajo" + must_begin_with_alphanumeric_or_underscore: "debe comenzar con una letra, un número o un guión bajo" + must_end_with_alphanumeric: "debe terminar con una letra o un número" must_not_contain_two_special_chars_in_seq: "no debe contener una secuencia de 2 o más caracteres especiales (.-_)" - must_not_contain_confusing_suffix: "no debe contener un sufijo confuso como .json, .png, etc." + must_not_end_with_confusing_suffix: "no debe terminar con un sufijo que lleve a confusión como .json o .png etc." email: not_allowed: "este proveedor de email no está permitido. Por favor, utiliza otra dirección de email." blocked: "no está permitido." ip_address: blocked: "No se permiten nuevos registros desde tu dirección IP." max_new_accounts_per_registration_ip: "No se permiten nuevos registros desde tu dirección IP (alcanzado el límite máximo). Contacta un miembro del staff." + flags_reminder: + flags_were_submitted: + one: "Hay reportes enviados hace 1 hora. Por favor, revísalos." + other: "Hay reportes enviados hace %{count} horas. Por favor, revísalos." + subject_template: + one: "1 reporte esperando ser atendidos." + other: "%{count} reportes esperando ser atendidos." + unsubscribe_mailer: + subject_template: "Confirma que no quieres recibir más emails de %{site_title}" + text_body_template: | + Alguien (posiblemente tú?) solicitó no recibir más actualizaciones por email desde %{site_domain_name} a esta dirección de email. + Si deseas confirmar esta acción, por favor haz clic en el siguiente enlace: + + %{confirm_unsubscribe_link} + + + Si quieres continuar recibiendo actualizaciones por email, por favor ignora este correo. invite_mailer: subject_template: "%{invitee_name} te invitó a '%{topic_title}' en %{site_domain_name}" text_body_template: | @@ -1200,87 +1295,10 @@ es: (Si el enlace anterior ha caducado, utiliza "Olvidé mi contraseña" cuando vayas a iniciar sesión con tu dirección de email.) test_mailer: subject_template: "[%{site_name}] Prueba de envío de email" - text_body_template: | - Este es un correo electrónico de prueba de - - [**%{base_url}**][0] - - La entrega de correo electrónico es complicada. Aquí hay unas cuantas cosas importantes que deberías comprobar primero: - - - *Asegúrate* de ajustar la dirección `notification email` desde: correctamente en los ajustes de tu sitio. **El dominio especificado en la dirección "from" de los emails que envíes es el dominio contra el que se validará tu email**. - - - Entérate de como ver el código fuente del email desde tu cliente de correo, para que así puedas examinar las cabeceras para ver pistas importantes. En Gmail está la opción "mostrar original" en el menú de lista desplegable en la parte superior derecha de cada email. - - - **IMPORTANTE:** ¿Tu ISP tiene registros de DNS inversa para asociar los nombres de dominio y las direcciones IP desde donde envías los correos? [Comprueba tu registro PTR Inverso][2] aquí. Si tu ISP no introduce el puntero de registro DNS inverso adecuado, es muy improbable que cualquiera de tus correos pueda ser entregado. - - - ¿Es el [registro SPF][8] de tu dominio correcto? [Comprueba tu registro SPF][1] aquí. Ten en cuenta que TXT es el tipo de registro oficial correcto para SPF. - - - ¿Es el [registro DKIM][3] de tu dominio correcto? Esto puede mejorar significativamente la entregabilidad de correos. [Comprueba tu registro DKIM][7] aquí. - - - Si estás corriendo tu propio servidor de correo, asegúrate de que las IPs de tu servidor de correo [no están en ninguna lista negra de correos][4]. También verifica que definitivamente se está enviando un nombre de huésped "hostname" completamente cualificado que resuelva en DNS en su mensaje HELO. Si no es así, esto causará que tu correo sea denegado por muchos servicios de correo. - - (La forma *fácil* es crear una cuenta gratuíta en [Mandrill][md] o [Mailgun][mg] o [Mailjet][mj], que proveen generosamente planes de mailing gratuítos y serán adecuados para pequeñas comunidades. ¡De todas formas todavía tendrás que configurar los registros SPF y DKIM en tus DNS!) - - ¡Esperamos que recibas esta prueba de entregabilidad de correo electrónico correctamente! - - Buena suerte, - - Tus amigos de [Discourse](http://www.discourse.org) - - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: https://www.mailjet.com/pricing new_version_mailer: subject_template: "[%{site_name}] Nueva versión de Discourse, actualización disponible" - text_body_template: | - Está disponible una nueva versión de [Discourse](http://www.discourse.org). - - Tu versión: %{installed_version} - Nueva versión: **%{new_version}** - - Tal vez quieras: - - - Ver qué hay de nuevo en el [historial de cambios de GitHub](https://github.com/discourse/discourse/commits/master). - - - Actualizar desde tu navegador en [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Visitar [meta.discourse.org](http://meta.discourse.org) para ver noticias, debatir u obtener soporte de Discourse. new_version_mailer_with_notes: subject_template: "[%{site_name}] actualización disponible" - text_body_template: | - Está disponible una nueva versión de [Discourse](http://www.discourse.org). - - Tu versión: %{installed_version} - Nueva versión: **%{new_version}** - - Tal vez quieras: - - - Ver qué hay de nuevo en el [historial de cambios de GitHub](https://github.com/discourse/discourse/commits/master). - - - Actualizar desde tu navegador en [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Visitar [meta.discourse.org](http://meta.discourse.org) para ver noticias, debatir u obtener soporte de Discourse. - - ### Notas de lanzamiento - - %{notes} - flags_reminder: - flags_were_submitted: - one: "Estos reportes fueron enviados desde hace 1 hora." - other: "Estos reportes fueron enviados desde hace %{count} horas." - please_review: "Por favor, revísalos." - post_number: "post" - how_to_disable: 'Puedes desactivar o cambiar la frecuencia de este email de recordatorio mediante la opción "notify about flags after".' - subject_template: - one: "1 reporte esperando ser atendidos." - other: "%{count} reportes esperando ser atendidos." queued_posts_reminder: subject_template: one: "[%{site_name}] 1 post esperando ser revisado" @@ -1319,12 +1337,7 @@ es: Para más información, por favor consulta nuestras [directrices](%{base_url}/guidelines). usage_tips: - text_body_template: "Aquí tienes unos breves consejos para empezar:\n\n## Lectura\n\nPara leer más, **¡tan solo tienes que hacer scroll!** \n\nTan pronto como se publiquen nuevas respuestas o temas, aparecerán automáticamente – sin necesidad de actualizar la página.\n\n## Navegación\n\n- Para la búsqueda, tu perfil de usuario, o el menú ;, usa los **botones con iconos de la esquina superior derecha**. \n\n- Entrar a un tema desde su título te llevará a la **última respuesta sin leer** del hilo. Para ir al primer o al último post, haz clic en el contador de respuestas o en la fecha de última respuesta.\n\n \n\n- Mientras lees un tema, selecciona la barra de progreso en la esquina inferior derecha para ver los controles de navegación. Podrás ir al inicio del hilo seleccionando su\ - \ título. Teclea ? para ver una lista de rápidos atajos de teclado.\n\n \n\n## Participando\n\n- Para responder al **tema en general**, utiliza al final del hilo. \n\n- Para responder a **una persona en específico**, utiliza en su post. \n\n- Para responder **creando un nuevo tema**, utiliza a la derecha del post. Tanto el tema original como el nuevo serán enlazados entre sí automáticamente. \n\nPara escribir una cita, selecciona el texto que quieres citar, después haz clic en el botón citar. ¡Puedes repetir para realizar\ - \ múltiples citas! \n\n\n\nPara notificar a alguien en tu respuesta, menciónale. Empieza a escribir `@` para elegir su nombre de usuario. \n\n \n\nPara usar [Emojis](http://www.emoji.codes/), teclea `:` para elegir por nombre, o usa los tradicionales smileys `;)` \n\n \n\n## Acciones\n\nHay algunos botones de acción al final de cada post: \n\n \n\nPara hacerle saber a alguien que has disfrutado o que aprecias su post, utiliza el botón de **Me gusta**. ¡Compartir es amor! \n\nSi ves algún problema en la publicación de\ - \ alguien, escríbele un privado, o házselo saber [a nuestros moderadores](%{base_url}/about), con el botón **reporte**. También puedes **compartir** un enlace a un post, o guardarlo en **marcadores** para tenerlo de referencia en tu página de perfil. \n\n## Notificaciones\n\nCuando alguien te responde, cita tu post, o bien menciona tu `@usuario`, inmediatamente aparecerá un número en la esquina superior derecha de la página. Usa ese botón para acceder a tus **notificaciones**. \n\n \n\nNo te preocupes si te pierdes alguna respuesta – te enviaremos un email con las notificaciones que lleguen cuando estés fuera.\n\n## Tus preferencias\n\n- Todos los temas creados hace menos de **dos días** se consideran nuevos. \n\n- Aquellos temas en los que hayas **participado activamente** (porque lo hayas creado,\ - \ o respondido o leído durante un período razonable) serán seguidos por tu usuario automáticamente. Verás los indicadores azules de temas nuevos o número de respuestas no leídas al lado de estos temas: \n\n \n\nPuedes cambiar tus notificaciones para cualquier tema mediante el control de notificaciones al final del tema. \n\n \n\nTambién puedes establecer el estado de notificación de una categoría entera, si quieres vigilar cualquier nuevo tema en una categoría específica. Para cambiar cualquiera de estas opciones, puedes ver [tus preferencias](%{base_url}/my/preferences). \n\n## Confianza \n\nAl participar aquí, con el tiempo te ganarás la confianza de la comunidad, te convertirás en usuario de\ - \ pleno derecho y te serán retiradas las limitaciones de nuevo usuario. Llegado a un punto de un alto [nivel de confianza](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), obtendrás además nuevas habilidades para ayudarnos a gestionar la comunidad juntos.\n" + text_body_template: "Aquí tienes unos breves consejos para empezar:\n\n## Lectura\n\nPara leer más, **¡tan solo tienes que hacer scroll!**\n\nTan pronto como se publiquen nuevas respuestas o temas, aparecerán automáticamente – sin necesidad de actualizar la página.\n\n## Navegación\n\n- Para realizar una búsqueda, ver tu perfil de usuario, o el menú , usa los **botones de la esquina superior derecha**.\n\n- Entrar a un tema desde su título te llevará a la **última respuesta sin leer** del hilo. Para ir al primer o al último post, haz clic en el contador de respuestas o en la fecha de última respuesta..\n\n \n\n- Mientras lees un tema, selecciona la barra de progreso en la esquina inferior derecha para ver los controles de navegación. Podrás ir al inicio del hilo seleccionando su título. Teclea ? para ver una lista de rápidos atajos de teclado.\n\n \n\n## Participación\n\n- Para responder al **tema en general**, utiliza al final del hilo.\n\n- Para responder a **una persona en específico**, utiliza en su post.\n\n- Para responder **creando un nuevo tema**, utiliza la derecha del post. Tanto el tema original como el nuevo serán enlazados entre sí automáticamente.\n\nTu respuesta puede estar en varios formatos como HTML simple, BBCode, o [Markdown](http://commonmark.org/help/):\n\n Esto es **negrita**.\n Esto es negrita.\n Esto es [b]negrita[/b].\n\n¿Quieres aprender Markdown? [¡Echa un vistazo a nuestro divertido tutorial interactivo de 10 minutos!](http://commonmark.org/help/tutorial/)\n\nPara escribir una cita, selecciona el texto que quieres citar, después haz clic en el botón citar. ¡Puedes repetir para realizar múltiples citas!\n\n\n\nPara notificar a alguien en tu respuesta, menciónale. Empieza a escribir `@` para elegir su nombre de usuario.\n\n\n\nPara usar [Emojis](http://www.emoji.codes/), teclea `:` para elegir por nombre, o usa los tradicionales smileys `;)`\n\n\n\nPara generar un extracto desde un enlace, pégalo en una línea aparte para él solo:\n\n\n\n## Acciones\n\nHay algunos botones de acción al final de cada post:\n\n\n\nPara hacerle saber a alguien que aprecias su post, utiliza el botón de **Me gusta**. ¡Compartir es amor!\n\nSi ves algún problema en la publicación de alguien, escríbele un privado, o házselo saber [a nuestros moderadores](%{base_url}/about), con el botón **reporte**. También puedes **compartir** un enlace a un post, o guardarlo en **marcadores** para tenerlo de referencia en tu página de perfil.\n\n## Notificaciones\n\nCuando alguien te responde, cita tu post, o bien menciona tu `@usuario`, inmediatamente aparecerá un número en la esquina superior derecha de la página. Usa ese botón para acceder a tus **notificaciones**.\n\n\n\nNo te preocupes si te pierdes alguna respuesta – te enviaremos un email con las notificaciones que lleguen cuando estés fuera.\n\n## Tus preferencias\n\n - Todos los temas creados hace menos de **dos días** se consideran nuevos..\n\n - Aquellos temas en los que hayas **participado activamente** (porque lo hayas creado, o respondido o leído durante un período razonable) serán seguidos por tu usuario automáticamente. \n\nVerás los indicadores de temas nuevos o número de respuestas no leídas al lado de estos temas::\n\n\n\nPuedes cambiar tus notificaciones para cualquier tema mediante el control de notificaciones al final del tema.\n\n\n\nTambién puedes establecer el estado de notificación de una categoría entera, si quieres vigilar cualquier nuevo tema en una categoría específica.\n\nPara cambiar cualquiera de estas opciones, puedes ver [tus preferencias](%{base_url}/my/preferences).\n\n## Confianza y comunidad\n\nAl participar aquí, con el tiempo te ganarás la confianza de la comunidad, te convertirás en usuario de pleno derecho y te serán retiradas las limitaciones de nuevo usuario. Llegado a un punto de un alto [nivel de confianza](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), obtendrás además nuevas habilidades para ayudarnos a gestionar la comunidad juntos.\n" welcome_user: subject_template: "¡Bienvenido a %{site_name}!" text_body_template: | @@ -1409,18 +1422,22 @@ es: csv_export_failed: subject_template: "La exportación de datos falló" text_body_template: "Lo sentimos, pero la exportación de datos falló. Por favor, verifica los registros o contacta a un miembro del staff." - email_reject_trust_level: - subject_template: "[%{site_name}] Problema con el correo electrónico -- Nivel de Confianza Insuficiente" + email_reject_insufficient_trust_level: + subject_template: "[%{site_name}] Problema relacionado con el email -- Insuficiente nivel de confianza" text_body_template: | - Lo sentimos, pero tu email para %{destination} (titulado %{former_title}) se ha rechazado. + Lo sentimos, pero tu email para %{destination} (titulado %{former_title}) no fue entregado. - Tu cuenta no tiene el nivel de confianza suficiente para publicar nuevos temas a esta dirección de correo electrónico. Si crees que esto es un error, contacta con algún miembro del Staff. + Tu cuenta no tiene el suficiente nivel de confianza requerido para publicar nuevos temas a esta dirección de email. Si crees que esto es un error, contacta a un administrador. + email_reject_inactive_user: + subject_template: "[%{site_name}] Problema relacionado con el email -- Usuario inactivo" + text_body_template: | + Lo sentimos, pero tu email para %{destination} (titulado %{former_title}) no se entregó. + + La cuenta asociada a esta dirección de email no ha sido activada. Por favor activa tu cuenta antes de enviar emails. + email_reject_reply_user_not_matching: + subject_template: "[%{site_name}] Problema relacionado con el email -- No coincide el usuario de la respuesta" email_reject_no_account: subject_template: "[%{site_name}] Problema con el correo electrónico -- Cuenta Desconocida" - text_body_template: | - Lo sentimos, pero tu email para %{destination} (titulado %{former_title}) se ha rechazado. - - No hay una cuenta de usuario asociada con esta dirección de email. Intenta enviarlo con otra dirección de email o contacta con algún miembro del Staff. email_reject_empty: subject_template: "[%{site_name}] Problema con el correo electrónico -- Sin Contenido" text_body_template: | @@ -1441,40 +1458,10 @@ es: Lo sentimos, pero tu mensaje por email a %{destination} (titled %{former_title}) no funcionó. Tu cuenta no tiene los privilegios para publicar nuevos temas en esa categoría. Si crees que esto es un error, contacta a un moderador o administrador. - email_reject_post_error: - subject_template: "[%{site_name}] Problema con el correo electrónico -- Error de publicación" - text_body_template: | - Lo sentimos, pero tu email para %{destination} (titulado %{former_title}) se ha rechazado. - - Posibles causas: formato complejo, mensaje demasiado extenso o demasiado breve. Por favor, inténtalo de nuevo. - email_reject_post_error_specified: - subject_template: "[%{site_name}] Problema con el correo electrónico -- Error de publicación" - text_body_template: | - Lo sentimos, pero tu mensaje e-mail para %{destination} (titulado %{former_title}) no funciono. - - Razón: - - %{post_error} - - Si puedes corregir el problema, por favor intenta de nuevo. email_reject_reply_key: subject_template: "[%{site_name}] Problema con el correo electrónico -- Clave de Respuesta Desconocida" - text_body_template: | - Lo sentimos, pero tu email para %{destination} (titulado %{former_title}) se ha rechazado. - - La clave de respuesta proporcionada no es válida o es desconocida, por lo que no sabemos a qué responde este email. Contacta con algún miembro del staff. - email_reject_destination: - subject_template: "[%{site_name}] Problema con el correo electrónico -- Desconocido Para: Dirección" - text_body_template: | - Lo sentimos, pero tu email para %{destination} (titulado %{former_title}) no funcionó. - - No se ha podido reconocer ninguna de las direcciones destino. Por favor, asegúrate de que la dirección del sitio está en Para: (no CC ni BCC), y que lo estás enviando a la dirección de e-mail proporcionada por los administradores. email_reject_topic_not_found: subject_template: "[%{site_name}] Problema con el correo electrónico -- Tema no encontrado" - text_body_template: | - Lo sentimos, pero tu email para %{destination} (titulado %{former_title}) no funcionó. - - El tema al que estás respondiendo ya no existe, quizá debe haber sido eliminado. Si crees que esto es un error, contacta a un administrador. email_reject_topic_closed: subject_template: "[%{site_name}] Problema con el correo electrónico -- Tema cerrado" text_body_template: | @@ -1483,16 +1470,8 @@ es: El tema actualmente está cerrado y no acepta más respuestas. Si crees que esto es un error, contacta a un administrador. email_reject_auto_generated: subject_template: "[%{site_name}] Problema con el correo electrónico -- Respuesta Auto Generada" - text_body_template: | - Lo sentimos, pero tu mensaje de correo electrónico para %{destination} (titulado %{former_title}) no funcionó. - - Tu respuesta de correo fue marcada como "generada automáticamente" y no aceptamos esto. Si crees que se trata de un error contacta con un administrador. email_error_notification: subject_template: "[%{site_name}] Problema con el correo electrónico -- Error de autenticación POP" - text_body_template: | - Ha habido un error de autenticación mientras se ejecutaba el polling de los emails desde el servidor POP. - - Por favor, asegúrate de que se han configurado las credenciales POP correctamente en los [ajustes del sitio](%{base_url}/admin/site_settings/category/email). too_many_spam_flags: subject_template: "Cuenta nueva bloqueada" text_body_template: | @@ -1502,28 +1481,29 @@ es: Como medida precautoria, tu nueva cuenta ha sido bloqueada para crear nuevas respuestas o temas hasta que un miembro del staff pueda revisar tu cuenta. - Para orientación adicional, por favor revise nuestras [reglas de comunidad](%{base_url}/guidelines). + Para orientación adicional, por favor revisa nuestras [reglas de comunidad](%{base_url}/guidelines). blocked_by_staff: subject_template: "Cuenta bloqueada" - text_body_template: | - Hola, - - Esto es un mensaje automatizado de %{site_name} para informatarte que tu cuenta ha sido bloqueada por un miembro del staff. - - Para orientación adicional, por favor revise nuestras [reglas de comunidad](%{base_url}/guidelines). user_automatically_blocked: subject_template: "El nuevo usuario %{username} ha sido bloqueado tras ser reportado por la comunidad" text_body_template: | - Éste es un mensaje automático. + Este es un mensaje automático. - El nuevo usuario [%{username}](%{base_url}%{user_url}) ha sido bloqueado automáticamente porque múltiples usuarios han reportado el/los post(s) de %{username}. + El usuario nuevo [%{username}](%{user_url}) ha sido automáticamente bloqueado porque varios usuarios han reportado los mensajes de %{username}. - Por favor, [revisa los informes](%{base_url}/admin/flags). Si %{username} ha sido bloqueado incorrectamente, clica el botón de desbloquear en [la página de administración para este usuario](%{base_url}%{user_url}). + Por favor, [mira los reportes](%{base_url}/admin/flags). Si %{username} hubiera sido bloqueado incorrectamente, click haz clic en el botón de desbloquear en la [página de administración del usuario](%{user_url}). - El umbral puede ser cambiado vía configuración del sitio en `block_new_user`. + Esto puede ser cambiado con el ajuste `block_new_user`. spam_post_blocked: subject_template: "El nuevo usuario %{username} tiene posts bloqueados debido a repetición de enlaces." - text_body_template: "Este es un mensaje automático. \n\nEl usuario [%{username}](%{base_url}%{user_url}) intento crear multiples posts con links hacia %{domains}, pero dichos posts fueron bloqueados para evitar el spam. El usuario aun esta habilitado para crear nuevos posts que no contengan links hacia %{domains}.\n\nPor favor [revise el usuario] (%{base_url}%{user_url}).\n\nEsto puede ser modificado por medio de las opciones de configuración `newuser_spam_host_threshold` y `white_listed_spam_host_domains`.\n" + text_body_template: | + Este es un mensaje automático. + + El usuario nuevo [%{username}](%{user_url}) ha intentado crear múltiples temas con enlaces a %{domains}, pero han sido bloqueados para evitar spam. El usuario todavía puede crear temas, siempre y cuando no contengan enlaces a %{domains}. + + Por favor, [echa un vistazo al usuario](%{user_url}). + + Esto puede ser modificado con los ajustes`newuser_spam_host_threshold` y`white_listed_spam_host_domains`. unblocked: subject_template: "Cuenta desbloqueada" text_body_template: | @@ -1544,52 +1524,45 @@ es: subject_template: "Inhabilitar la descarga de imágenes remotas" text_body_template: "La opción `download_remote_images_to_local` ha sido inhabilitada porque se ha llegado al límite de espacio en disco configurado en `download_remote_images_threshold`." unsubscribe_link: | - Para dar de baja tu suscripción a estos emails, visita tus [preferencias](%{user_preferences_url}). - - Para dejar de recibir notificaciones sobre este tema en particular, [haz clic aquí](%{unsubscribe_url}). + Para no recibir más notificaciones de este tema en particular, [haz clic aquí](%{unsubscribe_url}). Para darte de baja de estos emails, cambia tus [preferencias](%{user_preferences_url}) + unsubscribe_via_email_link: | + o, [haz clic aquí](mailto:reply@%{hostname}?subject=unsubscribe) para darte de baja por email. subject_re: "Re:" subject_pm: "[MP]" user_notifications: previous_discussion: "Respuestas anteriores" + in_reply_to: "En respuesta a" unsubscribe: title: "Darse de baja" description: "¿No estás interesado en recibir estos emails? ¡No hay problema! Haz clic abajo para darte de baja de forma instantánea:" - reply_by_email: "Para comentar, responde a este email o visita %{base_url}%{url} en tu navegador." - visit_link_to_respond: "Para responder, visita %{base_url}%{url} en tu navegador." + reply_by_email: "[Visita el tema](%{base_url}%{url}) o responde a este email para comentar" + reply_by_email_pm: "[Visita el mensaje](%{base_url}%{url}) o responde a este email para comentar" + only_reply_by_email: "Responde a este email para comentar" + visit_link_to_respond: "[Visita el tema](%{base_url}%{url}) para comentar" + visit_link_to_respond_pm: "[Visita el mensaje](%{base_url}%{url}) para comentar" posted_by: "Publicado por %{username} el %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} te ha invitado a un hilo de mensajes '%{topic_title}'" - text_body_template: |2 - - %{username} te invitó al hilo de mensajes - - > **%{topic_title}** - > - > %{topic_excerpt} - - en - - > %{site_title} -- %{site_description} - - Por favor visita este enlace para verlo: %{base_url}%{url} + user_invited_to_private_message_pm_staged: + subject_template: "[%{site_name}] %{username} te ha invitado a un mensaje '%{topic_title}'" user_invited_to_topic: - subject_template: "[%{site_name}] %{username} te ha invitado a un tema '%{topic_title}'" - text_body_template: |2 - - %{username} te invitó al hilo - - > **%{topic_title}** - > - > %{topic_excerpt} - - en - - > %{site_title} -- %{site_description} - - Por favor, visita este enlace para verlo: %{base_url}%{url} + subject_template: "[%{site_name}] %{username} te invitó a '%{topic_title}'" user_replied: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_replied_pm: + subject_template: "[%{site_name}] [MP] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1599,6 +1572,19 @@ es: user_quoted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_linked: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1608,6 +1594,19 @@ es: user_mentioned: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1617,20 +1616,31 @@ es: user_posted: subject_template: "[%{site_name}] %{subject_prefix}%{username} publicó en '%{topic_title}'" text_body_template: | - %{username} publicó en '%{topic_title}' en %{site_name}: + %{header_instructions} - --- - %{message} - - --- - Por favor visita este enlace para contestar: %{base_url}%{url} - user_posted_pm: - subject_template: "[%{site_name}] [MP] %{topic_title}" - text_body_template: | %{message} %{context} + --- + %{respond_instructions} + user_posted_pm: + subject_template: "[%{site_name}] [MP] %{topic_title}" + text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_posted_pm_staged: + subject_template: "%{optional_re}%{topic_title}" + text_body_template: |2 + + %{message} + --- %{respond_instructions} digest: @@ -1677,14 +1687,8 @@ es: text_body_template: | Una nueva cuenta ha sido creada por ti en %{site_name} - Da clic en el siguiente enlace para escoger una contraseña para tu nueva cuenta: + Pulsa en el siguiente enlace para escoger una contraseña para tu nueva cuenta: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Confirma tu nueva dirección de email" - text_body_template: | - Confirma tu nueva dirección de email para %{site_name} haciendo clic en el siguiente enlace: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "Tú solicitud ha sido aprobada en %{site_name}!" text_body_template: | @@ -1714,7 +1718,7 @@ es: Si el enlace anterior no es clicable, prueba copiándolo y pegándolo en la barra de direcciones de tu navegador. page_not_found: - title: "La página que deseas ver no existe o es privada." + title: "¡Ups! Esa página no existe o es privada." popular_topics: "Populares" recent_topics: "Recientes" see_more: "Más" @@ -1739,8 +1743,6 @@ es: images: too_large: "Lo sentimos, la imagen que estás intentando subir es demasiado grande (el tamaño máximo es %{max_size_kb}%KB). Por favor, modifica sus dimensiones y prueba otra vez." size_not_found: "Lo sentimos, pero no hemos podido determinar el tamaño de la imagen. ¿Quizás el archivo está corrupto?" - avatar: - missing: "Lo sentimos, pero el avatar que has elegido no está disponible en el servidor. ¿Puedes intentar subirlo de nuevo?" flag_reason: sockpuppet: "Un nuevo usuario ha creado un tema, y otro nuevo usuario con la misma dirección IP le ha respondido. Mira la opción flag_sockpuppets del sitio." spam_hosts: "Este nuevo usuario intentó crear varios posts con enlaces al mismo dominio. Mira la opción newuser_spam_host_threshold." @@ -1772,88 +1774,245 @@ es: Edita el primer post de este tema para cambiar el contenido de la página %{page_name}. guidelines_topic: title: "Preguntas Frecuentes / Directrices" + body: | + + + ## [Este es un lugar público para conversaciones civilizadas](#civilized) + + Por favor, trata este foro de debate con el mismo respeto con el que tratarías un parque. Este es un lugar donde compartir habilidades, conocimiento e intereses a través de debates y conversaciones. + + Estas no son unas normas estrictas y cerradas, sino una ayuda para el correcto desarrollo de la comunidad. Usa estas pautas para mantener este sitio como un lugar limpio y adecuado para poder debatir y conversar correctamente. + + + + ## [Aporta](#improve) + + Ayúdanos a mantener este foro como un buen lugar esforzándote para mejorar el debate de alguna manera, aunque sea mínima. Si no estás seguro de lo que tu mensaje aporta a la conversación, piensa sobre lo que quieres decir e intenta contestar después. + + El contenido de este foro nos importa, y queremos que actúes como si te importara a ti también. Sé respetuoso con los temas debatidos y con la gente que los debate, aunque no estés de acuerdo con algo de lo que digan. + + Una buena manera de de mejorar el foro es investigando un poco lo que está pasando o ya ha pasado. Por favor, echa un vistazo a los temas ya existentes antes de responder a uno o crearlo y así podrás ver quién opina lo mismo o tiene intereses parecidos a los tuyos. + + + + ## [Sé aceptable incluso cuando no estés de acuerdo](#agreeable) + + Cuando vayas a responder a algo con lo que no estás de acuerdo acuérdate de __criticar las ideas y no las personas__. Por favor, evita: + + + * Ridiculizar a los demás. + * Faltar al respeto e insultar. + * Responder al tono del mensaje en vez de a su contenido. + * Hacer comparaciones y contradicciones exageradas y/o fuera de lugar. + + En lugar de eso, da argumentos que aporten algo al tema, por favor. + + + + ## [Tu participación cuenta](#participate) + + Eres parte de la comunidad, y queremos que todo el mundo participe en ella. Crea o responde a los temas aportando algo y harás de este foro un lugar más interesante y agradable. + + Este foro ofrece herramientas que permiten a la comunidad identificar entre todas las mejores (y peores) contribuciones: "Me gusta", marcadores, reportes, distintivos, respuestas, ediciones, y demás. Usa todo esto para mejorar tu experiencia y la de los demás. + + Intentemos dejar esto mejor de lo que nos lo encontramos. + + + + ## [Si ves un problema, repórtalo](#flag-problems) + + Los moderadores tienen una autoridad especial: son los responsables de este foro. Pero tú lo eres también. Con tu ayuda, los moderadores pueden ser personas que faciliten el desarrollo de la comunidad en lugar de la policía del foro o el servicio de limpieza. + + Cuando veas un comportamiento inadecuado, no respondas. Eso hace que, al reconocer públicamente el contenido inadecuado, se siga publicando contenido de esa clase. Además, lo único que harás será perder energía y el tiempo de todos. En su lugar, repórtalo. Si un post es reportado lo suficiente, se tomarán medidas automáticamente o mediante la intervención de un moderador. + + Para el correcto funcionamiento de esta comunidad, los moderadores se reservan el derecho de eliminar cualquier contenido y cualquier cuenta, por cualquier razón en cualquier momento. Los moderadores no ven los temas antes de que sean publicados por lo que ellos y los operadores del foro no son responsables del contenido publicado por la comunidad. + + + + ## [Sé educado](#be-civil) + + Nada estropea más una conversación que la mala educación. + + * Sé educado. No publoques nada que una persona razonable consideraría ofensivo o abusivo. + * Mantén limpio el foro. No publiques nada obsceno o sexualmente explícito. + * Respeta. No molestes ni acoses a los demás usuarios, tampoco publiques su información privada y/o personal. + * Respeta el foro. No publiques spam ni nos estropees el foro. + + Como puedes ver, estos no son términos exactos con definiciones exactas. Evita siquiera la aparición de cualquiera de estas cosas en el foro. Si no estás seguro, piensa en cómo te sentirías si tu post apareciera en la portada de algún periódico importante. + + Este es un foro público y por tanto el contenido puede aparecer en los motores de búsqueda. El foro es para todos los públicos, así que debes tener cuidado con el vocabulario y el contenido. + + + + ## [Mantén limpio y organizado el foro](#keep-tidy) + + Esfuérzate para poner las cosas en su lugar correspondiente para que podamos estar más tiempo participando en la comunidad y menos tiempo limpiando y organizando. + + * No empieces un nuevo tema en la categoría equivocada. + * No publiques lo mismo en varios temas diferentes. + * No respondas con un mensaje sin contenido. + * No desvíes un tema en mitad de la discusión. + * No firmes tus mensajes — tu información y perfil están claramente visibles junto al post. + + En vez de responder “+1” or “Estoy de acuerdo”, usa el botón de Me gusta. En lugar de cambiar radicalmente la dirección de un tema, responde como nuevo tema. + + + + ## [Publica sólo lo que es tuyo](#stealing) + + No publiques nada que pertenezca a otra persona sin permiso. No debes facilitar enlaces, descipciones o métodos de robar la propiedad intelectual de los demás. (software, vídeo, audio, imágenes, etc.), o formas de violar las leyes. + + + + ## [Funcionamos gracias a gente como tú](#power) + + Este foro es operado por nuestro [equipo](/about) y *vosotros*, la comunidad. Si tienes alguna pregunta sobre cómo deberían funcionar las cosas aquí, abre un nuevo tema en la [categoría de Sugerencias](/c/site-feedback). Si pasa algo urgente que no puede ser resuelto con un tema o un reporte, contáctanos a través de [esta página](/about). + + + + ## [Términos del Servicio](#tos) + + Sí, estos temas aburren, pero debemos protegernos – y, por extensión, a ti y a tus datos – frente a gente poco amigable. Tenemos unos [Términos del Servicio](/tos) que describen nuestra forma de actuar (y la tuya), y los derechos con relación al contenido, la privacidad y las leyes, Para usar nuestros servicios, debes aceptar nuestros [Términos y Condiciones](/tos). tos_topic: title: "Términos de Servicio" + body: | + The following terms and conditions govern all use of the %{company_domain} website and all content, services and products available at or through the website, including, but not limited to, %{company_domain} Forum Software, %{company_domain} Support Forums and the %{company_domain} Hosting service ("Hosting"), (taken together, the Website). The Website is owned and operated by %{company_full_name} ("%{company_name}"). The Website is offered subject to your acceptance without modification of all of the terms and conditions contained herein and all other operating rules, policies (including, without limitation, %{company_domain}’s [Privacy Policy](/privacy) and [Community Guidelines](/faq)) and procedures that may be published from time to time on this Site by %{company_name} (collectively, the "Agreement"). + + Please read this Agreement carefully before accessing or using the Website. By accessing or using any part of the web site, you agree to become bound by the terms and conditions of this agreement. If you do not agree to all the terms and conditions of this agreement, then you may not access the Website or use any services. If these terms and conditions are considered an offer by %{company_name}, acceptance is expressly limited to these terms. The Website is available only to individuals who are at least 13 years old. + + + + ## [1. Your %{company_domain} Account](#1) + + If you create an account on the Website, you are responsible for maintaining the security of your account and you are fully responsible for all activities that occur under the account. You must immediately notify %{company_name} of any unauthorized uses of your account or any other breaches of security. %{company_name} will not be liable for any acts or omissions by you, including any damages of any kind incurred as a result of such acts or omissions. + + + + ## [2. Responsibility of Contributors](#2) + + If you post material to the Website, post links on the Website, or otherwise make (or allow any third party to make) material available by means of the Website (any such material, "Content"), You are entirely responsible for the content of, and any harm resulting from, that Content. That is the case regardless of whether the Content in question constitutes text, graphics, an audio file, or computer software. By making Content available, you represent and warrant that: + + * the downloading, copying and use of the Content will not infringe the proprietary rights, including but not limited to the copyright, patent, trademark or trade secret rights, of any third party; + * if your employer has rights to intellectual property you create, you have either (i) received permission from your employer to post or make available the Content, including but not limited to any software, or (ii) secured from your employer a waiver as to all rights in or to the Content; + * you have fully complied with any third-party licenses relating to the Content, and have done all things necessary to successfully pass through to end users any required terms; + * the Content does not contain or install any viruses, worms, malware, Trojan horses or other harmful or destructive content; + * the Content is not spam, is not machine- or randomly-generated, and does not contain unethical or unwanted commercial content designed to drive traffic to third party sites or boost the search engine rankings of third party sites, or to further unlawful acts (such as phishing) or mislead recipients as to the source of the material (such as spoofing); + * the Content is not pornographic, does not contain threats or incite violence, and does not violate the privacy or publicity rights of any third party; + * your content is not getting advertised via unwanted electronic messages such as spam links on newsgroups, email lists, blogs and web sites, and similar unsolicited promotional methods; + * your content is not named in a manner that misleads your readers into thinking that you are another person or company; and + * you have, in the case of Content that includes computer code, accurately categorized and/or described the type, nature, uses and effects of the materials, whether requested to do so by %{company_name} or otherwise. + + + + ## [3. User Content License](#3) + + User contributions are licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US). Without limiting any of those representations or warranties, %{company_name} has the right (though not the obligation) to, in %{company_name}’s sole discretion (i) refuse or remove any content that, in %{company_name}’s reasonable opinion, violates any %{company_name} policy or is in any way harmful or objectionable, or (ii) terminate or deny access to and use of the Website to any individual or entity for any reason, in %{company_name}’s sole discretion. %{company_name} will have no obligation to provide a refund of any amounts previously paid. + + + + + ## [4. Payment and Renewal](#4) + + ### General Terms + + Optional paid services or upgrades may be available on the Website. When utilizing an optional paid service or upgrade, you agree to pay %{company_name} the monthly or annual subscription fees indicated. Payments will be charged on a pre-pay basis on the day you begin utilizing the service or upgrade and will cover the use of that service or upgrade for a monthly or annual subscription period as indicated. These fees are not refundable. + + ### Automatic Renewal + + Unless you notify %{company_name} before the end of the applicable subscription period that you want to cancel a service or upgrade, your subscription will automatically renew and you authorize us to collect the then-applicable annual or monthly subscription fee (as well as any taxes) using any credit card or other payment mechanism we have on record for you. Subscriptions can be canceled at any time. + + + + ## [5. Services](#5) + + ### Hosting, Support Services + + Optional Hosting and Support services may be provided by %{company_name} under the terms and conditions for each such service. By signing up for a Hosting/Support or Support services account, you agree to abide by such terms and conditions. + + + + ## [6. Responsibility of Website Visitors](#6) + + %{company_name} has not reviewed, and cannot review, all of the material, including computer software, posted to the Website, and cannot therefore be responsible for that material’s content, use or effects. By operating the Website, %{company_name} does not represent or imply that it endorses the material there posted, or that it believes such material to be accurate, useful or non-harmful. You are responsible for taking precautions as necessary to protect yourself and your computer systems from viruses, worms, Trojan horses, and other harmful or destructive content. The Website may contain content that is offensive, indecent, or otherwise objectionable, as well as content containing technical inaccuracies, typographical mistakes, and other errors. The Website may also contain material that violates the privacy or publicity rights, or infringes the intellectual property and other proprietary rights, of third parties, or the downloading, copying or use of which is subject to additional terms and conditions, stated or unstated. %{company_name} disclaims any responsibility for any harm resulting from the use by visitors of the Website, or from any downloading by those visitors of content there posted. + + + + ## [7. Content Posted on Other Websites](#7) + + We have not reviewed, and cannot review, all of the material, including computer software, made available through the websites and webpages to which %{company_domain} links, and that link to %{company_domain}. %{company_name} does not have any control over those non-%{company_domain} websites and webpages, and is not responsible for their contents or their use. By linking to a non-%{company_domain} website or webpage, %{company_name} does not represent or imply that it endorses such website or webpage. You are responsible for taking precautions as necessary to protect yourself and your computer systems from viruses, worms, Trojan horses, and other harmful or destructive content. %{company_name} disclaims any responsibility for any harm resulting from your use of non-%{company_domain} websites and webpages. + + + + ## [8. Copyright Infringement and DMCA Policy](#8) + + As %{company_name} asks others to respect its intellectual property rights, it respects the intellectual property rights of others. If you believe that material located on or linked to by %{company_domain} violates your copyright, and if this website resides in the USA, you are encouraged to notify %{company_name} in accordance with %{company_name}’s [Digital Millennium Copyright Act](http://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act) ("DMCA") Policy. %{company_name} will respond to all such notices, including as required or appropriate by removing the infringing material or disabling all links to the infringing material. %{company_name} will terminate a visitor’s access to and use of the Website if, under appropriate circumstances, the visitor is determined to be a repeat infringer of the copyrights or other intellectual property rights of %{company_name} or others. In the case of such termination, %{company_name} will have no obligation to provide a refund of any amounts previously paid to %{company_name}. + + + + ## [9. Intellectual Property](#9) + + This Agreement does not transfer from %{company_name} to you any %{company_name} or third party intellectual property, and all right, title and interest in and to such property will remain (as between the parties) solely with %{company_name}. %{company_name}, %{company_domain}, the %{company_domain} logo, and all other trademarks, service marks, graphics and logos used in connection with %{company_domain}, or the Website are trademarks or registered trademarks of %{company_name} or %{company_name}’s licensors. Other trademarks, service marks, graphics and logos used in connection with the Website may be the trademarks of other third parties. Your use of the Website grants you no right or license to reproduce or otherwise use any %{company_name} or third-party trademarks. + + + + ## [10. Advertisements](#10) + + %{company_name} reserves the right to display advertisements on your content unless you have purchased an Ad-free Upgrade or a Services account. + + + + ## [11. Attribution](#11) + + %{company_name} reserves the right to display attribution links such as ‘Powered by %{company_domain},’ theme author, and font attribution in your content footer or toolbar. Footer credits and the %{company_domain} toolbar may not be removed regardless of upgrades purchased. + + + + ## [12. Changes](#12) + + %{company_name} reserves the right, at its sole discretion, to modify or replace any part of this Agreement. It is your responsibility to check this Agreement periodically for changes. Your continued use of or access to the Website following the posting of any changes to this Agreement constitutes acceptance of those changes. %{company_name} may also, in the future, offer new services and/or features through the Website (including, the release of new tools and resources). Such new features and/or services shall be subject to the terms and conditions of this Agreement. + + + + ## [13. Termination](#13) + + %{company_name} may terminate your access to all or any part of the Website at any time, with or without cause, with or without notice, effective immediately. If you wish to terminate this Agreement or your %{company_domain} account (if you have one), you may simply discontinue using the Website. All provisions of this Agreement which by their nature should survive termination shall survive termination, including, without limitation, ownership provisions, warranty disclaimers, indemnity and limitations of liability. + + + + ## [14. Disclaimer of Warranties](#14) + + The Website is provided "as is". %{company_name} and its suppliers and licensors hereby disclaim all warranties of any kind, express or implied, including, without limitation, the warranties of merchantability, fitness for a particular purpose and non-infringement. Neither %{company_name} nor its suppliers and licensors, makes any warranty that the Website will be error free or that access thereto will be continuous or uninterrupted. If you’re actually reading this, here’s [a treat](http://www.newyorker.com/online/blogs/shouts/2012/12/the-hundred-best-lists-of-all-time.html). You understand that you download from, or otherwise obtain content or services through, the Website at your own discretion and risk. + + + + ## [15. Limitation of Liability](#15) + + In no event will %{company_name}, or its suppliers or licensors, be liable with respect to any subject matter of this agreement under any contract, negligence, strict liability or other legal or equitable theory for: (i) any special, incidental or consequential damages; (ii) the cost of procurement for substitute products or services; (iii) for interruption of use or loss or corruption of data; or (iv) for any amounts that exceed the fees paid by you to %{company_name} under this agreement during the twelve (12) month period prior to the cause of action. %{company_name} shall have no liability for any failure or delay due to matters beyond their reasonable control. The foregoing shall not apply to the extent prohibited by applicable law. + + + + ## [16. General Representation and Warranty](#16) + + You represent and warrant that (i) your use of the Website will be in strict accordance with the %{company_name} [Privacy Policy](/privacy), [Community Guidelines](/guidelines), with this Agreement and with all applicable laws and regulations (including without limitation any local laws or regulations in your country, state, city, or other governmental area, regarding online conduct and acceptable content, and including all applicable laws regarding the transmission of technical data exported from the country in which this website resides or the country in which you reside) and (ii) your use of the Website will not infringe or misappropriate the intellectual property rights of any third party. + + + + ## [17. Indemnification](#17) + + You agree to indemnify and hold harmless %{company_name}, its contractors, and its licensors, and their respective directors, officers, employees and agents from and against any and all claims and expenses, including attorneys’ fees, arising out of your use of the Website, including but not limited to your violation of this Agreement. + + + + ## [18. Miscellaneous](#18) + + This Agreement constitutes the entire agreement between %{company_name} and you concerning the subject matter hereof, and they may only be modified by a written amendment signed by an authorized executive of %{company_name}, or by the posting by %{company_name} of a revised version. Except to the extent applicable law, if any, provides otherwise, this Agreement, any access to or use of the Website will be governed by the laws of the state of California, U.S.A., excluding its conflict of law provisions, and the proper venue for any disputes arising out of or relating to any of the same will be the state and federal courts located in San Francisco County, California. Except for claims for injunctive or equitable relief or claims regarding intellectual property rights (which may be brought in any competent court without the posting of a bond), any dispute arising under this Agreement shall be finally settled in accordance with the Comprehensive Arbitration Rules of the Judicial Arbitration and Mediation Service, Inc. (“JAMS”) by three arbitrators appointed in accordance with such Rules. The arbitration shall take place in San Francisco, California, in the English language and the arbitral decision may be enforced in any court. The prevailing party in any action or proceeding to enforce this Agreement shall be entitled to costs and attorneys’ fees. If any part of this Agreement is held invalid or unenforceable, that part will be construed to reflect the parties’ original intent, and the remaining portions will remain in full force and effect. A waiver by either party of any term or condition of this Agreement or any breach thereof, in any one instance, will not waive such term or condition or any subsequent breach thereof. You may assign your rights under this Agreement to any party that consents to, and agrees to be bound by, its terms and conditions; %{company_name} may assign its rights under this Agreement without condition. This Agreement will be binding upon and will inure to the benefit of the parties, their successors and permitted assigns. + + This document is CC-BY-SA. It was last updated May 31, 2013. + + Originally adapted from the [WordPress Terms of Service](http://en.wordpress.com/tos/). privacy_topic: title: "Políticas de Privacidad" - body: "\n\n## [¿Qué información recolectamos?](#collect)\n\nRecolectamos información tuya cuando te registras en nuestra web, y recopilamos información cuando participas en ella leyendo, escribiendo y evaluando el contenido compartido aquí.\n\nAl registrarte en nuestra web, puede que se te pida que indiques tu nombre y tu email. Sin embargo, puedes visitarnos sin registrarte. Tu email será verificado a través de un mensaje que contendrá un enlace único. Si ese enlace es visitado, sabremos que controlas el email.\n\nCuando estés registrado y publiques, guardamos la dirección IP de donde el mensaje ha sido publicado. Puede que guardemos registros que incluyan la dirección IP de cada intercambio de datos con nuestro servidor.\n\n\n\n## [¿Para qué usamos tu información?](#use)\n\nCualquier información recolectada puede ser usada en una de las siguientes\ - \ maneras:\n\n* Para personalizar tu experiencia — tu información nos ayuda a responder a tus necesidades individuales.\n* Para mejorar nuestra web — intentamos continuamente mejorar nuestro sitio web ofreciéndote contenido basado en la información que recibimos de ti.\n* Para mejorar el servicio de soporte — tu información nos ayuda a responder de una forma más efectiva a tus dudas y problemas.\n* Para enviar emails cada cierto tiempo — La direccion de email que nos proporciones puede ser usada para enviarte información, notificaciones que tú solicites sobre cambios en temas, sobre respuestas a tu nombre, respuestas a consultas y/o cualquier otro tipo de solicitudes o cuestiones.\n\n\n\n## [¿Cómo protegemos tu información?](#protect)\n\nTenemos implementadas varias medidas de seguridad para mantener tu información personal segura cuuando la introduces\ - \ o accedes a ella.\n\n\n\n## [¿Cuál es la política de retención de datos?](#data-retention)\n\nIntentamos:\n\n* No retener los registros de los servidores conteniendo la dirección IP de todas las solicitudes durante más de 90 días.\n* No retener las direcciones IP asociadas con usuarios registrados y sus mensajes durante no más de 5 años.\n\n\n\n\n## [¿Usamos cookies?](#cookies)\n\nSí. Las cookies con pequeños archivos que una web o su proveedor de servicios transfiere a tu disco duro a través de tu navegador (si lo permites).\nEstas cookies permiten a la web reconocer tu navegador y, si tienes una cuenta registrada, asociarlo con ella.nt.\n\nUsamos cookies para entender y guardar tus preferencias para futuras visitas y para recolectar información sobre el tráfico y la interacción con este sitio web para que podamos ofrecer mejores experiencias\ - \ y herramientas en un futuro. Puede que nos asociemos con terceras personas para que nos asisten a entender mejor a nuestros visitantes. Estos proveedores de servicios no tienen permitido usar esta información para otro propósito que no sea ayudarnos a mejorar.\n\n\n\n## [¿Revelamos alguna información a terceros?](#disclose)\n\nNo vendemos, intercambiamos o transferimos a terceros tu información personal. Esto no incluye a terceros que nos ayuden a operar correctamente este sitio web, a administrar nuestro negocio o a ofrecerte un servicio, siempre y cuando acepten mantener esta información confidencial.\nPuede que revelemos tu información cuando creamos que sea apropiado para cumplir con la ley, hacer cumplir con nuestras políticas, derechos, propiedades, o seguridad nuestros o de terceros. Sin embargo, la información no personal de los visitantes puede que sea entregada\ - \ debidamente a terceros con propósitos de marketing, publicidad u otros usos. \n\n\n\n## [Enlaces de terceros](#third-party)\n\nOcasionalmente, es posible que incluyamos u ofrezcamos enlaces a productos o servicios de terceros en esta web. Estos sitios webs de terceros tienen otras políticas de privacidad, por lo que no nos hacemos responsables del contenido y actividades de estos sitios. Sin embargo, intentamos proteger la integridad de nuestra web y aceptamos opiniones sobre estos sitios de terceros.\n\n\n\n## [Cumplimiento del Acta de Protección de la Privacidad Online de los Niños de 1998](#coppa)\n\nNuestra web, sus productos y servicios están dirigidos a personas que tengan 13 o más años de edas. Si este servidor está en EEUU, y tienes menos de 13 años de edad, a causa del Acta de Protección de la Privacidad Online de los Niños de 1998\ - \ ([Children's Online Privacy Protection Act](https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act)) de EEUU, no uses este sitio web.\n\n\n\n## [Política de privacidad online](#online)\n\nEsta política de privacidad sólo tiene validez para la información recolectada a través de nuestro sitio web, y no para aquella recolectada offline.\n\n\n\n## [Consentimiento](#consent)\n\nAl usar nuestra web, aceptas esta política.\n\n\n\n## [Cambios a nuestra política de privacidad](#changes)\n\nSi decidimos cambiar nuestra política de privacidad, publicaremos los cambios en esta misma página.\n\nEste documento tiene una licencia \"CC-BY-SA\". Última actualización: 31 de mayo del 2013.\n" - static: - search_help: | -

    Consejos

    -

    -

      -
    • Las coincidencias por título tienen prioridad – de manera que si tienes dudas, mejor busca por títulos
    • -
    • Buscar palabras diferentes, no muy comunes, siempre dará mejores resultados
    • -
    • Cuando sea posible, centra tu búsqueda en una categoría, un tema o un usuario en concreto
    • -
    -

    -

    Opciones

    -

    - - - - - - - -
    order:viewsorder:latestorder:likes
    status:openstatus:closedstatus:archivedstatus:norepliesstatus:single_user
    category:foouser:foogroup:foobadge:foo
    in:likesin:postedin:watchingin:trackingin:private
    in:bookmarksin:first
    posts_count:nummin_age:daysmax_age:days
    -

    -

    - gatos category:parques status:open order:latest buscará temas que contengan la palabra "gatos" en la categoría "parques" que no estén cerrados o archivados, ordenados por fecha del último post. -

    - badges: - long_descriptions: - autobiographer: | - Este distintivo se otorga por completar tu perfil de usuario y seleccionando una foto de perfil. Permitiendo a la comunidad saber más sobre ti y tus intereses hace que la comunidad sea mejor y esté más conectada. - first_like: "Este distintivo se otorga la primera vez que le das 'Me gusta' a un post usando el botón de :heart:. Dándole 'Me gusta' a posts es una manera estupenda de hacer saber al resto de compañeros de la comunidad que lo que han publicado te ha parecido interesante, útil, chulo o divertido. \n" - first_link: | - Este distintivo se otorga la primera vez que incluyes un enlace a otro tema en una respuesta. Enlazar temas ayuda al resto de lectores a encontrar interesantes conversaciones relevantes al enseñar las conexiones que dos temas tienen. - first_quote: | - Este distintivo se otorga la primera vez que citas un post en una respuesta. Citar secciones relevantes de posts anteriores en tus respuestas ayuda a mantener los debates centrados en el tema central. - first_share: | - Este distintivo se otorga la primera vez que compartes un enlace a una respuesta o tema usando el botón de compartir. Compartir enlaces es una buena manera de mostrar contenido interesante de la comunidad al resto de gente, ayudando a su crecimiento. - read_guidelines: | - Este distintivo se otorga por leer las directrices de la comunidad. Siguiendo y compartiendo estas simples directrices ayuda a construir una comunidad segura, divertida y sostenible. - reader: | - Este distintivo se otorga por leer un tema largo. Leer es fundamental. Leer al detalle ayuda a seguir la conversación y hace que las respuestas sean mejores y más completas. - editor: | - Este distintivo se otorga por editar tu post. No dudes en editar tus posts en cualquier momento para mejorarlos, corregir pequeños errores o añadir algo que olvidaste. - first_flag: "Este distintivo se concede por reportar un post. Reportar es crítico para la salud de tu comunidad. Si detectas que alguna publicación requiere de la atención de un moderador por favor \nno dudes en reportarlo. También puedes usar el diálogo de reporte para enviar mensajes a otros usuarios.\n\n" - nice_share: | - Este distintivo se concede por compartir un enlace a un post que ha recibido 25 visitantes nuevos. ¡Buen trabajo! Compartir enlaces a debates interesantes con amigos es una manera excelente de hacer crecer nuestra comunidad. - welcome: | - Este distintivo se concede cuando recibes tu primer Me gusta en un post. ¡Enhorabuena, has publicado algo que la comunidad considera guay, útil o interesante! - anniversary: | - Este distintivo se concede cuando cumples un año como miembro que ha publicado al menos un post. ¡Gracias por pasarte por aquí y contribuir a nuestra comunidad! - good_share: | - Este distintivo se concede por compartir un enlace a un post que ha recibido 300 visitantes nuevos. ¡Genial! Has descubierto un debate interesante para mucha gente que no conocía el sitio y nos has ayudado a crecer. - great_share: | - Este distintivo se concede por compartir un enlace a un post que ha recibido 1000 visitantes nuevos. ¡Bravo! Has promovido un debate interesante para una inmensa audiencia que no conocía el sitio y nos has ayudado a crecer muchísimo. - nice_post: | - Este distintivo se concede al publicar una respuesta con 10 Me gusta. ¡Buen trabajo! - nice_topic: | - Este distintivo se concede al crear un tema con 10 Me gusta. ¡Buen trabajo! - good_post: | - Este distintivo se concede al publicar una respuesta con 25 Me gusta. ¡Genial! - good_topic: | - Este distintivo se concede al crear un tema con 25 Me gusta. ¡Genial! - great_post: | - Este distintivo se concede al publicar una respuesta con 50 Me gusta. ¡Excelente! - great_topic: | - Este distintivo se concede al crear un tema con 50 Me gusta. ¡Excelente! - basic: | - Este distintivo se concede cuando alcanzas el nivel de confianza 1. Gracias por pasar por aquí un momento y leer unos cuantos temas para ver de qué va esta comunidad. Las restricciones de nuevo usuario se eliminan y podrás usar las funcionalidades esenciales del sitio como enviar mensajes a otras personas, reportar posts, editar posts wiki y publicar imágenes o varios enlaces. - member: | - Este distintivo se concede cuando alcanzas el nivel de confianza 2. Gracias por tu constante participación en la comunidad. Ahora puedes enviar invitaciones a otras personas desde tu perfil o temas individuales, enviar mensajes a grupos y dar más Me gusta por día. - regular: | - Este distintivo se concede cuando alcanzas el nivel de confianza 3. Gracias por tomar parte activa de nuestra comunidad por tanto tiempo, ser uno de los más ávidos lectores y contribuir tanto a su crecimiento y calidad. Ahora puedes recategorizar o renombrar temas, acceder al área vip, reportar spam de forma más contundente y dar muchos más Me gusta por día. - leader: | - Este distintivo se concede cuando alcanzas el nivel de confianza 4. Eres un líder de la comunidad elegido por los administradores, constituyes un ejemplo positivo para los demás mediante tus hechos y palabras. Ahora puedes editar todos los posts, dar muchísimos Me gusta por día y realizar acciones de moderador como destacar temas, cerrarlos, archivarlos, hacerlos invisibles, dividirlos o integrarlos. + body: "\n\n## [¿Qué información recolectamos?](#collect)\n\nRecolectamos información tuya cuando te registras en nuestra web, y recopilamos información cuando participas en ella leyendo, escribiendo y evaluando el contenido compartido aquí.\n\nAl registrarte en nuestra web, puede que se te pida que indiques tu nombre y tu email. Sin embargo, puedes visitarnos sin registrarte. Tu email será verificado a través de un mensaje que contendrá un enlace único. Si ese enlace es visitado, sabremos que controlas el email.\n\nCuando estés registrado y publiques, guardamos la dirección IP de donde el mensaje ha sido publicado. Puede que guardemos registros que incluyan la dirección IP de cada intercambio de datos con nuestro servidor.\n\n\n\n## [¿Para qué usamos tu información?](#use)\n\nCualquier información recolectada puede ser usada en una de las siguientes maneras:\n\n* Para personalizar tu experiencia — tu información nos ayuda a responder a tus necesidades individuales.\n* Para mejorar nuestra web — intentamos continuamente mejorar nuestro sitio web ofreciéndote contenido basado en la información que recibimos de ti.\n* Para mejorar el servicio de soporte — tu información nos ayuda a responder de una forma más efectiva a tus dudas y problemas.\n* Para enviar emails cada cierto tiempo — La direccion de email que nos proporciones puede ser usada para enviarte información, notificaciones que tú solicites sobre cambios en temas, sobre respuestas a tu nombre, respuestas a consultas y/o cualquier otro tipo de solicitudes o cuestiones.\n\n\n\n## [¿Cómo protegemos tu información?](#protect)\n\nTenemos implementadas varias medidas de seguridad para mantener tu información personal segura cuuando la introduces o accedes a ella.\n\n\n\n## [¿Cuál es la política de retención de datos?](#data-retention)\n\nIntentamos:\n\n* No retener los registros de los servidores conteniendo la dirección IP de todas las solicitudes durante más de 90 días.\n* No retener las direcciones IP asociadas con usuarios registrados y sus mensajes durante no más de 5 años.\n\n\n\n\n## [¿Usamos cookies?](#cookies)\n\nSí. Las cookies con pequeños archivos que una web o su proveedor de servicios transfiere a tu disco duro a través de tu navegador (si lo permites).\nEstas cookies permiten a la web reconocer tu navegador y, si tienes una cuenta registrada, asociarlo con ella.nt.\n\nUsamos cookies para entender y guardar tus preferencias para futuras visitas y para recolectar información sobre el tráfico y la interacción con este sitio web para que podamos ofrecer mejores experiencias y herramientas en un futuro. Puede que nos asociemos con terceras personas para que nos asisten a entender mejor a nuestros visitantes. Estos proveedores de servicios no tienen permitido usar esta información para otro propósito que no sea ayudarnos a mejorar.\n\n\n\n## [¿Revelamos alguna información a terceros?](#disclose)\n\nNo vendemos, intercambiamos o transferimos a terceros tu información personal. Esto no incluye a terceros que nos ayuden a operar correctamente este sitio web, a administrar nuestro negocio o a ofrecerte un servicio, siempre y cuando acepten mantener esta información confidencial.\nPuede que revelemos tu información cuando creamos que sea apropiado para cumplir con la ley, hacer cumplir con nuestras políticas, derechos, propiedades, o seguridad nuestros o de terceros. Sin embargo, la información no personal de los visitantes puede que sea entregada debidamente a terceros con propósitos de marketing, publicidad u otros usos. \n\n\n\n## [Enlaces de terceros](#third-party)\n\nOcasionalmente, es posible que incluyamos u ofrezcamos enlaces a productos o servicios de terceros en esta web. Estos sitios webs de terceros tienen otras políticas de privacidad, por lo que no nos hacemos responsables del contenido y actividades de estos sitios. Sin embargo, intentamos proteger la integridad de nuestra web y aceptamos opiniones sobre estos sitios de terceros.\n\n\n\n## [Cumplimiento del Acta de Protección de la Privacidad Online de los Niños de 1998](#coppa)\n\nNuestra web, sus productos y servicios están dirigidos a personas que tengan 13 o más años de edas. Si este servidor está en EEUU, y tienes menos de 13 años de edad, a causa del Acta de Protección de la Privacidad Online de los Niños de 1998 ([Children's Online Privacy Protection Act](https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act)) de EEUU, no uses este sitio web.\n\n\n\n## [Política de privacidad online](#online)\n\nEsta política de privacidad sólo tiene validez para la información recolectada a través de nuestro sitio web, y no para aquella recolectada offline.\n\n\n\n## [Consentimiento](#consent)\n\nAl usar nuestra web, aceptas esta política.\n\n\n\n## [Cambios a nuestra política de privacidad](#changes)\n\nSi decidimos cambiar nuestra política de privacidad, publicaremos los cambios en esta misma página.\n\nEste documento tiene una licencia \"CC-BY-SA\". Última actualización: 31 de mayo del 2013.\n" admin_login: success: "Email enviado" error: "¡Error!" @@ -1864,3 +2023,8 @@ es: performance_report: initial_post_raw: Este tema contiene informes diarios sobre el rendimiento de tu sito. initial_topic_title: Informe sobre el rendimiento del sitio + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.fa_IR.yml b/config/locales/server.fa_IR.yml index 92229021a8b..22b0cf5acca 100644 --- a/config/locales/server.fa_IR.yml +++ b/config/locales/server.fa_IR.yml @@ -10,18 +10,21 @@ fa_IR: short_date_no_year: "D MMM" short_date: "D MMM, YYYY" long_date: "MMMM D, YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%m-%d-%Y" + short_no_year: "%B %-d" + date_only: "%B %-d, %Y" title: "گفتمان" topics: "موضوعات" posts: "نوشته ها" loading: "بارگذاری..." powered_by_html: 'قدرت گرفته ازدیسکورسفارسی سازی دیسکورس فارسی, برای نمایش بهتر جاوا اسکریپت را فعال کنید.' log_in: "ورود" - via: "%{username} از %{site_name}" - is_reserved: "محفوظ است" purge_reason: "بطور خودکار پاک شد بدلیل استفاده نشدن٬ حساب کاربری غیرفعال" disable_remote_images_download_reason: "عکس های ریموت دانلود شده غیرفعال شدند زیرا آنجا فضای کافی در دیسک وجود نداشت" anonymous: "ناشناس" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "محدود به %{max} کاراکتر; شما وارد %{length} کردید " @@ -37,8 +40,10 @@ fa_IR: exclusion: محفوظ است greater_than: باید بیشتر از %{count} باشد greater_than_or_equal_to: باید بیشتر و یا مساوی %{count} باشد + has_already_been_used: "قبلا استفاده شده" inclusion: در لیست وجود ندارد invalid: صحیح نیست + is_invalid: "نامعتبر است, سعی کنید کمی بیشتر توضیح دهید" less_than: باید کمتر از %{count} باشد less_than_or_equal_to: باید کمتر و یا مساوی %{count} باشد not_a_number: یک عدد نمی باشد @@ -61,6 +66,13 @@ fa_IR: other: '%{count} خطاهای ممنوع این %{model} از ذخیره شد ' embed: load_from_remote: "خطایی در بارگذاری آن پست رخ داده است." + site_settings: + min_username_length_exists: "شما نمیتوانید حداقل طول نام کاربری را بیشتر از کوتاه ترین نام کاربری بگذارید." + min_username_length_range: "شما نمیتوانید حداقل را بیشتر از حداکثر بگذارید." + max_username_length_exists: "شما نمیتوانید حداکثر طول نام کاربری را کمتر از بلند ترین نام کاربری بگذارید." + max_username_length_range: "شما نمیتوانید حداکثر را کمتر از حداقل بگذارید." + default_categories_already_selected: "شما نمیتوانید یک دسته بندی که در یک فهرست دیگر استفاده شده را انتخاب کنید." + s3_upload_bucket_is_required: "شما نمیتوانید بارگذاری به S3 را فعال کنید مگر اینکه 's3_upload_bucket' ارائه بدهید." bulk_invite: file_should_be_csv: "قالب پرونده‌ی بارگذاری شده باید csv و یا txt باشد." backup: @@ -84,26 +96,21 @@ fa_IR: in_reply_to: "▶ %{username}" replies: other: "%{count} پاسخ" + no_mentions_allowed: "متأسفیم، شما نمی‌توانید به کاربران دیگر اشاره کنید." too_many_mentions: - zero: "متأسفیم، شما نمی‌توانید به کاربران دیگر اشاره کنید." - one: "متأسفیم، شما در هر دیدگاه تنها می‌توانید به یک کاربر اشاره کنید." - other: "متأسفیم، شما در هر دیدگاه تنها می‌توانید به %{count} کاربر اشاره کنید." + other: "متأسفیم، شما در هر ارسال تنها می‌توانید به %{count} کاربر اشاره کنید." + no_mentions_allowed_newuser: "متأسفیم، کاربران تازه نمی‌توانند به کاربران دیگر اشاره کنند." too_many_mentions_newuser: - zero: "متأسفیم، کاربران تازه نمی‌توانند به کاربران دیگر اشاره کنند." - one: "متأسفیم، کاربران تازه در هر دیدگاه تنها می‌توانید به یک کاربر دیگر اشاره کنند." - other: "متأسفیم، کاربران تازه در هر دیدگاه تنها می‌توانید به %{count} کاربر دیگر اشاره کنند." + other: "متأسفیم، کاربران تازه در هر ارسال تنها می‌توانند به %{count} کاربر دیگر اشاره کنند." + no_images_allowed: "متأسفیم، کاربران تازه نمی‌توانند در ارسال ها تصویر بگذارند." too_many_images: - zero: "متأسفیم، کاربران تازه نمی‌توانند در دیدگاه‌ها تصویر بگذارند." - one: "متأسفیم، کاربران تازه تنها می‌توانند یک تصویر در هر دیدگاه بگذارند" - other: "متأسفیم، کاربران تازه تنها می‌توانند %{count} تصویر در هر دیدگاه بگذارند" + other: "متأسفیم، کاربران تازه تنها می‌توانند %{count} تصویر در هر ارسال بگذارند." + no_attachments_allowed: "متأسفیم، کاربران تازه امکان قرار دادن پیوست را در ارسال هایشان ندارند." too_many_attachments: - zero: "متأسفیم، کاربران تازه امکان اضافه کردن فایل به ارسال هایشان را ندارند." - one: "متأسفیم ، کاربران تازه فقط امکان اتصال تنها یک فایل به ارسال هایشان را دارند." - other: "متأسفیم ، کاربران تازه تنها اجازه اتصال %{count} فایل به ارسالی شان را دارند." + other: "متأسفیم ، کاربران تازه تنها میتوانند %{count} پیوست در هر ارسال قرار بدهند." + no_links_allowed: "متأسفیم، کاربران تازه نمی‌توانند در ارسال ها پیوند بگذارند." too_many_links: - zero: "متأسفیم، کاربران تازه نمی‌توانند در دیدگاه‌ها پیوند بگذارند." - one: "متأسفیم، کاربران تازه تنها می‌توانند در هر دیدگاه یک پیوند بگذارند." - other: "متأسفیم، کاربران تازه تنها می‌توانند در هر دیدگاه %{count} پیوند بگذارند." + other: "متأسفیم، کاربران تازه تنها می‌توانند در هر ارسال %{count} پیوند بگذارند." spamming_host: "متأسفانه شما نمی‌توانید پیوندی با آن نشانی را بفرستید." user_is_suspended: "کاربر تعلیق شده نمی‌تواند نوشته ای بگذارد." topic_not_found: "یک مشکلی وجود دارد. شاید این جستار بسته شده یا پاک شده همزمان که داشتی نگاهش می کردی ؟" @@ -135,6 +142,7 @@ fa_IR: errors: can_not_modify_automatic: "شما امکان تغییر یک گروه خودکار را ندارید." member_already_exist: "%{username}' در حال حاضر عضو این گروه است." + invalid_domain: "'%{domain}' یک دامنه معتبر نیست." default_names: everyone: "همه" admins: "مدیران" @@ -194,9 +202,6 @@ fa_IR: user_profile: bio_raw: "درباره من" errors: - messages: - is_invalid: "نامعتبر است. تلاش کنید که کمی بیش‌تر توضیح بگذارید." - has_already_been_used: "موجود می باشد" models: topic: attributes: @@ -217,6 +222,7 @@ fa_IR: attributes: hex: invalid: "این یک رنگ معتبر نیست" + <<: *errors user_profile: no_info_me: "
    درباره من نمایه شما خالی در حال حاضر خالی است٬ علاقه دارید آن را تکمیل کنید ؟
    " no_info_other: "
    %{name}هنوز چیزی وارد نکرده درباره خودش در نمایه شان. " @@ -252,13 +258,10 @@ fa_IR: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "در رابطه با دسته بندی {category}% " - replace_paragraph: "[به جای پاراگراف اول توضیحات کوتاهی درباره دسته جدیدتون قرار بدید. این راهنما در قسمت دسته ها نمایش داده می شود٬ پس سعی کن زیر 200 کلمه اون را نگاه دارید. قبل از اینکه این متن را ویرایش کنید یا جستار جدیدی بوجود بیاورید٬ این دسته در صفحه دسته ها نمایش داده نمی شود.]" - post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, as well as to establish any category guidelines or rules.\n\nSome things to consider in any discussion replies below:\n\n- What is this category for? Why should people select this category for their topic?\n\n- How is this different than the other categories we already have?\n\n- Do we need this category?\n\n- Should we merge this with another category, or split it into more categories?\n" errors: uncategorized_parent: "بدون دسته بندی نمی تواند طبقه خانواده داشته باشد" self_parent: "والد زیر شاخه نمی تواند خودش باشد." depth: "شما نمی توانید یک زیر شاخه را به آشیانه تبدیل کنید تحت دیگری " - email_in_already_exist: "ایمیل آدرس های ورودی '%{email_in}' که در حال حاضر استفاده می شوند برای '%{category_name}' دسته بندی. " cannot_delete: uncategorized: "بدون دسته بندی را نمی توان حذف کرد" has_subcategories: "این دسته بندی به دلیل داشتن زیردسته قابل پاک شدن نیست." @@ -270,16 +273,26 @@ fa_IR: title: "کاربر جدید" basic: title: "کاربر پایه" - regular: + member: title: "عضو" + regular: + title: "عادی" leader: - title: "عمومی" - elder: - title: "رهبر" + title: "رئیس" change_failed_explanation: "شما تلاش برای تنزل رتبه دادید %{user_name} به '%{new_trust_level}'. در هر صورت سطح اعتمادشان در حال حاضر '%{current_trust_level}' است. %{user_name} می ماند در '%{current_trust_level}' - اگر شما امید با تنزل رتبه شان را دارید اول سطح اعتمادشان را نگاه کنید" rate_limiter: - slow_down: "شما این عمل را بیش از حد انجام داده اید، بعدا دوباره تلاش کنید" + slow_down: "شما این عمل را بیش از حد انجام داده اید, بعدا دوباره امتحان کنید." too_many_requests: "ما روزانه محدودیت زمانی داریم برای اینکه این اقدام چند بار انجام شود. لطفا صبر کنید %{time_left} قبل ازاینکه دوباره تلاش کنید. " + by_type: + first_day_replies_per_day: "شما به حداکثر تعداد پاسخ هایی که یک کاربر تازه میتواند در روز اولش ایجاد کند رسیده اید. لطفا به مدت %{time_left} صبر کنید قبل از اینکه دوباره امتحان کنید." + first_day_topics_per_day: "شما به حداکثر تعداد مباحثی که یک کاربر تازه میتواند در روز اولش ایجاد کند رسیده اید. لطفا به مدت %{time_left} صبر کنید قبل از اینکه دوباره امتحان کنید." + create_topic: "شما مباحث را خیلی سریع ایجاد میکنید. لطفا به مدت %{time_left} صبر کنید قبل از اینکه دوباره امتحان کنید." + create_post: "شما پاسخ ها را بسیار سریع میدهید. لطفا به مدت %{time_left} صبر کنید قبل از اینکه دوباره امتحان کنید." + topics_per_day: "شما به حداکثر تعداد مباحث جدیدی که امروز میتوانید ایجاد کنید رسیده اید. لطفا به مدت %{time_left} صبر کنید قبل از اینکه دوباره امتحان کنید." + pms_per_day: "شما به حداکثر تعداد پیام هایی که امروز میتوانید بفرستید رسیده اید. لطفا به مدت %{time_left} صبر کنید قبل از اینکه دوباره امتحان کنید." + create_like: "شما به حداکثر تعداد پسند هایی که امروز میتوانید بکنید رسیده اید. لطفا به مدت %{time_left} صبر کنید قبل از اینکه دوباره امتحان کنید." + create_bookmark: "شما به حداکثر تعداد بوک مارک هایی که امروز میتوانید بکنید رسیده اید. لطفا به مدت %{time_left} صبر کنید قبل از اینکه دوباره امتحان کنید." + edit_post: "شما به حداکثر تعداد ویرایش هایی که امروز میتوانید بکنید رسیده اید. لطفا به مدت %{time_left} صبر کنید قبل از اینکه دوباره امتحان کنید." hours: other: "%{count} ساعت" minutes: @@ -336,6 +349,7 @@ fa_IR: almost_x_years: other: "حداقل %{count} سال قبل" password_reset: + no_token: "متآسفیم, پیوند تغییر رمز عبور بسیار قدیمی است. دکمه ورود را انتخاب کنید و از 'من رمز عبور خود را فراموش کرده ام' برای دریافت یک پیوند جدید استفاده کنید." choose_new: "لطفا یک رمز عبور جدید وارد کنید" choose: "لطفا یک رمز عبور وارد کنید" update: 'به‌روز کردن گذرواژه' @@ -349,6 +363,7 @@ fa_IR: please_continue: "برو به %{site_name}" error: "در تغییر ایمیلتان خطایی روی داد. شاید آن نشانی از پیش در حال استفاده است؟" activation: + action: "برای فعال کردن حساب کاربری خود اینجا کلیک کنید" already_done: "متاسفیم٬‌ این پیوند تاییدیه حساب کاربری دیگر معتبر نیست. شاید حساب کاربری شما در حال حاضر فعال است." please_continue: "حساب کاربری جدید شما تایید شد; شما به صفحه اصلی هدایت می شوید. " continue_button: "برو به %{site_name}" @@ -371,16 +386,16 @@ fa_IR: description: 'محتوای این موضوع شامل مواردی میشود که یک شخص می تونه آن را توهین آمیز٬ آزار دهنده٬‌ یا نقض کننده قوانین انجمن باشد. اصول انجمن .' long_form: 'این مورد نامناسب دانسته شد.' notify_user: - title: 'پیام @{{username}}' - description: 'محتوای این نوشته چیزی هست که من می خوام بصورت خصوصی و مستقیم درباره آن حرف بزنم. برای دیگران پرچم گزاری نکن.' + title: 'فرستادن یک پیام به @{{username}}' + description: 'من میخواهم با این شخص به صورت مستقیم و محرمانه درباره ارسالشان صحبت کنم.' long_form: 'به کاربر پیام داده شد' email_title: 'نوشته ی شما در "{title}%"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "یک چیز دیگر" - description: 'این نوشته نیاز به توجه مدیر دارد به دلیل دیگری که در پایین لیست نشده است ' - long_form: 'این را برای توجه مدیر پرچم بزن ' - email_title: 'یک پست در "%{title}" نیاز به توجه مدیر دارد' + description: 'این ارسال نیاز به توجه مدیران دارد برای یک دلیل دیگر که در بالا ذکر نشده.' + long_form: 'برای توجه مدیران پرچم گذاری شد' + email_title: 'یک ارسال در "%{title}" نیاز به توجه مدیران دارد' email_body: "%{link}\n\n%{message}" bookmark: title: 'نشانک گذاری' @@ -405,7 +420,7 @@ fa_IR: long_form: 'پرچم گزاری شده به عنوان نامناسب' notify_moderators: title: "یک چیز دیگر" - description: 'این موضوع نیاز به توجه مدیر دارد بر اساس دستورعمل های سایت, TOS, یا به دلیل دیگری که اینجا اشاره نشده است. ' + description: 'این مبحث نیاز به توجه ستاد مدیران دارد بر اساس guidelines, TOS, یا یک دلیل دیگر که در بالا ذکر نشده.' long_form: 'این را برای توجه مدیر پرچم گزاری کن' email_title: 'این موضوع "%{title}" نیاز به توجه مدیر دارد. ' email_body: "%{link}\n\n%{message}" @@ -441,6 +456,10 @@ fa_IR: title: "کاربران جدید" xaxis: "روز" yaxis: "تعداد کاربران جدید" + profile_views: + title: "بازدید های پروفایل کاربر" + xaxis: "روز" + yaxis: "تعداد پروفایل های کاربری که بازدید شده اند" topics: title: "جُستارها" xaxis: "روز" @@ -588,37 +607,6 @@ fa_IR: consumer_email_warning: "سایت شما برای استفاده از ایمیل گوگل پیکربندی شده (یا دیگر سرویس دهندگان ایمیل) برای ارسال ایمیل. جیمیل محدود می کند که چند ایمیل می توانی بفرستی. استفاده از یک ارائه دهنده خدمات ایمیل را مانند mandrill.com در نظر بگیرید برای اطمنیان از قابلیت تحوبل ایمیل. " site_contact_username_warning: "برای ارسال پیام خودکار ایمیل یکی از کارکنان مهربان را وارد کن . اطلاعات تماس وب سایت را به روز کن در تنظیمات سایت ." notification_email_warning: "ایمیل های آگهی دهنده از طریق ایمیل نا صحیح در دامنه شما ارسال نمی شوند; تحویل ایمیل نامنظم و غیر قابل اعتماد خواهد بود. لطفا ایمیل آگهی دهنده را با یک ایمیل آدرس محلی وارد کنید در تنظیمات سایت ." - content_types: - education_new_reply: - title: "آموزش کاربر جدید: پاسخ های اول" - description: "نشانگر کوتاه فقط-در-زمان راهنما بطور خودکار در پایین قسمت نویسنده نشان داده می شود وقتی کاربران جدید در حال نوشتن دو پاسخ اولیه خود هستند. " - education_new_topic: - title: "آموزش کاربر جدید: موضوع های اول" - description: "نشانگر کوتاه فقط-در-زمان راهنما بطور خودکار در پایین قسمت نویسنده نشان داده می شود وقتی کاربران جدید در حال نوشتن دو جستار اولیه خود هستند. " - usage_tips: - title: "راهنما برای کاربر جدید" - description: "راهنما و اطلاعات ضروری برای کاربران جدید " - welcome_user: - title: "خوش آمدیده اید : کاربر جدید" - description: "این پیام بصورت خودکار به تمام کاربران جدید وقتی نام نویسی می کنند ارسال می شود. " - welcome_invite: - title: "خوش آمدید: کاربران دعوت شده" - description: "این پیام به صورت خودکار به تمام کاربران دعوت شده جدید ارسال می شود وقتی دعوتنامه را از طرف کاربر دیگری برای شرکت قبول می کنند. " - login_required_welcome_message: - title: "ورود مورد نیاز است: پیام خوش آمدید " - description: "پیام خوش آمدید به کاربرانی که از سیستم خارج شده اند نشان داده می شود وقتی که تنظیمات ورود به سیستم روشن است." - login_required: - title: "ورود مورد نیاز است: صفحه اصلی" - description: "نوشته نشان داده شده برای کاربران غیرمجاز است وقتی که ورود مورد نیاز است در سایت. " - head: - title: "HTML head" - description: "HTML هایی که در قبل از تگ باید استفاده شوند." - top: - title: "بالای صفحه ها " - description: "HTML هایی در بالای هر صفحه اضافه می شوند ( بعد از سربرگ٬ قبل از جهت نما یا عنوان جستار)." - bottom: - title: "پایین صفحه ها" - description: "HTML که قبل از تگ به آن اضافه می شه " site_settings: censored_words: "کلماتی که به صورت خودکار جایگزین می شوند با ■■■■" delete_old_hidden_posts: "پاک کردن خودکار تمام نوشته هایی که بیش از 30 روز بصورت پنهان باقی می مانند. " @@ -633,7 +621,6 @@ fa_IR: min_private_message_title_length: "حداقل طول مجاز عنوان برای پیام در کاراکتر" min_search_term_length: "حداقل طول واژه جستجوی معتبر در کاراکتر" allow_uncategorized_topics: "اجازه ایجاد عناوین فاقد دسته‌بندی را بده. هشدار: درصورتی که عناوین فاقد دسته‌بندی وجود داشته باشد، بایستی قبل از غیر فعال کردن این قابلیت آن‌ها را دسته‌بندی کنید." - uncategorized_description: "شرح دسته بندی های دسته بندی نشده. خالی بگذارید برای بدون شرح. " allow_duplicate_topic_titles: "جستارها را با عناوین یکسان و تکراری اجازه بده " unique_posts_mins: "چند دقیقه قبل از اینکه کاربر بتواند دوباره نوشته ای با محتویات یکسان را بگذارد." educate_until_posts: "وقتی کاربر شروع کرد به نوشتن اولین (n) پست جدید٬ آموزش ها را برای کاربران جدید بصورت بالاپر در قسمت نویسنده نشان بدهو" @@ -646,7 +633,6 @@ fa_IR: download_remote_images_to_local: "تبدیل عکس های سیار به عکس های محلی با دانلود کردن آنها; این مانع از شکستن عکس ها می شود." download_remote_images_threshold: "حداقل فضای دیسک مورد نیاز برای دانلود عکس های سیار محلی (در درصد)" disabled_image_download_domains: "عکس های سیار هرگز دانلود نخواهند شد از این دامنه ها. لیست Pipe-delimited" - ninja_edit_window: "برای (n) ثانیه بعد از نوشتن ویرایش کردن٬ نسخه جدیدی در سابقه نوشته نمی سازد." post_edit_time_limit: " نویسنده می تواند نوشته را ویرایش یا حذف کند بعد از (n) ساعت پست کردن آن. تنظیم به 0 برای همیشه." edit_history_visible_to_public: "به همه اجازه بده تا نسخه قبلی نوشته ویرایش شده را ببینند. وقتی غیر فعال است٬ فقی اعضل می توانند ببینند." delete_removed_posts_after: "نوشته های حذف شده توسط نویسنده بطور خودکار پاک می شوند بعد از (n) ساعت. اگر به 0 تنظیم شود همان موقع پاک خواهند شد. " @@ -671,7 +657,6 @@ fa_IR: summary_likes_required: "حداقل پسندها در این جستار قبل از اینکه \" خلاصه این جستار\" فعال شود" summary_percent_filter: "وقتی کاربر بر روی ' خلاصه این جستار ' کلیک کرد٬‌ % بهترین نوشته ها را نشان بده" summary_max_results: "حداکثر نوشته های برگردانده شد با \" خلاصه این جستار\"" - enable_private_messages: "به کاربران سطح اعتماد 1 برای ساختن پیام ها و ارسال پاسخ با پیام ها اجازه بده" enable_long_polling: "پیام اتوبوس استفاده شده برای آگاه سازی می تواند برای رای گیری طولانی استفاده شود. " long_polling_base_url: " URL پایه استفاده شده برای رای گیری طولانی ( وقتی CDN خدمت محتوای پویا می دهد٬ مطمئن شوید از تنظیم بودن منشا این کشش) برای نمونه : http://origin.site.com" long_polling_interval: "مدت زمانی که سرور باید صبر کند قبل پاسخ دادن به مشتری ها وقتی در آنجا داده ای برای ارسال نیست ( فقط کاربران وارد شده )" @@ -711,7 +696,6 @@ fa_IR: suppress_reply_directly_above: "in-reply-to قابل بزرگ شدن را نشان نده در یک نوشته وقتی فقط یک پاسخ بالای این نوشته است." suppress_reply_when_quoting: "in-reply-to قابل بزرگ شدن را نشان نده در یک نوشته وقتی به یک نوشته پاسخ داده می شود." max_reply_history: "حداکثر تعداد پاسخ ها به توسعه زمان گسترش in-reply-to" - experimental_reply_expansion: "پاسخ های میانی را مخفی کن زمان توسعه یک پاسخ به (آزمایشی) " topics_per_period_in_top_summary: "تعداد بهتریت جستارهای نشان داده شده در بخش پیش فرض خلاصه بهترین جستارها." topics_per_period_in_top_page: "تعداد جستارهای خوب نشان داده شود در بخش گسترش یافته \" بیشتر نشان بده\" بهترین جستارها. " redirect_users_to_top_page: "بطور خودکار کاربران جدید و کاربران غایب را به بهترین صفحه هدایت کن." @@ -805,16 +789,9 @@ fa_IR: tl2_requires_likes_received: "کاربر چندین پسند باید دریافت کند قبل از اینکه به سطح اعتماد 2 برسد." tl2_requires_likes_given: "کاربر چندین لایک باید بزند تا بتواند به سطح اعتماد 2 برسد. " tl2_requires_topic_reply_count: "کاربرچندین پاسخ باید بدهد قبل از اینکه به سطح اعتماد 2 برسد." - tl3_requires_days_visited: "حداقل روزهایی که روز که کاربر نیاز با بازدید از سایت دارد در 100 روز گذشته تا بتواند به سطح اعتماد 3 برسد. (0 to 100)" - tl3_requires_topics_replied_to: "حداقل تعداد جستارهایی که کاربر نیاز به پاسخ دارد در 100 روز گذشته تا بتواند سطح اعتماد 3 را بدست آورد. (0 to 100)" - tl3_requires_topics_viewed: "درصد جستارهای ساخته شده در 100 روز گذشته که کاربر نیاز به دیده شدن دارد برای ارتقا به سطح اعتماد 3. (0 to 100)" - tl3_requires_posts_read: "درصد نوشته های ساخته شده در 100 روز گذشته که کاربر نیاز به دیده شدن دارد برای ارتقا به سطح اعتماد 3. (0 to 100)" tl3_requires_topics_viewed_all_time: "حداقل تعداد جستار ها که کاربر نیاز به بازدید دارد تا بتواند به سطح اعتماد 3 برسد." tl3_requires_posts_read_all_time: "حداقل تعداد نوشته ها که کاربر نیاز به خواندن دارد تا بتواند به سطح اعتماد 3 برسد." - tl3_requires_max_flagged: "کاربر نباید بیشتر از X نوشته های پرچم گزاری شده توسط X کاربران متفاوت در 100 روز گذشته داشته باشد برای ارتقا به سطح اعتماد 3 ٬ که در آن X مقدار این تنظیمات است. (0 یا بیشتر)" tl3_promotion_min_duration: "حداقل تعداد روزهایی که ارتقا به سطح اعتماد 3 باقی می ماند قبل از اینکه کاربر تنزل پیدا کنه به سطح اعتماد 2. " - tl3_requires_likes_given: "حداقل تعداد پسندهای که باید داده شود در 100 روز گذشته تا بتواند به سطح اعتماد 3 ارتقا پیدا کند." - tl3_requires_likes_received: "حداقل تعداد پسندهایی که باید دریافت شود در 100 روز گذشته تا به سطح اعتماد 3 ارتقا پیدا کند. " tl3_links_no_follow: "rel=nofollow را از پیوند های پست شده توسط کاربران با سطح اعتماد 3 حذف نکن. " min_trust_to_create_topic: "حداقل سطح اعتمادی که برای ساخت جستار جدید مورد نیاز است. " min_trust_to_edit_wiki_post: "حداقل سطح اعتمادی برای ویرایش نوشته ای که بعنوان ویکی نشانه گزاری شده است. " @@ -895,7 +872,6 @@ fa_IR: automatically_download_gravatars: "آواتار را برای کاربران دریافت کن برای ساختن حساب کاربری یا ایمیل. " digest_topics: "حداکثر تعداد جستارهایی که در دایجست ایمیل نشان داده می شود " digest_min_excerpt_length: "حداقل نوشته های گزیده در ایمیل دایجست٬‌ در کاراکتر." - suppress_digest_email_after_days: "ایمیل های خلاصه را مهار کن برای کاربرانی که در وب سایت دیده نشده اند بیشتر از (n) روز " disable_digest_emails: "ایمیل های دایجست را برای تمام کاربران غیر فعال کن. " max_daily_gravatar_crawls: "حداکثرتعداد زمانی که دیسکورس Gravatar را چک می کند برای آواتار سفارشی در هر روز. " public_user_custom_fields: "لیست مجاز فیلد سفارشی برای کاربر که می تواند به همه نشان داده شود." @@ -905,7 +881,6 @@ fa_IR: anonymous_posting_min_trust_level: "حداقل سطح اعتماد برای فعال سازی نوشته گذاشتن در حالت ناشناس" anonymous_account_duration_minutes: "برای محافظت از ناشناس ماندن یک حساب کاربری نانشناس بساز هر N دقیقه. برای مثال: اگر به 600 تنظیم شد٬‌ به محض اینکه 600 دقیقه از نوشته گذشت و کاربر سوئیچ شد به چند لحظه بعد٬‌ حساب کاربری جدید ناشناس ساخته می شود. " allow_profile_backgrounds: "به کاربر اجازه بده تا پس زمینه نمایه خود را آپلود کنند." - sequential_replies_threshold: "تعداد پست هایی که کاربر باید بسازد در یک ردیف در یک جستار قبل از یاآوری درباره پاسخ های پی در پی. " enable_mobile_theme: "دستگاه های موبایلی که از تم دوستانه موبایل استفاده می کنن٬‌ با قابلیت جابجایی به حالت تمام سایت. این را از کار بیانداز اگر می خواهی از شیوه سفارشی استفاده کنی که بطور کامل پاسخگو است." dominating_topic_minimum_percent: " پست های یک کاربر چند درصد باید درست کنند در یک جستار قبل از اینکه یادآوری بشن درباره بیش از اندازه بودن آن در یک جستار. " daily_performance_report: "تحلیل لاگ‌های NGINX و ارسال یک پست شامل جزئیات ویژه مدیران" @@ -934,13 +909,11 @@ fa_IR: enable_cdn_js_debugging: "اجازه بده / logs به نمایش خطاهای مناسب با اضافه کردن مجوز crossorigin به همه آنها دارای js ." show_create_topics_notice: "اگر سایت کمتر از 5 جستار عمومی دارد٬ اطلاع بده به مدیران تا جستارهای بیشتری بسازند." delete_drafts_older_than_n_days: پیش‌نویس‌های قدیمی‌تر از (n) روز را حذف کن - vacuum_db_days: " VACUUM FULL ANALYZE را اجرا کن برای پس گرفتن فضای DB بعد از مهاجرت کردن ( 0 برای غیر فعال کردن)" prevent_anons_from_downloading_files: "جلوگیری از دانلود کردن فایل پیوست توسط افراد ناشناس. اخطار: این جلوگیری می کنه از هر سایت دارای بدون عکسی. " slug_generation_method: "Choose a slug generation method. 'encoded' will generate percent encoding string. 'none' will disable slug at all." enable_emoji: "فعالسازی ایموجی" emoji_set: "می‌خواهید ایموجی شما چطور باشد؟" enforce_square_emoji: "تحمیل نسبت ابعاد مربع به تمام شکلک ها emojis . " - approve_post_count: "تعداد پست ها برای کاربران جدید باید تایید شود" approve_unless_trust_level: "نوشته ها برای کاربران پایین ت از این سطح اعتماد نیاز به تایید دارد. " errors: invalid_email: "آدرس ایمیل نامعتبر" @@ -966,7 +939,6 @@ fa_IR: moved_post: "%{display_username} نوشته شما منتقل شد به %{link}" private_message: "%{display_username} یک پیام ارسال کنید: %{link}" invited_to_private_message: "%{display_username} شما را به این پیام دعوت کرده : %{link}" - invited_to_topic: "%{display_username} شما را به این جستار دعوت کرده: %{link}" invitee_accepted: " %{display_username} دعوت نامه شما را پذیرفته شد " linked: "%{display_username} شما پیوند خوردید در %{link}" granted_badge: "شما وارد شدید %{link}" @@ -976,11 +948,6 @@ fa_IR: category: 'دسته‌ها' topic: 'درخواست ها' user: 'کاربران' - sso: - not_found: "نمی توانی مراجعه کنی یا حساب کاربری بسازی٬ با مدیر سایت تماس بگیر " - account_not_approved: "حساب کاربری در انتظار تایید است٬ شما ایمیلی دریافت خواهید کرد زمانی که تایید شد" - unknown_error: "ایراد به روز رسانی اطلاعات٬ با مدیر سایت تماس بگیرید" - timeout_expired: "ورود حساب کاربری از زمان خارج شد است. لطفا دوباره وارد سیستم شوید" original_poster: "نویسنده اصلی" most_posts: "بیشترین نوشته ها" most_recent_poster: "جدیدترین نویسنده ها" @@ -1055,6 +1022,9 @@ fa_IR: ip_address: blocked: "ثبت‌نام‌های جدید از آدرس IP شما ممنوع شده است." max_new_accounts_per_registration_ip: "ثبت‌نام‌های جدید از آدرس IP شما ممنوع شده است (به حداکثر تعداد مجاز رسیده است). با یکی از مدیران تماس بگیرید." + flags_reminder: + subject_template: + other: "%{count} نشانه ها منتظر استفاده" invite_mailer: subject_template: "%{invitee_name} شما را دعوت کرده به %{topic_title}' در %{site_domain_name}" text_body_template: "%{invitee_name} شما را دعوت کرده به یک گفتگو\n\n> **%{topic_title}**\n>\n> %{topic_excerpt}\n\nدر \n\n> %{site_title} -- %{site_description}\n\nاگر علاقه مند هستید بر روی پیوند پایین کلیک کنید:‌\n\n%{invite_link}\n\nاین دعوتنامه از طرف یک کاربر قابل اعتماد است٬ پس شما نیازی به ورود ندارید. \n" @@ -1065,68 +1035,10 @@ fa_IR: subject_template: "تنظیم رمز عبور برای حساب کاربری {site_name}%" test_mailer: subject_template: "[%{site_name}] ایمیل تست دهش" - text_body_template: | - This is a test email from - - [**%{base_url}**][0] - - Email deliverability is complicated. Here are a few important things you should check first: - - - Be *sure* to set the `notification email` from: address correctly in your site settings. **The domain specified in the "from" address of the emails you send is the domain your email will be validated against**. - - - Know how to view the raw source of the email in your mail client, so you can examine email headers for important clues. in Gmail, it is the "show original" option in the drop-down menu at the top right of each mail. - - - **IMPORTANT:** Does your ISP have a reverse DNS record entered to associate the domain names and IP addresses you send mail from? [Test your Reverse PTR record][2] here. If your ISP does not enter the proper reverse DNS pointer record, it's very unlikely any of your email will be delivered. - - - Is your domain's [SPF record][8] correct? [Test your SPF record][1] here. Note that TXT is the correct official record type for SPF. - - - Is your domain's [DKIM record][3] correct? This will significantly improve email deliverability. [Test your DKIM record][7] here. - - - If you run your own mail server, check to make sure the IPs of your mail server are [not on any email blacklists][4]. Also verify that it is definitely sending a fully-qualified hostname that resolves in DNS in its HELO message. If not, this will cause your email to be rejected by many mail services. - - (The *easy* way is to create a free account on [Mandrill][md] or [Mailgun][mg] or [Mailjet][mj], which have free generous free mailing plans and will be fine for small communities. You'll still need to set up the SPF and DKIM records in your DNS, though!) - - We hope you received this email deliverability test OK! - - Good luck, - - Your friends at [Discourse](http://www.discourse.org) - - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: https://www.mailjet.com/pricing new_version_mailer: subject_template: "[%{site_name}] نسخه جدید Discourse برای به روز رسانی موجود است" - text_body_template: | - نسخه‌ جدیدی از [دیسکورس](http://www.discourse.org) موجود است. - - نسخه کنونی: %{installed_version} - نسخه جدید: **%{new_version}** - - شما می‌توانید: - - - تغییرات جدید را در [GitHub changelog](https://github.com/discourse/discourse/commits/master) ببینید. - - - از طریق مروگر خود به‌روزرسانی را انجام دهید [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - از [meta.discourse.org](http://meta.discourse.org) برای دسترسی به اخبار و پشتیبانی دیسکورس استفاده کنید. new_version_mailer_with_notes: subject_template: "[%{site_name}] بروزرسانی در دسترس" - flags_reminder: - flags_were_submitted: - other: "این پرچم گزاری ها در %{count} ساعت پیش ارسال شده است." - please_review: "لطفا بازبینی کن." - post_number: "نوشته" - how_to_disable: 'شما می توانید تکرار یاد توسط این ایمیل را عوض کنید یا از کار بیندازید از طریق اعلام کردت بعد ازتنظیم پرچم گزاری .' - subject_template: - other: "%{count} نشانه ها منتظر استفاده" queued_posts_reminder: subject_template: other: "[%{site_name}] %{count} نوشته منتظر بررسی است" @@ -1207,12 +1119,8 @@ fa_IR: csv_export_failed: subject_template: "خارج کردن فایل ها ناموفق شد" text_body_template: "ما متاسفیم٬ ولی خارج کردن اطلاعات ناموفق شد. لطفا سیستم را چک کنید یا با یکی از مدیران تماس بگیرید. " - email_reject_trust_level: - subject_template: "[%{site_name}] مشکل ایمیل -- سطح اعتماد کافی نیست" - text_body_template: "ما متاسفیم٬ ولی پیام شما در ایمیل به %{destination} (titled %{former_title}) کار نکرد. \n\nحساب کاربری شما دارای سطح اعتماد کافی برای ارسال نوشته جدید به این ایمیل نیست. اگر این مشکل را قبول دارید٬ با یکی از مدیران تماس بگیرید.\n" email_reject_no_account: subject_template: "[%{site_name}] مشکل ایمیل -- حساب کاربری ناشناس " - text_body_template: "ما متاسفیم٬ ولی پیام شما در ایمیل به %{destination} (titled %{former_title}) کار نکرد. \n\n\nحساب کاربری با این ایمیل شناخته نمی شود. دوباره برای ارسال تلاش کنید با ایمیل دیگری٬ یا با یکی از مدیران تماس بگیرید.\n" email_reject_empty: subject_template: "[%{site_name}] مشکل ایمیل -- بدون محتوا" email_reject_parsing: @@ -1220,22 +1128,8 @@ fa_IR: email_reject_invalid_access: subject_template: "[%{site_name}] مشکل ایمیل -- دسترسی نامعتبر " text_body_template: "ما متاسفیم٬ ولی پیام شما در ایمیل به %{destination} (titled %{former_title}) کار نکرد. \n\nحساب کاربری شما دارای سطح اعتماد کافی برای ارسال نوشته جدید به این ایمیل نیست. اگر این مشکل را قبول دارید٬ با یکی از مدیران تماس بگیرید.\n" - email_reject_post_error: - subject_template: "[%{site_name}] مشکل ایمیل -- ایراد ارسال" - text_body_template: "ما متاسفیم٫ ولی پیام ایمیل شما به %{destination} (titled %{former_title}) کار نکرد. \n\nبعضی ایراد های ممکن : قالب های پیچیده٬ پیغام بسیار بزرگ٬ پیغام بسیار کوچک. لطفا دوباره تلاش کنید٬ یا با وب سایت ارسال کنید اگر این ادامه داشت. \n" - email_reject_post_error_specified: - subject_template: "[%{site_name}] مشکل ایمیل -- ایراد ارسال" - text_body_template: "ما متاسفیم٬ ولی پیام ایمیل شما به %{destination} (titled %{former_title}) کار نکرد.\n\nدلیل: \n\n%{post_error}\n\nاگر می توانید مشکل را حل کنید٬ لطفا دوباره تلاش کنیدو\n\n\n" email_reject_reply_key: subject_template: "[%{site_name}] مشکل ایمیل -- کلید پاسخ ناشناس" - text_body_template: |+ - ما متاسفیم٬ ولی پیام ایمیل شما به %{destination} (titled %{former_title}) کار نکرد. - - کلید پاسخ وارد شده خراب یا ناشناس است٬ پس ما نمی دانیم این ایمیل در پاسخ چی هست. با یکی از مدیران تماس بگیرید. - - email_reject_destination: - subject_template: "[%{site_name}] مشکل ایمیل -- به ناشناس: آدرس" - text_body_template: "ما متاسفیم٬ ولی پیام شما در ایمیل به %{destination} (titled %{former_title}) کار نکرد. \n\n\nهیچ کدام این آدرس ها قابل شناسایی نیستند. مطمئن شو که آدرس سایت در : خط (نیست Cc: or Bcc:)٬ و شما به آدرس ایمیل صحیحی می فرستید که توسط مدیران ارائه شده.\n" email_reject_topic_not_found: subject_template: "[%{site_name}] مشکل ایمیل -- جستار یافت نشد" email_reject_topic_closed: @@ -1244,28 +1138,15 @@ fa_IR: subject_template: "[%{site_name}] مشکل ایمیل -- پاسخ خودکار" email_error_notification: subject_template: "[%{site_name}] مشکل ایمیل -- ایراد تصدیق POP " - text_body_template: "ایراد تصدیقی وجود داشته همزمان با گرفتن ایمیل ها از سرور POP. \n\n\nلطفا اطمینان حاصل کنید از اینکه بطور درست تنظیم اعتبارنامه POP را در [تنظیمات وب سایت] انجام داده اید. (%{base_url}/ریس/تنظیمات _ سایت /دسته/ایمیل)\n" too_many_spam_flags: subject_template: "حساب جدید کاربری انسداد شد " text_body_template: "سلام \n\nاین یک پیغام خوکار است از %{site_name} برای تایید اینکه نوشته های شما بطور خودکار مخفی شده اند زیرا آنها توسط انجمن پرچم گزاری شده اند. \n\n\nبه عنوان یک اقدام احتیاطی٬ حساب کاربری جدید شما مسدود شده است از ساختن پاسخ های جدید یا جستارهای جدید تا قبل از اینکه یک مدیران حساب کاربری شما را بررسی کند.\n\n\nبرای راهنمایی بیشتر به[ دستور عمل های انجمن] مراجعه کنید. (%{base_url}/guidelines).\n" blocked_by_staff: subject_template: "حساب کاربری مسدود شد" - text_body_template: "سلام٬ \n\n\nاین یک پیام خودکار است از طرف %{site_name} برای اطلاع در جهت اینکه حساب کاربری شما توسط یکی از مدیران مدیران مسدود شده است.\n\nبرای راهنمایی بیشتر٬ لطفا مراجعه کنید به [دستورالعمل انجمن](%{base_url}/guidelines).\n" user_automatically_blocked: subject_template: "کاربر جدید%{username} مسدود شد بخاطر پرچم های انجمن" - text_body_template: "این یک پیام خودکار است. \n\n\nکاربر جدید [%{username}](%{base_url}%{user_url}) بطور خودکار مسدود شد زیرا چند کاربر متفاوت %{username}'s این نوشته(ها) را پرچم گزاری کرده اند.\n\n\nلطفا [پرچم ها را بررسی کن](%{base_url}/admin/flags). اگر %{username} به اشتباه مسدود شده بود لطفا به روی کلید رفع مسدود کلیک کنید[مدیرصفحه برای این کاربر](%{base_url}%{user_url}). \n\n\nاین آستانه می تواند تغییر کند از طریق `block_new_user` تنظیمات سایت.\n" spam_post_blocked: subject_template: "کاربر جدید%{username} نوشته مسدود شده است بدلیل پیوند های تکراری" - text_body_template: | - این یک پیام خودکار است. - - کاربرجدید [%{username}](%{base_url}%{user_url}) تلاش کرد برای ساخت چند نوشته با پیوندهایی به %{domains}, ولی آن نوشته ها مسدود شده اند برای جلوگیری از هرزنامه. کاربر هنوز قادر به ساخت نوشته های جدید است که به پیوندی به این %{domains} ندارد. - - - لطفا [کاربر را بررسی کنید](%{base_url}%{user_url}). - - - این می تواند تغییر کند با `newuser_spam_host_threshold` و `white_listed_spam_host_domains` site settings. unblocked: subject_template: "حساب کاربری رفع انسداد شد " text_body_template: "سلام \n\nاین یک پیام خودکار هست از طرف %{site_name} برای تایید باز شدن حساب کاربری شما بعد از بررسی مدیران. \n\n\nشما می توانید دوباره پاسخ ها و جستارهای جدید را بوجود بیاورید.\n" @@ -1286,60 +1167,19 @@ fa_IR: unsubscribe: title: "لغو اشتراک" description: "آیا تمایلی به دریافت این ایمیل‌ها ندارید؟ مشکلی نیست! اینجا را کلیک کنید تا اشتراک آن هم‌اکنون حذف شود." - reply_by_email: "برای پاسخگویی، به این ایمیل جواب بده یا بازدید کنید از {base_url}%{url}% در مرورگر خود." - visit_link_to_respond: "برای پاسخگویی، لینک {base_url}%{url}% را در مرورگر خود مشاهده کنید." posted_by: "نوشته شده توسط {username}% در تاریخ {post_date}%" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} شما را به یک پیام دعوت کرده است: '%{topic_title}'" - text_body_template: "\n%{username} شما را به یک پیام دعوت کرده\n\n\n> **%{topic_title}**\n\n>\n\n> %{topic_excerpt}\n\n\nat \n\n\n> %{site_title} -- %{site_description}\n\n\nلطفا از این پیوند بازدید کنید تا پیام را ببینید: %{base_url}%{url}\n" - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} شما را به یک جستار دعوت کرده '%{topic_title}'" - text_body_template: "\n%{username} به گفتگو دعوت شده است\n\n\n> **%{topic_title}**\n\n>\n\n> %{topic_excerpt}\n\nat \n\n\n> %{site_title} -- %{site_description}\n\n\nلطفا از این پیوند بازدید کنید تا پیام را ببینید: %{base_url}%{url}\n" user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - {message}% - - {context}% - - --- - {respond_instructions}% user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "یک گزارش کوتاه از %{site_link} از آخرین باری که بازدید کردید در %{last_seen_at}" subject_template: "[%{site_name}] خلاصه" @@ -1373,9 +1213,6 @@ fa_IR: account_created: subject_template: "[%{site_name}] حساب کاربری جدید شما" text_body_template: "حساب کاربری جدید برای شما ساخته شد در %{site_name}\n\nبر روری پیوند پیش رو کلیک کنید برای انتخاب رمز برای حساب کاربری جدیدتان: \n\n%{base_url}/users/password-reset/%{email_token}\n" - authorize_email: - subject_template: "آدرس ایمیل جدید را تایید کنید برای [%{site_name}]" - text_body_template: "آدرس ایمیل جدید را تایید کنید برای %{site_name} با کلیک کردن بر پیوند پیش رو : \n\n\n%{base_url}/users/authorize-email/%{email_token}\n" signup_after_approval: subject_template: "شما تایید شدید %{site_name}! " text_body_template: "خوش آمدید به %{site_name}!\n\nیکی از مدیران حساب کاربری شما را تایید کرد در %{site_name}.\n\nبر روی پیوند پیش رو کلیک کنید تا حساب کاربری شما تایید شود: \n%{base_url}/users/activate-account/%{email_token}\n\nاگر پیوند بالا قابل کلیک کردن نیست٬ پیوند را کپی کنید و در مرور گر وب انتقال دهید. \n\n%{new_user_tips}\n\n\nما به [رفتار انجمن متمدن] معتقدیم (%{base_url}/guidelines) برای همیشه. \n\nاز بودنتان در اینجا لذت ببرید! \n\n( اگر شما نیاز به ارتباط با مدیران را دارید[staff members](%{base_url}/about) به عنوان یک کاربر جدید٬ لطفا به این پیام پاسخ دهید.)\n" @@ -1383,7 +1220,6 @@ fa_IR: subject_template: "[%{site_name}] حساب کاربری جدید را تایید کنید" text_body_template: "خوش آمدید به %{site_name}!\n\n\nبرای فعال نمودن حساب کاربریتان بر روی پیوند پیش رو کلیک کنید: \n\n%{base_url}/users/activate-account/%{email_token}\n\n\nاگر پیوند بالا قابل کلیک کردن نیست٬ پیوند را کپی کنید و در مرور گر وب انتقال دهید. \n" page_not_found: - title: "صفحه ای که درخواست کردید وجود ندارد یا خصوصی است. " popular_topics: "محبوب" recent_topics: "اخیر" see_more: "بیشتر" @@ -1436,6 +1272,7 @@ fa_IR: نوشته اول این جستار را ویرایش کن برای عوض کردن محتویا ت%{page_name} صفحه. guidelines_topic: title: "پرسش و پاسخ / دستورالعمل" + body: "اینجا مکانی متمدن برای بحث جمعی است.\nلطفا برای این فروم بحث همان احترامی را قائل باشید که برای یک پارک عمومی هستید. ما، هم، یک منبع جمعی مشترک هستیم – جایی که مهارت ها، دانش و علایق در اثر بحث های در جریان به اشتراک گذاشته می شود.\nاز راهنمای زیر برای تمیز نگه داشتن این مکان به صورت یک مجلس متمدن بحث بهره ببرید. این راهنما قوانین سفت و سختی ندارد، بلکه صرفا به قضاوت افراد از جامعه ی ما کمک میکند. \nبحث را بهبود ببخشید\nبا بهبود بحث ها، حتی اگر بهبود کوچکی باشد، به ما کمک کنید تا اینجا را همیشه یک مکان مناسب برای بحث نگه داریم. اگر مطمئن نیستید که پست های شما به بحث چیزی اضافه میکند، به چیزی که میخواهید فکر کنید و بعدتر دوباره تلاش کنید.\nموضوعات بحث شده در اینجا برای ما مهم است، و میخواهیم شما هم طوری رفتار کنید که گویی آن ها برای شما هم مهم هستند. نسبت به موضوعات مطرح شده و مردمی که راجع به آن بحث میکنند احترام قائل باشید، حتی اگر با بعضی چیزهایی که گفته می شود موافق نیستید.\nیک راه بهبود بحث ها، با کشف بحث هایی است که پیش تر اتفاق افتاده. لطفا پیش از اینکه پاسخ خودتان را بیان کنید، زمانی برای مرور عناوینی که اینجاست سپری کنید؛ در این صورت احتمال اینکه افراد دیگری با علایق مشترک با شما بیابید بیشتر میشود. \nحتی وقتی موافق نیستید، نیز دلپذیر باشید\nممکن است بخواهید با بعضی بحث های مطرح شده مخالفت کنید. این خوب است. فقط حواستان باشد که ایده ها را نقد کنید و نه افراد را. لطفا از موارد زیر دوری کنید:\n-\tنام بردن\n-\tحمله به شخصیت و یا انگیزه ی افراد\n-\tواکنش به نحوه ی بیان پست به جای محتوای آن\n-\tواکنش های سریع و متناقض \nبه جای این ها، استدلال های مخالفی که بحث را بهبود می بخشند فراهم کنید.\nمشارکت شما به حساب می آید\nبحث هایی که ما اینجا داریم برای همه خواهد ماند. با تعامل در بحث هایی که این فروم را به مکان جالب تری برای حضور میکند و دوری از بحث هایی که این چنین نمی کند، به ما کمک کنید در آینده ی این جمع تاثیرگذار باشیم. \nدیسکورس ابزاری در دسترس می گذارد که به جمع این امکان را میدهد که بهترین (و بدترین) مشارکتها را تشخیص دهند: علاقه مندی ها، نشانک ها، لایک ها، پرچم ها، پاسخ ها، ویرایش ها، و ... . از این ابزارها برای بهبود تجربه ی خودتان و همین طور دیگران بهره ببرید.\nبیاید تلاش کنیم پارک را نسبت به آن چه از ابتدا یافته ایم، بهبود ببخشیم.\nاگر مشکلی دیدید، آن را پرچم گذاری کنید.\nتعدیل کننده ها امتیازهای مشخصی دارند؛ آن ها مسئول این فروم هستند. و البته شما هم هستید. با کمک شما، تعدیل کننده ها میتوانند تسهیل گر باشند و نه فقط فراش یا پلیس.\nوقتی رفتار نامناسبی میبینید، پاسخ ندهید. این کار رفتار بد را تشویق میکند، انرژی شما را مصرف میکند، و زمان دیگران را خرج میکند. تنها کافی است آن را پرچم گذاری کنید. با تعلق گرفتن پرچم های کافی، اقدام مناسب انجام می شود، یا خود به خود و یا با دخالت تعدیل کننده ها.\nبرای حفظ جامعه یمان، تعدیل کننده ها این حق را دارند که محتوای هر کاربری و یا هر کاربری را به هر دلیلی در هر زمانی حذف کنند. تعدیل کننده ها، پست های جدید را پیش نمایش نمیکنند؛ و تعدیل کننده ها و مجریان سایت مسئول هیچ کدام از پست های جمع نیستند.\nهمیشه متمدن باشید\nهیچ چیزی یک بحث سالم را مانند بی ادبی خراب نمیکند:\n-\tمتمدن باشید. مطالبی که یک فرد معقول توهین آمیز، سواستفاده، و یا بیان نفرت در نظر میگیرد پست نکنید.\n-\tاینجا را تمیز نگه دارید. مطالب مستهجن و یا مطالب جنسی صریح پست نکنید.\n-\tبه همدیگر احترام بگذارید. باعث آزار یا اندوه دیگران نشوید، خود را به جای دیگران جا نزنید، و یا اطلاعات خصوصی دیگران را در معرض قرار ندهید.\n-\tبه فروم ما احترام بگذارید. اسپم پست نکنید و یا فروم را به تباهی نکشید.\nاین شرایط تعریف دقیق ندارند – از چیزهایی که حتی نمود این موارد هست نیز دوری کنید. اگر مطمئن نیستید، از خودتان بپرسید چه حسی به شما دست میداد اگر پستتان در صفحه ی اول نشریه نیویورک تایمز چاپ شود.\nاینجا یک فروم عمومی است، و موتورهای جستجو بحث های موجود را نشان میدهند. زبان، لینک ها، و تصاویر را برای دوستان و خانواده امن نگه دارید. \nاینجا را تمیز نگه دارید\nتلاش کنید تا چیزها را در جای مناسب خود قرار دهید، تا ما بتوانیم زمان بیشتری را به بحث و زمان کمتری را به تمیزکاری بپردازیم:\n-\tیک موضوع را در دسته بندی نادرست مطرح نکنید.\n-\tیک موضوع را در عناوین مختلف پست نکنید.\n-\tپاسخ های بدون محتوا پست نکنید.\n-\tیک موضوع را با ویرایش آن در حین بحث منحرف نکنید.\n-\tپست های خودتون رو امضا نکنید – هر پستی اطلاعات شما را با خود به همراه دارد.\nبه جای پست کردن «+1» یا «موافقم»، از دکمه ی لایک استفاده کنید. به جای اینکه یک موضوع موجود را به عنوان موضوع جدید مطرح کنید، از گزینه ی «پاسخ به صورت موضوع لینک شده» استفاده کنید. \nتنها مطالب خودتان را پست کنید\nمطالب دیگران را بدون اجازه مطرح نکنید. توصیف، لینک، و یا ابزاری برای دزدی دارایی های معنوی دیگران (نرم افزارها، ویدیوها، فایل صوتی، تصویر) و یا شکستن قوانین دیگر؛ را مطرح نکنید.\nقدرت گرفته از شما\nاین سایت توسط مدیران ما و شما، جمع حرکت میکند. اگر هر سوال دیگری درباره ی نحوه ی عملکرد چیزهای اینجا دارید، یک بحث جدید در دسته بندی فیدبک های سایت شروع کنید و بگذارید تا بحث صورت بگیرد. اگر یک موضوع بحرانی و یا مسئله ی فوری هست که نمیتواند در یک موضوع فیدبک و یا با پرچم مطرح شود، از طریق صفحه ی اعضا با ما تماس بگیرید. \nشرایط سرویس\nبله، قوانین خسته کننده هستند، ولی ما باید از خودمان در برابر گروه های غیردوستانه محافظت کنیم – و همین طور از شما و اطلاعات شما. در شرایط استفاده از سرویسمان که رفتار شما ( و ما) را توصیف میکند و حقوق مربوط به محتوا، حریم خصوصی، و قوانین را توضیح داده ایم. برای استفاده از این سرویس، لازم است شما با رعایت شرایط استفاده از سرویس ما موافقت کرده باشید. \n" tos_topic: title: "شرایط استفاده از خدمات" privacy_topic: @@ -1450,3 +1287,10 @@ fa_IR: performance_report: initial_post_raw: این مطلب شامل گزارش عملکرد روزانه سایت شماست. initial_topic_title: گزارش عملکرد وب‌سایت + date: + <<: *datetime_formats + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml index 8dd89d08fee..275495e01de 100644 --- a/config/locales/server.fi.yml +++ b/config/locales/server.fi.yml @@ -10,18 +10,41 @@ fi: short_date_no_year: "D. MMM" short_date: "D. MMMM[ta] YYYY" long_date: "D. MMMM[ta] YYYY, H:mm" + datetime_formats: &datetime_formats + formats: + short: "%-d.%-m.%Y" + short_no_year: "%-d. %B[ta]" + date_only: "%d. %B[ta] %Y" + date: + month_names: [null, Tammikuu, Helmikuu, Maaliskuu, Huhtikuu, Toukokuu, Kesäkuu, Heinäkuu, Elokuu, Syyskuu, Lokakuu, Marraskuu, Joulukuu] + <<: *datetime_formats title: "Discourse" topics: "Ketjut" posts: "viestit" loading: "Lataa" powered_by_html: 'Voimanlähteenä Discourse, toimii parhaiten, kun JavaScript on käytössä' - log_in: "Kirjaudu sisään" - via: "%{username} sivustolta %{site_name}" - is_reserved: "on varattu" + log_in: "Kirjaudu" purge_reason: "Poistettu automaattisesti hylättynä, aktivoimattomana tilinä" disable_remote_images_download_reason: "Linkattujen kuvien lataaminen poistettiin käytöstä vähäisen tallennustilan vuoksi." anonymous: "Anonyymejä" - errors: + emails: + incoming: + default_subject: "Uusi sähköposti osoitteesta %{email}" + show_trimmed_content: "Näytä piilotettu sisältö" + errors: + empty_email_error: "Näin käy, kun saapuneessa sähköpostissa ei lue mitään." + no_message_id_error: "Näin käy, kun viestin otsikkotiedoista puuttuu ID-tunniste (engl. message-ID)." + auto_generated_email_error: "Näin käy, kun viestin kiireellisyysluokitus (engl. precedence header) on joku seuraavista: list, junk, bulk tai auto_reply, tai kun joku muu otsikkotiedoista sisältää jonkun seuraavista: auto-submitted, auto-replied tai auto-generated." + no_body_detected_error: "Näin käy, kun leipätekstin poiminta epäonnistuu eikä liitteitä ole." + inactive_user_error: "Näin käy, kun lähettäjä ei ole aktiivinen." + blocked_user_error: "Näin käy, kun lähettäjä on estetty." + bad_destination_address: "Näin käy, kun viestin vastaanottaja/kopio/piilokopio -kenttien osoitteet eivät täsmää asetettuihin saapuvan sähköpostin osoitteiden kanssa." + strangers_not_allowed_error: "Näin käy, kun käyttäjä yrittää luoda ketjun alueelle, jonka jäsen ei ole." + insufficient_trust_level_error: "Näin käy, kun käyttäjä yrittää luoda ketjun alueelle, jonka vähimmäisluottamustasovaatimusta ei täytä." + reply_user_not_matching_error: "Näin käy, kun vastaus saapuu eri sähköpostiosoitteesta kuin mihin ilmoitus lähetettiin." + topic_not_found_error: "Näin käy, kun vastauksen saapuessa ketju, johon viesti oli tarkoitettu, on poistettu." + topic_closed_error: "Näin käy, kun vastauksen saapuessa ketju, johon viesti oli tarkoitettu, on suljettu." + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "on rajoitettu %{max} merkkiin; sinä syötit %{length} merkkiä." @@ -37,8 +60,10 @@ fi: exclusion: on varattu greater_than: täytyy olla suurempi kuin %{count} greater_than_or_equal_to: täytyy olla yhtä suuri, tai suurempi kuin %{count} + has_already_been_used: "on jo käytetty" inclusion: ei ole listalla invalid: ei kelpaa + is_invalid: "ei kelpaa; yritä olla kuvailevampi" less_than: täytyy olla vähemmän kuin %{count} less_than_or_equal_to: täytyy olla yhtä suuri, tai vähemmän kuin %{count} not_a_number: ei ole numero @@ -65,6 +90,13 @@ fi: other: '%{count} virhettä esti tallentamasta tätä %{model}' embed: load_from_remote: "Viestin lataamisessa tapahtui virhe." + site_settings: + min_username_length_exists: "Et voi asettaa käyttäjänimen minimipituutta lyhyemmäksi, kuin lyhyin käyttäjänimi" + min_username_length_range: "Et voi asettaa minimi korkeammaksi kuin maksimi" + max_username_length_exists: "Et voi asettaa käyttäjänimen enimmäispituutta alle pisimmän käyttäjänimen." + max_username_length_range: "Et voi asettaa maksimia minimin alle." + default_categories_already_selected: "Et voi valita aluetta, joka on käytössä toisella listalla" + s3_upload_bucket_is_required: "Et voi ottaa s3 latausta käyttöön, jos et ole määrittänyt 's3_upload_bucket'." bulk_invite: file_should_be_csv: "Ladattavan tiedoston pitäisi olla csv- tai txt-muodossa." backup: @@ -75,6 +107,8 @@ fi: not_found: "Pyydettyä osoitetta tai resurssia ei löytynyt." invalid_access: "Sinulla ei ole oikeutta nähdä pyydettyä resurssia." read_only_mode_enabled: "Sivusto on vain luku-tilassa. Vuorovaikutteiset toiminnot ovat poissa käytöstä." + reading_time: "Lukuaika" + likes: "Tykkäykset" too_many_replies: one: "Pahoittelut, uudet käyttäjät voivat kirjoittaa yhden vastauksen samaan ketjuun." other: "Pahoittelut, uudet käyttäjät voivat kirjoittaa %{count} vastausta samaan ketjuun." @@ -91,26 +125,26 @@ fi: replies: one: "1 kommentti" other: "%{count} kommenttia" + no_mentions_allowed: "Pahoittelut, et voi mainita muita käyttäjiä." too_many_mentions: - zero: "Pahoittelut, et voi viitata muihin käyttäjiin." - one: "Pahoittelut, voit viitata viestissä vain yhteen käyttäjään." - other: "Pahoittelut, voit viitata viestissä vain %{count} käyttäjään." + one: "Pahoittelut, voit mainita viestissä vain yhden käyttäjän." + other: "Pahoittelut, voit mainita viestissä vain %{count} käyttäjää." + no_mentions_allowed_newuser: "Pahoittelut, uusi käyttäjä ei voi mainita muita käyttäjiä." too_many_mentions_newuser: - zero: "Pahoittelut, uudet käyttäjät eivät voi viitata toisiin käyttäjiin." - one: "Pahoittleut, uudet käyttäjät voivat viitata vain yhteen käyttäjään viestissään." - other: "Pahoittelut, uudet käyttäjät voivat viitata viestissä vain %{count} käyttäjään." + one: "Pahoittelut, uusi käyttäjä voi mainita viestissä vain yhden käyttäjän." + other: "Pahoittelut, uusi käyttäjä voi mainita viestissä vain %{count} käyttäjää." + no_images_allowed: "Pahoittelut, uusi käyttäjä ei voi liittää kuvia viestiin." too_many_images: - zero: "Pahoittelut, uudet käyttäjät eivät voi ladata viesteihin kuvia." - one: "Pahoittelut, uudet käyttäjät voivat ladata viesteihinsä vain yhden kuvan." - other: "Pahoittelut, uudet käyttäjät voivat ladata viesteihinsä vain %{count} kuvaa." + one: "Pahoittelut, uusi käyttäjä voi liittää vain yhden kuvan viestiin." + other: "Pahoittelut, uusi käyttäjä voi liittää vain %{count} kuvaa viestiin." + no_attachments_allowed: "Pahoittelut, uusi käyttäjä ei voi liittää liitteitä viesteihin." too_many_attachments: - zero: "Pahoittelut, uudet käyttäjät eivät voi ladata viesteihin liitteitä." - one: "Pahoittelut, uudet käyttäjät voivat ladata viesteihinsä vain yhden liitteen." - other: "Pahoittelut, uudet käyttäjät voivat ladata viesteihinsä vain %{count} liitettä." + one: "Pahoittelut, uusi käyttäjä voi liittää vain yhden liitteen viestiin." + other: "Pahoittelut, uusi käyttäjä voi liittää vain %{count} liittettä viestiin." + no_links_allowed: "Pahoittelut, uusi käyttäjä ei voi laittaa linkkiä viestiin." too_many_links: - zero: "Pahoittelut, uudet käyttäjät eivät voi ladata viesteihin linkkejä." - one: "Pahoittelut, uudet käyttäjät voivat ladata viesteihinsä vain yhden linkin." - other: "Pahoittelut, uudet käyttäjät voivat ladata viesteihinsä vain %{count} linkkiä." + one: "Pahoittelut, uudet käyttäjät voivat laittaa vain yhden linkin viestiin." + other: "Pahoittelut, uusi käyttäjä voi laittaa vain %{count} linkkiä viestiin." spamming_host: "Pahoittelut, linkit tuolle sivulle eivät ole sallittuja." user_is_suspended: "Hyllytetyt käyttäjät eivät saa luoda viestejä." topic_not_found: "Jotain on mennyt pieleen. Ehkä tämä ketju on suljettu tai poistettu sillä välin, kun katselit sitä?" @@ -133,8 +167,13 @@ fi: rss_description: latest: "Tuoreimmat viestiketjut" hot: "Kuumat ketjut" + top: "Huippuketjut" posts: "Uusimmat viestit" + private_posts: "Uusimmat yksityisviestit" + group_posts: "Uusimmat viestit ryhmässä %{group_name}" + group_mentions: "Uusimmat maininnat ryhmässä %{group_name}" too_late_to_edit: "Tämä viesti luotiin liian kauan sitten. Sitä ei voi enää muokata tai poistaa." + revert_version_same: "Nykyinen revisio on sama, kuin jonka yrität palauttaa." excerpt_image: "kuva" queue: delete_reason: "Poistettu moderointijonon kautta" @@ -142,6 +181,10 @@ fi: errors: can_not_modify_automatic: "Et voi muokata automaattista ryhmää" member_already_exist: "'%{username}' on jo ryhmän jäsen." + invalid_domain: "'%{domain}' ei ole käypä verkkotunnus." + invalid_incoming_email: "'%{email}' ei ole käypä sähköpostiosoite." + email_already_used_in_group: "'%{email}' on jo käytössä ryhmällä '%{group_name}'." + email_already_used_in_category: "'%{email}' on jo käytössä alueella '%{category_name}'." default_names: everyone: "kaikki" admins: "ylläpitäjät" @@ -219,9 +262,6 @@ fi: user_profile: bio_raw: "Minusta" errors: - messages: - is_invalid: "ei kelpaa; yritä olla kuvailevampi" - has_already_been_used: "on jo käytössä" models: topic: attributes: @@ -242,6 +282,7 @@ fi: attributes: hex: invalid: "ei ole sallittu väri" + <<: *errors user_profile: no_info_me: "
    Minusta -kohta käyttäjäprofiilissasi on vielä täyttämättä,haluaisitko täyttää sen nyt?
    " no_info_other: "
    %{name} ei ole täyttänyt vielä mitään Minusta -kohtaan profiilissaan
    " @@ -277,13 +318,15 @@ fi: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Alueesta %{category}" - replace_paragraph: "[Korvaa tämä kappale lyhyellä kuvauksella uudesta alueesta. Tämä kuvaus näytetään alueen valinnan yhteydessä, joten yritä pitää se alle 200 merkin pituisenä. Tätä aluetta ei näytetä listauksissa ennen kuin olet muokannut tätä tekstiä tai luonut viestiketjuja.]" - post_template: "%{replace_paragraph}\n\nKäytä seuraavat kappaleet pidempään kuvaukseen ja selvittääksesi alueen säännöt ja ohjeet.\n\nJotain huomioitavia asioita alle muodostuvaa keskustelua ajatellen:\n\n- Mitä varten tämä alue on? Miksi ihmiset valitsisivat tämän alueen viestiketjulleen?\n\n- Kuinka se eroaa muista alueista?\n\n- Tarvitaanko tätä aluetta?\n\n- Pitäisikö alue yhdistää toisen alueen kanssa, tai jakaa useammaksi alueeksi?\n" + replace_paragraph: "(Korvaa tämä kappale lyhyellä kuvauksella uudesta alueesta. Tämä kuvaus näytetään alueen valinnan yhteydessä, joten yritä pitää se alle 200 merkin pituisenä. **Aluetta ei näytetä Keskustelualueet-sivulla ennen kuin olet muokannut tätä tekstiä tai luonut viestiketjuja.**)" + post_template: "%{replace_paragraph}\n\nKäytä seuraavat kappaleet pidempään kuvaukseen tai selvittääksesi alueen säännöt ja ohjeet:\n\n- Miksi käyttäjät valitsisivat tämän alueen? Mitä varten se on?\n\n- Kuinka se tarkkaan ottaen eroaa muista olemassa olevista alueista?\n\n- Minkälaista sisältöä alueen ketjuissa tulisi yleensä olla?\n\n- Tarvitaanko tätä aluetta? Voisiko sen yhdistää toiseen alueeseen tai siirtää toisen alueen alle?\n" errors: uncategorized_parent: "Alueettomia ei voi asettaa toisen alueen alle" self_parent: "Alue ei voi olla itsensä ylempi alue." - depth: "Et voi laittaa alempia alueita sisäkkäin" - email_in_already_exist: "Sisääntulevan sähköpostin osoite '%{email_in}' on jo käytössä alueella '%{category_name}'." + depth: "Alue ei voi olla tytäralueen tytäralue" + invalid_email_in: "'%{email}' ei ole käypä sähköpostiosoite" + email_already_used_in_group: "'%{email}' on jo käytössä ryhmällä '%{group_name}'." + email_already_used_in_category: "'%{email}' on jo käytössä alueella '%{category_name}'." cannot_delete: uncategorized: "Alueettomat-aluetta ei voi poistaa" has_subcategories: "Aluetta ei voi poistaa, koska sillä on sisempiä alueita." @@ -291,21 +334,36 @@ fi: one: "Aluetta ei voi poistaa, koska siellä on 1 ketju. Linkki ketjuun %{topic_link}." other: "Aluetta ei voi poistaa, koska siellä on %{count} ketjua. Vanhin ketju on %{topic_link}." topic_exists_no_oldest: "Aluetta ei voi poistaa, koska ketjujen lukumäärä on #{count}." + uncategorized_description: "Ketjut, jotka eivät tarvitse aluetta tai eivät sovi muihin alueisiin." trust_levels: newuser: title: "tulokas" basic: title: "haastaja" - regular: + member: title: "konkari" - leader: + regular: title: "mestari" - elder: + leader: title: "johtaja" change_failed_explanation: "Yritit alentaa käyttäjän %{user_name} luottamustasolle '%{new_trust_level}'. Käyttäjän luottamustaso on jo valmiiksi '%{current_trust_level}'. %{user_name} jatkaa edelleen luottamustasolla '%{current_trust_level}' - jos haluat alentaa luottamustasoa, lukitse se ensin" rate_limiter: slow_down: "Olet tehnyt tämän toiminnon liian monta kertaa, yritä uudelleen myöhemmin." - too_many_requests: "Sille, kuinka useasti tämä toiminto voidaan suorittaa on määritelty päivittäinen raja. Odota %{time_left} ennen uudelleen kokeilemista." + too_many_requests: "Tämä toiminto voidaan suorittaa vain määrätyn monta kertaa päivässä. Ole hyvä ja odota %{time_left} ja yritä sitten uudelleen." + by_type: + first_day_replies_per_day: "Uusi käyttäjä ei voi ensimmäisenä päivänään kirjoittaa enempää viestejä. Ole hyvä ja odota %{time_left} ja yritä sitten uudelleen." + first_day_topics_per_day: "Uusi käyttäjä ei voi ensimmäisenä päivänään luoda enempää ketjuja. Ole hyvä ja odota %{time_left} ja yritä sitten uudelleen." + create_topic: "Yrität luoda ketjuja liian nopeasti. Ole hyvä ja odota %{time_left} ja yritä sitten uudelleen." + create_post: "Yrität vastata liian nopeasti. Ole hyvä ja odota %{time_left} ja yritä sitten uudelleen." + delete_post: "Poistat viestejä liian nopeasti. Ole hyvä ja odota %{time_left} ja yritä sitten uudelleen." + topics_per_day: "Olet luonut enimmäismäärän uusia ketjuja tälle päivälle. Ole hyvä ja odota %{time_left} ja yritä sitten uudelleen." + pms_per_day: "Olet lähettänyt enimmäismäärän viestejä tälle päivälle. Ole hyvä ja odota %{time_left} ja yritä sitten uudelleen." + create_like: "Olet tykännyt enimmäismäärän tälle päivälle. Ole hyvä ja odota %{time_left} ja yritä sitten uudelleen." + create_bookmark: "Olet lisännyt enimmäismäärän kirjanmerkkejä tälle päivälle. Odota %{time_left}, ennen kuin yrität uudelleen." + edit_post: "Olet saavuttanut muokkausten enimmäismäärän tälle päivälle. Odota %{time_left}, ennen kuin yrität uudelleen." + live_post_counts: "Kysyt viestimääriä liian nopealla tahdilla. Odota %{time_left} ennen uudelleen yrittämistä." + unsubscribe_via_email: "Olet perunut enimmäismäärän sähköpostitse tänään. Odota %{time_left} ennen uudelleen yrittämistä." + topic_invitations_per_day: "Olet kutsunut enimmäismäärän tälle päivälle. Odota %{time_left} ennen uudelleen yrittämistä." hours: one: "1 tunti" other: "%{count} tuntia" @@ -400,7 +458,12 @@ fi: confirmed: "Sähköpostiosoite päivitetty." please_continue: "Jatka sivustolle %{site_name}" error: "Sähköpostiosoitteen vaihdossa tapahtui virhe. Ehkäpä tämä sähköpostiosoite on jo käytössä?" + already_done: "Pahoittelut, tämä varmennuslinnkki ei ole enää voimassa. Ehkäpä sähköpostiosoitteesi on jo vaihdettu?" + authorizing_old: + title: "Kiitos sähköpostiosoitteesi varmentamisesta" + description: "Lähetämme sinulle sähköpostin varmennusta varten." activation: + action: "Klikkaa tähän aktivoidaksesi tilisi" already_done: "Pahoittelut, tämän tilin varmennuslinkki ei ole enää voimassa. Ehkäpä tili on jo varmennettu?" please_continue: "Tilisi on nyt varmennettu; sivu ohjautuu palstan etusivulle." continue_button: "Jatka sivustolle %{site_name}" @@ -423,16 +486,16 @@ fi: description: 'Tämän viestin sisältö on loukkaava, herjaava tai ristiriidassa palstan sääntöjen kanssa.' long_form: 'liputti tämän asiattomaksi' notify_user: - title: 'Lähetä viesti käyttäjälle @{{username}}' - description: 'Tämä viesti sisältää jotain, mistä haluan keskustellä tämän henkilön kanssa suoraan ja yksityisesti. Tämä ei aiheuta liputusta.' + title: 'Lähetä käyttäjälle @{{username}} viesti.' + description: 'Haluan keskustella tästä viestistä kirjoittajan kanssa kahden kesken.' long_form: 'lähetä käyttäjälle viesti' email_title: 'Viestisi ketjussa "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Jotain muuta" - description: 'Valvojan tulee huomioida tämä viesti muusta, kuin yllä listatusta syystä.' - long_form: 'liputit tämän valvojille tiedoksi' - email_title: 'Viesti ketjussa "%{title}" kaipaa valvojan huomiota' + description: 'Valvojan tulee huomioida tämä viesti muusta kuin yllä listatusta syystä.' + long_form: 'liputti tämän valvojien nähtäväksi' + email_title: 'Valvojien tulisi huomioida viesti ketjussa "%{title}" ' email_body: "%{link}\n\n%{message}" bookmark: title: 'Kirjanmerkki' @@ -457,7 +520,7 @@ fi: long_form: 'liputti tämän asiattomaksi' notify_moderators: title: "Jotain muuta" - description: 'Valvojan tulee huomioida tämä ketju palstan sääntöjen, palveluehtojen, tai muun syyn vuoksi.' + description: 'Valvojan tulee huomioida tämä ketju palstan sääntöjen, palveluehtojen tai muun syyn vuoksi.' long_form: 'liputit tämän valvojille tiedoksi' email_title: 'Viestiketju"%{title}" kaipaa valvojan huomiota' email_body: "%{link}\n\n%{message}" @@ -493,6 +556,10 @@ fi: title: "Uudet käyttäjät" xaxis: "Päivä" yaxis: "Uusien käyttäjien määrä" + profile_views: + title: "Käyttäjäprofiilin katselut" + xaxis: "Päivä" + yaxis: "Katseltujen käyttäjäprofiilien määrä" topics: title: "Ketjut" xaxis: "Päivä" @@ -635,6 +702,7 @@ fi: s3_config_warning: 'Palvelin on konfiguroitu tallentamaan tiedostot s3:een, mutta vähintään yksi arvoista s3_access_key_id, s3_secret_access_key tai s3_upload_bucket ei ole asetettu. Päivitä arvot sivuston asetuksissa.Voit lukea lisätietoja oppaasta "How to set up image uploads to S3?".' s3_backup_config_warning: 'Palvelin on konfiguroitu lataamaan varmuuskopiot s3:een, mutta vähintään yksi arvoista s3_access_key_id, s3_secret_access_key tai s3_backup_bucket ei ole asetettu. Päivitä arvot sivuston asetuksissa.Voit lukea lisätietoja oppaasta "How to set up image uploads to S3?".' image_magick_warning: 'Palvelin on konfiguroitu luomaan esikatselukuvia suurista kuvista, mutta ImageMagickia ei ole asennettu. Asenna ImageMagick paketinhallinnasta tai lataamalla uusin versio.' + failing_emails_warning: 'Epäonnistuneiden sähköpostitehtävien määrä on %{num_failed_jobs}. Tarkista app.yml ja varmista, että palvelimen asetukset ovat kunnossa. Katsele epäonnistuneita tehtäviä Sidekiqissa.' default_logo_warning: "Aseta sivustolle logot. Päivitä logo_url, logo_small_url, ja favicon_url sivuston asetuksissa." contact_email_missing: "Aseta yhteystietoihin sähköpostiosoite, josta sinut saa tavoitettua sivustoon liittyvissä kiireellisissä asioissa. Voit syöttää sen sivuston asetuksissa." contact_email_invalid: "Sivuston sähköpostiosoite ei kelpaa. Muokkaa sitä sivuston asetuksissa." @@ -643,42 +711,16 @@ fi: consumer_email_warning: "Sivusto on konfiguroitu käyttämään Gmailia (tai muuta yksityishenkilöille suunnattua sähköpostipalvelua) sähköpostin lähettämiseen. Gmail rajoittaa lähetettävien sähköpostien määrää. Harkitse sähköpostipalveluntarjoajaa, kuten mandrill.com varmistaaksesi sähköpostin lähetyksen." site_contact_username_warning: "Aseta käyttäjänimi, jonka nimissä palsta automaattiset viestit lähetetään. Muokkaa asetusta site_contact sivuston asetuksissa." notification_email_warning: "Palstan sähköpostien lähettäjäosoite ei ole kelvollinen, josta johtuen sähköpostit eivät mene perille luotettavasti. Aseta toimiva sähköpostiosoite kohtaan notification_email sivuston asetuksissa." - content_types: - education_new_reply: - title: "Uuden käyttäjän opastus: Ensimmäinen vastaus" - description: "Ohjeistus uusille käyttäjille, joka näytetään viestikentän yläpuolella, kun he aloittavat kirjoittamaan ensimmäisiä vastauksiaan." - education_new_topic: - title: "Uuden käyttäjän opastus: Ensimmäiset ketjut" - description: "Ohjeistus uusille käyttäjille, joka näytetään viestikentän yläpuolella, kun he aloittavat kirjoittamaan ensimmäisiä ketjujaan." - usage_tips: - title: "Uuden käyttäjän ohjeet" - description: "Ohjeita ja tärkeää tietoa uusille käyttäjille." - welcome_user: - title: "Tervetuloa: Uusi käyttäjä" - description: "Tilin luomisen yhteydessä automaattisesti lähetettävä viesti uusille käyttäjille." - welcome_invite: - title: "Tervetuloa: Kutsuttu käyttäjä" - description: "Kutsun hyväksymisen yhteydessä automaattisesti lähetettävä viesti palstalle kutsutuille käyttäjille." - login_required_welcome_message: - title: "Kirjautuminen vaaditaan: Tervetuloviesti" - description: "Tervetuloviesti uloskirjautuneille käyttäjille, kun 'pakollinen kirjautuminen' on otettu käyttöön." - login_required: - title: "Kirjautuminen vaaditaan: Kotisivu" - description: "Teksti, joka näytetään tunnistautumattomille käyttäjille, kun sivustolle kirjautuminen on pakollista." - head: - title: "HTML head" - description: "HTML, joka lisätään tagien väliin." - top: - title: "Sivun yläosa" - description: "HTML joka lisätään jokaisen sivun ylälaitaan (headerin jälkeen, ennen navigaatiota tai ketjun otsikkoa)." - bottom: - title: "Sivun alaosa" - description: "HTML, joka lisätään ennen elementtiä." + subfolder_ends_in_slash: "Alihakemiston asetuksesi ei kelpaa; DISCOURSE_RELATIVE_URL_ROOT päättyy vinoviivaan." + email_polling_errored_recently: + one: "Sähköpostin pollaus on aiheuttanut virheen edellisen 24 tunnin aikana. Tarkastele lokeja saadaksesi lisätietoja." + other: "Sähköpostin pollaus aiheutti %{count} virhettä edellisen 24 tunnin aikana. Tarkastele lokeja saadaksesi lisätietoja." site_settings: censored_words: "Sanat, jotka korvataan automaattisesti merkeillä ■■■■" delete_old_hidden_posts: "Poista automaattisesti kaikki yli 30 päivää piilotettuna olleet viestit." default_locale: "Sivuston oletuskieli (ISO 639-1 koodi)" allow_user_locale: "Salli käyttäjien vaihtaa käyttöliittymän kieli omista asetuksista" + set_locale_from_accept_language_header: "Aseta sivuston kieli kirjautumattomille käyttäjille selaimen kielivalinnan perusteella. (KOKEELLINEN, ei toimi anonyymin välimuistin kanssa)" min_post_length: "Viestin merkkien minimimäärä" min_first_post_length: "Ketjun aloitusviestin (leipätekstin) merkkien minimimäärä" min_private_message_post_length: "Viestin merkkien minimimäärä viesteille" @@ -687,8 +729,7 @@ fi: max_topic_title_length: "Viestin otsikon merkkien maksimimäärä" min_private_message_title_length: "Viestin otsikon merkkien minimimäärä viestille" min_search_term_length: "Haun merkkien minimimäärä" - allow_uncategorized_topics: "Salli ketjujen luominen valitsematta aluetta. VAROITUS: Sinun täytyy siirtää alueettomat ketjut jollekin alueelle, ennen tämän asetuksen poistamista käytöstä." - uncategorized_description: "Alueettomien ketjujen alueen kuvaus. Jätä tyhjäksi, jos et halua käyttää kuvausta." + allow_uncategorized_topics: "Salli ketjujen luominen valitsematta aluetta. VAROITUS: Alueettomat ketjut täytyy siirtää jollekin alueelle ennen kuin poistat asetuksen käytöstä." allow_duplicate_topic_titles: "Salli ketjun luominen identtisellä otsikolla." unique_posts_mins: "Kuinka monta minuuttia, kunnes käyttäjä voi luoda uudestaan saman sisältöisen viestin" educate_until_posts: "Näytä uuden käyttäjän ohje, kun käyttäjä alkaa kirjoittamaan ensimmäistä (n) viestiään viestikenttään." @@ -701,14 +742,14 @@ fi: download_remote_images_to_local: "Muunna linkatut kuvat liitetiedostoiksi lataamalla ne; tämä estää kuvien rikkoontumisen vanhentuneiden linkkien vuoksi." download_remote_images_threshold: "Vähin vapaa tila, jotta linkatut kuvat ladataan (prosenteissa)" disabled_image_download_domains: "Linkattuja kuvia ei koskaan ladata näistä verkkotunnuksista. Pystyviivalla eroteltu lista." - ninja_edit_window: "Muokkaus ei tallenna erillistä versiota viestihistoriaan (n) sekunnin aikana viestin lähettämisen jälkeen." + editing_grace_period: "Viestin muokkaaminen (n) sekunnin sisällä sen lähettämisestä ei luo viestistä uutta versiota viestin lokiin." post_edit_time_limit: "Kirjoittaja voi muokata tai poistaa viestinsä (n) minuuttia lähettämisen jälkeen. Aseta 0 poistaaksesi rajoituksen kokonaan." edit_history_visible_to_public: "Salli kaikkien nähdä muokatun viestin edelliset versiot. Jos asetus otetaan pois käytöstä, vain henkilökunta näkee versiot." delete_removed_posts_after: "Kirjoittajalta poistetut viestit poistetaan automaattisesti (n) tunnin kuluttua. Jos asetetaan 0, viestit poistetaan välittömästi." max_image_width: "Esikatselukuvan suurin sallittu leveys viestissä" max_image_height: "Esikatselukuvan suurin sallittu korkeus viestissä" category_featured_topics: "Näytettävien ketjujen lukumäärä alueittan Alueet-sivulla. Arvon muuttamisen jälkeen voi kestää jopa 15 minuuttia sivun päivittymiseen." - show_subcategory_list: "Näytä sisempien alueiden lista ketjulistauksen sijaan alueelle saavuttaessa." + show_subcategory_list: "Näytä lista tytäralueista ketjulistauksen sijaan alueelle saavuttaessa." fixed_category_positions: "Jos tämä on valittuna, voit muokata alueiden järjestystä. Jos tätä ei valita, alueet järjetsetään aktiivisuuden mukaan." fixed_category_positions_on_create: "Jos tämä on valittuna, alueiden järjestys pysyy samana uuden ketjun luomisen dialogissa (edellyttää fixed_category_positions)" add_rel_nofollow_to_user_content: "Lisää rel nofollow kaikkeen käyttäjien lähettämään sisältöön, paitsi sivuston sisäisiin linkkeihin (sisältäen ylemmät verkkotunnukset). Jos muutat asetusta, sinun täytyy rakentaa viestit uudelleen komennolla: \"rake posts:rebake\"" @@ -719,6 +760,7 @@ fi: logo_url: "Logo sivustosi vasemmassa yläkulmassa. Sen pitäisi olla leveä suorakulmio muodoltaan. Jos jätetään tyhjäksi, näytetään sivuston otsikkoteksti." digest_logo_url: "Vaihtoehtoinen logo, jota käytetään sivustolta lähtevissä sähköpostitiivistelmissä. Sen pitäisi olle leveä suorakulmio muodoltaan. Jos jätetään tyhjäksi, sen tilalla käytetään 'logo_url'." logo_small_url: "Pieni logo sivuston vasemmassa reunassa, joka näytettään rullattaessa alaspäin. Sen pitäisi olla neliö muodoltaan. Jos jätetään tyhjäksi, näytetään sen tilalla koti-merkki." + favicon_url: "Palstan favicon, katso http://fi.wikipedia.org/wiki/Favicon, täytyy olla png toimiakseen CDN:n kanssa" mobile_logo_url: "Logo mobiilisivun vasemmassa ylälaidassa. Sen pitäisi olla neliön muotoinen. Jos jätetään tyhjäksi, 'logo_url' käytetään sen tilalla. Esim: http://example.com/uploads/default/logo.png" apple_touch_icon_url: "Applen laitteiden käyttämä ikoni, Suositeltu koko on 144px kertaa 144px." notification_email: "Sähköpostiosoite, josta kaikki tärkeät järjestelmän lähettämät sähköpostiviestit lähetetään. Verkkotunnuksen SPF, DKIM ja reverse PTR tietueiden täytyy olla kunnossa, jotta sähköpostit menevät perille." @@ -730,7 +772,7 @@ fi: summary_likes_required: "Montako tykkäystä ketjussa pitää olla, jotta ketjun tiivistelmä otetaan käyttöön" summary_percent_filter: "Kun käyttäjä klikkaa 'Näytä ketjun tiivistelmä', näytä paras % viesteistä" summary_max_results: "Maksimimäärä viestejä, jotka näytetään ketjun tiivistelmässä" - enable_private_messages: "Salli luottamustason 1 käyttäjien luoda ja vastata viesteihin" + enable_private_messages: "Salli luottamustason 1 (muokattavissa asetuksista) käyttäjien lähettää yksityisviestejä ja vastata viesteihin" enable_long_polling: "Ilmoitusten käyttämä viestiväylä voi käyttää long pollingia" long_polling_base_url: "Base URL, jota käytetään long pollingissa (kun CDN on käytössä, varmista että tähän on asetettu origin pull) esim: http://origin.site.com" long_polling_interval: "Kuinka kauan palvelimen pitäisi odottaa ennen vastaamista asiakkaalle, kun ei ole mitään dataa jota lähettää (vain kirjautuneille käyttäjille)" @@ -749,8 +791,10 @@ fi: notify_mods_when_user_blocked: "Jos käyttäjä estetään automaattisesti, lähetä viesti kaikille valvojille." flag_sockpuppets: "Jos uusi käyttäjä vastaa toisen uuden käyttäjän luomaan ketjun samasta IP osoitteesta, liputa molemmat viestit mahdolliseksi roskapostiksi." traditional_markdown_linebreaks: "Käytä perinteisiä rivinvaihtoja Markdownissa, joka vaatii kaksi perättäistä välilyöntiä rivin vaihtoon." + allow_html_tables: "Salli taulukoiden syöttäminen Markdowniin käyttäen HTML tageja. TABLE, THEAD, TD, TR, TH valkolistataan (edellyttää kaikkien taulukoita sisältävien vanhojen viestien uudelleen rakentamisen)" post_undo_action_window_mins: "Kuinka monta minuuttia käyttäjällä on aikaa perua viestiin kohdistuva toimi (tykkäys, liputus, etc)." must_approve_users: "Henkilökunnan täytyy hyväksyä kaikki uudet tilit, ennen uusien käyttäjien päästämistä sivustolle. VAROITUS: tämän asetuksen valitseminen poistaa pääsyn kaikilta jo olemassa olevilta henkilökuntaan kuulumattomilta käyttäjiltä." + pending_users_reminder_delay: "Ilmoita valvojille, jos uusi käyttäjä on odottanut hyväksyntää kauemmin kuin näin monta tuntia. Aseta -1, jos haluat kytkeä ilmoitukset pois päältä." ga_tracking_code: "Google analytics (ga.js) seurantakoodi, esim.: UA-12345678-9; katso http://google.com/analytics" ga_domain_name: "Google analytics (ga.js) verkkotunnus, esim.: osoite.fi; katso http://google.com/analytics" ga_universal_tracking_code: "Google Universal analytics (analytics.js) seurantakoodi, esim.: UA-12345678-9; katso http://google.com/analytics" @@ -759,6 +803,7 @@ fi: enable_noscript_support: "Ota käyttöön noscript-tagi hakukoneiden webcrawlereille" allow_moderators_to_create_categories: "Salli valvojien luoda uusia alueita" cors_origins: "Salli lähteet CORS-pyynnöille (cross-origin request). Jokaisen lähteen pitää sisältää http:// tai https://. DISCOURSE_ENABLE_CORS asetus pitää olla valittuna ottaaksesi CORSin käyttöön." + use_admin_ip_whitelist: "Ylläpitäjät voivat kirjautua vain IP osoitteista, jotka on määritetty Seulottavien IP:iden listassa (Ylläpito > Lokit > Seulottavat IP:t)" top_menu: "Mitkä painikkeet näytetään kotisivun navigointipalkissa, ja missä järjestyksessä. Esimerkiksi latest|new|unread|categories|top|read|posted|bookmarks" post_menu: "Mitkä painikkeet näytetään viestin valikossa, ja missä järjestyksessä. Esimerkiksi like|edit|flag|delete|share|bookmark|reply" post_menu_hidden_items: "Piilotettavat painikkeet viestin valikosta, kunnes '...' klikataan." @@ -770,14 +815,15 @@ fi: suppress_reply_directly_above: "Älä näytä vastauksena-painiketta viestin yläreunassa, jos viestissä on vastattu vain edelliseen viestiin." suppress_reply_when_quoting: "Älä näytä vastauksena-painiketta viestin yläreunassa, kun viestissä on lainaus." max_reply_history: "Maksimimäärä vastauksia, jotka avataan klikattaessa 'vastauksena' painiketta" - experimental_reply_expansion: "Piilota välilliset vastaukset, kun 'vastauksena' avataan (kokeellinen)" - topics_per_period_in_top_summary: "Kejujen lukumäärä, joka näytetään oletuksena Huiput-listauksissa." - topics_per_period_in_top_page: "Kejujen lukumäärä, joka näytetään laajennetussa Huiput-listauksessa." + topics_per_period_in_top_summary: "Ketjujen lukumäärä, joka näytetään oletuksena Huiput-listauksissa." + topics_per_period_in_top_page: "Ketjujen lukumäärä, joka näytetään laajennetussa Huiput-listauksessa." redirect_users_to_top_page: "Ohjaa uudet ja kauan poissa olleet käyttäjät automaattisesti huiput-sivulle." + top_page_default_timeframe: "Huiput-sivun oletusaikajakso." show_email_on_profile: "Näytä käyttäjän sähköpostiosoite profiilissa (näkyy vain käyttäjälle itselleen ja henkilökunnalle)" email_token_valid_hours: "Unohtuneen salasanan / tilin vahvistamisen tokenit ovat voimassa (n) tuntia." email_token_grace_period_hours: "Unohtuneen salasanan / tilin vahvistamisen tokenit ovat vielä voimassa (n) tuntia käyttämisen jälkeen." enable_badges: "Ota käyttöön arvomerkkijärjestelmä" + enable_whispers: "Salli henkilökunnan keskustella yksityisestä ketjun sisällä. (kokeellinen)" allow_index_in_robots_txt: "Määrittele robots.txt-tiedostossa, että hakukoneet saavat luetteloida sivuston." email_domains_blacklist: "Pystyviivalla eroteltu lista sähköposti-verkkotunnuksista, joista käyttäjät eivät voi luoda tiliä. Esimerkiksi mailinator.com|trashmail.net" email_domains_whitelist: "Pystyviivalla eroteltu lista sähköposti-verkkotunnuksista, joista käyttäjien pitää luoda tilinsä. VAROITUS: Käyttäjiä, joiden sähköpostiosoite on muusta verkkotunnuksesta ei sallita!" @@ -791,8 +837,11 @@ fi: invite_passthrough_hours: "Kuinka pitkään käyttäjä voi käyttää vastatun kutsun avainta kirjautuakseen sisään, tunneissa" invite_only: "Julkinen rekisteröityminen on otettu pois käytöstä, uuden tilin luominen vaatii kutsun muilta käyttäjiltä tai henkilökunnalta." login_required: "Vaadi kirjautumista sivuston lukemiseen, epää anonyymi pääsy." + min_username_length: "Käyttäjänimen vähimmäispituus merkeissä." + max_username_length: "Käyttäjänimen enimmäispituus merkeissä." reserved_usernames: "Käyttäjänimet, joiden rekisteröintiä ei sallita." min_password_length: "Salasanan vähimmäispituus." + min_admin_password_length: "Ylläpitäjän salasanan vähimmäispituus." block_common_passwords: "Älä salli salasanoja, jotka ovat 10 000 yleisimmän salasanan joukossa." enable_sso: "Ota käyttöön single sign on ulkopuolisen sivuston kautta (VAROITUS: ULKOPUOLISEN SIVUSTON TÄYTYY VALIDOIDA SÄHKÖPOSTIOSOITTEET!)" enable_sso_provider: "Ota käyttöön Discourse SSO provider -protokolla /session/sso_provider päätepisteessä, vaatii asetuksen sso_secret asettamista." @@ -805,6 +854,7 @@ fi: sso_not_approved_url: "Uudelleenohjaa hyväksymättömät SSO-tilit tähän osoitteeseen" enable_local_logins: "Ota käyttöön käyttäjätunnus/salasana -perusteinen kirjautuminen. (Huom: tämän täytyy olla käytössä kutsujen toimimiseksi)" allow_new_registrations: "Salli uusien käyttäjien rekisteröityminen. Ota tämä asetus pois käytöstä estääksesi uusien käyttäjätilien luomisen." + enable_signup_cta: "Näytä palaaville anonyymeille käyttäjille ilmoitus, jossa kehoitetaan heitä luomaan tili." enable_yahoo_logins: "Ota käyttöön Yahoo kirjautuminen" enable_google_oauth2_logins: "Ota käyttöön Google Oauth2 tunnistautuminen. Tämä on Googlen tällä hetkellä tukeva metodi. Vaatii key ja secret." google_oauth2_client_id: "Google-applikaatiosi Client ID." @@ -812,6 +862,9 @@ fi: enable_twitter_logins: "Ota käyttöön Twitter kirjautuminen, vaatimuksena twitter_consumer_key ja twitter_consumer_secret" twitter_consumer_key: "Consumer key Twitter autentikaatioon, rekisteröinti osoitteessa http://dev.twitter.com" twitter_consumer_secret: "Consumer secret key Twitter autentikaatioon, rekisteröinti osoitteessa http://dev.twitter.com" + enable_instagram_logins: "Ota Instagram-autentikaatio käyttöön, vaatimuksena instagram_consumer_key ja instagram_consumer_secret" + instagram_consumer_key: "Consumer key Instagram-autentikaatioon" + instagram_consumer_secret: "Consumer secret Instagram-autentikaatioon" enable_facebook_logins: "Ota käyttöön Facebook autentikaatio, vaatimuksena facebook_app_id ja facebook_app_secret" facebook_app_id: "App id Facebook autentikaatioon, rekisteröinti osoitteessa https://developers.facebook.com/apps" facebook_app_secret: "App secret Facebook autentikaatioon, rekisteröinti osoitteessa https://developers.facebook.com/apps" @@ -820,12 +873,19 @@ fi: github_client_secret: "Client secret Github autentikaatioon, rekisteröinti osoitteessa https://github.com/settings/applications" allow_restore: "Salli palautus, joka korvaa KAIKEN sivuston datan! Jätä valitsematta, jos et aio palauttaa sivuston varmuuskopiota" maximum_backups: "Tallennettuna pidettävien varmuuskopioiden maksimimäärä. Vanhemmat varmuuskopiot poistetaan automaattisesti" + automatic_backups_enabled: "Tee automaattinen varmuuskopiointi, kuten tiheysasetus on määritelty" backup_frequency: "Kuinka usein luodaan sivuston varmuuskopio, päivissä." enable_s3_backups: "Lataa varmuuskopiot S3:een niiden valmistuttua. TÄRKEÄÄ: edellyttää, että toimivat S3 kirjautumistiedot on syötetty asetuksiin." s3_backup_bucket: "Amazon S3 bucket johon varmuuskopiot ladataan. VAROITUS: Varmista, että se on yksityinen." + s3_disable_cleanup: "Älä poista varmuuskopiota S3:sta, kun se poistetaan paikallisesti." + backup_time_of_day: "UTC-kellonaika, jolloin varmuuskopio tehdään." + backup_with_uploads: "Sisällytä lataukset ajastettuihin varmuuskopioihin. Jos tämä on pois käytöstä, vain tietokanta varmuuskopioidaan." active_user_rate_limit_secs: "Kuinka usein 'last_seen_at' kenttä päivitetään, sekunneissa" verbose_localization: "Näytä laajennetut lokalisointitiedot käyttöliittymässä" previous_visit_timeout_hours: "Kuinka kauan vierailun on täytynyt kestää, jotta se lasketaan 'edelliseksi' vierailuksi, tunneissa" + top_topics_formula_log_views_multiplier: "katselukertojen logaritmin kerroin (n) Huiput-listauksen kaavassa: `log(katselut) * (n) + avausviestin tykkäykset * 0.5 + PIENEMPI(tykkäysten määrä / viestien määrä, 3) + 10 + log(viestien määrä)`" + top_topics_formula_first_post_likes_multiplier: "avausviestin tykkäysmäärän kerroin (n) Huiput-listauksen kaavassa: `log(katselut) * 2 + avausviestin tykkäykset * (n) + PIENEMPI(tykkäysten määrä / viestien määrä, 3) + 10 + log(viestien määrä)`" + top_topics_formula_least_likes_per_post_multiplier: "tykkäykset/viestit -suhteen enimmäisarvo (n) Huiput-listauksen kaavassa: `log(katselut) * 2 + avausviestin tykkäykset * 0.5 + PIENEMPI(tykkäysten määrä / viestien määrä, (n)) + 10 + log(viestien määrä)`" rate_limit_create_topic: "Ketjun luomisen jälkeen käyttäjän täytyy odottaa (n) sekuntia voidakseen luoda uuden ketjun." rate_limit_create_post: "Viestin luomisen jälkeen käyttäjän täytyy odottaa (n) sekuntia voidakseen luoda uuden viestin." rate_limit_new_user_create_topic: "Ketjun luomisen jälkeen uuden käyttäjän täytyy odottaa (n) sekuntia voidakseen luoda uuden ketjun." @@ -834,10 +894,12 @@ fi: max_flags_per_day: "Liputusten päivittäinen maksimäärä per käyttäjä." max_bookmarks_per_day: "Kirjanmerkkien päivittäinen maksimäärä per käyttäjä." max_edits_per_day: "Muokkausten päivittäinen maksimäärä per käyttäjä." - max_topics_per_day: "Luotujen ketjujen päivittäinen maksimäärä per käyttäjä." + max_topics_per_day: "Luotujen ketjujen päivittäinen enimmäismäärä per käyttäjä." max_private_messages_per_day: "Viestien päivittäinen maksimäärä per käyttäjä" max_invites_per_day: "Maksimimäärä kutsuja, jonka käyttäjä voi lähettää päivässä." max_topic_invitations_per_day: "Maksimimäärä ketjukutsuja, jonka yksittäinen käyttäjä voi lähettää päivässä" + alert_admins_if_errors_per_minute: "Virheiden määrä minuutissa, jonka seurauksena hälytetään ylläpitäjä. 0 ottaa toiminnon pois käytöstä. HUOM: vaatii uudelleenkäynnistyksen." + alert_admins_if_errors_per_hour: "Virheiden määrä tunnissa, jonka seurauksena hälytetään ylläpitäjä. 0 ottaa toiminnon pois käytöstä. HUOM: vaatii uudelleenkäynnistyksen." suggested_topics: "Suositeltujen ketjujen määrä ketjun alaosassa." limit_suggested_to_category: "Näytä suositeltuja ketjuja vain nykyiseltä alueelta." clean_up_uploads: "Poista orpoutuneet liitetiedostot, joita ei käytetä viesteissä, laittoman hostauksen estämiseksi. VAROITUS: kannattaa varmuuskopioida /uploads kansio ennen tämän asetuksen ottamista käyttöön." @@ -852,6 +914,10 @@ fi: s3_region: "Amazon S3 region, jota käytetään kuvien sijoittamisessa." s3_cdn_url: "CDN URL, jota käytetään S3:ssa sijaitseville tiedostoille (esimerkiksi https://cdn.jossain.com). VAROITUS: tämän asetuksen muuttamisen jälkeen sinun täytyy rakentaa uudelleen kaikki vanhat viestit." avatar_sizes: "Profiilikuvista automaattisesti luotavat koot." + external_system_avatars_enabled: "Käytä ulkopuolista avatarpalvelua." + external_system_avatars_url: "Ulkoisen avatarpalvelun URL. Sallitut vaihdokset ovat {username} {first_letter} {color} {size}" + default_opengraph_image_url: "Oletuksena käytettävän opengraph-kuvan URL." + allow_all_attachments_for_group_messages: "Sali kaikki sähköpostiliitteet ryhmäviestessä." enable_flash_video_onebox: "Ota käyttöön swf- ja flv-linkkien (Adobe Flash) onebox-tuki. VAROITUS: saattaa lisätä tietoturvariskejä." default_invitee_trust_level: "Oletus luottamustaso (0-4) kutsutuille käyttäjille." default_trust_level: "Uusien käyttäjien oletusarvoinen luottamustaso (0-4). VAROITUS! Tämän muuttaminen altistaa roskapostille." @@ -865,32 +931,38 @@ fi: tl2_requires_likes_received: "Kuinka monta tykkäystä käyttäjän täytyy saada ennen ylentämistä luottamustasolle 2." tl2_requires_likes_given: "Kuinka monta tykkäystä käyttäjän täytyy antaa ennen ylentämistä luottamustasolle 2." tl2_requires_topic_reply_count: "Kuinka moneen ketjuun käyttäjän täytyy vastata ennen ylentämistä luottamustasolle 2." - tl3_requires_days_visited: "Monenako päivänä vähintään käyttäjän täytyy olla vieraillut sivustolla viimeisen 100 päivän aikana voidakseen saavuttaa luottamustason 3. (asteikko 0-100)" - tl3_requires_topics_replied_to: "Moneenko ketjuun vähintään käyttäjän täytyy olla vastannut viimeisen 100 päivän aikana voidakseen saavuttaa luottamustason 3. (0 tai korkeampi)" - tl3_requires_topics_viewed: "Montako prosenttia viimeisen 100 päivän aikana luoduista ketjuista käyttäjän täytyy olla katsellut voidakseen saavuttaa luottamustason 3. (asteikko 0-100)" - tl3_requires_posts_read: "Montako prosenttia viimeisen 100 päivän aikana luoduista viesteistä käyttäjän täytyy olla katsellut voidakseen saavuttaa luottamustason 3. (asteikko 0-100)" + tl3_time_period: "Luottamustason 3 vaatimuksiin liittyvän ajanjakson pituus (päivissä)" + tl3_requires_days_visited: "Monenako päivänä vähintään käyttäjän täytyy olla vieraillut sivustolla viimeisen (tl3 time period) päivän aikana voidakseen saavuttaa luottamustason 3. Ota ylennykset käytöstä asettamalla arvo korkeammaksi kuin lt3 aikaraja, (0 tai korkeampi)" + tl3_requires_topics_replied_to: "Moneenko ketjuun vähintään käyttäjän täytyy olla vastannut viimeisen (tl3 time period) päivän aikana voidakseen saavuttaa luottamustason 3. (0 tai korkeampi)" + tl3_requires_topics_viewed: "Montako prosenttia viimeisen (tl3 time period) päivän aikana luoduista ketjuista käyttäjän täytyy olla katsellut voidakseen saavuttaa luottamustason 3. (asteikko 0-100)" + tl3_requires_posts_read: "Montako prosenttia viimeisen (tl3 time period) päivän aikana luoduista viesteistä käyttäjän täytyy olla katsellut voidakseen saavuttaa luottamustason 3. (asteikko 0-100)" tl3_requires_topics_viewed_all_time: "Montako ketjua käyttäjän täytyy olla katsonut voidakseen saavuttaa luottamustason 3." tl3_requires_posts_read_all_time: "Montako viestiä käyttäjän täytyy olla katsonut voidakseen saavuttaa luottamustason 3." - tl3_requires_max_flagged: "Käyttäjällä ei saa olla enempää kuin x viestiä liputettuna x eri käyttäjältä viimeisen 100 päivän aikana voidakseen saavuttaa luottamustason 3. (0 tai korkeampi)" + tl3_requires_max_flagged: "Käyttäjällä ei saa olla enempää kuin x viestiä liputettuna x eri käyttäjältä viimeisen (tl3 time period) päivän aikana voidakseen saavuttaa luottamustason 3. (0 tai korkeampi)" tl3_promotion_min_duration: "Kuinka montaa päivää luottamustasolle 3 ylennyksen jälkeen käyttäjä voidaa jälleen alentaa luottamustasolle 2." - tl3_requires_likes_given: "Montako tykkäystä käyttäjän täytyy olla vähintään antanut viimeisen 100 päivän aikana voidakseen saavuttaa luottamustason 3." - tl3_requires_likes_received: "Montako tykkäystä käyttäjän täytyy olla vähintään saanut viimeisen 100 päivän aikana voidakseen saavuttaa luottamustason 3." + tl3_requires_likes_given: "Montako tykkäystä käyttäjän täytyy olla vähintään antanut viimeisen (tl3 time period) päivän aikana voidakseen saavuttaa luottamustason 3." + tl3_requires_likes_received: "Montako tykkäystä käyttäjän täytyy olla vähintään saanut viimeisen (tl3 time period) päivän aikana voidakseen saavuttaa luottamustason 3." tl3_links_no_follow: "Älä poista rel=nofollow -attribuuttia linkeistä luottamustason 3 käyttäjiltä." min_trust_to_create_topic: "Ketjun luomiseksi vaadittava luottamustaso." min_trust_to_edit_wiki_post: "Wikiviestin muokkaamiseen vaadittava luottamustaso." + min_trust_to_allow_self_wiki: "Minimiluottamustaso, jolla käyttäjä voi tehdä omasta viestistään wiki-viestin." + min_trust_to_send_messages: "Yksityisviestien luomiseen vaadittava luottamustaso" newuser_max_links: "Kuinka monta linkkiä uusi käyttäjä voi lisätä viestiin." newuser_max_images: "Kuinka monta kuvaa uusi käyttäjä voi lisätä viestiin." newuser_max_attachments: "Kuinka monta liitettä uusi käyttäjä voi lisätä viestiin." newuser_max_mentions_per_post: "Kuinka monta @nimi mainintaa uusi käyttäjä voi lisätä viestiin." newuser_max_replies_per_topic: "Uuden käyttäjän viestien maksimimäärä samassa ketjussa, kunnes joku vastaa heille." max_mentions_per_post: "Kuinka monta @nimi mainintaa kukaan voi lisätä viestiin." + max_users_notified_per_group_mention: "Kuinka moni voi saada ilmoituksen, kun ryhmään viitataan (jos raja ylittyy, kukaan ei saa ilmoitusta)" create_thumbnails: "Luo esikatselu- ja lightbox-kuvia, jotka ovat liian suuria mahtuakseen viestiin." email_time_window_mins: "Odota (n) minuuttia ennen ilmoitussähköpostien lähettämistä, jotta käyttäjällä on aikaa muokata ja viimeistellä viestinsä." + private_email_time_window_seconds: "Odota (n) sekuntia ennen sähköposti-ilmoitusten lähettämistä käyttäjille, jotta kirjoittajalla on mahdollisuus tehdä muokkaukset ja viimeistellä viestinsä." email_posts_context: "Kuinka monta edellistä vastausta liitetään kontekstiksi sähköposti-ilmoituksessa." flush_timings_secs: "Kuinka usein timing data päivitetään palvelimelle, sekunneissa." title_max_word_length: "Sanan enimmäispituus merkkeinä ketjun otsikossa" title_min_entropy: "Ketjun otsikon minimientropia (uniikkeja merkkejä)." body_min_entropy: "Viestin minimientropia (uniikkeja merkkejä)." + allow_uppercase_posts: "Salli pelkillä isoilla kirjaimilla kirjoittaminen otsikossa tai viestin leipätekstissä." title_fancy_entities: "Muunna tavalliset ASCII merkit hienommiksi HTML merkinnöiksi ketjun otsikoissa, kuten SmartyPants http://daringfireball.net/projects/smartypants/" min_title_similar_length: "Ketjun otsikon minimipituus, kunnes sitä verrataan muihin samankaltaisiin ketjuihin." min_body_similar_length: "Viestin minimipituus, kunnes sitä verratataan muihin samankaltaisiin ketjuihin." @@ -919,6 +991,8 @@ fi: newuser_spam_host_threshold: "Kuinka monta kertaa uusi käyttäjä voi lisätä linkin samaan isäntään `newuser_spam_host_posts` viesteissään, kunnes se tulkitaan roskapostin lähettämiseksi." white_listed_spam_host_domains: "Lista verkkotunnuksista, joita ei oteta huomioon roskapostin tunnistamisessa. Uusilla käyttäjillä ei ole rajoituksia linkkaamisessa näihin tunnuksiin." staff_like_weight: "Kuinka suuri ylimääräinen arvo on henkilökunnan tykkäyksillä." + topic_view_duration_hours: "Laske uusi ketjun katselu kerran per IP/käyttäjä joka N:s tunti" + user_profile_view_duration_hours: "Laske uusi profiilin katselu kerran per IP/käyttäjä joka N:s tunti" levenshtein_distance_spammer_emails: "Verrattaessa sähköpostiosoitteita tunnettuihin roskapostittajiin, näin monen merkin ero saa vielä aikaan löydöksen." max_new_accounts_per_registration_ip: "Jos samasta IP osoitteesta on jo (n) luottamustason 0 käyttäjätiliä (eikä yhtään henkilökunnan tai vähintään LT2), lakkaa hyväksymästä uusia rekisteröitymisiä tästä IP:stä." min_ban_entries_for_roll_up: "Kun Kääri-painiketta painetaan, luodaan IP-porttikielloista aliverkon kattavia kieltoja jos kieltoja on asettu vähintään (N) määrä." @@ -936,6 +1010,11 @@ fi: disable_emails: "Estä Discoursea lähettämästä mitään sähköpostia" strip_images_from_short_emails: "Poista kuvat sähköposteista, joiden koko on alle 2800 tavua" short_email_length: "Lyhyen sähköpostin pituus tavuissa" + display_name_on_email_from: "Näytä sähköpostien lähettäjinä käyttäjien koko nimet" + unsubscribe_via_email: "Salli käyttäjän lakkauttaa sähköposti-ilmoitukset lähettämällä sähköpostiviesti, jonka otsikossa tai leipätekstissä esiintyy sana \"unsubscribe\"" + unsubscribe_via_email_footer: "Liitä sähköpostiviestien alaosaan linkki, jonka avulla saaja voi lakkauttaa sähköposti-ilmoitukset" + delete_email_logs_after_days: "Poista sähköpostilokit (N) päivän jälkeen. Aseta 0 säilyttääksesi ikuisesti." + max_emails_per_day_per_user: "Käyttäjälle päivässä lähetettävien sähköpostien enimmäismäärä. Aseta 0, jos et halua rajoittaa." pop3_polling_enabled: "Pollaa sähköpostivastaukset POP3:lla." pop3_polling_ssl: "Käytä SSL-salausta yhdistettäessä POP3-palvelimeen. (Suositellaan)" pop3_polling_period_mins: "Tiheys minuuteissa kuinka usein POP3 tililtä tarkastetaan uudet sähköpostit. HUOM: vaatii uudelleenkäynnistyksen." @@ -962,7 +1041,8 @@ fi: automatically_download_gravatars: "Lataa käyttäjille Gravatarit automaattisesti tilin luonnin ja sähköpostin vaihdon yhteydessä." digest_topics: "Sähköpostitiivistelmässä näytettävien ketjujen maksimimäärä." digest_min_excerpt_length: "Viestin katkelman vähimmäispituus sähköpostitiivistelmässä, merkeissä" - suppress_digest_email_after_days: "Jätä lähettämättä tiivistelmäsähköpostit käyttäjille, joita ei ole nähty (n) päivän aikana." + delete_digest_email_after_days: "Jätä lähettämättä tiivistelmäsähköpostit käyttäjille, joita ei ole nähty (n) päivän aikana." + digest_suppress_categories: "Älä liitä näiden alueiden viestejä sähköpostitiivistelmiin." disable_digest_emails: "Ota tiivistelmäsähköpostit pois käytöstä kaikilta käyttäjiltä." detect_custom_avatars: "Tarkistetaanko, ovatko käyttäjät ladanneet oman profiilikuvan." max_daily_gravatar_crawls: "Korkeintaan kuinka monta kertaa Discourse tarkistaa avatarit Gravatarista päivässä" @@ -972,21 +1052,25 @@ fi: allow_anonymous_posting: "Salli käyttäjien vaihtaa anonyymiin tilaan" anonymous_posting_min_trust_level: "Anonyymin tilan käyttämiseen vaadittava luottamustila" anonymous_account_duration_minutes: "Suojellaksesi anonymiteettiä, luo uusi anonyymi tili N minuutin välein jokaiselle käyttäjälle. Esimerkki: jos arvoksi asetetaan 600, kun 600 minuuttia tulee kuluneeksi edellisestä viestistä JA käyttäjä vaihtaa anonyymiin tilaan, luodaan uusi anonyymi tili." + hide_user_profiles_from_public: "Älä näytä käyttäjäkortteja, käyttäjäprofiileita tai käyttäjähakemistoa kirjautumattomille käyttäjille." allow_profile_backgrounds: "Salli käyttäjien ladata profiilin taustakuva." sequential_replies_threshold: "Kuinka monen peräkkäisen viestin jälkeen yhdessä ketjussa käyttäjää muistutetaan peräkkäisistä vastauksista." enable_mobile_theme: "Mobiililaitteet käyttävät erillistä teemaa ja kahden välillä on mahdollista vaihtaa. Poista asetus käytöstä, jos haluat käyttää omaa tyylitiedostoa, joka on mukautuva eri laitteille." dominating_topic_minimum_percent: "Kuinka monta prosenttia ketjun viesteistä käyttäjän täytyy kirjoittaa, ennen kuin tulee muistutetuksi ketjun dominoinnista." + disable_avatar_education_message: "Piilota opastusviesti, joka näytetään kun profiilikuvaa vaihdetaan." daily_performance_report: "Analysoi NGINX lokit päivittäin ja julkaise vain henkilökunnalle näkyvä ketju yksityiskohdista" suppress_uncategorized_badge: "Älä näytä alueettomille ketjuille tunnusta ketjujen listauksissa." global_notice: "Näytä KIIREELLISESTÄ HÄTÄTAPAUKSESTA kertova banneri kaikilla sivuilla kaikille käyttäjille, vaihda tyhjäksi piilottaaksesi sen (HTML sallittu)." disable_edit_notifications: "Poista muokkausilmoitukset system-käyttäjältä, kun 'download_remote_images_to_local' on asetettu." + automatically_unpin_topics: "Poista ketjun kiinnitys automaattisesti, kun käyttäjä on sen lopussa." + read_time_word_count: "Sanamäärä minuutissa, jota käytetään lukuajan arviointiin." full_name_required: "Koko nimi on käyttäjäprofiilin vaadittu kohta" enable_names: "Näytä käyttäjän koko nimi profiilissa, käyttäjäkortissa ja sähköposteissa. Poista käytöstä piilottaaksesi koko nimen kaikkialla." display_name_on_posts: "Näytä käyttäjän pitkä nimi viesteissä @nimen lisäksi." show_time_gap_days: "Jos kahden viestin välissä on kulunut näin monta päivää, näytä aikaväli ketjussa." invites_per_page: "Oletuksena montako kutsua näytetään käyttäjäsivulla." short_progress_text_threshold: "Kuinka monen viestin jälkeen ketjun edistyspalkissa näytetään vain nykyisen viestin numero. Jos muutat palkin leveyttä, voit joutua muuttamaan tätä arvoa." - default_code_lang: "Oletusarvoinen ohjelmointikieli syntaksin korostukseen Github koodiblokeissa (lang-auto, ruby, python etc.)" + default_code_lang: "Oletusarvoinen ohjelmointikieli syntaksin korostukseen Github koodiblokeissa (lang-auto, ruby, python jne.)" warn_reviving_old_topic_age: "Kun käyttäjä alkaa kirjoittamaan vastausta ketjuun, jonka uusin viesti on tätä vanhempi päivissä, näytetään varoitus. Poista käytöstä asettamalla arvoksi 0." autohighlight_all_code: "Pakota koodin korostus kaikkiin esimuotoiltuihin tekstiblokkeihin, vaikka käyttäjä ei määrittelisi kieltä." highlighted_languages: "Syntaksin korostamisen säännöt. (Varoitus: liian monen kielen sisällyttäminen voi vaikuttaa suorituskykyyn) katso demo: https://highlightjs.org/static/demo/" @@ -996,21 +1080,43 @@ fi: embed_username_key_from_feed: "Avain, jolla erotetaan Discourse-käyttäjänimi syötteestä." embed_truncate: "Typistä upotetut viestit." embed_post_limit: "Upotettavien viestien maksimimäärä." + embed_username_required: "Käyttäjänimi vaaditaan ketjun luomiseksi." embed_whitelist_selector: "CSS valitsin elementeille, jotka sallitaan upotetuissa viesteissä." embed_blacklist_selector: "CSS valitstin elementeille, jotka poistetaan upotetuista viesteistä." notify_about_flags_after: "Jos liputuksia ei ole käsitelty näin moneen tuntiin, lähetä sähköposti contact_email osoitteeseen. Aseta 0 ottaaksesi pois käytöstä." enable_cdn_js_debugging: "Salli /logs näyttää kunnolliset virheilmoitukset lisäämällä crossorigin permissions kaikkiin sisällytettyihin js-kirjastoihin." show_create_topics_notice: "Jos palstalla on vähemmän kuin 5 julkista ketjua, huomauta ylläpitäjiä ketjujen luonnista." delete_drafts_older_than_n_days: Poista yli (n) päivää vanhat luonnokset. - vacuum_db_days: "Aja VACUUM FULL ANALYZE vapauttaaksesi tilaa tietokantaan migraatioiden jälkeen (aseta 0 ottaaksesi pois käytöstä)" + vacuum_db_days: "Aja VACUUM ANALYZE vapauttaaksesi tietokannan viemää tilaa migraatioiden jälkeen (aseta 0 poistaaksesi käytöstä)" prevent_anons_from_downloading_files: "Estä kirjautumattomia käyttäjiä lataamasta liitetiedostoja. VAROITUS: tämä estää viestin liitettyjen muiden tiedostojen, kuin kuvien käyttämisen sivustolla." slug_generation_method: "Valitse polkulyhenteen luomisen metodi. 'encoded' käyttää prosenttikoodausta, 'none' poistaa polkulyhenteet käytöstä." enable_emoji: "Ota emoji käyttöön" emoji_set: "Minkälaisa emojia haluaisit käyttää?" enforce_square_emoji: "Pakota neliö kuvasuhteeksi kaikille emojille." - approve_post_count: "Viestien lukumäärä, joka tarkastetaan uusilta käyttäjiltä" + approve_post_count: "Viestien lukumäärä, joka tarkastetaan uusilta käyttäjiltä ja haastajilta." approve_unless_trust_level: "Tätä luottamustasoa alhaisempien käyttäjien viestit tarkastetaan" notify_about_queued_posts_after: "Jos hyväksyntää odottavia viestejä on odottanut näin monta tuntia, lähetä sähköposti contact_email osoitteeseen. Aseta 0 ottaaksesi pois käytöstä." + default_email_digest_frequency: "Kuinka usein käyttäjille lähetetään tiivistelmäsähköposti oletuksena." + default_include_tl0_in_digests: "Sisällytä uusien käyttäjien viestit sähköpostitiivistelmiin oletuksena. Tätä voi muuttaa käyttäjäasetuksissa." + default_email_private_messages: "Lähetä oletuksena sähköposti, kun joku lähettää käyttäjälle viestin." + default_email_direct: "Lähetä oletuksena sähköposti, kun joku lainaa/vastaa/mainitsee tai kutsuu käyttäjän." + default_email_mailing_list_mode: "Lähetä oletuksena sähköposti jokaisesta uudesta viestistä." + disable_mailing_list_mode: "Älä salli käyttäjien valita sähköpostilista-moodia." + default_email_always: "Lähetä oletuksena sähköposti, vaikka käyttäjä on ollut aktiivinen palstalla." + default_email_previous_replies: "Sisällytä aiemmat vastaukset sähköposteihin oletuksena." + default_email_in_reply_to: "Sisällytä lyhennelmä vastattavasta viestistä sähköpostiin oletuksena." + default_other_new_topic_duration_minutes: "Yleinen oletusarvo sille, koska ketju tulkitaan uudeksi." + default_other_auto_track_topics_after_msecs: "Yleinen oletusarvo sille, missä ajassa ketjua aletaan seurata." + default_other_external_links_in_new_tab: "Avaa oletuksena ulkopuoliset linkit uudessa välilehdessä." + default_other_enable_quoting: "Ota oletuksena käyttöön lainaaminen valitsemalla tekstiä." + default_other_dynamic_favicon: "Näytä oletuksena uusien/päivittyneiden ketjujen määrä selaimen ikonissa." + default_other_disable_jump_reply: "Älä hyppää oletuksena uuteen vastaukseen käyttäjän lähetettyä sen." + default_other_edit_history_public: "Tee oletuksena viestien versioista julkisia." + default_other_like_notification_frequency: "Ilmoita käyttäjiä tykkäyksistä oletuksena" + default_topics_automatic_unpin: "Aseta oletukseksi, että ketjun kiinnitys poistuu automaattisesti, jos käyttäjä selaa keskustelun loppuun" + default_categories_watching: "Lista oletuksena tarkkailtavista alueista." + default_categories_tracking: "Lista oletuksena seurattavista alueista." + default_categories_muted: "Lista oletuksena vaimennetuista alueista." errors: invalid_email: "Sähköpostiosoite ei kelpaa." invalid_username: "Tällä nimellä ei löydy käyttäjää." @@ -1025,7 +1131,14 @@ fi: invalid_string_min: "Täytyy olla vähintään %{min} merkkiä." invalid_string_max: "Ei saa olla yli %{max} merkkiä." invalid_reply_by_email_address: "Arvon täytyy sisältää '%{reply_key}' ja olla eri, kuin ilmoitusten sähköpostiosoite." + pop3_polling_host_is_empty: "Sinun täytyy asettaa 'pop3 polling host' ennen POP3-pollauksen ottamista käyttöön." + pop3_polling_username_is_empty: "Sinun täytyy asettaa 'pop3 polling username' ennen POP3-pollauksen ottamista käyttöön." + pop3_polling_password_is_empty: "Sinun täytyy asettaa 'pop3 polling password' ennen POP3-pollauksen ottamista käyttöön." + pop3_polling_authentication_failed: "POP3 autentikaatio epäonnistui. Tarkasta pop3 kirjautumistiedot." + reply_by_email_address_is_empty: "'reply by email address' täytyy olla asetettuna ennen sähköpostivastausten ottamista käyttöön." + user_locale_not_enabled: "'allow user locale' täytyy olla asetettuna ennen tämän asetuksen ottamista käyttöön." notification_types: + group_mentioned: "%{group_name} mainittiin täällä %{link}" mentioned: "%{display_username} viittasi sinuun viestissä %{link}" liked: "%{display_username} tykkäsi viestistäsi %{link}" replied: "%{display_username} vastasi viestiisi %{link}" @@ -1035,7 +1148,7 @@ fi: moved_post: "%{display_username} siirsi viestisi tänne %{link}" private_message: "%{display_username} lähetti sinulle viestin: %{link}" invited_to_private_message: "%{display_username} kutsui sinut viestiin: %{link}" - invited_to_topic: "%{display_username} kutsui sinut ketjuun: %{link}" + invited_to_topic: "%{display_username} kutsui sinut %{link}" invitee_accepted: "%{display_username} hyväksyi kutsusi" linked: "%{display_username} linkitti sinuun täällä %{link}" granted_badge: "Ansaitsit %{link}" @@ -1046,10 +1159,10 @@ fi: topic: 'Tulokset' user: 'Käyttäjät' sso: - not_found: "Käyttäjätilin hakeminen tai luominen ei onnistunut, ota yhteys järjestelmävalvojaan." - account_not_approved: "Tili odottaa hyväksyntää, saat sähköpostiin ilmoituksen kun hyväksyntä on valmis" - unknown_error: "Virhe tietojen päivittämisessä, ota yhteyttä järjestelmävalvojaan" - timeout_expired: "Kirjautuminen on vanhentunut, ole hyvä ja kirjaudu uudestaan" + not_found: "Tiliäsi ei löydetty. Ota yhteyttä sivuston ylläpitäjään." + account_not_approved: "Tilisi odottaa hyväksyntää. Saat sähköpostin, kun tunnuksesi on hyväksytty." + unknown_error: "Tiliisi liittyen on tapahtunut virhe. Ota yhteyttä sivuston ylläpitäjään." + timeout_expired: "Kirjautuminen on vanhentunut, yritä kirjautua sisään uudestaan." original_poster: "Alkuperäinen kirjoittaja" most_posts: "Eniten viestejä" most_recent_poster: "Uusin kirjoittaja" @@ -1124,6 +1237,7 @@ fi: reserved_username: "Käyttäjänimi ei ole sallittu." missing_user_field: "Et ole täyttänyt kaikkia kenttiä" close_window: "Kirjautuminen onnistui. Sulje tämä ikkuna jatkaaksesi." + already_logged_in: "Hups, näyttää siltä, että yrität hyväksyä kutsun käyttäjänä, jolle sitä ei lähetetty. Jos et ole %{current_user}, kirjaudu ulos ja yritä uudestaan." user: no_accounts_associated: "Ei liittyviä käyttäjätilejä" username: @@ -1132,12 +1246,32 @@ fi: characters: "täytyy koostua vain numeroista, kirjaimista ja alaviivoista" unique: "täytyy olla uniikki" blank: "pakollinen kenttä" + must_begin_with_alphanumeric_or_underscore: "täytyy alkaa kirjaimella, numerolla tai alaviivalla" + must_end_with_alphanumeric: "täytyy loppua kirjaimeen tai numeroon" + must_not_contain_two_special_chars_in_seq: "ei saa sisältää peräkkäin kahta tai useampaa erikoismerkkiä (.-_)" + must_not_end_with_confusing_suffix: "ei voi päättyä harhaanjohtavaan päätteeseen kuten .json tai .png jne." email: not_allowed: "ei sallita tältä sähköpostin palvelunatarjoajalta. Ole hyvä, ja käytä toista sähköpostiosoitetta." blocked: "ei ole sallittu." ip_address: blocked: "Uusien tilien luonti tästä IP-osoitteesta ei ole sallittu." max_new_accounts_per_registration_ip: "Rekisteröitymisiä ei oteta vastaan IP-osoitteestasi (maksimimäärä saavutettu). Ota yhteyttä henkilökuntaan." + flags_reminder: + flags_were_submitted: + one: "Viestejä liputettiin yli tunti sitten. Tarkasta liputukset." + other: "Viestejä liputettiin yli %{count} tuntia sitten. Tarkasta liputukset." + subject_template: + one: "Yksi liputus odottaa käsittelyä" + other: "%{count} liputusta odottaa käsittelyä" + unsubscribe_mailer: + subject_template: "Vahvista, ettet enää halua, että %{site_title} lähettää sinulle sähköpostimuistutuksia." + text_body_template: | + Joku (mahdollisesti sinä) pyysi, ettei sähköposti-ilmoituksia sivustolta %{site_domain_name} enää lähetettäisi tähän osoitteeseen. + Vahvista pyyntö klikkaamalla linkkiä: + + %{confirm_unsubscribe_link} + + Jos haluat jatkossakin saada sähköposti-ilmoituksia, voit jättää tämän viestin huomiotta. invite_mailer: subject_template: "%{invitee_name} kutsui sinut ketjuun '%{topic_title}' sivustolla %{site_domain_name}" text_body_template: | @@ -1181,90 +1315,10 @@ fi: (jos yllä oleva linkki on vanhentunut, valitse "unohdin salasanani" kirjautuessasi sisään sähköpostiosoitteellasi) test_mailer: subject_template: "[%{site_name}] Sähköpostin toimitettavuustesti" - text_body_template: | - Tämä on testisähköposti sivustolta - - [**%{base_url}**][0] - - Sähköpostin toimitus on monimutkaista. Tässä on muutama tärkeä asia, jotka kannattaa tarkistaa ensin: - - - *Varmista,* että `ilmoitusten sähköpostiosoitteen` from: kenttä on asetettu oikein sivuston asetuksissa. **Sähköpostin varmennus tapahtuu "from"-kentän sähköpostiosoitteen verkkotunnusta vastaan**. - - - Selvitä, miten sähköpostiohjelmassasi saa näkyville *sähköpostin raakadatan,* jotta voit tutkia viestin tunnistetiedot. Gmailissa tämä tapahtuu "näytä kokonaan" valinnalla viestin oikeassa yläkulmassa olevasta valikosta. - - - **TÄRKEÄÄ:** Onko palveluntarjoajasi syöttänyt reverse DNS kentän verkkotunnuksille ja IP osoitteille, joists lähetät sähköpostia? [Kokeile Reverse PTR tietuetta][2] täällä. Jos palveluntarjoajasi ei tarjoa kunnollista reverse DNS pointer tietuetta, on hyvin epätodennäköistä, että mikään sähköposti menee perille. - - - Onko verkkotunnuksesi [SPF record][8] oikein? [Kokeile SPF tietuetta][1] täällä. Huomaa, että TXT oikea tietuetyyppi SPF tietueelle. - - - Onko verkkotunnuksesi [DKIM tietue][3] oikein? Tämä vaikuttaa merkittävästi sähköpostin toimitettavuuteen. [Kokeile DKIM tietuetta][7] täällä. - - - Jos käytät omaa sähköpostipalvelinta, tarkista että palvelimen IP osoite [ei ole millään sähköpostin mustalla listalla][4]. - - - Tarkista myös, että se varmasti lähettää oikean muotoisen isäntänimen HELO viestissään, joka palauttaa oikean DNS tietueen. Jos näin ei ole, sähköposti hylätään monissa sähköpostipalveluissa. - - (Helpoin tapa on luoda ilmainen tili [Mandrilliin][md], [Mailguniin][mg] tai [Mailjetiin][mj], joide ilmaiset palvelut riittävät hyvin piemen palstan käyttöön. Muista silti asettaa SPF ja DKIM tietueet DNS:ään!) - - Toivottavasti tämä testisähköposti meni perille OK! - - Onnea matkaan, - - Ystäväsi [Discourselta](http://www.discourse.org) - - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: https://www.mailjet.com/pricing new_version_mailer: - subject_template: "[%{site_name}] Uusi Discourse versio, päivitys saatavilla" - text_body_template: |+ - Uusi versio [Discoursesta](http://www.discourse.org) on saatavilla - - Sinun versiosi: %{installed_version} - Uusin versio: **%{new_version}** - - Voit haluta: - - - Tarkastella mitä uutta on [GitHubin muutoslokissa](https://github.com/discourse/discourse/commits/master). - - - Asentaa päivityksen vierailemalla osoitteessa [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Vierailla osoitteessa [meta.discourse.org](http://meta.discourse.org) englanninkielisten uutisten, keskustelun ja tuen Discourselle vuoksi. - + subject_template: "[%{site_name}] Uusi Discourse-versio, päivitys saatavilla" new_version_mailer_with_notes: subject_template: "[%{site_name}] päivitys saatavilla" - text_body_template: | - Uusi versio [Discoursesta](http://www.discourse.org) on saatavilla - - Sinun versiosi: %{installed_version} - Uusin versio: **%{new_version}** - - Voit haluta: - - - Tarkastella mitä uutta on [GitHubin muutoslokissa](https://github.com/discourse/discourse/commits/master). - - - Asentaa päivityksen vierailemalla osoitteessa [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Vierailla osoitteessa [meta.discourse.org](http://meta.discourse.org) englanninkielisten uutisten, keskustelun ja tuen Discourselle vuoksi. - - ### Julkaisutiedot - - %{notes} - flags_reminder: - flags_were_submitted: - one: "Nämä liput annettiin yli tunti sitten." - other: "Nämä liput annettiin yli %{count} tuntia sitten." - please_review: "Ole hyvä ja tarkasta ne." - post_number: "viesti" - how_to_disable: 'Voit muuttaa tämän sähköpostimuistutuksen tiheyttä tai ottaa sen pois käytöstä muuttamalla "notify about flags after"-asetusta.' - subject_template: - one: "Yksi liputus odottaa käsittelyä" - other: "%{count} liputusta odottaa käsittelyä" queued_posts_reminder: subject_template: one: "[%{site_name}] 1 viesti odottaa hyväksyntää" @@ -1310,17 +1364,17 @@ fi: Lukeaksesi lisää, **jatka vain sivun vierittämistä alaspäin!** - Kun uusia vastauksia tai ketjuja luodaan, ne ilmestyvät näkyviin automaattisesti - ei tarvitse ladata sivua uudelleen. + Kun uusia vastauksia tai ketjuja luodaan, ne ilmestyvät näkyviin automaattisesti - sivua ei tarvitse ladata uudelleen. ## Navigointi - - Käyttääksesi hakua, päästäksesi käyttäjäsivullesi tai avataksesi valikon, käytä **oikeassa yläkulmassa olevia painikkeita**. + - Haku, käyttäjäprofiilisi ja palstan valikko avautuvat klikkaamalla **oikeassa yläkulmassa olevia painikkeita**. - - Ketjun otsikkoa klikkaamalla pääset aina **uusimpaan lukemattomaan viestiin** ketjussa. Hypätäksesi ketjun alkuun tai loppuun, klikkaa sen sijaan uusinta toimintaa tai viestien lukumäärää. + - Ketjun otsikkoa klikkaamalla pääset aina ketjun **uusimpaan lukemattomaan viestiin**. Hypätäksesi ketjun alkuun tai loppuun, klikkaa sen sijaan uusinta toimintaa tai viestien lukumäärää. - - Kun olet lukemassa viestiketjua, valitse edistymispalkki oikealla alhaalla tuodaksesi esiin täydet navigaatiopainikkeet. Paina ? tuodaksesi esiin listan näppäimistöoikoteistä. + - Kun olet lukemassa viestiketjua, klikkaa edistymispalkkia oikealla alhaalla tuodaksesi esiin navigaatiopainikkeet. Pääset hyppäämään viestin alkuun klikkaamalla ketjun otsikkoa. Näppäile ? tuodaksesi esiin listan näppäimistöoikoteistä. @@ -1328,23 +1382,31 @@ fi: - Vastataksesi **ketjuun yleisesti**, käytä ketjun lopussa. - - Vastataksesi **tiettylle henkilölle**, käytä heidän viestissään. + - Vastataksesi **tietylle henkilölle**, käytä heidän viestissään. - Vastataksesi **uudessa ketjussa**, käytä viestin oikealla puolella. Sekä vanha, että uusi ketju yhdistetään toisiinsa automaattisesti. - Lainataksesi toista käyttäjää, valitse teksti jota haluat lainata ja klikkaa mitä hyvänsä Vastaa-painiketta. Toista lisätäksesi useampia lainauksia. + Vastauksesi muotoilussa voit käyttää yksinkertaisia HTML-, BBCode- tai [Markdown](http://commonmark.org/help/)-komentoja: + + Tämä on **lihavoitu**. + Tämä on lihavoitu. + Tämä on [b]lihavoitu[/b]. + + Haluatko oppia enemmän Markdownista? [Käy kymmenen minuutin mittainen englanninkielinen tutoriaali!](http://commonmark.org/help/tutorial/) + + Lainataksesi toista käyttäjää, valitse teksti, jota haluat lainata ja klikkaa mitä hyvänsä Vastaa-painiketta. Toista lisätäksesi useampia lainauksia. - Jos haluat, että toinen käyttäjä saa ilmoituksen viestistäsi, mainitse hänen nimensä. Aloita kirjoittamaan `@` ja voit valita käyttäjänimen listasta. + Toinen käyttäjä saa ilmoituksen viestistäsi, jos mainitset hänet viestissäsi. Aloita kirjoittamaan `@` ja voit valita käyttäjänimen listasta. - Käyttääksesi [tavallisia Emojia](http://www.emoji.codes/), kirjoita vain `:` lisätäksesi nimellä tai käytä perinteisiä hymiöitä `:)` + [Tavallisia Emojia](http://www.emoji.codes/) voit lisätä nimeltä kirjoittamalla `:` tai voit käyttä perinteisiä hymiöitä, kuten `:)` - Luodaksesi lyhennelmän linkistä, liitä se omalle rivilleen: + Luodaksesi esikatselun linkistä, liitä se omalle rivilleen: @@ -1354,9 +1416,9 @@ fi: - Osoittaaksesi kirjoittajalle, että olet pitänyt hänen viestistään, käytä **tykkää** painiketta. Laita hyvä kiertämään! + Anna kirjoittajan tietää, että arvostit lukemaasi viestiä käyttämällä **tykkää** painiketta. Laitetaan hyvä kiertämään! - Jos huomaat jonkun viestissä ongelman, saata asia yksityisesti kirjoittajan tai [palstan henkilökunnan](%{base_url}/about) tietoon **liputa** painikkeella. Voit myös **jakaa** linkin viestiin tai **lisätä sen kirjanmerkkeihin** käyttäjäsivullesi myöhempää tarkastelua varten. + Jos huomaat jossain viestissä ongelman, saata asia yksityisesti kirjoittajan tai [palstan henkilökunnan](%{base_url}/about) tietoon **liputa** painikkeella. Voit myös **jakaa** linkin viestiin tai **lisätä sen kirjanmerkkeihin** käyttäjäsivullesi myöhempää tarkastelua varten. ## Ilmoitukset @@ -1364,15 +1426,13 @@ fi: - Eikä tarvitse murehtia siitä, että et huomaisi uusi vastauksia. Saat sähköposti-ilmoituksen uusista ilmoituksista jos et ole paikalla, kun ne saapuvat. + Eikä tarvitse murehtia siitä, että et huomaisi uusia vastauksia. Saat sähköpostin uusista ilmoituksista jos et ole paikalla, kun ne saapuvat. ## Omat asetukset - Oletuksena kaikki alle kaksi päivää vanhat keskustelut ovat uusia. - - Kaikkia keskusteluita **joissa olet ollut mukana** (luomalla, vastaamalla tai lukemalla pitkään) seurataan automaattisesti. - - Näet siniset uusien ja lukemattomien lukumäärän ilmaisimet näiden ketjujen yhteydessä. + - Kaikkia keskusteluita **joissa olet ollut mukana** (luomalla, vastaamalla tai lukemalla pitkään) seurataan automaattisesti. Näet siniset uusien ja lukemattomien lukumäärän ilmaisimet näiden ketjujen yhteydessä. @@ -1380,13 +1440,11 @@ fi: - Voit myös asettaa ilmoitusasetuksen aluekohtaisesti, jos haluat seurata jokaista ketjua tietyllä alueella. - - Voit muuttaa näitä asetuksia [käyttäjäasetuksissasi](%{base_url}/my/preferences). + Voit myös asettaa ilmoitusasetuksen aluekohtaisesti, jos haluat seurata jokaista ketjua tietyllä keskustelualueella. Voit muuttaa näitä asetuksia [käyttäjäasetuksissasi](%{base_url}/my/preferences). ## Yhteisön luottamus - Sitä mukaa, kun osallistut palstan keskusteluihin, keräät yhteisön luottamusta ja uuden käyttäjän rajoitukset poistuvat automaattisesti. Korkeammilla [luottamustasoilla](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924) saat vielä enemmän valtuuksia, joiden avulla voit auttaa yhteisön ylläpitämisessä. + Sitä mukaa kun osallistut palstan keskusteluihin, keräät yhteisön luottamusta ja uudelle käyttäjälle asetetut rajoitukset poistuvat automaattisesti. Korkeammilla [luottamustasoilla](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924) saat vielä enemmän valtuuksia, joiden avulla voit auttaa yhteisön ylläpitämisessä. welcome_user: subject_template: "Tervetuloa sivustolle %{site_name}!" text_body_template: | @@ -1471,20 +1529,39 @@ fi: csv_export_failed: subject_template: "Datan vienti epäonnistui" text_body_template: "Pahoittelemme, mutta datan vientisi epäonnistui. Tarkasta lokit tai ota yhteyttä henkilökuntaan." - email_reject_trust_level: + email_reject_insufficient_trust_level: subject_template: "[%{site_name}] Sähköpostiongelma -- Riittämätön luottamustaso" text_body_template: | Pahoittelut, sähköpostiviestiäsi tänne: %{destination} (otsikolla %{former_title}) ei voitu toimittaa. Tilisi luottamustaso ei ole riittävä, jotta saisit lähettää uusia ketjuja tähän sähköpostiosoitteeseen. Jos uskot, että tämä johtuu virheestä, ota yhteyttä henkilökuntaan. - email_reject_no_account: - subject_template: "[%{site_name}] Sähköpostiongelma -- Tuntematon tili" + email_reject_inactive_user: + subject_template: "[%{site_name}] Sähköpostiongelma -- Aktivoimaton käyttäjä" text_body_template: | Pahoittelemme, mutta sähköpostin lähettäminen tänne %{destination} (otsikolla %{former_title}) ei onnistunut. - Tälle sähköpostiosoitteelle ei löydy käyttäjätiliä. Yritä lähettää sähköposti toisesta osoitteesta tai ota yhteyttä henkilökuntaan. + Käyttäjätiliä tällä sähköpostiosoitteella ei ole aktivoitu. Aktivoi käyttäjätili ennen sähköpostien lähettämistä. + email_reject_blocked_user: + subject_template: "[%{site_name}] Sähköpostiongelma-- Estetty käyttäjä" + text_body_template: | + Pahoittelemme, mutta sähköpostiviesetisi tänne %{destination} (otsikolla %{former_title}) ei onnistunut. + + Käyttäjätili tällä sähköpostiosoitteella on estetty. + email_reject_reply_user_not_matching: + subject_template: "[%{site_name}] Sähköpostiongelma -- Käyttäjä ei täsmää" + text_body_template: | + Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (titled %{former_title}) ei onnistunut. + + Viestisi ei saapunut siitä sähköpostiosoitteesta josta odotimme, joten emme voineet olla varmoja lähettäjästä. Kokeile lähettää viestisi toisesta sähköpostiosoitteesta tai ota yhteyttä henkilökuntaan. + email_reject_no_account: + subject_template: "[%{site_name}] Sähköpostiongelma -- Tuntematon tili" + text_body_template: | + Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (titled %{former_title}) ei onnistunut. + + Sähköpostiosoitteesi ei vastaa yhtäkään käyttäjistä. Kokeile lähettää viestisi toisesta sähköpostiosoitteesta tai ota yhteyttä henkilökuntaan. email_reject_empty: subject_template: "[%{site_name}] Sähköpostiongelma -- Ei sisältöä" + text_body_template: "Pahoittelemme, mutta sähköpostin lähettäminen tänne %{destination} (otsikolla %{former_title}) ei onnistunut.\n\nEmme löytäneet sähköpostiviestistäsi sisältöä. \n\nJos saat tämän viestin ja viestisi _sisälsi_ sisältöä, yritä uudestaan yksinkertaisemmalla muotoilulla.\n\n" email_reject_parsing: subject_template: "[%{site_name}] Sähköpostiongelma -- Tunnistamaton sisältö" text_body_template: | @@ -1497,13 +1574,19 @@ fi: Pahoittelut, sähköpostiviestiäsi tänne: %{destination} (otsikolla %{former_title}) ei voitu toimittaa. Tililläsi ei ole riittäviä oikeuksia, jotta saisit lähettää uusia ketjuja tälle alueelle. Jos uskot, että tämä johtuu virheestä, ota yhteyttä henkilökuntaan. - email_reject_post_error: + email_reject_strangers_not_allowed: + subject_template: "[%{site_name}] Sähköpostiongelma -- Pääsy estetty" + text_body_template: | + Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (titled %{former_title}) ei onnistunut. + + Alueelle jolle lähetit viestin voivat kirjoittaa ne, joilla on käypä käyttäjätunnus ja sähköpostiosoite. Jos uskot tämän olevan virhe, ota yhteyttä henkilökuntaan. + email_reject_invalid_post: subject_template: "[%{site_name}] Sähköpostiongelma -- Lähetysvirhe" text_body_template: | - Pahoittelemme, mutta sähköpostin lähettäminen tänne %{destination} (otsikolla %{former_title}) ei onnistunut. + Pahoittelemme: sähköpostiviestisi kohteeseen %{destination} (titled %{former_title}) ei toiminut odotetusti. - Joitain mahdollisia syitä: monimutkainen muotoilu, liian suuri tai liian pieni viesti. Yritä uudelleen, tai lähetä viesti nettisivun kautta jos ongelma jatkuu. - email_reject_post_error_specified: + Mahdollisia syitä ovat muuan muassa: ei-tuettu muotoilu, liian suuri viesti, liian pieni viesti. Ole hyvä ja yritä uudelleen; voit myös lähettää viestisi sivuston kautta, jos tämä ongelma ei vaikuta poistuvan. + email_reject_invalid_post_specified: subject_template: "[%{site_name}] Sähköpostiongelma -- Lähetysvirhe" text_body_template: | Pahoittelemme, mutta sähköpostin lähettäminen tänne %{destination} (otsikolla %{former_title}) ei onnistunut. @@ -1513,24 +1596,36 @@ fi: %{post_error} Jos voit korjata ongelman, yritä uudelleen. - email_reject_reply_key: - subject_template: "[%{site_name}] Sähköpostiongelma -- Tuntematon vastausavain" + email_reject_rate_limit_specified: + subject_template: "[%{site_name}] Sähköpostiongelma -- Rajat" + text_body_template: | + Pahoittelemme, mutta sähköpostiviesetisi tänne %{destination} (otsikolla %{former_title}) ei onnistunut. + + Syy: %{rate_limit_description} + email_reject_invalid_post_action: + subject_template: "[%{site_name}] Sähköpostiongelma -- Kielletty viestitoiminto" text_body_template: | Pahoittelemme, mutta sähköpostin lähettäminen tänne %{destination} (otsikolla %{former_title}) ei onnistunut. - Annettu vastausavain on väärä tai tuntematon, joten emme pystyneet selvittämään mihin tämä sähköposti lähetettiin vastauksena. Ota yhteys henkilökuntaan. - email_reject_destination: + Toimintoa ei tunnistettu. Yritä uudelleen tai lähetä viesti nettisivun kautta, jos ongelma jatkuu. + email_reject_reply_key: + subject_template: "[%{site_name}] Sähköpostiongelma -- Tuntematon vastausavain" + text_body_template: | + Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (titled %{former_title}) ei onnistunut. + + Sähköpostiviestin vastaustunniste, engl. 'reply key', ei ole kelvollinen, minkä vuoksi ei tiedetä, mihin asiaan viestisi oli tarkoitus vastata. Ota yhteyttä henkilökuntaan. + email_reject_bad_destination_address: subject_template: "[%{site_name}] Sähköpostiongelma -- Tuntematon Vastaanottaja: -osoite" text_body_template: | - Pahoittelut, sähköpostiviestiäsi tänne: %{destination} (otsikolla %{former_title}) ei voitu toimittaa. + Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (titled %{former_title}) ei onnistunut. - Mitään sähköpostin kohdeosoitteista ei tunnistettu. Varmista, että sähköpostiosoite on "Vastaanottaja:"-rivillä (ei CC tai BCC) ja että yrität lähettää sähköpostia osoitteeseen, jonka palstan henkilökunta on antanut. + Viestisi kohdesähköpostiosoitteet olivat tuntemattomia. Ole hyvä ja varmistu, että lähetit viestin oikeaan osoitteeseen. email_reject_topic_not_found: subject_template: "[%{site_name}] Sähköpostiongelma -- Ketjua ei löytynyt" text_body_template: | - Pahoittelut, sähköpostiviestiäsi tänne: %{destination} (otsikolla %{former_title}) ei voitu toimittaa. + Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (titled %{former_title}) ei onnistunut. - Ketjua, johon vastaat ei enää ole. Ehkäpä se on poistettu? Jos uskot, että on tapahtunut virhe, ota yhteys palstan henkilökuntaan. + Ketjua johon yritit kirjoittaa ei ole enää olemassa - ehkä se poistettiin? Jos uskot tömön olevan virhe, ota yhteyttä henkilökuntaan. email_reject_topic_closed: subject_template: "[%{site_name}] Sähköpostiongelma -- Suljettu ketju" text_body_template: | @@ -1540,15 +1635,17 @@ fi: email_reject_auto_generated: subject_template: "[%{site_name}] Sähköpostiongelma -- Automaattivastaus" text_body_template: | - Pahoittelut, sähköpostiviestiäsi tänne: %{destination} (otsikolla %{former_title}) ei voitu toimittaa. + Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (titled %{former_title}) ei onnistunut. - Sähköpostiasi epäillään automaattisesti generoiduksi, jota emme hyväksy. Jos uskot, että on tapahtunut virhe, ota yhteys palstan henkilökuntaan. + Järjestelmä havaitsi viestisi olevan tietokoneen automaattisesti luoma, eikä sitä voitu siksi hyväksyä. Jos uskot tämän olevan virhe, ota yhteyttä henkilökuntaan. email_error_notification: subject_template: "[%{site_name}] Sähköpostiongelma -- POP-autentikoinnin virhe" text_body_template: | - Sähköpostin pollauksessa POP-palvelimelta tapahtui autentikointivirhe. + Sähköpostin pollauksessa POP-serveriltä tapahtui autentikointivirhe. - Varmista, että POP tunnukset on asetettu oikein [sivuston asetuksissa](%{base_url}/admin/site_settings/category/email). + Varmista, että olet konfiguroinut POP-tunnukset oikein [sivuston asetuksissa](%{base_url}/admin/site_settings/category/email). + + Jos POP-sähköpostitilille on nettikäyttöliittymä, voit joutua kirjautumaan sinne ja tarkistamaan asetukset. too_many_spam_flags: subject_template: "Uusi tili on estetty" text_body_template: | @@ -1561,32 +1658,26 @@ fi: Saadaksesi lisätietoa, tutustu [yhteisön ohjeisiin](%{base_url}/guidelines). blocked_by_staff: subject_template: "Tili estetty" - text_body_template: | - Hei, - - Tämä automaattinen viesti on lähetetty sivustolta %{site_name} kertoaksemme, että tilisi on estetty henkilökunnan toimesta. - - Saadaksesi lisätietoa, tutustu [yhteisön ohjeisiin](%{base_url}/guidelines). user_automatically_blocked: subject_template: "Uusi käyttäjä %{username} on estetty muiden käyttäjien liputuksen perusteella" text_body_template: | Tämä on automaattinen viesti. - Uusi käyttäjätili [%{username}](%{base_url}%{user_url}) on automaattisesti estetty, koska usea käyttäjä liputti käyttäjän %{username} viestin tai viestejä. + Uusi käyttäjätili [%{username}](%{user_url}) estettiin, koska monet liputtivat käyttäjän %{username} viestin tai viestejä. - Ole hyvä ja [tarkasta liput](%{base_url}/admin/flags). Jos %{username} on estetty virheellisesti, klikkaa poista esto -painiketta [käyttäjän hallinnointisivulta](%{base_url}%{user_url}). + [Tarkastele liputettuja viestejä](%{base_url}/admin/flags). Jos käyttäjä %{username} estettiin aiheettomasti, klikkaa poista esto -painiketta [tähän käyttäjään liittyvällä ylläpitäjän sivulla](%{user_url}). - Tätä kynnysarvoa voi muuttaa vaihtamalla asetuksen `block_new_user` arvoa. + Kynnysarvoa voi muuttaa säätämällä asetuksen `block_new_user` arvoa sivuston asetuksissa. spam_post_blocked: subject_template: "Uuden käyttäjän %{username} viestit on estetty toistuvien linkkien vuoksi" text_body_template: | - Tämä on automaattinen viesti + Tämä on automaattisesti luotu viesti. - Uusi käyttäjä [%{username}](%{base_url}%{user_url}) yritti luoda useita viestejä, jotka sisälsivät linkkejä osoitteeseen %{domains}, mutta nämä viestit estettiin roskapostin välttämiseksi. Käyttäjä voi edelleen luoda uusia viestejä, joissa ei ole linkkejä osoitteeseen %{domains}. + Uusi käyttäjä [%{username}](%{user_url}) yritti luoda useita viestejä, jotka sisälsivät linkkejä osoitteeseen %{domains}, mutta jotka estettiin roskapostin välttämiseksi. Käyttäjä voi edelleen luoda viesteijä, joissa ei ole linkkejä näihin osoitteisiin %{domains}. - Ole hyvä ja [tarkasta käyttäjä](%{base_url}%{user_url}). + [Tarkasta käyttäjätili](%{user_url}). - Tätä toimintoa voi muokata vaihtamalla asetuksia `newuser_spam_host_threshold` ja `white_listed_spam_host_domains` sivuston asetuksissa. + Tätä toimintoa voi muokata vaihtamalla asetuksia `newuser_spam_host_threshold` `white_listed_spam_host_domains` sivuston asetuksissa. unblocked: subject_template: "Tili avattu" text_body_template: | @@ -1606,49 +1697,90 @@ fi: download_remote_images_disabled: subject_template: "Linkattujen kuvien lataaminen on otettu pois käytöstä" text_body_template: "Asetus `download_remote_images_to_local` on otettu pois käytöstä, koska vapaan tilan rajoitus `download_remote_images_threshold` saavutettiin." + unsubscribe_link: | + Jos et enää halua ilmoituksia tästä ketjusta, [klikkaa tätä](%{unsubscribe_url}). Jos et halua sähköposti-ilmoituksia, muuta [tilisi asetuksia](%{user_preferences_url}). + unsubscribe_via_email_link: | + tai, [klikkaa tästä](mailto:reply@%{hostname}?subject=unsubscribe), jos et halua näitä viestejä sähköpostiisi. subject_re: "VS:" subject_pm: "[YV]" user_notifications: previous_discussion: "Edelliset vastaukset" + reached_limit: + one: "VAROITUS: Olet saavuttanut päivittäisen rajan sähköpostien määrälle. Seuraavia sähköposti-ilmoituksia ei lähetetä." + other: "VAROITUS: Sinulle on lähetetty tänään %{count} sähköpostia, joka on päivittäinen raja sähköpostien määrälle. Seuraavia sähköposti-ilmoituksia ei lähetetä." + in_reply_to: "Vastauksena" unsubscribe: title: "Peru tilaus" description: "Etkö halua vastaanottaa näitä sähköposteja? Ei hätää! Klikkaa alta peruaksesi tilauksen välittömästi:" - reply_by_email: "Vastataksesi, vastaa tähän sähköpostiin tai vieraile selaimella osoitteessa %{base_url}%{url}." - visit_link_to_respond: "Vastataksesi, vieraile selaimella osoitteessa %{base_url}%{url}." + reply_by_email: "Vastaa [vierailemalla ketjussa](%{base_url}%{url}) tai vastaamalla tähän sähköpostiin." + reply_by_email_pm: "Vastaa [vierailemalla ketjussa](%{base_url}%{url}) tai vastaamalla tähän sähköpostiin." + only_reply_by_email: "Vastaa vastaamalla tähän viestiin" + visit_link_to_respond: "Vastaa [vierailemalla ketjussa](%{base_url}%{url})" + visit_link_to_respond_pm: "Vastaa [vierailemalla ketjussa](%{base_url}%{url})." posted_by: "Käyttäjältä %{username} %{post_date}" + invited_to_private_message_body: | + %{username} kutsui sinut viestiketjuun + + > **%{topic_title}** + > + > %{topic_excerpt} + + sivustolla + + > %{site_title} -- %{site_description} + invited_to_topic_body: | + %{username} kutsui sinut keskusteluun + + > **%{topic_title}** + > + > %{topic_excerpt} + + sivustolla + + > %{site_title} -- %{site_description} user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} kutsui sinut viestiin '%{topic_title}'" - text_body_template: |2 + text_body_template: | + %{header_instructions} - %{username} kutsui sinut viestiin + %{message} - > **%{topic_title}** - > - > %{topic_excerpt} + --- + %{respond_instructions} + user_invited_to_private_message_pm_staged: + subject_template: "[%{site_name}] %{username} kutsui sinut yksityiseen keskusteluun '%{topic_title}'" + text_body_template: | + %{header_instructions} - sivustolla + %{message} - > %{site_title} -- %{site_description} - - Seuraa tätä linkkiä nähdäksesi viestin: %{base_url}%{url} + --- + %{respond_instructions} user_invited_to_topic: - subject_template: "[%{site_name}] %{username} kutsui sinut viestiin '%{topic_title}'" - text_body_template: |2 + subject_template: "[%{site_name}] %{username} kutsui sinut ketjuun '%{topic_title}'" + text_body_template: | + %{header_instructions} - %{username} kutsui sinut keskusteluun + %{message} - > **%{topic_title}** - > - > %{topic_excerpt} - - sivustolla - - > %{site_title} -- %{site_description} - - Seuraa tätä linkkiä nähdäksesi keskustelun: %{base_url}%{url} + --- + %{respond_instructions} user_replied: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_replied_pm: + subject_template: "[%{site_name}] [YV] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1658,6 +1790,19 @@ fi: user_quoted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_linked: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1666,17 +1811,31 @@ fi: %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: |+ + text_body_template: | + %{header_instructions} + %{message} %{context} --- %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} + + %{context} + + --- + %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1686,10 +1845,20 @@ fi: user_posted_pm: subject_template: "[%{site_name}] [YV] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} + --- + %{respond_instructions} + user_posted_pm_staged: + subject_template: "%{optional_re}%{topic_title}" + text_body_template: |2 + + %{message} + --- %{respond_instructions} digest: @@ -1738,12 +1907,29 @@ fi: Klikkaa seuraavaa linkkiä asettaaksesi salasanan uudelle tunnuksellesi: %{base_url}/users/password-reset/%{email_token} - authorize_email: + confirm_new_email: subject_template: "[%{site_name}] Vahvista uusi sähköpostiosoite" text_body_template: | Vahvista uusi sähköpostiosoite sivustolle %{site_name} klikkaamalla alla olevaa linkkiä: %{base_url}/users/authorize-email/%{email_token} + confirm_old_email: + subject_template: "[%{site_name}] Vahvista nykyinen sähköpostiosoiteesi" + text_body_template: |+ + Ennen kuin voit vaihtaa sähköpostiosoitteesti, meidän täytyy varmistaa, että hallinnoit nykyistä sähköpostiosoitetta. Kun olet suorittanut tämän, varmistamme vielä uuden sähköpostiosoitteenkin. + + Vahvista sähköpostiosoitteesti sivustolle %{site_name} klikkaamalla linkkiä: + + %{base_url}/users/authorize-email/%{email_token} + + notify_old_email: + subject_template: "[%{site_name}] Sähköpostiosoitteesi on vaihdettu" + text_body_template: | + Tämä on automaattinen vahvistus siitä, että sähköpostiosoitteesi sivustolle %{site_name} on vaihdettu. Jos on tapahtunut virhe, ota yhteyttä sivuston ylläpitäjään. + + Sähköpostiosoitteeksesi on vaihdettu: + + %{new_email} signup_after_approval: subject_template: "Sinut on hyväksytty sivustolle %{site_name}!" text_body_template: | @@ -1773,7 +1959,7 @@ fi: Jos linkkiä ei voi klikata, yritä kopioida ja liittää se selaimen osoiteriville. page_not_found: - title: "Pyytämääsi sivua ei ole tai se on yksityinen." + title: "Hups! Sivua ei ole tai se on yksityinen." popular_topics: "Suosittuja" recent_topics: "Tuoreimpia" see_more: "Lisää" @@ -1792,6 +1978,7 @@ fi: unauthorized: "Pahoittelut, tiedostomuoto ei ole sallittu (sallitut tiedostopäätteet: %{authorized_extensions})." pasted_image_filename: "Liitetty kuva" store_failure: "Latauksen #%{upload_id} käyttäjälle #%{user_id} tallentaminen epäonnistui." + file_missing: "Pahoittelut, sinun täytyy valita tiedosto joka ladataan." attachments: too_large: "Pahoittelut, tiedosto jonka latausta yritit on liian suuri ( suurin tiedostokoko on %{max_size_kb}KB)." images: @@ -1811,6 +1998,7 @@ fi: post_deleted: "kirjoittaja poisti viestin" user_suspended: "käyttäjä hyllytettiin" already_read: "käyttäjä on jo lukenut tämän viestin" + exceeded_limit: "Ylitti max_emails_per_day_per_user" message_blank: "viesti on tyhjä" message_to_blank: "message.to on tyhjä" text_part_body_blank: "text_part.body on tyhjä" @@ -1828,10 +2016,272 @@ fi: Muokkaa ketjun aloitusviestiä muokataksesi sivun %{page_name} sisältöä. guidelines_topic: title: "UKK/Ohjeet" + body: | + + + ## [Tämä on sivistynyt paikka julkiselle keskustelulle](#civilized) + + Kohtele tätä palstaa kuin yleistä puistoa. Me olemme yhteisöpalvelu — keskusteluissa voi jakaa taitoja, tietoa ja intohimoja. + + Nämä ohjeet eivät ole kaiken kattavat vaan pikemminkin suuntaviivat terveen järjen käyttöön pohjautuvassa yhteisössä. Noudattamalla niitä tämä palsta pysyy siistinä ja toimivana alustana sivistyneelle julkiselle vuorovaikutukselle. + + + + ## [Edistä keskustelua](#improve) + + Autat tekemään tästä hyvän keskustelupalstan pyrkimällä aina edistämään keskustelua, edes hieman. Jos et ole ihan varma siitä, tuoko viestisi lisäarvoa keskusteluun, mieti hetki mitä haluat sanoa ja yritä uudelleen hieman myöhemmin. + + Aiheet, joista täällä keskustellaan ovat meille tärkeitä, ja edellytämme sinun käyttäytyvän niin kuin ne olisivat sitä myös sinulle. Kunnioita keskusteluita ja keskustelijoita, vaikka olisit eri mieltä jostain. + + Yksi edistävä tapa on tutustua palstalla käynnissä olevaan keskusteluun. Vietä hetki selailemalla palstaa ennen kuin lähetät viestin tai aloitat uuden ketjun, niin sinulla on parempi mahdollisuus löytää samanhenkistä seuraa. + + + + ## [Ole rakentava, vaikka olisit eri mieltä](#agreeable) + + Saatat haluta esittää eriävän mielipiteen johonkin liittyen. Se on sallittua. Muista kuitenkin _kritisoida esitettyjä ajatuksia, älä niiden esittäjiä_. Vältä: + + * nimittelyä. + * henkilökohtaisuuksiin menemistä. + * toisen käyttäjän viestin sävyn arviointia: keskity sisältöön. + * poteroitumista. + + Tarjoa sen sijaan perusteltuja, keskustelua edistäviä vasta-argumentteja. + + + + ## [Tekemisilläsi on väliä](#participate) + + Keskustelut vaikuttavat palstan yleismielialaan. Vaikutat parhaiten yhteisön tulevaisuuteen osallistumalla niihin keskusteluihin, jotka tekevät tästä kiintoisan paikan — ja välttämällä niitä, joilla on päinvastainen vaikutus. + + Discoursen työkalut mahdollistavat sen, että yhteisö kollektiivisesti tunnistaa parhaan (ja huonoimman) sisällön: suosikit, kirjanmerkit, tykkäykset, liputukset, vastaukset, muokkaukset ja niin edelleen. Käyttämällä niitä parannat omaa käyttäjäkokemustasi ja samalla kaikkien muidenkin. + + Yritetään jättää puisto parempaan kuntoon kuin se oli tullessa. + + + + ## [Jos havaitset ongelman, liputa se](#flag-problems) + + Valvojilla on erityisasema; he ovat vastuussa palstasta. Mutta niin olet sinäkin. Avullasi valvojat voivat olla keskustelun ohjaajia eivätkä talonmiehiä ja poliiseja. + + Jos havaitset huonoa käytöstä, älä vastaa siihen. Huomiointi vain yllyttää sitä, kuluttaa voimiasi ja tuhlaa kaikkien aikaa. _Liputa se_. Jos tarpeeksi moni liputtaa, asiaan puututaan, joko palstan automaation tai valvojien toimesta. + + Yhteisömme ylläpitämiseksi valvojat pidättävät oikeuden poistaa sisältöä tai käyttäjätunnuksia harkintansa mukaan kaikissa tilanteissa. Valvojat eivät ennakkosensuroi viestejä millään tapaa; valvojat tai ylläpito ei ota vastuuta mistään, mitä yhteisö julkaisee. + + + + ## [Ole aina kohtelias](#be-civil) + + Mikään ei häiritse sivistynyttä keskustelua niin kuin töykeys: + + * Ole kohtelias. Älä kirjoita mitään, minkä voi järkevä ihminen tulkita hyökkääväksi, loukkaavaksi tai vihapuheeksi. + * Pidä palsta siistinä. Älä levitä säädyttömyyksiä tai seksuaalista materiaalia. + * Kunnioita kanssaihmisiä. Älä kiusaa tai ärsytä ketään, esiinny toisena tai kerro heidän yksityisyytensä piiriin kuuluvista asioista. + * Kunnioita palstaa. Älä levitä roskapostia tai muullakaan tavoin tärvele sitä. + + Nämä eivät ole tarkkarajaiset säännöt — vältä kaikkea kiellettyihin asioihin edes _viittaavaa_. Jos olet epävarma, kysy itseltäsi miltä tuntuisi, jos viestisi olisi lainattuna aamun sanomalehden kanteen. + + Tämä on julkinen palsta ja hakukoneet johdattavat näihin keskusteluihin. Kiinnitä huomiota kielenkäyttöön ja linkkien ja kuvien tietoturvaan for family and friends. + + + + ## [Ylläpidä järjestystä](#keep-tidy) + + Keskity laittamaan viestit oikeisiin paikkoihin, jotta voimme keskittyä enemmän keskustelemiseen ja vähemmän jälkien siivoamiseen. Joten: + + * älä avaa ketjua väärälle alueelle. + * älä kirjoita samaa asiaa moniin ketjuihin. + * älä kirjoita sisällöttömiä viestejä. + * älä johdata ketjua sivuraiteille. + * älä allekirjoita viestejä — lähetyttyihin viesteihin liitetään käyttäjätiedot joka tapauksessa. + + Sen sijaan, että kirjoittaisit “+1” or “Samaa mieltä”, käytä tykkäysnappia. Olemassa olevan ketjun sivuraiteille johdattamisen sijaan käytä Vastaa aihetta sivuavassa ketjussa -toimintoa. + + + + ## [Lähetä vain omia tuotoksiasi](#stealing) + + Älä julkaise mitään toisen omistamaa digitaalista sisältöä ilman lupaa. Älä julkaise kertomuksia tekijänoikeusrikkomuksista tai jaa linkkejä tai keinoja toisen tahon immateriaalioikeuksien (ohjelmistot, videot, äänitteet, kuvat) rikkomiseksi, tai mitään muutakaan lainvastaista. + + + + ## [Sinä pidät pyörät pyörimässä](#power) + + Tätä sivustoa pyörittää [avulias palstahenkilökunta](/about) sekä *me kaikki*, yhteisö. Jos sinulla on kysyttävää palstan toiminnasta tai ehdotuksia sen suhteen, avaa uusi ketju [sivuston palautealueelle](/c/site-feedback) niin käydään asiaa yhdessä läpi! Jos kyseessä on kriittinen ja kiireellinen ongelma, jota ei voida käsitellä palauteosion tai liputuksen kautta, ota yhteyttä [henkiökunnan sivun](/about) kautta. + + + + ## [Käyttöehdot](#tos) + + Kyllä, lakikieli on tylsää, mutta meidän on suojeltava itseämme – ja siinä sivussa sinua ja sinun tietojasi – epäsuotuisia tahoja vastaan. Palstalla on [käyttöehdot](/tos), jotka säätelevät sinun (ja meidän) toimintaa and oikeuksia sisältöön, yksityisyyteen ja lakeihin liittyen. Käyttääksesi palvelua sinun on hyväksyttävä [käyttöehdot](/tos). tos_topic: title: "Käyttöehdot" privacy_topic: title: "Rekisteriseloste" + static: + search_help: | +

    Vinkkejä

    +

    +

      +
    • Otsikon vastaavuudet ovat etusijalla – jos olet epävarma, etsi otsikkoa
    • +
    • Parhaat tulokset saa uniikeilla ja harvinaisilla sanoilla
    • +
    • Voit kokeilla etsiä tietyn alueen, ketjun tai käyttäjän viesteistä
    • +
    +

    +

    Options

    +

    + + + + + + + +
    order:viewsorder:latestorder:likes
    status:openstatus:closedstatus:archivedstatus:norepliesstatus:single_user
    category:foouser:foogroup:foobadge:foo
    in:likesin:postedin:watchingin:trackingin:private
    in:bookmarksin:firstin:pinnedin:unpinned
    posts_count:numbefore:days or dateafter:days or date
    +

    +

    Esimerkkejä

    +

    +

      +
    • rainbows category:parks status:open order:latest etsii alueelta "parks" ketjuja, joissa esiintyy sana "rainbows" ja joita ei suljettu tai arkistoitu, ja esittää ylimmäisinä ne ketjut, joihin on viimeksi kirjoitettu.
    • +
    • rainbows category:"parks and gardens" in:bookmarks etsii alueelta "parks and gardens" kirjanmerkkeihin lisäämiäsi ketjuja, joissa esiintyy sana "rainbows".
    • +
    +

    + badges: + editor: + name: Muokkaaja + description: Ensimmäinen viestin muokkaus + long_description: | + Tämä arvomerkki myönnetään, kun ensimmäistä kertaa muokkaat viestiäsi. Viestiä ei voi muokata kuin määrätyn ajan viestin lähettämisen jälkeen, mutta sinä aikana muokkaaminen on aina hyvä ajatus. Voit parannella viestiä, korjata pieniä virheitä tai lisätä jotakin, mikä pääsi unohtumaan viestin kirjoittamisen hetkellä. Muokkaa viesteistäsi entistäkin parempia! + basic_user: + name: Haastaja + description: Myönnetty kaikki palstan välttämättömimmät toiminnot + long_description: | + Tämä arvomerkki myönnetään, kun nouset luottamustasolle 1. Kiitos siitä, että olet päättänyt antaa palstalle mahdollisuuden ja lukenut muutamaa ketjua ottaaksesi selvää, mistä yhteisössä on kyse. Uuden käyttäjän rajoituksia on nyt poistettu; sait käyttöösi välttämättömimmät palstan toiminnot kuten yksityisviestit, liputtamisen, wiki-viestien muokkaamisen ja oikeuden laittaa viestiin useampia kuvia ja linkkejä. + member: + name: Konkari + description: Myönnetty kutsut, ryhmäviestit ja lisää tykkäyksiä + long_description: | + Tämä arvomerkki myönnetään, kun nouset luottamustasolle 2. Kiitos siitä, että olet ollut keskuudessamme viikkojen ajan ja tullut osaksi yhteisöä. Voit nyt lähettää kutsuja käyttäjäsivultasi ja ketjuista, luoda ryhmäviestejä ja käytössäsi on muutama tykkäys enemmän päivää kohden. + regular: + name: Mestari + description: Myönnetty ketjujen siirto toiselle alueelle ja uudelleen nimeäminen, hakukoneiden seuraamat linkit, wiki-viestit ja lisää tykkäyksiä + long_description: | + Tämä arvomerkki myönnetään, kun nouset luottamustasolle 3. Kiitos kun olet ollut tärkeä osa yhteisöä kuukausien ajan. Olet yksi innokkaimmista lukijoista ja luotettava sisällön tuottaja, ja olet tekemässä yhteisöstä niin hienoa kuin se on. Voit nyt siirtää alueelta toiselle ja uudelleennimetä ketjuja, roskapostiliputuksesi ovat tehokkaampia, pääset lounge-alueelle ja käytössäsi on selvästi enemmän tykkäyksiä päivää kohden. + leader: + name: Johtaja + description: Myönnetty minkä tahansa viestin muokkaaminen, kiinnittäminen, sulkeminen, arkistoiminen, pilkkominen ja yhdistäminen ja lisää tykkäyksiä + long_description: | + Tämä arvomerkki myönnetään, kun nouset luottamustasolle 4. Palstan henkilökunta on valinnut sinut johtajaksi. Näytät muille positiivista esimerkkiä sanoin ja teoin. Voit nyt muokata mitä tahansa viestiä ja käytössäsi on yleiset valvojatyökalut, joilla voit hallita ketjuja kuten kiinnittäminen, sulkeminen, listauksista poistaminen, arkistoiminen, pilkkominen ja yhdistäminen, ja käytössäsi on paljon enemmän tykkäyksiä päivää kohden. + welcome: + name: Tervetuloa + description: Sai tykkäyksen + long_description: | + Tämä arvomerkki myönnetään, kun viestistäsi tykätään ensi kertaa. Onnittelut, olet tuottanut jotakin, mitä toinen käyttäjä on pitänyt mielenkiintoisena, hauskana tai hyödyllisenä! + autobiographer: + name: Omaelämäkerta + description: Täytti käyttäjätiedot + long_description: | + Tämä arvomerkki myönnetään , kun täytät käyttäjätiedot ja valitset profiilikuvan. Kertomalla hieman itsestäsi ja kiinnostuksen kohteistasi edistät yhteisöllisyyttä. Liity meihin! + anniversary: + name: Vuosipäivä + description: Aktiivinen jäsen vuoden ajan, kirjoittanut ainakin yhden viestin + long_description: | + Tämä arvomerkki myönnetään, kun olet ollut jäsen vuoden ajan ja kirjoittanut sinä aikana ainakin yhden viestin. Kiitos, kun olet yhä keskuudessamme ja antanut panoksesi yhteisön hyväksi. Emme pärjäisi ilman sinua. + nice_post: + name: Hyvä vastaus + description: Vastaus sai 10 tykkäystä + long_description: | + Tämä arvomerkki myönnetään, kun vastauksesi saa 10 tykkäykstä. Teit sillä todellisen vaikutuksen yhteisöön ja edistit keskustelua! + good_post: + name: Erinomainen vastaus + description: Vastaus sai 25 tykkäystä + long_description: | + Tämä arvomerkki myönnetään, kun vastauksesi saa 25 tykkäystä. Vastauksesi oli poikkeuksellinen ja teki keskustelusta todella paljon paremman! + great_post: + name: Loistava vastaus + description: Vastaus sai 50 tykkäystä + long_description: | + Tämä arvomerkki myönnetään, kun vastauksesi saa 50 tykkäystä. Vau! Vastauksesi oli innoittava, hulvaton tai oivaltava, ja yhteisö rakasti sitä. + nice_topic: + name: Hyvä ketju + description: Ketjunavaus sai 10 tykkäystä + long_description: | + Tämä arvomerkki myönnetään, kun luomasi ketju saa 10 tykkäystä. Aloitit kiintoisan keskustelun, josta yhteisö nautti! + good_topic: + name: Erinomainen ketju + description: Ketjunavaus sai 25 tykkäystä + great_topic: + name: Loistava ketju + description: Ketjunavaus sai 50 tykkäystä + nice_share: + name: Hyvä jako + description: Jakoi viestin, ja linkin kautta saapui 25 vierailijaa + good_share: + name: Erinomainen jako + description: Jakoi viestin, ja linkin kautta saapui 300 vierailijaa + great_share: + name: Loistava jako + description: Jakoi viestin, ja linkin kautta saapui 1000 vierailijaa + first_like: + name: Ensimmäinen tykkäys + description: Tykkäsi viestistä + first_flag: + name: Ensimmäinen liputus + description: Liputti viestin + promoter: + name: Markkinoija + description: Kutsui käyttäjän + campaigner: + name: Kampanjoija + description: Kutsui kolme haastajaa (luottamustaso 1) + champion: + name: Kampanjapäällikkö + description: Kutsui viisi konkaria (luottamustaso 2) + first_share: + name: Ensimmäinen jako + description: Jakoi viestin + first_link: + name: Ensimmäinen linkki + description: Linkitti toiseen ketjuun + first_quote: + name: Ensimmäinen lainaus + description: Lainasi viestiä + read_guidelines: + name: Luki ohjeet + description: Luki palstan säännöt + reader: + name: Lukutoukka + description: Luki jokaisen viestin ketjusta, jossa on enemmän kuin 100 vastausta + popular_link: + name: Suosittu linkki + description: Linkitti ulkoiselle sivustolle, ja linkkiä klikattiin 50 kertaa + hot_link: + name: Kuuma linkki + description: Linkitti ulkoiselle sivustolle, ja linkkiä klikattiin 300 kertaa + famous_link: + name: Kuuluisa linkki + description: Linkitti ulkoiselle sivustolle, ja linkkiä klikattiin 1000 kertaa + appreciated: + name: Arvostettu + description: 20 viestiä sai tykkäyksen + respected: + name: Kunnioitettu + description: 100 viestiä sai ainakin 2 tykkäystä + admired: + name: Ihailtu + description: 300 viestiä sai ainakin 5 tykkäystä + out_of_love: + name: Rakkauden rajat + description: Tykkäsi 50 kertaa päivän aikana + thank_you: + name: Kiitos + description: 20 viestistä on tykätty ja on tykännyt 10 viestistä + gives_back: + name: Vastavuoroinen + description: 100 viestistä on tykätty ja on tykännyt 100 viestistä + empathetic: + name: Empaattinen + description: 500 viestistä on tykätty ja on tykännyt 1000 viestistä admin_login: success: "Sähköposti lähetetty" error: "Virhe!" @@ -1842,3 +2292,10 @@ fi: performance_report: initial_post_raw: Tämä ketju sisältää päivittäisiä suorituskykyrapotteja sivustoltasi initial_topic_title: Sivuston suorituskykyraportit + topic_invite: + user_exists: "Pahoittelut, tämä käyttäjä on jo kutsuttu. Voit kutsua toisen käyttäjän ketjuun vain yhden kerran." + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml index 0d25be8244c..7f68d0d66de 100644 --- a/config/locales/server.fr.yml +++ b/config/locales/server.fr.yml @@ -10,18 +10,41 @@ fr: short_date_no_year: "D MMM" short_date: "D MMM, YYYY" long_date: "D MMMM YYYY H:mm" + datetime_formats: &datetime_formats + formats: + short: "%d-%m-%Y" + short_no_year: "%B %-d" + date_only: "%B %-d, %Y" + date: + month_names: [null, janvier, février, mars, avril, mai, juin, juillet, août, septembre, octobre, novembre, décembre] + <<: *datetime_formats title: "Discourse" topics: "Sujets" posts: "messages" loading: "Chargement" powered_by_html: 'Propulsé par Discourse, le rendu est meilleur avec le JavaScript activé' log_in: "Se connecter" - via: "%{username} via %{site_name}" - is_reserved: "est réservé" purge_reason: "Supprimé automatiquement comme compte abandonné, non activé" disable_remote_images_download_reason: "Le téléchargement des images externes a été désactivé faute de place suffisante sur le disque." anonymous: "Anonyme" - errors: + emails: + incoming: + default_subject: "Courriel arrivant de %{email}" + show_trimmed_content: "Montrer le contenu raccourci" + errors: + empty_email_error: "Arrive quand le courriel reçu était vide." + no_message_id_error: "Arrive quand le courrier n'a pas d'en-tête \"Message-Id\"." + auto_generated_email_error: "Se produit lorsque le header 'precedence' est : list, junk, bulk ou auto-reply, ou lorsque n'importe quel autre header contient : auto-submitted, auto-replied ou auto-generated." + no_body_detected_error: "Arrive quand il est impossible d'extraire le corps du message et qu'il n'y a pas de pièces-jointes." + inactive_user_error: "Arrive quand l'expéditeur n'est pas actif." + blocked_user_error: "Arrive quand l'expéditeur a été bloqué." + bad_destination_address: "Arrive quand aucune des adresses de courriel dans les champs To/Cc/Bcc ne correspondent à une adresse de courriel entrante configurée." + strangers_not_allowed_error: "Arrive quand un utilisateur a essayé de créer un nouveau sujet dans une catégorie dans laquelle il n'est pas membre." + insufficient_trust_level_error: "Se produit lorsqu'un utilisateur a essayé de créer un nouveau sujet dans une catégorie dans laquelle il n'a pas le niveau de confiance nécessaire." + reply_user_not_matching_error: "Arrive quand une réponse est venue d'une adresse de courriel différente de celle où a été envoyée la notification." + topic_not_found_error: "Arrive quand quelqu'un répond à un sujet qui a été supprimé." + topic_closed_error: "Arrive quand quelqu'un répond mais le sujet lié a été fermé." + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "est limité à %{max} caractères maximum; il y en a %{length}." @@ -37,8 +60,10 @@ fr: exclusion: est réservé greater_than: doit être supérieure à %{count} greater_than_or_equal_to: doit être supérieur ou égal à %{count} + has_already_been_used: "a déjà été utilisée" inclusion: n'est pas inclus dans la liste invalid: est invalide + is_invalid: "n'est pas valide; merci d'être un peu plus descriptif" less_than: doit être inférieure à %{count} less_than_or_equal_to: doit être inférieur ou égal à %{count} not_a_number: n'est pas un nombre @@ -69,8 +94,9 @@ fr: min_username_length_exists: "Il n'est pas possible de définir une longeur minimale de pseudo qui soit plus court qu'un pseudo qui existe déjà." min_username_length_range: "Il n'est pas possible de définir un minimum plus grand qu'un maximum." max_username_length_exists: "Il n'est pas possible de définir une longeur maximale de pseudo qui soit plus court qu'un pseudo qui existe déjà." - max_username_length_range: "Vous ne pouvez pas mettre le maximum sous le minimum" + max_username_length_range: "Il n'est pas possible de définir un maximum plus petit que le minimum." default_categories_already_selected: "Vous ne pouvez pas séléctionner une catégorie qui est utilisée dans une autre liste." + s3_upload_bucket_is_required: "Vous ne pouvez pas activer l'upload sur S3 avant d'avoir renseigné le 's3_upload_bucket'." bulk_invite: file_should_be_csv: "Le fichier envoyé doit être au format csv ou txt." backup: @@ -81,6 +107,8 @@ fr: not_found: "L'URL ou ressource demandée n'a pas été retrouvé." invalid_access: "Vous n'avez pas la permission de voir cette ressource." read_only_mode_enabled: "Le site est en mode lecture seule. Les interactions sont désactivées." + reading_time: "Temps de lecture" + likes: "J'aime" too_many_replies: one: "Nous sommes désolés, mais les nouveaux utilisateurs sont limités temporairement à 1 réponse par sujet." other: "Nous sommes désolés, mais les nouveaux utilisateurs sont limités temporairement à %{count} réponses par sujet." @@ -97,26 +125,26 @@ fr: replies: one: "1 réponse" other: "%{count} réponses" + no_mentions_allowed: "Désolé, vous ne pouvez pas mentionner d'autres utilisateurs." too_many_mentions: - zero: "Désolé, vous ne pouvez pas mentionner d'utilisateur." - one: "Désolé, vous ne pouvez mentionner qu'un seul utilisateur." - other: "Désolé, vous ne pouvez mentionner que %{count} utilisateurs." + one: "Désolé, vous ne pouvez mentionner qu'un utilisateur dans un message." + other: "Désolé, vous ne pouvez mentionner que %{count} utilisateurs dans un message." + no_mentions_allowed_newuser: "Désolé, les nouveaux utilisateurs ne peuvent pas mentionner d'autres utilisateurs." too_many_mentions_newuser: - zero: "Désolé, les nouveaux utilisateurs ne peuvent pas mentionner d'utilisateur." - one: "Désolé, les nouveaux utilisateurs ne peuvent mentionner qu'un seul utilisateur." - other: "Désolé, les nouveaux utilisateurs ne peuvent mentionner que %{count} utilisateurs." + one: "Désolé, les nouveaux utilisateurs ne peuvent mentionner qu'un utilisateur dans un message." + other: "Désolé, les nouveaux utilisateurs ne peuvent mentionner que %{count} utilisateurs dans un message." + no_images_allowed: "Désolé, les nouveaux utilisateurs ne peuvent pas ajouter d'image dans les messages." too_many_images: - zero: "Désolé, les nouveaux utilisateurs ne peuvent pas ajouter d'image." - one: "Désolé, les nouveaux utilisateurs ne peuvent ajouter qu'une seule image." - other: "Désolé, les nouveaux utilisateurs ne peuvent ajouter que %{count} images." + one: "Désolé, les nouveaux utilisateurs ne peuvent ajouter qu'une image dans un message." + other: "Désolé, les nouveaux utilisateurs ne peuvent ajouter que %{count} images dans un message." + no_attachments_allowed: "Désolé, les nouveaux utilisateurs ne peuvent pas ajouter de fichiers dans leurs messages." too_many_attachments: - zero: "Désolé, les nouveaux utilisateurs ne peuvent pas ajouter de fichiers dans leurs messages." one: "Désolé, les nouveaux utilisateurs ne peuvent ajouter qu'un fichier dans leurs messages." other: "Désolé, les nouveaux utilisateurs ne peuvent ajouter que %{count} fichiers dans leurs messages." + no_links_allowed: "Désolé, les nouveaux utilisateurs ne peuvent pas insérer de liens dans leurs messages." too_many_links: - zero: "Désolé, les nouveaux utilisateurs ne peuvent pas insérer de liens." - one: "Désolé, les nouveaux utilisateurs ne peuvent insérer qu'un seul lien." - other: "Désolé, les nouveaux utilisateurs ne peuvent insérer que %{count} liens." + one: "Désolé, les nouveaux utilisateurs ne peuvent insérer qu'un seul lien par message." + other: "Désolé, les nouveaux utilisateurs ne peuvent insérer que %{count} liens par message." spamming_host: "Désolé, vous ne pouvez pas insérer de lien vers ce domaine." user_is_suspended: "Les utilisateurs suspendus ne sont pas autorisés à poster de messages." topic_not_found: "Une erreur est survenue. Peut-être que ce sujet a été fermé ou supprimé pendant que vous le regardiez?" @@ -139,8 +167,10 @@ fr: rss_description: latest: "Sujets récents" hot: "Sujets populaires" + top: "Meilleurs sujets" posts: "Messages récents" too_late_to_edit: "Ce message a été créé il y a trop longtemps. Il ne peut plus être modifié ou supprimé." + revert_version_same: "La version actuelle est la même que la version vers laquelle vous essayez de revenir." excerpt_image: "image" queue: delete_reason: "Supprimé depuis la liste des messages en attente de validation" @@ -148,6 +178,10 @@ fr: errors: can_not_modify_automatic: "Vous ne pouvez pas modifier un groupe automatique" member_already_exist: "'%{username}' est déjà membre de ce groupe." + invalid_domain: "'%{domain}' n'est pas un domaine valide." + invalid_incoming_email: "'%{email}' n'est pas une adresse de courriel valide." + email_already_used_in_group: "'%{email}' est déjà utilisé par le groupe '%{group_name}'." + email_already_used_in_category: "'%{email}' est déjà utilisé par la catégorie '%{category_name}'." default_names: everyone: "tous" admins: "administrateurs" @@ -171,7 +205,7 @@ fr: - Incluez des mots fréquents dans votre sujet pour que les utilisateurs puissent le *retrouver*. Pour le regrouper avec des sujets liés, sélectionnez une catégorie. - Pour plus d'info, [jettez un œil au règlement de la communauté](/guidelines). Ce message apparaîtra uniquement pour vos premiers messages. + Pour plus d'info, [jettez un œil sur la charte de la communauté](/guidelines). Ce message apparaîtra uniquement pour vos premiers %{education_posts_text}. new-reply: | Bienvenue sur %{site_name} — **Merci de contribuer !** @@ -181,7 +215,7 @@ fr: - Les critiques constructives sont les bienvenues, mais critiquez les *idées*, pas les gens. - Pour plus d'informations, [consulter le règlement de la communauté](/guidelines). Cet encart apparaîtra pour votre premier %{education_posts_text}. + Pour plus d'informations, [consulter la charte de la communauté](/guidelines). Cet encart apparaîtra pour votre premier %{education_posts_text}. avatar: | ### Avez-vous pensé à une photo de profil ? @@ -220,9 +254,6 @@ fr: user_profile: bio_raw: "À propos de moi" errors: - messages: - is_invalid: "n'est pas valide; merci d'être plus descriptif" - has_already_been_used: "est déjà utilisé" models: topic: attributes: @@ -243,6 +274,7 @@ fr: attributes: hex: invalid: "n'est pas une couleur valide" + <<: *errors user_profile: no_info_me: "
    Le champs A Propos de moi de votre profil est vide, voulez vous le remplir ?
    " no_info_other: "
    %{name} n'a pas encore renseigné le champ A Propos de Moi de son profil
    " @@ -278,13 +310,15 @@ fr: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "A propos de la catégorie %{category}" - replace_paragraph: "[Remplacez ce premier paragraphe par une courte description de votre nouvelle catégorie. Ce texte apparaît dans la zone de sélection de catégorie, alors essayez de le maintenir en dessous de 200 caractères. Cette catégorie n'apparaîtra pas sur la page des catégories tant que vous modifiez ce texte ou jusqu'à ce qu'un sujet soit crée.]" - post_template: "%{replace_paragraph}\n\nUtilisez les paragraphes suivants pour une plus longue description, voire pour établir des règles. \n\nChoses à considérer avant toute réponse ou discussion :⏎\n\n- A quoi sert cette catégorie ? Pourquoi les utilisateurs choisiraient-ils cette catégorie pour leur discussion ?\n\n- En quoi elle est différente des autres catégories que nous avons déjà ?\n\n- Avons-nous besoin de cette catégorie ?\n\n- Devrions-nous fusionner celle-ci avec une autre catégorie, ou la diviser en plusieurs catégories ?\n" + replace_paragraph: "(Remplacez ce premier paragraphe par une brève description de votre nouvelle catégorie. Ce guide apparaîtra dans la zone de sélection de la catégorie, alors essayez de rester en dessous de 200 caractères. **Cette catégorie n'apparaîtra pas sur la page des catégories jusqu'à ce que vous ayez modifié cette description ou créé des sujets.**" + post_template: "%{replace_paragraph}\n\nUtilisez les paragraphes suivants pour une plus longue description, voire pour établir des règles.:\n\n- A quoi sert cette catégorie ? Pourquoi les utilisateurs choisiraient-ils cette catégorie pour leur discussion ?\n\n- En quoi elle est différente des autres catégories que nous avons déjà ?\n\n- Quels sujets devraient figurer dans cette catégorie ?\n\n- Avons-nous besoin de cette catégorie ? Devrions-nous fusionner celle-ci avec une autre catégorie ?\n" errors: uncategorized_parent: "Sans catégorie ne peut pas avoir de parent" self_parent: "Le parent d'une sous-catégorie ne peut pas être elle-même" depth: "Vous ne pouvez pas imbriquer une sous-catégorie sous une autre" - email_in_already_exist: "L'adresse courriel entrante '%{email_in}' est déjà utilisée pour la catégorie '%{category_name}'." + invalid_email_in: "'%{email}' n'est pas une adresse de courriel valide." + email_already_used_in_group: "'%{email}' est déjà utilisé par le groupe '%{group_name}'." + email_already_used_in_category: "'%{email}' est déjà utilisé par la catégorie '%{category_name}'." cannot_delete: uncategorized: "Vous ne pouvez pas supprimer Sans Catégorie" has_subcategories: "Vous ne pouvez pas supprimer cette catégorie car elle a des sous-catégories." @@ -292,21 +326,35 @@ fr: one: "Vous ne pouvez pas supprimer cette catégorie car elle contient 1 sujet. Le plus vieux sujet est %{topic_link}." other: "Vous ne pouvez pas supprimer cette catégorie car elle contient %{count} sujets. Le plus vieux sujet est %{topic_link}." topic_exists_no_oldest: "Vous ne pouvez pas supprimer cette catégorie car le nombre de sujet est de %{count}." + uncategorized_description: "Sujets sans catégorie, ou qui ne correspond à aucune catégorie existante." trust_levels: newuser: title: "nouvel utilisateur" basic: title: "utilisateur de base" - regular: + member: title: "membre" - leader: + regular: title: "habitué" - elder: + leader: title: "meneur" change_failed_explanation: "Vous avez essayé de rétrograder %{user_name} au niveau '%{new_trust_level}'. Cependant son niveau de confiance est déjà '%{current_trust_level}'. %{user_name} restera au niveau '%{current_trust_level}' - Si vous souhaitez rétrograder un utilisateur vous devez verrouiller le niveau de confiance au préalable" rate_limiter: - slow_down: "Vous avez effectué cette action trop de fois, réessayez plus tard" + slow_down: "Vous avez réalisé cette action un trop grand nombre de fois, essayez plus tard." too_many_requests: "Nous avons une limite journalière du nombre d'actions qui peuvent être effectuées. Veuillez patienter %{time_left} avant de recommencer." + by_type: + first_day_replies_per_day: "Vous avez atteint le nombre maximum de réponses qu'un nouvel utilisateur peut créer pour son premier jour. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + first_day_topics_per_day: "Vous avez atteint le nombre maximum de sujets qu'un nouvel utilisateur peut créer pour son premier jour. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + create_topic: "Vous créez des sujets trop rapidement. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + create_post: "Vous répondez trop rapidement. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + delete_post: "Vous effacez des messages trop rapidement. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + topics_per_day: "Vous avez atteint le nombre maximum de nouveaux sujets pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + pms_per_day: "Vous avez atteint le nombre maximum de nouveaux messages pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + create_like: "Vous avez atteint le nombre maximum de J'aime pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + create_bookmark: "Vous avez atteint le nombre maximum de favoris pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + edit_post: "Vous avez atteint le nombre maximum de modifications pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + unsubscribe_via_email: "Vous avez atteint le nombre maximum de désinscriptions par email pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + topic_invitations_per_day: "Vous avez atteint le nombre maximum d'invitations dans un sujet pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." hours: one: "1 heure" other: "%{count} heures" @@ -401,6 +449,10 @@ fr: confirmed: "Votre adresse de courriel a été mise à jour." please_continue: "Continuer vers %{site_name}" error: "Il y a eu une erreur lors de la modification de votre adresse de courriel. Elle est peut-être déjà utilisée ?" + already_done: "Désolé, ce lien de confirmation n'est plus valide. Votre adresse de courriel a peut-être déjà été changée ?" + authorizing_old: + title: "Merci d'avoir confirmée votre adresse de courriel" + description: "Nous envoyons un courriel sur votre nouvelle adresse pour confirmation." activation: action: "Cliquer ici pour activer votre compte" already_done: "Désolé, ce lien de confirmation n'est plus valide. Votre compte est peut-être déjà activé ?" @@ -422,19 +474,19 @@ fr: email_body: "%{link}\n\n%{message}" inappropriate: title: 'Inapproprié' - description: 'Ce message contient du contenu qu''une personne raisonnable jugerait offensant, abusif ou en violation du règlement de notre communauté.' + description: 'Ce message contient du contenu qu''une personne raisonnable jugerait offensant, abusif ou en violation de la charte de notre communauté.' long_form: 'signalé comme inapproprié' notify_user: - title: 'Contacter @{{username}}' - description: 'Ce message contient quelque chose sur lequel je souhaite discuter en privé avec cet utilisateur. N''envoi pas de signalement.' + title: 'Envoyer un message à @{{username}} ' + description: 'Je veux parler à cette personne directement et de manière privée à propos de son message.' long_form: 'utilisateur contacté' email_title: 'Votre message sur "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Autre chose" - description: 'Ce message nécessite l''attention d''un modérateur pour une autre raison que celles listées ci-dessus.' - long_form: 'signalé pour modération' - email_title: 'Un message dans "%{title}" requière l''attention d''un modérateur' + description: 'Ce sujet nécessite l''attention de l''équipe pour une autre raison non mentionnée ci-dessous' + long_form: 'signalé aux responsables' + email_title: 'Un sujet dans "%{title}" nécessite l''attention d''un modérateur' email_body: "%{link}\n\n%{message}" bookmark: title: 'Signet' @@ -455,11 +507,11 @@ fr: long_form: 'signalé comme spam' inappropriate: title: 'Inapproprié' - description: 'Ce message contient du contenu qu''une personne raisonnable jugerait offensant, abusif ou en violation du règlement de notre communauté.' + description: 'Ce message contient du contenu qu''une personne raisonnable jugerait offensant, abusif ou en violation de la charte de notre communauté.' long_form: 'signalé comme inapproprié' notify_moderators: title: "Autre chose" - description: 'Ce message requiert l''attention de la modération d''après le règlement de la communauté, TOS, ou pour une autre raison non listée ici.' + description: 'Ce message requiert l''attention d''un responsable d''après la charte de la communauté, les conditions générales de service, ou pour une autre raison indéterminée.' long_form: 'signalé pour modération' email_title: 'Ce sujet "%{title}" requière l''attention d''un modérateur' email_body: "%{link}\n\n%{message}" @@ -495,6 +547,10 @@ fr: title: "Nouveaux utilisateurs" xaxis: "Jour" yaxis: "Nombre de nouveaux utilisateurs" + profile_views: + title: "Vues du Profil Utilisateur" + xaxis: "Jour" + yaxis: "Nombre de profils utilisateurs consultés" topics: title: "Sujets" xaxis: "Jour" @@ -637,6 +693,7 @@ fr: s3_config_warning: 'Le serveur est configuré pour charger les fichiers vers s3, mais au moins un de ces paramètre n''est pas configuré : s3_access_key_id, s3_secret_access_key or s3_upload_bucket. Allez dans les Paramètres pour les renseignés. Voir le guide "Comment charger les images sur S3 ?" pour en savoir plus' s3_backup_config_warning: 'Le serveur est configuré pour envoyer les sauvegardes sur S3, mais l''un des paramètres suivants n''est pas renseigné: s3_access_key_id, s3_secret_access_key or s3_backup_bucket. Allez dans les Paramètres et mettez les à jour. Voir "Comment mettre en place une sauvegarde sur S3?" pour en savoir plus.' image_magick_warning: 'Le serveur est configuré pour créer des aperçus des grandes images, mais ImageMagick n''est pas installé. Installez ImageMagick en utilisant votre gestionnaire de paquets favori ou bien allez ici pour télécharger la dernière version.' + failing_emails_warning: 'Il y a %{num_failed_jobs} tâches d''envois de courriel en erreur. Vérifiez votre fichier app.yml et assurez-vous de la conformité des paramètres du serveur de courriel. Voir aussi les processus en échec dans Sidekiq.' default_logo_warning: "Modifier le logo de votre site. Mettez à jour les paramètres du site suivant : logo_url, logo_small_url et favicon_url." contact_email_missing: "Saisissez l'adresse courriel de contact pour votre site web afin qu'on puisse vous contacter pour des problèmes urgents sur votre site. Mettez-le à jour dans les Paramètres du site." contact_email_invalid: "L'adresse courriel de contact du site est invalide. Mettez-le à jour dans les paramètre du site." @@ -645,37 +702,7 @@ fr: consumer_email_warning: "Votre site est configuré pour envoyer les courriels en utilisant Gmail (ou un autre site de courriels pour utilisateur standard). Gmail limite le nombre d'emails que vous pouvez envoyer. Nous vous conseillons d'utiliser un autre service d'envoi de courriels afin d'assurer une meilleure délivrabilité." site_contact_username_warning: "Saisissez le pseudo d'un responsable sympathique à partir duquel sera envoyé les messages importants. Mettez à jour site_contact_username dans les Paramètres du site." notification_email_warning: "Les courriels de notification ne serot pas envoyés depuis une adresse de courriel valide sur votre domaine ; l'envoie des courriels sera aléatoire et peu fiable. Veuillez saisir une adresse de courriel locale dans notification_email dans les Paramètres du site." - content_types: - education_new_reply: - title: "Education du nouvel utlisateur : premières réponses" - description: "Pop-up affichée au dessus de la zone de saisie lorsqu'un nouvel utilisateur rédige ses 2 premières réponses." - education_new_topic: - title: "Education du nouvel utilisateur : premiers sujets" - description: "Pop-up affichée au dessus de la zone de saisie lorsqu'un nouvel utilisateur rédige ses 2 premiers sujets." - usage_tips: - title: "Conseil pour les nouveaux utilisateurs" - description: "Conseil et informations essentielles pour les nouveaux utilisateurs." - welcome_user: - title: "Bienvenue : nouvel utilisateur" - description: "Un message envoyé automatiquement à tous les nouveaux utilisateurs lorsqu'ils s'enregistrent." - welcome_invite: - title: "Bienvenue : utilisateur invité" - description: "Un message envoyé automatiquement à tous les invités lorsqu'ils acceptent l'invitation d'un utilisateur à participer au forum." - login_required_welcome_message: - title: "Connexion requise : message d'accueil" - description: "Message d'accueil qui est affiché pour déconnecter les utilisateurs quand le paramètre 'connexion obligatoire' est activé." - login_required: - title: "Connexion requise : page d'accueil" - description: "Texte affiché aux utilisateurs non autorisés quand la connexion est requise sur ce site." - head: - title: "HTML head" - description: "HTML qui sera inséré dans les balises ." - top: - title: "Entête des pages" - description: "HTML qui sera ajouté en haut de toutes les pages (après l'en-tête, avant la navigation ou le titre du sujet)." - bottom: - title: "Pied des pages" - description: "HTML qui sera ajouté avant la balise ." + subfolder_ends_in_slash: "Votre configuration de sous-répertoire est erronée; DISCOURSE_RELATIVE_URL_ROOT se termine avec une barre oblique ." site_settings: censored_words: "Mots qui seront automatiquement remplacés par ■■■■" delete_old_hidden_posts: "Supprimer automatiquement les messages cachés plus de 30 jours." @@ -689,8 +716,8 @@ fr: max_topic_title_length: "Longueur maximale autorisée des titres de sujet en nombre de caractères" min_private_message_title_length: "Longueur minimale pour un titre de message en nombre de caractères" min_search_term_length: "Longueur minimale autorisée du texte saisie avant de lancer une recherche en nombre de caractères" + search_tokenize_chinese_japanese_korean: "Forcer la tokenisation dans la recherche chinois/japonais/koréen, même sur des sites non-CJK." allow_uncategorized_topics: "Autorise la création de sujets sans catégorie. ATTENTION : S'il existe des sujets non-catégorisés, vous devez les catégoriser avant de désactiver cette fonction." - uncategorized_description: "La description de la catégorie Sans catégorie. Laissez vide pour ne pas avoir de description." allow_duplicate_topic_titles: "Autoriser la création de sujet avec le même titre." unique_posts_mins: "Combien de temps avant qu'un utilisateur puisse poster le même contenu à nouveau" educate_until_posts: "Lors de la rédaction des (n) premiers nouveaux sujets de l'utilisateur, afficher le panneau d'aide à la saisie." @@ -703,7 +730,7 @@ fr: download_remote_images_to_local: "Transformer les images distantes en images locales en les téléchargeant; cela permet d'éviter les liens morts." download_remote_images_threshold: "Quantité minimum d'espace disque requise pour télécharger localement des images distantes (en pourcentage)" disabled_image_download_domains: "Les images distantes de ces domaines ne seront jamais téléchargés. Liste délimitée par un pipe (|)." - ninja_edit_window: "Pendant (n) secondes après la publication d'un message, l'édition de ce dernier ne provoquera pas d'historisation." + editing_grace_period: "Pendant (n) secondes après la publication d'un message, l'édition de ce dernier ne provoquera pas d'historisation." post_edit_time_limit: "L'auteur peut modifier ou supprimer ses messages pendant (n) minutes après leurs publications. Mettre à 0 pour l'autoriser sans limite de temps." edit_history_visible_to_public: "Autoriser tout le monde à voir les versions précédentes d'un message modifié. Quand désactivé, seuls les membres de l'équipe peuvent voir l'historique." delete_removed_posts_after: "Les messages retirés par leur auteur seront automatiquement supprimés après (n) heures. Pour une valeur renseignée à 0, les messages seront supprimés immédiatement." @@ -733,7 +760,7 @@ fr: summary_likes_required: "Nombre de J'aime minimum dans un sujet avant que le 'Résumé du sujet' soit activé" summary_percent_filter: "Quand un utilisateur clique sur 'Résumé du sujet', montrer le top % des messages" summary_max_results: "Nombre maximum de messages retournés par 'Résumé de ce sujet'" - enable_private_messages: "Autoriser les utilisateurs de niveau de confiance 1 à créer des messages et à y répondre" + enable_private_messages: "Autorise les utilisateurs de niveau de confiance 1 à créer des messages et à répondre (configurable via le niveau de confiance minimum pour envoyer des messages)." enable_long_polling: "Utiliser les requêtes longues pour le flux de notifications." long_polling_base_url: "Racine de l'url utilisée pour les requêtes longues (dans le cas de l'utilisation d'un CDN pour fournir du contenu dynamique, pensez à le configurer en mode \"origin pull\") par exemple: http://origin.site.com" long_polling_interval: "Délai d'attente du serveur avant de répondre aux clients lorsqu'il n'y a pas de données à envoyer\n(réservé aux utilisateurs connectés)" @@ -750,11 +777,12 @@ fr: num_flags_to_block_new_user: "Si le message d'un nouvel utilisateur obtient plusieurs signalements pour spam de la part de num_users_to_block_new_user différents utilisateurs, masquer tous ses messages et l'empêcher de poster à l'avenir. 0 désactive cette fonctionnalité." num_users_to_block_new_user: "Si le message d'un nouvel utilisateur obtient num_flags_to_block_new_user signalements pour spam de la part nombreux utilisateurs différents, masquer tous ses messages et l'empêcher de poster à l'avenir. 0 désactive cette fonctionnalité." notify_mods_when_user_blocked: "Si un utilisateur est bloqué automatiquement, envoyer un message à tous les modérateurs." - flag_sockpuppets: "Si un nouvel utilisateur répond à un sujet avec la même adresse I¨P que le nouvel utilisateur qui a commencé le sujet, alors leurs messages seront automatiquement marqués comme spam." + flag_sockpuppets: "Si un nouvel utilisateur répond à un sujet avec la même adresse IP que le nouvel utilisateur qui a commencé le sujet, alors leurs messages seront automatiquement marqués comme spam." traditional_markdown_linebreaks: "Utiliser le retour à la ligne traditionnel dans Markdown, qui nécessite deux espaces pour un saut de ligne." - allow_html_tables: "Permet le rendu des tableaux HTML au sein de Markdown, les balises TABLE, THEAD, TD, TR, TH sont autorisées (nécessite un full rebake sur tous les anciens sujets contenant des tableaux)" + allow_html_tables: "Autoriser la saisie des tableaux dans le Markdown en utilisant les tags HTML : TABLE, THEAD, TD, TR, TH sont autorisés (nécessite un rebake de tous les anciens messages contenant des tableaux)" post_undo_action_window_mins: "Nombre de minutes pendant lesquelles un utilisateur peut annuler une action sur un message (j'aime, signaler, etc.)" must_approve_users: "Les responsables doivent approuver les nouveaux utilisateurs afin qu'ils puissent accéder au site. ATTENTION : activer cette option sur un site en production suspendra l'accès des utilisateurs existants qui ne sont pas des responsables !" + pending_users_reminder_delay: "Avertir les modérateurs si des nouveaux utilisateurs sont en attente d'approbation depuis x heures. Mettre -1 pour désactiver les notifications." ga_tracking_code: "Google Analytics (ga.js) code de suivi, par exemple: UA-12345678-9; voir http://google.com/analytics" ga_domain_name: "Google Analytics (ga.js) de noms de domaine, par exemple: monsite.com; voir http://google.com/analytics" ga_universal_tracking_code: "Google Analytics Universal (analytics.js) code de suivi, par exemple: UA-12345678-9; voir http://google.com/analytics" @@ -763,6 +791,7 @@ fr: enable_noscript_support: "Activer le support des moteurs de recherches standards via le tag noscript" allow_moderators_to_create_categories: "Autoriser les modérateurs à créer de nouvelles catégories" cors_origins: "Requêtes cross-origin (CORS) autorisées. Chaque origine doit inclure http:// ou https://. la variable d'environnement DISCOURSE_ENABLE_CORS doit être renseignée à true pour activer CORS." + use_admin_ip_whitelist: "Les administrateurs ne peuvent se connecter que s'ils sont à une adresse IP définie dans la liste 'IP surveillés' (Admin > Journaux > IP surveillés)." top_menu: "Déterminer les éléments qui apparaissent dans la navigation de la page d'accueil, et dans quel ordre. Exemple latest|new|unread|categories|top|read|posted|bookmarks" post_menu: "L'ordre des éléments dans le menu de rédaction. Exemple like|edit|flag|delete|share|bookmark|reply" post_menu_hidden_items: "Les éléments du menu qui seront cachés par défaut jusqu’à extension du menu." @@ -774,14 +803,15 @@ fr: suppress_reply_directly_above: "Ne pas afficher 'en réponse à' sur un message quand la seule réponse est juste en dessus de ce dernier." suppress_reply_when_quoting: "Ne pas affiché le panneau \"En réponse à\" sur un message qui répond à une citation." max_reply_history: "Nombre maximum de réponses à développer lors du développement d'une \"réponse à\"" - experimental_reply_expansion: "Masquer les réponses intermédiaires lors de l'ouverture d'une répondre à (expérimental)" topics_per_period_in_top_summary: "Nombre de meilleurs sujets affichés dans le résumé par défaut des meilleurs sujets." topics_per_period_in_top_page: "Nombre de meilleurs sujets affichés lorsqu'on sélectionne \"Voir plus\" des meilleurs sujets." redirect_users_to_top_page: "Rediriger automatiquement les nouveaux utilisateurs et les longues absences sur la page Top." + top_page_default_timeframe: "Période par défaut pour la page la plus vue." show_email_on_profile: "Afficher l'adresse du courriel de l'utilisateur sur leur page utilisateur (seulement visible pour l'utilisateur et les équipes techniques)" email_token_valid_hours: "Les jetons (tokens) de Mot de passe oublié / Activation de comptes sont valides (n) jours." email_token_grace_period_hours: "Les jetons (tokens) de Mot de passe oublié / Activation de comptes sont encore valides pour une période de grâce de (n) heures après leur expiration." enable_badges: "Activer le système de badges" + enable_whispers: "Permettre communication privée entre responsables au sein du sujet (expérimental)." allow_index_in_robots_txt: "Spécifier dans robots.txt que le site est autorisé à être indexer par les robots des moteurs de recherche." email_domains_blacklist: "Liste des domaines de courriel qui ne sont pas autorisé lors de la création de compte, délimités par un pipe. Exemple: mailinator.com|trashmail.net" email_domains_whitelist: "Liste des domaines de courriel avec lesquelles les utilisateurs DOIVENT s'enregistrer, délimités par un pipe. ATTENTION : les utilisateurs ayant une adresse de courriel sur un autre domaine ne pourront pas s'enregistrer." @@ -799,6 +829,7 @@ fr: max_username_length: "Longueur maximum des pseudos en nombre de caractères." reserved_usernames: "Pseudos pour lesquels l'inscription n'est pas autorisée." min_password_length: "Longueur minimale du mot de passe." + min_admin_password_length: "Longueur minimale du mot de passe pour l'administrateur." block_common_passwords: "Ne pas autoriser les mots de passe qui font parti des 10 000 les plus utilisés." enable_sso: "Activer l'authentification unique via un site externe (ATTENTION: LES ADRESSES EMAIL *DOIVENT* ÊTRE VALIDÉES PAR LE SITE EXTERNE !)" enable_sso_provider: "Implémenter le procotole Discourse de provider SSO à /session/sso_provider, requiert sso_secret" @@ -811,6 +842,7 @@ fr: sso_not_approved_url: "Rediriger les comptes SSO non validés vers cette URL" enable_local_logins: "Activer l'authentification traditionnelle, avec pseudo local et mot de passe. (Note: Doit être activé pour que les invitations fonctionnent)" allow_new_registrations: "Autorise l'inscription des nouveaux utilisateurs. Décocher pour prévenir la création de nouveau compte." + enable_signup_cta: "Afficher un rappel aux utilisateurs anonymes pour les encourager à créer un compte." enable_yahoo_logins: "Activer l'authentification Yahoo" enable_google_oauth2_logins: "Activer l'authentification Google Oauth2. C'est la méthode d'authentification que Google supporte désormais. Nécessite une clé et une phrase secrète." google_oauth2_client_id: "Client ID de votre application Google." @@ -818,6 +850,9 @@ fr: enable_twitter_logins: "Activer l'authentification Twitter, nécessite twitter_consumer_key et twitter_consumer_secret" twitter_consumer_key: "Clé utilisateur pour l'authentification Twitter, enregistrée sur http://dev.twitter.com" twitter_consumer_secret: "Secret utilisateur pour l'authentification Twitter, enregistré sur http://dev.twitter.com" + enable_instagram_logins: "Activer l'authentification Instagram, nécessite instagram_consumer_key et instagram_consumer_secret" + instagram_consumer_key: "\"Consumer key\" pour l'identification Instagram" + instagram_consumer_secret: "\"Consumer secret\" pour l'identification Instagram" enable_facebook_logins: "Activer l'authentification Facebook, nécessite facebook_app_id et facebook_app_secret" facebook_app_id: "App id pour l'authentification Facebook, enregistré sur https://developers.facebook.com/apps" facebook_app_secret: "App secret pour l'authentification Facebook, enregistré sur https://developers.facebook.com/apps" @@ -830,9 +865,15 @@ fr: backup_frequency: "Fréquence de création des sauvegardes du site, en jours." enable_s3_backups: "Envoyer vos sauvegardes à S3 lorsqu'elles sont terminées. IMPORTANT: Vous devez avoir renseigné vos identifiants S3 dans les paramètres de fichiers." s3_backup_bucket: "Bucket distant qui contiendra les sauvegardes. ATTENTION: Vérifiez que c'est un bucket privé" + s3_disable_cleanup: "Désactiver la suppression des sauvegardes de S3 lors de leur suppression locale." + backup_time_of_day: "Heure de la sauvegarde, au format UTC." + backup_with_uploads: "Inclure les téléchargements dans les archivages. Si désactivé, seul la base de données sera archivée." active_user_rate_limit_secs: "A quelle fréquence mettre à jour le champ 'last_seen_at' (Dernière vu à), en secondes." verbose_localization: "Afficher des informations de debug sur l'interface à coté des textes traduits." previous_visit_timeout_hours: "Combien de temps pour qu'une visite soit considérer comme la visite 'précédente', en heures." + top_topics_formula_log_views_multiplier: "formule pour la valeur de multiplicateur de vues de journal (n) dans les sujets tendance : `log(views_count) * (n) + op_likes_count * 0.5 + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_first_post_likes_multiplier: "formule pour la valeur de multiplicateur de premiers J'aime (n) dans les sujets tendance: `log(views_count) * 2 + op_likes_count * (n) + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_least_likes_per_post_multiplier: "formule pour la valeur de multiplicateur de moins de J'aime par message (n) dans les sujets tendance: `log(views_count) * 2 + op_likes_count * 0.5 + LEAST(likes_count / posts_count, (n)) + 10 + log(posts_count)`" rate_limit_create_topic: "Après la création d'un sujet, les utilisateurs doivent attendre (n) secondes avant de pouvoir en créer un nouveau." rate_limit_create_post: "Après avoir posté un message, les utilisateurs doivent attendre (n) secondes avant de pouvoir en poster un nouveau." rate_limit_new_user_create_topic: "Après la création d'un sujet, les nouveaux utilisateurs doivent attendre (n) secondes avant de pouvoir en créer un nouveau." @@ -845,6 +886,8 @@ fr: max_private_messages_per_day: "Nombre maximum de messages que les utilisateurs peuvent créer chaque jour." max_invites_per_day: "Nombre maximum d'invitations qu'un utilisateur peut envoyer par jour." max_topic_invitations_per_day: "Nombre maximum d'invitations à un sujet qu'un utilisateur peut envoyer par jour." + alert_admins_if_errors_per_minute: "Nombre d'erreurs par minute nécessaires pour déclencher une alerte administrateur. Une valeur de 0 désactive cette fonctionnalité. NB : nécessite un redémarrage." + alert_admins_if_errors_per_hour: "Nombre d'erreurs par heure nécessaires pour déclencher une alerte administrateur. Une valeur de 0 désactive cette fonctionnalité. NB : Nécessite un redémarrage." suggested_topics: "Nombre de sujets suggérés affichés en bas d'un sujet." limit_suggested_to_category: "Afficher uniquement les sujets de la catégorie courante dans les sujets similaires." clean_up_uploads: "Retirer les fichiers téléchargés orphelins pour prévenir les hébergements illégaux. ATTENTION: vous devriez faire une sauvegarde de votre répertoire /uploads avant d'activer ce paramètre." @@ -859,6 +902,10 @@ fr: s3_region: "Le nom de la région Amazon S3 qui va être utilisée pour uploader des images." s3_cdn_url: "L'adresse du CDN à utiliser pour toutes les ressources s3 (par exemple : https://cdn.monsite.com). ATTENTION : après avoir changé ce paramètre, vous devez régénérer la totalité des messages existants. " avatar_sizes: "Liste des tailles des avatars automatiquement générés" + external_system_avatars_enabled: "Utilisez un service d'avatars externe." + external_system_avatars_url: "URL du système de service d'avatars externe. Substitutions permises: {username} {first_letter} {color} {size}" + default_opengraph_image_url: "URL de l'image par défaut pour les balises Open Graph." + allow_all_attachments_for_group_messages: "Autorise toutes les pièces-jointes pour les messages de groupes." enable_flash_video_onebox: "Activer l'utilisation de swf et flv (Adobe Flash) dans les boites imbriquées. ATTENTION : cela pourrait introduire un risque de sécurité." default_invitee_trust_level: "Niveau de confiance par défaut (0-4) pour les invités." default_trust_level: "Niveau de confiance par défaut (entre 0 et 4) pour tous les nouveaux utilisateurs. ATTENTION ! Changer ce paramètre peut vous exposer à des spams." @@ -872,25 +919,21 @@ fr: tl2_requires_likes_received: "Combien de J'aime un utilisateur doit recevoir pour être promu au niveau de confiance 2." tl2_requires_likes_given: "Combien de J'aime un utilisateur doit donner pour être promu au niveau de confiance 2." tl2_requires_topic_reply_count: "A combien de sujet un utilisateur doit avoir participé pour être promu au niveau de confiance 2." - tl3_requires_days_visited: "Nombre minimum de jours qu'un utilisateur doit avoir passer sur le site dans les 100 derniers jours pour être promu au niveau de confiance 3. (0 à 100)" - tl3_requires_topics_replied_to: "Nombre minimum de sujets auquel un utilisateur doit avoir répondu dans les 100 derniers jours pour être promu au niveau de confiance 3. (0 à 100)" - tl3_requires_topics_viewed: "Pourcentage de sujets crées dans les 100 derniers jours qu'un utilisateur doit avoir vu pour être promu au niveau de confiance 3. (0 à 100)" - tl3_requires_posts_read: "Pourcentage de message crées dans les 100 derniers jours qu'un utilisateur doit avoir vu pour être promu au niveau de confiance 3. (0 à 100)" tl3_requires_topics_viewed_all_time: "Nombre minimum de sujets qu'un utilisateur doit avoir vu pour être promu au niveau de confiance 3." tl3_requires_posts_read_all_time: "Nombre minimum de messages qu'un utilisateur doit avoir vu pour être promu au niveau de confiance 3." - tl3_requires_max_flagged: "L'utilisateur ne doit pas avoir plus de x messages signalés par x utilisateurs différents dans les 100 derniers jours pour être promu au niveau de confiance 3; x étant la valeur de ce paramètre. (0 ou plus)" tl3_promotion_min_duration: "Nombre minimum de jours qu'un utilisateur restera promu au niveau de confiance 3 avant de pouvoir être rétrogradé au niveau de confiance 2." - tl3_requires_likes_given: "Nombre minimum de J'aime à donner dans les 100 derniers jours pour être promu au niveau de confiance 3." - tl3_requires_likes_received: "Nombre minimum de J'aime à recevoir dans les 100 derniers jours pour être promu au niveau de confiance 3." tl3_links_no_follow: "Ne pas retirer rel=nofollow sur les liens des messages par les utilisateurs de niveau de confiance 3." min_trust_to_create_topic: "Le niveau de confiance minimum pour créer un nouveau sujet." min_trust_to_edit_wiki_post: "Le niveau de confiance minimum requis pour modifier les messages de type wiki." + min_trust_to_allow_self_wiki: "Le niveau de confiance minimum requis pour transformer ses propres messages en type wiki." + min_trust_to_send_messages: "Le niveau de confiance minimum pour être autorisé à créer des nouveaux messages privés." newuser_max_links: "Combien de liens un nouvel utilisateur peut-il ajouter à un message." newuser_max_images: "Combien d'images un nouvel utilisateur peut-il ajouter à un message." newuser_max_attachments: "Combien de fichiers un nouvel utilisateur peut-il ajouter à un message." newuser_max_mentions_per_post: "Nombre maximum de @pseudo qu'un nouvel utilisateur peut mentionner dans un message." newuser_max_replies_per_topic: "Nombre maximum de réponses qu'un nouvel utilisateur peut faire dans une même discussion avant que quelqu'un lui réponde." max_mentions_per_post: "Nombre maximal de @pseudo que tout le monde peut mentionner dans un message." + max_users_notified_per_group_mention: "Nombre maximum d'utilisateurs qui peuvent recevoir une notification si un groupe est mentionné (si le seuil est atteint aucune notification n'est envoyée)" create_thumbnails: "Créer un aperçu pour les images imbriquées qui sont trop large pour le message." email_time_window_mins: "Attendre (n) minutes avant l'envoi des courriels de notification, afin de laisser une chance aux utilisateurs de modifier ou finaliser leurs messages." email_posts_context: "Combien de réponses précédentes doit-on inclure dans les courriels de notifications pour situer le contexte." @@ -898,6 +941,7 @@ fr: title_max_word_length: "Le nombre maximum de caractères dans le titre d'un sujet." title_min_entropy: "L'entropie minimale (caractères unique, les caractères en langues étrangères compte pour plus) requise pour le titre d'un sujet." body_min_entropy: "L'entropie minimale (caractères unique, les caractères en langues étrangères compte pour plus) requise pour le corps d'un message." + allow_uppercase_posts: "Autoriser des messages ou titres de sujets entièrement en majuscules." title_fancy_entities: "Convertir les caractères ASCII commun en jolies entitées HTML dans les titres des sujets, comme SmartyPants http://daringfireball.net/projects/smartypants/" min_title_similar_length: "La taille minimale d'un titre avant que l'on vérifie l'existence de sujets identiques." min_body_similar_length: "La taille minimale d'un message avant que l'on vérifie l'existence de sujets identiques." @@ -926,6 +970,8 @@ fr: newuser_spam_host_threshold: "Limite du nombre de liens vers un même host compris dans `newuser_spam_host_posts` qu'un nouvel utilisateur peut insérer dans un message avant d'être considérer comme un spam." white_listed_spam_host_domains: "Une liste des domaines exclus des hôtes testés comme spam. Les nouveaux utilisateurs ne seront jamais restreint dans la création de message contenant des liens vers ses domaines. " staff_like_weight: "Quel poids supplémentaire donner aux J'aime de l'équipe." + topic_view_duration_hours: "Compte la vue d'un sujet une seule fois par IP ou par utilisateur toutes les N heures" + user_profile_view_duration_hours: "Compte la vue d'un profil d'utilisateur une seule fois par IP ou par utilisateur qui visite toutes les N heures" levenshtein_distance_spammer_emails: "Lorsque des courriels correspondent à des spammer, la différence du nombre de caractère permettra toujours une correspondance floue." max_new_accounts_per_registration_ip: "S'il y a déjà (n) Niveau de confiance 0 comptes à partir de cette adresse IP ( et aucun n'est un membre du personnel ou au NC2 ou ultérieure), ne plus accepter de nouvelles inscriptions de cette IP." min_ban_entries_for_roll_up: "En cliquant sur le bouton Consolider, une liste d'au moins (N) adresses interdites sera remplacée par une plage de sous réseau." @@ -943,6 +989,10 @@ fr: disable_emails: "Désactiver l'envoi de les courriels depuis Discourse." strip_images_from_short_emails: "Retirer les images des courriels dont la taille est inférieur à 2800 Octets" short_email_length: "Taille des courriels courts en Octets" + display_name_on_email_from: "Affiche les noms complets dans le champ From du courriel." + unsubscribe_via_email: "Autorise les utilisateurs à se désinscrire des courriels en envoyant un courriel avec \"unsubscribe\" dans le sujet ou le corps du message." + unsubscribe_via_email_footer: "Ajoute un lien pour se désinscrire dans le pied des courriels envoyés" + delete_email_logs_after_days: "Efface les journaux de messagerie après (N) jours. 0 pour conserver indéfiniment." pop3_polling_enabled: "Utiliser POP3 pour les réponses via courriel." pop3_polling_ssl: "Utiliser SSL pour les connections au serveur POP3. (Recommandé)" pop3_polling_period_mins: "La période en minute entre chaque vérification du compte POP3 des courriels.\nNote: nécessite un redémarrage de la machine." @@ -969,7 +1019,7 @@ fr: automatically_download_gravatars: "Télécharger les gravatars pour les utilisateurs lors de la création de compte ou de la modification de courriel." digest_topics: "Nombre maximum de sujets à afficher dans le courriel de résumé." digest_min_excerpt_length: "Taille minimum du résumé des messages dans les courriels, en caractères." - suppress_digest_email_after_days: "Ne pas envoyer de résumés courriel aux utilisateurs qui n'ont pas visité le site depuis (n) jours." + delete_digest_email_after_days: "Ne pas envoyer de résumés courriel aux utilisateurs qui n'ont pas visité le site depuis plus de (n) jours." disable_digest_emails: "Désactiver les résumés par courriels pour tous les utilisateurs." detect_custom_avatars: "Vérifier ou non si les utilisateurs ont envoyé une photo de profil personnalisée." max_daily_gravatar_crawls: "Nombre maximum de fois que Discourse vérifiera Gravatar pour des avatars personnalisés en une journée." @@ -979,15 +1029,18 @@ fr: allow_anonymous_posting: "Permettre aux utilisateurs de passer en mode anonyme" anonymous_posting_min_trust_level: "Le niveau de confiance minimum pour passer en mode anonyme." anonymous_account_duration_minutes: "Pour protéger l'anonymat, créer un nouveau compte anonyme tous les N minutes pour chaque utilisateur. Exemple: si 600 est choisi, dès 600 minutes après le dernier message ET que l'utilisateur passe en mode anonyme, un nouveau compte anonyme lui sera crée." + hide_user_profiles_from_public: "Désactive les cartes utilisateurs, les profils utilisateurs et les répertoires utilisateurs pour les utilisateurs anonymes." allow_profile_backgrounds: "Autoriser les utilisateurs à envoyer des arrières-plans de profil." - sequential_replies_threshold: "Nombre de messages qu'un utilisateur doit poster d'affilé dans un sujet avant d'être rappelé à l'ordre pour multiple réponses." + sequential_replies_threshold: "Nombre de messages successifs qu'un utilisateur peut poster dans un sujet avant d'être averti d'avoir posté un nombre excessif de réponses qui se suivent." enable_mobile_theme: "Les appareils mobiles utilisent un thème adapté aux mobiles, avec la possibilité de passer à la totalité du site. Désactivez cette option si vous voulez utiliser une feuille de style personnalisée qui répond à tous les types de client." dominating_topic_minimum_percent: "Quel est le pourcentage de messages un utilisateur doit poster dans un sujet avant d'être rappelé à l'ordre pour laissé la communauté répondre." + disable_avatar_education_message: "Désactiver le message incitant à changer l'avatar." daily_performance_report: "Analyser les logs de NGINX quotidiennement et poster un sujet Responsables Uniquement avec les détails" suppress_uncategorized_badge: "Ne pas afficher le badge pour les sujets non catégorisés dans les listes des sujets." - permalink_normalizations: "Appliquer l'expression régulière suivante avant de faire correspondre les permaliens, par exemple /(\\/topic.*)\\?.*/\\1 supprimera les query strings des routes des sujets. Le format est regex+string, utilisez \\1 etc. pour accéder aux captures" global_notice: "Affiche un bandeau global URGENT pour tout les utilisateurs du site, laissez vide pour le cacher (HTML autorisé)." disable_edit_notifications: "Désactiver les notifications de modifications par l'utilisateur système lorsque l'option 'download_remote_images_to_local' est activée." + automatically_unpin_topics: "Désépingler automatiquement le sujet lorsque l'utilisateur atteint la fin." + read_time_word_count: "Nombre de mots par minute servant de base de calcul à l'estimation du temps de lecture." full_name_required: "Le nom complet est requis dans le profil utilisateur." enable_names: "Autoriser l'affichage des noms complets des utilisateurs dans leur profil, sur leur carte d'utilisateur et dans les courriels. Décocher pour cacher les noms complets partout." display_name_on_posts: "Afficher le nom complet de l'utilisateur dans ses messages en plus de son @pseudo." @@ -1004,32 +1057,39 @@ fr: embed_username_key_from_feed: "Clé pour extraire le pseudo du flux." embed_truncate: "Tronquer les messages embarqués." embed_post_limit: "Nombre maximum de messages à embarquer." + embed_username_required: "Un pseudo d'utilisateur pour la création du sujet est nécessaire." embed_whitelist_selector: "Sélecteur CSS pour les éléments qui seront autorisés dans les contenus embarqués." embed_blacklist_selector: "Sélecteur CSS pour les éléments qui seront interdits dans les contenus embarqués." notify_about_flags_after: "Si il y a des signalements qui n'ont pas été traités après ce nombre d'heure, envoyer un courriel à contact_email. Désactiver la fonctionnalité en indiquant: 0." enable_cdn_js_debugging: "Autoriser /logs à afficher correctement les erreurs en ajoutant des permissions de crossorigin sur toutes les inclusions de js." show_create_topics_notice: "Si le site contient moins de 5 sujets publics, afficher un message pour demander aux administrateurs de créer d'autres sujets." delete_drafts_older_than_n_days: Supprimer les brouillons plus vieux que (n) jours. - show_logout_in_header: "Afficher le lien de déconnexion dans la liste utilisateur du header" - vacuum_db_days: "Exécuter VACUUM FULL ANALYZE pour récupérer de l'espace dans la base de donnée après une migration (0 pour désactivé) " + vacuum_db_days: "Exécuter VACUUM ANALYZE pour récupérer de l'espace dans la base de données après une migration (mettre à 0 pour désactiver)" prevent_anons_from_downloading_files: "Refuser le téléchargement de pièces jointes aux utilisateurs anonymes. ATTENTION: cela empêchera de fonctionner les ressources envoyées en pièce jointe qui ne sont pas des images." slug_generation_method: "Choisissez une méthode de génération d'identifiant. \"encodé\" générera des chaines de caractères encodées avec des pourcentages. \"aucune\" désactivera complètement les identifiants." enable_emoji: "Activer les emojis" emoji_set: "Comment aimeriez-vous vos emoji ?" enforce_square_emoji: "Forcer tous les emojiis à être carrés." - approve_post_count: "Le nombre de messages d'un nouvel utilisateur qui doivent être approuvés" + approve_post_count: "Le nombre de messages d'un utilisateur nouveau ou basique devant être approuvés" approve_unless_trust_level: "Les messages des utilisateurs qui n'ont pas atteint ce niveau de confiance doivent être approuvés" notify_about_queued_posts_after: "Si des messages sont en attente de modération depuis ce nombre d'heures, un email sera envoyé à l'email de contact. Désactivez ces emails en indiquant 0." default_email_digest_frequency: "A quelle fréquence les utilisateurs reçoivent-ils les courriels par défaut." default_email_private_messages: "Envoyer un courriel quand quelqu'un envoie un message à un utilisateur." default_email_direct: "Envoyer un courriel quand quelqu'un cite/répond à/mentionne ou invite un utilisateur." default_email_mailing_list_mode: "Envoyer un courriel pour chaque nouveau message." + disable_mailing_list_mode: "Interdit aux utilisateur d'activer le mode mailing list." default_email_always: "Envoyer une notification courriel même quand l'utilisateur est actif." + default_email_previous_replies: "Inclure par défaut les réponses précédentes dans les courriels." + default_email_in_reply_to: "Inclure par défaut l'extrait du message auquel se fait la réponse dans les courriels." + default_other_new_topic_duration_minutes: "Paramètre global de temps pendant lequel un sujet est considéré comme nouveau." + default_other_auto_track_topics_after_msecs: "Paramètre global fixant le temps par défaut au bout duquel un sujet est suivi automatiquement." default_other_external_links_in_new_tab: "Par défaut, ouvrir tous les liens externes dans un nouvel onglet" default_other_enable_quoting: "Par défaut, proposer la citation du texte surligné." default_other_dynamic_favicon: "Par défaut, faire apparaître le nombre de sujets récemment créés ou mis à jour sur l'icône navigateur." default_other_disable_jump_reply: "Par défaut, ne pas se déplacer au nouveau message après avoir répondu." default_other_edit_history_public: "Par défaut, rendre publiques les révisions de message." + default_other_like_notification_frequency: "Notifier lors d'un J'aime par défaut" + default_topics_automatic_unpin: "Par défaut, désépingler automatiquement le sujet lorsque l'utilisateur atteint la fin." default_categories_watching: "Liste de catégories surveillées par défaut." default_categories_tracking: "Liste de catégories suivies par défaut." default_categories_muted: "Liste de catégories silencées par défaut." @@ -1047,7 +1107,13 @@ fr: invalid_string_min: "Doit être d'au moins %{count} caractères." invalid_string_max: "Ne doit pas être supérieur à %{max} caractères." invalid_reply_by_email_address: "La valeur doit contenir '%{reply_key}' et être différente de la notification email." + pop3_polling_host_is_empty: "Vous devez indiquer le \"nom d'un serveur pop3\" avant d'activer le relevé via POP3." + pop3_polling_username_is_empty: "Vous devez indiquer le \"login utilisateur pop3\" avant d'activer le relevé via POP3." + pop3_polling_password_is_empty: "Vous devez indiquer le \"mot de passe pop3\" avant d'activer le relevé via POP3." + pop3_polling_authentication_failed: "Echec d'authentication POP3. Veuillez contrôler vos détails POP3." + reply_by_email_address_is_empty: "Vous devez renseigner une 'adresse de réponse par courriel' avant d'activer la réponse par courriel." notification_types: + group_mentioned: "%{group_name} a été mentionné dans %{link}" mentioned: "%{display_username} vous a mentionné dans %{link}" liked: "%{display_username} a aimé votre message dans %{link}" replied: "%{display_username} a répondu à votre message dans %{link}" @@ -1057,7 +1123,7 @@ fr: moved_post: "%{display_username} a déplacé votre message vers %{link}" private_message: "%{display_username} vous a envoyé un message : %{link}" invited_to_private_message: "%{display_username} vous a invité dans une discussion: %{link}" - invited_to_topic: "%{display_username} vous a invité dans un sujet: %{link}" + invited_to_topic: "%{display_username} vous a invité à %{link}" invitee_accepted: "%{display_username} a accepté votre invitation" linked: "%{display_username} a mentionné l'un de vos messages : %{link}" granted_badge: "Vous avez gagné %{link}" @@ -1067,11 +1133,6 @@ fr: category: 'Catégories' topic: 'Résultats' user: 'Utilisateurs' - sso: - not_found: "Impossible de rechercher ou de créer un compte, contacter l'administrateur du site" - account_not_approved: "Le compte est en attente d'approbation. Vous recevrez un avis par courriel une fois approuvé." - unknown_error: "Erreur de mise à jour des informations, contacter l'administrateur du site" - timeout_expired: "La connexion au compte a été interrompue, veuillez vous connecter à nouveau" original_poster: "Créateur du sujet" most_posts: "Le plus de messages" most_recent_poster: "Auteur le plus récent" @@ -1146,6 +1207,7 @@ fr: reserved_username: "Ce pseudo n'est pas autorisé." missing_user_field: "Vous n'avez pas renseigné l'ensemble des champs utilisateur" close_window: "Identification terminée. Fermez cette fenêtre pour continuer." + already_logged_in: "Oups, on dirait que vous essayez d'accepter une invitation d'un autre utilisateur. Si vous n'êtes pas %{current_user}, veuillez vous déconnecter et réessayer." user: no_accounts_associated: "Aucun compte associé" username: @@ -1154,16 +1216,33 @@ fr: characters: "doit inclure uniquement des chiffres, lettres et caractères de soulignement" unique: "doit être unique" blank: "doit être présent" - must_begin_with_alphanumeric: "doit débuter par une lettre ou un nombre ou un underscore" - must_end_with_alphanumeric: "doit terminer par une lettre, un chiffre ou un caractère souligné (underscore)" + must_begin_with_alphanumeric_or_underscore: "doit commencer par une lettre, un chiffre ou un tiret du bas." + must_end_with_alphanumeric: "doit finir par une lettre ou un chiffre" must_not_contain_two_special_chars_in_seq: "ne doit pas contenir une séquence de 2 caractères spéciaux ou plus (.-_)" - must_not_contain_confusing_suffix: "ne doit pas contenir un sufix déroutant comme .json ou .png etc." + must_not_end_with_confusing_suffix: "ne doit pas se terminer avec un suffixe déroutant comme .json ou .png etc." email: not_allowed: "n'est pas autorisé pour ce fournisseur de courriels. Merci d'utiliser une autre adresse." blocked: "n'est pas autorisé." ip_address: blocked: "Les nouvelles inscriptions ne sont pas acceptées depuis votre adresse IP." max_new_accounts_per_registration_ip: "Les nouvelles inscriptions ne sont pas autorisées depuis votre adresse IP (limite atteinte). Contactez un responsable." + flags_reminder: + flags_were_submitted: + one: "Un signalement a été soumis il y a plus d'une heure. Veuillez la passer en revue." + other: "Des signalements ont été soumis il y a plus de %{count} heures. Veuillez les passer en revue." + subject_template: + one: "un signalement en attente de traitement" + other: "%{count} signalements en attente de traitement." + unsubscribe_mailer: + subject_template: "Confirmez que vous ne souhaitez plus recevoir d'email de mise à jour de %{site_title}" + text_body_template: | + Quelqu’un (est-ce vous?) a demandé à ne plus envoyer d'email de mise à jour de %{site_domain_name} a cette adresse. + Pour confirmer, merci de cliquer sur ce lien: + + %{confirm_unsubscribe_link} + + + Si vous souhaitez continuer à recevoir les emails, vous pouvez ignorer cet email. invite_mailer: subject_template: "%{invitee_name} vous a invité(e) à participer à '%{topic_title}' sur %{site_domain_name}" text_body_template: | @@ -1212,27 +1291,28 @@ fr: [**%{base_url}**][0] - Assurer la distribution de courriel est compliqué. Voici un certain nombre de points importants que vous devez vérifier au préalable: + Assurer la distribution de courriel est compliqué. Voici un certain nombre de points importants que vous devez vérifier au préalable : - - Soyez *certain* de renseigner le champs from: de la `notification par email` correctement dans votre configuration. **Le nom de domaine renseigné dans l'addresse "from" des courriels que vous envoyez sera le nom de domaine utilisé pour la validation**. + - Soyez *certain* de renseigner le champs from: de la `notification par email` correctement dans votre configuration. **Le nom de domaine renseigné dans l'addresse "from" des courriels que vous envoyez sera le nom de domaine utilisé pour la validation**. - - Sachez comment consulter le format brut d'un courriel dans votre client de courriel, pour vous permettre de consulter les entêtes pour obtenirs des indices importants. Dans Gmail, c'est l'option "show original" dans le menu contextuel situé en haut à droite de chaque courriel. + - Sachez comment consulter le format brut d'un courriel dans votre client de courriel, pour vous permettre de consulter les entêtes pour obtenirs des indices importants. Dans Gmail, c'est l'option "show original" dans le menu contextuel situé en haut à droite de chaque courriel. - - **IMPORTANT:** Does your ISP have a reverse DNS record entered to associate the domain names and IP addresses you send mail from? [Test your Reverse PTR record][2] here. If your ISP does not enter the proper reverse DNS pointer record, it's very unlikely any of your email will be delivered. + - **IMPORTANT:** Votre FAI a-t-il un enregistrement DNS inverse renseigné pour associer les noms de domaine et les adresses IP depuis lesquelles vous envoyez des courriels ? [Testez votre enregistrement inverse PTR][2] ici. Si votre FAI n'a pas renseigné correctement votre enregistrement DNS inverse, il est très improbable que vos courriels soient délivrés. - - l'enregistrement [SPF record][8] de votre nom de domaine est-il correcte ? [Testez votre enregistrement SPF][1] ici Veuillez noter que le type officiel d'enregistrment est TXT pour l'enregistrement SPF. + - L'[enregistrement SPF][8] de votre nom de domaine est-il correct ? [Testez votre enregistrement SPF][1] ici. Veuillez noter que le type officiel d'enregistrement est TXT pour le SPF. - - l'enregistrement [DKIM record][3] de votre nom de domaine est-il correcte ? Ce point particulier augmentera de manière significative la bonne distribution de vos courriels. [Testez votre enregistrement DKIM][7] ici. + - L'[enregistrement DKIM][3] de votre nom de domaine est-il correct ? Ceci augmentera de manière significative la bonne distribution de vos courriels. [Testez votre enregistrement DKIM][7] ici. - - If you run your own mail server, check to make sure the IPs of your mail server are [not on any email blacklists][4]. Also verify that it is definitely sending a fully-qualified hostname that resolves in DNS in its HELO message. If not, this will cause your email to be rejected by many mail services. + - Si vous maintenez votre propre serveur de courriel, assurez-vous que les IPs de votre serveur [liste noire de courriel][4]. Vérifiez également qu'il envoie un "fully qualified hostname" résolvable en DNS dans son message HELO. Si ce n'est pas le cas, vos courriels seront rejetés par de nombreux services de courriel. - (La mannière la plus *facile* est de créer un compte gratuit sur [Mandrill][md] ou [Mailgun][mg] ou [Mailjet][mj], qui ont des options gratuites généreuses et qui seront parfaite pour de petites communautés. Vous devrez quand même configurer les entrées SPF et DKIM dans votre DNS!) + - Nous vous recommandons chaudement d'**envoyer un courriel de test à [mail-tester.com][mt]** pour vérifier que tout ce qui est mentionné ci-dessus fonctionne bien. + + + (La manière *la plus facile* est de créer un compte gratuit sur [SendGrid][sg], [SparkPost][sp], [Mailgun][mg] ou [Mailjet][mj], qui ont de généreuses options gratuites et qui seront parfaits pour de petites communautés. Vous devrez quand même configurer les entrées SPF et DKIM dans votre DNS !) Nous espérons que vous avez bien reçu ce courriel de test de distribution ! - Bonne chance, - - Vos amis de [Discourse](http://www.discourse.org) + Bonne chance, vos amis de [Discourse](http://www.discourse.org) [0]: %{base_url} [1]: http://www.kitterman.com/spf/validate.html @@ -1241,53 +1321,15 @@ fr: [4]: http://whatismyipaddress.com/blacklist-check [7]: http://dkimcore.org/tools/dkimrecordcheck.html [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com + [sg]: https://sendgrid.com/ + [sp]: https://www.sparkpost.com/ [mg]: http://www.mailgun.com/ [mj]: https://www.mailjet.com/pricing + [mt]: http://www.mail-tester.com/ new_version_mailer: subject_template: "[%{site_name}] Nouvelle version de Discourse, mise à jour disponible" - text_body_template: | - Une nouvelle version de [Discourse](http://www.discourse.org) est disponible. - - Votre version: %{installed_version} - Nouvelle version: **%{new_version}** - - Vous voulez peut-être: - - - Voir les nouveautés sur le [changelog de GitHub](https://github.com/discourse/discourse/commits/master). - - - Mettre à jour depuis votre navigateur en allant sur [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade) - - - Visiter [meta.discourse.org](http://meta.discourse.org) pour vous tenir au courant, discuter et avoir de l'aide à propos de Discourse. new_version_mailer_with_notes: subject_template: "[%{site_name}] mise à jour disponible" - text_body_template: | - Une nouvelle version de [Discourse](http://www.discourse.org) est disponible. - - Votre version: %{installed_version} - Nouvelle version: **%{new_version}** - - Vous voulez peut-être: - - - Voir les nouveautés sur le [changelog de GitHub](https://github.com/discourse/discourse/commits/master). - - - Mettre à jour depuis votre navigateur en allant sur [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade) - - - Visiter [meta.discourse.org](http://meta.discourse.org) pour vous tenir au courant, discuter et avoir de l'aide à propos de Discourse. - - ### Notes de mise à jour - - %{notes} - flags_reminder: - flags_were_submitted: - one: "Il y a un signalement qui a été soumis il y a plus de %{count} heures." - other: "Ces signalements ont été soumis il y a plus de %{count} heures." - please_review: "Veuillez examiner cela." - post_number: "message" - how_to_disable: 'Vous pouvez désactiver ou modifier la fréquence de ce courriel de rappel via le réglage "m''informer sur les signalements".' - subject_template: - one: "un signalement en attente de traitement" - other: "%{count} signalements en attente de traitement." queued_posts_reminder: subject_template: one: "[%{site_name}] 1 message en attente de modération" @@ -1298,7 +1340,7 @@ fr: Des messages de nouveaux utilisateurs sont en attente de modération. [Ils peuvent être approuvés ou rejetés ici](%{base_url}/queued-posts). flag_reasons: off_topic: "Votre message a été signalé comme étant **hors sujet**: la communauté considère qu'il ne correspond au sujet en discussion, qui est fixé par son titre et son premier message." - inappropriate: "Votre message a été signalé comme étant **inapproprié**: la communauté considère que son contenu est offensif, abusif ou enfreint notre [règlement interne](/guidelines)." + inappropriate: "Votre message a été signalé comme étant **inapproprié**: la communauté considère que son contenu est offensif, abusif ou enfreint notre [charte](/guidelines)." spam: "Votre message a été signalé comme étant du **spam**: la communauté considère qu'il s'agit d'une publicité, ou du contenu trop promotionnel au lieu d'être utile et à propos du sujet en discussion." notify_moderators: "Votre message a été **signalé aux modérateurs**: la communauté considère que quelque chose requiert une intervention d'un des responsables." flags_dispositions: @@ -1324,104 +1366,107 @@ fr: Cependant, si votre message est masqué par la communauté une seconde fois, il restera masqué jusqu'à ce qu'un membre de l'équipe s'en occupe – et il est possible que des actions supplémentaires soient entreprises, ceci pouvant mener à la suspension de votre compte. - Afin d'être guider, merci de vous référer à notre [guide de bonne conduite](%{base_url}/guidelines). + Afin d'être guider, merci de vous référer à notre [charte](%{base_url}/guidelines). usage_tips: text_body_template: | Vous trouverez ci-dessous quelques astuces pour vous aider à démarrer : - ##Lire + ## Lire Pour en lire plus, **faites défiler vers le bas !** - Lorsqu'une nouvelle réponse ou un nouvel article sont publiés, ils apparaissent automatiquement - pas besoin de rafraîchir la page. + Lorsque de nouveaux sujets ou de nouvelles réponses sont publiés, ils apparaissent automatiquement ; inutile de rafraîchir la page. - ##Navigation + ## Navigation - - Pour effectuer une recherche, sur votre page profil ou le menu , utilisez l'icône en haut à droite. + - Pour effectuer une recherche, accéder à votre profil ou utiliser le menu , cliquez sur les **icônes en haut à droite**. - - Sélectionner un titre de l'article, vous dirigera toujours vers **la nouvelle réponse non lue** dans celui-ci. Pour entrer au début ou à la fin, sélectionnez le compteur de réponse ou alors la date de la dernière réponse. + - Sélectionner le titre d'un article, vous dirigera toujours vers **la nouvelle réponse non lue** dans celui-ci. Pour aller au début ou à la fin, sélectionnez le compteur de réponses ou la date de la dernière réponse. - - Pendant la lecture d'un article, sélectionnez la barre de progression au fond à droite pour utiliser les contrôles de navigation. Revenez directement au début en cliquant sur le titre de l'article. Utilisez '?' pour avoir la liste des raccourcis clavier super rapide. + - Pendant la lecture d'un article, sélectionnez la barre de progression en bas à droite pour utiliser les commandes de navigation. Revenez directement au début en cliquant sur le titre de l'article. Appuyez sur ? pour afficher la liste des raccourcis clavier. - ##Répondre + ## Répondre - - Pour répondre **de manière générale à une conversation**, utilisez tout en bas de celui-ci. + - Pour répondre **de manière générale à un sujete**, utilisez tout en bas de celle-ci. - Pour répondre à **une personne en particulier**, utilisez sur leur message. - - Pour répondre à **une nouvelle conversation**, utilisez qui se trouve à la droite du message. L'ancien et le nouveau sujet seront alors automatiquement liés. + - Pour répondre en initiant **un nouveau sujet**, utilisez qui se trouve à la droite du message. L'ancien et le nouveau sujet seront alors automatiquement liés. - Pour insérer une citation, sélectionnez le texte que vous souhaitez citer, cliquez sur n’importe quel bouton **Répondre**. Répétez autant de fois que nécessaire. + Votre réponse peut être mise page en utilisant soit du HTML simple, soit les syntaxes BBCode ou [Markdown](http://commonmark.org/help/) : + + Ceci est **gras**. + Ceci est gras. + Ceci est [b]gras<[/b]. + + Vous voulez apprendre Markdown ? [Suivez notre tutoriel interactif amusant de 10 minutes !](http://commonmark.org/help/tutorial/) + + Pour insérer une citation, sélectionnez le texte que vous souhaitez citer, puis cliquez sur n'importe quel bouton Répondre. Répétez l'opération pour insérer d'autres citations. - Pour signaler à quelqu'un votre réponse, mentionnez son nom. Mettez un '@' au début de son pseudo pour choisir un utilisateur. + Pour signaler à quelqu'un votre réponse, mentionnez son nom. Tapez un `@` pour commencer à choisir un utilisateur. - Pour utiliser [standard Emoji](http://www.emoji.codes/) (les émoticones), utilisez le caractère ':' et tapez son nom ou insérez des smileys de manière traditionnelle ;) + Pour insérer un [émoticône standard Emoji](http://www.emoji.codes/), utilisez le caractère `:` et tapez son nom ou utilisez des des émoticônes traditionnels comme `;)`. - Pour générer l'aperçu d'un lien, collez-le simplement dans la zone de texte : + Pour générer l'aperçu d'un lien, mettez le lien seul sur une ligne. - ##Actions + ## Actions Il y a des boutons d'actions en bas de chaque commentaire : - Pour prévenir quelqu'un que vous appréciez son commentaire, cliquez **sur le coeur**. Partagez votre amour ! + Pour prévenir quelqu'un que vous appréciez son commentaire, cliquez **sur le cœur**. Partagez votre amour ! - Si le commentaire de quelqu'un vous pose problème, prévenez [l'équipe de modération](%{base_url}/about) ou l'auteur en privé grâce au bouton **drapeau**. Vous pouvez aussi partager un lien vers le post ou le marquer comme **favori*** pour le mentionner plus tard dans votre page utilisateur. + Si un commentaire vous pose problème, prévenez soit son auteur en privé, soit [l'équipe de modération](%{base_url}/about) grâce au bouton **drapeau**. - ##Notifications + ## Notifications - Quand quelqu’un vous répond, vous cite ou vous mentionne '@pseudo', un numéro apparaitra immédiatement en haut à droite de la page. Cliquez dessus pour accéder aux **notifications**. + Quand quelqu'un vous répond, vous cite ou mentionne votre `@pseudo`, un numéro apparaîtra immédiatement en haut à droite de la page. Cliquez dessus pour accéder à vos **notifications**. - Pas de soucis si vous manquez une réponse, vous serez notifié par email de toutes les notifications pendant que vous n’êtes pas connecté. + N'ayez pas la crainte de manquer une réponse ; vous serez notifié par courriel de toutes les notifications survenant pendant que vous n'êtes pas connecté. - ##Vos préférences + ## Vos préférences - - Tout article de **moins de 2 jours** est considéré comme nouveau. + - Tout article vieux de **moins de 2 jours** est considéré comme nouveau. - - Toute conversation à laquelle vous avez **participé** (création, réponses ou lecture pendant une période prolongée) sera automatiquement suivie. + - Tout sujet auquel vous avez **participé** (création, réponses ou lecture pendant une période prolongée) sera automatiquement suivi. - Vous verrez “nouveau” en bleu et l’indicateur de quantité de notifications non lues en face de chaque article : + En face de ces articles, vous verrez en bleu la mention "nouveau" ou bien le nombre de messages non lues : - Vous pouvez changer les paramètres de notification de chaque article par le système de contrôle de notification accessible en bas de chaque article. + Vous pouvez changer les paramètres de notification de chaque article en utilisant la commande de notification, en bas de l'article. - Vous pouvez aussi configure l’état des notifications par catégorie si vous voulez voir chaque nouvel article dans une catégorie spécifique. + Vous pouvez aussi configurer les notifications par catégorie, si vous voulez voir chaque nouvel article d'une catégorie spécifique. - Pour changer n’importe lequel de ces paramètres, allez dans [vos préférences](%{base_url}/my/preferences). + Pour changer n'importe lequel de ces paramètres, allez dans [vos préférences](%{base_url}/my/preferences). - ##Une communauté basé sur la confiance - Par votre participation sur ici, au fur et à mesure vous gagnerez la confiance de la communauté, vous deviendrez un membre à part entière et les limitations fonctionnelles propres à chaque nouvel utilisateur seront levées. A un niveau de confiance [suffisamment élevé](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), vous aurez accès à de nouvelles fonctionnalités pouvant nous aider à gérer la communauté tous ensemble. + ## Une communauté basé sur la confiance - Nous croyons au comportement communautaire civilisé en tous temps. - - Amusez-vous bien ! - - (Si, en tant que nouvel utilisateur, vous avez besoin de communiquer avec un responsable, répondez simplement à ce message.) + Au fur et à mesure de votre participation, vous allez progressivement gagner la confiance de la communauté, vous deviendrez un membre à part entière et les limitations fonctionnelles propres à chaque nouvel utilisateur seront levées. À un niveau de confiance [suffisamment élevé](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), vous aurez accès à de nouvelles fonctionnalités vous permettant de nous aider à gérer la communauté. welcome_user: subject_template: "Bienvenue sur %{site_name} !" text_body_template: "Merci d'avoir rejoint %{site_name} et bienvenue ! \n\n%{new_user_tips}\n\nNous croyons au [comportement communautaire civilisé](%{base_url}/guidelines) en tous temps. \n\nAmusez-vous bien ! \n\n(Si, en tant que nouvel utilisateur, vous avez besoin de communiquer avec un [responsable](%{base_url}/about), répondez simplement à ce message.)\n" welcome_invite: subject_template: "Bienvenue sur %{site_name} !" - text_body_template: "Merci d'avoir accepté votre invitation sur %{site_name} et bienvenue !\n\nNous avons créé un nouveau compte : **%{username}**, et vous y êtes connecté. Vous pouvez changer votre pseudo en allant sur [votre profil][prefs].\n\nPour vous reconnecter :\n\n1. Toujours **utiliser la même adresse de courriel que celle de l'invitation** que vous avez reçue. Autrement, nous ne pourrons pas vous reconnaître.\n\n2. Créer un mot de passe unique sur votre [sur votre profil][prefs] et connectez-vous avec. \n\n%{new_user_tips}\n\nNous croyons au [comportement communautaire civilisé](%{base_url}/guidelines) en tous temps.\n\nAmusez-vous bien !\n\n(Si, en tant que nouvel utilisateur, vous avez besoin de communiquer avec un [responsable](%{base_url}/about), répondez simplement à ce message).\n\n[prefs] : %{user_preferences_url}\n" + text_body_template: "Merci d'avoir accepté votre invitation sur %{site_name} et bienvenue !\n\nNous avons créé un nouveau compte : **%{username}**, et vous y êtes connecté. Vous pouvez changer votre pseudo en allant sur [votre profil][prefs].\n\nPour vous reconnecter :\n\n1. Toujours **utiliser la même adresse de courriel que celle de l'invitation** que vous avez reçue. Autrement, nous ne pourrons pas vous reconnaître.\n\n2. Créer un mot de passe unique sur votre [sur votre profil][prefs] et connectez-vous avec. \n\n%{new_user_tips}\n\nNous croyons au [comportement communautaire civilisé](%{base_url}/guidelines) en tous temps.\n\nAmusez-vous bien !\n\n(Si, en tant que nouvel utilisateur, vous avez besoin de communiquer avec un [responsable](%{base_url}/about), répondez simplement à ce message).\n\n[prefs]: %{user_preferences_url}\n" backup_succeeded: subject_template: "Sauvegarde terminée avec succès" text_body_template: "La sauvegarde a bien réussie.\nVisitez [la section admin > sauvegarde](%{base_url}/admin/backups) pour télécharger votre nouvelle sauvegarde." @@ -1472,20 +1517,41 @@ fr: csv_export_failed: subject_template: "Échec de l'exportation des données " text_body_template: "Nous sommes désolés, l'exportation de vos données a échoué. Veuillez consultez les logs ou contactez un modérateur." - email_reject_trust_level: + email_reject_insufficient_trust_level: subject_template: "[%{site_name}] Incident d'email -- Niveau de confiance insuffisant " text_body_template: | - Nous sommes désolé, mais l'envoi de votre courriel à destination de {destination} (intitulé %{former_title}) n'a pas fonctionné. + Nous sommes désolé, mais l'envoi de votre courriel à destination de %{destination} (intitulé %{former_title}) n'a pas fonctionné. - Votre compte n'a pas le niveau de confiance requis pour créer un nouveau sujet via cette adresse de courriel. Si vous pouvez que c'est une erreur, contacter un membre de l'équipe du site. - email_reject_no_account: - subject_template: "[%{site_name}] Problème de courriel - Compte utilisateur inconnu" + Votre compte n'a pas le niveau de confiance requis pour créer un nouveau sujet via cette adresse de courriel. Si vous considérez que c'est une erreur, contacter un responsable. + email_reject_inactive_user: + subject_template: "[%{site_name}] Erreur de courriel -- Compte inactivé" text_body_template: | Malheureusement votre courriel à %{destination} (titled %{former_title}) a échoué. - Aucun compte d'utilisateur avec cette adresse existe. Essayez de l'envoyer depuis une autre adresse, ou contactez un membre de l'équipe. + Le compte associé avec cette adresse existe n'est pas activé. Veuillez activer votre compte avant d'envoyer des courriels. + email_reject_blocked_user: + subject_template: "[%{site_name}] Erreur de courriel -- Utilisateur bloqué" + text_body_template: | + Malheureusement votre courriel à %{destination} (titled %{former_title}) a échoué. + + Le compte associé avec cette adresse a été bloqué. + email_reject_reply_user_not_matching: + subject_template: "[%{site_name}] Problème de courriel - l'adresse de réponse ne correspond pas" + text_body_template: | + Malheureusement votre courriel à %{destination} (titled %{former_title}) a échoué. + + Votre réponses nous est parvenue d'une autre adresse courriel que celle attendue, nous ne savons donc pas s'il s'agit de la même personne. Essayez de l'envoyer depuis une autre adresse, ou contactez un responsable. + email_reject_no_account: + subject_template: "[%{site_name}] Problème de courriel - Compte utilisateur inconnu" + text_body_template: "Nous sommes désolé, mais l'envoi de votre courriel à destination de %{destination} (intitulé %{former_title}) n'a pas fonctionné.\n\nAucun compte d'utilisateur avec cette adresse existe. Essayez de l'envoyer depuis une autre adresse, ou contactez un membre de l'équipe. \n" email_reject_empty: subject_template: "[%{site_name}] Problème de courriel - sans contenu" + text_body_template: | + Nous sommes désolés, mais votre message envoyé à %{destination} (intitulé %{former_title}) n'a pu être être envoyé. + + Assurez-vous d'avoir écrit votre réponse au début de l'e-mail. + + Si vous obtenez ce message alors que vous _aviez_ inclus une réponse, réessayez avec un formatage plus simple de votre e-mail. email_reject_parsing: subject_template: "[%{site_name}] Problème de courriel - contenu non reconnu." text_body_template: | @@ -1498,40 +1564,56 @@ fr: Nous sommes désolé, mais votre email à destination de {destination} (intitulé %{former_title}) n'a pas fonctionné. Votre compte n'a pas les privilèges pour créer un nouveau sujet dans cette catégorie. Si vous trouvez que c'est une erreur, contacter l’équipe du site. - email_reject_post_error: + email_reject_strangers_not_allowed: + subject_template: "[%{site_name}] Problème de courriel -- Accès invalide" + text_body_template: | + Nous sommes désolé, mais l'envoi de votre courriel à destination de %{destination} (intitulé %{former_title}) n'a pas fonctionné. + + La catégorie à laquelle vous avez envoyé ce courriel ne permet des réponses que par des utilisateurs avec des comptes valides et des adresses courriels reconnues. Si vous considérez que c'est une erreur, contacter un membre de l'équipe du site. + email_reject_invalid_post: subject_template: "[%{site_name}] Incident d'email -- Erreur d'envoi d'un message" text_body_template: | - Nous sommes désolé, mais l'envoi de votre courriel à destination de {destination} (intitulé %{former_title}) n'a pas fonctionné. + Nous sommes désolé, mais l'envoi de votre courriel à destination de %{destination} (intitulé %{former_title}) n'a pas fonctionné. Cela peut-être à cause de: format trop complexe, message trop long ou trop court. Veuillez réessayer, ou rédigé votre message directement sur le site si le problème persiste. - email_reject_post_error_specified: + email_reject_invalid_post_specified: subject_template: "[%{site_name}] Incident d'email -- Erreur d'envoi d'un message" text_body_template: | - Nous sommes désolé, mais l'envoi de votre courriel à destination de {destination} (intitulé %{former_title}) n'a pas fonctionné. + Nous sommes désolé, mais l'envoi de votre courriel à destination de %{destination} (intitulé %{former_title}) n'a pas fonctionné. Raison: %{post_error} Si vous pouvez corriger les erreurs, veuillez réessayer. - email_reject_reply_key: - subject_template: "[%{site_name}] Problème de courriel -- Mauvaise clé de réponse" + email_reject_rate_limit_specified: + subject_template: "[%{site_name}] Problème de courriel -- Limitation du débit" + text_body_template: |+ + Nous sommes désolé, mais l'envoi de votre courriel à destination de %{destination} (intitulé %{former_title}) n'a pas fonctionné. + + Pour la raison suivante: %{rate_limit_description} + + email_reject_invalid_post_action: + subject_template: "[%{site_name}] Problème de courriel -- Action Post invalide" text_body_template: | Nous sommes désolé, mais l'envoi de votre courriel à destination de {destination} (intitulé %{former_title}) n'a pas fonctionné. - La clé de réponse du fournisseur est invalide ou inconnu, et nous ne pouvons pas savoir à quel sujet s’adresse cette réponse. Contactez un membre de l'équipe du site. - email_reject_destination: + Le Post Action n'était pas reconnu. Veuillez réessayer, ou rédigé votre message directement sur le site si le problème persiste. + email_reject_reply_key: + subject_template: "[%{site_name}] Problème de courriel -- Mauvaise clé de réponse" + text_body_template: "Nous sommes désolé, mais l'envoi de votre courriel à destination de%{destination} (intitulé %{former_title}) n'a pas fonctionné. \n\nLa clé de réponse du fournisseur est invalide ou inconnu, et nous ne pouvons pas savoir à quel sujet s’adresse cette réponse. Contactez un responsable. \n" + email_reject_bad_destination_address: subject_template: "[%{site_name}] Problème de courriel - Adresse de destinataire inconnue" text_body_template: | Nous sommes désolé, mais l'envoi de votre courriel à destination de {destination} (intitulé %{former_title}) n'a pas fonctionné. - Aucune adresse de destination n'est reconnue. Veuillez vérifier que l'adresse du site est bien renseignée dans le champs To: (et non dans les champs C:: ou Bcc:), et que vous envoyez bien à l'adresse de courriel fournie par l'équipe. + Aucune des adresses de destination n'est reconnue. Veuillez vérifier que vous envoyez bien à l'adresse de courriel fournie par l'équipe. email_reject_topic_not_found: subject_template: "[%{site_name}] Erreur de courriel -- Le sujet est introuvable" text_body_template: | - Nous sommes désolés, mais votre email à %{destination} (titled %{former_title}) n'a pas été envoyé. + Nous sommes désolés, mais votre email à %{destination} (intitulé %{former_title}) n'a pas été envoyé. - Le sujet auquel vous répondez n'existe plus, peut-être a-t-il été supprimé ? Si vous pensez qu'il s'agit d'une erreur, contactez un responsable. + Le sujet auquel vous répondez n'existe plus, peut-être a-t-il été supprimé? Si vous pensez qu'il s'agit d'une erreur, contactez un responsable. email_reject_topic_closed: subject_template: "[%{site_name}] Erreur de courriel -- Le sujet est fermé" text_body_template: | @@ -1540,16 +1622,15 @@ fr: Le sujet auquel vous répondez est actuellement fermé et n'accepte plus de réponses. Si vous pensez qu'il s'agit d'une erreur, contactez un responsable. email_reject_auto_generated: subject_template: "[%{site_name}] Problème de courriel - Réponse automatique" - text_body_template: | - Nous sommes désolés, mais votre email à %{destination} (titled %{former_title}) n'a pas été envoyé. - - Votre email a été marqué comme "automatiquement généré", ce que nous ne pouvons accepter. Si vous pensez qu'il s'agit d'une erreur, contactez un responsable. + text_body_template: "Nous sommes désolés, mais votre email à %{destination} (intitulé %{former_title}) n'a pas été envoyé.\n\nVotre email a été marqué comme \"automatiquement généré\" ce qui signifie qu'il était créer par un ordinateur au lieu d'être écrit par un humain; ce que nous ne pouvons accepter. Si vous pensez qu'il s'agit d'une erreur, contactez un responsable. \n" email_error_notification: subject_template: "[%{site_name}] Incident d'email -- Erreur d'authentification POP3" text_body_template: | - Il y a eu un erreur d'authentification lors de la récupération des courriels depuis le serveur POP. + Malheureusement il y a eu un erreur d'authentification lors de la récupération des courriels depuis le serveur POP. Assurez-vous que les paramètres de connexion POP sont corrects dans les [paramètres du site](%{base_url}/admin/site_settings/category/email). + + S'il y a une interface web pour le compte POP, vous devrez peut-être vous y connecter pour vérifier les paramètres. too_many_spam_flags: subject_template: "Nouveau compte bloqué" text_body_template: | @@ -1559,35 +1640,22 @@ fr: Par mesure de précaution, votre compte a été bloqué, vous ne pourrez par créer de nouvelles réponses ou sujets tant qu'un membre de l'équipe n'aura pas étudié votre compte. - Pour plus d'informations, merci de vous en référer au [règlement de la communauté](%{base_url}/guidelines). + Pour plus d'informations, merci de vous en référer à la [charte de la communauté](%{base_url}/guidelines). blocked_by_staff: subject_template: "Compte bloqué" - text_body_template: | - Bonjour, - - Ceci est un message automatique de %{site_name} pour vous informer que vos messages ont été bloqués par un membre de l'équipe. - - Pour plus d'informations, merci de vous en référer au [règlement de la communauté](%{base_url}/guidelines). user_automatically_blocked: subject_template: "Nouvel utilisateur %{username} bloqué à cause de signalements de la communauté" text_body_template: | - Ceci est un message automatique. + Ceci est un message automatique - Le nouvel utilisateur [%{username}](%{base_url}%{user_url}) a été bloqué automatiquement par plusieurs utilisateurs ayant signalés ses messages. + Le nouvel utilisateur [%{username}](%{user_url}) a été bloqué automatiquement par plusieurs utilisateurs ayant signalés ses (%{username}) messages. - Merci de [vérifier les signalements](%{base_url}/admin/flags). Si %{username} a été bloqué injustement, cliquez sur le bouton débloquer sur la [page d'administration de cet utilisateur](%{base_url}%{user_url}). + Merci de [vérifier les signalements](%{base_url}/admin/flags). Si %{username} a été bloqué injustement, cliquez sur le bouton débloquer sur la [page d'administration de cet utilisateur](%{user_url}). Cette limite peut être changée par le paramètre du site `block_new_user`. spam_post_blocked: subject_template: "Les messages du nouvel utilisateur %{username} sont bloqués pour des liens répétés" - text_body_template: | - Ceci est un message automatique. - - Le nouvel utilisateur [%{username}](%{base_url}%{user_url}) tente de créer de multiples messages avec des liens vers %{domains}, mais que ces messages ont été bloqués pour éviter le spam. Cet utilisateur est toujours capable de créer des messages qui ne contiennent pas de liens vers %{domains}. - - Merci de [vérifier cet utilisateur](%{base_url}%{user_url}). - - Ceci peut être modifier via les options `newuser_spam_host_threshold` et white_listed_spam_host_domains`. + text_body_template: "Ceci est un message automatique.\n\nLe nouvel utilisateur [%{username}](%{user_url}) tente de créer de multiples messages avec des liens vers %{domains}, mais que ces messages ont été bloqués pour éviter le spam. Cet utilisateur est toujours capable de créer des messages qui ne contiennent pas de liens vers %{domains}.\n\nMerci de [review the user](%{user_url}).\n\nCeci peut être modifier via les options `newuser_spam_host_threshold` et white_listed_spam_host_domains`. \n" unblocked: subject_template: "Compte débloqué" text_body_template: | @@ -1608,28 +1676,45 @@ fr: subject_template: "Téléchargement d'images distantes désactivé" text_body_template: "Le paramètre `download_remote_images_to_local` a été désactivé car la limite (`download_remote_images_threshold`) d'espace disque utilisé par les images vient d'être dépassée." unsubscribe_link: | - Pour ne plus recevoir ces courriels, visitez vos [préférences utilisateur](%{user_preferences_url}). - - Pour ne plus recevoir de notifications pour ce sujet en particulier, [cliquer ici](%{unsubscribe_url}). + Pour ne plus recevoir de notifications pour ce sujet, [cliquez ici](%{unsubscribe_url}). Pour ne plus recevoir ces courriels, visitez vos [préférences utilisateur](%{user_preferences_url}). + unsubscribe_via_email_link: | + ou, [cliquer ici](mailto:reply@%{hostname}?subject=unsubscribe) pour se désinscrire par courriel. subject_re: "Re:" subject_pm: "[MP]" user_notifications: previous_discussion: "Réponses précédentes" + in_reply_to: "En réponse à" unsubscribe: title: "Désabonnement" description: "Ces courriels ne vous intéressent pas ? Aucun problème ! Cliquez ci-dessous pour vous désabonner immédiatement :" - reply_by_email: "Pour répondre, faites une réponse à ce courriel ou visitez %{base_url}%{url} avec votre navigateur." - visit_link_to_respond: "Pour répondre, visitez %{base_url}%{url} avec votre navigateur." + reply_by_email: "[Visiter sujet](%{base_url}%{url}) ou répondre à ce courriel pour répondre." + reply_by_email_pm: "[Visiter message](%{base_url}%{url}) ou répondre à ce courriel pour répondre." + only_reply_by_email: "Répondre à ce courriel pour répondre" + visit_link_to_respond: "[Visiter sujet](%{base_url}%{url}) pour répondre." + visit_link_to_respond_pm: "[Visiter message](%{base_url}%{url}) pour répondre." posted_by: "Ecrit par %{username} le %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} vous a invité dans la conversation '%{topic_title}'" - text_body_template: "\n%{username} vous a invité dans un message\n\n> **%{topic_title}**\n>\n> %{topic_excerpt}\n\nsur \n\n> %{site_title} -- %{site_description}\n\nVeuillez suivre ce lien pour voir le message: %{base_url}%{url}\n" + user_invited_to_private_message_pm_staged: + subject_template: "[%{site_name}] %{username} vous a invité à voir un message '%{topic_title}'" user_invited_to_topic: subject_template: "[%{site_name}] %{username} vous a invité dans le sujet '%{topic_title}'" - text_body_template: "\n%{username} vous a invité à une conversation\n\n> **%{topic_title}**\n>\n> %{topic_excerpt}\n\nsur \n\n> %{site_title} -- %{site_description}\n\nVeuillez suivre ce lien pour voir le message: %{base_url}%{url}\n" user_replied: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_replied_pm: + subject_template: "[%{site_name}] [PM] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1639,6 +1724,19 @@ fr: user_quoted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_linked: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1648,6 +1746,19 @@ fr: user_mentioned: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1657,6 +1768,8 @@ fr: user_posted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1666,10 +1779,20 @@ fr: user_posted_pm: subject_template: "[%{site_name}] [MP] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} + --- + %{respond_instructions} + user_posted_pm_staged: + subject_template: "%{optional_re}%{topic_title}" + text_body_template: |2 + + %{message} + --- %{respond_instructions} digest: @@ -1710,14 +1833,34 @@ fr: text_body_template: | Un nouveau compte utilisateur a été créé pour vous sur {site_name} - Cliquez sur le liens ci-dessous pour choisir un mot de passe pour votre nouveau compte: + Cliquez sur le lien ci-dessous pour choisir un mot de passe pour votre nouveau compte : %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Confirmation de votre nouvelle adresse de courriel" + confirm_new_email: + subject_template: "[%{site_name}] Confirmer votre nouvelle adresse courriel" text_body_template: | - Confirmez votre nouvelle adresse de courriel pour %{site_name} en cliquant sur le lien suivant : + Confirmer votre nouvelle adresse courriel pour %{site_name} en cliquant sur le lien suivant : %{base_url}/users/authorize-email/%{email_token} + confirm_old_email: + subject_template: "[%{site_name}] Confirmer votre adresse courriel actuelle" + text_body_template: | + Avant de pouvoir changer votre adresse courriel, nous devons confirmer que vous contrôlez + bien l'adresse actuelle. Après avoir effectuée cette étape, vous devrez confirmer + la nouvelle adresse courriel. + + Confirmer votre adresse courriel actuelle pour %{site_name} en cliquant sur le lien suivant : + + %{base_url}/users/authorize-email/%{email_token} + notify_old_email: + subject_template: "[%{site_name}] Votre adresse courriel a bien été modifiée" + text_body_template: | + Ceci est un message automatique pour vous informer que votre adresse courriel pour + %{site_name} a été modifiée. Si c'est une erreur, merci de contacter + un administrateur du site. + + Votre adresse courriel a été modifiée pour : + + %{new_email} signup_after_approval: subject_template: "Votre compte a été approuvé sur %{site_name} !" text_body_template: | @@ -1746,7 +1889,7 @@ fr: Si le lien ci-dessus n'est pas cliquable, essayez de le copier et coller dans la barre d'adresse de votre navigateur web. page_not_found: - title: "La page que vous avez demandé n'existe pas ou est privée." + title: "Oops! Cette page n'existe pas ou est privée." popular_topics: "Populaires" recent_topics: "Récents" see_more: "Plus" @@ -1792,7 +1935,7 @@ fr: color_schemes: base_theme_name: "Base" about: "A propos" - guidelines: "Règlement" + guidelines: "Charte" privacy: "Protection des données" edit_this_page: "Modifier cette page" csv_export: @@ -1801,16 +1944,8 @@ fr: static_topic_first_reply: | Modifier le premier message de ce sujet pour changer le contenu de la page %{page_name}. guidelines_topic: - title: "FAQ/Règlement" - body: "\n\n## [Ceci est un endroit civilisé, merci de le respecter](#civilized)\n\nMerci de traiter ce forum de discussion avec le même respect que vous pourriez avoir dans un parc public. Nous, aussi, sommes une ressource partagée par la communauté — un endroit pour partager des compétences, savoirs et intérêts au travers de conversations.\n\nIl ne s'agit pas de règles absolues, uniquement d'aide au bon sens de notre communauté. Suivez ces instructions pour garder cet endroit propre et bien éclairé pour un débat public civilisé.\n\n\n\n## [Améliorez la discussion](#improve)\n\nAidez nous à faire de cet endroit un lieu idéal pour la discussion en améliorant constamment le débat d'une certaine façon, même minime. Si vous n'êtes pas sûr que votre message soit utile à la discussion\ - \ ou pourrait nuire à son utilité, pensez à ce que vous voulez dire et essayer de nouveau plus tard.\n\nLes sujets abordés ici sont importants pour nous et nous voulons que vous agissiez comme s'ils comptaient également pour vous. Soyez respectueux des sujets et des autres utilisateurs, même si vous êtes en désaccord avec une partie de ce qui est dit.\n\nUne façon d'améliorer la discussion est de découvrir celles qui sont déjà en cours. Essayez de passez un peu de temps à parcourir les sujets avant de répondre ou démarrer votre propre discussion. De fait, vous aurez de plus grandes chances de rencontrer d'autres personnes qui partagent vos intérêts.\n\n\n\n## [Soyez agréable, même si vous n'êtes pas d'accord](#agreeable)\n\nLa critique peut être constructive. Vous pouvez répondre à une personne en étant\ - \ en désaccord avec elle. C'est très bien. Mais n'oubliez pas de *critiquer les idées, pas les gens*. Merci d'éviter :\n\n* les injures,\n* les attaques ad hominem,\n* de répondre à la tonalité d'un sujet plutôt qu'à son contenu réel,\n* les contradictions primaires.\n \nAu lieu de cela, fournissez des contre-arguments motivés qui améliorent la conversation.\n\n\n\n## [Votre participation compte](#participate)\n\nLes conversations que nous avons ici donnent le ton pour tout le monde. Aidez-nous à influencer l'avenir de cette communauté en choisissant de vous engager dans des discussions qui font de ce forum un lieu intéressant — et en évitant celles qui n'y participent pas.\n\nDiscourse fournit des outils qui permettent à la communauté d'identifier collectivement le meilleur (et le pire) des contributions\ - \ : favoris, signets, des *J'aime*, des signalements, des réponses, des vérifications et ainsi de suite. Utilisez ces outils pour améliorer votre propre expérience et celle de tous les autres aussi.\n\nEssayons de laisser notre parc mieux que nous l'avons trouvé.\n\n\n\n## [Si vous voyez un problème, signaler le](#flag-problems)\n\nLes modérateurs ont un rôle spécial ; ils sont responsables de ce forum. Mais vous aussi. Avec votre aide, les modérateurs peuvent être des facilitateurs de la vie de la communauté et pas seulement des concierges ou des policiers.\n\nQuand vous voyez un mauvais comportement, ne répondez pas. Votre reconnaissance encourage le mauvais comportement, il consomme votre énergie et fait perdre du temps à chacun. *Signalez-le*. Si suffisamment de signalements s'accumulent, des\ - \ mesures seront prises, automatiquement ou par l'intervention d'un modérateur.\n\nAfin de maintenir notre communauté, les modérateurs se réservent le droit de supprimer tout contenu et n'importe quel compte utilisateur pour une raison quelconque, et ce à n'importe quel moment. Les modérateurs ne disposent pas d'un aperçu des nouveaux messages avant leur publication, les modérateurs et opérateurs du site n'assument aucune responsabilité pour tout contenu affiché par la communauté.\n\n\n\n## [Soyez toujours civilisé](#be-civil)\n\nRien ne sabote une conversation saine mieux que la grossièreté :\n\n* Soyez civilisé. Ne postez pas ce qu'une personne raisonnable jugerait offensif, ni de discours violent ou haineux.\n* Gardez-le forum propre. Ne publiez rien d'obscène ou sexuellement explicite.\n* Se respecter\ - \ mutuellement est primordial. Ne pas harceler ou chagriner quelqu'un, ni usurper l'identité de quelqu'un ou exposer des informations privées le concernant.\n* Respecter notre forum. Ne postez pas de spam ou tout autre forme de vandalisme.\n \nIl ne s'agit pas ici de choses concrètes avec des définitions précises - évitez *même d'avoir l'air* d'agir de la sorte. Si vous avez un doute, demandez-vous comment vous vous sentiriez si votre sujet était publié sur la première page du Monde.\n\nIl s'agit d'un forum public et les moteurs de recherche indexent ces discussions. Utilisez un langage, des liens et des images sans danger pour votre famille et vos amis.\n\n\n\n## [Gardez cet endroit propre](#keep-tidy)\n\nFaites l'effort de mettre les choses au bon endroit, afin que nous puissions passer plus de temps\ - \ à discuter et moins à ranger. Ainsi :\n\n* Ne commencez pas un sujet dans la mauvaise catégorie.\n* Ne postez pas le même contenu dans plusieurs discussions.\n* Ne postez pas de message sans contenu.\n* Ne pas détourner un sujet en le changeant en cours de route.\n* Ne signez pas vos messages — chaque message dispose d'informations sur le profil qui s'y rattache.\n\nPlutôt que de poster \"+1\", \"lol\", \"mdr\" ou \"d'accord\", utilisez le bouton 'J'aime'. Plutôt que de faire prendre à une discussion existante une direction radicalement différente, utilisez \"Répondre en créant un sujet lié\". \n\n\n\n## [Postez seulement vos propres trucs](#stealing)\n\nVous ne pouvez pas poster n'importe quel contenu numérique s'il appartient à quelqu'un d'autre sans son autorisation. Vous ne pouvez pas poster\ - \ des descriptions, des liens ou des méthodes pour voler la propriété intellectuelle de quelqu'un (logiciels, vidéo, audio, images), ou pour transgresser toute autre loi.\n\n\n\n## [Powered by You](#power)\n\nCe site est géré par votre [équipe de responsables](/about) ainsi que *vous*, la communauté. Si vous avez d'autres questions sur comment les choses devraient fonctionner ici, créez un nouveau sujet dans [la catégorie meta](/c/meta) et discutons-en ! S'il y un problème critique ou urgent qui ne peut pas être résolu par un sujet meta ou un signalement, contactez nous [ici](/about). \n\n\n\n## [Lisez les conditions générales d'utilisation](#tos)\n\nOui, le jargon juridique est ennuyeux, mais nous devons nous protéger – et par extension, vous et vos données – contre des gens\ - \ hostiles. Nous avons des [Conditions générales d'utilisation](/tos) décrivant votre (et notre) comportement et les droits liés au contenu, la confidentialité et les lois. Pour utiliser ce service, vous devez accepter de respecter nos [CGU](/tos).\n" + title: "FAQ/Charte" + body: "\n\n## [Ceci est un endroit civilisé, merci de le respecter](#civilized)\n\nMerci de traiter ce forum de discussion avec le même respect que vous pourriez avoir dans un parc public. Nous, aussi, sommes une ressource partagée par la communauté — un endroit pour partager des compétences, savoirs et intérêts au travers de conversations.\n\nIl ne s'agit pas de règles absolues, uniquement d'aide au bon sens de notre communauté. Suivez ces instructions pour garder cet endroit propre et bien éclairé pour un débat public civilisé.\n\n\n\n## [Améliorez la discussion](#improve)\n\nAidez nous à faire de cet endroit un lieu idéal pour la discussion en améliorant constamment le débat d'une certaine façon, même minime. Si vous n'êtes pas sûr que votre message soit utile à la discussion ou pourrait nuire à son utilité, pensez à ce que vous voulez dire et essayer de nouveau plus tard.\n\nLes sujets abordés ici sont importants pour nous et nous voulons que vous agissiez comme s'ils comptaient également pour vous. Soyez respectueux des sujets et des autres utilisateurs, même si vous êtes en désaccord avec une partie de ce qui est dit.\n\nUne façon d'améliorer la discussion est de découvrir celles qui sont déjà en cours. Essayez de passez un peu de temps à parcourir les sujets avant de répondre ou démarrer votre propre discussion. De fait, vous aurez de plus grandes chances de rencontrer d'autres personnes qui partagent vos intérêts.\n\n\n\n## [Soyez agréable, même si vous n'êtes pas d'accord](#agreeable)\n\nLa critique peut être constructive. Vous pouvez répondre à une personne en étant en désaccord avec elle. C'est très bien. Mais n'oubliez pas de *critiquer les idées, pas les gens*. Merci d'éviter :\n\n* les injures,\n* les attaques ad hominem,\n* de répondre à la tonalité d'un sujet plutôt qu'à son contenu réel,\n* les contradictions primaires.\n \nAu lieu de cela, fournissez des contre-arguments motivés qui améliorent la conversation.\n\n\n\n## [Votre participation compte](#participate)\n\nLes conversations que nous avons ici donnent le ton pour tout le monde. Aidez-nous à influencer l'avenir de cette communauté en choisissant de vous engager dans des discussions qui font de ce forum un lieu intéressant — et en évitant celles qui n'y participent pas.\n\nDiscourse fournit des outils qui permettent à la communauté d'identifier collectivement le meilleur (et le pire) des contributions : favoris, signets, des *J'aime*, des signalements, des réponses, des vérifications et ainsi de suite. Utilisez ces outils pour améliorer votre propre expérience et celle de tous les autres aussi.\n\nEssayons de laisser notre parc mieux que nous l'avons trouvé.\n\n\n\n## [Si vous voyez un problème, signaler le](#flag-problems)\n\nLes modérateurs ont un rôle spécial ; ils sont responsables de ce forum. Mais vous aussi. Avec votre aide, les modérateurs peuvent être des facilitateurs de la vie de la communauté et pas seulement des concierges ou des policiers.\n\nQuand vous voyez un mauvais comportement, ne répondez pas. Votre reconnaissance encourage le mauvais comportement, il consomme votre énergie et fait perdre du temps à chacun. *Signalez-le*. Si suffisamment de signalements s'accumulent, des mesures seront prises, automatiquement ou par l'intervention d'un modérateur.\n\nAfin de maintenir notre communauté, les modérateurs se réservent le droit de supprimer tout contenu et n'importe quel compte utilisateur pour une raison quelconque, et ce à n'importe quel moment. Les modérateurs ne disposent pas d'un aperçu des nouveaux messages avant leur publication, les modérateurs et opérateurs du site n'assument aucune responsabilité pour tout contenu affiché par la communauté.\n\n\n\n## [Soyez toujours civilisé](#be-civil)\n\nRien ne sabote une conversation saine mieux que la grossièreté :\n\n* Soyez civilisé. Ne postez pas ce qu'une personne raisonnable jugerait offensif, ni de discours violent ou haineux.\n* Gardez-le forum propre. Ne publiez rien d'obscène ou sexuellement explicite.\n* Se respecter mutuellement est primordial. Ne pas harceler ou chagriner quelqu'un, ni usurper l'identité de quelqu'un ou exposer des informations privées le concernant.\n* Respecter notre forum. Ne postez pas de spam ou tout autre forme de vandalisme.\n \nIl ne s'agit pas ici de choses concrètes avec des définitions précises - évitez *même d'avoir l'air* d'agir de la sorte. Si vous avez un doute, demandez-vous comment vous vous sentiriez si votre sujet était publié sur la première page du Monde.\n\nIl s'agit d'un forum public et les moteurs de recherche indexent ces discussions. Utilisez un langage, des liens et des images sans danger pour votre famille et vos amis.\n\n\n\n## [Gardez cet endroit propre](#keep-tidy)\n\nFaites l'effort de mettre les choses au bon endroit, afin que nous puissions passer plus de temps à discuter et moins à ranger. Ainsi :\n\n* Ne commencez pas un sujet dans la mauvaise catégorie.\n* Ne postez pas le même contenu dans plusieurs discussions.\n* Ne postez pas de message sans contenu.\n* Ne pas détourner un sujet en le changeant en cours de route.\n* Ne signez pas vos messages — chaque message dispose d'informations sur le profil qui s'y rattache.\n\nPlutôt que de poster \"+1\", \"lol\", \"mdr\" ou \"d'accord\", utilisez le bouton 'J'aime'. Plutôt que de faire prendre à une discussion existante une direction radicalement différente, utilisez \"Répondre en créant un sujet lié\". \n\n\n\n## [Postez seulement vos propres trucs](#stealing)\n\nVous ne pouvez pas poster n'importe quel contenu numérique s'il appartient à quelqu'un d'autre sans son autorisation. Vous ne pouvez pas poster des descriptions, des liens ou des méthodes pour voler la propriété intellectuelle de quelqu'un (logiciels, vidéo, audio, images), ou pour transgresser toute autre loi.\n\n\n\n## [Powered by You](#power)\n\nCe site est géré par votre [équipe de responsables](/about) ainsi que *vous*, la communauté. Si vous avez d'autres questions sur comment les choses devraient fonctionner ici, créez un nouveau sujet dans [la catégorie meta](/c/meta) et discutons-en ! S'il y un problème critique ou urgent qui ne peut pas être résolu par un sujet meta ou un signalement, contactez nous [ici](/about). \n\n\n\n## [Lisez les conditions générales d'utilisation](#tos)\n\nOui, le jargon juridique est ennuyeux, mais nous devons nous protéger – et par extension, vous et vos données – contre des gens hostiles. Nous avons des [Conditions générales d'utilisation](/tos) décrivant votre (et notre) comportement et les droits liés au contenu, la confidentialité et les lois. Pour utiliser ce service, vous devez accepter de respecter nos [CGU](/tos).\n" tos_topic: title: "Conditions générales d'utilisation" privacy_topic: @@ -1895,55 +2030,11 @@ fr: Si nous décidons de changer notre politique de confidentialité, nous afficherons ces modifications sur cette page. Ce document est soumis à la licence creative commons CC-BY-SA. Il a été mis à jour le 31 mai 2013. badges: - long_descriptions: - autobiographer: | - Ce badge est accordé au remplissage de votre profil utilisateur et au choix d'une photo de profil. En dire plus à la communauté sur vous et vos intérêts permet de la rendre plus agréable et plus connectée. - first_like: | - Ce badge est accordé la première fois que vous aimez un message en utilisant le bouton :heart:. Aimer des messages est le moyen parfait pour dire aux autres membres de la communauté que ce qu'ils ont posté était intéressant, utile, cool, ou amusant. - first_link: | - Ce badge est accordé la première fois que vous placez un lien vers un autre sujet dans une de vos réponses. Lier des sujets aide les autres lecteurs à trouver des conversations proches potentiellement intéressantes, en montrant les connexions entre sujets dans les deux directions. - first_quote: | - Ce badge est accordé la première fois que vous citez un message dans une de vos réponses. Citer des passages pertinents des messages précédents dans votre réponse aide à garder les discussions ciblées et à rester dans le sujet. - first_share: | - Ce badge est accordé la première fois que vous partagez un lien vers une réponse ou un sujet en utilisant le bouton de partage. Partager des liens est un très bon moyen de diffuser des discussions intéressantes auprès du reste du monde et de faire grandir votre communauté. - read_guidelines: | - Ce badge est accordé après lecture des règles de la communauté. Respecter et partager ces règles simples permet de construire une communauté sure, agréable et durable. - reader: | - Ce badge est accordé après lecture d'un long sujet. Lire est fondamental. Lire attentivement vous aide à suivre une conversation et mène à des réponses meilleures et plus complètes. - editor: | - Ce badge est accordé après édition d'un de vos messages. N'hésitez pas à éditer vos messages à n'importe quel moment pour les améliorer, corriger de petites erreurs, ou ajouter quelque chose que vous auriez oublié. - first_flag: | - Ce badge est accordé après signalement d'un message. Les signalements sont essentiels à la santé de votre communauté. Si vous remarquez des messages nécessitant l'intervention d'un modérateur n'hésitez pas à les signaler. Vous pouvez aussi utiliser les boîtes de dialogue de signalement pour envoyer des messages à d'autres utilisateurs. - nice_share: | - Ce badge est accordé après le partage d'un lien vers un message consulté par 25 visiteurs extérieurs. Bien joué ! Partager des liens vers des discussions intéressantes auprès de vos amis est un excellent moyen de faire grandir votre communauté. - welcome: | - Ce badge est accordé lorsque vous recevez votre premier "J'aime" sur un de vos messages. Félicitations, vous avez écrit quelque chose que les membres de votre communauté ont trouvé intéressant, cool, ou utile ! - anniversary: | - Ce badge est accordé après avoir été membre du site pendant une année, avec au moins un message crée. Merci d'être resté avec nous et de contribuer ainsi à notre communauté ! - good_share: | - Ce badge est accordé après le partage d'un lien vers un message consulté par 300 visiteurs extérieurs. Bon travail ! Vous avez diffusé une discussion intéressante à beaucoup de nouvelles personnes et nous avez aidés à grandir. - great_share: | - Ce badge est accordé après le partage d'un lien vers un message consulté par 100 visiteurs extérieurs. Wow ! Vous avez fait la promotion d'une discussion intéressante auprès d'une énorme nouvelle audience pour le compte de cette communauté, et nous avez beaucoup aidé à grandir. - nice_post: | - Ce badge est accordé après la création d'une réponse ayant reçu 10 "J'aime". Bien joué ! - nice_topic: | - Ce badge est accordé après la création d'un sujet ayant reçu 10 "J'aime". Bien joué ! - good_post: | - Ce badge est accordé après la création d'une réponse ayant reçu 25 "J'aime". Bon travail ! - good_topic: | - Ce badge est accordé après la création d'un sujet ayant reçu 25 "J'aime". Bon travail ! - great_post: | - Ce badge est accordé après la création d'un message ayant reçu 50 "J'aime". Wow ! - great_topic: | - Ce badge est accordé après la création d'une réponse ayant reçu 50 "J'aime". Wow ! - basic: | + basic_user: + name: Actif + description: Accordé toutes les fonctions communautaires essentielles sont accessibles + long_description: | Ce badge est accordé lorsque vous atteignez le niveau de confiance 1. Merci d'être resté dans le coin un petit moment et d'avoir lu quelques sujets pour en apprendre plus sur notre communauté. Vos restrictions "nouvel utilisateur" ont été levées, et vous avez accès aux fonctionnalités essentielles telles que la messagerie personnelle, le signalement, l'édition des wikis, et la possibilité de poster des images et de multiples liens. - member: | - Ce badge est accordé lorsque vous atteignez le niveau de confiance 2. Merci d'avoir participé durant plusieurs semaines à notre communauté. Vous pouvez désormais envoyer des invitations personnelles depuis votre page utilisateur ou un sujet, des messages groupés, et quelques "J'aime" supplémentaires chaque jour. - regular: | - Ce badge est accordé lorsque vous atteignez le niveau de confiance 3. Merci d'avoir été un participant régulier à notre communauté pendant ces quelques mois, l'un de nos lecteurs les plus actifs et un contributeur sérieux à ce qui rend notre communauté si belle. Vous pouvez désormais recatégoriser et renommer des sujets, accéder à la section privée, signaler des spams, et vous avez plein de "J'aime" en plus chaque jour. - leader: | - Ce badge est accordé lorsque vous atteignez le niveau de confiance 4. Vous êtes un meneur choisi par l'équipe dans cette communauté, et vous montrez l'exemple dans vos actions et vos mots. Vous avez la capacité d'éditer tous les messages, utiliser les actions de modérations telles qu'épingler, fermer, cacher, archiver, scinder et réunir, ainsi que des tonnes de "J'aime" par jour. admin_login: success: "Courriel envoyé" error: "Erreur !" @@ -1954,3 +2045,10 @@ fr: performance_report: initial_post_raw: Ce sujet comprend des rapports de performance journaliers concernant votre site. initial_topic_title: Rapports de performances du site + topic_invite: + user_exists: "Désolé, cet utilisateur a déjà été invité. Vous ne pouvez inviter un utilisateur qu'une seule fois par sujet." + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.gl.yml b/config/locales/server.gl.yml new file mode 100644 index 00000000000..ec595498c70 --- /dev/null +++ b/config/locales/server.gl.yml @@ -0,0 +1,484 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +gl: + dates: + short_date_no_year: "D MMM" + short_date: "D MMM, YYYY" + long_date: "D MMMM, YYYY h:mm a" + datetime_formats: &datetime_formats + formats: + short: "%d-%m-%Y" + short_no_year: "%-d de %B" + date_only: "%-d de %B, %Y" + date: + month_names: [null, Xaneiro, Febreiro, Marzo, Abril, Maio, Xuño, Xullo, Agosto, Setembro, Outubro, Novembro, Decembro] + <<: *datetime_formats + title: "Discourse" + topics: "Temas" + posts: "publicacións" + loading: "Cargndo" + log_in: "Iniciar sesión" + anonymous: "Anónimo" + errors: &errors + format: '%{attribute} %{message}' + messages: + taken: "xa está en uso" + accepted: debe ser aceptado + blank: non pode quedar baleiro + present: debe quedar baleiro + confirmation: "%{attribute} non coincide" + empty: non pode quedar baleiro + equal_to: debe ser igual a %{count} + exclusion: está reservado + greater_than: debe ser maior de %{count} + greater_than_or_equal_to: debe ser igual ou maior de %{count} + has_already_been_used: "xa está en uso" + inclusion: no está incluído na lista + invalid: é incorrecto + less_than: debe ser menor de %{count} + less_than_or_equal_to: debe ser igual ou menor de %{count} + not_a_number: non é un número + not_an_integer: debe ser un enteiro + odd: debe ser impar + record_invalid: 'Fallou a validación: %{errors}' + restrict_dependent_destroy: + one: "Non é posíbel eliminalo porque existe outro %{record} dependente" + many: "Non é posíbel eliminalo porque existen outros %{record} dependentes" + too_long: + one: demasiado longo (máximo un caracterer) + other: demasiado longo (máximo %{count} caracteres) + too_short: + one: demasiado curto (mínimo un caracter) + other: demasiado curto (mínimo %{count} caracteres) + other_than: "debe ser distinto de %{count}" + template: + body: 'Producíronse problemas cos seguintes campos:' + embed: + load_from_remote: "Produciuse un erro cargando esta publicación." + site_settings: + min_username_length_range: "O mínimo non pode ser maior que o máximo." + not_logged_in: "Debes iniciar sesión para facer iso." + not_found: "Non foi posíbel atopar o recurso ou URL solicitado." + invalid_access: "Non se che permite ver o recurso solicitado." + read_only_mode_enabled: "O sitio está en modo só-lectura. As interaccións están desactivadas." + reading_time: "Tempo de lectura" + likes: "Gústames" + embed: + start_discussion: "Comezar a discusión" + continue: "Continuar a discusión" + more_replies: + one: "Unha resposta máis" + other: "%{count} respostas máis" + loading: "Cargando a discusión..." + permalink: "Ligazón permanente" + in_reply_to: "▶ %{username}" + replies: + one: "Unha resposta" + other: "%{count} respostas" + no_mentions_allowed: "Sentímolo pero non podes mencionar outros usuarios" + has_already_been_used: "xa está en uso" + invalid_characters: "contén caracteres incorrectos" + next_page: "páxina seguinte →" + prev_page: "← páxina anterior" + page_num: "Páxina %{num}" + home_title: "Inicio" + rss_posts_in_topic: "Fonte RSS de '%{topic}»" + author_wrote: "%{author} escribiu:" + num_posts: "Publicacións:" + num_participants: "Participantes:" + read_full_topic: "Ler todo o tema" + private_message_abbrev: "Msx." + rss_description: + latest: "Últimos temas" + hot: "Temas quentes" + posts: "Últimas publicacións" + too_late_to_edit: "Esta publicación ten moito tempo. Xa non se pode modificar nin eliminar." + excerpt_image: "imaxe" + queue: + delete_reason: "Eliminación por medio da cola de moderación de publicacións" + groups: + default_names: + everyone: "todos" + admins: "administradores" + moderators: "moderadores" + staff: "equipo" + trust_level_0: "nivel_de_confianza_0" + trust_level_1: "nivel_de_confianza_1" + trust_level_2: "nivel_de_confianza_2" + trust_level_3: "nivel_de_confianza_3" + trust_level_4: "nivel_de_confianza_4" + education: + until_posts: + one: "Unha publicación" + other: "%{count} publicacións" + activerecord: + attributes: + category: + name: "Nome da categoría" + post: + raw: "Corpo" + user_profile: + bio_raw: "Verbo de min" + errors: + models: + topic: + attributes: + base: + warning_requires_pm: "Só podes anexar avisos a mensaxes privadas." + no_user_selected: "Debes seleccionar un usuario correcto." + user: + attributes: + password: + common: "é un dos 10000 contrasinais máis habituais. Usa un máis seguro." + same_as_username: "é igual ao teu nome de usuario. Usa un contrasinal máis seguro." + same_as_email: "é igual ao teu correo electrónico. Usa un contrasinal máis seguro." + ip_address: + signup_not_allowed: "Non esta permitido rexistrarse desde esta conta." + color_scheme_color: + attributes: + hex: + invalid: "non é unha cor válida" + <<: *errors + vip_category_name: "Taberna" + vip_category_description: "Unha categoría exclusiva para membros cun nivel de confianza igual ou maior a 3." + meta_category_name: "Opinións sobre o sitio" + meta_category_description: "Discusións sobre este sitio, a súa organización, como funciona e como se pode mellorar." + staff_category_name: "Equipo" + staff_category_description: "Categoría privada para discusións do equipo. Os temas son visíbeis unicamente para administradores e moderadores." + lounge_welcome: + title: "Benvido/a á Taberna" + category: + topic_prefix: "Sobre a categoría %{category}" + errors: + depth: "Non podes aniñar unha subcategoría dentro doutra" + trust_levels: + newuser: + title: "novo usuario" + basic: + title: "usuario básico" + member: + title: "membro" + regular: + title: "normal" + leader: + title: "líder" + rate_limiter: + hours: + one: "Unha hora" + other: "%{count} horas" + datetime: + distance_in_words: + half_a_minute: "< 1m" + less_than_x_seconds: + one: "< 1s" + other: "< %{count}s" + x_seconds: + one: "1s" + other: "%{count}s" + less_than_x_minutes: + one: "< 1m" + other: "< %{count}m" + about_x_hours: + one: "1h" + other: "%{count}h" + x_days: + one: "1d" + other: "%{count}d" + about_x_months: + one: "1mes" + other: "%{count}mes" + x_months: + one: "1mes" + other: "%{count}mes" + about_x_years: + one: "1ano" + other: "%{count}ano" + over_x_years: + one: "> 1ano" + other: "> %{count}ano" + almost_x_years: + one: "1ano" + other: "%{count}ano" + distance_in_words_verbose: + half_a_minute: "agora mesmiño" + password_reset: + choose_new: "Selecciona un novo contrasinal" + choose: "Selecciona un contrasinal" + update: 'Actualizar contrasinal' + save: 'Estabelecer o contrasinal' + title: 'Contrasinal restabelecido' + continue: "Continuar a %{site_name}" + change_email: + confirmed: "O teu correo electrónico foi actualizado." + please_continue: "Continuar a %{site_name}" + error: "Produciuse un erro cambiando o enderezo de correo electrónico. Quizais xa está en uso?" + activation: + action: "Preme aquí para activar a conta" + continue_button: "Continuar a %{site_name}" + welcome_to: "Benvido/a a %{site_name}!" + post_action_types: + off_topic: + title: 'Sen-relación' + long_form: 'marcou isto como non relacionado' + spam: + title: 'Spam' + long_form: 'denunciou isto como spam' + inappropriate: + title: 'Inapropiado' + long_form: 'denunciou isto como inapropiado' + notify_moderators: + title: "Algo máis" + description: 'Esta publicación require a atención dos responsábeis do sitio por unha razón non listada arriba.' + long_form: 'denunciou isto para revisión polo equipo' + email_title: 'Unha publicación en «%{title}» require a atención dos responsábeis do sitio' + bookmark: + title: 'Marcador' + description: 'Marcar esta publicación' + long_form: 'Marcar este tema' + like: + title: 'Gústame' + description: 'Gústame esta publicación' + long_form: 'gustoume isto' + vote: + title: 'Votar' + description: 'Votar por esta publicación' + long_form: 'votei esta publicación' + topic_flag_types: + spam: + title: 'Spam' + long_form: 'denunciou isto como spam' + inappropriate: + title: 'Inapropiado' + long_form: 'denunciou isto como inapropiado' + notify_moderators: + title: "Algo máis" + long_form: 'denunciou isto para revisión por un moderador' + archetypes: + regular: + title: "Tema normal" + banner: + title: "Tema do báner" + unsubscribed: + title: 'Dado de baixa' + description: "Démoste de baixa. Non contactaremos contigo de novo." + resubscribe: + action: "Re-subscribir" + title: "Subscrito de novo" + description: "Subscribícheste de novo" + reports: + visits: + title: "Visitas de usuarios" + xaxis: "Día" + yaxis: "Número de visitas" + signups: + title: "Novos usuarios" + xaxis: "Día" + yaxis: "Número de novos usuarios" + profile_views: + title: "Vistas dos perfís de usuario" + xaxis: "Día" + yaxis: "Número de perfís de usuario vistos" + topics: + title: "Temas" + xaxis: "Día" + yaxis: "Número de temas vistos" + posts: + title: "Publicacións" + xaxis: "Día" + yaxis: "Número de novas publicacións" + likes: + title: "Gústames" + xaxis: "Día" + yaxis: "Número de novos gústames" + flags: + title: "Denuncias" + xaxis: "Día" + yaxis: "Número de denuncias" + bookmarks: + title: "Marcadores" + xaxis: "Día" + yaxis: "Número de novos marcadores" + starred: + title: "Con estrela" + xaxis: "Día" + yaxis: "Número de novos temas con estrela" + users_by_trust_level: + title: "Usuarios por nivel de confianza" + xaxis: "Nivel de confianza" + yaxis: "Número de usuarios" + emails: + title: "Correos-e enviados" + xaxis: "Día" + yaxis: "Número de correos-e enviados" + user_to_user_private_messages: + title: "Entre usuarios" + xaxis: "Día" + yaxis: "Número de mensaxes" + system_private_messages: + title: "Sistema" + xaxis: "Día" + yaxis: "Número de mensaxes" + moderator_warning_private_messages: + title: "Avisos dun moderador" + xaxis: "Día" + yaxis: "Número de mensaxes" + notify_moderators_private_messages: + title: "Notificacións os moderadores" + xaxis: "Día" + yaxis: "Número de mensaxes" + notify_user_private_messages: + title: "Notificacións os usuarios" + xaxis: "Día" + yaxis: "Número de mensaxes" + top_referrers: + xaxis: "Usuario" + num_clicks: "Clics" + num_topics: "Temas" + top_traffic_sources: + title: "As maiores fontes de tráfico" + xaxis: "Dominio" + num_clicks: "Clics" + num_topics: "Temas" + num_users: "Usuarios" + top_referred_topics: + xaxis: "Tema" + num_clicks: "Clics" + page_view_anon_reqs: + title: "Anónimo" + xaxis: "Día" + yaxis: "Peticións API anónimas" + page_view_logged_in_reqs: + title: "Sesión iniciada" + xaxis: "Día" + page_view_crawler_reqs: + title: "Extractores web" + xaxis: "Día" + yaxis: "Peticións API dos extractores web" + page_view_total_reqs: + title: "Total" + xaxis: "Día" + yaxis: "Total de peticións API" + page_view_logged_in_mobile_reqs: + xaxis: "Día" + page_view_anon_mobile_reqs: + xaxis: "Día" + http_background_reqs: + title: "Fondo" + xaxis: "Día" + yaxis: "Peticións usadas para actualizacións e seguimentos" + http_2xx_reqs: + title: "Estado 2xx (OK)" + xaxis: "Día" + yaxis: "Peticións con éxito (estado 2xx)" + http_3xx_reqs: + title: "HTTP 3xx (redireccionar)" + xaxis: "Día" + yaxis: "Redireccionar peticións (estado 3xx)" + http_4xx_reqs: + title: "HTTP 4xx (erro do cliente)" + xaxis: "Día" + yaxis: "Erros do cliente (estado 4xx)" + http_5xx_reqs: + title: "HTTP 5xx (erro do servidor)" + xaxis: "Día" + http_total_reqs: + title: "Total" + xaxis: "Día" + time_to_first_response: + xaxis: "Día" + topics_with_no_response: + xaxis: "Día" + yaxis: "Total" + mobile_visits: + title: "Visitas de usuarios" + xaxis: "Día" + yaxis: "Número de visitas" + site_settings: + delete_old_hidden_posts: "Eliminar automaticamente as publicacións ocultas durante máis de 30 días." + default_locale: "Idioma predeterminado desta instancia (código ISO 639-1)" + allow_user_locale: "Permitir os usuarios escoller o idioma da interface" + min_post_length: "Número mínimo de caracteres permitido para unha publicación" + min_first_post_length: "Número mínimo de caracteres (corpo do tema) permitido para unha primeira publicación" + min_private_message_post_length: "Número mínimo de caracteres permitido para unha mensaxe" + max_post_length: "Número máximo de caracteres permitido para unha publicación" + post_undo_action_window_mins: "Número de minutos que os usuarios teñen para desfacer accións recentes nunha publicación (gústames, denuncias, etc)." + enable_badges: "Activar o sistema de insignias" + max_flags_per_day: "Número máximo de denuncias por usuario e día." + category_style: "Estilo visual para as insignias de categoría." + enable_user_directory: "Proporcionar un directorio de usuarios para navegación" + allow_anonymous_posting: "Permitir os usuarios cambiar ao modo anónimo" + suppress_uncategorized_badge: "Non mostrar a insignia para temas sen categoría nas listas de temas." + automatically_unpin_topics: "Despegar os temas automaticamente cando o usuario chega ao fondo." + full_name_required: "O nome completo no perfil do usuario é obrigatorio." + embed_username_key_from_feed: "Clave para recuperar o nome do usuario desde a fonte." + enable_emoji: "Activar emojis" + notification_types: + liked: "A %{display_username} gustoulle a túa publicación en %{link}" + search: + types: + category: 'Categorías' + user: 'Usuarios' + frequent_poster: "Publicador frecuente" + redirected_to_top_reasons: + new_user: "Benvido/a á nosa comunidade. Estes son os temas recentes máis populares." + login: + admin_not_allowed_from_ip_address: "Non podes acceder como administrador desde este enderezo IP." + new_registrations_disabled: "Neste momento non se permite o rexistro de novas contas." + flags_dispositions: + agreed: "Grazas por comunicárnolo. Estamos de acordo en que hai un problema e estamos botándolle un ollo." + agreed_and_deleted: "Grazas por comunicárnolo. Estamos de acordo en que hai un problema e xa eliminamos a publicación." + disagreed: "Grazas por comunicárnolo. Estamos botándolle un ollo." + deferred: "Grazas por comunicárnolo. Estamos botándolle un ollo." + deferred_and_deleted: "Grazas por comunicárnolo. Xa eliminamos a publicación." + temporarily_closed_due_to_flags: "Este tema está pechado temporalmente polo gran número de denuncias da comunidade." + system_messages: + post_hidden: + subject_template: "Publicación oculta polas denuncias da comunidade." + welcome_user: + subject_template: "Benvido/a a %{site_name}!" + text_body_template: | + Grazas por unirte %{site_name}, e benvido/a! + + %{new_user_tips} + + Cremos nun [comportamento civilizado da comunidade](%{base_url}/guidelines) en todo momento. + + Goza da túa estancia! + + (Se precisas comunicarte cos [membros do equipo](%{base_url}/about) como novo usuario responde a esta mensaxe.) + welcome_invite: + subject_template: "Benvido/a a %{site_name}!" + backup_succeeded: + subject_template: "A copia de seguranza completouse correctamente" + bulk_invite_succeeded: + subject_template: "O convite en bloque procesouse correctamente" + csv_export_succeeded: + subject_template: "Completouse a exportación dos datos" + page_not_found: + see_more: "Máis" + search_google: "Google" + terms_of_service: + title: "Termos do servizo" + about: "Sobre" + guidelines: "Directrices" + privacy: "Confidencialidade" + csv_export: + boolean_yes: "Si" + boolean_no: "Non" + tos_topic: + title: "Termos do servizo" + privacy_topic: + title: "Política de intimidade" + admin_login: + error: "Erro!" + submit_button: "Enviar correo-e" + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.he.yml b/config/locales/server.he.yml index 7cc94cc1f99..d15f7b2b335 100644 --- a/config/locales/server.he.yml +++ b/config/locales/server.he.yml @@ -10,18 +10,24 @@ he: short_date_no_year: "D MMM" short_date: "D MMM, YYYY" long_date: "MMMM D, YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%m-%d-%Y" + short_no_year: "%B %-d" + date_only: "%B %-d, %Y" + date: + month_names: [null, ינואר, פברואר, מרס, אפריל, מאי, יוני, יוני, אוגוסט, ספטמבר, אוקטובר, נובמבר, דצמבר] + <<: *datetime_formats title: "Discourse" topics: "נושאים" posts: "הודעות" loading: "טוען" powered_by_html: 'מונע ע"י Discourse, פועל מיטבית עם Javascript' log_in: "התחברות" - via: "%{username} עם %{site_name}" - is_reserved: "שמור" purge_reason: "נמחק באופן אוטומטי כחשבון נטוש ולא פעיל" disable_remote_images_download_reason: "הורדת תמונות מרחוק נחסמה בשל היעדר מספיק שטח אכסון פנוי." anonymous: "אנונימי" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "מוגבל לאורך של %{max} תוים: את/ה הקשת %{length}." @@ -37,8 +43,10 @@ he: exclusion: שמור greater_than: ' חייב להיות יותר מ-%{count}' greater_than_or_equal_to: חייב להיות גדול יותר או שווה ל-%{count} + has_already_been_used: "כבר בשימוש" inclusion: לא נכלל ברשימה invalid: לא תקין + is_invalid: "אינו קביל; נסה להיות מעט יותר מפורט" less_than: חייב להיות פחות מ-%{count} less_than_or_equal_to: חייב להיות פחות או שווה ל-%{count} not_a_number: אינו מספר @@ -71,6 +79,7 @@ he: max_username_length_exists: "לא ניתן לקבוע את אורך שם המשתמש המקסימלי לקצר יותר משם משתמש שקיים כבר. " max_username_length_range: "לא ניתן לקבוע את המקסימום מתחת למינימום." default_categories_already_selected: "לא ניתן לבחור קטגוריה שהשתמשו בה ברשימה אחרת" + s3_upload_bucket_is_required: "אינך יכול להעלות ל-S3 ללא 's3_upload_bucket'." bulk_invite: file_should_be_csv: "הקובץ המועלה צריך להיות בפורמט csv או txt." backup: @@ -97,26 +106,16 @@ he: replies: one: "תגובה אחת" other: "%{count} תגובות" + no_mentions_allowed: "מצטערים, אך אינכם יכולים לאזכר משתמשים אחרים" too_many_mentions: - zero: "סליחה, אתה לא יכול לאזכר משתמשים אחרים" - one: "סליחה, אתה יכול לאזכר רק משתמש אחד בהודעה." - other: "סליחה, אתה יכול לאזכר רק %{count} משתמשים לכל היותר בהודעה" + one: "מצטערים, אתם יכולים לאזכר רק משתמש אחד בפוסט" + other: "מצטערים, אתם יכולים לאזכר רק %{count} משתמשים בהודעה" too_many_mentions_newuser: - zero: "סליחה, משתמשים חדשים לא יכולים לאזכר משתמשים אחרים." - one: "סליחה, משתמשים חדשים יכולים לאזכר רק משתמש אחד בהודעה." - other: "סליחה, משתמשים חדשים יכולים לאזכר רק %{count} משתמשים לכל היותר בהודעה." - too_many_images: - zero: "סליחה, משתמשים חדשים לא יכולים להוסיף תמונות להודעות." - one: "סליחה, משתמשים חדשים יכולים להוסיף רק הודעה אחת להודעה." - other: "סליחה, משתמשים חדשים יכולים להוסיף %{count} תמונות לכל היותר להודעה." - too_many_attachments: - zero: "סליחה, משתמשים חדשים לא יכולים לצרף קבצים להודעות." - one: "סליחה, משתמשים חדשים יכולים להוסיף רק קובץ אחד להודעה." - other: "סליחה, משתמשים חדשים יכולים להוסיף רק %{count} קבצים לכל היותר להודעה." - too_many_links: - zero: "ליחה, משתמשים חדשים לא יכולים להוסיף קישורים להודעות." - one: "סליחה, משתמשים חדשים יכולים להוסיף רק קישור אחד להודעה." - other: "סליחה, משתמשים חדשים יכולים להוסיף רק %{count} קישורים לכל היותר להודעה." + one: "מצטערים, משתמשים חדשים יכולים לאזכר רק משתמש אחד בהודעה." + other: "מצטערים, משתמשים חדשים יכולים להזכיר רק %{count} משתמשים אחרים בהודעה. " + no_images_allowed: "מצטערים, משתמשים חדשים לא יכולים להוסיף תמונות להודעות." + no_attachments_allowed: "מצטערים, משתמשים חדשים לא יכולים להוסיף קבצים להודעות." + no_links_allowed: "מצטערים, משתמשים חדשים לא יכולים להוסיף קישורים להודעות. " spamming_host: "סליחה אך אינך יכול להוסיף קישור לאתר זה." user_is_suspended: "משתמשים מושעים אינפ מורשים לפרסם" topic_not_found: "משהו השתבש אולי נושא זה נסגר או נמחק בזמן שקראת אותו?" @@ -206,9 +205,6 @@ he: user_profile: bio_raw: "אודותיי" errors: - messages: - is_invalid: "אינו קביל; נסה להיות מעט יותר מפורט" - has_already_been_used: "כבר בשימוש" models: topic: attributes: @@ -229,6 +225,7 @@ he: attributes: hex: invalid: "זהו אינו צבע תקני" + <<: *errors user_profile: no_info_me: "
    שדה האודות של הפרופיל שלך ריק כרגע, תרצה למלא אותו?
    " no_info_other: "
    %{name} עדיין לא הזין דבר בשדה אודות של הפרופיל שלהם
    " @@ -263,13 +260,10 @@ he: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "אודות הקטגוריה %{category}" - replace_paragraph: "[החלף את הפסקה הראשונה הזו עם תיאור קצר של הקטגוריה החדש שלך. התיאור הזה יופיע באיזור בחירת הקטגוריה, כך שיש לנסות לשמור עליו באורך פחות מ-200 תויים. עד שתעריך את המלל הזה או תיצור נושאים, הקטגוריה הזו לא תופיע בעמוד הקטגוריות.]" - post_template: "%{replace_paragraph}\n\nהשתמש בפסקאות הבאו עבור תיאור אורך יותר, כמו גם כדי להחיל כללים או חוקים על הקטגוריה.\n\nחלק מהנושאים שיש לשקול בכל דיון:\n\n- בשביל מה הקטגוריה הזו? למה שאנשים יבחרו בה בשביל הנושא שלהם?\n\n- איך היא שונה מקטגוריות אחרות שכבר יש לנו?\n\n- אנחנו צריכים את הקטגוריה הזו?\n\n- אולי כדאי לאחד אותה עם קטגוריה אחרת, או לפצל אותה לכמה קטגוריות?\n" errors: uncategorized_parent: "נטול קטגוריה לא יכול להיות עם קטגוריית אם" self_parent: "קטגוריית אם לא יכולה להיות הקטגוריה עצמה" depth: "לא ניתן להניח תת-קטגוריה תחת תת-קטגוריה אחרת" - email_in_already_exist: "דוא\"ל '%{email_in}' כבר בשימוש עבור קטגוריה '%{category_name}' ." cannot_delete: uncategorized: "לא ניתן למחוק תוכן ללא קטגוריה" has_subcategories: "לא ניתן למחוק קטגוריה זו משום שיש בה תת-קטגוריות." @@ -282,16 +276,24 @@ he: title: "משתמש חדש" basic: title: "משתמש בסיסי" + member: + title: "חבר" regular: - title: "חבר/ה" - leader: - title: "רגיל/ה" - elder: - title: "מוביל/ה" + title: "רגיל" change_failed_explanation: "ניסיתם להוריד בדרגה %{user_name} ל- '%{new_trust_level}'. אולם רמת האמון שלהם היא כבר '%{current_trust_level}'. %{user_name} ישאר/תישאר ב-'%{current_trust_level}' - אם ברצונכם להוריד את המשתמש/ת נעלו קודם את רמת האמון" rate_limiter: - slow_down: "ביצעתם פעולה זו מספר רב מידי של פעמים, נסו שוב מאוחר יותר" + slow_down: "ביצעת פעולה זו מספר רב מדי של פעמים. נסה שוב מאוחר יותר." too_many_requests: "יש לנו מגבלה יומית על מספר הפעמים שניתן לבצע פעולה זו. אנא המתן %{time_left} לפני ניסיון חוזר." + by_type: + first_day_replies_per_day: "הגעת למספר המירבי של תגובות שמתמש חדש יכול ליצור ביומו הראשון. אנא המתן %{time_left} לפני ניסיון חוזר לבצע פעולה זו." + first_day_topics_per_day: "הגעת למספר המירבי של נושאים שמשתמש חדש יכול ליצור ביומו הראשון. אנא המתן %{time_left} לפני ניסיון חוזר לבצע פעולה זו." + create_topic: "אתה יוצר נושא חדש מהר מדי. אנא המתן %{time_left} לפני ניסיון חוזר לבצע פעולה זו." + create_post: "אתה מגיב מהר מדי. אנא המתן %{time_left} לפני ניסיון חוזר לבצע פעולה זו." + topics_per_day: "הגעת למספר המירבי של נושאים חדשים היום. אנא המתן %{time_left} לפני ניסיון חוזר לבצע פעולה זו." + pms_per_day: "הגעת למספר המירבי של הודעות היום. אנא המתן %{time_left} לפני ניסיון חוזר לבצע פעולה זו." + create_like: "הגעת למספר המירבי של לייקים היום. אנא המתן %{time_left} לפני ניסיון חוזר לבצע פעולה זו." + create_bookmark: "הגעת למספר המירבי של מעודפים היום. אנא המתן %{time_left} לפני ניסיון חוזר לבצע פעולה זו." + edit_post: "הגעת למספר המירבי של עריכות היום. אנא המתן %{time_left} לפני ניסיון חוזר לבצע פעולה זו." hours: one: "שעה אחת" other: "%{count} שעות" @@ -410,16 +412,11 @@ he: description: 'פרסום זה מכיל תוכן שאדם סביר היה רואה כפוגעני, מתעלל או הפרה של כללי הקהילה .' long_form: 'דוגלל כלא ראוי' notify_user: - title: 'הודעה ל-@{{username}}' - description: 'פרסום זה מכיל משהו שארצה לשוחח עליו עם האדם הזה באופן ישיר ופרטי. אין צורך בסימון.' long_form: 'הודעה נשלחה למשתמש/ת' email_title: 'הפרסום שלךב"%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "משהו אחר" - description: 'פרסום זה דורש את תשומת ליבו של מנחה מסיבה שאינה מצויינת למעלה.' - long_form: 'זה סומן לתשומת הלב של מנחה' - email_title: 'הודעה ב-"%{title}" דורשת תשומת לב של מנהל' email_body: "%{link}\n\n%{message}" bookmark: title: 'מועדפים' @@ -444,7 +441,6 @@ he: long_form: 'דוגלל כלא ראוי' notify_moderators: title: "משהו אחר" - description: 'נושא זה דורש התייחסות של מנחה (moderator) כללי, על פי הכללים המנחים , TOS, או סיבה אחרת שאינה מופיעה כאן.' long_form: 'זה סומן לתשומת הלב של מנחה' email_title: 'הנושא "%{title}" דורש תשומת לב של מנהל' email_body: "%{link}\n\n%{message}" @@ -480,6 +476,10 @@ he: title: "משתמשים חדשים" xaxis: "יום" yaxis: "מספר משתמשים חדשים" + profile_views: + title: "צפיות בפרופיל משתמש" + xaxis: "יום" + yaxis: "מספר פרופילי משתמש שנצפו" topics: title: "נושאים" xaxis: "יום" @@ -622,6 +622,7 @@ he: s3_config_warning: 'The server is configured to upload files to s3, but at least one the following setting is not set: s3_access_key_id, s3_secret_access_key or s3_upload_bucket. Go to the Site Settings and update the settings. See "How to set up image uploads to S3?" to learn more.' s3_backup_config_warning: 'The server is configured to upload backups to s3, but at least one the following setting is not set: s3_access_key_id, s3_secret_access_key or s3_backup_bucket. Go to the Site Settings and update the settings. See "How to set up image uploads to S3?" to learn more.' image_magick_warning: 'The server is configured to create thumbnails of large images, but ImageMagick is not installed. Install ImageMagick using your favorite package manager or download the latest release.' + failing_emails_warning: 'There are %{num_failed_jobs} email jobs that failed. Check your app.yml and ensure that the mail server settings are correct. See the failed jobs in Sidekiq.' default_logo_warning: "כוונו את הסמלילים הגרפיים לשימוש באתר שלך. עדכנו את כתובת ה-URL של הלוגו, כתובת ה-URL ללוגו המוקטן, וכתובת ה-URL של ה-favicon. " contact_email_missing: "הזינו כתובת דוא\"ל ליצירת קשר, בה ניתן יהיה ליצור עמכם קשר בנושאים דחופים בנוגע לאתר שלכם. עדכנו אותה בהגדרות האתר." contact_email_invalid: "כתובת הדוא\"ל ליצירת קשר של האתר אינה תקינה. עדכנו אותה ב הגדרות האתר." @@ -630,37 +631,6 @@ he: consumer_email_warning: "Your site is configured to use Gmail (or another consumer email service) to send email. Gmail limits how many emails you can send. Consider using an email service provider like mandrill.com to ensure email deliverability." site_contact_username_warning: "הזינו שם חשבון ידידותי של אי/אשת צות ממנו ישלחו הודעות אוטומטיות חשובות. עדכנו את site_contact_username בהגדרות האתר." notification_email_warning: "מיילים ליידוע אינם נשלחים מכתובת תקינה בדומיין שלכם; משלוח דוא\"ל יהיה בעייתי ולא אמין. אנא כוונו את כתובת המייל למשלוח התראות לכתובת מקומית תקינה בהגדרות האתר." - content_types: - education_new_reply: - title: "הדרכת משתמש חדש: תגובות ראשונות" - description: "Pop up just-in-time guidance automatically displayed above the composer when new users begin typing their first two new replies." - education_new_topic: - title: "הדרכת משתמש חדש: נושאים ראשונים" - description: "Pop up just-in-time guidance automatically displayed above the composer when new users begin typing their first two new topics." - usage_tips: - title: "הדרכה למשתמש/ת חדשים" - description: "הדרכה ומידע חשוב למשתמשים חדשים." - welcome_user: - title: "Welcome: New User" - description: "הודעה שנשלחת באופן אוטומטי לכל המשתמשים החדשים כאשר הם נרשמים." - welcome_invite: - title: "Welcome: Invited User" - description: "הודעה שנשלחת באופן אוטומטי לכל המשתמשים המוזמנים כאשר הם מקבלים את ההזמנה ממשתמש אחר." - login_required_welcome_message: - title: "Login Required: Welcome Message" - description: "Welcome message that is displayed to logged out users when the 'login required' setting is enabled." - login_required: - title: "Login Required: Homepage" - description: "The text displayed for unauthorized users when login is required on the site." - head: - title: "HTML head" - description: "HTML that will be inserted inside the tags." - top: - title: "Top of the pages" - description: "HTML that will be added at the top of every page (after the header, before the navigation or the topic title)." - bottom: - title: "Bottom of the pages" - description: "קוד HTML שיתווסף לפני התגית ." site_settings: censored_words: "מלים שיוחלפו באופן אוטומטי ב- ■■■■" delete_old_hidden_posts: "מחיקת אוטומטית של פרסומים מוסתרים שנותרים מוסתרים במשך יותר מ-30 יום." @@ -675,7 +645,6 @@ he: min_private_message_title_length: "אורך הכותרת המנימילי המותר להודעה בתווים" min_search_term_length: "מספר התווים המינמלי התקין כאורך מונח לחיפוש" allow_uncategorized_topics: "הרשה לפתוח נושאים ללא קטגוריה.\nאזהרה: אם יש נושאים ללא קטגוריה, יש לסדר אותם לפני שמבטלים את האופציה. " - uncategorized_description: "תיאור הקבוצה \"ללא קטגוריה\". השאירו ריק אם אין צורך בתיאור." allow_duplicate_topic_titles: "אשר/י נושאים עם כותרות זהות או משוכפלות." unique_posts_mins: "How many minutes before a user can make a post with the same content again" educate_until_posts: "כאשר המשתמש/ת מתחילים להקיש את (n) ההודעות הראשונות שלהם, הציגו פאנל הנחיה למשתמש באזור חיבור ההודעות." @@ -688,7 +657,6 @@ he: download_remote_images_to_local: "המרת תמונות מרחוק לתמונות מקומיות באמצעות הורדות; למניעת שגיאות של תמונות חסרות" download_remote_images_threshold: "שטח האכסון המינימלי (באחוזים) הנדרש להורדת תמונות באופן מקומי" disabled_image_download_domains: "תמונות מרחוק לעולם לא יורדו ממתחמים (domains) אלו. " - ninja_edit_window: "במשך (n) שניות לאחר הפרסום, עריכה לא תיצור גרסא חדשה בהיסטוריית הגרסאות." post_edit_time_limit: "העורכ/ת יכול לערות או למחקור את הפרסום שלהם במשך (0) דקות לאחר הפרסום. הזינו 0 כ\"תמיד\"." edit_history_visible_to_public: "אפשרו לכולם לראות גרסאות קודמות של פרסום ערוך. כאשר אפשרות זו מנוטרלת, רק חברי צוות יכולים לצפות בהן." delete_removed_posts_after: "פרסומים שהוסרו על ידי מחבריהם ימחקו באופן אוטומטי לאחר (n) שעות. אם הגדרה זו מכוונת ל-0, הפרסום ימחקו מיידית." @@ -718,7 +686,6 @@ he: summary_likes_required: "מינימום הלייקים לנושא לפני שהאפשרות \"סיכום נושא זה\" תתאפשר" summary_percent_filter: "כאשר משתמש/ת מקליקים על \"סיכום נושא זה\", הציגו את % o הפרסומים הראשונים" summary_max_results: "מספר הפרסומים שיוחזרו באמצעות \"סיכום נושא זה\"" - enable_private_messages: "אפשרו למשתמשים בעלי רמת_אמון 1 ליצור הודעות ולהגיב להודעות" enable_long_polling: "Message bus used for notification can use long polling" long_polling_base_url: "בסיס ה-URL שנמצא בשימוש עבור long polling (כאשר CDN מחזיר תוכן דינמי, זכרו להגדיר את ערך זה ל-Origin pull, דוגמת http://origin.site.com)" long_polling_interval: "כמות הזמן שהשרת צריך לחכות לפני שעונה ללקוחות, כאשר אין מידע לשליחה (משתמשים רשומים מחוברים למערכת בלבד)" @@ -737,7 +704,6 @@ he: notify_mods_when_user_blocked: "If a user is automatically blocked, send a message to all moderators." flag_sockpuppets: "אם משתמש/ת חדשים מגיבים לנושא מכתובת IP זהה לזו של מי שהחל את הנושא, סמנו את הפרסומים של שניהם כספאם פוטנציאלי." traditional_markdown_linebreaks: "שימוש בשבירת שורות מסורתית בסימון, מה שדורש שני רווחים עוקבים למעבר שורה." - allow_html_tables: "Allow tables to be entered in Markdown using HTML tags, TABLE, THEAD, TD, TR, TH are whitelisted (requires full rebake on all old posts containing tables)" post_undo_action_window_mins: "מספר הדקות בהן מתאפשר למשתמשים לבטל פעולות אחרות בפרסום (לייק, סימון, וכו')." must_approve_users: "על הצוות לאשר את כל המשתמשים החדשים לפני שהם מקבלים גישה לאתר. אזהרה: בחירה זו עבור אתר קיים תשלול גישה ממשתמשים קיימים שאינם מנהלים." ga_tracking_code: "Google analytics (ga.js) tracking code code, eg: UA-12345678-9; see http://google.com/analytics" @@ -759,7 +725,6 @@ he: suppress_reply_directly_above: "אל תציגו את את אפשרות ההרחבה \"בתגובה ל..\" לפרסום כאשר יש רק תגובה אחת ישירה מעל לפרסום זה." suppress_reply_when_quoting: "אל תציגו את הפרסום המקורי בפרסומים שמצטטים תגובות" max_reply_history: "מספר התגובות המקסימלי להרחבה כאשר מרחיבים \"בתגובה ל\"" - experimental_reply_expansion: "החבא תגובות ביניים כאשר מרחיבים תגובה (ניסיוני)" topics_per_period_in_top_summary: "מספר הנושאים המוצגים בבריכת המחדל של סיכום הנושאים." topics_per_period_in_top_page: "מספר הנושאים הראשונים המוצגים בתצוגה המורחבת של \"הצג עוד\"." redirect_users_to_top_page: "כוון באופן אוטומטי משתמשים חדשים וכאלה שנעדרו במשך זמן לראש העמוד." @@ -767,6 +732,7 @@ he: email_token_valid_hours: "סיסמאות שכחת סיסמא / הפעלת חשבון תקפים במשך (n) שעות." email_token_grace_period_hours: "סיסמאות שכחת סיסמא / הפעלת חשבון עדיין זמינים לזמן חסד של (n) שעות לאחר שהופקו." enable_badges: "הפעלת מערכת התגים (badges)" + enable_whispers: "הודעות פרטיות בין חברי הצוות אפשריות בתוך הפוסט (בנסיון)." allow_index_in_robots_txt: "פרטו ב-robots.txt שלאתר זה מותר להיות מאונדקס על ידי מנועי חיפוש." email_domains_blacklist: "A pipe-delimited list of email domains that users are not allowed to register accounts with. Example: mailinator.com|trashmail.net" email_domains_whitelist: "A pipe-delimited list of email domains that users MUST register accounts with. WARNING: Users with email domains other than those listed will not be allowed!" @@ -815,6 +781,7 @@ he: backup_frequency: "How frequently we create a site backup, in days." enable_s3_backups: "העלאת גיבויים ל-S3 לאחר השלמתם. חשוב: דורש הזנת הרשאות S3 תקפות להגדרות הקבצים." s3_backup_bucket: "The remote bucket to hold backups. WARNING: Make sure it is a private bucket." + backup_time_of_day: "הגדרת זמן לגיבוי בפורמט UTC." active_user_rate_limit_secs: "How frequently we update the 'last_seen_at' field, in seconds" verbose_localization: "הצגת טיפים מורחבים של לוקליזציה בממשק המשתמש." previous_visit_timeout_hours: "How long a visit lasts before we consider it the 'previous' visit, in hours" @@ -846,6 +813,7 @@ he: avatar_sizes: "רשימה של גדלי אווטרים שנוצרת אוטומטית. " external_system_avatars_enabled: "Use external system avatars service." external_system_avatars_url: "URL of the external system avatars service. Allowed substitions are {username} {first_letter} {color} {size}" + default_opengraph_image_url: "כתובת של תמונת opengraph בברירת המחדל." enable_flash_video_onebox: "אפשרו הטמעת קישורי swf ו-flv (פלאש של אדובי) בפרסומים. אזהרה: עלול להביא לבעיות בטיחות באתר." default_invitee_trust_level: "ברירת מחדל של דרגת אמון (0-4) של משתמשים מוזמנים." default_trust_level: "Default trust level (0-4) for all new users. WARNING! Changing this will put you at serious risk for spam." @@ -859,16 +827,9 @@ he: tl2_requires_likes_received: "כמה \"לייקים\" משתמש צריך לקבל לפני שישודרג לרמת אמון 2." tl2_requires_likes_given: "כמה לייקים משתמש צריך לתת לפני שישודרג לרמת אמון 2." tl2_requires_topic_reply_count: "בכמה נושאים משתמש צריך לענות לפני שישודרג לרמת אמון 2." - tl3_requires_days_visited: "מספר מינימלי של ימים שמשתמש צריך לבקר בהם ב-100 הימים האחרונים על מנת שיתאפשר לו להיות משודרג לרמת אמון 3 (ערך בין 0 ל-100)." - tl3_requires_topics_replied_to: "מספר נושאים מינימלי שמשתמש צריך היה לענות להם ב-100 הימים האחרונים על מנת שיתאפשר לו להיות משודרג לרמת אמון 3 (ערך בין 0 ל-100)." - tl3_requires_topics_viewed: "אחוז הנושאים שנוספו שמשתמש צריך היה לעיין בהם ב-100 הימים האחרונים על מנת שיתאפשר לו להיות משודרג לרמת אמון 3 (ערך בין 0 ל-100)." - tl3_requires_posts_read: "מספר הפרסומים שמשתמש פרסם ב-100 הימים האחרונים על מנת שיתאפשר לו להיות משודרג לרמת אמון 3 (ערך בין 0 ל-100)." tl3_requires_topics_viewed_all_time: "מספר מינימלי של נושאים שמשתמש צריך לעיין בהם על מנת שיתאפשר לו להיות משודרג לרמת אמון 3." tl3_requires_posts_read_all_time: "מספר מינימלי של פרסומים שמשתמש קרא על מנת שיוכל להיות משודרג לרמת אמון 3." - tl3_requires_max_flagged: "משתמש לא פרסם יותר מ-X פרסומים שסומנו (flagged) ע\"י משתמשים ב-100 הימים האחרונים, על מנת שיוכל להיות משודרג לרמת אמון 3, כאשר X הוא הערך הזה (0 או גבוה יותר)." tl3_promotion_min_duration: "מספר הימים המינימלי ששדרוג לרמת אמון 3 תארך לפני שמשתמש יורד בדרגה לרמת אמון 2." - tl3_requires_likes_given: "מינימום הלייקים הנדרשים ב-100 הימים האחרונים כדי להכשיר קידום לרמת אמון 3." - tl3_requires_likes_received: "מינימום הלייקים הנדרש ב-100 הימים האחרונים כדי לאפשר קידום לרמת אמון 3." tl3_links_no_follow: "מניעת הסרת rel=nofollow מקישורים שמפורסמים על ידי משתמשים ברמת אמון 3." min_trust_to_create_topic: "The minimum trust level required to create a new topic." min_trust_to_edit_wiki_post: "דרגת האמון המינימלי הנדרשת כדי לערוך פרסום שמסומן כ-wiki." @@ -956,7 +917,6 @@ he: automatically_download_gravatars: "הורדת גראווטרים למשתמשים בעת יצירת החשבון או שינוי כתובת הדוא\"ל." digest_topics: "מספר הנושאים המקסימלי להצגה במייל סיכום." digest_min_excerpt_length: "מספר התווים המינימלי למובאות מתוך הפרסום במייל הסיכום." - suppress_digest_email_after_days: "השהיית מיילים מסכמים עבור משתמשים שלא נראו באתר במשך יותר מ(n) ימים." disable_digest_emails: "נטרול דוא\"ל סיכום לכל המשתמשים." detect_custom_avatars: "Whether or not to check that users have uploaded custom profile pictures." max_daily_gravatar_crawls: "מספר הפעמים המקסימלי ש-Discourse יבדוק אווטרים ב-Gravatar ביום" @@ -967,12 +927,10 @@ he: anonymous_posting_min_trust_level: "רמת האמון המינמלית הנדרשת כדי לאפשר פרסום אנונימי" anonymous_account_duration_minutes: "בכדי להגן על האנונימות צרו חשבון אנונימי כל N דקות לכ משתמש. לדוגמה: אם מכוון ל-600, כאשר יעברו 600 דקות מהפרסום האחרון והמשתמש/ת יחליפו לזהות אנונימית, חשבון אנונימי חדש יווצר." allow_profile_backgrounds: "אפשרו למשתמשים להעלות רקעים לפרופיל." - sequential_replies_threshold: "מספר הפרסומים שעל משתמש להכין ברצף בפרסום לפני שיקבל תזכורת בנוגע ליותר מידי תגובות עוקבות." enable_mobile_theme: "Mobile devices use a mobile-friendly theme, with the ability to switch to the full site. Disable this if you want to use a custom stylesheet that is fully responsive." dominating_topic_minimum_percent: "איזה אחוז מהפרסומים משתמש צריך לייצר בנושא לפני שיקבל תזכורת לגבי שליטת/שתלטנות יתר על הנושא." daily_performance_report: "Analyze NGINX logs daily and post a Staff Only topic with details" suppress_uncategorized_badge: "אל תציגו את התג (badge) לנושאים נטולי קטגוריה ברשימת הנושאים." - permalink_normalizations: "Apply the following regex before matching permalinks, for example: /(\\/topic.*)\\?.*/\\1 will strip query strings from topic routes. Format is regex+string use \\1 etc. to access captures" global_notice: "הציגו הודעת אזהרה דחופה כללית לכל המבקרים, החליפו לריק כדי להסתיר אותה (ניתן להשתמש ב-HTML)." disable_edit_notifications: "ביטול התראות עריכה על ידי משתמש המערכת כאשר 'download_remote_images_to_local' פעיל." full_name_required: "שם מלא הוא שדה נדרש לפרופיל משתמש/ת." @@ -991,20 +949,18 @@ he: embed_username_key_from_feed: "מפתח למשיכת שם המשתמש ב-discourse מהפיד." embed_truncate: "חיתוך הפרסומים המוטמעים." embed_post_limit: "מספר מקסימלי של פרסומים להטמעה." + embed_username_required: "נדרש שם משתמש ליצירת הפוסט." embed_whitelist_selector: "בוררי CSS לאלמנטים שיותר להטמיע." embed_blacklist_selector: "בוררי CSS לאלמנטים שיוסרו מן ההטמעות." notify_about_flags_after: "If there are flags that haven't been handled after this many hours, send an email to the contact_email. Set to 0 to disable." enable_cdn_js_debugging: "אפשרו ל-/logs להציג שגיאות בצורה נכונה באמצעות הוספת הרשאות לגישה בין אתרים (crossorigin permissions) בכל ה-js הכלולים." show_create_topics_notice: "אם לאתר פחות מ-5 נושאים פומביים, הציגו הודעה המבקשת מן המנהלים/מנהלות ליצור עוד נושאים." delete_drafts_older_than_n_days: Delete drafts older than (n) days. - show_logout_in_header: "Show log out in user dropdown in header" - vacuum_db_days: "הריצו VACUUM FULL ANALYZE כדי להשיב שטח בסיס הנתונים אחרי העברות (כוונו ל-0 כדי לנטרל)" prevent_anons_from_downloading_files: "מונע ממשתמשים אנונימיים להוריד צרופות (attachments). אזהרה: דבר זה ימנע מכל משאב שאינו תמונה ופורסם כצרופה לעבוד." slug_generation_method: "Choose a slug generation method. 'encoded' will generate percent encoding string. 'none' will disable slug at all." enable_emoji: "אפשרו emoji" emoji_set: "איך אתם אוהבים את ה-emoji שלכם?" enforce_square_emoji: "חובת מימדי ריבועיים בכל ה-emojis." - approve_post_count: "The amount of posts from a new user that must be approved" approve_unless_trust_level: "Posts for users below this trust level must be approved" notify_about_queued_posts_after: "If there are posts that have been waiting to be reviewed for more than this many hours, an email will be sent to the contact email. Set to 0 to disable these emails." default_email_digest_frequency: "באיזה תדירות משתמשים מקבלים מייל עדכון בתור ברירת מחדל. " @@ -1046,7 +1002,6 @@ he: moved_post: "%{display_username} העביר את ההודעה שלך ל %{link}" private_message: "%{display_username} שלח/ה לך הודעה: %{link}" invited_to_private_message: "%{display_username} הזמין אותך להודעה: %{link}" - invited_to_topic: "%{display_username} הזמין אותך לנושא: %{link}" invitee_accepted: "%{display_username} קיבל את הזמנתך" linked: "%{display_username} קישר אליך ב %{link}" granted_badge: "הרווחת %{link}" @@ -1056,11 +1011,6 @@ he: category: 'קטגוריות' topic: 'תוצאות' user: 'משתמשים' - sso: - not_found: "לא ניתן לאתר או ליצור חשבון, צרו קשר עם אדמין." - account_not_approved: "החשבון ממתין לאישור, תקבל/י הודעת דוא\"ל ברגע שיאושר." - unknown_error: "שגיאה בעדכון המידע, צרו קשר עם האדמין" - timeout_expired: "תם זמן החיבור לחשבון, אנא נסו להתחבר שוב" original_poster: "מפרסם מקורים" most_posts: "מירב ההודעות" most_recent_poster: "המפרסם האחרון" @@ -1143,16 +1093,17 @@ he: characters: "חייב לכלול מספרים, אותיות ומקפים תחתונים בלבד." unique: "חייב להיות ייחודי" blank: "חייב להיות מלא" - must_begin_with_alphanumeric: "חייב להתחיל עם אות, מספר או קו תחתון" - must_end_with_alphanumeric: "חייב להסתיים עם אות, מספר, או קו תחתון" must_not_contain_two_special_chars_in_seq: "לא יכול להכיל רצף של 2 או יותר תווים מיוחדים (.-_)" - must_not_contain_confusing_suffix: "לא יכול להכיל סיומת מבלבלת כמו png." email: not_allowed: "לא מורשה מכתובת הדואר האלקטרוני הזו. בבקשה השתמש בכתובת אחרת." blocked: "לא מורשה." ip_address: blocked: "הרשמות חדשות אסורות מכתובת ה-IP שלך. " max_new_accounts_per_registration_ip: "הרשמות חדשות אסורות מכתובת ה-IP שלך. (עברת את הסף המותר) צרו קשר עם מנהל." + flags_reminder: + subject_template: + one: "סימון אחד ממתין לטיפול" + other: "%{count} סימונים ממתינים לטיפול" invite_mailer: subject_template: "הוזמנת על ידי %{invitee_name} ל '%{topic_title}' ב%{site_domain_name}" text_body_template: | @@ -1194,83 +1145,10 @@ he: (אם הקישור פג תוקף, בחר ב"שכחתי אץ הסיסמא שלי" בהתחברות.) test_mailer: subject_template: "[%{site_name}] Email Deliverability Test" - text_body_template: | - This is a test email from - [**%{base_url}**][0] - - Email deliverability is complicated. Here are a few important things you should check first: - - - Be *sure* to set the `notification email` from: address correctly in your site settings. **The domain specified in the "from" address of the emails you send is the domain your email will be validated against**. - - - Know how to view the raw source of the email in your mail client, so you can examine email headers for important clues. in Gmail, it is the "show original" option in the drop-down menu at the top right of each mail. - - - **IMPORTANT:** Does your ISP have a reverse DNS record entered to associate the domain names and IP addresses you send mail from? [Test your Reverse PTR record][2] here. If your ISP does not enter the proper reverse DNS pointer record, it's very unlikely any of your email will be delivered. - - - Is your domain's [SPF record][8] correct? [Test your SPF record][1] here. Note that TXT is the correct official record type for SPF. - - - Is your domain's [DKIM record][3] correct? This will significantly improve email deliverability. [Test your DKIM record][7] here. - If you run your own mail server, check to make sure the IPs of your mail server are [not on any email blacklists][4]. Also verify that it is definitely sending a fully-qualified hostname that resolves in DNS in its HELO message. If not, this will cause your email to be rejected by many mail services. - - - (The *easy* way is to create a free account on [Mandrill][md] or [Mailgun][mg] or [Mailjet][mj], which have free generous free mailing plans and will be fine for small communities. You'll still need to set up the SPF and DKIM records in your DNS, though!) - - We hope you received this email deliverability test OK! - - Good luck, - - Your friends at [Discourse](http://www.discourse.org) - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: https://www.mailjet.com/pricing new_version_mailer: subject_template: "[%{site_name}] גרסת Discourse חדשה, עדכון זמין." - text_body_template: |+ - גרסה חדש של [Discourse](http://www.discourse.org) זמינה. - - הגרסה שלכם: %{installed_version} - הגרסה החדשה: **%{new_version}** - - ייתכן ותרצו: - - - לראות מה חדש ב- [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - לעדכן דרך הדפדפן ב [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - לבקר ב-[meta.discourse.org](http://meta.discourse.org) לחדשות, דיונים ותמיכה ב-Discourse. - new_version_mailer_with_notes: subject_template: "[%{site_name}] update available" - text_body_template: | - גרסא חדש של [Discourse] (http://www.discourse.org) זמינה. - הגרסא שלכם: %{installed_version} - גרסא חדשה: **%{new_version}** - - ייתכן שתרצו: - - - לראות מה חדש ב[יומן השינויים בגיטהאב](https://github.com/discourse/discourse/commits/master). - - - לעדכן דרך הדפדפן ב- [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade) - - - לבקר ב[meta.discourse.org](http://meta.discourse.org) לחדשות, דיונים ותמיכה ב-Discourse. - ### Release notes - %{notes} - flags_reminder: - flags_were_submitted: - one: "סימונים אלו נשלחו לפני כשעה." - other: "סימונים אלה נשלחו לפני %{count} שעות." - please_review: "Please review them." - post_number: "post" - how_to_disable: 'תוכל/י לבטל או לשנות את תדירות תזכורת דוא"ל באמצעות ההגדרה "הודעה על סימונים אחרי...".' - subject_template: - one: "סימון אחד ממתין לטיפול" - other: "%{count} סימונים ממתינים לטיפול" queued_posts_reminder: subject_template: one: "[%{site_name}] תגובה אחת מחכה לבדיקה" @@ -1294,12 +1172,6 @@ he: post_hidden: subject_template: "הודעה הוסתרה בעקבות סימון" text_body_template: "שלום,\n\nזו הודעה אוטומטית מ %{site_name} לידע אותך שהפרסום שלך הוסתר. \n\n%{base_url}%{url}\n\n%{flag_reason}\n\nמספר חברי קהילה סימנו את הפרסום הזה לפני שהוסתר, אז בבקשה תשקול איך תוכל לשנות את הפרסום בהתאם להערותיהם. \n\n**תוכל לערוך את הפרסום אחרי %{edit_delay} דקות, והוא יוצג באופן אוומטי**\n\nאולם, אם הפרסום יוסתר על ידי הקהילה פעם נוספת, הוא ישאר מוסתר עד לטיפול של צוות האתר, ותתכן תגובה נוספת, כולל השהייה של חשבונך. \n\nלהדכה נוספת, [קווים מנחים](%{base_url}/guidelines).\n" - usage_tips: - text_body_template: "הינה מספר טיפים קצרים לעזור לך להתחיל:\n\n## קריאה\n\nלקרוא יותר, **פשו המשך לגלול למטה**\n\nכשתגובות או נושאים חדשים יגיעו, הם יופיעו באוםן אוטומטי – אין צורך לרענן את העמוד.\n\n##ניווט\n\n-לחיפוש השתמש בעמוד משתמש או בתפריט , השתמש ב**כפתורי אייקון משמשאל למעלה**\n\n-בחירת כותרת נושא תמיד תקח אותך ל**תגובה אחרונה שלא נקראה** בנושא. להכנס ללמעלה או למטה, בחר בספירת תגובות או תאריך פרסום אחרון.\n\n\n\n-בעת קריאה נושא, בחר בסרגל התקדמות מימין למטה לשליטה מלאה בניווט. עבור במהירות חזרה למעלה על ידי בחירה בכותרת הנושא. לחץ ? לרשימה של קיצורי מקלדת מהירים. \n\n\n## תגובה\n\n-להגיב ל**נושא באופן כללי**, השתמש בתחתית הנושא.\n\n-להגיב ל**אדם מסוים**, השתמש בפרסום שלהם. \n\n-להגיב עם **נושא חדש** השתמש ב מימין לתגובה. הנושא החדש והישן יקושרו ביחד. \n\nלהכניס ציטוט, בחר בטקסט שברצונך לצטט, ואז בחר בכל כפתור תגובה. חזור על כך שוב למספר ציטוטים!\n\n\n\nלידע מישהו בנוגע לתגובה שלך, הזכר את שמם. הקלד @ להתחיל\ - \ בבחירת שם משתמש. \n\n\n\nלהשתמש ב [standard Emoji](http://www.emoji.codes/), הקלד ':' להתאים על ידי שם, או השתמש בסמיילים סטנדרטים ';)'\n\n\n\nליצר תקציר לקישור, הדבק אותו בשורה משל עצמו:\n\n\n\n##פעולות\n\nישנם כפתורי פעולות בתחתית כל פרסום:\n\n\n\nבשביל לידע מישהו/י שנהנת מפרסום שלו/ה, השתמש בכפתור **לייק**. \n\nאם יש בעיה בפרסום של מישהו/י ידע\ - \ אותם או [צוות האתר](%{base_url}/about) באופן פרטי באמצעות כפתור **דגל**. תוכל/י גם **לחלוק** קישור לפרסום, או **לסמן** לשימוש עתידי בעמוד המשתמש שלך.\n\n## התראות\n\nכשמגיבים לך, מצטטים את הפרסום שלך או מזכירים את '@שם המשתמש' שלך, מספר יופיע ישר בחלק השמאלי העליון של העמוד. השתמש בו לגשת ל**התראות**\n\n\n\nאל תדאגו בנוגע לפספוס תגובה, ישלח אליכם מייל עם התראות שהגיעו כשלא היית באתר.\n\n- כל הנושאים בני פחות מ**יומיים** נחשבים חדשים. \n\n- כל נושא שהשתתפת בו באופן אקטיבי יוגדר למעקב – רגיל+ באופן אוטומטי. \n\n- תראו את המספרים הכחולים לנושאים חדשים ושלא נקראו ליד נושאים אלו:\n\n \n\nתוכלו לשנות את ההתראות שלכם לכל נושא דרך שליטה בהתראות שתחתית הנושא. \n\n\n\nתוכלו גם לקבוע מצב התראות עבור קטגוריה, אם ברצונכם לעקוב אחרי כל נושא חדש בקטגוריה מסוימת. \n\nבשביל לשנות אחד מההגדרות האלה, גש ל [your user preferences](%{base_url}/my/preferences).\n\n\n## אמון קהילתי\n\nככל שתשתתפו כאן, לאורך הזמן תצברו את אמון הקהילה, תהפכו לאזרח מן השורה, והגבלות למשתמשים חדשים יוסרו. [בדרגת אמון ](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924) גבוהה, תקבלו יכולות לעזור לנו בטיפוח הקהילה. \n" welcome_user: subject_template: "ברוכים הבאים ל %{site_name}!" text_body_template: | @@ -1360,18 +1232,8 @@ he: csv_export_failed: subject_template: "ייצוא הנתונים נכשל" text_body_template: "צר לנו, אך ייצוא הנתונים שלכם נכשל. אנא בדקו את רישומי המערכת או צרו קשר עם איש/אשת צוות." - email_reject_trust_level: - subject_template: "[%{site_name}] בעיית מייל -- רמת אמון לא מספיקה. " - text_body_template: | - אנו מצטערים, אבל הודעת הדוא"ל שלך אל %{destination} (titled %{former_title}) לא עברה. - - אין לחשבון שלך את רמון האמון הנדרשת כדי לפרסם נושאים חדשים לכתובת דוא"ל זו. אם אתם מאמינים כי זוהי שגיאה, צרו קשר עם אחד מאנשי הצוות. email_reject_no_account: subject_template: "[%{site_name}] בעיית מייל -- חשבון לא מזוהה" - text_body_template: | - אנחנו מצטערים, אך הודעת הדוא"ל שלכם אל %{destination} (titled %{former_title}) לא עברה. - - לא ידוע לנו על חשבון משתמש/ת עם כתובת כזו. נסו לשלוח מכתובת דוא"ל אחרת, או צרו קשר עם אנשי הצוות שלנו. email_reject_empty: subject_template: "[%{site_name}] בעיית מייל -- ללא תוכן" email_reject_parsing: @@ -1383,47 +1245,10 @@ he: אנו מצטערים, אבל הודעת הדוא"ל שלך אל %{destination} (titled %{former_title}) לא עברה. אין לחשבון שלך את רמון האמון הנדרשת כדי לפרסם נושאים חדשים בקטגוריה הזו. אם אתם חושבים שזוהי שגיאה, צרו קשר עם אחד מאנשי הצוות. - email_reject_post_error: - subject_template: "[%{site_name}] בעיית מייל -- שגיאת פרסום" - text_body_template: | - אנו מצטערים, אך מסר הדוא"ל שלך ל-%{destination} (שכותרתו %{former_title}) לא עבר. - - סיבות אפשריות לעניין: מבנה מורכב, המסר ארוך מידי, המסר קצר מידי. אנא נסו שוב, או פרסמו באמצעות האתר עם הבעיה נמשכת. - email_reject_post_error_specified: - subject_template: "[%{site_name}] בעיית מייל -- שגיאת פרסום" - text_body_template: | - אנחנו מצטערים, אבל הודעת הדוא"ל שלך אל %{destination} (titled %{former_title}) לא עברה. - - הסיבה: - - %{post_error} - - אם באפשרותך לתקן את בעיה, אנא נסו שוב. - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - Reason: - - %{post_error} - - If you can correct the problem, please try again. email_reject_reply_key: subject_template: "[%{site_name}] בעיית מייל -- תו תגובה לא מוכר" - text_body_template: | - אנו מצטערים, אבל הודעת הדוא"ל שלך אל %{destination} (titled %{former_title}) לא עברה. - - מפתח התגובה לא קיים או לא מוכר, כך שאיננו יודעים לאיזה פרסום המייל הזה אמור להגיב. אנא צרו קשר עם אנשי הצוות. - email_reject_destination: - subject_template: "[%{site_name}] בעיית מייל -- כתובת יעד לא מזוהה" - text_body_template: | - מצטערים, אבל הודעת הדוא"ל שלך ל-%{destination} עם הכותרת %{former_title} לא הצליחה. - - לא הצלחנו לזהות כתובות יעד. אנא ודא שכתובת האתר נמצאת בשדה "אל:", ולא ב-"עותק" או "עותק מוחבא (CC / BCC), ושאתה שולח לכתובת אימייל שסופקה בידי הצוות. email_reject_topic_not_found: subject_template: "[%{site_name}] בעיית מייל -- לא נמצא נושא" - text_body_template: | - אנחנו מצטערים, אך הודעת הדוא"ל ששלחת אל %{destination} (בנושא %{former_title}) לא עברה. - - הנושאחושבים שהגבתם אליו כבר לא קיים, אולי הוא נמחק? אם אתם שמדובר בתקלה, צרו קשר עם איש/אשת צוות. email_reject_topic_closed: subject_template: "[%{site_name}] בעיית מייל -- נושא נסגר" text_body_template: | @@ -1432,16 +1257,8 @@ he: הנושא שהשבתם אליו נסגר ולכן לא ניתן להשיב לו יותר. אם אתם מאמינים שזוהי תקלה, אנא צרו קשר עם איש/אשת צוות. email_reject_auto_generated: subject_template: "[%{site_name}] בעיית מייל -- תגובה נוצרה אוטומטית" - text_body_template: | - אנחנו מצטערים, אך הודעת הדוא"ל ששלחת אל %{destination} (בנושא %{former_title}) לא עברה. - - המייל שלך סומן כ"נוצר אוטומטית", ולכן לא ניתן לקבל אותו. אם אתם מאמינים שמדובר בתקלה, צרו קשר עם איש/אשת צוות. email_error_notification: subject_template: "[%{site_name}] בעיית מייל -- בעיית אימות POP" - text_body_template: | - התרחשה תקלת אימות בזמן שבדקנו הודעות מייל בשרת ה-POP. - - אנא וודאו שכיוונים נכון את הרשאות ה-POP ב[הגדרות האתר](%{base_url}/admin/site_settings/category/email). too_many_spam_flags: subject_template: "New account blocked" text_body_template: | @@ -1454,24 +1271,10 @@ he: לפרטים נוספים, אנא פנו אל [כללי ההתנהלות הקהילתיים] [community guidelines](%{base_url}/guidelines) שלנו. blocked_by_staff: subject_template: "Account blocked" - text_body_template: | - שלום. - - זוהי הודעה אוטומטית שנשלחה אליך מ%{site_name} כדי לעדכן אותך שהחשבון שלך נחסם על ידי איש/אשת צוות. - - להדרכה נוספת, אנא פנו ל[כללי ההתנהגות הקהיליתיים](%{base_url}/guidelines) שלנו. user_automatically_blocked: subject_template: "המשתמש/ת החדשים %{username} נחסמו בשל התראות מהקהילה." - text_body_template: | - זהו מסר שנשלח בצורה אוטמטית. - המשתמש/ת החדש/ה [%{username}](%{base_url}%{user_url}) נחסמו באופן אוטומטי בשל כמה התראות בנוגע להודעה/הודעות שפרסמ/ה. - - אנא [סרקו את ההתראות] (%{base_url}/admin/flags). אם %{username נחסם בטעות מפרסום הודעות, הקישו על הכפתור "ביטול חסימה" ש[בעמוד האדמין עבור משתמש/ת אלה](%{base_url}%{user_url}). - - ניתן לשנות את המנגנון הזה דרך הגדרות 'חסימת_משתמש_חדש' שבאתר. spam_post_blocked: subject_template: "הודעות של המשתמש/ת החדש/ה %{username} נחסמו בשל קישורים חוזרים." - text_body_template: "זוהי הודעה שנשלחה באופן אוטומטי.\nהמשתמש/ת החדש/ה [%{username}](%{base_url}%{user_url}) ניסו ליצור כמה הודעות עם קישור ל-%{domains}, אבל הודעות אלו נחסמו כדי למנוע דואר זבל (spam). המשתמש/ת עדיין יכול/ה ליצור הודעות חדשות שלא מקשרות ל-%{domains}.\n\nאנא [סקרו את המשתמש/ת] (%{base_url}%{user_url}). \nהגדרות אלו ניתנו שינוי דרך ההגדרות 'משתמשיםחדשים_ספאם_סף'.\n" unblocked: subject_template: "Account unblocked" text_body_template: | @@ -1491,10 +1294,6 @@ he: download_remote_images_disabled: subject_template: "הורדת תמונות מרחוק מנוטרלת" text_body_template: "האפשרות \"הורדת תמונות מרוחקות\" נוטרלה בגלל שכל שטח האכסון שמוקצה ל\"תמונות שהורדו מרחוק\" נוצל." - unsubscribe_link: | - להסרה מרשימת התפוצה, בקר ב [הגדרות משתמש/ת](%{user_preferences_url}). - - בשביל להפסיק לקבל התראות בנוגע לשיחה הזאת [לחץ כאן](%{unsubscribe_url}). subject_re: "תגובה: " subject_pm: "[PM] " user_notifications: @@ -1502,60 +1301,19 @@ he: unsubscribe: title: "Unsubscribe" description: "Not interested in getting these emails? No problem! Click below to unsubscribe instantly:" - reply_by_email: "To respond, reply to this email or visit %{base_url}%{url} in your browser." - visit_link_to_respond: "To respond, visit %{base_url}%{url} in your browser." posted_by: "Posted by %{username} on %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} הזמין אותך להודעה '%{topic_title}'" - text_body_template: "\n%{username} הזמינ/ה אותך להודעה. \n\n> **%{topic_title}**\n>\n> %{topic_excerpt}\n\nב\n\n> %{site_title} -- %{site_description}\n\nתלחץ על הלינק בשביל לראות את ההודעה %{base_url}%{url}\n" - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} הזמין אותך לנושא '%{topic_title}'" - text_body_template: "\n%{username} הזמינ/ה אותך לשיחה. \n\n> **%{topic_title}**\n>\n> %{topic_excerpt}\n\nב\n\n> %{site_title} -- %{site_description}\n\nתלחץ על הלינק בשביל לראות את ההודעה %{base_url}%{url}\n" user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "סיכום קצר של %{site_link} מאז ביקורך האחרון ב-%{last_seen_at}" subject_template: "[%{site_name}] תקציר" @@ -1596,12 +1354,6 @@ he: הקישו על הקישור המצורף כדי להגדיר סיסמא לחשבונך החדש: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Confirm your new email address" - text_body_template: | - Confirm your new email address for %{site_name} by clicking on the following link: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "You've been approved on %{site_name}!" text_body_template: "ברוכים הבאים ל%{site_name}!\n\nחבר צוות אישר את החשבון שלך ב %{site_name}. \n\nלחץ על הקישור הבא לאשר והפעיל את החשבון החדש שלך:\n%{base_url}/users/activate-account/%{email_token}\n\nאם הלינק לא לחיץ, נסה להעתיק ולהדביק אותו לסרגל הכתובת בראש הדפדפן. \n\n%{new_user_tips}\n\nאנו מאמינים ב [civilized community behavior](%{base_url}/guidelines) בכל זמן.\n\nתהנה מהביקור!\n\n(אם אתה צריך ליצור קשר עם [staff members](%{base_url}/about) כחבר חדש, רק השב להודעה זאת. )\n\n" @@ -1615,7 +1367,6 @@ he: If the above link is not clickable, try copying and pasting it into the address bar of your web browser. page_not_found: - title: "The page you requested doesn't exist or is private." popular_topics: "פופלארי" recent_topics: "לאחרונה" see_more: "עוד" @@ -1675,19 +1426,6 @@ he: title: "תנאי השימוש" privacy_topic: title: "מדיניות פרטיות" - badges: - long_descriptions: - autobiographer: "אות יוענק לך כשתמלא את פרופיל המשתמש שלך ותבחר תמונת פרופיל. לשתף את הקהילה לגבי מי אתה ובמה אתה מעוניין עוזר ליצור קהילה יותר טובה ומחוברת. \n" - first_like: | - אות מוענק בפעם הראשונה שאתה עושה "לייק" לפרסום בעזרת כפתור ה :heart: . לעשות לייק לפרסומים היא דרך מעולה לידע את חברך בקהילה שמה שהם פרסמו היה מעניין, שימושי או מגניב. חלוק את האהבה! - first_link: | - תג זה מוענק בפעם הראשונה ששמים קישור לנושא אחר בתגובה. קישור נושאים עוזר לקוראים למצוא שיחות מעניינות קשורות לנושא. - first_quote: | - תג זה מוענק בפעם הראשונה שמצטטים פרסום בתגובה. ציטוט חלקים רלוונטים של פרסומים קודמים בתגובתך עוזר לשמור על דיונים מפוקסים. - first_share: | - תג זה מוענק בפעם הראשונה שמשתפים קישור לתגובה או נושא באמצעות כפתור השיתוף. שיתוף קישורים היא דרך מעולה להראות דיונים מעניינים עם שאר העולם ולהגדיל את הקהילה. - read_guidelines: | - תג זה מוענק על קריאת נהלי הקהילה. מעקב ושיתוף של הקוים המנחים עוזר ליצור קהילה בטוחה, כיפית ובת קימא. admin_login: success: "דוא\"ל נשלח" error: "שגיאה!" @@ -1698,3 +1436,8 @@ he: performance_report: initial_post_raw: 'נושא זה כולל דוחות פעילות יומיים עבור האתר שלך. ' initial_topic_title: דוחות פעילות לאתר + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.id.yml b/config/locales/server.id.yml index 19c8c01db55..a9f7b772f39 100644 --- a/config/locales/server.id.yml +++ b/config/locales/server.id.yml @@ -10,34 +10,35 @@ id: short_date_no_year: "D MMM" short_date: "D MMM, YYYY" long_date: "MMMM D, YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%m-%d-%Y" + short_no_year: "%B %-d" + date_only: "%B %-d, %Y" title: "Discourse" topics: "Topik" posts: "post" loading: "Memuat" powered_by_html: 'Didayakan oleh Discourse, aktifkan JavaScript untuk tampilan terbaik' - via: "%{username} via %{site_name}" - is_reserved: "telah dipesan" + log_in: "Log In" + anonymous: "Anonim" + errors: &errors + messages: + invalid: tidak benar + not_a_number: bukan numerik + not_an_integer: harus integer + odd: harus ganjil backup: operation_already_running: "Proses lain sedang berjalan. Tidak dapat menjalankan proses baru saat ini." backup_file_should_be_tar_gz: "File backup harus berupa arsip .tar.gz." not_logged_in: "Anda harus login untuk melakukan itu." read_only_mode_enabled: "Situs ini dalam modus read-only. Interaksi dinonaktifkan." - too_many_mentions: - zero: "Maaf, Anda tidak dapat mencantumkan pengguna lain." - one: "Maaf, Anda hanya dapat mencantumkan satu pengguna lain per post." - other: "Maaf, Anda hanya dapat mencantumkan %{count} pengguna per post." - too_many_mentions_newuser: - zero: "Maaf, pengguna baru tidak dapat mencantumkan pengguna lain." - one: "Maaf, pengguna baru hanya dapat mencantumkan satu pengguna lain per post." - other: "Maaf, pengguna baru hanya dapat mencantumkan %{count} pengguna per post." - too_many_images: - zero: "Maaf, pengguna baru tidak dapat memasukkan gambar ke dalam post." - one: "Maaf, pengguna baru hanya dapat memasukkan satu gambar per post." - other: "Maaf, pengguna baru hanya dapat memasukkan %{count} gambar per post." - too_many_links: - zero: "Maaf, pengguna baru tidak dapat memasukkan tautan dalam post." - one: "Maaf, pengguna baru hanya dapat memasukkan satu tautan per post." - other: "Maaf, pengguna baru hanya dapat memasukkan %{count} tautan per post." + embed: + start_discussion: "Mulai Diskusi" + continue: "Lanjutkan Diskusi" + in_reply_to: "▶ %{username}" + replies: + other: "%{count} balasan" spamming_host: "Maaf, Anda tidak dapat mencantumkan tautan ke host tersebut." just_posted_that: "tingkat kemiripan dengan post sebelumnya sangat tinggi" has_already_been_used: "telah digunakan" @@ -45,17 +46,34 @@ id: is_invalid: "tidak valid; cobalah dengan sesuatu yang lebih deskriptif" next_page: "halaman berikutnya →" prev_page: "← halaman sebelumnya" + page_num: "Halaman %{num}" + home_title: "Beranda" topics_in_category: "Topik dalam kategori '%{category}'" rss_posts_in_topic: "RSS feed dari '%{topic}'" rss_topics_in_category: "RSS feed dari topik-topik pada kategori '%{category}'" author_wrote: "%{author} menuliskan:" + num_posts: "Pos:" + num_participants: "Peserta:" + read_full_topic: "Baca topik sepenuhnya" + private_message_abbrev: "Psn" + rss_description: + latest: "Topik Terbaru" + hot: "Topik Terpanas" + posts: "Pos terbaru" + excerpt_image: "gambar" groups: errors: can_not_modify_automatic: "Anda tidak dapat mengubah grup otomatis" default_names: + everyone: "setiap orang" admins: "admin" moderators: "moderator" staff: "staff" + trust_level_0: "trust_level_0" + trust_level_1: "trust_level_1" + trust_level_2: "trust_level_2" + trust_level_3: "trust_level_3" + trust_level_4: "trust_level_4" education: until_posts: other: "%{count} post" @@ -65,21 +83,30 @@ id: name: "Nama Kategori" post: raw: "Konten" + user_profile: + bio_raw: "Tentang Saya" errors: - messages: - is_invalid: "tidak valid; cobalah dengan sesuatu yang lebih deskriptif" - has_already_been_used: "telah digunakan" + <<: *errors user_profile: no_info_me: "
    kolom Tentang Saya dari profil Anda masih kosong, apakah Anda mau mengisinya?
    " no_info_other: "
    %{name} belum mengisi kolom Tentang Saya untuk profilnya
    " + vip_category_name: "Lounge / Santai" + staff_category_name: "Staf" + lounge_welcome: + title: "Selamat datang di Lounge" category: topic_prefix: "Tentang kategori %{category}" - replace_paragraph: "[Ganti paragraf pertama ini dengan deskripsi singkat mengenai kategori baru Anda. Panduan ini akan muncul dalam area pemilihan kategori, cobalah untuk membuatnya kurang dari 200 karakter. Kategori ini tidak akan muncul dalam halaman kategori hingga Anda mengubah teks ini atau membuat topik.]" trust_levels: newuser: title: "pengguna baru" basic: title: "pengguna standar" + member: + title: "anggota" + regular: + title: "umum" + leader: + title: "pemimpin" rate_limiter: too_many_requests: "Kami membatasi jumlah tindakan itu dapat dilakukan dalam satu hari. Mohon tunggu %{time_left} sebelum mencoba lagi." hours: @@ -95,12 +122,19 @@ id: other: "baru saja" x_seconds: other: "%{count} detik yang lalu" + post_action_types: + bookmark: + title: 'Penandaan' topic_flag_types: spam: long_form: 'menandai sebagai spam' notify_moderators: email_title: 'Perhatian moderator dibutuhkan di topik "%{title}"' reports: + posts: + title: "Pos" + likes: + title: "Suka" notify_moderators_private_messages: xaxis: "Hari" notify_user_private_messages: @@ -117,6 +151,8 @@ id: top_referred_topics: xaxis: "Topik" num_clicks: "Klik" + page_view_anon_reqs: + title: "Anonim" dashboard: rails_env_warning: "Server Anda berjalan dalam modus %{env}." host_names_warning: "Berkas config/database.yml Anda menggunakan nama host default localhost. Ubahlah untuk menggunakan nama host dari situs Anda." @@ -134,9 +170,26 @@ id: user_notifications: previous_discussion: "Balasan Sebelumnya" posted_by: "Dipost oleh %{username} pada %{post_date}" + page_not_found: + see_more: "Selengkapnya" + terms_of_service: + title: "Ketentuan Layanan" upload: images: size_not_found: "Maaf, kami tidak dapat mendeteksi ukuran dari gambar. Apa berkas gambar yang Anda unggah rusak?" email_log: no_user: "Tidak dapat menemukan pengguna dengan id %{user_id}" post_not_found: "Tidak dapat menemukan post dengan id %{post_id}" + guidelines: "Petunjuk" + privacy: "Privasi" + tos_topic: + title: "Ketentuan Layanan" + privacy_topic: + title: "Kebijakan Privasi" + date: + <<: *datetime_formats + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml index f2f2729300d..859e27ccca8 100644 --- a/config/locales/server.it.yml +++ b/config/locales/server.it.yml @@ -10,18 +10,28 @@ it: short_date_no_year: "D MMM" short_date: "D MMM YYYY" long_date: "D MMMM YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%d-%m-%Y" + short_no_year: "%B %-d" + date_only: "%B %-d, %Y" + date: + month_names: [null, Gennaio, Febbraio, Marzo, Aprile, Maggio, Giugno, Luglio, Agosto, Settembre, Ottobre, Novembre, Dicembre] + <<: *datetime_formats title: "Discourse" topics: "Argomenti" posts: "messaggi" loading: "Caricamento" powered_by_html: 'Powered by Discourse, è consigliato abilitare JavaScript ' log_in: "Accedi" - via: "%{username} via %{site_name}" - is_reserved: "è riservato" purge_reason: "Cancellato automaticamente come account abbandonato e mai attivato" disable_remote_images_download_reason: "Lo scaricamento delle immagini remote è stato disabilitato perché non c'è abbastanza spazio disco disponibile." anonymous: "Anonimo" - errors: + emails: + incoming: + default_subject: "Email in arrivo da %{email}" + show_trimmed_content: "Mostra contenuto tagliato" + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "è limitato a %{max} caratteri; tu ne hai inseriti %{length}." @@ -37,8 +47,10 @@ it: exclusion: è riservato greater_than: deve essere maggiore di %{count} greater_than_or_equal_to: deve essere maggiore o uguale a %{count} + has_already_been_used: "è già stato usato" inclusion: non è incluso nella lista invalid: non è valido + is_invalid: "non è valido; prova a specificare meglio" less_than: deve essere minore di %{count} less_than_or_equal_to: deve essere minore o uguale a %{count} not_a_number: non è un numero @@ -66,8 +78,12 @@ it: embed: load_from_remote: "Si è verificato un errore nel caricamento del messaggio." site_settings: + min_username_length_exists: "C'è almeno un utente con il nome più corto della lunghezza minima che stai cercando di impostare." min_username_length_range: "Non puoi impostare il minimo più grande del massimo." + max_username_length_exists: "C'è almeno un utente con il nome più lungo della lunghezza massima che stai cercando di impostare." + max_username_length_range: "Non puoi impostare il massimo inferiore al minimo." default_categories_already_selected: "Non puoi selezionare una categoria usata in un'altra lista." + s3_upload_bucket_is_required: "Non è possibile attivare i caricamenti da S3 a meno che non imposti l'opzione 's3_upload_bucket'." bulk_invite: file_should_be_csv: "Il file caricato deve essere in formato csv o txt." backup: @@ -78,6 +94,8 @@ it: not_found: "L'URL o la risorsa richiesta non sono stati trovati." invalid_access: "Non hai il permesso di vedere la risorsa richiesta." read_only_mode_enabled: "Il sito è in modalità di sola lettura. Le interazioni sono disabilitate." + reading_time: "Tempo di lettura" + likes: "Mi piace" too_many_replies: one: "Spiacenti, ma i nuovi utenti possono inserire solo 1 risposta nello stesso argomento." other: "Spiacenti, ma i nuovi utenti possono inserire solo %{count} risposte nello stesso argomento." @@ -94,26 +112,26 @@ it: replies: one: "1 risposta" other: "%{count} risposte" + no_mentions_allowed: "Spiacenti, non puoi menzionare altri utenti." too_many_mentions: - zero: "Spiacenti, non puoi menzionare altri utenti." - one: "Spiacenti, puoi menzionare un solo altro utente in un messaggio." - other: "Spiacenti, puoi menzionare solo %{count} utenti in un messaggio." + one: "Spiacenti, puoi menzionare al massimo un utente in un messaggio." + other: "Spiacenti, puoi menzionare al massimo %{count} utenti in un messaggio." + no_mentions_allowed_newuser: "Spiacenti, i nuovi utenti non possono menzionare altri utenti." too_many_mentions_newuser: - zero: "Spiacenti, i nuovi utenti non possono menzionare altri utenti." - one: "Spiacenti, i nuovi utenti possono menzionare un solo altro utente in un messaggio." - other: "Spiacenti, i nuovi utenti possono menzionare solo %{count} utenti in un messaggio." + one: "Spiacenti, i nuovi utenti possono menzionare al massimo un utente in un messaggio." + other: "Spiacenti, i nuovi utenti possono menzionare al massimo %{count} utenti in un messaggio." + no_images_allowed: "Spiacenti, i nuovi utenti non possono inserire immagini nei messaggi." too_many_images: - zero: "Spiacenti, i nuovi utenti non possono inserire immagini nei messaggi." - one: "Spiacenti, i nuovi utenti possono inserire solo un'immagine in un messaggio." - other: "Spiacenti, i nuovi utenti possono inserire solo %{count} immagini in un messaggio." + one: "Spiacenti, i nuovi utenti possono inserire al massimo un'immagine in un messaggio." + other: "Spiacenti, i nuovi utenti possono inserire al massimo %{count} immagini in un messaggio." + no_attachments_allowed: "Spiacenti, i nuovi utenti non possono inserire allegati nei messaggi." too_many_attachments: - zero: "Spiacenti, i nuovi utenti non possono inserire allegati nei messaggi." - one: "Spiacenti, i nuovi utenti possono inserire un solo allegato in un messaggio." - other: "Spiacenti, i nuovi utenti possono solo inserire %{count} allegati in un messaggio." + one: "Spiacenti, i nuovi utenti possono inserire al massimo un allegato in un messaggio." + other: "Spiacenti, i nuovi utenti possono inserire al massimo %{count} allegati in un messaggio." + no_links_allowed: "Spiacenti, i nuovi utenti non possono inserire collegamenti nei messaggi." too_many_links: - zero: "Spiacenti, i nuovi utenti non possono inserire collegamenti nei messaggi." - one: "Spiacenti, i nuovi utenti possono inserire solo un collegamento in un messaggio." - other: "Spiacenti, i nuovi utenti possono inserire solo %{count} collegamenti in un messaggio." + one: "Spiacenti, i nuovi utenti possono inserire al massimo un collegamento in un messaggio." + other: "Spiacenti, i nuovi utenti possono inserire al massimo %{count} collegamenti in un messaggio." spamming_host: "Spiacenti, non puoi inserire un collegamento verso quel dominio." user_is_suspended: "Agli utenti sospesi non è permesso creare messaggi." topic_not_found: "Quancosa non ha funzionato. Forse questo argomento è stato chiuso o cancellato mentre lo leggevi." @@ -145,6 +163,7 @@ it: errors: can_not_modify_automatic: "Non puoi modificare un gruppo automatico" member_already_exist: "'%{username}' è già membro di questo gruppo." + invalid_domain: "'%{domain}' non è un dominio valido." default_names: everyone: "chiunque" admins: "amministratori" @@ -170,6 +189,7 @@ it: - Le critiche costruttive sono benvenute, ma critica le *idee* non le persone. Per maggiori informazioni, [guarda le nostre linee guida delle community](/guidelines). Questo pannello sarà visualizzato soltanto per i primi %{education_posts_text}. + avatar: "### Che ne dici di un'immagine per il tuo account? \n\nHai pubblicato alcuni argomenti e risposte, ma l'immagine del tuo profilo non è speciale quanto te -- è solo una lettera. \n\nPerché non **[accedi al tuo profilo utente](%{profile_path})** e carichi un'immagine che ti rappresenta? \n\nÈ più facile seguire le discussioni e trovare persone interessanti nelle conversazioni se tutti hanno un'immagine profilo univoca!\n" sequential_replies: "### Considera la possibilità di rispondere a più messaggi contemporaneamente\n\nPiuttosto che inviare più risposte di seguito ad un messaggio, considera la possibilità di inserire un'unica risposta con citazioni o riferimenti @nome ai messaggi precedenti. \n\nPuoi modificare la tua precedente risposta per aggiungere una citazione evidenziando il testo e selezionando il bottone Rispondi citando che compare. \n\nE' più facile per chiunque leggere argomenti che hanno poche risposte più dettagliate, rispetto a molte brevi risposte individuali.\n" dominating_topic: | ### Permetti agli altri di partecipare alla conversazione @@ -198,9 +218,6 @@ it: user_profile: bio_raw: "Su di me" errors: - messages: - is_invalid: "non è valido; cerca di essere più descrittivo" - has_already_been_used: "è stato già usato" models: topic: attributes: @@ -221,6 +238,7 @@ it: attributes: hex: invalid: "non è un colore valido" + <<: *errors user_profile: no_info_me: "
    il campo \"Su di me\" del tuo profilo è vuoto, vuoi compilarlo?
    " no_info_other: "
    %{name} non ha ancora compilato il campo \"Su di me\" del suo profilo
    " @@ -236,13 +254,12 @@ it: body: "\nCongratulazioni! :confetti_ball: \n\nSe vedi questo argomento, sei stato recentemente promosso a **esperto** (livello di esperienza 3). \n\nAdesso puoi … \n\n* Modificare il titolo di qualunque argomento \n* Cambiare la categoria di qualunque argomento \n* Seguire tutti i tuoi collegamenti (è rimosso il [nofollow automatico](http://it.wikipedia.org/wiki/Nofollow) ) \n* Accedere alla categoria privata Lounge visibile solo agli utenti con livello di esperienza 3 o superiore \n* Cancellare i messaggi spam con un singolo clic\n\nEcco l'elenco degli altri [utenti esperti](/badges/3/regular). Vai a salutarli. \n\nGrazie per essere una parte importante di questa comunità! \n\n(Per maggiori informazioni sui livelli di esperienza, [leggi questa discussione][trust]. Nota che possono rimanere utenti esperti solo quegli utenti che continuano a soddisfare i criteri di selezione)\n\n[trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924\n" category: topic_prefix: "Definizione della categoria %{category}" - replace_paragraph: "[Sostituisci questo primo paragrafo con una breve descrizione della nuova categoria. Questa guida apparirà nell'area di selezione della categoria, perciò cerca di stare sotto i 200 caratteri. Finché non modifichi questo testo o non crei argomenti, questa categoria non apparirà sulla pagina delle categorie.]" - post_template: "%{replace_paragraph}\n\nUsa i paragrafi seguenti per una descrizione più estesa, ed anche per stabilire delle regole per la categoria o delle linee guida.\n\nAlcune cose da considerare in qualunque discussione sono:\n\n- A che serve questa categoria? Perché la gente dovrebbe scegliere questa categoria per i loro argomenti?\n\n- In cosa questa categoria è diversa dalle altre categorie già esistenti?\n\n- C'è bisogno di questa categoria?\n\n- Dovremmo fondere questa categoria con un'altra, oppure dividerla in più categorie?\n" + replace_paragraph: "(Sostituisci questo primo paragrafo con una breve descrizione della nuova categoria. Questa guida apparirà nell'area di selezione della categoria, perciò cerca di stare sotto i 200 caratteri. **Finché non modifichi questo testo o non crei argomenti, questa categoria non apparirà sulla pagina delle categorie.**)" + post_template: "%{replace_paragraph}\n\nUsa i seguenti paragrafi per una descrizione più estesa, ed anche per stabilire delle regole o linee guida per la categoria:\n\n- Perché la gente dovrebbe usare questa categoria? A che serve? \n\n- In cosa esattamente questa categoria è diversa dalle altre categorie già esistenti? \n\n- Cosa dovrebbero contenere gli argomenti in questa categoria? \n\n- C'è bisogno di questa categoria? Possiamo fonderla con un'altra categoria o sottocategoria?\n" errors: uncategorized_parent: "La categoria \"Non classificato\" non può avere una categoria superiore." self_parent: "La categoria-genitore di una sottocategoria non può essere se stessa." depth: "Non puoi annidare una sottocategoria sotto un'altra" - email_in_already_exist: "L'indirizzo email in ingresso '%{email_in}' è già stato usato per la categoria '%{category_name}'." cannot_delete: uncategorized: "Non puoi eliminare la categoria \"Non classificato\"" has_subcategories: "Non puoi cancellare questa categoria perché ha sotto-categorie." @@ -250,21 +267,32 @@ it: one: "Non puoi eliminare questa categoria perché ha 1 argomento. L'argomento più vecchio è %{topic_link}." other: "Non puoi cancellare questa categoria perché ha %{count} argomenti. L'argomento più vecchio è %{topic_link}." topic_exists_no_oldest: "Non puoi cancellare questa categoria perché il numero di argomenti è di %{count}." + uncategorized_description: "Argomenti che non necessitano di una categoria, o che non ricadono in nessuna categoria esistente." trust_levels: newuser: title: "nuovo utente" basic: title: "utente base" - regular: + member: title: "assiduo" + regular: + title: "esperto" leader: - title: "abituale" - elder: - title: "capo" + title: "veterano" change_failed_explanation: "Hai cercato di degradare %{user_name} a '%{new_trust_level}'. Comunque il suo livello di esperienza è già '%{current_trust_level}'. %{user_name} resterà a '%{current_trust_level}' - se vuoi degradarlo, prima blocca il suo livello di esperienza" rate_limiter: - slow_down: "Hai eseguito questa operazione troppe volte, riprova più tardi" + slow_down: "Hai eseguito questa operazione troppe volte, riprova più tardi." too_many_requests: "C'è un limite giornaliero su quante volte si può fare questa azione. Per favore attendi %{time_left} prima di riprovare." + by_type: + first_day_replies_per_day: "Hai raggiunto il massimo numero di risposte che può creare un nuovo utente il suo primo giorno. Per favore attendi %{time_left} prima di riprovare." + first_day_topics_per_day: "Hai raggiunto il massimo numero di argomenti che può creare un nuovo utente il suo primo giorno. Per favore attendi %{time_left} prima di riprovare." + create_topic: "Stai creando argomenti troppo rapidamente. Attendi %{time_left} prima di riprovare." + create_post: "Stai rispondendo troppo rapidamente. Attendi %{time_left} prima di riprovare." + topics_per_day: "Hai raggiunto il massimo numero di nuovi argomenti per oggi. Per favore attendi %{time_left} prima di riprovare." + pms_per_day: "Hai raggiunto il massimo numero di messaggi per oggi. Per favore attendi %{time_left} prima di riprovare." + create_like: "Hai raggiunto il massimo numero di \"Mi piace\" per oggi. Per favore attendi %{time_left} prima di riprovare." + create_bookmark: "Hai raggiunto il massimo numero di segnalibri per oggi. Per favore attendi %{time_left} prima di riprovare." + edit_post: "Hai raggiunto il massimo numero di modifiche per oggi. Per favore attendi %{time_left} prima di riprovare." hours: one: "1 ora" other: "%{count} ore" @@ -383,19 +411,19 @@ it: description: 'Questo messaggio ha dei contenuti che una persona ragionevole considererebbe offensivi, aggressivi o una violazione delle linee guida della comunità.' long_form: 'segnalato come inappropriato' notify_user: - title: 'Messaggio @{{username}}' - description: 'Vorrei discutere direttamente e privatamente con l''autore di questo messaggio. Non voglio attivare una segnalazione.' + title: 'Invia un messaggio a @{{username}}' + description: 'Vorrei discutere direttamente e privatamente con l''autore di questo messaggio.' long_form: 'messaggio inviato' email_title: 'Il tuo messaggio su "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Altro" - description: 'Questo messaggio richiede attenzione da parte dei moderatori per altri motivi non elencati.' - long_form: 'segnalato all''attenzione dei moderatori' - email_title: 'Un messaggio "%{title}" richiede l''attenzione dei moderatori' + description: 'Questo messaggio richiede attenzione da parte dello staff per altri motivi non elencati.' + long_form: 'segnalato all''attenzione dello staff' + email_title: 'Un messaggio in "%{title}" richiede l''attenzione dello staff' email_body: "%{link}\n\n%{message}" bookmark: - title: 'Segnalibri' + title: 'Segnalibro' description: 'Messaggio nei segnalibri' long_form: 'Messaggio inserito nei segnalibri' like: @@ -417,7 +445,7 @@ it: long_form: 'segnalato come inappropriato' notify_moderators: title: "Altro" - description: 'Questo argomento richiede attenzione da parte dei moderatori in base alle linee guida, ai TOS o per altri motivi non elencati.' + description: 'Questo argomento richiede attenzione da parte deilo staff in base alle linee guida, ai TOS o per altri motivi non elencati.' long_form: 'segnalato all''attenzione dei moderatori' email_title: 'L''argomento "%{title}" richiede l''attenzione di un moderatore' email_body: "%{link}\n\n%{message}" @@ -453,6 +481,10 @@ it: title: "Nuovi Utenti" xaxis: "Giorno" yaxis: "Numero di nuovi utenti" + profile_views: + title: "Visite Profilo Utente" + xaxis: "Giorno" + yaxis: "Numero profili utente visualizzati" topics: title: "Argomenti" xaxis: "Giorno" @@ -537,9 +569,13 @@ it: xaxis: "Giorno" yaxis: "Richieste API Totali" page_view_logged_in_mobile_reqs: + title: "Richieste API registrate" xaxis: "Giorno" + yaxis: "Richieste API da mobile registrate" page_view_anon_mobile_reqs: + title: "Richieste anonime API" xaxis: "Giorno" + yaxis: "Richieste anonime API da mobile" http_background_reqs: title: "Background" xaxis: "Giorno" @@ -582,14 +618,16 @@ it: host_names_warning: "Il tuo file config/database.yml usa l'hostname di default: localhost. Aggiornalo con l'hostname del tuo sito." gc_warning: 'Il tuo server usa i parametri di garbage collection di default di ruby, che potrebbero non garantirti le migliori prestazioni. Leggi questo argomento sulla taratura delle prestazioni: Tuning Ruby and Rails for Discourse.' sidekiq_warning: 'Sidekiq non è in esecuzione. Molte attività, come l''invio di email, sono eseguite in maniera asincrona da sidekiq. Assicurati che almeno un processo sidekiq sia in esecuzione. Leggi altro su sidekiq qui.' + queue_size_warning: 'Il numero di job in coda è %{queue_size}, il che è alto. Ciò potrebbe indicare un problema con i processi Sidekiq, oppure devi aggiungere altri worker Sidekiq.' memory_warning: 'Il tuo server gira con meno di 1 GB di memoria. Si raccomanda almeno 1 GB di memoria.' - google_oauth2_config_warning: 'Il server è configurato per permettere registrazioni e login con Google Oauth2 (enable_google_oauth2_logins), ma il client id e il client secret non sono impostati. Vai nelle Impostazioni del sito e aggiorna le impostazioni. Leggi questa guida per saperne di più.' - facebook_config_warning: 'Il server è configurato per accettare registrazioni e login con Facebook (enable_facebook_logins), tuttavia i parametri app id e secret non sono stati impostati. Vai alle Impostazioni e aggiorna i campi interessati. Leggi questa guida per saperne di più.' - twitter_config_warning: 'Il server è configurato per accettare registrazioni e login con Twitter (enable_twitter_logins), tuttavia i parametri key e secret non sono stati impostati. Vai alle Impostazioni e aggiorna i campi interessati. Leggi questa guida per saperne di più.' - github_config_warning: 'Il server è configurato per accettare registrazioni e login con GitHub (enable_github_logins), tuttavia i parametri client id e secret non sono stati impostati. Vai alle Impostazioni e aggiorna i campi interessati. Leggi questa guida per saperne di più.' + google_oauth2_config_warning: 'Il server è configurato per permettere iscrizioni e login con Google Oauth2 (enable_google_oauth2_logins), ma il client id e il client secret non sono impostati. Vai nelle Impostazioni del sito e aggiorna le impostazioni. Leggi questa guida per saperne di più.' + facebook_config_warning: 'Il server è configurato per accettare iscrizioni e login con Facebook (enable_facebook_logins), tuttavia i parametri app id e secret non sono stati impostati. Vai alle Impostazioni e aggiorna i campi interessati. Leggi questa guida per saperne di più.' + twitter_config_warning: 'Il server è configurato per accettare iscrizioni e login con Twitter (enable_twitter_logins), tuttavia i parametri key e secret non sono stati impostati. Vai alle Impostazioni e aggiorna i campi interessati. Leggi questa guida per saperne di più.' + github_config_warning: 'Il server è configurato per accettare iscrizioni e login con GitHub (enable_github_logins), tuttavia i parametri client id e secret non sono stati impostati. Vai alle Impostazioni e aggiorna i campi interessati. Leggi questa guida per saperne di più.' s3_config_warning: 'Il server è configurato per caricare file su s3, ma almeno uno dei seguenti parametri non è impostato: s3_access_key_id, s3_secret_access_key, s3_upload_bucket. Vai nelle Impostazioni Sito e aggiorna i parametri. Leggi anche "How to set up image uploads to S3?" per saperne di più.' s3_backup_config_warning: 'Il server è configurato per caricare i backup su S3, ma almeno una delle seguenti impostazioni non è impostata: s3_access_key_id, s3_secret_access_key, s3_backup_bucket. Vai nelle Impostazioni Sito e aggiorna le impostazioni. Leggi anche "How to set up image uploads to S3?" per saperne di più.' image_magick_warning: 'Il server è configurato per creare miniature di immagini grandi, ma ImageMagick non è installato. Installa ImageMagick usando il tuo package manager preferito o scarica la versione più recente.' + failing_emails_warning: 'Ci sono %{num_failed_jobs} email job falliti. Controlla il tuo app.yml e assicurati che le impostazioni del server mail siano corrette. Vedi i job falliti in Sidekiq.' default_logo_warning: "Non hai personalizzato il logo del tuo sito. Aggiorna logo_url, logo_small_url e favicon_url nelle Impostazioni Sito." contact_email_missing: "Inserisci un indirizzo email di contatto per il sito, in modo da essere raggiungibile per questioni urgenti riguardanti il sito. Aggiornalo nelle Impostazioni Sito." contact_email_invalid: "La email di contatto non è valida. Aggiornala nelle Impostazioni Sito." @@ -598,37 +636,7 @@ it: consumer_email_warning: "Il tuo sito è configurato per usare Gmail (o un altro servizio email consumer) per inviare le email. Gmail limita il numero di email che puoi inviare. Considera l'utilizzo di un fornitore di servizi come mandrill.com per assicurare l'invio delle email." site_contact_username_warning: "Inserisci il nome di un membro dello staff da cui inviare messaggi importanti in maniera automatica. Aggiorna site_contact_username nelle Impostazioni Sito." notification_email_warning: "Le email di notifica non vengono inviate da un indirizzo email valido del tuo dominio; l'invio di email sarà inaffidabile. Definisci notification_email con un indirizzo email valido nelle Impostazioni Sito." - content_types: - education_new_reply: - title: "Educazione Nuovi Utenti: Prime Risposte" - description: "Per le prime due risposte dei nuovi utenti, durante la composizione del messaggio una pop-up verrà automaticamente visualizzata per mostrare dei consigli." - education_new_topic: - title: "Educatione Nuovi Utenti: Primi Argomenti" - description: "Per i primi due argomenti dei nuovi utenti, verrà automaticamente visualizzata una finestra pop-up per mostrare dei consigli durante la composizione del messaggio." - usage_tips: - title: "Guida Nuovi Utenti" - description: "Guida e informazioni essenziali per nuovi utenti." - welcome_user: - title: "Benvenuto: Nuovo Utente" - description: "Verrà inviato automaticamente un messaggio a tutti i nuovi utenti dopo la registrazione." - welcome_invite: - title: "Benvenuto: Utente Invitato" - description: "Verrà inviato automaticamente un messaggio a tutti gli utenti invitati quando accettano l'invito a partecipare da parte di un altro utente." - login_required_welcome_message: - title: "Accesso Richiesto: Messaggio di Benvenuto" - description: "Messaggio che viene mostrato agli utenti non collegati quando l'impostazione \"login obbligatorio\" è attiva." - login_required: - title: "Login Richiesto: Homepage" - description: "Testo mostrato agli utenti non autorizzati quando il login è necessario." - head: - title: "Intestazione HTML" - description: "HTML che verrà inserito all'interno dei tag ." - top: - title: "Intestazione delle pagine" - description: "HTML che verrà aggiunto in cima a ogni pagina (dopo l'header, prima della barra di navigazione o del titolo dell'argomento)." - bottom: - title: "Fondo delle pagine" - description: "HTML che verrà aggiunto prima del tag ." + subfolder_ends_in_slash: "L'impostazione della sottocartella è errata; DISCOURSE_RELATIVE_URL_ROOT finisce con uno slash." site_settings: censored_words: "Parole che saranno automaticamente sostituite con ■■■■" delete_old_hidden_posts: "Cancella automaticamente tutti i messaggi nascosti che restano nascosti per più di 30 giorni." @@ -642,8 +650,8 @@ it: max_topic_title_length: "Numero massimo di caratteri per i titoli degli argomenti" min_private_message_title_length: "Numero minimo di caratteri per un messaggio" min_search_term_length: "Numero minimo di caratteri per le parole cercate" + search_tokenize_chinese_japanese_korean: "Attiva la tokenizzazione dei caratteri Cinesi/Giapponesi/Coreani nella ricerca anche sui siti non CJK" allow_uncategorized_topics: "Permetti la creazione di argomenti senza categoria. ATTENZIONE: se ci sono argomenti senza categoria, devi ricategorizzarli prima di disabilitare questa opzione." - uncategorized_description: "La descrizione della categoria \"Non classificato\". Lascia vuoto per nessuna descrizione." allow_duplicate_topic_titles: "Permetti più argomenti con lo stesso identico titolo" unique_posts_mins: "Quanti minuti prima che un utente possa inviare un altro argomento con lo stesso contenuto" educate_until_posts: "Per i primi (n) messaggi di un utente, mostra la finestra pop-up con il pannello di istruzioni per nuovi utenti." @@ -656,7 +664,7 @@ it: download_remote_images_to_local: "Scarica localmente le immagini remote; ciò permettei di evitare immagini assenti." download_remote_images_threshold: "Minimo spazio disco necessario per scaricare le immagini remote in locale (in percentuale)" disabled_image_download_domains: "Le immagini non verranno mai scaricate dai seguenti domini. Elenco delimitato dal carattere pipe |" - ninja_edit_window: "Per (n) secondi dopo la creazione del messaggio, le modifiche non saranno tracciate nella cronologia." + editing_grace_period: "Per (n) secondi dopo la creazione del messaggio, le modifiche non saranno tracciate nella cronologia." post_edit_time_limit: "L'autore può modificare o cancellare il proprio messaggio per (n) minuti dopo averlo inserito. Metti 0 per sempre." edit_history_visible_to_public: "Permetti a tutti di vedere le precedenti versioni di un messaggio modificato. Se disabilitato solo i membri dello staff possono vederle." delete_removed_posts_after: "I messaggi rimossi dall'autore saranno automaticamente cancellati dopo (n) ore. Se impostato a 0, i messaggi saranno cancellati subito." @@ -671,6 +679,9 @@ it: post_excerpt_maxlength: "Lunghezza massima dell'estratto / riassunto di un messaggio." post_onebox_maxlength: "Lunghezza massima in caratteri di un messaggio Discourse in Onebox." onebox_domains_whitelist: "Lista di domini per i quali consentire la funzione di onebox; questi domini devono supportare OpenGraph o oEmbed. Testali su http://iframely.com/debug" + logo_url: "L'immagine nel logo in alto a sinistra del sito, dovrebbe essere larga e di forma rettangolare. Se non impostata, verrà usato il testo del titolo del sito." + digest_logo_url: "Il logo alternativo usato in cima alla email di riepilogo. Dovrebbe essere a forma di un ampio rettangolo. Se lasciato vuoto, sarà utilizzato il campo `logo_url`." + logo_small_url: "Il piccolo logo in alto a sinistra del tuo sito, dovrebbe essere a forma di quadrato. Se non impostato, verrà mostrata l'icona di una casa." apple_touch_icon_url: "Icona usata per dispositivi touch Apple. La dimensione consigliata è 144 x 144 pixel." notification_email: "L'indirizzo presente nel campo from: usato per inviare tutte le email essenziali di sistema. Il dominio indicato deve avere i record SPF, DKIM e reverse PTR impostati correttamente perché l'email arrivi." email_custom_headers: "Una lista di intestazioni email personalizzate delimitata da una barra verticale (pipe |)" @@ -681,7 +692,6 @@ it: summary_likes_required: "Minimo numero di \"Mi piace\" in un argomento affinché venga abilitato 'Riassumi Questo Argomento'" summary_percent_filter: "Quando un utente clicca su 'Riassumi Questo Argomento', mostra i primi % messaggi" summary_max_results: "Massimo numero di messaggi mostrati in 'Riassumi Argomento'" - enable_private_messages: "Autorizza gli utenti con livello di esperienza 1 a creare e rispondere ai messaggi" enable_long_polling: "Il message bus per le notifiche può usare il long polling" long_polling_base_url: "URL di base usato per il long polling (quando una CDN serve contenuto dinamico, bisogna impostarlo come origin pull) es. http://origin.site.com" long_polling_interval: "Tempo di attesa prima che il server risponda ai client che non ci sono dati da trasmettere (solo per utenti autenticati)" @@ -720,7 +730,6 @@ it: suppress_reply_directly_above: "Non mostrare in-risposta-a espandibile in un messaggio quando c'è una sola risposta sopra quel messaggio. " suppress_reply_when_quoting: "Non mostrare in-risposta-a espandibile in un messaggio quando il messaggio include la citazione." max_reply_history: "Numero massimo di risposte da espandere quando si espande in-risposta-a" - experimental_reply_expansion: "Nascondi le risposte intermedie quando si espande una risposta (sperimentale)" topics_per_period_in_top_summary: "Numero di argomenti di punta mostrati nel riepilogo di default." topics_per_period_in_top_page: "Numero di argomenti di punta mostrati nella vista espansa 'Mostra Altro'" redirect_users_to_top_page: "Redirigi automaticamente i nuovi utenti e quelli assenti da tempo sulla pagina degli argomenti di punta." @@ -742,7 +751,7 @@ it: login_required: "E' richiesta l'autenticazione per leggere contenuti su questo sito, disabilita l'accesso anonimo." min_username_length: "Lunghezza minima del nome utente in caratteri." max_username_length: "Lunghezza massima del nome utente in caratteri. " - reserved_usernames: "Nomi utente ai quali non è permesso l'accesso." + reserved_usernames: "Nomi utente ai quali non è permessa l'iscrizione.." min_password_length: "Minima lunghezza della password." block_common_passwords: "Non permettere password che sono nelle 10.000 password più comuni." enable_sso_provider: "Implementa il protocollo SSO Discourse nell'endpoint /session/sso_provider, richiede che sia impostata l'opzione sso_secret" @@ -798,6 +807,7 @@ it: s3_secret_access_key: "La access key secret Amazon S3 che verrà usata per caricare le immagini." s3_region: "La region name Amazon S3 che verrà usata per caricare le immagini." avatar_sizes: "Elenco delle dimensioni degli avatar, generate automaticamente." + external_system_avatars_enabled: "Utilizza un servizio esterno per gli avatar." enable_flash_video_onebox: "Attiva l'inserimento di collegamenti swf e flv (Adobe Flash) in onebox. ATTENZIONE: comporta rischi per la sicurezza." default_invitee_trust_level: "Livello di esperienza (0-4) assegnato di default agli utenti invitati." default_trust_level: "Livello di esperienza (da 0 a 4) assegnato ai nuovi utenti. ATTENZIONE! Modificare questa opzione ti espone ad un serio rischio di ricevere posta indesiderata." @@ -811,16 +821,9 @@ it: tl2_requires_likes_received: "Quanti \"Mi piace\" deve ricevere un utente per essere promosso al livello di esperienza 2." tl2_requires_likes_given: "Quanti \"Mi piace\" deve dare un utente per essere promosso al livello di esperienza 2." tl2_requires_topic_reply_count: "A quanti argomenti deve rispondere un utente per essere promosso al livello di esperienza 2." - tl3_requires_days_visited: "Per quanti giorni un utente deve aver visitato il sito negli ultimi 100 giorni per essere promosso al livello di esperienza 3 (da 0 a 100)." - tl3_requires_topics_replied_to: "Numero minimo di argomenti cui un utente deve aver risposto negli ultinmi 100 giorni per essere promosso al livello di esperienza 3 (0 o maggiore)." - tl3_requires_topics_viewed: "Percentuale di argomenti creati negli ultimi 100 giorni che un utente deve leggere per essere promosso al livello di esperienza 3 (da 0 a 100)." - tl3_requires_posts_read: "Percentuale di messaggi creati negli ultimi 100 giorni che un utente deve leggere per essere promosso al livello di esperienza 3 (da 0 a 100)." tl3_requires_topics_viewed_all_time: "Il numero minimo di argomenti che un utente deve aver letto per poter accedere al livello di esperienza 3." tl3_requires_posts_read_all_time: "Il numero minimo di messaggi che un utente deve aver letto per poter accedere al livello di esperienza 3." - tl3_requires_max_flagged: "L'utente non deve aver ricevuto più di x segnalazioni sui messaggi da x diversi utenti negli ultimi 100 giorni, per poter essere promosso al livello di esperienza 3, dove x è il valore di questa impostazione (0 o maggiore)." tl3_promotion_min_duration: "Per quanti giorni al minimo mantenere la promozione al livello di esperienza 3 prima che un utente venga degradato al livello di esperienza 2." - tl3_requires_likes_given: "Il minimo numero di Mi piace che devono essere dati negli ultimi 100 giorni per essere promossi al livello di esperienza 3." - tl3_requires_likes_received: "Il minimo numero di Mi piace che devono essere ricevuti negli ultimi 100 giorni per essere promossi al livello di esperienza 3." tl3_links_no_follow: "Non rimuovere rel=nofollow dai collegamenti pubblicati da utenti con livello di esperienza 3." min_trust_to_create_topic: "Livello minimo richiesto per creare un nuovo argomento." min_trust_to_edit_wiki_post: "Livello minimo richiesto per modificare un argomento segnato come wiki." @@ -837,6 +840,7 @@ it: title_max_word_length: "La lunghezza massima di una parola, in caratteri, nel titolo di un argomento." title_min_entropy: "Minima entropia (caratteri unici) richiesti come titolo di un argomento." body_min_entropy: "Minima entropia (caratteri unici) richiesti come corpo di un messaggio." + allow_uppercase_posts: "Permetti l'uso di tutti caratteri maiuscoli nel titolo di argomento o nel corpo di un messaggio. " title_fancy_entities: "Converti caratteri ASCII comuni in HTML nei titoli dell'argomento, tipo SmartyPants http://daringfireball.net/projects/smartypants/" min_title_similar_length: "Lunghezza minima di un titolo che attiva il controllo su argomenti simili." min_body_similar_length: "Lunghezza minima del corpo di un messaggio che attiva il controllo su argomenti simili." @@ -847,9 +851,9 @@ it: authorized_extensions: "Una lista di estensioni dei file che è permesso caricare (usa '*' per permettere tutti i tipi di file) " max_similar_results: "Quanti argomenti simili mostrare sopra l'editor quando si scrive un nuovo argomento. Il paragone viene fatto sul titolo e sul corpo." title_prettify: "Evita refusi ed errori comuni nei titoli, incluso il testo tutto maiuscolo, il primo carattere minuscolo, troppi caratteri ! e ?, puntini aggiuntivi alla fine della parola ecc." - topic_views_heat_low: "Dopo tale numero di visualizzazioni, il campo visualizzazioni è evidenziato leggermente." - topic_views_heat_medium: "Dopo tale numero di visualizzazioni, il campo visualizzazioni è evidenziato mediamente." - topic_views_heat_high: "Dopo tale numero di visualizzazioni, il campo visualizzazioni è evidenziato fortemente." + topic_views_heat_low: "Dopo tale numero di visualizzazioni, il campo visite viene leggermente evidenziato." + topic_views_heat_medium: "Dopo tale numero di visualizzazioni, il campo visite viene mediamente evidenziato." + topic_views_heat_high: "Dopo tale numero di visualizzazioni, il campo visite viene fortemente evidenziato." cold_age_days_low: "Dopo tale numero di giorni di conversazione, la data di ultima attività viene leggermente oscurata." cold_age_days_medium: "Dopo tale numero di giorni di conversazione, la data di ultima attività viene mediamente oscurata." cold_age_days_high: "Dopo tale numero di giorni di conversazione, la data di ultima attività viene fortemente oscurata." @@ -866,7 +870,7 @@ it: white_listed_spam_host_domains: "Una lista di domini esclusi dal controllo antispam. Ai nuovi utenti non verrà mai impedito di creare messaggi con collegamenti a tali domini." staff_like_weight: "Peso extra attribuito ai \"mi piace\" dati dallo staff." levenshtein_distance_spammer_emails: "Quanti caratteri di differenza faranno comunque scattare una corrispondenza approssimativa nell'analisi delle email di spam. " - max_new_accounts_per_registration_ip: "Se vi sono già (n) account con livello di esperienza 0 da questo IP (e nessuno è membro dello staff o TL2 o superiore), non accettare nuove registrazioni utente da questo IP." + max_new_accounts_per_registration_ip: "Se vi sono già (n) account con livello di esperienza 0 da questo IP (e nessuno è membro dello staff o TL2 o superiore), non accettare nuove iscrizioni utente da questo IP." num_flaggers_to_close_topic: "Il numero minimo di segnalatori univoci richiesto affinché un argomento venga messo in pausa fino all'intervento di un moderatore" num_flags_to_close_topic: "Il numero minimo di segnalazioni attive richiesto affinché un argomento venga messo in pausa fino all'intervento di un moderatore" reply_by_email_enabled: "Abilita la possibilità di rispondere ai messaggi tramite email." @@ -880,7 +884,7 @@ it: pop3_polling_host: "L'host a cui collegarsi per ricevere email via POP3." pop3_polling_username: "Il nome utente dell'account POP3 per la ricezione di email." pop3_polling_password: "La password dell'account POP3 per la ricezione di email." - log_mail_processing_failures: "Traccia all'indirizzo http://yoursitename.com/logs tutti i fallimenti di processamento delle email" + log_mail_processing_failures: "Traccia tutti i fallimenti di lavorazione delle email all'indirizzo http://tuosito.com/logs " email_in: "Permetti agli utenti di pubblicare nuovi argomenti per email (richiede il pop3 polling). Configura gli indirizzi nella scheda \"Impostazioni\" di ciascuna categoria." email_in_min_trust: "Livello di esperienza minimo necessario affinché un utente possa pubblicare nuovi argomenti via email." email_prefix: "La [etichetta] utilizzata nell'oggetto delle email. Se non impostata sarà 'titolo'." @@ -893,7 +897,7 @@ it: allow_uploaded_avatars: "Permetti agli utenti di caricare immagini di profilo personalizzate." allow_animated_avatars: "Permetti agli utenti di utilizzare gif animate come immagini di profilo. ATTENZIONE: lanciare il comando rake \"avatars:refresh\" dopo aver cambiato questa impostazione." allow_animated_thumbnails: "Genera miniature animate delle gif animate." - default_avatars: "URL degli avatar che verranno utilizzati come predefiniti per tutti i nuovi utenti, fintanto che non li cambieranno esplicitamente." + default_avatars: "URL degli avatar che verranno utilizzati come predefiniti per i nuovi utenti, fintanto che non li cambieranno esplicitamente." automatically_download_gravatars: "Scarica i Gravatars per gli utenti quando viene creato l'account o quando viene modificata l'email" digest_topics: "Numero massimo di argomenti da mostrare nel riassunto email." allow_profile_backgrounds: "Permetti agli utenti di caricare immagini di sfondo per il profilo." @@ -910,6 +914,10 @@ it: notify_about_flags_after: "Se ci sono segnalazioni che non sono state revisionate dopo un tale numero di ore, invia un'email al contact_email. Imposta a 0 per disattivare." show_create_topics_notice: "Se il sito ha meno di 5 argomenti pubblici, mostra un avviso chiedendo agli amministratori di creare qualche argomento." enable_emoji: "Attiva gli emoji" + default_other_disable_jump_reply: "Per default non saltare al messaggio dell'utente dopo la sua risposta." + default_categories_watching: "Elenco di categorie osservate per default." + default_categories_tracking: "Elenco di categorie seguite per default." + default_categories_muted: "Elenco di categorie silenziate per default." errors: invalid_email: "Indirizzo email non valido." invalid_username: "Non c'è alcun utente con quel nome." @@ -939,11 +947,6 @@ it: category: 'Categorie' topic: 'Risultati' user: 'Utenti' - sso: - not_found: "Impossibile cercare o creare l'account, contatta l'amministratore del sito" - account_not_approved: "L'account è in attesa di approvazione, riceverai una notifica per email una volta approvato" - unknown_error: "Errore nell'aggiornamento delle informazioni, contatta l'amministratore del sito" - timeout_expired: "Il tempo di autenticazione di questo account è scaduto, prova ad autenticarti nuovamente" original_poster: "Autore Iniziale" most_posts: "Maggioranza Messaggi" most_recent_poster: "Autore Più Recente" @@ -953,6 +956,7 @@ it: not_seen_in_a_month: "Bentornato! Non ti si vede da un po'. Questi sono gli argomenti più popolari da quando sei stato via." change_owner: post_revision_text: "Proprietà trasferita da %{old_user} a %{new_user}" + deleted_user: "un utente eliminato" topic_statuses: archived_enabled: "Questo argomento è stato archiviato. È congelato e non può più essere modificato." archived_disabled: "Questo argomento non è più archiviato. Non è più congelato e può essere modificato." @@ -987,7 +991,7 @@ it: login: not_approved: "Il tuo account non è ancora stato approvato. Verrai avvertito via mail quando potrai collegarti." incorrect_username_email_or_password: "Nome utente, email o password errati" - wait_approval: "Grazie per esserti registrato. Ti avvertiremo quando il tuo account sarà approvato." + wait_approval: "Grazie per esserti iscritto. Ti avvertiremo quando il tuo account sarà approvato." active: "Il tuo account è attivo e pronto all'uso." activate_email: "

    Ci siamo quasi! Abbiamo mandato una email di attivazione a %{email}. Per favore segui le istruzioni contenute nell'email per attivare il tuo account.

    Se l'email non ti arriva, controlla la tua cartella spam o prova a collegarti ancora per inviare un'altra email di attivazione.

    " not_activated: "Non puoi ancora collegarti. Ti abbiamo mandato un'email di attivazione. Per favore segui le istruzioni contenute nell'email per attivare il tuo account." @@ -999,6 +1003,7 @@ it: omniauth_error_unknown: "Qualcosa è andato storto durante il collegamento, per favore riprova." new_registrations_disabled: "Non sono permesse nuove registrazioni al momento." password_too_long: "Le password sono limitate a 200 caratteri." + reserved_username: "Questo utente non ha il permesso." missing_user_field: "Non hai inserito tutti i campi utente" close_window: "L'autenticazione è completa. Chiudi questa finestra per continuare." user: @@ -1012,6 +1017,10 @@ it: email: not_allowed: "non è permesso da quel fornitore di email. Per favore usa un altro indirizzo email." blocked: "non è permesso." + flags_reminder: + subject_template: + one: "1 segnalazione in attesa di essere revisionata" + other: "%{count} segnalazioni in attesa di essere revisionate" invite_mailer: subject_template: "%{invitee_name} ti ha invitato a '%{topic_title}' su %{site_domain_name}" text_body_template: "%{invitee_name} ti invita ad una discussione\n\n> **%{topic_title}**\n>\n> %{topic_excerpt}\n\nsu\n\n> %{site_title} -- %{site_description}\n\nSe sei interessato, clicca il collegamento qui sotto:\n\n%{invite_link}\n\nL'invito è da parte di un utente affidabile, perciò puoi rispondere alla discussione immediatamente. \n" @@ -1026,15 +1035,6 @@ it: subject_template: "[%{site_name}] Nuova versione di Discourse, aggiornamento disponibile" new_version_mailer_with_notes: subject_template: "[%{site_name}] aggiornamento disponibile" - flags_reminder: - flags_were_submitted: - one: "Queste segnalazioni sono state inviate oltre un'ora fa." - other: "Queste segnalazioni sono state inviate oltre %{count} ore fa." - please_review: "Per favore, revisionale." - post_number: "messaggio" - subject_template: - one: "1 segnalazione in attesa di essere revisionata" - other: "%{count} segnalazioni in attesa di essere revisionate" flag_reasons: off_topic: "Il tuo messaggio è stato segnalato come **fuori tema**: la comunità pensa non riguardi l'argomento, come attualmente definito dal titolo e dal contenuto del primo messaggio." inappropriate: "Il tuo messaggio è stato segnalato come **inappropriato**: la comunità lo ritiene offensivo, ingiurioso o una violazione delle [linee guida della comunità](/guidelines)." @@ -1049,8 +1049,10 @@ it: system_messages: post_hidden: subject_template: "Messaggio nascosto a causa di segnalazioni dalla comunità" + text_body_template: "Salve,\n\nquesto è un messaggio automatico da parte di %{site_name} per informarti che il tuo messaggio è stato nascosto.\n\n%{base_url}%{url}\n\n%{flag_reason}\n\nVari membri della comunità hanno segnalato il messaggio prima che venisse nascosto, quindi per favore pensa come modificarlo alla luce di queste osservazioni. **Puoi modificare il messaggio dopo %{edit_delay} minuti, e verrà automaticamente ripubblicato.** \n\nTuttavia, se il messaggio dovesse venire nascosto dalla comunità una seconda volta, rimarrà nascosto fino a che un membro dello staff se ne occuperà – e saranno possibili ulteriori sanzioni, compresa la sospensione del tuo account.\n\nPer ulteriori informazioni, puoi far riferimento alle nostre [community guidelines](%{base_url}/guidelines).\n" welcome_user: subject_template: "Benvenuto su %{site_name}!" + text_body_template: "Grazie per esserti unito a %{site_name}, e benvenuto!\n\n%{new_user_tips} \n\nNoi crediamo in un [comportamento comunitario civile](%{base_url}/guidelines), sempre. Buona permanenza!\n\n(Se desideri comunicare con [i membri dello staff](%{base_url}/about) come nuovo utente, rispondi semplicemente a questo messaggio.)\n" welcome_invite: subject_template: "Benvenuto su %{site_name}!" backup_succeeded: @@ -1087,45 +1089,33 @@ it: subject_template: "Esportazione dati completa" csv_export_failed: subject_template: "Esportazione dati fallita" - email_reject_trust_level: - text_body_template: | - Ci dispiace, ma il tuo messaggio email per %{destination} (con il titolo %{former_title}) non è stato processato. - - Il tuo utente non ha il livello di esperienza richiesto per inviare nuovi argomenti a questo indirizzo email. Se credi che ciò sia un errore, contatta un membro dello staff. + email_reject_no_account: + subject_template: "[%{site_name}] Problema relativo all'email -- Account Sconosciuto" + email_reject_empty: + subject_template: "[%{site_name}] Problema relativo all'email -- Nessun Contenuto" + email_reject_parsing: + subject_template: "[%{site_name}] Problema relativo all'email -- Contenuto non riconosciuto" + email_reject_invalid_access: + subject_template: "[%{site_name}] Problema relativo all'email -- Accesso non valido" + email_reject_reply_key: + subject_template: "[%{site_name}] Problema relativo all'email -- Chiave di risposta sconosciuta" email_reject_topic_not_found: subject_template: "[%{site_name}] Problema relativo all'email -- Argomento Non Trovato" + email_reject_topic_closed: + subject_template: "[%{site_name}] Problema relativo all'email -- Argomento Chiuso" + email_reject_auto_generated: + subject_template: "[%{site_name}] Problema relativo all'email -- Risposta Autogenerata" + email_error_notification: + subject_template: "[%{site_name}] Problema relativo all'email -- Errore di autenticazione POP" too_many_spam_flags: subject_template: "Nuovo account bloccato" text_body_template: "Ciao, \n\nil presente è un messaggio automatico da %{site_name} per informarti che i tuoi messaggi sono stati automaticamente nascosti perché segnalati dalla comunità. \n\nCome misura precauzionale, il tuo nuovo account non può creare altre risposte o argomenti finché il tuo account non verrà revisionato da un membro dello staff. \n\nPer ulteriori informazioni, ti rimandiamo alle [Linee guida della comunità](%{base_url}/guidelines).\n" blocked_by_staff: subject_template: "Account bloccato" - text_body_template: | - Ciao, - - questo è un messaggio automatico da %{site_name} per informarti che il tuo account è stato bloccato da un membro dello staff. - - Per maggiori dettagli, fai riferimento alle nostre [linee guida della community](%{base_url}/guidelines). user_automatically_blocked: subject_template: "Nuovo utente %{username} bloccato a causa delle segnalazioni" - text_body_template: | - Questo è un messaggio automatico. - - Il nuovo utente [%{username}](%{base_url}%{user_url}) è stato automaticamente bloccato perché più utenti hanno contrassegnato i messaggi di %{username}. - - Per favore [controlla le segnalazioni](%{base_url}/admin/flags). Se %{username} è stato bloccato per errore, clicca sul tasto di sblocco nella [pagina di amministrazione di questo utente](%{base_url}%{user_url}). - - La soglia può essere modificata tramite l'impostazione del sito `block_new_user`. spam_post_blocked: subject_template: "Il messaggi del nuovo utente %{username} sono stati bloccati a causa dell'invio di ripetuti collegamenti." - text_body_template: |+ - Questo è un messaggio automatico. - - Il nuovo utente [%{username}](%{base_url}%{user_url}) ha creato diversi messaggi con collegamenti a %{domains}, ma tali messaggi sono stati bloccati per evitare spam. L'utente è ancora abilitato alla creazione di messaggi ma senza collegamenti verso %{domains}. - - Per favore [controlla questo utente](%{base_url}%{user_url}). - - Questa soglia può essere modificata tramite l'impostazione `newuser_spam_host_threshold` e `white_listed_spam_host_domains` del sito. - unblocked: subject_template: "Account sbloccato" text_body_template: | @@ -1138,7 +1128,7 @@ it: subject_template: one: "1 utente in attesa di approvazione" other: "%{count} utenti in attesa di approvazione" - text_body_template: "Ci sono nuove iscrizioni che vanno approvate (o rifiutate) prima che possano accedere a questo forum. \n\n[Per favore valutale nella sezione di amministrazione](%{base_url}/admin/users/list/pending).\n" + text_body_template: "Ci sono nuove iscrizioni in attesa di essere approvate (o rifiutate) prima che possano accedere a questo forum. \n\n[Per favore valutale nella sezione di amministrazione](%{base_url}/admin/users/list/pending).\n" download_remote_images_disabled: subject_template: "Lo scaricamento delle immagini remote è disabilitato" text_body_template: "L'impostazione `download_remote_images_to_local` è stata disabilitata perché è stato raggiunto il limite di spazio su disco definito in `download_remote_images_threshold`." @@ -1149,56 +1139,47 @@ it: unsubscribe: title: "Annulla iscrizione" description: "Non vuoi ricevere queste email? Nessun problema! Clicca qui sotto per annullare l'iscrizione:" - reply_by_email: "Per intervenire, rispondi a questa email o visita %{base_url}%{url}." - visit_link_to_respond: "Per rispondere, visita %{base_url}%{url}" posted_by: "Pubblicato da %{username} il %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} ti invita al partecipare al messaggio '%{topic_title}'" - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} ti invita a partecipare all'argomento '%{topic_title}'" user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} + text_body_template: "%{header_instructions} \n\n%{message}\n\n%{context}\n\n---\n%{respond_instructions}\n" + user_replied_pm: + subject_template: "[%{site_name}] [PM] %{topic_title}" + text_body_template: "%{header_instructions} \n\n%{message}\n\n%{context}\n\n---\n%{respond_instructions}\n" user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} + text_body_template: "%{header_instructions} \n\n%{message}\n\n%{context}\n\n---\n%{respond_instructions}\n" + user_linked: + subject_template: "[%{site_name}] %{topic_title} " + text_body_template: "%{header_instructions}\n \n%{message}\n\n%{context}\n\n---\n%{respond_instructions}\n" user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} + text_body_template: "%{header_instructions}\n\n%{message}\n \n%{context}\n\n---\n%{respond_instructions}\n" + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: "%{header_instructions}\n\n%{message}\n\n%{context}\n \n---\n%{respond_instructions}\n" user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} + text_body_template: "%{header_instructions}\n\n%{message}\n \n%{context}\n\n---\n%{respond_instructions}\n" user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} + --- + %{respond_instructions} + user_posted_pm_staged: + subject_template: "%{optional_re}%{topic_title}" + text_body_template: |2 + + %{message} + --- %{respond_instructions} digest: @@ -1234,16 +1215,11 @@ it: Fai clic sul seguente collegamento per scegliere una password per il tuo nuovo account: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Conferma il tuo nuovo indirizzo email" - text_body_template: | - Conferma il tuo nuovo indirizzo email per %{site_name} cliccando sul seguente collegamento: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "Sei stato ammesso su %{site_name}!" - text_body_template: "Benvenuto su %{site_name}! \n\nUn membro dello staff ha approvato il tuo account su %{site_name}. \n\nClicca sul seguente collegamento per confermare e attivare il tuo nuovo account:\n%{base_url}/users/activate-account/%{email_token} \n\nSe il collegamento qui sopra non è cliccabile, prova a copiarlo e incollarlo nella barra degli indirizzi del tuo browser. \n\n%{new_user_tips}\n\nNoi crediamo fermamente in un [comportamento comunitario civile](%{base_url}/guidelines) sempre.\n\nBuona permanenza!\n\n(Se hai bisogno di comunicare privatamente con i [membri dello staff](%{base_url}/about) come nuovo utente, rispondi semplicemente a questo messaggio privato.)\n" + text_body_template: "Benvenuto su %{site_name}! \n\nUn membro dello staff ha approvato il tuo account su %{site_name}. \n\nClicca sul seguente collegamento per confermare e attivare il tuo nuovo account:\n%{base_url}/users/activate-account/%{email_token} \n\nSe il collegamento qui sopra non è cliccabile, prova a copiarlo e incollarlo nella barra degli indirizzi del tuo browser. \n\n%{new_user_tips}\n\nNoi crediamo in un [comportamento comunitario civile](%{base_url}/guidelines), sempre.\n\nBuona permanenza!\n\nps: se vuoi comunicare privatamente con i [membri dello staff](%{base_url}/about) come nuovo utente, rispondi semplicemente a questo messaggio.\n" signup: + subject_template: "[%{site_name}] Conferma il tuo nuovo account" text_body_template: | Benvenuto su %{site_name}! @@ -1271,6 +1247,7 @@ it: unauthorized: "Spiacenti, il file che stai cercando di caricare non è autorizzato (estensioni autorizzate: %{authorized_extensions})." pasted_image_filename: "Immagine incollata" store_failure: "Caricamento n°%{upload_id} fallito per l'utente n°%{user_id}." + file_missing: "Spiacenti, devi fornire un file da caricare." attachments: too_large: "Spiacenti, ma il file che stai cercando di caricare è troppo grande (la dimensione massima è %{max_size_kb}KB)." images: @@ -1316,3 +1293,8 @@ it: error: "Errore!" email_input: "Email Amministratore" submit_button: "Invia Email" + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.ja.yml b/config/locales/server.ja.yml index d786fa759ce..81ce45a79be 100644 --- a/config/locales/server.ja.yml +++ b/config/locales/server.ja.yml @@ -10,18 +10,21 @@ ja: short_date_no_year: "MMM D" short_date: "MMM D, YYYY" long_date: "MMMM D, YYYY h:mma" + date: + month_names: [null, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月] title: "Discourse" topics: "トピック" posts: "投稿" loading: "読み込み中" powered_by_html: 'Powered by Discourse, best viewed with JavaScript enabled' log_in: "ログイン" - via: "%{username} via %{site_name}" - is_reserved: "は予約されています" purge_reason: "アクティブでないアカウントは放棄されたとして削除されました" disable_remote_images_download_reason: "ディスク容量が不足しているため、リモートでの画像ダウンロードは無効になっています。" anonymous: "匿名" - errors: + emails: + incoming: + default_subject: "%{email}からメール" + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "は、最大文字数(%{max}文字)を超えています。(入力したのは%{length}文字 ) " @@ -37,8 +40,10 @@ ja: exclusion: は予約されています greater_than: は%{count}より大きい値にしてください greater_than_or_equal_to: は%{count}以上の値にしてください + has_already_been_used: "は既に使用されています" inclusion: は一覧にありません invalid: は不正な値です + is_invalid: "は不正です。もう少し説明を追加してください" less_than: は%{count}より小さい値にしてください less_than_or_equal_to: は%{count}以下の値にしてください not_a_number: は数値で入力してください @@ -84,26 +89,6 @@ ja: in_reply_to: "▶ %{username}" replies: other: "%{count} 通の返信" - too_many_mentions: - zero: "申し訳ありませんが、この投稿において他のユーザをタグ付けできません。" - one: "申し訳ありませんが、この投稿においてあと1人しかタグ付けできません。" - other: "申し訳ありませんが、このポストにおいてあと%{count}人しかタグ付けできません。" - too_many_mentions_newuser: - zero: "申し訳ありませんが、新規ユーザはこのポストにおいて他のユーザをタグ付けできません。" - one: "申し訳ありませんが、新規ユーザはこのポストにおいてあと1人しかタグ付けできません。" - other: "申し訳ありませんが、新規ユーザはこのポストにおいてあと%{count}人しかタグ付けできません。" - too_many_images: - zero: "申し訳ありませんが、新規ユーザはこのポストに画像をアップロードできません。" - one: "申し訳ありませんが、新規ユーザはこのポストに画像を1つしかアップロードできません。" - other: "申し訳ありませんが、新規ユーザはこのポストに画像を%{count}個しかアップロードできません。" - too_many_attachments: - zero: "申し訳ありませんが、新規ユーザはこのポストにファイルを添付できません。" - one: "申し訳ありませんが、新規ユーザはこのポストにファイルを1つしか添付できません。" - other: "申し訳ありませんが、新規ユーザはこのポストにファイルを%{count}個しか添付できません。" - too_many_links: - zero: "申し訳ありませんが、新規ユーザはこのポストにリンクを貼れません。" - one: "申し訳ありませんが、新規ユーザはこのポストにリンクを1つしか貼れません。" - other: "申し訳ありませんが、新規ユーザはこのポストにリンクを%{count}個しか貼れません。" spamming_host: "申し訳ありませんが、このホストへのリンクを貼ることはできません。" user_is_suspended: "サスペンド中のユーザーは投稿ができません。" topic_not_found: "何かがおかしいです。トピックが終了したか、閲覧してる間に削除された可能性があります" @@ -190,11 +175,8 @@ ja: post: raw: "本文" user_profile: - bio_raw: "About Me" + bio_raw: "自己紹介" errors: - messages: - is_invalid: "は不正です。もう少し説明を追加してください" - has_already_been_used: "は既に使用中です" models: topic: attributes: @@ -215,6 +197,7 @@ ja: attributes: hex: invalid: "は有効なカラーではありません" + <<: *errors user_profile: no_info_me: "
    プロフィールの自己紹介フィールドが空欄のようです。自己紹介をしてみませんか?
    " no_info_other: "
    %{name} は、まだプロフィールの自己紹介フィールドに何も書いていません
    " @@ -229,13 +212,10 @@ ja: title: "ラウンジへようこそ" category: topic_prefix: "%{category} カテゴリの定義" - replace_paragraph: "[この最初のパラグラフを、本カテゴリの簡単な紹介文に置き換えてください。このガイダンスはカテゴリ選択エリアに表示されるため、パラグラフは200文字以内にしてください。]" - post_template: "%{replace_paragraph}\n\nこれ以降のパラグラフに、カテゴリのガイドライン等を書いてください。\n\nいくつかのヒント:\n\n- このカテゴリは何か? どのようなトピックをこのカテゴリに入れるべきか?\n\n- 既に存在するカテゴリとの違いは何か?\n\n- このカテゴリはなぜ必要か?\n\n- 他のカテゴリとの統合や、複数カテゴリへの分割をするべきか?\n" errors: uncategorized_parent: "未分類カテゴリは親カテゴリに設定出来ません。" self_parent: "自分自身がサブカテゴリの親になることはできません" depth: "他のサブカテゴリの下にサブカテゴリを作成することはできません" - email_in_already_exist: "受信メールアドレス '%{email_in}' は '%{category_name}' カテゴリですでに使用されています。" cannot_delete: uncategorized: "未分類カテゴリは削除出来ません" has_subcategories: "サブカテゴリを持っているため、このカテゴリを削除できません。" @@ -247,15 +227,8 @@ ja: title: "新規ユーザ" basic: title: "ベーシックユーザ" - regular: - title: "メンバー" - leader: - title: "レギュラー" - elder: - title: "リーダー" change_failed_explanation: "%{user_name} を '%{new_trust_level}' に格下げしようとしましたが、既にトラストレベルが '%{current_trust_level}' です。%{user_name} は '%{current_trust_level}' のままになります - もしユーザーを降格させたい場合は、トラストレベルをロックしてください" rate_limiter: - slow_down: "多すぎるアクションが実行されました。時間を置いてから試してください" too_many_requests: "このアクションを一日の間に実施可能な回数が決まっています。%{time_left}待ってから再度試してください。" hours: other: "%{count} 時間" @@ -349,16 +322,11 @@ ja: description: 'この投稿は、誹謗中傷、恫喝、名誉毀損、わいせつ、犯罪行為など他人を不快にさせる内容を含んでいる。' long_form: '不適切フラグをたてる' notify_user: - title: 'メッセージ @{{username}}' - description: 'この投稿やトピックを書いた人に、直接メッセージを送る。(フラグを付けません)' long_form: 'メッセージが送られたユーザ' email_title: '「%{title}」にの投稿' email_body: "%{link}\n\n%{message}" notify_moderators: title: "その他" - description: 'このポストは、記載されていない別の理由でモデレータの注意が必要です' - long_form: 'モデレータへの注意としてフラグを立てる' - email_title: '"%{title}" のポストに関する管理人の確認が必要とする' email_body: "%{link}\n\n%{message}" bookmark: title: 'ブックマーク' @@ -383,7 +351,6 @@ ja: long_form: '不適切フラグをたてる' notify_moderators: title: "その他" - description: 'この投稿やトピックは不適切な可能性があるため、管理人による確認を必要とする。' long_form: 'モデレータへの注意としてフラグを立てる' email_title: 'トピック"%{title}" は不適切な可能性があるため、管理人による確認を必要とする。' email_body: "%{link}\n\n%{message}" @@ -569,37 +536,6 @@ ja: consumer_email_warning: "サイトはメール送信に Gmail (または他のカスタムメールサービス) を利用するように設定されています。Gmail で送信可能なメール数には制限があります。メールを確実に送信するために mandrill.com などのメールサービスプロバイダーの利用を検討してください。" site_contact_username_warning: "重要な自動メッセージを送信するフレンドリースタッフユーザーアカウントの名前を入力してください。サイト設定 のsite_contact_username を更新してください。" notification_email_warning: "通知用メールがあなたのドメインで有効なメールアドレスから送信されていません。メール配信が不安定になり、信頼性が低くなります。\nサイトの設定で更新してください" - content_types: - education_new_reply: - title: "新規ユーザ支援: 初めての回答" - description: "新規ユーザが回答の入力を開始した際に自動的にポップアップするガイダンスの内容 (最初の2回のみ表示)。" - education_new_topic: - title: "新規ユーザ支援: 初めてのポスト" - description: "新規ユーザが新規トピックの作成を行った際に自動的にポップアップするガイダンスに内容 (最初の2回のみ表示)。" - usage_tips: - title: "新規ユーザガイダンス" - description: "新規ユーザのための重要な情報とガイダンス" - welcome_user: - title: "ウェルカムメッセージ: 新規ユーザ" - description: "サインアップ時にすべての新規ユーザに自動送信されるメッセージ。" - welcome_invite: - title: "ウェルカムメッセージ: 招待ユーザ" - description: "他のユーザからの招待を受け入れたときにすべての新しい招待ユーザに自動送信されるメッセージ" - login_required_welcome_message: - title: "ウェルカムメッセージ: 要ログイン" - description: "'login required' 設定有効時に、ユーザに対してログインを促すメッセージの内容。" - login_required: - title: "ホームページ: 要ログイン" - description: "要ログイン設定の際に、未ログインユーザに対して表示されるメッセージの内容。" - head: - title: "HTML head" - description: " タグの中に挿入されるHTML" - top: - title: "ページトップ" - description: "全ページのトップに追加される HTML (ヘッダとナビゲーション/トピックタイトルの間に表示されます)" - bottom: - title: "ページボトム" - description: "タグの前に挿入されるHTML" site_settings: censored_words: "自動的に ■■■■ で置換されます" delete_old_hidden_posts: "30日以上非表示になっているポストを自動で削除します" @@ -614,7 +550,6 @@ ja: min_private_message_title_length: "プライベートメッセージのタイトルとして許容する最小の文字数" min_search_term_length: "検索ワードとして有効にする最小の文字数" allow_uncategorized_topics: "カテゴリなしのトピック作成を許可するか。警告:未分類のトピックがある場合は、これをオフにする前に、再分類する必要があります。" - uncategorized_description: "未分類カテゴリについての説明。存在しない場合は空白のままにします" allow_duplicate_topic_titles: "トピックタイトルの重複を許可" unique_posts_mins: "同じ内容のポストを再投稿可能にする時間 (分)" educate_until_posts: "最初(または複数)の投稿でタイピングを開始したら、ポップアップでガイダンスを表示させるか" @@ -627,7 +562,6 @@ ja: download_remote_images_to_local: "リモート画像をダウンロードしてローカル画像に変換する。破損した画像を防ぎます" download_remote_images_threshold: "リモート画像をダウンロードするために必要なディスクスペースの最低残容量 (パーセント)" disabled_image_download_domains: "これらのドメインからは、リモート画像のダウンロードを行いません。パイプ区切りのリスト" - ninja_edit_window: "投稿から(N)秒間は、ポストの新しいバージョンを作成しない" post_edit_time_limit: "作者は投稿から(N)分間、編集と削除が可能。0を設定すると無期限です" edit_history_visible_to_public: "すべてのユーザに対してポストの編集履歴を許可する。無効の場合はスタッフメンバーのみが確認できます" delete_removed_posts_after: "投稿は作者が削除してから(N)時間後に削除されます。0を設定すると、すぐに削除されます" @@ -656,7 +590,6 @@ ja: summary_likes_required: "'トピックサマリー'が有効になるために必要な最小「いいね!」数" summary_percent_filter: "ユーザが'トピックサマリー'をクリックしたとき, 上位何パーセントのポストを表示するか" summary_max_results: "'トピックサマリー'として返却される最大ポスト数" - enable_private_messages: "トラストレベル1のユーザーにプライベートメッセージの作成と返信を許可する" enable_long_polling: "通知用のメッセージバスによるロングポーリングの利用を許可する" long_polling_base_url: "ロングポーリングのベースURL(CDNが動的コンテンツを配信している場合、これをoriginに指定してください) eg: http://origin.site.com" long_polling_interval: "ユーザに送信するデータが存在しないとき、サーバが待機する時間(ログインユーザーのみ)" @@ -696,7 +629,6 @@ ja: suppress_reply_directly_above: "ポストに回答が1つしかない場合、ポストのin-reply-toを表示しない" suppress_reply_when_quoting: "ポストが引用返信だった場合、ポストのin-reply-toを表示しない" max_reply_history: "回答のin-reply-toを展開する最大数" - experimental_reply_expansion: "回答を展開するときに、その間にある回答を非表示にする(実験)" topics_per_period_in_top_summary: "デフォルトのトピックサマリに表示されるトップトピックの数" topics_per_period_in_top_page: "'もっと見る'を展開したときに表示するトップトピックの数" redirect_users_to_top_page: "新規ユーザーと長く不在のユーザーをトップページに自動的にリダイレクトさせる" @@ -791,16 +723,9 @@ ja: tl2_requires_likes_received: "トラストレベル2に昇格するためにもらわなければならない「いいね!」の数" tl2_requires_likes_given: "トラストレベル2に昇格するためにしなければならない「いいね!」の数" tl2_requires_topic_reply_count: "トラストレベル2に昇格するために回答しなければいけないトピックの数" - tl3_requires_days_visited: "トラストレベル3に昇格するために必要な、最後の100日の間にサイトを訪れた日数 (0-100)" - tl3_requires_topics_replied_to: "トラストレベル3に昇格するために必要な最後の100日の間に返信したトピックの数(0 or higher)" - tl3_requires_topics_viewed: "トラストレベル3に昇格するために必要な、最後の100日の間に作成されたトピックを閲覧した割合(0 to 100)" - tl3_requires_posts_read: "トラストレベル3に昇格するために必要な、最後の100日の間に作成されたポストを閲覧した割合(0 to 100)" tl3_requires_topics_viewed_all_time: "トラストレベル3に昇格するために必要な、トピックを閲覧した合計" tl3_requires_posts_read_all_time: "トラストレベル3に昇格するために必要なユーザが閲覧したポストの合計" - tl3_requires_max_flagged: "トラストレベル3に昇格するためには、 最後の100日の間に投稿がx個以上x人の違うユーザにフラグを立てられてはいけない。xが設定値です(0 or higher)" tl3_promotion_min_duration: "トラストレベル3に昇格したユーザが、トラストレベル2に降格しない日数" - tl3_requires_likes_given: "トラストレベル3に昇格するために、最後の100日の間にしなければならない「いいね!」の数" - tl3_requires_likes_received: "トラストレベル3に昇格するために、最後の100日の間にもらわなければならない「いいね!」の数" tl3_links_no_follow: "トラストレベル3のユーザのポスト内のrel=nofolowを削除しない" min_trust_to_create_topic: "新規にトピックを作成するために必要な最低トラストレベル。" min_trust_to_edit_wiki_post: "ポストをwikiにするために必要な最低トラストレベル" @@ -888,7 +813,6 @@ ja: automatically_download_gravatars: "アカウントの生成時、メールアドレスの変更時にGravatarをダウンロード" digest_topics: "ダイジェストメールに表示されるトピックの最大数" digest_min_excerpt_length: "ダイジェストメール内の投稿の抜粋の最小文字数" - suppress_digest_email_after_days: "(n)日以上ユーザが参照していなければダイジェストメールを抑制します" disable_digest_emails: "全てのユーザのダイジェストメールを無効にする" detect_custom_avatars: "ユーザがプロフィール画像をアップロードしたか確認する" max_daily_gravatar_crawls: "Discourseがプロフィール画像の確認をgravastarに行う回数の上限" @@ -899,12 +823,10 @@ ja: anonymous_posting_min_trust_level: "匿名の投稿を行うための最小のトラストレベル" anonymous_account_duration_minutes: "匿名性を守るため、N 分毎に匿名ユーザーを作成しなおします。 例 : 600を設定すると匿名ユーザへの変更と最後の投稿から600分経過していた場合、匿名アカウントが作成されます" allow_profile_backgrounds: "プロフィール背景のアップロードを許可" - sequential_replies_threshold: "ユーザに連続回答が多すぎることをリマインドする、連続ポスト投稿のしきい値" enable_mobile_theme: "モバイル端末にモバイル向けテーマ (通常サイト用テーマにスイッチ可能) を利用する。レスポンシブなスタイルシートを使用する場合はこの設定を無効にしてください。" dominating_topic_minimum_percent: "ユーザがトピックを占拠しているとリマインドを行う、ポスト投稿支配率 " daily_performance_report: "日別のNGINXのログを解析し、Staff Onlyトピックへ詳細を投稿する" suppress_uncategorized_badge: "トピック一覧でカテゴライズされていないトピックのバッジは表示しない" - permalink_normalizations: "パーマリンクをマッチングさせる前に正規表現を適用します。例えば、/(\\/topic.*)\\?.*/\\1 は、トピックURLのクエリ文字列を取り除きます。 フォーマットは、正規表現と \\1 のようなキャプチャにアクセスする文字列です" global_notice: "緊急の内容を表示します。全ての訪問者の緊急バナーで注意を行います。隠すには空白に変更してください(HTMLが許可されています)" disable_edit_notifications: "システムユーザが'download_remote_images_to_local' を有効にした場合、編集時の通知を無効にする" full_name_required: "ユーザープロフィールのフルネームを必須にする" @@ -929,13 +851,11 @@ ja: enable_cdn_js_debugging: "全てのJSにcrossorigin権限を追加することで、/logsに適切なエラーを表示することを許可する" show_create_topics_notice: "サイトにpublicなトピックが5よりも少ない場合、トピックを作成するための通知が管理者に表示される" delete_drafts_older_than_n_days: (n) 日間経過したドラフトを削除 - vacuum_db_days: "DB領域を再利用するため、migration後にVACUUM FULL ANALYZEを実行する(0を設定すると無効化)" prevent_anons_from_downloading_files: "匿名ユーザーが添付ファイルをダウンロードするのを防止。警告: 画像ではなく、添付ファイルとして投稿された全てのファイルが対象です" slug_generation_method: "slugを生成するメソッドを選択。 'encode'はパーセントエンコードされた文字列を生成します。 'none'は、slugを無効にします" enable_emoji: "絵文字を有効にする" emoji_set: "How would you like your emoji?" enforce_square_emoji: "絵文字のアスペクト比を強制的に揃える" - approve_post_count: "新規ユーザーの投稿に承認が必要になる投稿数" approve_unless_trust_level: "トラストレベル以下のユーザーの投稿には承認が必要" notify_about_queued_posts_after: "設定した時間よりも長い間レビュー待ちの状態になっている投稿があると、メールで通知します。0を設定するとこのメールは無効化されます" errors: @@ -962,7 +882,6 @@ ja: moved_post: "%{display_username} があなたのポストを %{link} に移動しました" private_message: "%{display_username} があなたにメッセージを送信しました: %{link}" invited_to_private_message: "%{display_username} がメッセージにあなたを招待しました: %{link}" - invited_to_topic: "%{display_username} がトピックにあなたを招待しました: %{link}" invitee_accepted: "%{display_username} があなたの招待を受けました" linked: "%{display_username} は%{link}であなたをリンクしました" granted_badge: "あなたは%{link}を獲得しました" @@ -972,11 +891,6 @@ ja: category: 'カテゴリ' topic: '結果' user: 'ユーザ' - sso: - not_found: "アカウントを検索、作成することができません。サイト管理者に連絡してください" - account_not_approved: "アカウントの承認は保留され、承認されると通知メールが届きます" - unknown_error: "情報の更新中にエラーが発生しました。サイト管理者に連絡してください" - timeout_expired: "ログインがタイムアウトしました。もう一度ログインを試してください" original_poster: "Original Poster" most_posts: "Most Posts" most_recent_poster: "Most Recent Poster" @@ -1057,6 +971,9 @@ ja: ip_address: blocked: "あなたのIPアドレスからの新規登録は許可されていません" max_new_accounts_per_registration_ip: "あなたのIPアドレスからの新規登録は許可されていません(最大数に達しました)。スタッフメンバーに連絡してください" + flags_reminder: + subject_template: + other: "%{count} 個のフラグが判断待ちです" invite_mailer: subject_template: "%{invitee_name} があなたを %{site_domain_name}の'%{topic_title}'に招待しました" text_body_template: | @@ -1090,85 +1007,10 @@ ja: text_body_template: "%{site_name} へようこそ\n\nこのリンクをクリックしてパスワードを設定してください:\n%{base_url}/users/password-reset/%{email_token}\n\n(リンクの有効期限が切れていた場合は、\"パスワードを忘れたました\"を選択しメールアドレスを入力してください) \n" test_mailer: subject_template: "[%{site_name}] メール送信テスト" - text_body_template: | - This is a test email from - - [**%{base_url}**][0] - - Email deliverability is complicated. Here are a few important things you should check first: - - - Be *sure* to set the `notification email` from: address correctly in your site settings. **The domain specified in the "from" address of the emails you send is the domain your email will be validated against**. - - - Know how to view the raw source of the email in your mail client, so you can examine email headers for important clues. in Gmail, it is the "show original" option in the drop-down menu at the top right of each mail. - - - **IMPORTANT:** Does your ISP have a reverse DNS record entered to associate the domain names and IP addresses you send mail from? [Test your Reverse PTR record][2] here. If your ISP does not enter the proper reverse DNS pointer record, it's very unlikely any of your email will be delivered. - - - Is your domain's [SPF record][8] correct? [Test your SPF record][1] here. Note that TXT is the correct official record type for SPF. - - - Is your domain's [DKIM record][3] correct? This will significantly improve email deliverability. [Test your DKIM record][7] here. - - - If you run your own mail server, check to make sure the IPs of your mail server are [not on any email blacklists][4]. Also verify that it is definitely sending a fully-qualified hostname that resolves in DNS in its HELO message. If not, this will cause your email to be rejected by many mail services. - - (The *easy* way is to create a free account on [Mandrill][md] or [Mailgun][mg] or [Mailjet][mj], which have free generous free mailing plans and will be fine for small communities. You'll still need to set up the SPF and DKIM records in your DNS, though!) - - We hope you received this email deliverability test OK! - - Good luck, - - Your friends at [Discourse](http://www.discourse.org) - - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: https://www.mailjet.com/pricing new_version_mailer: subject_template: "[%{site_name}] New Discourse version, update available" - text_body_template: | - 新しいバージョンの[Discourse](http://www.discourse.org) が利用可能です。 - - あなたのバージョン: %{installed_version} - 新しいバージョン: **%{new_version}** - - You may want to: - - - See what's new in the [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - Upgrade from your browser at [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Visit [meta.discourse.org](http://meta.discourse.org) for news, discussion, and support for Discourse. new_version_mailer_with_notes: subject_template: "[%{site_name}] update available" - text_body_template: | - 新しいバージョンの[Discourse](http://www.discourse.org) が利用可能です。 - - あなたのバージョン: %{installed_version} - 新しいバージョン: **%{new_version}** - - You may want to: - - - See what's new in the [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - Upgrade from your browser at [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Visit [meta.discourse.org](http://meta.discourse.org) for news, discussion, and support for Discourse. - - ### Release notes - - %{notes} - flags_reminder: - flags_were_submitted: - other: "これらのフラグは%{count}時間以上前に作成されました" - please_review: "これを確認してください" - post_number: "投稿" - how_to_disable: ' "notify about flags after"設定でこのリマインダーを停止、頻度を変更することができます' - subject_template: - other: "%{count} 個のフラグが判断待ちです" queued_posts_reminder: subject_template: other: "[%{site_name}] %{count} 件の投稿がレビュー待ちです" @@ -1192,90 +1034,6 @@ ja: post_hidden: subject_template: "コミュニティによるフラグによりポストが非表示になりました" text_body_template: "こんにちは \n\nこれは あなたの投稿が非表示になったことを %{site_name}% からのメッセージです\n\n%{base_url}%{url}\n\n%{flag_reason}\n\n複数のコミュニティメンバーによりこのポストにフラグが立てられた結果としてポストが非表示になったことを理解し、ポスト内容を修正することを検討してください。\nポスト内容の編集は %{edit_delay}後より行うことができます。編集後、非表示状態は解除されます。\n\n編集後、非表示状態は解除されます。 ただし、再度あなたのポストがコミュニティによってフラグ立てされた場合、モデレータに通知が行われます。この結果アカウントの凍結などの処置が行われる可能性もあります。\n\n詳しいガイドラインは、 [community guidelines]を参照してください (%{base_url}/guidelines).\n" - usage_tips: - text_body_template: |+ - 初心者向けヒントをいくつかご紹介します。 - - ### スクロールするだけ - - もっと読むためには、ただスクロールするだけです。 - 新しい返信や新しいトピックが追加された場合、それらは自動的に表示されます。ページのリフレッシュは必要ありません。 - - ## ナビゲーション - - - 検索、ユーザーページ、 メニュー, *右上のアイコンボタン*. - - - トピックのタイトルを選択すると、常に”未読返信"に移動することができます。reply countまたは、投稿日を選択すると、上部、下部に移動できます。 - - - - - トピックを読んでいる間、ナビゲーションのために右下にプログレスバーを表示します。 トピックタイトルを選択すると上部に移動します。? を押すと、キーボードショートカットが表示されます - - - - ## 返信 - - - トピック全体に返信するには、トピックの一番下にある を使います - - - 特定のユーザーに返信するには、そのポストのを使います - - - 新しいトピックで返信するには、ポストのを使います。新旧のトピック両方が自動的にリンクされます - - 引用を挿入したい場合、引用したいテキストを選択し、返信ボタンを押してください。繰り返し使えます! - - - - 返信を誰かに通知する場合は、メンションを作成します。 `@`をタイプし、ユーザー名を選択してください。 - - - - 絵文字(http://www.emoji.codes/)を利用するには、`:`をタイプし名前を入力してください - - - - リンクをペーストするだけで、サマリーを生成します: - - - ## アクション - - ポスト毎にアクションボタンがあります - - - - そのポストで楽しみ、高く評価したことを伝えるため Likeボタンを押してシェアしましょう - - ポストに問題を発生した場合、個人的に伝えるか、[スタッフ](%{base_url}/about) に flagボタンで伝えることができます。また、ポストのリンクをshareし、後で読むためにbookmarkすることもできます - - ## 通知 - - あなたに返信したり、ポストを引用したり、あなたの`@username`にメンションがあると、ページの右上にすぐ数字が表示されます。通知にアクセスするために使用します。 - - - - 返信を忘れてしまう心配はありません。あなたが席を離れてる間に届いた通知はメールで通知されます。 - - ## あなたの設定 - - - 2日前よりも新しいトピックは新着と判断されます - - - 作成、返信、または長時間読むことにより、積極的に参加したトピックとして自動的に追跡します - - これらのトピックの横には、青い新着マークと、未読件数が表示されます - - - - トピックの下部にある通知コントロールにより通知を変更できます - - - - あるカテゴリに所属しているトピックを全て参照したいときなど、カテゴリ毎に通知を設定することができます - - 設定を変更するには、[設定](%{base_url}/my/preferences) を参照してください - - ## コミュニティトラスト - - 参加し、時間をかけることで、コミュニティからの信頼を獲得した完全な市民になり、ユーザーへの制限が解除されます。十分に高いトラストレベル(https://meta.discourse.org/t/what-do-user-trust-levels-do/4924)で、コミュニティを共に管理する能力を得ることが出来ます。 - welcome_user: subject_template: "%{site_name} へようこそ!" text_body_template: |2 @@ -1290,8 +1048,7 @@ ja: (もし[スタッフメンバー](%{base_url}/about) に新規ユーザーとして連絡する必要がある場合、このメッセージに返信してください) welcome_invite: subject_template: "%{site_name}へようこそ!" - text_body_template: "ようこそ%{site_name} へ!\nあなたのアカウント**%{username}** を作成して、あなたはログインしています。\n氏名の変更は [your user profile][prefs] より行ってください。\n\n次回ログインするときは、\n\n1. かならず招待をうけたメールアドレスを使ってログインしてください。\n\n2.[your user profile][prefs]でパスワードを設定して、ログインのときはそれを使用してください。\n\n%{new_user_tips} [civilized community behavior](%{base_url}/guidelines)をお守りいただき、健全なコミュニティとなるよう皆様のご協力をお願いいたします。 \n\nそれではお楽しみください! \n\n(もし個人的に [staff members](%{base_url}/about)\ - \ と連絡を取る必要がある場合、このメッセージに返信してください)\n\n[prefs]: %{user_preferences_url}\n" + text_body_template: "ようこそ%{site_name} へ!\nあなたのアカウント**%{username}** を作成して、あなたはログインしています。\n氏名の変更は [your user profile][prefs] より行ってください。\n\n次回ログインするときは、\n\n1. かならず招待をうけたメールアドレスを使ってログインしてください。\n\n2.[your user profile][prefs]でパスワードを設定して、ログインのときはそれを使用してください。\n\n%{new_user_tips} [civilized community behavior](%{base_url}/guidelines)をお守りいただき、健全なコミュニティとなるよう皆様のご協力をお願いいたします。 \n\nそれではお楽しみください! \n\n(もし個人的に [staff members](%{base_url}/about) と連絡を取る必要がある場合、このメッセージに返信してください)\n\n[prefs]: %{user_preferences_url}\n" backup_succeeded: subject_template: "バックアップは正常に完了しました" text_body_template: "バックアップが成功しました。\n [admin > backup section](%{base_url}/admin/backups) から、バックアップをダウンロードしてください" @@ -1342,18 +1099,8 @@ ja: csv_export_failed: subject_template: "データ出力失敗" text_body_template: "申し訳ありません。データ出力に失敗しました。ログを確認するかスタッフメンバーに連絡してください" - email_reject_trust_level: - subject_template: "[%{site_name}] Email issue -- 不十分なトラストレベル" - text_body_template: | - 申し訳ありません,あなたの %{destination} へのメール(titled %{former_title}) は動きませんでした - - あなたのアカウントは、このアドレスに新しいトピックを投稿するために必要なトラストレベルに達していませんでした。不明な点がある場合は、スタッフメンバーに連絡してください。 email_reject_no_account: subject_template: "[%{site_name}] Email issue -- 不明なアカウント" - text_body_template: | - 申し訳ありません,あなたの %{destination} へのメール(titled %{former_title}) は動きませんでした。 - - このメールアドレスを持つユーザーアカウントがありませんでした。違うメールアドレスから送信するか、スタッフメンバーに連絡してください。 email_reject_empty: subject_template: "[%{site_name}] Email issue -- 本文なし" email_reject_parsing: @@ -1361,28 +1108,8 @@ ja: text_body_template: "申し訳ありません,あなたの %{destination} へのメール(titled %{former_title}) は動きませんでした \nメールから回答を見つける事ができませんでした。返信はメールのトップにあることを確認してください。インライン回答を見つける事はできません。\n" email_reject_invalid_access: subject_template: "[%{site_name}] Email issue -- 不正なアクセス" - email_reject_post_error: - subject_template: "[%{site_name}] Email issue -- 投稿エラー" - text_body_template: | - 申し訳ありません,あなたの %{destination} へのメール(titled %{former_title}) は動きませんでした - - 複雑な書式、大きすぎるメッセージ、小さすぎるメッセージなど、複数の原因が考えられます。もう一度試してください。もし続くようであれば、ウェブサイトから投稿してください - email_reject_post_error_specified: - subject_template: "[%{site_name}] Email issue -- 投稿エラー" - text_body_template: | - 申し訳ありません,あなたの %{destination} へのメール(titled %{former_title}) は動きませんでした - - 理由: - - %{post_error} - - 問題が修正できたら、もう一度試してください email_reject_reply_key: subject_template: "[%{site_name}] Email issue -- 不明なReply Key" - text_body_template: "申し訳ありません,あなたの %{destination} へのメール(titled %{former_title}) は動きませんでした。 \n\n提供されたreply keyが無効または不明のため、このメールがどの返答なのかがわかりません。スタッフメンバーに連絡してください。\n" - email_reject_destination: - subject_template: "[%{site_name}] Email issue -- 不明な宛先" - text_body_template: "申し訳ありません,あなたの %{destination} へのメール(titled %{former_title}) は動きませんでした。 \n\n宛先が認識されませんでした。宛先(CC,BCCではなく)にサイトのアドレスがあること、スタッフから提供された正しいメールアドレスに送信していることを確認してください。\n\n" email_reject_topic_not_found: subject_template: "[%{site_name}] Email issue -- 存在しないトピック" email_reject_topic_closed: @@ -1391,10 +1118,6 @@ ja: subject_template: "[%{site_name}] Email issue -- 自動生成された返信" email_error_notification: subject_template: "[%{site_name}] Email issue -- POP認証エラー" - text_body_template: | - メールをポーリングするPOPサーバで認証エラーが発生しました。 - - [the site settings](%{base_url}/admin/site_settings/category/email)で、POP認証の設定を確認してください。 too_many_spam_flags: subject_template: "新規アカウントのブロック" text_body_template: | @@ -1407,33 +1130,10 @@ ja: 詳細については[コミュニティガイドライン](%{base_url}/guidelines)を参照してください。 blocked_by_staff: subject_template: "アカウントのブロック" - text_body_template: | - こんにちは - - スタッフメンバーによってブロックされたことをお知らせするために、%{site_name} から自動的に送信されています。 - - 詳細については[コミュニティガイドライン](%{base_url}/guidelines)を参照してください。 user_automatically_blocked: subject_template: "コミュニティフラッグによって新たにブロックされたユーザ%{username}" - text_body_template: |+ - これは自動送信メッセージです。 - - 複数のユーザが%{username}'のポストにフラグを立てているため、新規ユーザ[%{username}](%{base_url}%{user_url})は自動的にブロックされました。 - - フラグを確認してください(%{base_url}/admin/flags)。もし%{username}が間違ってブロックされた場合は、 このユーザの管理ページ(%{base_url}%{user_url})でブロック解除ボタンをクリックしてください。 - - この閾値はサイト設定の`block_new_user`で変更できます。 - spam_post_blocked: subject_template: "同一リンクの連続投稿による新規ユーザ %{username} のブロック" - text_body_template: | - これは自動送信メッセージです。 - - 新規ユーザ[%{username}](%{base_url}%{user_url})は、%{domains}へのリンクを複数投稿しようとしましたが、スパムを避けるために投稿をブロックしました。ユーザは%{domains}のリンクを含まない投稿であれば引き続き作成可能です。 - - ユーザを確認してください。(%{base_url}%{user_url}) - - この設定はサイト設定の `newuser_spam_host_threshold` と `white_listed_spam_host_domains` で変更できます。 unblocked: subject_template: "アカウントのブロック解除" text_body_template: | @@ -1459,59 +1159,19 @@ ja: unsubscribe: title: "解除" description: "メールに興味がありませんか? 下のリンクをクリックすると、即座にメール解除ができます:" - reply_by_email: "回答するにはこのメールに返信するか、ブラウザで %{base_url}%{url} にアクセスしてください。" - visit_link_to_respond: "回答するにはブラウザで %{base_url}%{url} にアクセスしてください。" posted_by: "%{post_date} に %{username} が投稿" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} がメッセージにあなたを招待しました '%{topic_title}'" - text_body_template: "\n{username} があなたをメッセージに招待しました \n\n> '%{topic_title}' \n>\n> %{topic_excerpt}\n\n> %{site_title} -- %{site_description}\n\nこのリンクからメッセージを参照してください: %{base_url}%{url}\n" - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} がトピックにあなたを招待しました '%{topic_title}'" user_replied: subject_template: "[%{site_name}] '%{topic_title}' 内のあなたのポストに新たな回答が投稿されました" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] '%{topic_title}' で %{username} があなたを引用しました" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] '%{topic_title}' で %{username} があなたをタグ付けしました" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] '%{topic_title}' に %{subject_prefix}個の新しいポストが投稿されました" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [プライベートメッセージ] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "あなたが最後にアクセスした %{last_seen_at} 以降の %{site_link} のまとめです" subject_template: "[%{site_name}] ダイジェスト" @@ -1552,12 +1212,6 @@ ja: 以下のリンクをクリックしてパスワードを設定してください: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] メールアドレスの確認" - text_body_template: | - 次のリンクをクリックして %{site_name} 用のメールアドレスを確認してください: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "%{site_name} への参加承認完了!" signup: @@ -1570,7 +1224,6 @@ ja: もし上記リンクがクリックできない場合は、ブラウザのアドレスバーにリンクアドレスをコピー&ペーストしてください。 page_not_found: - title: "リクエストしたページは存在しないかモデレータによって削除されました。" popular_topics: "人気" recent_topics: "最新" see_more: "もっと見る" @@ -1640,3 +1293,6 @@ ja: performance_report: initial_post_raw: このトピックでは、あなたのサイトの毎日のパフォーマンスレポートが含まれています。 initial_topic_title: ウェブサイトパフォーマンスレポート + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.ko.yml b/config/locales/server.ko.yml index b755b55a113..bcf02cbecd6 100644 --- a/config/locales/server.ko.yml +++ b/config/locales/server.ko.yml @@ -10,18 +10,27 @@ ko: short_date_no_year: "M월 D일" short_date: "YYYY-M-D" long_date: "YYYY-M-D a h:mm" + datetime_formats: &datetime_formats + formats: + short: "%Y-%m-%d" + short_no_year: "%B %-d" + date_only: "%B %-d, %Y" + date: + month_names: [] + <<: *datetime_formats title: "Discourse" topics: "글타래" posts: "글" loading: "로딩중" powered_by_html: 'Powered by Discourse, best viewed with JavaScript enabled' log_in: "로그인" - via: "%{site_name}의 %{username}" - is_reserved: "예약됨" purge_reason: "비활성화된 계정은 자동적으로 삭제됩니다." disable_remote_images_download_reason: "디스크저장공간이 부족하여 원격 이미지 다운로드 기능이 비활성화 되었습니다." anonymous: "익명" - errors: + emails: + incoming: + default_subject: "%{email} 으로부터 받은 이메일" + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "%{length}자를 입력하셨습니다. 최대 %{max}자까지 입력 가능합니다. " @@ -37,8 +46,10 @@ ko: exclusion: 예약됨 greater_than: '%{count}보다 커야 함' greater_than_or_equal_to: '%{count}보다 크거나 같아야 함' + has_already_been_used: "이미 사용되었음" inclusion: 리스트에 없음 invalid: 올바르지 않음 + is_invalid: "유효하지 않음; 좀더 자세하게 서술해주세요" less_than: '%{count}보다 작아야 함' less_than_or_equal_to: '%{count}보다 작거나 같아야 함' not_a_number: 숫자가 아님 @@ -71,6 +82,8 @@ ko: not_found: "요청한 URL이나 리소스를 찾지 못했습니다." invalid_access: "요청한 리소스를 볼 권한이 없습니다." read_only_mode_enabled: "현재 읽기 전용 모드입니다." + reading_time: "읽은 시간" + likes: "좋아요" too_many_replies: other: "죄송합니다. 신규 가입자는 글 하나에 %{count}개까지만 댓글을 달 수 있습니다." embed: @@ -84,26 +97,10 @@ ko: in_reply_to: "▶ %{username}" replies: other: "댓글 %{count}개" + no_mentions_allowed: "죄송합니다, 다른 사용자를 언급할 수 없습니다." too_many_mentions: - zero: "죄송합니다. 회원님은 다른 사용자를 언급할 수 없습니다." - one: "죄송합니다. 회원님은 한 댓글에서 한 사용자만 언급할 수 있습니다." - other: "죄송합니다. 회원님은 한 댓글에서 %{count}명의 사용자만 언급할 수 있습니다." - too_many_mentions_newuser: - zero: "죄송합니다. 신규회원은 다른 사용자를 언급할 수 없습니다." - one: "죄송합니다. 신규회원은 글 하나에 한 사용자만 언급할 수 있습니다." - other: "죄송합니다. 신규회원은 글 하나에 %{count}명의 사용자만 언급할 수 있습니다." - too_many_images: - zero: "죄송합니다. 신규회원은 글에 이미지를 넣을 수 없습니다." - one: "죄송합니다. 신규회원은 글 하나에 이미지 한 개만 넣을 수 있습니다." - other: "죄송합니다. 신규회원은 글 하나에 이미지 %{count}개만 넣을 수 있습니다." - too_many_attachments: - zero: "죄송합니다. 신규회원은 글에 파일을 첨부 할 수 없습니다." - one: "죄송합니다. 신규회원은 글 하나에 파일 한 개만 첨부할 수 있습니다." - other: "죄송합니다. 신규회원은 글 하나에 파일 %{count}개만 첨부한 수 있습니다." - too_many_links: - zero: "죄송합니다. 신규회원은 글에 링크를 넣을 수 없습니다." - one: "죄송합니다. 신규회원은 글 하나에 링크 한 개만 넣을 수 있습니다." - other: "죄송합니다. 신규회원은 글 하나에 링크 %{count}개까지만 넣을 수 있습니다." + other: "죄송합니다, 이 포스트에서 %{count}명의 사용자만 언급할 수 있습니다." + no_mentions_allowed_newuser: "죄송합니다. 새로운 사용자는 다른 사용자를 언급할 수 없습니다." spamming_host: "죄송합니다. 회원님은 링크를 첨부할 수 없습니다." user_is_suspended: "가입이 보류된 회원은 글을 쓸 수 없습니다." topic_not_found: "뭔가 잘못됐네요. 아마 글 보려는 도중에 글타래가 닫혔거나 지워진 건 아닐까요?" @@ -122,10 +119,11 @@ ko: num_posts: "글 수:" num_participants: "참여자:" read_full_topic: "전체 글타래 읽기" - private_message_abbrev: "MSG" + private_message_abbrev: "메시지" rss_description: latest: "최신 글타래" hot: "인기 글타래" + top: "인기 토픽" posts: "최근 글" too_late_to_edit: "이 글은 작성된 지 너무 오랜 기간이 지났습니다. 수정 또는 삭제할 수 없습니다." excerpt_image: "이미지" @@ -135,6 +133,7 @@ ko: errors: can_not_modify_automatic: "자동 그룹은 수정 하실 수 없습니다." member_already_exist: "'%{username}'은 이미 이 그룹의 멤버입니다." + invalid_domain: "'%{domain}'은 유효한 도메인이 아닙니다." default_names: everyone: "모든 사람" admins: "관리자" @@ -159,7 +158,7 @@ ko: 이 글은 당신의 첫 %{education_posts_text} 에서만 나옵니다. 자세한 내용은 [커뮤니티 가이드라인](/guidelines)을 참조하세요. new-reply: | - %{site_name}에 오신것을 환영합니다! + %{site_name}에 오신것을 환영합니다! — **참여해주셔서 감사합니다!** - 당신의 댓글이 어떤 식으로든 토론을 발전시키나요? @@ -200,11 +199,8 @@ ko: post: raw: "본문" user_profile: - bio_raw: "About Me" + bio_raw: "내 소개" errors: - messages: - is_invalid: "사용할 수 없습니다. 조금 더 자세하게 적어주세요." - has_already_been_used: "이미 사용 중." models: topic: attributes: @@ -216,7 +212,7 @@ ko: user: attributes: password: - common: "가장 자주 사용되는 10000개의 비밀번호 중 하나압니다. 보다 안전한 비밀번호를 사용하세요." + common: "가장 자주 사용되는 10000개의 비밀번호 중 하나입니다. 보다 안전한 비밀번호를 사용하세요." same_as_username: "는 아이디랑 같음. 제발 좀 더 안전한 비밀번호를 사용해주세요." same_as_email: "는 이메일 주소랑 같음. 좀 더 안전한 비밀번호를 사용해주세요." ip_address: @@ -225,6 +221,7 @@ ko: attributes: hex: invalid: "유효한 색상이 아닙니다." + <<: *errors user_profile: no_info_me: "
    프로필이 현재 비어있습니다. 지금 작성하시겠습니까?
    " no_info_other: "
    %{name}님께서는 아직 프로필을 작성하지 않으셨습니다
    " @@ -242,13 +239,10 @@ ko: 축하합니다! :confetti_ball: 당신의 회원등급이 **지도자** (회원등급 3등급)로 올라갔기 때문에 이 글타래를 볼 수 있게 되었습니다. 이제부터 아래의 행동들을 할 수 있습니다 … * 글타래를 제목을 수정할 수 있습니다 * 글타래의 카테고리를 수정할 수 있습니다 * 링크가 follow로 처리됩니다 ([automatic nofollow](http://en.wikipedia.org/wiki/Nofollow) 가 제거됩니다) * 회원등급 3 이상인 사용자가 접근할 수 있는 비공개 카테고리인 라운지에 접근할 수 있습니다 * 좋아요와 신고의 가중치가 높아집니다 [정규 멤버 목록](/badges/3/regular)을 확인할 수 있습니다. 인사하는 것을 잊지마세요. 이 커뮤니티의 중요한 역할을 해주신 것에 감사드립니다! (회원등급에 관한 더 자세한 정보를 보시려면, [이 글타래를 확인하세요][trust]. 기준에 맞는 사람만 정규 회원으로 자격이 유지됩니다.) [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "'%{category}' 카테고리의 설명" - replace_paragraph: "[이 첫번째 문단을 당신의 새로운 카테고리의 짧은 설명으로 바꿔주세요. 이 지침은 카테고리 선택 화면에 나타날 것입니다. 200자 이하로 적어주세요.]" - post_template: "%{replace_paragraph}\n\n이 공간은 긴 설명을 사용하여 주세요. 또한 카테고리 가이드라인이나 룰도 이 공간을 이용해주세요.\n\n몇 가지 답글에 관련하여 고려해봐야 할 것들:\n\n- 무엇을 위한 카테고리인가? 왜 사용자들이 이 카테고리를 필요로 하겠는가?\n\n- 이미 가지고있는 다른 카테고리와 어떻게 다른가?\n\n- 정말 이 카테고리가 필요한가?\n\n- 다른 카테고리와 합병이 필요한가 아니면 더욱 자세한 카테고리로 나눌 필요가 있는가?\n" errors: uncategorized_parent: "Uncategorized 카테고리는 부모 카테고리를 가질 수 없습니다." self_parent: "하위 카테고리의 부모는 자신이 될 수 없습니다." depth: "하위 카테고리는 계층 구조로 사용할 수 없습니다." - email_in_already_exist: "'%{email_in}' 수신용 이메일 주소는 '%{category_name}' 카테고리 에서 사용 중입니다." cannot_delete: uncategorized: "Uncategorized는 삭제할 수 없습니다." has_subcategories: "하위 카테고리가 있어, 삭제할 수 없습니다." @@ -260,16 +254,21 @@ ko: title: "새로운 사용자" basic: title: "기본 사용자" + member: + title: "멤버" regular: - title: "회원" + title: "일반" leader: - title: "정규 회원" - elder: - title: "지도자" + title: "리더" change_failed_explanation: "당신은 %{user_name} 사용자를 '%{new_trust_level}'으로 강등시키려 하였습니다. 하지만 해당 사용자의 회원등급는 이미 '%{current_trust_level}'입니다. %{user_name} 사용자의 회원등급는 '%{current_trust_level}'으로 유지됩니다. - if you wish to demote user lock trust level first" rate_limiter: - slow_down: "해당 작업을 너무 많이 수행했습니다. 잠시 뒤에 다시 시도해보세요." + slow_down: "해당 작업을 너무 많이 수행했습니다. 잠시후 다시 시도해보세요. " too_many_requests: "지금 하시려는 행동에는 하루 제한이 있습니다. %{time_left} 동안 기다리시고 다시 시도해 주세요." + by_type: + first_day_replies_per_day: "새 유저가 가입한 첫 날에 작성할 수 있는 댓글의 최대 갯수에 도달했습니다. %{time_left}동안 기다리셨다가 다시 시도해보세요." + first_day_topics_per_day: "새 유저가 가입한 첫 날에 작성할 수 있는 토픽의 최대 갯수에 도달했습니다. %{time_left}동안 기다리셨다가 다시 시도해보세요." + create_topic: "너무 빨리 토픽을 작성했습니다. %{time_left}동안 기다리셨다가 다시 시도해보세요." + create_post: "너무 빨리 댓글을 작성했습니다. %{time_left}동안 기다리셨다가 다시 시도해보세요." hours: other: "%{count}시간" minutes: @@ -280,11 +279,11 @@ ko: distance_in_words: half_a_minute: "<1분" less_than_x_seconds: - other: "%{count}초 전" + other: "< %{count}초" x_seconds: other: "%{count}초" less_than_x_minutes: - other: "%{count}분 전" + other: "< %{count}분" x_minutes: other: "%{count}분" about_x_hours: @@ -339,6 +338,7 @@ ko: please_continue: "%{site_name}으로 가기" error: "이메일 주소를 변경하는데 문제가 있습니다. 주소가 이미 사용되고 있나요?" activation: + action: "여기를 눌러 계정을 활성화하세요." already_done: "죄송합니다. 이 계정 확인 링크는 더 이상 유효하지 않습니다." please_continue: "계정이 활성화 되었습니다; 홈페이지로 이동합니다." continue_button: "%{site_name}으로 가기" @@ -361,16 +361,13 @@ ko: description: '이 글은 다른 사용자들에게 공격적이나 모욕적 또는 침해적인 글을 담고 있습니다.' long_form: '부적절함으로 신고하기' notify_user: - title: '메세지 @{{username}}' - description: '이 글에 내가 작성자와 직접 대화하고 싶은 내용이 있습니다. 신고에서 제외해주세요.' + title: '@{{username}} 님에게 메시지를 보냅니다' long_form: '메세지한 유저' email_title: '"%{title}" 내의 당신의 글' email_body: "%{link}\n\n%{message}" notify_moderators: title: "뭔가 다른것" - description: '이 글은 리스트에 없는 이유로 관리자의 주의가 필요합니다.' - long_form: '관리자의 주의를 위해 신고' - email_title: '"%{title}" 글에 대한 운영자의 확인이 필요합니다' + long_form: '주의를 위해 운영진에게 신고했습니다' email_body: "%{link}\n\n%{message}" bookmark: title: '북마크' @@ -397,7 +394,6 @@ ko: long_form: '부적절함으로 신고하였습니다.' notify_moderators: title: "뭔가 다른것" - description: '이 글은 가이드라인, 이용약관, 또는 다른 이유와 관련해서 운영자의 주의가 필요합니다.' long_form: '관리자의 주의를 위해 신고' email_title: '글타래 "%{title}" 은 운영자의 확인이 필요합니다' email_body: "%{link}\n\n%{message}" @@ -433,6 +429,10 @@ ko: title: "새 사용자" xaxis: "일" yaxis: "새로운 사용자 수" + profile_views: + title: "회원 프로필 조회수" + xaxis: "일" + yaxis: "회원 프로필 조회된 횟수" topics: title: "글타래들" xaxis: "일" @@ -516,6 +516,10 @@ ko: title: "총" xaxis: "일" yaxis: "총 API 요청" + page_view_logged_in_mobile_reqs: + xaxis: "일" + page_view_anon_mobile_reqs: + xaxis: "일" http_background_reqs: title: "백그라운드" xaxis: "일" @@ -548,6 +552,10 @@ ko: title: "답글 없는 주제" xaxis: "일" yaxis: "총" + mobile_visits: + title: "사용자 방문횟수" + xaxis: "일" + yaxis: "방문 횟수" dashboard: rails_env_warning: "당신의 서버는 %{env} 모드에서 실행되고 있습니다." ruby_version_warning: "당신은 문제가 자주 발생하는 루비 버전 2.0.0을 사용하시고 있습니다. 247 또는 이후 패치 레벨로 업그레이드를 해주세요." @@ -570,37 +578,6 @@ ko: consumer_email_warning: "이메일 전송을 위해 Gmail(또는 다른 커스텀 이메일 서비스)을 사용하고 있습니다. Gmail의 이메일 전송 제한 을 읽어보세요. mandrill.com을 이메일 서비스로 설정하는 것을 고려해보세요." site_contact_username_warning: "중요 자동 메세지를 보낼 스태프 사용자 계정의 이름을 적으세요. 사이트 설정에서 site_contact_username을 업데이트하세요." notification_email_warning: "알람 메일이 올바른 이 사이트의 도메인 내 이메일 주소로 전송되지 않고 있습니다; 이메일 전송이 안정적이지 않을 것입니다. 사이트 설정에서 올바른 도메인의 이메일 주소로 정해주세요." - content_types: - education_new_reply: - title: "새로운 사용자 교육: 첫번째 답글들" - description: "새로운 사용자가 첫 두개의 답글을 작성하면 자동 팝업됩니다." - education_new_topic: - title: "새로운 사용자 교육: 첫번째 글타래들" - description: "새로운 사용자가 첫 두개의 글타래를 작성하면 자동 팝업됩니다." - usage_tips: - title: "새로운 사용자 가이드" - description: "새로운 사용자를 위한 가이드와 팁." - welcome_user: - title: "환영: 새로운 사용자" - description: "새 가입자에게 전달할 자동 메세지" - welcome_invite: - title: "환영: 초대된 사용자" - description: "사용자가 다른 사람이 보낸 초대장에 승인했을 때 에게 전달 될 자동 메세지" - login_required_welcome_message: - title: "로그인 필요: Welcome Message" - description: "'login required' 설정이 활성화 되어있으면 웰컴 메시지가 로그인 되지 않은 사용자들에게 보여집니다." - login_required: - title: "로그인 필요: 홈페이지" - description: "이 텍스트는 로그인이 필요하지만 인증되지 않은 사용자들에게 보여집니다." - head: - title: "HTML head" - description: " 태그 사이에 추가할 HTML" - top: - title: "페이지 상단" - description: "모든 페이지 상단에 추가할 HTML(헤더 아래, 네비게이션이나 글타래 제목 위)." - bottom: - title: "페이지 하단" - description: "모든 페이지 하단에 추가할 HTML" site_settings: censored_words: "단어는 자동적으로 `■■■■` 로 대체 됩니다." delete_old_hidden_posts: "30일이 지난 숨겨진 글은 자동으로 삭제됩니다." @@ -615,7 +592,6 @@ ko: min_private_message_title_length: "메세지 제목의 최소 길이" min_search_term_length: "검색을 하기 위한 최소 글자 수" allow_uncategorized_topics: "카테고리 없이 게시 허용. 주의: 카테고리 없는 글은 이 항목을 비활성화에 하기전에 카테고리 설정을 해야 합니다." - uncategorized_description: "'카테고리 없음' 카테고리의 설명, 설명을 쓰지 않으려면 빈칸으로 놔둔다." allow_duplicate_topic_titles: "같은 제목의 동일한 글타래 허용" unique_posts_mins: "같은 컨텐츠를 다시 글 할 수 있는 기간(분)" educate_until_posts: "새로운 사용자가 글를 작성할 시 글 작성 방법에 대한 교육패널을 보여주는데, 해당 패널이 보여지는 초기 글 개수" @@ -628,7 +604,6 @@ ko: download_remote_images_to_local: "이미지를 다운로드하면 원격 이미지를 로컬이미지로 변경. 이미지가 깨지는 것을 막을 수 있습니다." download_remote_images_threshold: "원격의 이미지를 로컬에 다운받기 위한 최소 디스크 공간(%)" disabled_image_download_domains: "이 도메인을 통해서 원격 이미지를 다운로드 하지 않는다. ` | `를 구분자로 한 리스트" - ninja_edit_window: "편집을 결과가 새로운 버전을 생성하지 않는 포스팅 이후에 경과할 시간(초)" post_edit_time_limit: "글 작성자가 해당 글을 편집하거나 삭제할 수 있도록 허용되는 시간(분). 0으로 설정하면 언제든지 편집이나 삭제가 허용됨." edit_history_visible_to_public: "모든 사용자가 글의 수정 내역을 볼 수 있도록 허용. 비활성화시 스태프 맴버만 수정 내역을 볼 수 있음." delete_removed_posts_after: "작성자에 의해 삭제된 글은 (n) 시간 뒤 자동으로 삭제됩니다. 0으로 설정 시, 즉시 삭제됩니다." @@ -653,7 +628,6 @@ ko: summary_likes_required: "하나의 글타래에 대하여 요약본 보기 모드가 활성화되기 전까지 요구되는 최소 좋아요 수" summary_percent_filter: "요약본 보기를 클릭시, 글 중에 몇 %의 상위 글을 보여줄 것인가?" summary_max_results: "이 주제에 대한 요약 글 최대 갯수" - enable_private_messages: "회원등급 1인 유저들에게 메세지 작성과 메세지 답변을 허용하기" enable_long_polling: "Message bus used for notification can use long polling" long_polling_base_url: "long polling에 사용 될 Base URL (CDN이 동적 콘텐트를 제공할 시에는 origin pull로 설정) eg: http://origin.site.com" long_polling_interval: "보낼 데이터가 없을 때 응답 전에 서버가 기다려야하는 시간 (로그인된 유저 전용)" @@ -674,6 +648,7 @@ ko: traditional_markdown_linebreaks: "Markdown에서 전통적인 linebreak를 사용, linebreak시 두개의 trailing space를 사용하는 것." post_undo_action_window_mins: "사용자가 어떤 글에 대해서 수행한 작업(신고 등)을 취소하는 것이 허용되는 시간(초)" must_approve_users: "스태프는 반드시 사이트 엑세스권한을 허용하기 전에 모든 신규가입계정을 승인해야 합니다. 경고: 이것을 활성화하면 기존 스태프 아닌 회원들의 엑세스권한이 회수됩니다." + pending_users_reminder_delay: "새로운 사용자가 승인을 기다리는 시간이 여기에 지정된 시간횟수보다 더 길어길경우 운영자에게 알려줍니다. 알림을 해제하려면 -1로 설정하세요." ga_tracking_code: "Google analytics (ga.js)의 트래킹 코드, 예: UA-12345678-9; 참고 http://google.com/analytics" ga_domain_name: "Google analytics (ga.js)의 도메인 이름, 예: mysite.com; 참고 http://google.com/analytics" ga_universal_tracking_code: "Google Universal Analytics (analytics.js)의 트래킹 코드, 예: UA-12345678-9; 참고 http://google.com/analytics" @@ -693,7 +668,6 @@ ko: suppress_reply_directly_above: "단 하나의 댓글 위의 글이 하나 있는 상황에서 '~에 대한 댓글'을 보여주지 않음." suppress_reply_when_quoting: "글안에 답글이 인용될 때 in-reply-to를 보여주지 않습니다." max_reply_history: "덧글 확장해서 보여지는 최대 갯수" - experimental_reply_expansion: "답글을 펼쳤을 때 중간 답글을 숨깁니다(실험 중)" topics_per_period_in_top_summary: "인기 글타래 요약에 기본으로 보여질 글타래 수" topics_per_period_in_top_page: "인기 글타래에서 '더 보기'를 요청할 시 보여질 글타래 수" redirect_users_to_top_page: "자동으로 신규 사용자와 오래간만에 들어온 사용자를 탑 페이지로 리다이렉트 시킴" @@ -714,6 +688,9 @@ ko: invite_passthrough_hours: "사용되어진 방문키를 로그인하는데 재사용할 수 있는 기간, 시간" invite_only: "공개 가입은 불가하도록 설정됨. 초대를 받아야만 신규 가입 가능함." login_required: "글을 읽으려면 인증(로그인)이 필요함" + min_username_length: "아이디 최소길이 (문자 갯수)" + max_username_length: "아이디 최대길이 (문자 갯수)" + reserved_usernames: "회원가입 금지된 아이디 목록" min_password_length: "비밀번호 최소 글자수." block_common_passwords: "가장 흔히 사용되는 10,000개 비밀번호 목록에 있는 비밀번호를 사용하는 것을 허용하지 않음." enable_sso: "외부사이트 Single Sign On, SSO를 통해 로그인 활성화(경고: 유저의 이메일 주소는 반드시 외부에서 확인해야합니다!)" @@ -786,16 +763,9 @@ ko: tl2_requires_likes_received: "회원등급-2가 되기 위해 받아야 하는 좋아요 횟수" tl2_requires_likes_given: "회원등급-2가 되기 위해 눌러야하는 좋아요 횟수" tl2_requires_topic_reply_count: "기회원등급-2가 되기 위해 달아야 하는 댓글 갯수" - tl3_requires_days_visited: "VIP 사용자-3 이 되기 위해 지난 100일 동안 최소한 사이트에 방문해야 하는 수 (0 ~ 100)" - tl3_requires_topics_replied_to: "VIP 사용자-3 이 되기 위해 지난 100일 동안 답글을 달아야하는 최소 글타래수(0 ~ )" - tl3_requires_topics_viewed: "VIP 사용자-3 이 되기 위해 지난 100일 동안 생성된 전체 글타래 중 본 글타래의 비율(%, 0 ~ 100)" - tl3_requires_posts_read: "VIP 사용자-3 이 되기 위해 지난 100일 동안 생성된 전체 글 중 본 글의 비율(%, 0 ~ 100)" tl3_requires_topics_viewed_all_time: "VIP 사용자-3 이 되기 위해 꼭 보아야 하는 글타래의 전체 개수" tl3_requires_posts_read_all_time: "VIP 사용자-3 이 되기 위해 꼭 보아야 하는 글타래의 전체 개수" - tl3_requires_max_flagged: "사용자가 VIP 사용자-3 이 되기 위해 지난 100일동안 서로 다른 사용자에게 최소한으로 받지 말아야하는 신고된 글 수(0 ~ )" tl3_promotion_min_duration: "회원등급이 2로 떨어진 후 다시 VIP 사용자-3 이 될 수 있는 최소 일 수" - tl3_requires_likes_given: "VIP 사용자-3 이 되기 위해 지난 100일 동안 해야 할 좋아요 수" - tl3_requires_likes_received: "VIP 사용자-3 이 되기 위해 지난 100일 동안 받아야 할 좋아요 수" tl3_links_no_follow: "VIP 사용자-3 의 글에 있는 링크에서 rel=nofollow 를 제거하지 마시오." min_trust_to_create_topic: "새로운 글타래를 생성하기 위한 최소 회원등급" min_trust_to_edit_wiki_post: "위키로 설정된 글 수정할 수 있는 최소 회원등급" @@ -876,7 +846,6 @@ ko: automatically_download_gravatars: "사용자가 계정을 만들거나 이메일을 변경하자마자 Gravatar를 다운로드합니다." digest_topics: "요약 이메일에서 보여질 최대 글타래 개수" digest_min_excerpt_length: "요약 이메일에서 최소 글 발췌 수" - suppress_digest_email_after_days: "(n)일동안 사이트에서 보지 못한 사용자에게는 이메일 요약을 보내지 않습니다." disable_digest_emails: "모든 유저들 이메일 다이제스트 못하게 하기" max_daily_gravatar_crawls: "하루에 Discourse가 커스텀 아파타를 위해 Gravatar를 체크하는 최대 횟수" public_user_custom_fields: "유저가 쓸 수 있는 공개 커스텀 필드 목록" @@ -886,7 +855,6 @@ ko: anonymous_posting_min_trust_level: "익명 게시 할 수 있는 최소 회원등급" anonymous_account_duration_minutes: "한 익명이 익명계정을 만들 때 빨리 만드는 걸 막을 분 단위 시간 예: 600으로 정해놓으면 마지막 게시하고 익명 전환 후로 600분이 지나는 즉시 새 계정이 만들어 집니다." allow_profile_backgrounds: "사용자에게 프로필 배경 이미지 업로드를 허용합니다." - sequential_replies_threshold: "한 유저가 한 글타래에 너무 연속으로 답글 달았다고 알리게 될 연속 글 수" enable_mobile_theme: "모바일 디바이스는 모바일 환경에 친화적인 테마를 사용합니다, 그리고 PC용 화면으로 전환할 수 있습니다. 만약 커스텀 스타일 시트를 사용한다면 이것을 비활성화 시키세요." dominating_topic_minimum_percent: "한 글타래에서 한 사용자의 영향력을 결정하는 글 수의 퍼센트" daily_performance_report: "NGINX 일별 로그를 분석하고 상세정보를 스태프들에게 글타래 게시" @@ -915,13 +883,11 @@ ko: enable_cdn_js_debugging: "/logs에서 적절한 모든 js를 포함해 crossorigin 권한 오류가 뜨도록 합니다." show_create_topics_notice: "이 사이트에 5개 이하의 공개 글타래가 있으면, 관리자에게 글타래 좀 만들라고 알려줍니다." delete_drafts_older_than_n_days: (n) 일지난 임시 보관글 삭제하기 - vacuum_db_days: "VACUUM FULL ANALYZE를 실행해서 통합 후 DB 공간 재확인 (0으로 설정하면 비활성화)" prevent_anons_from_downloading_files: "익명 사용자가 다운로드를 받지 못하게 합니다. 경고: 이미지 파일 외 모든 첨부파일이 다운로드 받지 못하게 됩니다." slug_generation_method: "slug 생성 방식. 'encoded'는 퍼센트 기호로 인코딩해서 생성합니다. 'none'은 slug 자체를 비활성화합니다.." enable_emoji: "emoji 활성화" emoji_set: "어떤 emoji가 좋은가요?" enforce_square_emoji: "모든 emoji를 정사각형 비율로 강제로 바꿉니다." - approve_post_count: "신규가입자가 올릴 수 있는 글 수" approve_unless_trust_level: "허가 받고 글 올려야 하는 유저들 최저 회원등급" notify_about_queued_posts_after: "글이 리뷰가 되길 기다리면서 이 시간이 지나면 문의처 메일로 연락을 보냅니다. 0으로 두면 보내지 않습니다." errors: @@ -948,7 +914,6 @@ ko: moved_post: "%{display_username} 사용자가 %{link} 에 당신의 글을 이동하였습니다." private_message: "%{display_username} 회원님이 메세지를 보냈습니다: %{link}" invited_to_private_message: "%{display_username} 회원님이 메세지에 초대했습니다: %{link}" - invited_to_topic: "%{display_username} 회원님이 글타래에 초대했습니다: %{link}" invitee_accepted: "%{display_username} 사용자가 당신의 초대를 수락하였습니다." linked: "%{display_username} 사용자가 %{link} 에서 당신을 링크했습니다." granted_badge: "당신은 %{link}를 획득했습니다." @@ -958,11 +923,6 @@ ko: category: '카테고리' topic: '검색 결과' user: '사용자' - sso: - not_found: "계정 생성 또는 찾기 불가, 관리자에게 문의하세요" - account_not_approved: "계정이 승인을 기다리고 있습니다, 승인 후 완료 이메일이 보내집니다." - unknown_error: "업데이트 정보에 오류가 있습니다. 사이트 관리자에게 문의해주세요." - timeout_expired: "로그인 연결 시간이 초과되었습니다. 다시한번 시도해주세요" original_poster: "원본 게시자" most_posts: "최대 게시자" most_recent_poster: "최근 게시자" @@ -1035,6 +995,9 @@ ko: ip_address: blocked: "이 IP주소에서는 가입이 안됩니다." max_new_accounts_per_registration_ip: "이 IP에서는 가입이 더이상 되지 않습니다(최대 가입 제한 도달). 스태프에게 연락주세요." + flags_reminder: + subject_template: + other: "%{count}개의 신고가 접수 대기 중" invite_mailer: subject_template: "%{invitee_name} 회원님이 %{site_domain_name} 에 '%{topic_title}'에 초대하였습니다." text_body_template: | @@ -1071,86 +1034,10 @@ ko: subject_template: "%{site_name} 계정을 위해 비밀번호 설정" test_mailer: subject_template: "[%{site_name}] 이메일 발송 테스트" - text_body_template: | - 이것은 테스트 이메일 양식입니다. - - [**%{base_url}**][0] - - 이메일 발송은 어렵습니다. 먼저 체크해야 할 몇가지 사항을 알려드립니다: - - - `알림 이메일` 발신지 주소가 사이트 설정에 적었는지 *확실히* 보세요. **발신지 이메일 주소에 적힌 도메인은 받는 곳에서 검사하게 될 도메인입니다**. - - - 이메일 raw source를 이메일 클라이언트에서 보는 방법을 알아두고 이메일 헤더에서 중요한 단서를 찾도록 합니다. Gmail에서는, 각 메일의 오른쪽 위에 있는 드롭다운 메뉴의 "원본보기" 옵션입니다. - - - **중요:** 당신의 ISP회사가 도메인네임과 IP주소를 연결시켜주러 들어오는 a reverse DNS record 갖고 있나요? [Reverse PTR record 테스트][2]해보세요. ISP회사가 적절한 reverse DNS pointer record를 안 넣었다면, 어떤 이메일도 발송이 안될 수 있습니다. - - - 이메일 도메인의 [SPF record][8]가 제대로 설정됐나요? [SPF record 테스트][1]해보세요. 참고로 TXT가 제대로된 공식 SPF 타입입니다. - - - 이메일 도메인의 [DKIM record][3]가 제대로 설정됐나요? 이게 이메일 전송에 큰 영향을 줍니다. [your DKIM record 테스트][7]해보세요. - - - 스스로 이메일서버를 운영중이라면, 메일서버 IP가 [블랙리스트][4]에 안들어 가있는지 확실히 봐야합니다. 또 DNS의 HELO 메세지로 resolve가 되는 완벽히 인증된 호스트네임으로 제대로 보내고 있는지 확인해야 합니다. 아니라면 대부분의 받는 쪽 메일 서비스에서 거절 받을 겁니다. - - (한 가지 *쉬운* 방법은 [Mandrill][md]이나 [Mailgun][mg]이나 [Mailjet][mj]에 가입해 메일링 서비스를 받는 것이고 작은 커뮤니티에서는 괜찮을 겁니다. 그래도 SPF레코드 DKIM레코드는 DNS에 등록해줘야합니다!) - - 우리도 이 이메일 전송 테스트를 제대로 받았기를 바랍니다. - - 행운을 빕니다. - - 당신의 친구 [Discourse](http://www.discourse.org) - - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: https://www.mailjet.com/pricing new_version_mailer: subject_template: "[%{site_name}] 새 Discourse 버전으로 업데이트 가능." - text_body_template: | - [Discourse](http://www.discourse.org) 새 버전이 나왔습니다. - - 현재 이 Discourse 버전: %{installed_version} - 새 버전: **%{new_version}** - - 제안: - - - [GitHub changelog](https://github.com/discourse/discourse/commits/master)에 뭐가 바뀌었는지 확인해보세요. - - - 브라우저 상에서 [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade)로 들어가 업그레이드가 가능합니다. - - - [meta.discourse.org](http://meta.discourse.org) 포럼에서 Discourse 관련 지원, 토의, 뉴스를 보실 수 있습니다. new_version_mailer_with_notes: subject_template: "[%{site_name}] 업데이트 가능." - text_body_template: |+ - [Discourse](http://www.discourse.org) 새 버전이 나왔습니다. - - 현재 이 Discourse 버전: %{installed_version} - 새 버전: **%{new_version}** - - 제안: - - - [GitHub changelog](https://github.com/discourse/discourse/commits/master)에 뭐가 바뀌었는지 확인해보세요. - - - 브라우저 상에서 [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade)로 들어가 업그레이드가 가능합니다. - - - [meta.discourse.org](http://meta.discourse.org) 포럼에서 Discourse 관련 지원, 토의, 뉴스를 보실 수 있습니다. - - ### 릴리즈 노트 - - %{notes} - - flags_reminder: - flags_were_submitted: - other: "이 신고들은 %{count}시간 전에 접수 됐습니다." - please_review: "후기를 써주세요." - post_number: "글" - how_to_disable: '"notify about flags after" 설정을 통해 이메일 알림의 빈도를 변경하거나 비활성화할 수 있습니다.' - subject_template: - other: "%{count}개의 신고가 접수 대기 중" queued_posts_reminder: subject_template: other: "[%{site_name}]의 %{count}개의 글이 검토를 기다리고 있습니다." @@ -1187,6 +1074,99 @@ ko: 하지만 글이 한번 더 커뮤니티에서 숨김이 된 경우 스태프가 풀어주기 전까지 숨김해제가 안되며 계정 정지 등의 조치가 취해질 수 있습니다. 조언을 얻기 위해, [커뮤니티 가이드라인](%{base_url}/guidelines)을 참고해 주세요. + usage_tips: + text_body_template: | + 시작하기 위한 몇 가지 간단한 팁을 알려드릴께요: + + ## 읽기 + + 더 읽으시려면, **그냥 계속해서 스크롤다운 하세요!** + + 새 댓글이나 새 포픽이 올라오면 자동으로 나타나기 때문에 페이지 새로고침할 필요가 없습니다. + + ## 탐색 + + - 검색 또는 메뉴, 사용자페이지는 **화면 우상단에 있는 아이콘 버튼**을 사용하세요. + + - 토픽을 선택하면 항상 당신이 그 토픽에서 **읽지 않은 다음 댓글**로 바로 갑니다. 제일 위나 아래로 가려면, 댓글 카운트 또는 마지막 댓글 날짜를 선택하세요. + + + + - 토픽을 읽는 도중에는, 우하단에 있는 프로그레스 바를 이용해서 전체 탐색하세요. 토픽 제목을 선택하면 제일 위로 바로 갈 수 있답니다. 초스피드 키보드 단축키 목록이 궁금하면 ?키를 누르세요. + + + + ## 댓글달기 + + - 토픽에 **평범하게 댓글 달때**는, 토픽 맨 밑에 있는 버튼을 이용하세요. + + - **특정 사람**에게 댓글 달때는, 그 글에 딸린 버튼을 이용하세요. + + - **새로운 토픽으로** 댓글 달때는, 글 오른쪽에 있는 버튼을 이용하세요. 오래된 토픽과 새 토픽 모두 자동적으로 함께 링크됩니다. + + 댓글은 간단한 HTML 또는 BBCode, [마크다운 (Markdown)](http://commonmark.org/help/) 형식으로 쓸 수 있습니다. + + 이건 **볼드체**입니다. + 이건 볼드체입니다. + 이건 [b]볼드체[/b]입니다. + + 마크다운을 배우고 싶으시다면? [저희의 10분짜리 재밌는 인터랙티브 튜토리얼을 해보세요!](http://commonmark.org/help/tutorial/) + + 인용문을 삽입하려면, 인용하고 싶은 텍스트를 선택한 다음에 댓글달기(응답하기) 버튼 아무거나 누르세요. 인용문이 여러개면 앞 동작을 반복하세요. + + + + 댓을을 누군가에게 알리고 싶을 때는 그 사람 이름을 언급하세요. `@` 키를 쳐서 사용자이름 선택하기를 시작할 수 있답니다. + + + + [표준 이모지(Emoji)](http://www.emoji.codes/)를 사용하려면, 그냥 `:`키를 눌러서 매칭되는 이름을 찾거나 예전부터 써온 `;)` 웃음표시를 이용하세요. + + + + 링크 요약을 생성하려면, 편집기 화면에 그 링크를 그냥 아래처럼 붙여넣기 하세요: + + + + ## 액션 + + 각각의 글 밑에는 액션 버튼들이 있습니다: + + + + 누군가의 글이 마음에 쏙 들어서 감사표시를 하고 싶으면 **좋아요** 버튼을 이용하세요. 애정을 공유하는 거에요! + + 누군가의 글에 문제가 있으면, **신고** 버튼으로 글쓴이에게 또는 [우리 운영진](%{base_url}/about)에게 개인적으로 조용히 알려주세요. 그 글로 가는 링크를 **공유**하거나 **북마크**해서 당신의 사용자 페이지에서 나중에 참고할 수도 있습니다. + + ## 알림 + + 누군가 당신에게 댓글달거나 당신의 글을 인용, 또는 당신의 `@아이디`를 언급하면, 페이지 우상단에 숫자가 즉시 나타납니다. **알림**으로 접근할 때 그걸 이용하세요. + + + + 댓글 놓칠까봐 걱정하지 마세요 - 당신이 없는 사이에 온 알림은 이메일로 보내드릴 꺼에요. + + ## 환경설정 + + - **쓴지 이틀이 안 된** 모든 토픽은 새글로 간주합니다. + + - **당신이 활동적으로 참여한** (글쓰기, 댓글달기, 일정시간 이상 읽기 등) 토픽은 자동적으로 추적됩니다. + + 이 토픽들 바로 옆에는 파란색 new 또는 읽지 않는 댓글수가 표시됩니다: + + + + 토픽 맨 밑에 있는 알림제어판을 통해 어떤 토픽이든지 알림설정을 바꿀 수 있습니다. + + + + 그리고 만일 특정 카테고리의 모든 새토픽을 지켜보고 싶으면, 카테고리 별로 알림설정 할 수 있습니다. + + 설정을 바꾸려면 [당신의 사용자 환경설정](%{base_url}/my/preferences)을 참고하세요. + + ## 커뮤니티 신뢰 + + 이곳에 참여하시면, 시간이 지남에 따라 커뮤니티의 신뢰를 받게 되고 정회원이 되어 신규회원 제한은 사라질 꺼에요. 충분이 높은 [회원등급이 되면](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), 우리 커뮤니티를 함께 꾸려나가는 걸 도와줄 새능력을 얻을 껍니다. welcome_user: subject_template: "%{site_name} 사이트에 오신것을 환영합니다!" text_body_template: | @@ -1271,18 +1251,8 @@ ko: csv_export_failed: subject_template: "데이터 추출 실패" text_body_template: "죄송합니다. 데이터 추출에 실패하였습니다. 로그를 확인하시거나 관리자에게 문의해주세요." - email_reject_trust_level: - subject_template: "[%{site_name}] 이메일 문제 -- 회원등급 충족 안됨." - text_body_template: | - 죄송합니다, 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. - - 새 글타래를 작성하는 데 필요한 회원등급이 없습니다. 오류라고 생각되면 스태프에게 연락주세요. email_reject_no_account: subject_template: "[%{site_name}] 이메일 문제 -- 모르는 계정" - text_body_template: | - 죄송합니다 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. - - 이 이메일 주소로 되어있는 사용자 계정이 없습니다. 다른 이메일 주소로 보내거나 스태프에게 연락 주세요. email_reject_empty: subject_template: "[%{site_name}] 이메일 문제 -- 내용 없음" email_reject_parsing: @@ -1297,42 +1267,17 @@ ko: 죄송합니다, 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. 이 카테고리에서 새 글타래를 작성하는 데 필요한 회원등급이 없습니다. 오류라고 생각되면 스태프에게 연락주세요. - email_reject_post_error: - subject_template: "[%{site_name}] 이메일 문제 -- 게시 오류" - text_body_template: | - 죄송합니다, 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. - - 복잡한 포매팅, 대용량 메세지, 너무 짧은 메세지가 문제일 수 있습니다. 다시 시도 해보고 계속 문제 된다면 웹사이트를 통해 글을 올리세요. - email_reject_post_error_specified: - subject_template: "[%{site_name}] 이메일 문제 -- 게시 오류" - text_body_template: "죄송합니다, 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. \n\n이유:\n\n%{post_error}\n\n문제를 고치고 다시 시도해 보세요.\n" email_reject_reply_key: subject_template: "[%{site_name}] 이메일 문제 -- 잘못된 답글 Key" - text_body_template: | - 죄송합니다 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. - - 받은 답글 key가 올바르지 않거나 모르는 key여서 어디에 답글을 달아야 하는지 모르겠스빈다. 스태프에게 연락주세요. - email_reject_destination: - subject_template: "[%{site_name}] 이메일 문제 -- 모르는 주소" - text_body_template: | - 죄송합니다 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. - - 목적지 이메일 주소 전부가 식별되지 않습니다. 사이트 주소가 To: 줄(Cc:나 Bcc:는 안됨)에 들어 있는지 스태프에게 받은 올바른 이메일 주소로 보내고 있는지 확인해주세요. email_reject_topic_not_found: subject_template: "[%{site_name}] 이메일 문제 -- 글타래 못 찾음" - text_body_template: "죄송합니다, 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. \n\n답글하려는 글타래가 더이상 존재하지 않습니다, 아마 지워졌을 수도 있습니다. 오류라고 생각되면 스태프에게 연락주세요.\n" email_reject_topic_closed: subject_template: "[%{site_name}] 이메일 문제 -- 글타래 닫힘" - text_body_template: "죄송합니다, 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. \n\n답글하려는 글타래가 닫혔거나 더이상 답글을 받지 않스빈다. 오류라고 생각되면 스태프에게 연락 주세요.\n" + text_body_template: "죄송합니다, 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. \n\n답글하려는 글타래가 닫혔거나 더이상 답글을 받지 않습니다. 오류라고 생각되면 스태프에게 연락 주세요.\n" email_reject_auto_generated: subject_template: "[%{site_name}] 이메일 문제 -- 자동 생성된 답글" - text_body_template: "죄송합니다, 이메일 메세지 %{destination} (titled %{former_title})가 안 됐습니다. \n\n이메일이 \"자동 생성\"으로 확인 되어 받을 수 없습니다. 오류라고 생각되면 스태프에게 연락주세요.\n" email_error_notification: subject_template: "[%{site_name}] 이메일 문제 -- POP 인증 오류" - text_body_template: | - POP서버에서 메일을 가져오는데 인증 오류가 발생했습니다. - - POP 인증정보를 제대로 입력했는지 확인해주세요. [사이트 설정](%{base_url}/admin/site_settings/category/email). too_many_spam_flags: subject_template: "새로운 계정은 블락되었습니다." text_body_template: | @@ -1345,32 +1290,10 @@ ko: 추가적인 조언은 [커뮤니티 가이드라인](%{base_url}/guidelines)에서 확인하실 수 있습니다. blocked_by_staff: subject_template: "계정이 블락" - text_body_template: | - 안녕하세요, - - %{site_name}에서 이 계정이 스태프에 의해 블락되었음을 알리는 자동 메세지 입니다. - - 추가적인 조언은 [community guidelines](%{base_url}/guidelines)에서 확인하실 수 있습니다. user_automatically_blocked: subject_template: "%{username} 신규가입자가 커뮤니티 신고로 블락됨" - text_body_template: | - 자동 생성 메세지입니다. - - 새 사용자 [%{username}](%{base_url}%{user_url})님이 여러 사용자가 %{username}님의 글(들)을 신고하여 자동으로 블락되었습니다. - - [신고 접수](%{base_url}/admin/flags) 확인 바랍니다. %{username}님이 잘못 블락 되었으면, [사용자 관리 페이지](%{base_url}%{user_url})에서 블락해제해 주세요. - - `block_new_user` 사이트 설정을 변경해 쓰레솔드를 바꿀 수 있습니다. spam_post_blocked: subject_template: "%{username} 신규가입자가 연속 링크로 블락됨" - text_body_template: | - 자동 생성 메세지입니다. - - 새 사용자 [%{username}](%{base_url}%{user_url})님이 %{domains} 링크로 여러 글을 올려서 스팸이 의심되어 블락되었습니다. 다만, 이 사용자는 %{domains} 링크가 없는 글은 계속 올릴 수 있습니다. - - [사용자 관리 페이지](%{base_url}%{user_url})에서 확인 바랍니다. - - 이는 `newuser_spam_host_threshold`와 `white_listed_spam_host_domains` 사이트 설정으로 변경할 수 있습니다. unblocked: subject_template: "계정 블락 해제" text_body_template: | @@ -1396,84 +1319,19 @@ ko: unsubscribe: title: "구독해지" description: "이메일들에 관심이 없나요? 아래 구독해지를 눌러서 바로 구독을 해지할 수 있습니다:" - reply_by_email: "응답하시려면 %{base_url}%{url} 를 방문하시거나 이메일에 답장하세요." - visit_link_to_respond: "응답하시려면 %{base_url}%{url} 를 방문하세요." posted_by: "%{username} 사용자가 %{post_date}에 게시하였습니다." user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} 회원님이 '%{topic_title}' 글타래에 초대했습니다" - text_body_template: |2 - - %{username} 회원님이 메세지에 초대했습니다. - - > **%{topic_title}** - > - > %{topic_excerpt} - - 사이트: - - > %{site_title} -- %{site_description} - - %{base_url}%{url} 로 들어가서 메세지를 확인하기 - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} 회원님이 '%{topic_title}' 글타래에 초대했습니다." - text_body_template: |2 - - %{username} 회원님이 토의에 초대하였습니다. - - > **%{topic_title}** - > - > %{topic_excerpt} - - 사이트: - - > %{site_title} -- %{site_description} - - 메세지 링크: %{base_url}%{url} user_replied: subject_template: "[%{site_name}] '%{topic_title}'에 답글이 달렸습니다" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{username}님께서 '%{topic_title}' 글타래에 당신을 인용하였습니다" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{username}님께서 '%{topic_title}'에서 당신을 언급하였습니다" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{subject_prefix} '%{topic_title}'에 새로운 글이 등록되었습니다" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "%{last_seen_at}부터 지금까지 %{site_link} 사이트 근황" subject_template: "[%{site_name}] 근황" @@ -1518,12 +1376,6 @@ ko: 비밀번호 설정 페이지: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] 이메일 확인" - text_body_template: | - %{site_name} 사이트에서 사용할 새로운 이메일을 아래 링크를 클릭하여 확인하세요: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "당신은 %{site_name} 가입이 승인되었습니다!" text_body_template: | @@ -1552,7 +1404,6 @@ ko: 만약 위의 링크를 클릭 할 수 없으면 주소를 복사하여 당신의 웹브라우저에 붙여넣으세요. page_not_found: - title: "당신이 요청한 페이지를 찾을 수 없습니다. 혹시 아래와 같은 글타래를 찾으신 것은 아닌가요?" popular_topics: "인기" recent_topics: "최근" see_more: "더" @@ -1622,3 +1473,8 @@ ko: performance_report: initial_post_raw: 이 글타래는 웹사이트의 일일 성능 보고를 포함하고 있습니다. initial_topic_title: 웹사이트 성능 보고 + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.nb_NO.yml b/config/locales/server.nb_NO.yml index 86e266e1efa..a9527735a40 100644 --- a/config/locales/server.nb_NO.yml +++ b/config/locales/server.nb_NO.yml @@ -16,12 +16,10 @@ nb_NO: loading: "Laster" powered_by_html: 'Drevet av Discourse, best nyttet med JavaScript på' log_in: "Logg inn" - via: "%{username} via %{site_name}" - is_reserved: "er reservert" purge_reason: "Automatisk slettet som som forlatt, uaktivert konto" disable_remote_images_download_reason: "Nedlasting av bilder ble deaktivert grunnet mangel på tilgjengelig diskplass." anonymous: "Anonym" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "er begrenset til %{max} karakterer; du brukte %{length}." @@ -37,8 +35,10 @@ nb_NO: exclusion: er reservert greater_than: må være større enn %{count} greater_than_or_equal_to: må være lik eller større enn %{count} + has_already_been_used: "har allerede blitt brukt" inclusion: er ikke inkludert i listen invalid: er ugyldig + is_invalid: "er ugyldig; prøv å være litt mer beskrivende" less_than: må være mindre enn %{count} less_than_or_equal_to: må være lik eller mindre enn %{count} not_a_number: er ikke et nummer @@ -65,6 +65,8 @@ nb_NO: other: '%{count} feil forhindret lagring av %{model}' embed: load_from_remote: "Det oppstod et problem med innlastingen av innlegget." + site_settings: + min_username_length_range: "Du kan ikke sette minimum høyere enn maksimum." bulk_invite: file_should_be_csv: "Den opplastede filen må være i .csv eller .txt format." backup: @@ -75,6 +77,7 @@ nb_NO: not_found: "Den etterspurte URL eller ressurs ble ikke funnet" invalid_access: "Du har ingen tilgang til denne resurssen." read_only_mode_enabled: "Siden er i skrivebeskyttet modus. Alle interaksjoner er utilgjengelige." + likes: "Likes" too_many_replies: one: "Vi beklager, men nye brukere er midlertidig begrenset til 1 svar i det samme emnet." other: "Vi beklager, men nye brukere er midlertidig begrenset til %{count} svar i det samme emnet." @@ -91,26 +94,6 @@ nb_NO: replies: one: "1 svar" other: "%{count} svar" - too_many_mentions: - zero: "Beklager, du kan ikke nevne andre brukere." - one: "Beklager, du kan bare nevne én annen bruker i et innlegg." - other: "Beklager, du kan bare nevne %{count} brukere i et innlegg." - too_many_mentions_newuser: - zero: "Beklager, nye brukere kan ikke nevne andre brukere." - one: "Beklager, nye brukere kan bare nevne én annen bruker i et innlegg." - other: "Beklager, nye brukere kan bare nevne %{count} brukere i et innlegg." - too_many_images: - zero: "Beklager, nye brukere kan ikke legge til bilder i et innlegg." - one: "Beklager, nye brukere kan bare legge til 1 bilde i et innlegg." - other: "Beklager, nye brukere kan bare legge til %{count} bilder i et innlegg." - too_many_attachments: - zero: "Beklager, nye brukere kan ikke laste opp vedlegg til et innlegg." - one: "Beklager, nye brukere kan bare laste opp 1 vedlegg til et innlegg." - other: "Beklager, nye brukere kan bare laste opp %{count} vedlegg til et innlegg." - too_many_links: - zero: "Beklager, nye brukere kan ikke legge til lenker i et innlegg." - one: "Beklager, nye brukere kan bare legge inn en lenke per innlegg." - other: "Beklager, nye brukere kan bare legge til %{count} lenker i et innlegg." spamming_host: "Beklager, du kan ikke lenke til det domenet." user_is_suspended: "Utviste brukere kan ikke skrive innlegg." topic_not_found: "Noe gikk galt. Kanskje emnet har blitt lukket eller slettet samtidig som du har sett på det?" @@ -156,6 +139,16 @@ nb_NO: until_posts: one: "1 innlegg" other: "%{count} innlegg" + new-topic: | + Velkommen til %{site_name} — **takk for at du startet et nytt innlegg!** + + - Høres tittelen på innlegget interessant ut hvis du leser det høyt? Er det en god oppsummering? + + - Hvem vil være interessert i dette? Hvorfor betyr det noe? Hva slags respons er du ute etter? + + - Bruk relevante begreper i emnet så andre kan *finne* det. Venligst velg en kategori for å gruppere emnet ditt med andre liknende emner. + + [Se våre retningslinjer](/guidelines) for mer informasjon. Denne meldingen vises kun for ditt første %{education_posts_text}. new-reply: | Velkommen til %{site_name} — **takk for bidraget!** @@ -201,9 +194,6 @@ nb_NO: user_profile: bio_raw: "Om meg" errors: - messages: - is_invalid: "er ugyldig; prøv å være litt mer beskrivende" - has_already_been_used: "har allerede blitt brukt" models: topic: attributes: @@ -224,6 +214,7 @@ nb_NO: attributes: hex: invalid: "er ikke en gyldig farge" + <<: *errors user_profile: no_info_me: "
    Om meg-feltet på din profil er for øyeblikket blankt, ønsker du å fylle det ut?
    " no_info_other: "
    %{name} har ikke skrevet noe i Om meg-feltet på sin profil ennå
    " @@ -259,7 +250,6 @@ nb_NO: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Om kategorien %{category} " - replace_paragraph: "[Erstatt dette første avsnittet med en kort beskrivelse av din nye kategori. Denne veiledningen vil vises i kategorivelgeren så prøv å hold den kortere enn 200 tegn. Frem til du redigerer denne teksten eller oppretter emner vil ikke denne kategorien vises på kategorisiden.]" errors: uncategorized_parent: "Ukategorisert kan ikke ha en foreldrekategori" self_parent: "En underkategori kan ikke være underlagt seg selv" @@ -276,14 +266,9 @@ nb_NO: title: "ny bruker" basic: title: " bruker" - regular: + member: title: "medlem" - leader: - title: "trofast" - elder: - title: "leder" rate_limiter: - slow_down: "Du har utført denne handlingen for mange ganger. Prøv igjen senere." too_many_requests: "Vi har en daglig begrensning for hvor mange ganger den handlingen kan utføres. Venligst vent %{time_left} før du prøver igjen." hours: one: "1 time" @@ -401,16 +386,11 @@ nb_NO: description: 'Dette innlegget har innhold som for en fornuftig person vil kunne være fornærmende, nedverdigende eller brudd på retningslinjene til dette nettsamfunnet.' long_form: 'markerte dette som upassende' notify_user: - title: 'Send melding til @{{username}}' - description: 'Dette innlegget inneholder noe jeg ønsker å ta opp med vedkommende direkte på privaten. Oppretter ikke en markering.' long_form: 'sendt melding til bruker' email_title: 'Ditt innlegg i "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Noe annet" - description: 'Dette innlegget trenger moderator oppmerksomhet for en annen grunn enn listet over.' - long_form: 'merket for moderators oppmerksomhet' - email_title: 'Et innlegg i "%{title}" krever moderator oppmerksomhet' email_body: "%{link}\n\n%{message}" bookmark: title: 'Bokmerke' @@ -435,7 +415,6 @@ nb_NO: long_form: 'markerte dette som upassende' notify_moderators: title: "Noe annet" - description: 'Dette emnet krever moderators oppmerksomhet basert på retningslinjene, TOS, eller en annen grunn ikke listet over. ' long_form: 'Markert for mederering' email_title: 'Emne "%{title}" krever moderator oppmerksomhet' email_body: "%{link}\n\n%{message}" @@ -471,6 +450,8 @@ nb_NO: title: "nye brukere" xaxis: "Dag" yaxis: "Antall nye brukere" + profile_views: + xaxis: "Dag" topics: title: "Emner" xaxis: "Dag" @@ -602,32 +583,6 @@ nb_NO: host_names_warning: "Din config/database.yml fil bruker standard localhost hostnavn. Venligst legg inn ditt ønskede hostnavn" memory_warning: 'Serveren din kjører med mindre enn 1 GB med minne. Minst 1 GB RAM er anbefalt.' title_nag: "Oppgi navnet på nettstedet. Oppdater tittelen under Nettstedinstillinger." - content_types: - education_new_reply: - title: "Ny bruker utdanning: Første svar" - education_new_topic: - title: "Ny bruker utdanning: Første Emne" - usage_tips: - title: "Ny Bruker Guide" - description: "Brukerveiledning og nyttig informasjon for nye brukere" - welcome_user: - title: "Velkommen: Ny Bruker" - description: "En melding som automatisk sendes til alle nye brukere når de oppretter konto." - welcome_invite: - title: "Velkommen: Invitert Bruker" - login_required_welcome_message: - title: "Pålogging påkrevd: Velkommen Melding" - login_required: - title: "Pålogging påkrevd: Hjemmeside" - description: "Tekst som vil bli vist uautoriserte brukere når logg inn er påkrevd." - head: - title: "HTML head" - description: "HTML som vil bli satt inn i klammene. " - top: - title: "Toppen av siden" - bottom: - title: "Bunnen av siden" - description: "HTML som vil bli lagt til før tag. " site_settings: censored_words: "Ord som automatisk vil bli erstattet med ■■■■" delete_old_hidden_posts: "Auto-slett skjulte innlegg som er skjult i mer enn 30 dager." @@ -639,7 +594,6 @@ nb_NO: min_topic_title_length: "Minimum tillatt lengde for tittel i tegn" max_topic_title_length: "Maksimum tillatt lengde for innlegg i tegn" min_search_term_length: "Minimum lengde på søkeord i tegn" - uncategorized_description: "Beskrivelsen av denne ukategoriserte kategorien. La stå tom for ingen beskrivelse." allow_duplicate_topic_titles: "Tillat emner med lik, duplikat tittel." unique_posts_mins: "Hvor mange minutter før en bruker kan lage en post med det samme innholdet igjen" educate_until_posts: "Når bruker begynner å skrive på de første (n) innleggene, vis pop-up med opplæringspanelet for nye brukere i editoren." @@ -652,7 +606,6 @@ nb_NO: download_remote_images_to_local: "Konverter eksterne bilder ved å laste de ned lokalt, dette forhindrer ødelagte bilder." download_remote_images_threshold: "Minimum ledig diskplass for å kunne laste ned eksterne bilder (i prosent)" disabled_image_download_domains: "Eksterne bilder vil aldri bli lastet ned fra disse domenene (pipe-separert liste)." - ninja_edit_window: "Endring innen (n) sekunder etter oppretting av innlegg vil ikke lage ny versjon av innlegget." post_edit_time_limit: "Forfattere kan redigere eller slette innleggene sine (n) minutter etter opprettelse. Sett 0 for uendelig." edit_history_visible_to_public: "Alle kan se tidligere versjoner av et redigert innlegg. Hvis det er slått av kan kun stab se det." delete_removed_posts_after: "Innlegg som blir fjernet av forfatter blir automatisk slettet etter (n) timer. Sett til 0 og innleggene blir slettet øyeblikkelig." @@ -744,9 +697,6 @@ nb_NO: blank: "Må være til stede" email: blocked: "er ikke tillatt." - flags_reminder: - please_review: "Vennligst vurder dem." - post_number: "innlegg" flags_dispositions: agreed: "Takk for at du sier ifra. Vi er enig at det er et problem her og vi ser på saken." disagreed: "Takk for at du sier ifra. Vi skal se på det. " @@ -769,7 +719,15 @@ nb_NO: click_here: "trykk her" read_more: "Les Mer" more_topics_category: "Flere nye emner:" + account_created: + subject_template: "[%{site_name}] Din Nye Konto" + text_body_template: | + En ny konto ble registrert for deg på %{site_name} + + Trykk på følgende link for å velge et passord for kontoen din: + %{base_url}/users/password-reset/%{email_token} signup: + subject_template: "[%{site_name}] Bekreft din nye konto" text_body_template: | Velkommen til %{site_name}! @@ -806,3 +764,6 @@ nb_NO: csv_export: boolean_yes: "Ja" boolean_no: "Nei" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml index e359d44e127..041b874c979 100644 --- a/config/locales/server.nl.yml +++ b/config/locales/server.nl.yml @@ -10,18 +10,40 @@ nl: short_date_no_year: "D MMM" short_date: "D MMM YYYY" long_date: "D MMMM YYYY H:mm" + datetime_formats: &datetime_formats + formats: + short: "%d-%m-%Y" + short_no_year: "%-d %B" + date_only: "%B %-d, %Y" + date: + month_names: [null, januari, februari, maart, april, mei, juni, juli, augustus, september, oktober, november, december] + <<: *datetime_formats title: "Discourse" topics: "Topics" posts: "berichten" loading: "Laden" powered_by_html: 'Powered by Discourse, werkt het beste met JavaScript ingeschakeld' log_in: "Inloggen" - via: "%{username} via %{site_name}" - is_reserved: "is gereserveerd" purge_reason: "Automatisch verwijderd, account is nooit geactiveerd" disable_remote_images_download_reason: "Het downloaden van plaatjes is uitgeschakeld omdat er niet genoeg schijfruimte beschikbaar is." anonymous: "Anoniem" - errors: + emails: + incoming: + default_subject: "Inkomende email van %{email}" + errors: + empty_email_error: "Gebeurt wanneer de mail die wij ontvangen hebben leeg is." + no_message_id_error: "Gebeurt wanneer de mail geen 'Message-Id' header heeft." + auto_generated_email_error: "Gebeurt wanneer de 'voorrang' header is ingesteld op: lijst, ongewenst, bulk of automatisch auto_reply, of wanneer een andere header bevat: auto-submitted, auto-replied of auto-generated." + no_body_detected_error: "Gebeurt wanneer wij de body niet konden uitpakken en er geen bijlages zijn." + inactive_user_error: "Gebeurt wanneer de zender niet actief is." + blocked_user_error: "Gebeurt wanneer de zender is geblokkeerd." + bad_destination_address: "Gebeurt wanneer geen van de E-mail adressen in de To/Cc/Bcc velden gelijk zijn aan de geconfigureerde inkomende E-mail adressen." + strangers_not_allowed_error: "Gebeurt wanneer een gebruiker heeft geprobeerd een nieuw topic aan te maken in een categorie waar zijn geen lid van zijn." + insufficient_trust_level_error: "Gebeurt als een gebruiker heeft geprobeerd om een nieuw topic aan te maken in een categorie waarvoor hij niet het benodigde vertrouwensniveau heeft." + reply_user_not_matching_error: "Gebeurt wanneer een reactie kwam van een ander E-mail adres dan waar de notificatie was heen gestuurd. " + topic_not_found_error: "Gebeurt wanneer een reactie binnen kwam, maar het topic al is verwijdert." + topic_closed_error: "Gebeurt wanneer een reactie binnen kwam, maar het verwante topic is gesloten." + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "is beperkt tot %{max} tekens; je gebruikt %{length}." @@ -37,8 +59,10 @@ nl: exclusion: is gereserveerd greater_than: moet groter zijn dan %{count} greater_than_or_equal_to: moet groter zijn dan of gelijk zijn aan %{count} + has_already_been_used: "is al gebruikt" inclusion: komt niet voor in de lijst invalid: is ongeldig + is_invalid: "is ongeldig; probeer een betere omschrijving" less_than: moet minder zijn dan %{count} less_than_or_equal_to: moet minder zijn dan of gelijk zijn aan %{count} not_a_number: is niet een getal @@ -82,6 +106,8 @@ nl: not_found: "De opgevraagde URL of resource kan niet gevonden worden." invalid_access: "Je hebt geen permissie om de opgevraagde resource te bekijken." read_only_mode_enabled: "De site is in read only modus. Interactie is niet mogelijk." + reading_time: "leestijd" + likes: "'Vind ik leuks' " too_many_replies: one: "Sorry, nieuwe gebruikers mogen één reactie plaatsen in hetzelfde topic." other: "Sorry, nieuwe gebruikers mogen %{count} reacties plaatsen in hetzelfde topic." @@ -98,26 +124,26 @@ nl: replies: one: "1 reactie" other: "%{count} reacties" + no_mentions_allowed: "Sorry, je mag geen andere gebruikers noemen." too_many_mentions: - zero: "Sorry, je kan niet verwijzen naar andere leden." - one: "Sorry, je kan naar één ander lid verwijzen in een bericht." - other: "Sorry, je kan naar %{count} leden verwijzen in een bericht." + one: "Sorry, je mag slechts één andere gebruiker noemen in een post." + other: "Sorry, je mag slechts %{count} andere gebruikers noemen in een bericht." + no_mentions_allowed_newuser: "Sorry, nieuwe gebruikers mogen geen andere gebruikers noemen." too_many_mentions_newuser: - zero: "Sorry, nieuwe leden kunnen niet verwijzen naar andere leden." - one: "Sorry, nieuwe leden kunnen naar één andere lid verwijzen in een bericht." - other: "Sorry, nieuwe leden kunnen naar %{count} leden verwijzen in een bericht." + one: "Sorry, nieuwe gebruikers mogen slechts één andere gebruiker noemen in een post." + other: "Sorry, nieuwe gebruikers mogen slechts %{count} andere gebruikers noemen in een bericht." + no_images_allowed: "Sorry, nieuwe gebruikers mogen geen afbeeldingen plaatsen in een bericht." too_many_images: - zero: "Sorry, nieuwe leden kunnen geen afbeeldingen in een bericht opnemen." - one: "Sorry, nieuwe leden kunnen één afbeelding in een bericht opnemen." - other: "Sorry, nieuwe leden kunnen %{count} afbeeldingen in een bericht opnemen." + one: "Sorry, nieuwe gebruikers mogen slechts één afbeelding plaatsen in een post." + other: "Sorry, nieuwe gebruikers mogen slechts %{count} afbeeldingen plaatsen in een bericht." + no_attachments_allowed: "Sorry, nieuwe gebruikers mogen geen bijlages invoegen in een bericht." too_many_attachments: - zero: "Sorry, nieuwe leden kunnen geen bestanden in een bericht opnemen." - one: "Sorry, nieuwe leden kunnen één bestand in een bericht opnemen." - other: "Sorry, nieuwe leden kunnen %{count} bestanden in een bericht opnemen." + one: "Sorry, nieuwe gebruikers mogen slechts één bijlages invoegen in een post." + other: "Sorry, nieuwe gebruikers mogen slechts %{count} bijlages invoegen in een bericht." + no_links_allowed: "Sorry, nieuwe gebruikers mogen geen links plaatsen in een bericht." too_many_links: - zero: "Sorry, nieuwe leden kunnen geen links in een bericht opnemen." - one: "Sorry, nieuwe leden kunnen één link in een bericht opnemen." - other: "Sorry, nieuwe leden kunnen %{count} links in een bericht opnemen." + one: "Sorry, nieuwe gebruikers mogen slechts één link plaatsen in een post." + other: "Sorry, nieuwe gebruikers mogen slechts %{count} links plaatsen in een bericht." spamming_host: "Sorry, je kan niet linken naar die host." user_is_suspended: "Geschorste gebruikers mogen geen berichten meer plaatsen." topic_not_found: "Er is iets fout gegaan. Wellicht is het topic gesloten of verwijderd terwijl je er naar keek?" @@ -140,6 +166,7 @@ nl: rss_description: latest: "Nieuwste topics" hot: "Hot topics" + top: "Top topics" posts: "Nieuwste berichten" too_late_to_edit: "Dat bericht is lang geleden geschreven. Het kan niet meer gewijzigd of verwijderd worden." excerpt_image: "afbeelding" @@ -149,6 +176,7 @@ nl: errors: can_not_modify_automatic: "Je kunt automatische groepen niet wijzigen" member_already_exist: "'%{username}' is al lid van deze groep." + invalid_domain: "%{domain}' is geen geldig domein." default_names: everyone: "iedereen" admins: "admins" @@ -199,9 +227,9 @@ nl: Hou je in de gaten dat anderen ook de ruimte krijgen om hun visie te geven? too_many_replies: | - ### Je hebt de reactielimiet bereikt voor deze topic + ### Je hebt de reactielimiet voor deze topic bereikt - Sorry, maar nieuwe gebruikers mogen tijdelijk niet meer dan %{newuser_max_replies_per_topic} reacties plaatsen in hetzelfde topic. + Sorry, maar nieuwe gebruikers mogen tijdelijk niet meer dan %{newuser_max_replies_per_topic} reacties plaatsen in het desbetreffende topic. Overweeg een eerdere reactie te wijzigen in plaats van nog een nieuwe reactie te plaatsen. reviving_old_topic: | @@ -217,11 +245,8 @@ nl: post: raw: "Inhoud" user_profile: - bio_raw: "Over Mij" + bio_raw: "Over mij" errors: - messages: - is_invalid: "is ongeldig; probeer wat uitgebreider te zijn" - has_already_been_used: "is al gebruikt" models: topic: attributes: @@ -242,16 +267,17 @@ nl: attributes: hex: invalid: "is niet een geldige kleur" + <<: *errors user_profile: no_info_me: "
    Het Over Mij-profielveld is nog leeg, zou je deze willen invullen?
    " no_info_other: "
    %{name} heeft nog niks in zijn of haar Over Mij-profielveld ingevuld
    " vip_category_name: "Lounge" vip_category_description: "Een categorie exclusief voor leden met trust level 3 en hoger." - meta_category_name: "Over Deze Site" + meta_category_name: "Site Feedback" meta_category_description: "Discussies over deze site, de organisatie, hoe het werkt en hoe het verbeterd kan worden." staff_category_name: "Staf" staff_category_description: "Privécategorie voor stafgesprekken. Topics zijn alleen zichtbaar voor admins en moderatoren." - assets_topic_body: "Dit is een permanent topic, alleen zichtbaar voor de staf, gebruikt voor het opslaan van afbeeldingen en bestanden die gebruikt worden in het design van de site. Gooi deze niet weg!\n\n\nHoe te gebruiken:\n\n\n1. Antwoord op dit topic.\n2. Upload hier alle afbeeldingen die je wenst te gebruiken voor logo's, favicons enzovoort. (Gebruik het upload icoon in de toolbar of sleep danwel plak afbeeldingen.)\n3. Verzend je bericht om het te posten.\n4. Klik met de rechtermuisknop op de afbeeldingen in je nieuwe bericht om het pad naar de geüploade afbeelding te krijgen, of klik het bewerken icoon om je bericht te wijzigen en zo het pad naar de afbeeldingen te verkrijgen. Kopieer het pad naar de afbeeldingen.\n5. Plak deze paden naar de afbeeldingen in [basic settings](/admin/site_settings/category/required).\n\n\nAls je andere bestandstypen wilt kunnen uploaden, moet je dit instellen in `authorized_extensions` in de [file settings](/admin/site_settings/category/files)." + assets_topic_body: "Dit is een permanent topic, dat alleen zichtbaar is voor de staf, en dient als opslag voor afbeeldingen en documenten die worden gebruikt in het design van de site . Gooi deze niet weg!\n\n\nHoe het werkt:\n\n\n1. Antwoord op dit topic.\n2. Upload hier alle afbeeldingen die je wenst te gebruiken als logo's, favicons enzovoort. (Gebruik het upload icoon in de toolbar, sleep afbeeldingen, of plak afbeeldingen.)\n3. Verzend je bericht om het te posten.\n4. Klik met de rechtermuisknop op de afbeeldingen in je nieuwe bericht om het pad naar de geüploade afbeelding te verkrijgen, of klik het bewerken icoon om je bericht te wijzigen en zo het pad naar de afbeeldingen te verkrijgen. Kopieer het pad naar de afbeeldingen.\n5. Plak deze paden naar de afbeeldingen in [basic settings](/admin/site_settings/category/required).\n\n\nAls je andere bestandstypen wilt kunnen uploaden, moet je dit instellen in `authorized_extensions` in de [file settings](/admin/site_settings/category/files)." lounge_welcome: title: "Welkom in de Lounge" body: |2 @@ -277,35 +303,49 @@ nl: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Over de categorie %{category}" - replace_paragraph: "[Vervang deze eerste regel met een korte omschrijving van je nieuwe categorie. Deze regel verschijnt in het selectiemenu als iemand een categorie kiest, dus hou het kort (max. 200 tekens). Deze categorie zal niet in de lijst verschijnen totdat je deze tekst wijzigt of zelf een topic in de categorie plaatst.]" - post_template: "%{replace_paragraph}\n\nGebruik de volgende alinea's voor een lange omschrijving en om wat verwachtingen en regels van deze categorie uit te leggen.\n\nZaken waar je het over kan hebben in de reacties hieronder:\n\n- Waar is deze categorie voor? Waarom zouden mensen deze categorie moeten kiezen voor hun topic?\n\n- Waarin verschilt deze categorie van de andere categorien die we al hebben?\n\n- Hebben we deze categorie echt nodig?\n\n- Moeten we deze categorie samenvoegen met een andere categorie, of juist opsplitsen?\n" + replace_paragraph: "(Vervang deze eerste paragraaf met een korte beschrijving van je nieuwe categorie. Deze leidraad zal worden getoond in het categorie selectie scherm, dus probeer minder dan 200 karakters te gebruiken. **Totdat je deze beschrijving bewerkt of topics aanmaakt, zal deze categorie niet weergegeven worden op de pagina Categorieën.**)" + post_template: "%{replace_paragraph}\n\nGebruik de volgende paragrafen voor een langere beschrijving, of om categorierichtlijnen of regels vast te stellen:\n\n- Waarom zouden mensen deze categorie gebruiken? Waar dient het voor?\n\n- Op welke punten onderscheid het zich van andere categorieën die we al hebben?\n\n- Wat moet topics in deze categorie over het algemeen bevatten?\n\n- Hebben we deze categorie nodig? Kunnen we het samenvoegen met een andere categorie of subcategorie?\n" errors: uncategorized_parent: "Ongecategoriseerd kan geen bovenliggende categorie hebben" self_parent: "Een categorie kan niet zijn eigen bovenliggende categorie zijn" depth: "Je kan een subcategorie niet onder een andere subcategorie plaatsen" - email_in_already_exist: "Inkomend email-adres '%{email_in}' is al in gebruik voor '%{category_name}' categorie." cannot_delete: uncategorized: "De categorie Ongecategoriseerd kan niet verwijderd worden" - has_subcategories: "Deze categorie kan niet verwijderd worden, omdat deze subcategorieën heeft" + has_subcategories: "Deze categorie kan niet verwijderd worden, omdat deze subcategorieën bevat" topic_exists: one: "Categorie kan niet verwijderd worden omdat het 1 topic heeft. Het oudste topic is %{topic_link}." other: "Categorie kan niet verwijderd worden omdat het %{count} topics heeft. Het oudste topic is %{topic_link}." topic_exists_no_oldest: "Categorie kan niet verwijderd worden omdat het aantal topics %{count} is." + uncategorized_description: "Topics die geen categorie nodig hebben of niet in een andere bestaande categorie passen." trust_levels: newuser: title: "nieuw lid" basic: title: "lid" - regular: + member: title: "lid" + regular: + title: "Normaal" leader: - title: "vaste bezoeker" - elder: title: "leider" change_failed_explanation: "Je probeerde %{user_name} te degraderen naar '%{new_trust_level}'. Echter, het trustlevel is al '%{current_trust_level}'. %{user_name} blijft op trust level '%{current_trust_level}'. Als je de gebruiker wil degraderen, zet het trustlevel dan eerst vast." rate_limiter: - slow_down: "Je hebt deze actie te vaak uitgevoerd. Probeer het later nog een keer." + slow_down: "je hebt deze actie te vaak uitgevoerd, probeer het later nog eens." too_many_requests: "Er is een dagelijks limiet voor hoe vaak je dat kan doen. Wacht %{time_left} voordat je dit opnieuw probeert." + by_type: + first_day_replies_per_day: "Je hebt het maximum aantal reacties dat een nieuwe gebruiker op hun eerste dag kan creëren bereikt. Wacht %{time_left} voor je het opnieuw probeert ." + first_day_topics_per_day: "Je hebt het maximum aantal topics dat een nieuwe gebruiker op hun eerste dag kan creëren bereikt. Wacht %{time_left} voordat je het opnieuw probeert." + create_topic: "Je maakt te snel topics aan. Wacht %{time_left} voordat je het opnieuw probeert. " + create_post: "Je reageert te snel. Wacht %{time_left} voordat je het opnieuw probeert. " + delete_post: "Je verwijdert berichten te snel. Wacht %{time_left} voor je het opnieuw probeert." + topics_per_day: "Je hebt het maximum aantal nieuwe topics bereikt voor vandaag. Wacht %{time_left} voordat je het opnieuw probeert. " + pms_per_day: "Je hebt het maximum aantal berichten bereikt voor vandaag. Wacht a.u.b. %{time_left} voordat je het opnieuw probeert." + create_like: "Je hebt het maximum aantal likes voor vandaag bereikt. Wacht aub %{time_left} voordat je het opnieuw probeert." + create_bookmark: "Je hebt het maximum aantal bladwijzers voor vandaag bereikt. Wacht aub %{time_left} voordat je het opnieuw probeert." + edit_post: "Je hebt het maximum aantal bewerkingen voor vandaag bereikt. Wacht aub %{time_left} voordat je het opnieuw probeert." + live_post_counts: "Je vraagt te snel om het huidige aantal berichten. Wacht %{time_left} voor je het opnieuw probeert." + unsubscribe_via_email: "Je hebt het maximum aantal uitschrijvingen voor vandaag bereikt. Wacht aub %{time_left} voordat je het opnieuw probeert." + topic_invitations_per_day: "Je hebt het maximum aantal topic uitnodigingen bereikt voor vandaag. Wacht aub %{time_left} voordat je het opnieuw probeert." hours: one: "1 uur" other: "%{count} uren" @@ -425,15 +465,15 @@ nl: long_form: 'heeft dit als ongepast gemeld' notify_user: title: 'Stuur @{{username}} een bericht' - description: 'Dit bericht bevat iets waarover ik je graag persoonlijk en privé wil spreken. Dit zet geen vlag.' - long_form: 'een bericht gestuurd aan gebruiker ' - email_title: 'Uw bericht in ''%{title}''' + description: 'I wil praten met deze persoon direct en privé over hun bericht.' + long_form: 'bericht verstuurd aan gebruiker' + email_title: 'Je bericht in ''%{title}''' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Iets anders" - description: 'Dit bericht heeft de aandacht van een moderator nodig om een andere reden dan hier boven gespecificeerd.' + description: 'Dit bericht vereist actie van de moderator voor een reden die hier boven niet genoemd wordt.' long_form: 'heeft dit gemarkeerd voor moderatie' - email_title: 'Graag aandacht van een moderator voor een bericht in ''%{title}''' + email_title: 'De topic "%{title}" moet door een moderator worden bekeken' email_body: "%{link}\n\n%{message}" bookmark: title: 'Favoriet' @@ -454,11 +494,11 @@ nl: long_form: 'markeerde dit als spam' inappropriate: title: 'Ongepast' - description: 'Dit topic bevat inhoud dat iemand als beledigend, discriminerend of kwetsend kan ervaren. Ook kan het een overtreding van de regels zijn.' + description: 'Dit topic bevat inhoud die een gemiddeld persoon als beledigend, kwetsend, of als een overtreding van de regels zou beschouwen.' long_form: 'markeerde dit als ongepast' notify_moderators: title: "Iets anders" - description: 'Dit topic moet door een moderator bekeken worden. Dit vanwege de regels, voorwaarden of vanwege een andere reden.' + description: 'Dit topic moet door een staflid bekeken worden. Dit vanwege de regels, voorwaarden of vanwege een andere reden.' long_form: 'heeft dit gemarkeerd voor moderatie' email_title: 'De topic "%{title}" moet door een moderator worden bekeken' email_body: "%{link}\n\n%{message}" @@ -494,6 +534,10 @@ nl: title: "Nieuwe Gebruikers" xaxis: "Dag" yaxis: "Aantal leden" + profile_views: + title: "Gebruikersprofielen bekeken" + xaxis: "Dag" + yaxis: "Aantal gebruikersprofielen bekeken" topics: title: "Topics" xaxis: "Dag" @@ -623,7 +667,7 @@ nl: yaxis: "Aantal bezoeken" dashboard: rails_env_warning: "Je server draait in %{env} modus." - ruby_version_warning: "Je gebruikt een versie van Ruby 2.0.0 met problemen. Upgrade naar patch level 247 of later." + ruby_version_warning: "Je gebruikt een versie van Ruby 2.0.0 die wel vaker problemen geeft. Upgrade naar patch level 247 of later." host_names_warning: "Het bestand config/database.yml heeft localhost als standaard hostname. Verander dat in de hostname van je site." gc_warning: 'Je server gebruikt de standaard ruby garbage collection instellingen, en daarmee krijg je niet de beste prestaties. Lees deze topic over instellingen voor prestaties: Tuning Ruby and Rails for Discourse.' sidekiq_warning: 'Sidekiq draait niet. Veel taken, zoals het versturen van e-mails, worden asynchroon uitgevoerd door sidekiq. Zorg ervoor dat er altijd een sidekiq process draait. Hier is meer informatie over sidekiq.' @@ -636,6 +680,7 @@ nl: s3_config_warning: 'De server is geconfigureerd om bestanden naar S3 te uploaden, maar tenminste een van de volgende instellingen is niet opgegeven: s3_access_key_id, s3_secret_access_key of s3_upload_bucket. Ga naar de Instellingen en vul de waarden in. Zie "How to set up image uploads to S3?" voor meer informatie.' s3_backup_config_warning: 'De server is geconfigureerd om backups naar s3 toe te staan, maar op zijn minst een van de volgende instellingen is niet ingesteld: s3_access_key_id, s3_secret_access_key of s3_backup_bucket. Ga naar de Site Instellingen en stel deze in. Bekijk "How to set up image uploads to S3?" voor meer informatie.' image_magick_warning: 'De server is geconfigureerd om thumbnails te maken van grote afbeeldingen, maar ImageMagick is niet geïnstalleerd. Installeer ImageMagick met je favoriete package manager of download de laatste release.' + failing_emails_warning: 'Er zijn %{num_failed_jobs} e-mail jobs mislukt. Controleer in app.yml of de e-mailserver instelling correct zijn. Toon de mislukte jobs in Sidekiq.' default_logo_warning: "Stel de grafische logos voor je site in. Stel logo_url, logo_small_url, en favicon_url in in Site Instellingen." contact_email_missing: "Vul een site contact email adres in zodat je te bereiken bent voor dringende zaken aangaande je site. Stel deze in via Site Instellingen." contact_email_invalid: "De site contact email is ongeldig. Verander deze in Site Instellingen." @@ -644,52 +689,21 @@ nl: consumer_email_warning: "Je site is ingesteld om Gmail te gebruiken voor het versturen van mails. Gmail heeft limieten voor het aantal mails dat je kan versturen. Overweeg om een andere e-mailprovider te gebruiken om er zeker van te zijn dat mails aankomen." site_contact_username_warning: "Vul de naam in van een vriendelijke staf gebruikersaccount om belangrijke geautomatiseerde berichten vandaan te verzenden. Verander site_contact_username in Site Instellingen." notification_email_warning: "Notificatie e-mails worden niet verzonden van een geldig email-adres op je domein; email bezorging zal onberekenbaar en onbetrouwbaar zijn. Verander a.u.b. notification_email naar een geldig lokaal email adres in Site Instellingen." - content_types: - education_new_reply: - title: "Uitleg voor nieuw lid: Eerste reacties" - description: "Popup verschijnt automatisch als een nieuw lid zijn eerste twee reacties schrijft." - education_new_topic: - title: "Uitleg voor nieuwe leden: Eerste topics" - description: "Popup verschijnt automatisch als een nieuw lid zijn eerste twee topics schrijft." - usage_tips: - title: "Hulp voor nieuwe leden" - description: "Hulp en essentiële informatie voor nieuwe leden." - welcome_user: - title: "Welkom: Nieuw lid" - description: "Een boodschap welke automatisch naar alle nieuwe gebruikers verzonden wordt als ze zich inschrijven." - welcome_invite: - title: "Welkom: Uitgenodigd lid" - description: "Een boodschap welke automatisch naar alle nieuw uitgenodigde gebruikers wordt verzonden als ze ingaan op een uitnodiging van een andere gebruiker om deel te nemen." - login_required_welcome_message: - title: "Inloggen vereist: Welkomstbericht" - description: "Welcomstbericht dat getoond wordt aan uitgelogde gebruikers als 'login required' is ingesteld." - login_required: - title: "Inloggen nodig: Homepage" - description: "De tekst die getoond wordt als men moet inloggen om naar het forum te kunnen gaan." - head: - title: "HTML head" - description: "HTML wordt ingevoegd in de tags." - top: - title: "Bovenkant van de pagina's" - description: "HTML dat aan de bovenkant van alle pagina's wordt toegevoegd (na de header, voor de navigatie of topictitel)." - bottom: - title: "Onderkant van de pagina's" - description: "HTML welke toegevoegd wordt voor de tag." + subfolder_ends_in_slash: "Je submap setup is onjuist; de DISCOURSE_RELATIVE_URL_ROOT eindigt in een schuine streep." site_settings: censored_words: "Woorden welke automatisch vervangen zullen worden met ■■■■" delete_old_hidden_posts: "Auto-delete alle verborgen berichten die meer dan 30 dagen verborgen zijn." default_locale: "De standaard taal van dit Discourse forum (ISO 639-1 code)" allow_user_locale: "Gebruikers kunnen zelf een taal instellen voor de interface van de site" min_post_length: "Minimum lengte van een bericht in tekens" - min_first_post_length: "Minimale toegestane lengte voor de eerste post (topic body) in tekens" - min_private_message_post_length: "Minimale toegestane post lengte in tekens voor berichten" + min_first_post_length: "Minimale toegestane lengte voor het eerste bericht (topic body) in tekens" + min_private_message_post_length: "Minimale toegestane lengte in tekens voor berichten" max_post_length: "Maximum lengte van een bericht in tekens" min_topic_title_length: "Minimum lengte van een topictitel" max_topic_title_length: "Maximum lengte van een topictitel" min_private_message_title_length: "Minimale toegestane titel lengte in tekens voor berichten" min_search_term_length: "Minimum lengte van een zoekterm in tekens" allow_uncategorized_topics: "Topics zonder categorie toestaan. WAARSCHUWING: Alle topics moet weer aan een categorie zijn toegekend voor dit wordt uitgezet." - uncategorized_description: "De omschrijving voor de ongecategoriseerde categorie. Laat blanco voor geen omschrijving." allow_duplicate_topic_titles: "Sta topics met dezelfde titels toe" unique_posts_mins: "Hoeveel minuten iemand moet wachten voordat deze een bericht met dezelfde inhoud mag plaatsen" educate_until_posts: "Laat de popup voor nieuwe gebruikers zien als een gebruiker start met het typen van hun eerste (n) nieuwe berichten in de berichtopsteller." @@ -702,7 +716,7 @@ nl: download_remote_images_to_local: "Download externe afbeeldingen en sla ze lokaal op. Dit voorkomt dat afbeeldingen niet meer beschikbaar zouden kunnen worden." download_remote_images_threshold: "Minimum schijfruimte vereist om externe afbeeldingen lokaal te downloaden (percentage)" disabled_image_download_domains: "Externe afbeeldingen zullen nooit gedownload worden van deze domeinen. Pipe-gescheiden lijst." - ninja_edit_window: "Hoe snel je een aanpassing kan maken zonder dat er een nieuwe versie wordt opgeslagen, in (n) seconden." + editing_grace_period: "De eerste (n) seconden na het plaatsen van een bericht leidt het wijzigen ervan niet tot een nieuwe versie in de geschiedenis van het bericht." post_edit_time_limit: "Berichten mogen na (n) minuten nog gewijzigd of verwijderd worden door de schrijver. Gebruik 0 voor onbeperkt." edit_history_visible_to_public: "Sta toe dat iedereen vorige versies van een gewijzigd bericht kan zien. Als dit uit staat kunnen alleen stafleden dit zien." delete_removed_posts_after: "Berichten verwijderd door de auteur zullen automatisch verwijderd worden na (n) uur. Als dit ingesteld is op 0 zullen berichten direct verwijderd worden." @@ -712,7 +726,7 @@ nl: show_subcategory_list: "Laat subcategorielijst zien in plaats van de topiclijst bij het openen van een categorie." fixed_category_positions: "Indien aangevinkt kun je categorieën in een vaste volgorde arrangeren. Indien uitgevinkt zullen de categorieeen gesorteerd worden op activiteit." fixed_category_positions_on_create: "Indien aangevinkt wordt de categorie volgorde aangehouden in het menu voor nieuwe topics (vaste-categorie-posities vereist)." - add_rel_nofollow_to_user_content: "Voeg 'rel nofollow' toe aan alle ingediende gebruikers-content, behalve voor interne links (inclusief parent domeinen). Als je dit verandert moet je ook alle berichten rebaken met: \"rake posts:rebake\"" + add_rel_nofollow_to_user_content: "Voeg 'rel nofollow' toe aan alle ingediende gebruikerscontent, behalve voor interne links (inclusief bovenliggende domeinen). Als je dit verandert, moet je ook alle berichten opnieuw renderen met: \"rake posts:rebake\"" exclude_rel_nofollow_domains: "Een lijst van domeinen waar ´nofollow´ niet aan de links moet worden toegevoegd. (voorbeelddomein.com staat automatisch sub.voorbeelddomein toe). Voeg minimaal het 'top-level' domein van deze site toe om web crawlers alle content te laten vinden. Als delen van deze site zich op andere domeinen bevinden, voeg deze eveneens toe." post_excerpt_maxlength: "Maximale lengte van een uittreksel / samenvatting van een bericht." post_onebox_maxlength: "Maximale lengte van een 'oneboxed Discourse' bericht in tekens." @@ -732,7 +746,7 @@ nl: summary_likes_required: "Minimum aantal Likes in een topic voor weergave ´Samenvatting Topic´" summary_percent_filter: "Als iemand op 'Samenvatting Topic' klikt, laat dan de top % van de berichten zien" summary_max_results: "Maximaal aantal berichten in weergave ´Samenvatting Topic´" - enable_private_messages: "Sta toe dat trust level 1 gebruikers berichten kunnen maken en kunnen antwoorden op berichten" + enable_private_messages: "Sta toe dat vertrouwensniveau 1 (configureerbaar via min vertrouwensniveau om berichten te versturen) gebruikers berichten mogen maken en mogen antwoorden op berichten" enable_long_polling: "De 'message bus' die gebruikt wordt voor notificaties kan 'long polling' gebruiken." long_polling_base_url: "Basis URL voor ´long polling´ (indien via een CDN dynamische content wordt toegepast, kies hier dan 'origin pull´) b.v. http://originele.website.com" long_polling_interval: "De hoeveelheid tijd die de server zou moeten wachten voordat het clients beantwoord als er geen data te verzenden is (alleen voor ingelogde gebruikers)" @@ -751,8 +765,10 @@ nl: notify_mods_when_user_blocked: "Als een gebruiker automatisch geblokkeerd is, stuur dan een bericht naar alle moderatoren." flag_sockpuppets: "Als een nieuwe gebruiker antwoord op een topic vanaf hetzelfde ip-adres als de nieuwe gebruiker die het topic opende, markeer dan beide berichten als potentiële spam." traditional_markdown_linebreaks: "Gebruik traditionele regeleinden in Markdown, welke 2 spaties aan het einde van een regel nodig heeft voor een regeleinde." + allow_html_tables: "Sta toe dat tabellen in Markdown mogen worden ingevoerd met behulp van HTML-tags. TABLE, TD, TR, TH zullen aan de whitelist worden toegevoegd (vereist volledig herbouwen van alle oude berichten met tabellen)" post_undo_action_window_mins: "Het aantal minuten waarin gebruikers hun recente acties op een bericht nog terug kunnen draaien (liken, markeren, etc)." must_approve_users: "Stafleden moeten alle nieuwe gebruikersaccounts goedkeuren voordat ze de site mogen bezoeken. OPGELET: als dit wordt aangezet voor een actieve site wordt alle toegang voor bestaande niet stafleden ingetrokken." + pending_users_reminder_delay: "Stuur moderators een bericht als nieuwe gebruikers al langer dan dit aantal uren op goedkeuring wacht. Stel in op -1 om notificaties uit te schakelen." ga_tracking_code: "Google analytics (ga.js) trackingcode, bijv. UA-12345678-9; zie: http://google.com/analytics" ga_domain_name: "Google analytics (ga.js) domeinnaam, bijv. mijnsite.nl; zie http://google.com/analytics" ga_universal_tracking_code: "Google Universal Analytics (analytics.js) trackingcode, bijv. UA-12345678-9; zie http://google.com/analytics" @@ -761,6 +777,7 @@ nl: enable_noscript_support: "Ondersteun <noscript> tag" allow_moderators_to_create_categories: "Moderators mogen nieuwe categorieën maken" cors_origins: "Toegestane domeinen voor ´cross-origin requests´ (CORS). Elk domein moet http:// of https:// bevatten. De DISCOURSE_ENABLE_CORS omgevingsvariabele moet staan ingesteld op ´WAAR´ om CORS te kunnen gebruiken." + use_admin_ip_whitelist: "Admins kunnen alleen inloggen vanaf een IP-adres dat is gedefinieerd in de gescreende IP-lijst (Beheer > Logs > Gescreende IP's)" top_menu: "Bepaal de volgorde en selectie van items in het hoofdmenu. Bijvoorbeeld latest|new|unread|categories|top|read|posted|bookmarks" post_menu: "De volgorde en selectie van items in het berichtmenu. Bijvoorbeeld like|edit|flag|delete|share|bookmark|reply" post_menu_hidden_items: "De menu-items die standaard verborgen moeten worden in het post menu totdat er op de uitbreidings-ellips is geklikt." @@ -772,14 +789,15 @@ nl: suppress_reply_directly_above: "Verberg de uitklapbare 'in antwoord op' knop bij een bericht als er maar één reactie direct boven staat." suppress_reply_when_quoting: "Verberg de uitklapbare 'in antwoord op' knop bij een bericht als er er gequoteerd is." max_reply_history: "Maximaal aantal uit te klappen antwoorden als een 'in antwoord op' uitgeklapt wordt." - experimental_reply_expansion: "Verberg tussenliggende antwoorden als een antwoord uitgeklapt wordt (experimenteel)" topics_per_period_in_top_summary: "Aantal topics in het top-topics overzicht" topics_per_period_in_top_page: "Aantal topics in het uitgeklapte ´Meer...´ top-topics overzicht" redirect_users_to_top_page: "Stuur nieuwe en lang-niet-geziene gebruikers door naar de top-pagina" + top_page_default_timeframe: "Standaard tijdspanne voor de top overzicht pagina." show_email_on_profile: "Laat e-mail van gebruikers zien in hun profiel (alleen zichtbaar voor henzelf en staf)" email_token_valid_hours: "Wachtwoord vergeten / activeer account tokens zijn (n) uur geldig." email_token_grace_period_hours: "Wachtwoord vergeten / activeer account tokens zijn nog geldig gedurende een respijtperiode van (n) uur na het benutten." enable_badges: "Activeer het badgesysteem" + enable_whispers: "Sta private communicatie tussen medewerkers toe in een topic. (experimenteel)" allow_index_in_robots_txt: "Specificeer in robots.txt dat de site geïndexeerd mag worden door zoekmachines." email_domains_blacklist: "Een lijst van e-maildomeinen gescheiden door een vertikaal streepje (pipe), die niet worden toegestaan. Voorbeeld: mailingen.com|trashmail.net" email_domains_whitelist: "Een lijst van e-maildomeinen gescheiden door een vertikaal streepje (pipe), die zijn voorgeschreven om te worden toegelaten. WAARSCHUWING: Gebruikers met andere e-maildomeinen dan opgenomen in de lijst worden NIET toegelaten." @@ -797,6 +815,7 @@ nl: max_username_length: "Maximale lengte gebruikersnaam in karakters." reserved_usernames: "Gebruikersnamen waarvoor registratie niet is toegestaan." min_password_length: "Minimum lengte wachtwoord." + min_admin_password_length: "Minimale wachtwoordlengte voor de beheerder." block_common_passwords: "Accepteer geen wachtwoorden die voorkomen in de 10.000 meest voorkomende wachtwoorden." enable_sso: "Schakel single sign on in via een externe site (WAARSCHUWING: E-MAILADRESSEN VAN GEBRUIKERS '* MOETEN * DOOR DE EXTERNE SITE WORDEN GEVALIDEERD)" enable_sso_provider: "Pas Discourse SSO provider protocol toe op het /session/sso_provider eindpunt, vereist dat sso_secret is ingesteld" @@ -809,6 +828,7 @@ nl: sso_not_approved_url: "Stuur niet geaccepteerde SSO accounts door naar deze URL" enable_local_logins: "Accounts op basis van een lokale gebruikersnaam en wachtwoord toestaan. (Let op: dit moet aan staan voor toegang op basis van een uitnodiging.)" allow_new_registrations: "Nieuwe gebruikers registreren toestaan. Uitschakelen om te voorkomen dat iedereen een nieuw account kan maken." + enable_signup_cta: "Toon een notificatie aan terugkerende anonieme gebruikers waarin gevraagd wordt zich aan te melden voor een account." enable_yahoo_logins: "Zet inloggen met Yahoo! aan" enable_google_oauth2_logins: "Google Oauth2 authenticatie toestaan. Dit is de authenticatiemethode die momenteel door Google wordt ondersteund. Vereist key en secret." google_oauth2_client_id: "Client ID van je Google applicatie." @@ -816,6 +836,7 @@ nl: enable_twitter_logins: "Zet inloggen met Twitter aan. Hiervoor heb je een twitter_consumer_key en twitter_consumer_secret nodig." twitter_consumer_key: "consumer_key (registreer op dev.twitter.com)" twitter_consumer_secret: "consumer secret (registreer op dev.twitter.com)" + enable_instagram_logins: "Zet inloggen met Instagram aan. Hiervoor heb je een instagram_consumer_key and instagram_consumer_secret nodig" enable_facebook_logins: "Zet inloggen met Facebook aan. Hiervoor heb je een facebook_app_id en facebook_app_secret nodig." facebook_app_id: "app_id (registreer op https://developers.facebook.com/apps)" facebook_app_secret: "app_secret (registreer op https://developers.facebook.com/apps)" @@ -828,6 +849,8 @@ nl: backup_frequency: "Hoe vaak we een back-up van de site maken, in dagen." enable_s3_backups: "Upload voltooide back-ups naar S3. LET OP: Zorg ervoor dat je je S3 inloggegevens hebt ingevuld in de Bestanden instellingen." s3_backup_bucket: "De S3 bucket voor de backups. WAARSCHUWING: zorg er voor dat dit een privébucket is." + backup_time_of_day: "Tijdstip UTC wanneer de back-up moet plaatsvinden." + backup_with_uploads: "Uploads ook meenemen in de geplande back-ups. Deze optie uitschakelen zal alleen een back-up maken van de database." active_user_rate_limit_secs: "Hoe vaak we het 'last_seen_at'-veld updaten, in seconden." verbose_localization: "Uitgebreide localization tips weergeven in de gebruikersinterface." previous_visit_timeout_hours: "Hoe lang een bezoek duurt voordat we het als het 'vorige' bezoek beschouwen, in uren." @@ -843,6 +866,8 @@ nl: max_private_messages_per_day: "Het maximum aantal berichten dat een gebruiker per dag kan maken." max_invites_per_day: "Het maximum aantal uitnodigingen dat een gebruiker per dag kan versturen." max_topic_invitations_per_day: "Het maximum aantal uitnodigingen voor een topic dat een gebruiker per dag kan sturen." + alert_admins_if_errors_per_minute: "Aantal foutmeldingen per minuut waarbij de beheerder een melding krijgt. Een waarde van 0 schakelt deze mogelijkheid uit. LET OP: herstart vereist." + alert_admins_if_errors_per_hour: "Aantal foutmeldingen per uur waarbij de beheerder een melding krijgt. Een waarde van 0 schakelt deze mogelijkheid uit. LET OP: herstart vereist." suggested_topics: "Aantal aanbevolen topics onderaan een topic." limit_suggested_to_category: "Alleen topics van de huidige categorie weergeven in aanbevolen topics." clean_up_uploads: "Verwijder weesbestanden zonder referentie om illegale hosting te voorkomen. LET OP: maak een back-up van je /uploads directory voordat je deze instelling aanzet." @@ -857,6 +882,9 @@ nl: s3_region: "De naam van de Amazon S3 region die wordt gebruikt voor het uploaden van afbeeldingen." s3_cdn_url: "De CDN URL voor alle S3 assets (bijvoorbeeld: https://cdn.ergens.com). LETOP: na het wijzigen van deze instelling moeten je alle oude berichten rebaken." avatar_sizes: "Lijst van automatisch gegenereerde avatar groottes." + external_system_avatars_enabled: "Gebruik een avatars service van een extern systeem." + external_system_avatars_url: "URL van de avatars service van het externe systeem. Toegestande vervangingen zijn {username} {first_letter} {color} {size}" + default_opengraph_image_url: "URL van de standaard opengraph afbeelding." enable_flash_video_onebox: "Embedden van swf en flv (Adobe Flash) links toestaan in oneboxen. LET OP: dit kan onveilig zijn" default_invitee_trust_level: "Het standaard trustlevel (0-4) voor uitgenodigde leden." default_trust_level: "Het standaard trustlevel (0-4) voor alle nieuwe gebruikers. LET OP! Wijzigen van deze instelling geeft een serieus risico op spam." @@ -870,66 +898,185 @@ nl: tl2_requires_likes_received: "Hoeveel likes een lid moet ontvangen voordat deze naar trustlevel 2 gepromoveerd wordt." tl2_requires_likes_given: "Hoeveel likes een lid moet geven voordat deze naar trustlevel 2 gepromoveerd wordt." tl2_requires_topic_reply_count: "Op hoeveel topics een lid moet reageren voordat deze naar trustlevel 2 gepromoveerd wordt." - tl3_requires_days_visited: "Minimum aantal dagen dat een lid de site moet hebben bezocht in de laatste 100 dagen om in aanmerking te komen voor promotie naar trustlevel 3 (0 tot 100)" - tl3_requires_topics_replied_to: "Minimum aantal topics waarop een lid moet hebben gereageerd in de laatste 100 dagen om in aanmerking te komen voor promotie naar trustlevel 3 (0 of hoger)" - tl3_requires_topics_viewed: "Het percentage van topics gemaakt in de afgelopen 100 dagen dat een lid bekeken moet hebben om in aanmerking te komen voor promotie naar trustlevel 3. (0 to 100)" - tl3_requires_posts_read: "Het percentage van berichten gemaakt in de afgelopen 100 dagen dat een lid bekeken moet hebben om in aanmerking te komen voor promotie naar trustlevel 3. (0 to 100)" tl3_requires_topics_viewed_all_time: "Het minimum totaal aantal topics dat een lid moet hebben bekeken om te kwalificeren voor trustlevel 3." tl3_requires_posts_read_all_time: "Het minimum totaal aantal berichten dat een lid moet hebben bekeken om te kwalificeren voor trustlevel 3." - tl3_requires_max_flagged: "Van leden moeten minder dan x berichten gemarkeerd zijn door x verschillende leden in de afgelopen 100 dagen om in aanmerking te komen voor promotie naar trustlevel 3, waarbij x de waarde van deze instelling is. (0 of hoger)" tl3_promotion_min_duration: "Het minimum aantal dagen van de duur van een promotie naar trustlevel 3 voordat een lid kan worden gedegradeerd naar trustlevel 2." - tl3_requires_likes_given: "Het minimum aantal likes dat een lid moet hebben gegeven in de afgelopen 100 dagen om in aanmerking te komen voor promotie naar trustlevel 3." - tl3_requires_likes_received: "Het minimum aantal likes dat een lid moet hebben gekregen in de afgelopen 100 dagen om in aanmerking te komen voor promotie naar trustlevel 3." tl3_links_no_follow: "rel=nofollow niet verwijderen van links geplaatst door leden met trustlevel 3." min_trust_to_create_topic: "Het minimale trust level dat nodig is om een topic te mogen maken." min_trust_to_edit_wiki_post: "Het minimale trust level dat nodig is om een bericht te wijzigen dat als wiki gemarkeerd is." + min_trust_to_send_messages: "Het minimum vertrouwensniveau dat nodig is om nieuwe private berichten aan te maken." newuser_max_links: "Hoeveel links een nieuw lid in een bericht kan plaatsen." newuser_max_images: "Hoeveel afbeeldingen een nieuw lid in een bericht kan plaatsen." newuser_max_attachments: "Hoeveel bestanden een nieuw lid in een bericht kan plaatsen." newuser_max_mentions_per_post: "Het maximum aantal @naam notificaties dat een nieuw lid kan gebruiken in een bericht. " newuser_max_replies_per_topic: "Het maximum aantal reacties dat een nieuw lid kan maken in een enkel topic totdat iemand terug reageert." max_mentions_per_post: "Het maximum aantal @naam notificaties iedereen kan gebruiken in een bericht." + max_users_notified_per_group_mention: "Maximum aantal gebruikers dat een notificatie kan krijgen als een groep genoemd wordt (boven dit aantal worden er geen notificaties verstuurd)." + create_thumbnails: "Maak miniaturen en lightbox afbeeldingen die te groot zijn en niet in een post passen." + email_time_window_mins: "Wacht (n) minuten met verzenden van notificaties, geef gebruikers de kans om hun berichten te bewerken en af te ronden." + email_posts_context: "Hoeveel voorgaande antwoorden bijvoegen als context in de notificatie e-mails." + flush_timings_secs: "Hoe frequent we de timing data naar de server sturen, in seconden. " + title_max_word_length: "De maximum toegestane woordlengte, in letters, in een topic titel." + title_min_entropy: "De minimum entropie (unieke karakters, niet-Engels telt zwaarder) vereist voor een topic titel." + body_min_entropy: "De minimum entropie (unieke karakters, niet-Engels telt zwaarder) vereist voor de inhoud van een bericht." + allow_uppercase_posts: "Sta alleen hoofdletters toe in een topic titel of bericht inhoud." title_fancy_entities: "Converteer algemene ASCII-tekens naar fancy HTML in topictitels, zoals SmartyPants (http://daringfireball.net/projects/smartypants)" min_title_similar_length: "De minimale lengte die een titel van een topic moet hebben voordat er wordt gezocht naar vergelijkbare topics." min_body_similar_length: "De minimale lengte die de inhoud van een bericht moet hebben voordat er wordt gezocht naar vergelijkbare topics." category_colors: "Een lijst me hexadecimale kleurwaardes die gebruikt kunnen worden voor categorieën." + category_style: "Visuele stijl voor categorie badges." + max_image_size_kb: "De maximale grootte van te uploaden afbeeldingen in kB. Dit moet ook worden geconfigureerd in nginx (client_max_body_size) / apache of proxy." + max_attachment_size_kb: "De maximale grootte van te uploaden bijlages in kB. Dit moet ook worden geconfigureerd in nginx (client_max_body_size) / apache of proxy." authorized_extensions: "Een lijst met bestandsextensies die mogen worden geupload (gebruik '*' voor alle bestandsextensies)" + max_similar_results: "Hoeveel vergelijkbare topics om te laten zien boven de editor bij het opstellen van een nieuw topic. Vergelijking is gebaseerd op titel en inhoud." title_prettify: "Voorkom veel voorkomende fouten in titels (alles in hoofdletters, eerste woord zonder hoofdletter, meerdere ! en ?, een extra . aan het eind, etc." + topic_views_heat_low: "Na dit aantal keer bekeken zal het aantal keer bekeken veld licht gemarkeerd zijn." + topic_views_heat_medium: "Na dit aantal keer bekeken zal het aantal keer bekeken veld middelmatig gemarkeerd zijn." + topic_views_heat_high: "Na dit aantal keer bekeken zal het aantal keer bekeken veld sterk gemarkeerd zijn." + cold_age_days_low: "Na dit aantal dagen van een conversatie zal de laatste activiteit licht gedimd zijn." + cold_age_days_medium: "Na dit aantal dagen van een conversatie zal de laatste activiteit middelmatig gedimd zijn." + cold_age_days_high: "Na dit aantal dagen van een conversatie zal de laatste activiteit sterk gedimd zijn." + history_hours_low: "Bij een post die binnen dit aantal uur is bewerkt zal de de bewerk indicator licht gemarkeerd zijn." + history_hours_medium: "Bij een post die binnen dit aantal uur is bewerkt zal de de bewerk indicator middelmatig gemarkeerd zijn." + history_hours_high: "Bij een post die binnen dit aantal uur is bewerkt zal de de bewerk indicator sterk gemarkeerd zijn." + topic_post_like_heat_low: "Als de likes:post ratio dit ratio overschrijdt zal de veld met aantal posts licht gemarkeerd zijn." + topic_post_like_heat_medium: "Als de likes:post ratio dit ratio overschrijdt zal de veld met aantal posts middelmatig gemarkeerd zijn." + topic_post_like_heat_high: "Als de likes:post ratio dit ratio overschrijdt zal de veld met aantal posts sterk gemarkeerd zijn." faq_url: "Heb je je FAQ ergens extern staan, geef hier dan de volledige url op." tos_url: "Heb je je Algemene Voorwaarden ergens extern staan, geef hier dan de volledige url op." privacy_policy_url: "Heb je je Privacy Voorwaarden ergens extern staan, geef hier dan de volledige url op." newuser_spam_host_threshold: "Hoe vaak kan een gebruiker linken naar dezelfde host in hun `newuser_spam_host_posts` berichten voordat deze links als spam gezien worden." white_listed_spam_host_domains: "Een lijst met domeinen die niet op spam gecontroleerd worden. Nieuwe gebruikers kunnen ongelimiteerd links plaatsen naar deze domeinen." staff_like_weight: "Hoeveel zwaarder de weegfactor moet zijn voor likes gegeven door staf." + topic_view_duration_hours: "Tel een nieuw topic bekeken één keer per IP/Gebruiker elke N uur." + user_profile_view_duration_hours: "Tel een nieuw gebruikersprofiel bekeken één keer per IP/Gebruiker elke N uur." levenshtein_distance_spammer_emails: "Bij het matchen van spammer e-mails , het aantal verschillende karakters waarbij nog steeds een fuzzy match kan bestaan." max_new_accounts_per_registration_ip: "Als er al (n) accounts met trustlevel 0 zijn van een bepaald IP-adres (en geen daarvan is staflid of heeft een trustlevel 2 of hoger), stop met het accepteren van nieuwe aanmeldingen van dat IP-adres." - reply_by_email_enabled: "Ondersteuning voor antwoorden per e-mail." + min_ban_entries_for_roll_up: "Bij het klikken op de Roll up knop, maak een nieuwe subnet ban boeking aan als er tenminste (N) boekingen zijn." + max_age_unmatched_emails: "Verwijder niet-gekoppelde gecontroleerde e-mail boekingen na (N) dagen." + max_age_unmatched_ips: "Verwijder niet-gekoppelde gecontroleerde IP boekingen na (N) dagen." + num_flaggers_to_close_topic: "Minimun aantal unieke markeerders benodigd om geautomatiseerd een topic te pauzeren." + num_flags_to_close_topic: "Minimun aantal actieve markeerders benodigd om geautomatiseerd een topic te pauzeren." + auto_respond_to_flag_actions: "Automatisch antwoord Inschakelen op moment van weggooien van een markering." + min_first_post_typing_time: "Minimum tijd in milliseconden dat een gebruiker moet typen tijdens een eerste post, als de drempelwaarde niet wordt bereikt zal de post automatisch in de wachtrij voor goedkeuring gezet worden. Zet op 0 om uit te schakelen (niet aanbevolen)" + auto_block_fast_typers_on_first_post: "Blokkeer gebruikers automatisch als ze niet voldoen aan min_first_post_typing_time" + auto_block_fast_typers_max_trust_level: "Maximum vertrouwensniveau om snelle typers automatisch te blokkeren " + auto_block_first_post_regex: "Hoofdlettergevoelige regex die, indien een resultaat gevonden, de eerste post van een gebruiker zal blokkeren en in de wachtirj voor goedkeuring zal zetten. Bijvoorbeeld: raging|a[bc]a , zal alle posts die raging of aba of aca bevatten blokkeren. Geldt alleen voor eerste posts." + reply_by_email_enabled: "Mogelijk inschakelen om te antwoorden per e-mail." reply_by_email_address: "Template voor antwoorden per e-mail, bijvoorbeeld: %{reply_key}@reageer.mijnforum.nl" + disable_emails: "Voorkomt dat Discourse e-mails van welke soort dan ook verstuurd." + strip_images_from_short_emails: "Verwijder afbeeldingen met grootte van minder dan 2800 Bytes uit e-mails." + short_email_length: "Korte e-mail lengte in Bytes" + display_name_on_email_from: "Toon de volledige naam in het afzenderveld van e-mails." + unsubscribe_via_email_footer: "Voeg in de voettekst van verstuurde e-mails een link toe waarmee de ontvanger zich kan uitschrijven." + pop3_polling_enabled: "Poll via POP3 voor antwoorden per e-mail." + pop3_polling_ssl: "Gebruik SSL bij de verbinding naar de POP3 server. (Aanbevolen)" + pop3_polling_period_mins: "De periode in minuten tussen controleren van het POP3 account voor e-mail. LET OP: vereist een herstart." + pop3_polling_port: "Het portnummer om een POP3 account te pollen." + pop3_polling_host: "De servernaam om e-mail te pollen via POP3." + pop3_polling_username: "De gebruikersnaam van het te pollen POP3 account voor e-mail." + pop3_polling_password: "Het wachtwoord van het te pollen POP3 account voor e-mail." + log_mail_processing_failures: "Log alle e-mail verwerkingsfouten naar http://yoursitename.com/logs" + email_in: "Sta toe dat gebruikers een nieuw topic via e-mail (vereist het pollen van pop3). Configureer het adres in de \"Instellingen\" tabblad van elke categorie." email_in_min_trust: "Het minium trustlevel dat een gebruiker moet hebben om nieuwe topics te kunnen mailen." + email_prefix: "Het [label] gebruikt in het onderwerp van e-mails. Als standaard wordt 'titel' gebruikt als niet gezet." + email_site_title: "De titel van de website, wordt gebruikt als de naam van de afzender van e-mails van de website. Als standaard wordt 'titel' gebruikt als niets is ingesteld. Gebruik deze instelling als uw 'titel' karakters bevat die niet zijn toegestaan in een e-mail afzender tekst." + minimum_topics_similar: "Hoeveel topics moeten er aanwezig zijn voordat er vergelijkbare topics worden voorgesteld bij het opstellen van nieuwe topics." + relative_date_duration: "Na hoeveel dagen moet een post datum niet meer worden getoond als relatieve datum (7d) maar als absolute datum (20 feb)." delete_user_max_post_age: "Gebruikers wiens eerste bericht ouder dan (x) dagen is kunnen niet meer verwijderd worden." delete_all_posts_max: "Het maximaal aantal berichten dat ineens verwijderd kan worden met de 'Verwijder alle berichten'-knop. Als een gebruiker meer berichten heeft, kunnen de berichten niet in een keer verwijderd worden en kan de gebruiker dus niet verwijderd worden." username_change_period: "The number of days after registration that accounts can change their username (0 om wijziging niet toe te staan)." email_editable: "Gebruikers mogen hun e-mailadres na registratie nog wijzigen." + logout_redirect: "Stuur browser naar deze locatie na het uitloggen EG: (http://website.nl/uitloggen)" + allow_uploaded_avatars: "Sta gebruikers toe eigen profielfoto's te uploaden." + allow_animated_avatars: "Sta gebruikers toe gif animaties als profielfoto te gebruiken. WAARSCHUWING: draai de avatars:refresh rake task na het aanpassen van deze instelling. " + allow_animated_thumbnails: "Genereer bewegende miniaturen van bewegende gifs." + default_avatars: "URL's naar standaard te gebruiken avatars voor nieuwe gebruikers, totdat ze deze veranderen." + automatically_download_gravatars: "Download Gravatars voor gebruikers bij account creatie of aanpassing van email." digest_topics: "Het maximum aantal topics dat in de e-maildigest opgenomen wordt." digest_min_excerpt_length: "Hoeveel karakters er per bericht getoond worden in de mail digest" + delete_digest_email_after_days: "Blokkeer e-mails met periodieke samenvattingen voor gebruikers die al meer dan (n) dagen niet meer op de site zijn gezien." + disable_digest_emails: "Uitschakelen e-mails met korte verslagen voor alle gebruikers." + detect_custom_avatars: "Wel of niet te verifiëren of gebruikers eigen profielfoto's hebben geüpload. " + max_daily_gravatar_crawls: "Maximaal aantal keren op een dag dat Discourse Gravatar zal controleren voor aangepaste avatars" + public_user_custom_fields: "Een toegestane lijst van veldnamen voor een gebruiker dat publiekelijk kan worden getoond." + staff_user_custom_fields: "Een toegestane lijst van veldnamen voor een gebruiker dat aan medewerkers wordt getoond." + enable_user_directory: "Biedt een overzicht van gebruikers aan om door te bladeren." + allow_anonymous_posting: "Sta gebruikers toe naar de anonimiteitsmodus over te schakelen." + anonymous_posting_min_trust_level: "minimum vertrouwensniveau benodigd om anoniem posten in te kunnen schakelen." + anonymous_account_duration_minutes: "Ter bescherming van anonimiteit, maak een nieuw anonieme account aan elke N minuten voor elke gebruiker. Bijvoorbeeld: als ingesteld op 600 dan zal een nieuwe anonieme account worden aangemaakt als er 600 minuten zijn verstreken na het laatste bericht EN de gebruiker schakelt om naar anon." + hide_user_profiles_from_public: "Uitschakelen gebruikerskaarten, gebruikersprofielen en het gebruikersoverzicht voor anonieme gebruikers." allow_profile_backgrounds: "Gebruikers mogen een profielachtergrond instellen." + sequential_replies_threshold: "Aantal berichten dat een gebruiker achter elkaar in één topic moet plaatsen voordat hij een melding krijgt over te veel opeenvolgende reacties." enable_mobile_theme: "Mobiele apparaten gebruiken een mobiel-vriendelijke theme met de mogelijkheid te schakelen naar de volledige site. Schakel deze optie uit als je een eigen stylesheet wil gebruiken die volledig responsive is." + dominating_topic_minimum_percent: "Welk percentage van de berichten een gebruiker moet maken in een onderwerp voordat ze worden herinnerd aan het te veel domineren van een topic." + daily_performance_report: "Analyseer elke dag NGINX logs en post een Alleen Voor Medewerkers topic met de details" suppress_uncategorized_badge: "Laat de badge niet zien voor topics zonder categorie in de topiclijsten." global_notice: "Laat een LET OP, BELANGRIJK-banner zien aan alle gebruikers. Laat leeg om niet te tonen (HTML is toegestaan)." + disable_edit_notifications: "Schakelt bewerkingsnotificaties van de systeemgebruiker uit als 'download_remote_images_to_local' actief is." + automatically_unpin_topics: "Automatisch ont-pinnen van topics als de gebruiker onderaan de pagina komt." + full_name_required: "Volledige naam is een verplicht veld van het gebruikersprofiel." + enable_names: "Toon de volledige naam van de gebruiker op hun profiel, gebruikerskaart en e-mails. Scahkel uit om volledige naam overal te verbergen." display_name_on_posts: "Laat de volledige naam van een gebruiker bij zijn berichten zien, na de @gebruikersnaam" + show_time_gap_days: "Als twee berichten dit aantal dagen na elkaar zijn gemaakt zal een tijdsgat worden getoond in het topic." + invites_per_page: "Standaard uitnodigingen getoond op de gebruikerspagina." short_progress_text_threshold: "Als het aantal berichten in een topic meer is dan dit aantal zal de voortgangsbalk alleen het nummer van het huidige bericht tonen. Als je de breedte van de voortgangsbalk verandert, moet je dit getal misschien ook aanpassen." default_code_lang: "Standaard programmeertaal die gebruikt wordt voor syntax highlighting van GitHub codeblokken (lang-auto, ruby, python etc.)" + warn_reviving_old_topic_age: "Wanneer iemand begint met antwoorden op een topic waar het laatste antwoord ouder is dan dit aantal dagen, zal er een waarschuwing worden weergegeven. Kan worden uitsgechakeld door op 0 te zetten." + autohighlight_all_code: "Forceer het toepassen van code highlighting bij alle opgemaakte code blokken, zelfs als de codetaal niet expliciet is opgeven." + highlighted_languages: "Includeer de regels voor syntax highlighting. (Waarschuwing: het includeren van veel talen kan prestaties beïnvloeden) zie: https://highlightjs.org/static/demo/ voor een demonstratie." + feed_polling_enabled: "ALLEEN INSLUITEN: Het al of niet insluiten van een RSS / ATOM-feed als berichten." + feed_polling_url: "ALLEEN INSLUITEN: URL van de RSS/ATOM feed om in te sluiten." + embed_by_username: "Discourse gebruikersnaam van de gebruiker die de ingesloten topics aanmaakt." + embed_username_key_from_feed: "Sleutel waarmee de discourse gebruikersnaam uit de feed kan worden gehaald." embed_truncate: "Kort de geembedde berichten in" + embed_post_limit: "Maximum aantal in te sluiten posts." + embed_username_required: "De gebruikersnaam om topics aan te maken is vereist." + embed_whitelist_selector: "CSS-selector voor de elementen die zijn toegestaan in invoegberichten." + embed_blacklist_selector: "CSS-selector voor de elementen die zijn verwijderd uit invoegberichten." + notify_about_flags_after: "Als er vlaggen zijn die nog niet zijn afgehandeld na dit aantal uren, stuur dan een e-mail naar de contact_email. Zet op 0 om uit te schakelen." + enable_cdn_js_debugging: "Laat /logs juiste errors weergeven door crossorigin toestemmingen toe te voegen op alle js includes." + show_create_topics_notice: "Als de site minder dan 5 publieke topics heeft, toon dan een melding waarin admins gevraagd wordt om een aantal topics te creëren." + delete_drafts_older_than_n_days: Verwijder concepten ouder dan (n) dagen. + prevent_anons_from_downloading_files: "Voorkom dat anonieme gebruikers bijlagen mogen downloaden. WAARSCHUWING: hierdoor zullen website onderdelen, anders dan afbeeldingen, die zijn gepost als bijlage niet langer werken." + slug_generation_method: "Kies een slug generate methode. 'encoded' zal een percentage encoderen string genereren. 'none' zal slug helemaal uitschakelen." + enable_emoji: "Inschakelen emoji" + emoji_set: "Hoe wil je jouw emoji hebben?" + enforce_square_emoji: "Forceer een vierkant aspect ratio bij alle emojis." + approve_post_count: "Het aantal berichten van een nieuwe of normale gebruiker dat moet worden goedgekeurd" + approve_unless_trust_level: "Posts voor gebruikers onder dit vertrouwensniveau moeten worden goedgekeurd" + notify_about_queued_posts_after: "Als er posts zijn die meer dan dit aantal uren klaar staan om te worden beoordeeld, dan zal er een e-mail worden gestuurd naar het contact e-mail. Zet op 0 om deze e-mails uit te schakelen." + default_email_digest_frequency: "Hoe vaak ontvangen gebruikers standaard een samenvattings-e-mails." + default_email_private_messages: "Stuur standaard een e-mail als iemand de gebruiker bericht." + default_email_direct: "Stuur standaard een e-mail wanneer iemand de gebruiker citeert/beantwoordt/vermeldt of uitnodigt." + default_email_mailing_list_mode: "Stuur standaard een email voor elk nieuw bericht." + default_email_always: "Stuur standaard een e-mail notificatie, zelfs wanneer de gebruiker actief is." + default_other_new_topic_duration_minutes: "Globale standaard voorwaarde waarvoor een topic als nieuw wordt beschouwd." + default_other_auto_track_topics_after_msecs: "Globale standaard tijdbestek voordat een onderwerp automatisch wordt bijgehouden." + default_other_external_links_in_new_tab: "Open externe links standaard in een nieuw tabblad." + default_other_enable_quoting: "Citeer antwoord standaard inschakelen voor gemarkeerde tekst." + default_other_dynamic_favicon: "Toon standaard een teller van nieuwe/bijgewerkte topics op browser icoon." + default_other_disable_jump_reply: "Spring standaard niet naar de gebruiker post nadat ze hebben geantwoord." + default_other_edit_history_public: "Maak standaard de aanpassingen aan de post openbaar." + default_other_like_notification_frequency: "Stuur gebruikers standaard een bericht bij een like" + default_topics_automatic_unpin: "Standaard automatisch topics ontpinnen wanneer de gebruiker het einde van de pagina heeft bereikt." + default_categories_watching: "Lijst van categorieën die standaard worden bekeken." + default_categories_tracking: "Lijst van categorieën die standaard worden bijgehouden." + default_categories_muted: "Lijst van categorieën die standaard worden gedempt." errors: invalid_email: "Ongeldig e-mailadres." invalid_username: "Er is geen gebruiker met die gebruikersnaam." + invalid_integer_min_max: "Waarde moet tussen %{min} en %{max} liggen." invalid_integer_min: "Waarde moet minimaal %{min} zijn." invalid_integer_max: "Waarde kan maximaal %{max} zijn." invalid_integer: "Waarde moet een integer zijn." + regex_mismatch: "Waarde voldoet niet aan het vereiste formaat." + must_include_latest: "Top menu moet 'nieuwste' tabblad bevatten." invalid_string: "Ongeldige waarde." invalid_string_min_max: "Moet tussen %{min} en %{max} tekens zijn." invalid_string_min: "Moet te minste uit %{min} tekens bestaan." invalid_string_max: "Mag uit niet meer dan %{max} tekens bestaan." + invalid_reply_by_email_address: "Waarde moet '%{reply_key}' bevatten en moet afwijken van de e-mail notificatie." notification_types: mentioned: "%{display_username} heeft je genoemd in %{link}" liked: "%{display_username} vond je bericht in %{link} leuk" @@ -938,6 +1085,8 @@ nl: edited: "%{display_username} bewerkte je bericht in %{link}" posted: "%{display_username} heeft een bericht geplaatst in %{link}" moved_post: "%{display_username} verplaatste je bericht naar %{link}" + private_message: "%{display_username} heeft je een bericht gestuurd: %{link}" + invited_to_private_message: "%{display_username} heeft je uitgenodigd voor een bericht: %{link}" invitee_accepted: "%{display_username} heeft je uitnodiging geaccepteerd" linked: "%{display_username} heeft je gelinkt in %{link}" granted_badge: "%{link} is aan jou toegekend" @@ -954,14 +1103,45 @@ nl: redirected_to_top_reasons: new_user: "Welkom bij deze community! Dit zijn een aantal van de meest populaire topics." not_seen_in_a_month: "Welkom terug! We hebben je een tijdje niet gezien. Dit is een overzicht van de meest populaire topics die zijn gemaakt tijdens je afwezigheid." + move_posts: + new_topic_moderator_post: + one: "Een bericht is gesplitst naar een nieuw topic: %{topic_link}" + other: "%{count} berichten zijn gesplitst naar een nieuw topic: %{topic_link}" + existing_topic_moderator_post: + one: "Een bericht is samengevoegd in een bestaand topic: %{topic_link}" + other: "%{count} berichten zijn samengevoegd in een bestaand topic: %{topic_link}" change_owner: post_revision_text: "Eigendom overgezet van %{old_user} naar %{new_user}" + deleted_user: "een verwijderde gebruiker" + emoji: + errors: + name_already_exists: "Sorry, de naam '%{name}' is al in gebruik voor een andere emoji." + error_while_storing_emoji: "Sorry, fout opgetreden tijdens het opslaan van de emoji." topic_statuses: archived_enabled: "Deze topic is nu gearchiveerd en kan niet meer veranderd worden." archived_disabled: "Deze topic is niet langer gearchiveerd en kan weer veranderd worden." closed_enabled: "Deze topic is nu gesloten. Nieuwe reacties worden niet langer geaccepteerd." closed_disabled: "Deze topic is nu geopend. Nieuwe reacties worden weer geaccepteerd." + autoclosed_enabled_days: + one: "Dit topic is automatisch na één dag gesloten. Reageren is niet meer mogelijk." + other: "Dit topic is automatisch na %{count} dagen gesloten. Reageren is niet meer mogelijk." + autoclosed_enabled_hours: + one: "Dit topic is automatisch na één uur gesloten. Reageren is niet meer mogelijk." + other: "Dit topic is automatisch na %{count} uren gesloten. Reageren is niet meer mogelijk." + autoclosed_enabled_minutes: + one: "Dit topic is automatisch na één minuut gesloten. Reageren is niet meer mogelijk." + other: "Dit topic is automatisch na %{count} minuten gesloten. Reageren is niet meer mogelijk." + autoclosed_enabled_lastpost_days: + one: "Dit topic is automatisch gesloten één dag na het laatste antwoord. Reageren is niet meer mogelijk." + other: "Dit topic is automatisch gesloten %{count} dagen na het laatste antwoord. Reageren is niet meer mogelijk." + autoclosed_enabled_lastpost_hours: + one: "Dit topic is automatisch gesloten één uur na het laatste antwoord. Reageren is niet meer mogelijk." + other: "Dit topic is automatisch gesloten %{count} uren na het laatste antwoord. Reageren is niet meer mogelijk." + autoclosed_enabled_lastpost_minutes: + one: "Dit topic is automatisch gesloten één minuut na het laatste antwoord. Reageren is niet meer mogelijk." + other: "Dit topic is automatisch gesloten %{count} minuten na het laatste antwoord. Reageren is niet meer mogelijk." autoclosed_disabled: "Deze topic is geopend. Reageren is mogelijk." + autoclosed_disabled_lastpost: "Dit topic is nu geopend. Nieuwe reacties worden weer geaccepteerd." pinned_enabled: "Deze topic is nu vastgepind en zal bovenaan de categorie verschijnen totdat de pin door de staf voor iedereen of een gebruiker voor zichzelf verwijderd wordt." pinned_disabled: "Deze topic is niet langer gepind en zal niet meer bovenaan de lijst van topics in zijn categorie staan." pinned_globally_enabled: "Deze topic is nu globaal vastgepind en zal bovenaan de lijst van topics in zijn categorie en alle andere topiclijsten staan. Wanneer iemand op 'Verwijder pin' drukt, zal de topic voor diegene niet meer bovenaan staan." @@ -982,9 +1162,11 @@ nl: errors: "%{errors}" not_available: "Niet beschikbaar. Probeer %{suggestion}?" something_already_taken: "Er ging iets mis, misschien zijn de gebruikersnaam en/of e-mailadres al in gebruik? Gebruik dan de 'wachtwoord vergeten' link" + omniauth_error: "Sorry, er is iets mis gegaan met de bevestiging van je account. Misschien heb je de bevestiging niet geaccepteerd?" omniauth_error_unknown: "Er is iets misgegaan bij het inloggen. Probeer het opnieuw." new_registrations_disabled: "Het registeren van nieuwe accounts is niet toegestaan op dit moment." password_too_long: "Wachtwoorden mogen maximaal 200 tekens lang zijn." + email_too_long: "De e-mail die je hebt opgegeven is te lang. Mailbox namen mogen niet langer zijn dan 254 tekens, en domeinnamen niet langer dan 253 tekens." reserved_username: "Die gebruikersnaam is niet toegestaan." missing_user_field: "Je hebt niet alle velden ingevuld." close_window: "Authenticatie is voltooid. Sluit dit venster om verder te gaan." @@ -996,15 +1178,29 @@ nl: characters: "mag alleen nummers, letters en underscores bevatten" unique: "moet uniek zijn" blank: "mag niet leeg zijn" - must_begin_with_alphanumeric: "moet beginnen met een letter, cijfer of underscore" + must_begin_with_alphanumeric_or_underscore: "moet beginnen met een letter, een nummer of een laag streepje" + must_end_with_alphanumeric: "moet eindigen op een letter of een nummer" must_not_contain_two_special_chars_in_seq: "mag niet 2 of meer opvolgende speciale karakters bevatten (.-_)" - must_not_contain_confusing_suffix: "mag geen verwarrend achtervoegsel bevatten, zoals b.v.: .json of .png " + must_not_end_with_confusing_suffix: "mag niet eindigen op een verwarrend achtervoegsel zoals .json, .png etc." email: not_allowed: "is niet toegestaan vanaf die e-mailprovider. Gebruik een ander e-mailadres." blocked: "is niet toegestaan." ip_address: blocked: "Nieuwe registraties vanaf jouw IP-adres zijn niet toegestaan." max_new_accounts_per_registration_ip: "Nieuwe registraties vanaf jouw IP-adres zijn niet toegestaan (maximum limiet bereikt). Neem contact op met een staflid." + flags_reminder: + subject_template: + one: "Eén vlag af te handelen" + other: "%{count} vlaggen af te handelen" + unsubscribe_mailer: + text_body_template: | + Iemand (jij misschien?) heeft verzocht om op dit adres niet langer e-mails met nieuws van %{site_domain_name} te ontvangen. + Klik op de volgende link als je dit wil bevestigen: + + %{confirm_unsubscribe_link} + + + Als je deze e-mails wel wil blijven ontvangen, kan je deze e-mail negeren. invite_mailer: subject_template: "%{invitee_name} nodigt je uit voor '%{topic_title}' op %{site_domain_name}" text_body_template: | @@ -1037,109 +1233,58 @@ nl: %{invite_link} Deze uitnodiging is van een vertrouwde gebruiker, het is daarom niet nodig om in te loggen. + invite_password_instructions: + subject_template: "Geeft wachtwoord voor je %{site_name} account" + text_body_template: | + Bedankt voor het accepteren van je uitnodiging bij %{site_name} -- welkom! + + Klik deze link om nu een wachtwoord te kiezen: + %{base_url}/users/password-reset/%{email_token} + + (Als bovenstaande link is verlopen, kies dan "Ik ben mijn wachtwoord vergeten" tijdens het inloggen met je e-mail adres.) test_mailer: subject_template: "[%{site_name}] E-mail Bezorgtest" new_version_mailer: subject_template: "[%{site_name}] Nieuwe Discourse-versie, update beschikbaar" new_version_mailer_with_notes: subject_template: "[%{site_name}] Update beschikbaar" - flags_reminder: - please_review: "Kijk hier even naar." - post_number: "bericht" + queued_posts_reminder: + subject_template: + one: "[%{site_name}] 1 bericht wacht op beoordeling" + other: "[%{site_name}] %{count} berichten wachten op beoordeling" + text_body_template: | + Hallo, + + Er zijn berichten van nieuwe gebruikers die nog moeten worden beoordeeld. [Ze kunnen hier worden goedgekeurd of afgekeurd] (% {base_url}/queued-posts). + flag_reasons: + off_topic: "Je bericht is gemarkeerd als **off-topic**: de gemeenschap meent het niet goed past bij het onderwerp, zoals momenteel bepaald door de titel en de eerste post." + inappropriate: "Je bericht is gemarkeerd als **ongepast**: de gemeenschap vindt het bericht beledigend, grof, of een schending van [onze gemeenschapsrichtlijnen](/guidelines)." + spam: "Je bericht is gemarkeerd als **spam**: de gemeenschap vindt het bericht een reclame uiting, dat wil zeggen overdreven reclamerend van aard in plaats van nuttig of relevant voor het onderwerp zoals verwacht." + notify_moderators: "Je bericht is gemarkeerd als **voorleggen aan moderator**: de gemeenschap vindt dat er iets is met het bericht dat nagekeken moet worden." flags_dispositions: agreed: "Bedankt dat je het ons hebt laten weten. We zijn het er mee eens dat er een probleem is en we gaan er naar kijken." agreed_and_deleted: "Bedankt dat je het ons hebt laten weten. We zijn het er mee eens dat er een probleem is en we hebben het bericht verwijderd." disagreed: "Bedankt dat je het ons hebt laten weten. We gaan er naar kijken." deferred: "Bedankt dat je het ons hebt laten weten. We gaan er naar kijken." deferred_and_deleted: "Bedankt dat je het ons hebt laten weten. We hebben het bericht verwijderd." + temporarily_closed_due_to_flags: "Dit topic is tijdelijk gesloten vanwege een groot aantal vlaggen vanuit de gebruikersgroep" system_messages: post_hidden: subject_template: "Bericht van %{site_name}: je bericht is verborgen wegens meldingen uit de community" - usage_tips: text_body_template: | - Hier een paar snelle tips om je op weg te helpen: + Hallo, - ## Lezen + Dit is een automatisch bericht van %{site_name} om je te laten weten dat je bericht is verborgen. - Om verder te lezen, **gewoon door blijven scrollen naar beneden!** + %{base_url}%{url} - Als er nieuwe reacties zijn op een topic, verschijnen deze automatisch – het is niet nodig de pagina te verversen. + %{flag_reason} - ## Navigatie + Voordat dit bericht werd verborgen, hebben meerdere gebruikers het als ongewenst aangemeld. Denk er daarom goed over na hoe je je bericht aan de hand van hun commentaar aan kan passen. **Je kan je bericht na %{edit_delay} minuten wijzigen, waarna het automatisch weer zichtbaar wordt.** - - Voor zoeken, je profielpagina, of het menu, klik op de **icoontjes rechts boven**. + Maar als je bericht nogmaals door de gemeenschap wordt verborgen, blijft het verborgen tot een moderator of beheerder ernaar kijkt. Zij kunnen verder actie ondernemen, inclusief het mogelijk schorsen van je account. - - Het selecteren van een titel van een topic leid je altijd naar het **volgende ongelezen bericht** in de topic. Om naar het begin of eind van de topic te gaan, selecteer dan reacties of activiteit. - - - - - Bij het lezen van een topic, selecteer de voortgangsbalk rechts onder voor uitgebreide navigatie. Spring snel terug naar boven door de titel van de topic te selecteren. Druk op ? voor een lijst met supersnelle toets combinaties. - - - - ## Reageren - - - Om te regageren op het **topic in het algemeen**, gebruik helemaal onderaan de topic. - - - Om te reageren op een **iemand in het bijzonder**, gebruik op zijn of haar bericht. - - - Om te reageren met **een nieuwe topic**, gebruik aan de rechterkant van een bericht. De oude en nieuwe topic worden aan elkaar verbonden. - - Om een quote te plaatsen, selecteer de tekst die je wilt quoten en klik op de Reageer knop. Herhalen voor meerdere quotes! - - - - Om iemand op de hoogte te stellen van je reactie, vermeld zijn of haar naam. Typ'@' en selecteer dan een gebruikersnaam. - - - - Om [standard Emoji](http://www.emoji.codes/) te gebruiken, type gewoon `:` en selecteer er een via de naam, of gebruik traditionele smileys `;)` - - - - Voor een automatische ingekorte vermelding van je link, plaats de link op een losse regel. - - - - ## Acties - - Er zijn actieknoppen onder aan elk bericht: - - - - Om te laten weten dat je een bericht waardeert, gebruik de **leuk** knop. Deel je waardering! - - Als je een probleem ziet met iemands bericht, laat het weten aan iemand privé, of [our staff](%{base_url}/about) met de **markeer** knop. Je kunt ook een link naar een bericht **delen**, of het toevoegen aan de favorieten van je gebruikerspagina om het later gemakkelijk te vinden. - - ## Notificaties - - Als iemand op je reageert op één van je berichten, tekst van je quote, of jou specifiek noemt met '@gebruikersnaam', dan verschijnt er een direct een getal rechts boven op de pagina. Klik er op en je ziet je **notificaties**. - - - - Maak je geen zorgen over het missen van een reactie – je ontvangt via e-mail alle notificaties die binnenkomen als je weg bent. - - ## Jouw instellingen - - - Alle topics minder dan **twee dagen oud** worden als nieuw gerekend. - - - Alle topics waarin je **actief in hebt geparticipeerd** (door maken, reageren, of gedurende een langere periode lezen) volg je automatisch. - - Een getal in het blauw staat als nieuw en ongelezen indicatoren naast deze topics: - - - - Je kan je notificaties voor elke topic wijzigen via In de gaten houden onder aan de topic. - - - - Je kan ook je notificaties instellen per categorie, als je elke nieuwe topic in een bepaalde categorie wilt bekijken. - - Om één van deze instellingen te wijzigen, zie: [your user preferences](%{base_url}/my/preferences). - - ## Groeps Vertrouwen - - Als je gaat deelnemen, win je na verloop van tijd het vertrouwen van de gebruikersgemeenschap, wordt je een volwaardig deelnemer, en worden de beperkingen de gelden voor nieuwe gebruikers opgeheven. Als je [vertrouwensniveau] (https://meta.discourse.org/t/what-do-user-trust-levels-do/4924) hoog genoeg is, krijg je nieuwe mogelijkheden om ons te helpen de gebruikersgemeenschap de managen. + Voor meer hulp verwijzen we je door naar onze [richtlijnen](%{base_url}/guidelines). welcome_user: subject_template: "Welkom bij %{site_name}!" welcome_invite: @@ -1161,10 +1306,134 @@ nl: text_body_template: "Het terugzetten van de backup is geslaagd." restore_failed: subject_template: "Terugzetten van backup is mislukt" + bulk_invite_succeeded: + subject_template: "Massale uitnodiging aan gebruikers met succes verwerkt" + text_body_template: "Je bestand voor een massale uitnodiging aan gebruikers is verwerkt. Er zijn %{sent} uitnodigingen verstuurd." + bulk_invite_failed: + subject_template: "Massale uitnodiging aan gebruikers verwerkt, met fouten" csv_export_succeeded: subject_template: "Export succesvol afgerond." csv_export_failed: subject_template: "Export mislukt" + text_body_template: "Het spijt ons, maar de export is mislukt. Bekijk de logbestanden of neem contact op met de staf." + email_reject_insufficient_trust_level: + subject_template: "[%{site_name}] E-mailprobleem -- Vertrouwensniveau te laag" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Het vertrouwensniveau van je account is niet hoog genoeg om nieuwe topics aan dit e-mailadres te sturen. Als je denkt dat dit niet klopt, kan je contact opnemen met de staf. + email_reject_inactive_user: + subject_template: "[%{site_name}] E-mailprobleem -- Gebruiker inactief" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Het account dat bij dit e-mailadres hoort, is niet geactiveerd. Je moet je account activeren voordat je e-mails instuurt. + email_reject_blocked_user: + subject_template: "[%{site_name}] E-mailprobleem -- Geblokkeerde gebruiker" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Het account dat bij dit e-mailadres hoort, is geblokkeerd. + email_reject_reply_user_not_matching: + subject_template: "[%{site_name}] E-mailprobleem -- Reagerende gebruiker komt niet overeen" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Je reactie werd verstuurd van een ander e-mailadres dan we verwacht hadden, dus we weten niet zeker of dit dezelfde persoon is. Probeer de e-mail vanaf een ander adres te sturen, of neem contact op met de staf. + email_reject_no_account: + subject_template: "[%{site_name}] E-mailprobleem -- Onbekende account" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + We konden geen accounts vinden die overeenkomen met je e-mailadres. Probeer de e-mail van een ander adres te sturen, of neem contact op met de staf. + email_reject_empty: + subject_template: "[%{site_name}] E-mailprobleem -- Geen inhoud" + text_body_template: |+ + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + We konden geen bruikbare tekst in je e-mail vinden. + + Als je deze melding krijgt en _wel_ een reactie had gestuurd, kan je het opnieuw proberen met een eenvoudigere opmaak. + + + email_reject_parsing: + subject_template: "[%{site_name}] E-mailprobleem -- Inhoud niet herkend" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + We konden je reactie niet in je e-mail vinden. **Zorg ervoor dat je reactie bovenaan de e-mail staat**, we kunnen ingebedde reacties niet verwerken. + email_reject_invalid_access: + subject_template: "[%{site_name}] E-mailprobleem -- Ongeldige toegang" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Je hebt niet het privilege om nieuwe topics in die categorie te plaatsen. Als je denkt dat dit niet klopt, kan je contact opnemen met de staf. + email_reject_strangers_not_allowed: + subject_template: "[%{site_name}] E-mailprobleem -- Ongeldige toegang" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + In de categorie waaraan je de e-mail stuurde, zijn alleen reacties van gebruikers met geldige accounts en bekende e-mailadressen toegestaan. Als je denkt dat dit niet klopt, kan je contact opnemen met de staf. + email_reject_invalid_post: + subject_template: "[%{site_name}] E-mailprobleem -- Foutmelding bij het plaatsen" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Dit kan bijvoorbeeld komen door complexe opmaak of door een te groot of te klein bericht. Probeer het opnieuw of plaats je bericht via de website als het nog steeds niet lukt. + email_reject_invalid_post_specified: + subject_template: "[%{site_name}] E-mailprobleem -- Foutmelding bij het plaatsen" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Reden: + + %{post_error} + + Probeer het opnieuw als je het probleem kan oplossen. + email_reject_rate_limit_specified: + subject_template: "[%{site_name}] E-mailprobleem -- Gelimiteerde snelheid" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Reden: %{rate_limit_description} + email_reject_invalid_post_action: + subject_template: "[%{site_name}] E-mailprobleem -- Ongeldige plaatsingsactie" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + De plaatsingsactie werd niet herkend. Probeer het opnieuw of plaats je bericht via de website als het nog steeds niet lukt. + email_reject_reply_key: + subject_template: "[%{site_name}] E-mailprobleem -- Onbekende antwoordsleutel" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + De antwoordsleutel in de e-mail is ongeldig of onbekend, dus we weten niet waar deze e-mail een reactie op is. Neem contact op met de staf. + email_reject_bad_destination_address: + subject_template: "[%{site_name}] E-mailprobleem -- Onbekend bestemmingsadres" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Geen van de bestemmingsadressen werd herkend. Zorg ervoor dat je je e-mail naar het juiste door de staf verstrekte e-mailadres stuurt. + email_reject_topic_not_found: + subject_template: "[%{site_name}] E-mailprobleem -- Topic niet gevonden" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Het topic waarop je reageert bestaat niet meer. Misschien is het verwijderd? Als je denkt dat dit niet klopt, kan je contact opnemen met de staf. + email_reject_topic_closed: + subject_template: "[%{site_name}] E-mailprobleem -- Topic gesloten" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Het topic waarop je reageert is op dit moment gesloten en accepteert geen reacties meer. Als je denkt dat dit niet klopt, kan je contact opnemen met de staf. + email_reject_auto_generated: + subject_template: "[%{site_name}] E-mailprobleem -- Automatisch gegenereerde reactie" + text_body_template: | + Het spijt ons, maar het plaatsen van je e-mail op %{destination} (met onderwerp %{former_title}) is niet gelukt. + + Je e-mail is als ‘automatisch gegenereerd’ gemarkeerd, wat betekent dat het automatisch door een computer is geschreven in plaats van door een mens. Zulke e-mails kunnen wij niet accepteren. Als je denkt dat dit niet klopt, kan je contact opnemen met de staf. + email_error_notification: + subject_template: "[%{site_name}] Email probleem -- POP authenticatie fout" too_many_spam_flags: subject_template: "Account geblokkeerd" text_body_template: | @@ -1177,32 +1446,10 @@ nl: Kijk voor verdere uitleg in de [community richtlijnen](%{base_url}/guidelines). blocked_by_staff: subject_template: "Account geblokkeerd" - text_body_template: | - Hallo, - - Dit is een automatisch bericht van %{site_name} om je te informeren dat je account geblokkeerd is door de staf. - - Kijk voor verdere uitleg in de [regels](%{base_url}/guidelines). user_automatically_blocked: subject_template: "Nieuwe gebruiker %{username} geblokkeerd wegens meldingen van andere gebruikers" - text_body_template: | - Dit is een automatisch gegenereerd bericht. - - De nieuwe gebruiker [%{username}](%{base_url}%{user_url}) is automatisch geblokkeerd, omdat meerdere gebruikers de bericht(en) van %{username} gemarkeerd hebben. - - Kijk hier voor [de markeringen](%{base_url}/admin/flags). Als %{username} ten onrechte geblokkeerd is, klik dan op de deblokkeerdknop op [de beheerpagina van deze gebruiker](%{base_url}%{user_url}). - - De gevoeligheid kan worden gewijzigd via de `block_new_user` site instellingen. spam_post_blocked: subject_template: "Berichten van nieuwe gebruiker %{username} geblokkeerd vanwege herhaalde links" - text_body_template: | - Dit is een automatisch gegenereerd bericht. - - Nieuwe gebruiker [%{username}](%{base_url}%{user_url}) probeerde meerdere berichten te plaatsen met links naar %{domains}, maar deze berichten zijn geblokkeerd om spam tegen te gaan. De gebruiker kan nog steeds nieuwe berichten plaatsen die niet linken naar %{domains}. - - Bekijk de gebruiker [hier](%{base_url}%{user_url}). - - De drempel hiervoor kan ingesteld worden met de `newuser_spam_host_threshold` en de `white_listed_spam_host_domains` site instellingen. unblocked: subject_template: "Account gedeblokkeerd" text_body_template: | @@ -1225,61 +1472,23 @@ nl: subject_pm: "[PM]" user_notifications: previous_discussion: "Vorige reacties" + in_reply_to: "in reactie op" unsubscribe: title: "Uitschrijven" description: "Niet geïnteresseerd in deze e-mails? Geen probleem! Klik hieronder om direct uitgeschreven te worden:" - reply_by_email: "Beantwoord deze mail om te reageren op dit forumbericht, of ga naar %{base_url}%{url} in je browser." - visit_link_to_respond: "Ga naar %{base_url}%{url} in je browser om te reageren." posted_by: "Geplaatst door %{username} op %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} nodigt je uit voor een bericht '%{topic_title}'" - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} nodigt je uit voor een topic '%{topic_title}'" user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "Een korte samenvatting van %{site_link} sinds we je voor het laatst zagen op %{last_seen_at}." subject_template: "[%{site_name}] Digest" @@ -1310,6 +1519,15 @@ nl: Klik op de volgende link om een wachtwoord in te stellen: %{base_url}/users/password-reset/%{email_token} + admin_login: + subject_template: "[%{site_name}] Login" + text_body_template: | + Iemand heeft geprobeerd om met je account op [%{site_name}](%{base_url}) in te loggen. + + Als jij het niet was, kan je deze e-mail gewoon negeren. + + Klik op de volgende link om in te loggen: + %{base_url}/users/admin-login/%{email_token} account_created: subject_template: "[%{site_name}] Uw Nieuwe Account" text_body_template: | @@ -1317,12 +1535,6 @@ nl: Klik op deze link om een wachtwoord in te stellen voor je nieuwe account: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Bevestig je nieuwe e-mailadres" - text_body_template: | - Bevestig je nieuwe e-mailadres voor %{site_name} door op de volgende link te klikken: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "Je inschrijving op %{site_name} is geaccepteerd!" text_body_template: | @@ -1352,7 +1564,7 @@ nl: Mocht je de bovenstaande link niet kunnen aanklikken, probeer deze dan te kopiëren en te plakken in de adresbalk van je web browser. page_not_found: - title: "De opgevraagde pagina bestaat niet op dit forum of is privé." + title: "Oeps! Die pagina bestaat niet of is privé." popular_topics: "Populair" recent_topics: "Recent" see_more: "Meer" @@ -1371,6 +1583,7 @@ nl: unauthorized: "Sorry, je mag dat bestand niet uploaden (toegestane extensies: %{authorized_extensions})." pasted_image_filename: "Geplakte afbeelding" store_failure: "Het opslaan van upload #%{upload_id} voor gebruiker #%{user_id} is mislukt." + file_missing: "Sorry, maar je moet een bestand leveren om te uploaden." attachments: too_large: "Sorry, het bestand dat je wil uploaden is te groot (maximum grootte is %{max_size_kb}%KB)." images: @@ -1381,7 +1594,8 @@ nl: spam_hosts: "Deze nieuwe gebruiker probeerde om meerdere berichten met links naar hetzelfde domein te plaatsen. Zie de newuser_spam_host_threshold instelling." email_log: no_user: "Kan geen gebruiker met id %{user_id} vinden" - anonymous_user: "Lid is anoniem" + anonymous_user: "Gebruiker is anoniem" + suspended_not_pm: "Gebruiker is geschorst, geen bericht" seen_recently: "Gebruiker was recentelijk nog online" post_not_found: "Kan geen bericht met id %{post_id} vinden" notification_already_read: "De notificatie waar deze mail voor is is al gezien" @@ -1410,21 +1624,20 @@ nl: title: "Algemene Voorwaarden" privacy_topic: title: "Privacy Voorwaarden" - badges: - long_descriptions: - basic: | - Deze badge is aan je toegekend met het bereiken van trustlevel 1. Bedankt dat je een tijdje hebt rondgekeken, wat topics hebt gelezen en wat meer te weten bent gekomen over bedoeling van dit forum. De restricties voor nieuwe gebruikers gelden nu niet meer voor jou, en je kunt nu gebruik maken van alle basis communicatie mogelijkheden, zoals persoonlijke berichten, markeren, wijzigen van wiki's en de mogelijkheid om afbeeldingen en meerdere links in één bericht te plaatsen. - member: | - Deze badge is aan je toegekend met het bereiken van trustlevel 2. Bedankt voor je deelname gedurende enkele weken om op het forum actief te zijn. Je kunt nu persoonlijke uitnodigingen versturen vanuit je gebruikerspagina of een bepaalde topic, groepsberichten versturen en je hebt per dag meer likes tot je beschikking. - regular: | - Deze badge is aan je toegekend met het bereiken van trustlevel 3. Bedankt dat je al meerdere maanden deel uit maakt van ons forum, behoort tot de meest actieve lezers en regelmatig bijdraagt aan wat dit forum zo goed maakt. Je kunt nu de naam en categorie van topics aanpassen en gebruik maken van een speciale "lounge", krachtiger spam markeringen en nog veel meer likes per dag. - leader: | - Deze badge is aan je toegekend met het bereiken van trustlevel 4. Je bent door de staf uitgekozen voor een voortrekkersrol, om op dit forum een positief voorbeeld te geven in woord en gedrag. Je kunt nu alle berichten aanpassen, topics modereren door bijvoorbeeld pinnen, sluiten, verbergen, archiveren, splitsen en samenvoegen en je hebt een vrijwel onbeperkt aantal likes per dag. admin_login: success: "E-mail verstuurd" error: "Fout!" email_input: "Beheerder E-mail" submit_button: "E-mail versturen" + discourse_hub: + access_token_problem: "Licht een admin in: Gelieve de site instellingen bijwerken met de juiste discourse_org_access_key." performance_report: initial_post_raw: Deze topic bevat dagelijkse performance rapporten van je site initial_topic_title: Website performance rapporten + topic_invite: + user_exists: "Excuus, die gebruiker is al uitgenodigd. Je kan een gebruiker maar een keer voor een topic uitnodigen." + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.pl_PL.yml b/config/locales/server.pl_PL.yml index 6b8a993c42d..e92c1002205 100644 --- a/config/locales/server.pl_PL.yml +++ b/config/locales/server.pl_PL.yml @@ -10,18 +10,27 @@ pl_PL: short_date_no_year: "D MMM" short_date: "D MMM RRRR" long_date: "D MMMM YYYY H:mm" + datetime_formats: &datetime_formats + formats: + short: "%d.%m.%Y" + short_no_year: "%-d %B" + date_only: "%-d %b %Y" + date: + month_names: [null, Styczeń, Luty, Marzec, Kwiecień, Maj, Czerwiec, Lipiec, Sierpień, Wrzesień, Październik, Listopad, Grudzień] + <<: *datetime_formats title: "Discourse" topics: "Tematy" posts: "wpisy" loading: "Ładowanie" powered_by_html: 'Zasilane przez Discourse, najlepiej oglądać z włączonym JavaScriptem' log_in: "Logowanie" - via: "%{username} z %{site_name}" - is_reserved: "jest zarezerwowana" purge_reason: "Automatycznie usunięto jako porzucone, nieaktywne konto" disable_remote_images_download_reason: "Pobieranie zewnętrznych grafik zostało wyłączone z uwagi na niską ilość wolnego miejsca na dysku." anonymous: "Anonim" - errors: + emails: + incoming: + default_subject: "Przychodzący email od %{email}" + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "ograniczono do %{max} znaków, podano %{length}." @@ -69,6 +78,13 @@ pl_PL: other: '%{count} błędów uniemożliwiło zapisanie %{model}' embed: load_from_remote: "Wystąpił błąd podczas wczytywania tego wpisu." + site_settings: + min_username_length_exists: "Nie możesz ustawić najkrótszej długości nazwy użytkownika powyżej najkrótszej nazwy użytkownika." + min_username_length_range: "Nie możesz ustawić minimum powyżej maksimum." + max_username_length_exists: "Nie możesz ustawić maksymalnej długości nazwy użytkownika poniżej najdłuższej nazwy użytkownika." + max_username_length_range: "Nie możesz ustawić maksimum poniżej minimum." + default_categories_already_selected: "Nie możesz wybrać kategorii użytej w innej liście." + s3_upload_bucket_is_required: "Nie możesz wysyłać na S3 jeżeli nie podasz 's3_upload_bucket'." bulk_invite: file_should_be_csv: "Wysłany plik powinien być w formacie CSV lub TXT." backup: @@ -77,7 +93,7 @@ pl_PL: not_enough_space_on_disk: "Nie ma wystarczającej ilości wolnego miejsca, aby wczytać tę kopię zapasową." not_logged_in: "Aby to zrobić musisz się zalogować." not_found: "Żądany URL lub źródło nie mógł zostać znaleziony." - invalid_access: "Nie jesteś uprawniony by zobaczyć żądane źródło." + invalid_access: "Nie jesteś uprawniony, by zobaczyć żądane źródło." read_only_mode_enabled: "Strona jest w trybie tylko do odczytu. Możliwość interakcji jest wyłączona." too_many_replies: one: "Przepraszamy, ale nowi użytkownicy są tymczasowo ograniczeni do 1 odpowiedzi w ramach jednego tematu." @@ -98,26 +114,6 @@ pl_PL: one: "1 odpowiedź" few: "%{count} odpowiedzi" other: "%{count} odpowiedzi" - too_many_mentions: - zero: "Przepraszamy, nie możesz odwoływać się do innych użytkowników." - one: "Przepraszamy, możesz odwołać się tylko do jednego użytkownika we wpisie." - other: "Przepraszamy, możesz odwołać się tylko do %{count} użytkowników we wpisie." - too_many_mentions_newuser: - zero: "Przepraszamy, nowi użytkownicy nie mogą odwoływać się do innych użytkowników." - one: "Przepraszamy, nowi użytkownicy mogą odwołać się tylko do jednego użytkownika we wpisie." - other: "Przepraszamy, nowi użytkownicy mogą odwołać się tylko do %{count} użytkowników we wpisie." - too_many_images: - zero: "Przepraszamy, nowi użytkownicy nie mogą dodawać zdjęć do wpisów." - one: "Przepraszamy, nowi użytkownicy mogą umieścić tylko jedno zdjęcie we wpisie." - other: "Przepraszamy, nowi użytkownicy mogą umieścić tylko %{count} zdjęć we wpisie." - too_many_attachments: - zero: "Nowi użytkownicy nie mogą dodawać załączników do postów." - one: "Nowi użytkownicy mogą dodać tylko jeden załącznik do posta." - other: "Nowi użytkownicy mogą dodać %{count} załączników do wpisu." - too_many_links: - zero: "Przepraszamy, nowi użytkownicy nie mogą umieszczać linków we wpisach." - one: "Przepraszamy, nowi użytkownicy mogą dodać tylko jeden link we wpisie." - other: "Przepraszamy, nowi użytkownicy mogą dodać tylko %{count} linków we wpisie." spamming_host: "Przepraszamy, nie możesz umieścić linka do tej strony." user_is_suspended: "Zawieszeni użytkownicy nie mogą wysyłać wiadomości." topic_not_found: "Coś poszło nie tak. Być może temat został zamknięty lub usunięty w międzyczasie?" @@ -128,6 +124,7 @@ pl_PL: next_page: "następna strona →" prev_page: "← poprzednia strona" page_num: "Strona %{num}" + home_title: "Strona główna" topics_in_category: "Tematy w kategorii '%{category}'" rss_posts_in_topic: "Kanał RSS tematu '%{topic}'" rss_topics_in_category: "Kanał RSS tematów z kategorii '%{category}'" @@ -165,6 +162,22 @@ pl_PL: other: "%{count} wpisów" new-topic: "Witaj na %{site_name} — **dziękujemy za rozpoczęcie nowej dyskusji!**\n\n- Czy tytuł brzmi interesująco, gdy przeczytasz go na głos? Czy jest dobrym podsumowaniem treści?\n\n- Kto będzie tym zainteresowany? Dlaczego temat jest istotny? Jakiego rodzaju odpowiedzi oczekujesz? \n\n- Postaraj się umieścić słowa kluczowe w tytule, dzięki czemu inni będą mogli łatwo *wyszukać* temat. Przypisz go do kategorii o pokrewnej tematyce. \n\nAby dowiedzieć się więcej, [zobacz przewodnik społeczności](/guidelines). Ten panel pojawi się tylko przy pierwszym %{education_posts_text}.\n\n\n" new-reply: "Witaj na %{site_name} — **dziękujemy za zaangażowanie!**\n\n- Czy twoja odpowiedź wnosi coś pozytywnego do dyskusji?\n\n- Zachowuj się przyjaźnie w stosunku do innych.\n\n- Konstruktywna krytyka jest mile widziana, ale krytykujemy *pomysły*, a nie ludzi.\n\nWięcej informacji znajdziesz [w przewodniku społeczności](/guidelines). \nTen panel pojawi się tylko przy pisaniu pierwszych %{education_posts_text}.\n" + avatar: | + ### A może dodasz zdjęcie profilowe do swojego konta? + + Otworzyłeś kilka tematów i napisałeś kilka odpowiedzi, ale twoje zdjęcie profilowe nie jest tak niezwykłe jak ty - to tylko litera. + + Myślałeś o **[odwiedzeniu swojego profilu użytkownika](%{profile_path})** i załączeniu przedstawiającego cię zdjęcia? + + Kiedy każdy ma unikatowe zdjęcie profilowe, łatwiej jest obserwować dyskusje i znaleźć interesujących ludzi do rozmów! + sequential_replies: | + ### Pomyśl o odpowiadaniu na kilka postów jednocześnie + + Zamiast kilku kolejnych odpowiedzi do tematu, pomyśl o pojedynczej odpowiedzi, która zawierałaby cytaty z wcześniejszych postów lub wzmianki @imię. + + Możesz edytować swoje wcześniejsze odpowiedzi, aby dodać cytat, poprzez podświetlenie tekstu i wybranie przycisku quote reply. + + Każdemu łatwiej będzie przeczytać temat, który ma kilka pogłębionych odpowiedzi, zamiast wielu niewielkich, indywidualnych replik. dominating_topic: | ### Pozwól innym dołączyć do rozmowy @@ -192,9 +205,6 @@ pl_PL: user_profile: bio_raw: "O mnie" errors: - messages: - is_invalid: "jest niewystarczająca – spróbuj ją rozwinąć" - has_already_been_used: "jest już użyty" models: topic: attributes: @@ -215,6 +225,7 @@ pl_PL: attributes: hex: invalid: "nie jest poprawnym kolorem" + <<: *errors user_profile: no_info_me: "
    Pole O mnie w Twoim profilu jest obecnie puste, czy chcesz je wypełnić?
    " no_info_other: "
    %{name} jeszcze nie podał swojego opisu w profilu
    " @@ -250,13 +261,10 @@ pl_PL: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "O kategorii %{category}" - replace_paragraph: "[Zamień ten pierwszy paragraf na krórki opis nowej kategorii. Opis ten będzie wyświetlany na karcie wyboru kategorii, więc postaraj się utrzymać go poniżej 200 znaków. Póki nie zmienisz tego tekstu, ani nie utworzysz tematu, kategoria nie będzie wyświetlana na liście kategorii.]" - post_template: "%{replace_paragraph}\n\nW kolejnych paragrafach możesz umieścić dłuższy opis, oraz opisać zasady i zwyczaje jakie będą obowiązywać w tej kategorii. \n\nKilka rzeczy do rozważenia:\n\n- Czemu ma służyć ta kategoria? Dlaczego inni powinni wybierać tę kategorię dla swoich tematów?\n\n- Czym się różni od innych kategorii, które już mamy?\n\n- Czy potrzebujemy tej kategorii?\n\n- Czy powinniśmy ją połączyć z jakąś inną kategorią, lub podzielić na więcej kategorii?\n" errors: uncategorized_parent: "Inne nie mogą być podkategorią innej kategorii." self_parent: "Podkategoria nie może być swoim rodzicem" depth: "Nie możesz umieścić subkategorii w innej subkategorii" - email_in_already_exist: "Przychodzący adres email '%{email_in}' jest teraz używany w tej '%{category_name}' kategorii. " cannot_delete: uncategorized: "Nie można usunąć kategorii Inne" has_subcategories: "Nie można usunąć tej kategorii ponieważ posiada podkategorie. " @@ -270,16 +278,20 @@ pl_PL: title: "nowy" basic: title: "początkujący" - regular: - title: "zwykły" - leader: - title: "regularny" - elder: - title: "starszyzna" change_failed_explanation: "Twoja próba obniżenia poziomu %{user_name} do '%{new_trust_level}' była nieudana. Ten użytkownik posiada już poziom '%{current_trust_level}'. %{user_name} pozostanie na poziomie '%{current_trust_level}' - jeśli chcesz to zmienić, najpierw zablokuj poziom zaufania temu użytkownikowi." rate_limiter: - slow_down: "Ta akcja została wykonana zbyt wiele razy, próbuj ponownie za jakiś czas" + slow_down: "Powtórzyłeś to działanie zbyt wiele razy, spróbuj ponownie później." too_many_requests: "Liczba wykonań tej czynności w ciągu dnia jest ograniczona. Odczekaj %{time_left} przed ponowną próbą." + by_type: + first_day_replies_per_day: "Osiągnąłeś maksymalną liczbę odpowiedzi, jakie może napisać nowy użytkownik pierwszego dnia. Musisz odczekać %{time_left} zanim znów spróbujesz." + first_day_topics_per_day: "Osiągnąłeś maksymalną liczbę tematów, jakie może napisać nowy użytkownik pierwszego dnia. Musisz odczekać %{time_left}, zanim znów spróbujesz." + create_topic: "Zbyt szybko tworzysz tematy. Musisz poczekać %{time_left}, zanim znów spróbujesz." + create_post: "Odpowiadasz zbyt szybko. Musisz poczekać %{time_left}, zanim znów spróbujesz." + topics_per_day: "Osiągnąłeś maksymalną liczbę nowych tematów na dziś. Musisz poczekać %{time_left}, zanim znów spróbujesz." + pms_per_day: "Osiągnąłeś maksymalną liczbę wiadomości na dziś. Musisz poczekać %{time_left}, zanim znów spróbujesz." + create_like: "Osiągnąłeś maksymalną liczbę lajków na dziś. Musisz poczekać %{time_left}, zanim znów spróbujesz." + create_bookmark: "Wyczerpałeś na dziś możliwość dodawania zakładek. Musisz poczekać %{time_left}, zanim znów spróbujesz." + edit_post: "Wyczerpałeś na dziś możliwość edytowania. Musisz poczekać %{time_left}, zanim znów spróbujesz." hours: one: "1 godzina" few: "%{count} godziny" @@ -386,6 +398,7 @@ pl_PL: few: "prawie %{count} lata temu" other: "prawie %{count} lat temu" password_reset: + no_token: "Przepraszamy, ten link do zmiany hasła jest zbyt stary. Wybierz przycisk \"Zaloguj\", a następnie \"Zapomniałem hasła\", by uzyskać nowy link." choose_new: "Wybierz nowe hasło" choose: "Wprowadź hasło" update: 'Zmień hasło' @@ -399,6 +412,7 @@ pl_PL: please_continue: "Przejdź do %{site_name}" error: "Podczas próby zmiany Twojego adresu email wystąpił błąd. Być może ten adres jest już używany?" activation: + action: "Kliknij, by aktywować swoje konto." already_done: "Przepraszamy, ten link aktywujący konto jest już nieważny. Być może Twoje konto jest już aktywne ?" please_continue: "Twoje nowe konto zostało aktywowane, zostaniesz przekierowany na stronę główną." continue_button: "Przejdź do %{site_name}" @@ -421,16 +435,11 @@ pl_PL: description: 'Ten wpis zawiera treści które umiarkowana osoba może uznać za wulgarne, obraźliwe lub naruszające wytyczne społeczności.' long_form: 'oflagowano jako niewłaściwe' notify_user: - title: 'Powiadom @{{username}}' - description: 'Ten wpis zawiera coś o czym chciałbym porozmawiać z tą osobą bezpośrednio i prywatnie. Bez oflagowania.' long_form: 'użytkownik został powiadomiony' email_title: 'Twój wpis w "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Coś innego" - description: 'Ten post wymaga uwagi moderatora z powodu nie uwzględnionego na liście powyżej.' - long_form: 'oznaczył to dla uwagi moderatora' - email_title: 'Wpis w "%{title}" wymaga uwagi moderatorów' email_body: "%{link}\n\n%{message}" bookmark: title: 'Zakładka' @@ -455,7 +464,6 @@ pl_PL: long_form: 'oflagowano jako niewłaściwe' notify_moderators: title: "Coś innego" - description: 'Ten temat wymaga interwencji moderatora z uwagi na niezgodność z wytycznymi społeczności, warunkami użytkowania lub z innego, niewymienionego tu powodu.' long_form: 'oznaczył to dla uwagi moderatora' email_title: 'Temat "%{title}" wymaga uwagi moderatora' email_body: "%{link}\n\n%{message}" @@ -466,6 +474,7 @@ pl_PL: regular: title: "Zwykły temat" banner: + title: "Ustaw jako baner" message: make: "Ten temat został ustawiony jako baner. Będzie pojawiać się na górze każdej strony do czasu zamknięcia przez użytkownika." remove: "Ten temat nie jest już banerem. Nie będzie pojawiać się na górze każdej strony." @@ -490,6 +499,10 @@ pl_PL: title: "Nowi Użytkownicy" xaxis: "Dzień" yaxis: "Liczba nowych użytkowników" + profile_views: + title: "Wyświetlenia profilu użytkownika" + xaxis: "Dzień" + yaxis: "Liczba wyświetleń profilów użytkowników" topics: title: "Tematy" xaxis: "Dzień" @@ -574,9 +587,13 @@ pl_PL: xaxis: "Dzień" yaxis: "Razem żądań API" page_view_logged_in_mobile_reqs: + title: "Zalogowany w zapytaniach API " xaxis: "Dzień" + yaxis: "Urządzenie zalogowane w zapytaniach API" page_view_anon_mobile_reqs: + title: "Anonimowe zapytania do API" xaxis: "Dzień" + yaxis: "Mobilne anonimowe zapytania do API" http_background_reqs: title: "Tło" xaxis: "Dzień" @@ -619,6 +636,7 @@ pl_PL: host_names_warning: "Twój plik config/database.yml używa domyślnej nazwy serwera localhost. Zmień go by używał nazwy serwera Twojej strony." gc_warning: 'Twój serwer wykorzystuje domyślne ustawienia odśmiecacza ruby, który nie da Ci optymalnej wydajności. Przeczytaj ten temat o optymalizacji wydajności: Tuning Ruby and Rails for Discourse.' sidekiq_warning: 'Sidekiq nie działa. Wiele zadań, takich jak wysyłanie emaili, jest wykonywane asynchronicznie przez sidekiqa. Zagwarantuj, że przynajmniej jeden proces sidekiqa działa. Dowiedz się więcej o Sidekiqu.' + queue_size_warning: 'Liczba oczekujących zadań wynosi %{queue_size}, to dużo. Może to wskazywać na problem z procesem (procesami) Sidekiq, lub możesz potrzebować więcej pracowników Sidekiq.' memory_warning: 'Twój serwer działa z mniej niż 1 GB pamięci całkowitej. Przynajmniej 1 GB pamięci jest zalecany.' google_oauth2_config_warning: 'Serwis umożliwia rejestrację i logowanie poprzez Google OAuth2 (enable_google_oauth2_logins), ale ''client id'' oraz ''client secret'' nie są jeszcze ustawione. Przejdź do Ustawień i wprowadź te wartości. Zobacz ten przewodnik, aby dowiedzieć się więcej.' facebook_config_warning: 'Serwer jest skonfigurowany by pozwalać na rejestrację i logowanie za pomocą Facebooka (enable_facebook_logins), ale identyfikator i sekret aplikacji nie są ustawione. Przejdź do ustawień serwisu i zmień ustawienia. Zobacz ten poradnik by dowiedzieć się więcej.' @@ -635,37 +653,6 @@ pl_PL: consumer_email_warning: "Twój serwis jest skonfigurowany by używać Gmaila (lub innego konsumenckiego serwisu poczty) do wysyłania emaili. Gmail ogranicza jak dużo wiadomości możesz wysłać. Rozważ wykorzystanie dostawcy serwisu pocztowego jak mandrill.com by zagwarantować dostarczanie poczty." site_contact_username_warning: "Wprowadź nazwę użytkownika zespołu, aby wysłać ważny szablon automatycznej wiadomości. Zaktualizuj site_contact_username w Ustawieniach Strony " notification_email_warning: "Emaile z powiadomieniami nie zostały wysłane z prawidłowego adresu email na twojej domenie; dostawca usługi email może być niekonsekwentny i nierzetelny. Ustaw prawidłowy email w notification_email w Ustawieniach Strony." - content_types: - education_new_reply: - title: "Edukacja nowych użytkowników: Pierwsze odpowiedzi" - description: "Okienko z wskazówkami automatycznie wyświetlane nad panelem pisania gdy nowi użytkownicy zaczynają pisać swoje pierwsze 2 odpowiedzi." - education_new_topic: - title: "Edukacja nowych użytkowników: Pierwsze tematy" - description: "Okienko z wskazówkami automatycznie wyświetlane nad panelem pisania gdy nowi użytkownicy rozpoczynają swoje pierwsze 2 tematy." - usage_tips: - title: "Wiadomość powitalna" - description: "Przewodnik i inne informacje dla nowych użytkowników." - welcome_user: - title: "Przywitanie: Nowy użytkownik" - description: "Wiadomość wysyłana automatycznie do wszystkich nowych użytkowników zaraz po ich rejestracji." - welcome_invite: - title: "Przywitanie: Zaproszony użytkownik" - description: "Wiadomość wysyłana automatycznie do nowych użytkowników po zaakceptowaniu zaproszenia od innego użytkownika." - login_required_welcome_message: - title: "Wymagane logowanie: wiadomość powitalna" - description: "Wiadomość powitalna wyświetlana niezalogowanym użytkownikom, gdy ustawienie 'login required' jest włączone." - login_required: - title: "Login Required: Homepage" - description: "The text displayed for unauthorized users when login is required on the site." - head: - title: "Nagłówki HTML" - description: "Kod HTML jaki zostanie umieszczony między tagami ." - top: - title: "Nagłówek każdej strony" - description: "Kod HTML jaki zostanie dołączony na górze każdej strony (po nagłówku, przed nawigacją lub tytułem tematu)." - bottom: - title: "Stopka każdej strony" - description: "Kod HTML, który zostanie załączony przed tagiem ." site_settings: censored_words: "Wskazane słowa będą automatycznie zamieniane na ■■■■" delete_old_hidden_posts: "Automatycznie kasuj wpisy ukryte dłużej niż 30 dni." @@ -679,7 +666,7 @@ pl_PL: max_topic_title_length: "Maksymalna długość tytułu tematu, w znakach" min_private_message_title_length: "Minimalna liczba znaków w temacie wiadomości " min_search_term_length: "Minimalna długość wyszukiwanego tekstu, w znakach" - uncategorized_description: "Znajdują się tu wątki którym jeszcze nie przypisano odpowiedniej kategorii." + allow_uncategorized_topics: "Zezwól na tworzenie tematów bez kategorii. UWAGA: jeśli jest jakiś nieskategoryzowany temat, musisz go przypisać do kategorii, zanim wyłączysz tę opcję." allow_duplicate_topic_titles: "Pozwól na tworzenie tematów o identycznych tytułach." unique_posts_mins: "Ile minut musi upłynąć zanim użytkownik będzie mógł ponownie zrobić wpis z tą samą treścią" educate_until_posts: "Wyświetlaj okno edukacyjne po rozpoczęciu pisania dopóki nowy użytkownik nie napisze tylu wpisów." @@ -692,7 +679,6 @@ pl_PL: download_remote_images_to_local: "Pobieraj zdalne grafiki i twórz ich lokalne kopie aby zapobiegać uszkodzonym/brakującym obrazkom na stronach." download_remote_images_threshold: "Minimalna ilość wolnego miejsca na dysku wymagana przez funkcję pobierania zdalnych grafik (w procentach)" disabled_image_download_domains: "Zdalne grafiki z tych domen nie będą pobierane." - ninja_edit_window: "Przez tyle sekund po utworzeniu nowego wpisu jego kolejne edycje nie będą tworzyć nowych wersji w historii wpisu." post_edit_time_limit: "Autor może edytować lub usunąć swój wpis przez tyle minut po jego utworzeniu. Ustawienie 0 oznacza 'zawsze'." edit_history_visible_to_public: "Pozwól wszystkim przeglądać poprzednie wersje edytowanych wpisów. Gdy wyłączone, jedynie obsługa/staff może." delete_removed_posts_after: "Wpisy usunięte przez autora będą automatycznie zlikwidowane po (n) godzinach. Jeżeli liczba godzin będzie wynosić 0, to zostaną usunięte natychmiast. " @@ -705,6 +691,7 @@ pl_PL: post_excerpt_maxlength: "Maksymalna długość podsumowania / streszczenia wpisu." post_onebox_maxlength: "Maksymalna długość (ilość znaków) treści wpisu osadzonego via Onebox" onebox_domains_whitelist: "Lista domen dla których włączony jest oneboxing; te domeny powinny wspierać OpenGraph lub oEmbed. Można to sprawdzić na http://iframely.com/debug" + logo_url: "Zdjęcie logo w lewym górnym rogu twojej strony powinno mieć kształt szerokiego prostokąta. Jeśli zostawisz miejsce puste, wyświetlany będzie tytuł strony." apple_touch_icon_url: "Ikona używana przez urządzenia Apple. Rekomendowany wymiar to 144px na 144px." notification_email: "Adres z którego wysyłane będą wszystkie istotne emaile systemowe.\nKonieczna jest poprawna konfiguracja rekordów SPF, DKIM oraz zwrotnego PTR użytej domeny." email_custom_headers: "A pipe-delimited list of custom email headers" @@ -713,11 +700,18 @@ pl_PL: summary_likes_required: "Minimalna liczba polubień w temacie zanim 'Podsumowanie tematu' jest dostępne" summary_percent_filter: "Gdy użytkownik kliknie na 'Podsumowaniu tematu', pokaż % najlepszych wpisów" summary_max_results: "Maksymalna liczba wpisów w 'Podsumowaniu tematu'" - enable_private_messages: "Zezwalaj użytkownikom o 1 poziomie zaufania na tworzenie wiadomości i odpowiadanie na nie." enable_long_polling: "Message bus used for notification can use long polling" anon_polling_interval: "How often should anonymous clients poll in milliseconds" flags_required_to_hide_post: "Number of flags that cause a post to be automatically hidden and PM sent to the user (0 for never)" + cooldown_minutes_after_hiding_posts: "Liczba minut, ile musi odczekać użytkownik, zanim będzie mógł edytować post ukryty w wyniku oflagowania przez społeczność" + max_topics_in_first_day: "Maksymalna liczba tematów, jakie może stworzyć użytkownik pierwszego dnia na tej stronie." + max_replies_in_first_day: "Maksymalna liczba odpowiedzi, jakie może napisać użytkownik pierwszego dnia na tej stronie." + tl2_additional_likes_per_day_multiplier: "Zwiększ limit lajków na dzień dla tl2 (członek), mnożąc przez tę liczbę" + tl3_additional_likes_per_day_multiplier: "Zwiększ limit lajków na dzień dla tl3 (użytkownik stały), mnożąc przez tę liczbę" + tl4_additional_likes_per_day_multiplier: "Zwiększ limit lajków na dzień dla tl4 (lider), mnożąc przez tę liczbę" notify_mods_when_user_blocked: "If a user is automatically blocked, send a message to all moderators." + flag_sockpuppets: "Jeśli nowy użytkownik odpowiada na dany temat z tego samego adresu IP co nowy użytkownik, który założył temat, oznacz ich posty jako potencjalny spam." + post_undo_action_window_mins: "Przez tyle minut użytkownicy mogą cofnąć swoje ostatnie działania przy danym poście (lajki, flagowanie, itd.)." ga_tracking_code: "Identyfikator Google analytics (ga.js), np: UA-12345678-9; zobacz http://google.com/analytics" ga_domain_name: "Google analytics (ga.js) domain name, eg: mysite.com; see http://google.com/analytics" ga_universal_tracking_code: "Identyfikator Google Universal Analytics (analytics.js), np: UA-12345678-9; zobacz http://google.com/analytics" @@ -727,17 +721,26 @@ pl_PL: post_menu: "Określ które elementy menu wpisu powinny być widoczne i w jakiej kolejności. Przykład like|edit|flag|delete|share|bookmark|reply" share_links: "Określ które elementy menu udostępniania powinny być widoczne i w jakiej kolejności. " track_external_right_clicks: "Śledź zewnętrzne linki kliknięte prawym klawiszem (np. otwierane w nowej zakładce). Domyślnie wyłączone, gdyż wymaga nadpisywania URLi." + send_welcome_message: "Wyślij wszystkim nowym użytkownikom powitalną wiadomość z krótkim przewodnikiem." topics_per_period_in_top_summary: "Liczba tematów wyświetlanych w domyślnym podsumowaniu najbardziej popularnych wątków" topics_per_period_in_top_page: "Liczba tematów wyświetlanych w widoku 'Pokaż więcej' na ekranie popularnych wątków." + redirect_users_to_top_page: "Automatycznie kieruj nowych i długo nieobecnych użytkowników na stronę główną." + show_email_on_profile: "Pokazuj email użytkownika w jego profilu (widoczny jedynie dla użytkownika i personelu)." email_token_valid_hours: "Tokeny resetujące hasło / aktywujące konto są ważne przez (n) godzin." enable_badges: "Włącz system odznak" + log_out_strict: "Po wylogowaniu wyloguj WSZYSTKIE sesje użytkownika na wszystkich urządzeniach." port: "DEVELOPER ONLY! WARNING! Use this HTTP port rather than the default of port 80. Leave blank for default of 80." force_hostname: "DEVELOPER ONLY! WARNING! Specify a hostname in the URL. Leave blank for default." invite_expiry_days: "Jak długo klucz zaproszenie użytkownika jest ważny, w dniach." invite_only: "Publiczna rejestracja jest wyłączona: wszyscy nowi użytkownicy muszą zostać zaproszeni przez innych użytkowników lub zespół." login_required: "Wymagaj autoryzacji do wyświetlenia zawartości strony, zablokuj możliwość anonimowego dostępu." + min_username_length: "Minimalna długość nazwy użytkownika w znakach." + max_username_length: "Maksymalna długość nazwy użytkownika w znakach." + reserved_usernames: "Niedozwolone nazwy użytkowników." min_password_length: "Minimalna długość hasła." + block_common_passwords: "Nie zezwalaj na hasła znajdujące się w grupie 10 000 najpopularniejszych haseł." allow_new_registrations: "Zezwól na rejestrację nowych użytkowników. Odznacz opcję żeby uniemożliwić rejestrację nowych kont." + enable_signup_cta: "Pokazuj wiadomość dla powracających użytkowników anonimowych, zachęcającą ich do założenia konta." enable_yahoo_logins: "Enable Yahoo authentication" google_oauth2_client_id: "Client ID twojej aplikacji w Google" google_oauth2_client_secret: "Client Secret twojej aplikacji w Google" @@ -754,6 +757,10 @@ pl_PL: active_user_rate_limit_secs: "How frequently we update the 'last_seen_at' field, in seconds" verbose_localization: "Wyświetlaj dodatkowe identyfikatory tłumaczeń w treści etykiet" previous_visit_timeout_hours: "How long a visit lasts before we consider it the 'previous' visit, in hours" + rate_limit_create_topic: "Po otworzeniu tematu użytkownicy muszą odczekać (n) sekund, zanim otworzą inny temat." + rate_limit_create_post: "Po napisaniu posta użytkownicy muszą odczekać (n) sekund, zanim napiszą inny post." + rate_limit_new_user_create_topic: "Po otworzeniu tematu nowi użytkownicy muszą odczekać (n) sekund, zanim otworzą inny temat." + rate_limit_new_user_create_post: "Po napisaniu posta nowi użytkownicy muszą odczekać (n) sekund, zanim napiszą inny post." max_likes_per_day: "Maksymalna liczba polubień per użytkownik per dzień" max_flags_per_day: "Maksymalna liczba oflagowań per użytkownik per dzień." max_bookmarks_per_day: "Maksymalna liczba zakładek per użytkownik per dzień." @@ -761,6 +768,7 @@ pl_PL: max_topics_per_day: "Maksymalna liczba tematów jakie użytkownik może stworzyć jednego dnia." max_private_messages_per_day: "Maksymalna liczba wiadomości jakie użytkownik może wysłać jednego dnia." max_invites_per_day: "Maksymalna liczba zaproszeń jakie użytkownik może wysłać jednego dnia." + max_topic_invitations_per_day: "Maksymalna dzienna liczba zaproszeń do tematu, jakie może wysłać użytkownik." suggested_topics: "Liczba sugerowanych tematów widocznych na końcu aktualnego tematu." limit_suggested_to_category: "Sugeruj tematy jedynie z tej samej kategorii." avatar_sizes: "Lista automatycznie wygenerowanych rozmiarów awatarów." @@ -771,10 +779,21 @@ pl_PL: tl2_requires_topics_entered: "Jak wiele tematów musi odwiedzić użytkownik, przed promocją na 2-gi poziom zaufania." tl2_requires_read_posts: "Jak wiele postów musi przeczytać użytkownik, przed promocją na 2-gi poziom zaufania." tl2_requires_time_spent_mins: "Jak wiele minut musi spędzić użytkownik czytając posty, przed promocją na 2-gi poziom zaufania." + tl2_requires_days_visited: "Ile dni użytkownik musi odwiedzać stronę, zanim otrzyma promocję na 2 poziom zaufania. " + tl2_requires_likes_received: "Ile lajków musi otrzymać użytkownik, zanim otrzyma promocję na 2 poziom zaufania." + tl2_requires_likes_given: "Ile lajków musi dać użytkownik, zanim otrzyma promocję na 2 poziom zaufania." + tl2_requires_topic_reply_count: "Na ile tematów musi odpowiedzieć użytkownik, zanim otrzyma promocję na 2 poziom zaufania." min_trust_to_create_topic: "The minimum trust level required to create a new topic." + newuser_max_links: "Ile linków może dodać nowy użytkownik do posta." + newuser_max_images: "Ile obrazów może dodać nowy użytkownik do posta." + newuser_max_attachments: "Ile załączników może dodać nowy użytkownik do posta." newuser_max_mentions_per_post: "Maksymalna liczba powiadomień poprzez @nazwę w jednym wpisie (dla nowych użytkowników)." max_mentions_per_post: "Maksymalna liczba powiadomień poprzez @nazwę w jednym wpisie (dla wszystkich)." + email_time_window_mins: "Odczekaj (n) minut przed wysłaniem maila z powiadomieniem, aby dać użytkownikom szansę na edytowanie i ukończenie postów." + title_max_word_length: "Maksymalna dozwolona długość słowa, w znakach, jako tytuł tematu." title_fancy_entities: "Convert common ASCII characters to fancy HTML entities in topic titles, ala SmartyPants http://daringfireball.net/projects/smartypants/" + min_title_similar_length: "Minimalna długość tytułu zanim zostanie sprawdzony z podobnymi tematami." + min_body_similar_length: "Minimalna długość treści posta zanim zostanie sprawdzony z podobnymi tematami." category_colors: "Lista kolorów w formacie hex do użycia w etykietach kategorii." category_style: "Styl etykiet kategorii" title_prettify: "Prevent common title typos and errors, including all caps, lowercase first character, multiple ! and ?, extra . at end, etc." @@ -791,20 +810,32 @@ pl_PL: email_editable: "Allow users to change their e-mail address after registration." digest_topics: "Maksymalna liczba tematów w podsumowaniu e-mail." digest_min_excerpt_length: "Minimalny wycinek wpisu (liczba znaków) w podsumowaniu e-mail." - suppress_digest_email_after_days: "Nie wysyłaj podsumowań e-mail użytkownikom, którzy nie odwiedzili serwisu dłużej niż (n) dni." disable_digest_emails: "Wyłącz wysyłanie podsumowania e-mail wszystkim uzytkownikom. " + allow_anonymous_posting: "Zezwól użytkownikom na przechodzenie w tryb anonimowości." allow_profile_backgrounds: "Zezwól użytkownikom na przesyłanie obrazu tła dla profilu." enable_mobile_theme: "Urządzenia mobilne używają dedykowanego mobilnego szablonu. Wyłącz to, jeśli chcesz użyć własnego, pojedynczego i responsywnego szablonu stylów. " suppress_uncategorized_badge: "Nie pokazuj etykiety z nazwą kategorii Inne na listach tematów." + full_name_required: "Pełne imię i nazwisko to wymagane pole w profilu użytkownika." + display_name_on_posts: "Pokazuj imię i nazwisko użytkownika przy jego postach, a także jego @nazwę użytkownika." enable_emoji: "Włącz obsługę emoji" emoji_set: "Jaki jest twój preferowany styl emoji?" + approve_unless_trust_level: "Posty użytkowników poniżej tego poziomu zaufania muszą być zatwierdzane" + default_categories_watching: "Lista kategorii obserwowanych domyślnie." + default_categories_tracking: "Lista kategorii śledzonych domyślnie." errors: invalid_email: "Nieprawidłowy adres email." invalid_username: "Użytkownik o takiej nazwie nie istnieje." + invalid_integer_min_max: "Wartość musi być między %{min} i %{max}." + invalid_integer_min: "Wartość musi wynosić %{min} albo więcej." + invalid_integer_max: "Wartość nie może być wyższa niż %{max}." invalid_integer: "Wartość musi być liczbą całkowitą." regex_mismatch: "Wartość nie jest zgodna z wymaganym formatem." must_include_latest: "Górne menu musi zawierać zakładkę 'aktualne'." invalid_string: "Nieprawidłowa wartość." + invalid_string_min_max: "Musi być między %{min} i %{max} znaków." + invalid_string_min: "Musi być co najmniej %{min} znaków." + invalid_string_max: "Musi być nie więcej niż %{max} znaków." + invalid_reply_by_email_address: "Wartość musi zawierać '%{reply_key}' i musi być inna niż mail z powiadomieniem." notification_types: mentioned: "%{display_username} wspomina o Tobie w %{link}" liked: "%{display_username} polubił(-a) Twój wpis w %{link}" @@ -813,7 +844,10 @@ pl_PL: edited: "%{display_username} edytuje Twój wpis w %{link}" posted: "%{display_username} pisze w %{link}" moved_post: "%{display_username} przenosi twój wpis do %{link}" + private_message: "%{display_username} wysłał ci wiadomość: %{link}" + invited_to_private_message: "%{display_username} zaprosił cię do wiadomości: %{link}" invitee_accepted: "%{display_username} przyjął(-ęła) Twoje zaproszenie" + linked: "%{display_username} powiązał cię z %{link}" granted_badge: "Zdobywasz %{link}" search: within_post: "#%{post_number} przez %{username}" @@ -821,12 +855,15 @@ pl_PL: category: 'Kategorie' topic: 'Wyniki' user: 'Użytkownicy' - sso: - account_not_approved: "Konto czeka na zatwierdzenie. Dostaniesz powiadomienie emailem, kiedy to się stanie." original_poster: "Autor pierwszego wpisu" most_posts: "Większość postów" most_recent_poster: "Autor najnowszego wpisu" frequent_poster: "Aktywny uczestnik" + redirected_to_top_reasons: + new_user: "Witamy w naszej społeczności! Oto najpopularniejsze najnowsze tematy." + not_seen_in_a_month: "Witamy ponownie! Długo tu nie zaglądałeś. Oto najpopularniejsze tematy z czasów, kiedy cię tu nie było." + change_owner: + deleted_user: "usunięty użytkownik" topic_statuses: archived_enabled: "Temat został zarchiwizowany. Został zablokowany i nie może być zmieniany. " archived_disabled: "Temat został przywrócony z archiwum. Został odblokowany i może ponownie być zmieniany." @@ -857,6 +894,7 @@ pl_PL: few: "Ten temat został automatycznie zamknięty %{count} minuty po ostatnim wpisie. Tworzenie nowych odpowiedzi nie jest już możliwe." other: "Ten temat został automatycznie zamknięty %{count} minut po ostatnim wpisie. Tworzenie nowych odpowiedzi nie jest już możliwe." autoclosed_disabled: "Temat został otwarty. Dodawanie odpowiedzi jest ponownie możliwe." + autoclosed_disabled_lastpost: "Temat został otwarty. Pisanie odpowiedzi jest możliwe." pinned_enabled: "Temat został przypięty. Będzie pojawiać się na początku swojej kategorii dopóki nie zostanie odpięty przez obsługę lub prywatnie przez użytkownika." pinned_disabled: "Temat został odpięty. Już nie będzie pojawiać się na początku swojej kategorii." pinned_globally_enabled: "Temat został przypięty globalnie. Będzie pojawiać się na początku swojej kategorii i wszystkich list dopóki nie zostanie odpięty przez obsługę lub prywatnie przez użytkownika." @@ -870,11 +908,19 @@ pl_PL: active: "Twoje konto zostało aktywowane i jest gotowe do użycia." activate_email: "

    Prawie gotowe! Wysłaliśmy email aktywacyjny na adres %{email}. Postępuj zgodnie z instrukcją z tego emaila, żeby dokończyć ten proces.

    Jeśli email nie dotrze do Ciebie, sprawdź folder ze spamem, lub zaloguj sie jeszcze raz, żeby wysłać go ponownie.

    " not_activated: "Nie możesz się jeszcze zalogować. Wysłaliśmy do Ciebie email aktywacyjny. Wykonaj instrukcje w nim zawarte by aktywować Twoje konto." + not_allowed_from_ip_address: "Nie możesz się zalogować jako %{username} z tego adresu IP." + admin_not_allowed_from_ip_address: "Nie możesz zalogować się jako administrator z tego adresu IP." + suspended: "Nie możesz się zalogować aż do %{date}." + suspended_with_reason: "Konto zawieszone do %{date}: %{reason}" errors: "%{errors}" not_available: "Niedostępny. Może spróbuj %{suggestion}?" something_already_taken: "Coś poszło źle. Możliwe, że ta nazwa użytkownika lub email są już zarejestrowane. Spróbuj użyć procedury przypominania hasła." + omniauth_error: "Przepraszamy, pojawił się błąd autoryzacji twojego konta. Sprawdź, czy zatwierdziłeś autoryzację." omniauth_error_unknown: "Wystąpił błąd podczas logowania, spróbuj ponownie." + new_registrations_disabled: "Aktualnie nie jest możliwe zarejestrowanie nowego konta." password_too_long: "Hasła są ograniczone do 200 znaków." + email_too_long: "Podałeś zbyt długi adres email. Nazwa skrzynki pocztowej nie może być dłuższa niż 254 znaki, a nazwa domeny nie może zawierać więcej niż 253 znaki." + reserved_username: "Niedozwolona nazwa użytkownika." missing_user_field: "Nie wypełniłeś wszystkich pól użytkownika" close_window: "Uwierzytelnianie zakończone. Aby kontynuować, zamknij to okno." user: @@ -885,10 +931,22 @@ pl_PL: characters: "może zawierać tylko litery, cyfry i podkreślenia" unique: "musi być unikalna" blank: "musi zostać podana" + must_not_contain_two_special_chars_in_seq: "nie może zawierać sekwencji 2 lub więcej znaków specjalnych (.-_)" email: not_allowed: "nie jest dopuszczany od tego dostawcy poczty. Użyj innego adresu email." blocked: "is not allowed." + ip_address: + blocked: "Z twojego adresu IP nowe rejestracje nie są możliwe." + max_new_accounts_per_registration_ip: "Z twojego adresu IP nowe rejestracje nie są możliwe (wyczerpany limit). Skonaktuj się z personelem." + flags_reminder: + subject_template: + one: "1 flaga oczekuje na reakcję" + few: "%{count} flagi oczekują na reakcję" + other: "%{count} flagi oczekują na reakcję" + invite_mailer: + subject_template: "%{invitee_name} zaprosił cię do '%{topic_title}' na %{site_domain_name}" invite_forum_mailer: + subject_template: "%{invitee_name} zaprosił cię do dołączenia do %{site_domain_name}" text_body_template: | %{invitee_name} wysłał Tobie zaproszenie @@ -903,25 +961,32 @@ pl_PL: To zaproszenie zostało wysłane przez zaufanego użytkownika, nie musisz się logować. invite_password_instructions: subject_template: "Ustaw hasło dla swojego konta na %{site_name}" + text_body_template: |+ + Dziękujemy za zaakceptowanie zaproszenia do %{site_name} -- witamy! + + + + Kliknij ten link, by wybrać hasło: + + %{base_url}/users/password-reset/%{email_token} + + + + (Jeśli powyższy link wygasł, wybierz "Zapomniałem hasła", logując się za pomocą adresu email.) + test_mailer: subject_template: "[%{site_name}] Test dostarczania poczty" new_version_mailer: subject_template: "[%{site_name}] Aktualizacja do nowej wersji Discourse jest dostępna." new_version_mailer_with_notes: subject_template: "[%{site_name}] dostępna aktualizacja" - flags_reminder: - flags_were_submitted: - one: "Flagi dodane godzinę temu." - few: "Flagi dodane ponad %{count} godziny temu." - other: "Flagi dodane ponad %{count} godzin temu." - post_number: "wpis" - subject_template: - one: "1 flaga oczekuje na reakcję" - few: "%{count} flagi oczekują na reakcję" - other: "%{count} flagi oczekują na reakcję" flag_reasons: inappropriate: "Twój wpis został oznaczony jako **nieodpowiedni**: społeczność uznała, że zbyt agresywny lub niezgodny z [jej wytycznymi](/guidelines)." + spam: "Twój post został oznaczony jako **spam**: społeczność czuje, że jest to reklama, czyli coś nadmiernie promującego, a nie użytecznego czy odnoszącego się do tematu." + notify_moderators: "Twój post został oznaczony jako **do uwagi moderatora**: społeczność czuje, że post wymaga ręcznej interwencji członka personelu." flags_dispositions: + agreed: "Dziękujemy za zwrócenie uwagi. Zgadzamy się, że jest to problem i przyjrzymy się temu. " + agreed_and_deleted: "Dziękujemy za zwrócenie uwagi. Zgadzamy się, że jest to problem i post został usunięty. " disagreed: "Dziękujemy za zwrócenie uwagi. Zajmiemy się tym wkrótce." deferred: "Dziękujemy za zwrócenie uwagi. Zajmiemy się tym wkrótce." deferred_and_deleted: "Dziękujemy za zwrócenie uwagi. Wpis został usunięty." @@ -929,6 +994,20 @@ pl_PL: system_messages: post_hidden: subject_template: "Wpis został ukryty z powodu oflagowania przez społeczność" + text_body_template: | + Witamy, + + To automatyczna wiadomość od %{site_name}, by poinformować Cię, że Twój post został ukryty. + + %{base_url}%{url} + + %{flag_reason} + + Wielu członków społeczności oznaczyło ten post przed jego ukryciem, zatem prosimy Cię, byś zastanowił się, jak możesz zrewidować swoje stanowisko, uwzględniając ich opinię. **Możesz edytować post po %{edit_delay} minutach, po czym będzie on znów widoczny. + + Jednakże jeśli post został ukryty przez społeczność po raz drugi, pozostanie taki, dopóki nie zajmie się nim personel - za tym mogą iść dalsze działania, jak możliwe zawieszenie Twojego konta. + + Aby uzyskać informacje na temat dalszego postępowania, przeczytaj [wytyczne dla społeczności] (%{base_url}/guidelines). welcome_user: subject_template: "Witaj na %{site_name}!" welcome_invite: @@ -1011,54 +1090,17 @@ pl_PL: unsubscribe: title: "Wypisz" description: "Nie chcesz otrzymywać tych emaili? Nie ma problemu! Kliknij poniżej by wypisać się natychmiast:" - reply_by_email: "Aby odpowiedzieć odpisz na ten email lub otwórz %{base_url}%{url} w swojej przeglądarce." - visit_link_to_respond: "To respond, visit %{base_url}%{url} in your browser." posted_by: "Dodany przez %{username} w dniu %{post_date}" user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [PW] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: subject_template: "[%{site_name}] Podsumowanie" new_activity: "Nowa aktywność w twoich tematach i wpisach:" @@ -1092,15 +1134,28 @@ pl_PL: Kliknij na linku poniżej, aby ustawić swoje hasło: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Potwierdź nowy adres email" - text_body_template: | - Potwierdź Twój nowy adres email na forum %{site_name} przez kliknięcie na poniższy link: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "Zostałeś zaakceptowany na forum %{site_name}!" + text_body_template: |+ + Witamy na %{site_name}! + + Nasz personel zatwierdził twoje konto na %{site_name}. + + Kliknij na podany link, aby potwierdzić i aktywować swoje nowe konto: + %{base_url}/users/activate-account/%{email_token} + + Jeśli podany link nie działa, spróbuj skopiować go i przykleić w pasku adresów swojej wyszukiwarki. + + %{new_user_tips} + + Wierzymy, że [cywilizowana dyskusja](%{base_url}/guidelines) jest zawsze możliwa. + + Baw się dobrze! + + (Jeśli potrzebujesz skontaktować się z [członkiem zespołu](%{base_url}/about) jako nowy użytkownik, odpowiedz na tę wiadomość.) + signup: + subject_template: "[%{site_name}] Potwierdź swoje nowe konto" text_body_template: | Witaj na %{site_name}! @@ -1109,13 +1164,13 @@ pl_PL: Jeśli powyższy link nie jest klikalny, spróbuj skopiować i wkleić go do pasku adresu Twojej przeglądarki. page_not_found: - title: "Strona, którą chciałeś odwiedzić, nie istnieje lub jest prywatna." popular_topics: "Popularne" recent_topics: "Ostatnie" see_more: "Więcej" search_title: "Szukaj w serwisie" search_google: "Google" terms_of_service: + title: "Warunki użytkowania" signup_form_message: 'Przeczytałem i zgadzam się z Regulaminem Serwisu.' deleted: 'usunięte' upload: @@ -1130,6 +1185,7 @@ pl_PL: no_user: "Nie można znaleźć użytkownika z ID %{user_id}" post_deleted: "Wpis został usunięty przez autora" user_suspended: "użytkownik został zawieszony" + already_read: "użytkownik przeczytał ten post" color_schemes: base_theme_name: "Podstawa" guidelines: "Przewodnik" @@ -1156,3 +1212,8 @@ pl_PL: performance_report: initial_post_raw: 'Ten temat zawiera codzienne raporty wydajności dla twojej witryny. ' initial_topic_title: 'Testy wydajności witryny. ' + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.pt.yml b/config/locales/server.pt.yml index 19ff795b9f7..9eac10487fb 100644 --- a/config/locales/server.pt.yml +++ b/config/locales/server.pt.yml @@ -10,18 +10,41 @@ pt: short_date_no_year: "DD MMM" short_date: "DD MMM, YYYY" long_date: "DD de MMMM de YYYY hh:mm" + datetime_formats: &datetime_formats + formats: + short: "%m-%d-%Y" + short_no_year: "%B %-d" + date_only: "%B %-d, %Y" + date: + month_names: [null, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro] + <<: *datetime_formats title: "Discourse" topics: "Tópicos" posts: "mensagens" loading: "A carregar" powered_by_html: 'Desenvolvido por Discourse, e melhor visualizado com o JavaScript ativo' log_in: "Iniciar Sessão" - via: "%{username} através de %{site_name}" - is_reserved: "está reservado" purge_reason: "Automaticamente eliminado devido a abandono, conta inativada" disable_remote_images_download_reason: "O download remoto de imagens foi desativado por não haver espaço disponível no disco." anonymous: "Anónimo" - errors: + emails: + incoming: + default_subject: "Email recebido de %{email}" + show_trimmed_content: "Mostrar conteúdo aparado" + errors: + empty_email_error: "Acontece quando, a informação não processada, do email recebido veio em branco." + no_message_id_error: "Acontece quando o email recebido não tem 'Message-Id' no cabeçalho da mensagem." + auto_generated_email_error: "Acontece quando o cabeçalho 'precedence' é definida como: 'list', 'junk' ou 'auto_reply', ou quando algum cabeçalho contém: 'auto-submitted', 'auto-replied' ou 'auto-generated'." + no_body_detected_error: "Acontece quando não conseguimos extrair o corpo da mensagem e não existem anexos." + inactive_user_error: "Acontece quando o remetente não está activo." + blocked_user_error: "Acontece quando o remetente está bloqueado." + bad_destination_address: "Acontece quando nenhum dos endereços de email nos campos para/cc/bcc coincide com um endereço de email configurado." + strangers_not_allowed_error: "Acontece quando um utilizador tenta criar um tópico numa categoria em que não é membro." + insufficient_trust_level_error: "Acontece quando um utilizador tentar criar um tópico numa categoria para a qual não tem o nível de confiança necessário." + reply_user_not_matching_error: "Acontece quando uma resposta veio de um endereço de email diferente do destinatário da notificação." + topic_not_found_error: "Acontece quando a resposta veio de um tópico relacionado mas o tópico relacionado foi apagado." + topic_closed_error: "Acontece quando uma resposta chegou mas o tópico relacionado foi fechado." + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "está limitado a %{max} caracteres; inseriu %{length}." @@ -37,8 +60,10 @@ pt: exclusion: está reservado greater_than: tem que ser maior que %{count} greater_than_or_equal_to: tem que ser maior ou igual a %{count} + has_already_been_used: "já foi usado" inclusion: não está incluído na lista invalid: é inválido + is_invalid: "é inválido; tente ser um pouco mais descritivo" less_than: tem que ser menos que %{count} less_than_or_equal_to: tem que ser menos ou igual a %{count} not_a_number: não é um número @@ -82,6 +107,8 @@ pt: not_found: "O URL ou recurso pedido não foi encontrado." invalid_access: "Não tem permissões para visualizar o recurso pedido." read_only_mode_enabled: "Este sítio encontra-se no modo só de leitura. As interações estão desativadas." + reading_time: "Tempo de leitura" + likes: "Gostos" too_many_replies: one: "Pedimos desculpa mas novos utilizadores estão temporariamente limitados a 1 resposta no mesmo tópico." other: "Pedimos desculpa mas novos utilizadores estão temporariamente limitados a %{count} respostas no mesmo tópico." @@ -98,26 +125,26 @@ pt: replies: one: "1 resposta" other: "%{count} respostas" + no_mentions_allowed: "Pedimos desculpa, não pode mencionar outros utilizadores." too_many_mentions: - zero: "Pedimos desculpa, não pode mencionar outros utilizadores." - one: "Pedimos desculpa, pode mencionar apenas um outro utilizador numa mensagem." - other: "Pedimos desculpa, pode mencionar apenas %{count} utilizadores numa mensagem." + one: "Pedimos desculpa, pode mencionar apenas 1 outro utilizador numa mensagem." + other: "Pedimos desculpa, pode mencionar apenas %{count} outros utilizadores numa mensagem." + no_mentions_allowed_newuser: "Pedimos desculpa, novos utilizadores não podem mencionar outros utilizadores." too_many_mentions_newuser: - zero: "Pedimos desculpa, utilizadores novos não podem mencionar outros utilizadores." - one: "Pedimos desculpa, utilizadores novos podem mencionar apenas um outro utilizador numa mensagem." - other: "Pedimos desculpa, utilizadores novos podem mencionar apenas %{count} utilizadores numa mensagem." + one: "Pedimos desculpa, novos utilizadores podem mencionar apenas 1 outro utilizador numa mensagem." + other: "Pedimos desculpa, novos utilizadores podem mencionar apenas %{count} utilizadores numa mensagem." + no_images_allowed: "Pedimos desculpa, novos utilizadores não podem colocar imagens nas mensagens." too_many_images: - zero: "Pedimos desculpa, utilizadores novos não podem colocar imagens nas mensagens." - one: "Pedimos desculpa, utilizadores novos podem colocar apenas uma imagem nas mensagens." - other: "Pedimos desculpa, utilizadores novos podem colocar apenas %{count} imagens numa mensagem." + one: "Pedimos desculpa, novos utilizadores podem colocar apenas 1 imagem numa mensagem." + other: "Pedimos desculpa, novos utilizadores podem colocar apenas %{count} imagens numa mensagem." + no_attachments_allowed: "Pedimos desculpa, novos utilizadores não podem colocar anexos nas mensagens." too_many_attachments: - zero: "Pedimos desculpa, novos utilizadores não podem colocar anexos nas mensagens." - one: "Pedimos desculpa, novos utilizadores podem colocar apenas um anexo nas suas mensagens." - other: "Pedimos desculpa, novos utilizadores podem colocar apenas %{count} anexos nas suas mensagens." + one: "Pedimos desculpa, novos utilizadores podem colocar apenas 1 anexo numa mensagem." + other: "Pedimos desculpa, novos utilizadores podem colocar apenas %{count} anexos numa mensagem." + no_links_allowed: "Pedimos desculpa, novos utilizadores não podem colocar hiperligações nas mensagens." too_many_links: - zero: "Pedimos desculpa, utilizadores novos não podem colocar hiperligações nas mensagens." - one: "Pedimos desculpa, utilizadores novos podem colocar apenas uma hiperligação nas mensagens." - other: "Pedimos desculpa, utilizadores novos podem colocar apenas %{count} hiperligações nas mensagens." + one: "Pedimos desculpa, novos utilizadores podem colocar apenas 1 hiperligação numa mensagem." + other: "Pedimos desculpa, novos utilizadores podem colocar apenas %{count} hiperligações numa mensagem." spamming_host: "Pedimos desculpa, não pode colocar uma hiperligação para esse servidor." user_is_suspended: "Utilizadores suspensos não têm permissão para publicar." topic_not_found: "Algo de errado ocorreu. Talvez este tópico tenha sido fechado ou eliminado enquanto olhava para ele?" @@ -140,8 +167,13 @@ pt: rss_description: latest: "Tópicos recentes" hot: "Tópicos quentes" + top: "Melhores tópicos" posts: "Últimas mensagens" + private_posts: "Últimas mensagens privadas" + group_posts: "Últimas mensagens em %{group_name}" + group_mentions: "Últimas menções em %{group_name}" too_late_to_edit: "Essa mensagem foi criada há muito tempo. Já não pode ser editada ou apagada." + revert_version_same: "A versão atual é o mesma versão para a qual você está tentando reverter." excerpt_image: "imagem" queue: delete_reason: "Eliminado através da fila de moderação de mensagens" @@ -149,6 +181,10 @@ pt: errors: can_not_modify_automatic: "Não pode modificar um grupo automático" member_already_exist: "'%{username}' já é membro deste grupo." + invalid_domain: "'%{domain}' não é um domínio válido." + invalid_incoming_email: "'%{email}' não é um endereço de email válido." + email_already_used_in_group: "'%{email}' já é utilizado pelo grupo '%{group_name}'." + email_already_used_in_category: "'%{email}' já é utilizado pela categoria '%{category_name}'." default_names: everyone: "todos" admins: "administradores" @@ -228,9 +264,6 @@ pt: user_profile: bio_raw: "Sobre Mim" errors: - messages: - is_invalid: "é inválido; tente ser um pouco mais descritivo" - has_already_been_used: "já está sendo usado" models: topic: attributes: @@ -251,6 +284,7 @@ pt: attributes: hex: invalid: "não é uma cor válida" + <<: *errors user_profile: no_info_me: "
    o campo Sobre Mim do seu perfil está em branco, quer preenchê-lo?
    " no_info_other: "
    %{name} ainda não colocou nada no campo Sobre Mim
    " @@ -287,13 +321,15 @@ pt: category: topic_prefix: "Acerca da categoria %{category}" - replace_paragraph: "[Substituir este primeiro parágrafo, com uma breve descrição de sua nova categoria. Esta orientação será exibida na área de seleção de categoria, por isso tente mantê-la abaixo de 200 caracteres. Até editar este texto ou criar tópicos, esta categoria não aparece na página de categorias.]" - post_template: "%{replace_paragraph}\n\nUse os seguintes parágrados para uma descrição longa, assim como para estabelecer diretrizes ou regras da categoria.\n\nAlguns pontos a ter em consideração em qualquer resposta a uma discussão:\n\n- Para que serve esta categoria? Porque alguém usaria esta categoria no seu tópico?\n\n- Como é que esta categoria se difere das demais categorias já existentes?\n\n- Precisamos desta categoria?\n\n- Deveríamos juntar esta categoria com outra, ou dividir esta categoria em mais categorias?\n" + replace_paragraph: "(Substitua este primeiro parágrafo com uma breve descrição da sua nova categoria. Este guia irá aparecer na área de seleção da categoria, por isso tente mantê-lo abaixo dos 200 caracteres. **Até editar esta descrição ou criar tópicos, esta categoria não irá aparecer na página das categorias.**)" + post_template: "%{replace_paragraph}\n\nUtilize os seguintes parágrafos para uma descrição mais longa, ou para estabelecer diretrizes ou regras da categoria:\n\n- Porque devem as pessoas utilizar esta categoria? Para que serve?\n\n- No que difere ao certo em relação às outras categorias que já temos?\n\n- O que devem conter, de maneira geral, os tópicos desta categoria?\n\n- Precisamos desta categoria? Podemos juntá-la com outra categoria, ou subcategoria?\n" errors: uncategorized_parent: "Sem categoria não podem ter categorias de nível superior" self_parent: "Uma subcategoria não pode ser superior a ela própria" depth: "Não pode juntar uma subcategoria dentro de outra" - email_in_already_exist: "Endereço de email de recepção %{email_in}' já está a ser utilizado pela categoria %{category_name}'." + invalid_email_in: "'%{email}' não é um endereço de email válido." + email_already_used_in_group: "'%{email}' já é utilizado pelo grupo '%{group_name}'." + email_already_used_in_category: "'%{email}' já é utilizado pela categoria '%{category_name}'." cannot_delete: uncategorized: "Não é possível eliminar Sem Categoria" has_subcategories: "Não é possível eliminar esta categoria porque contém sub-categorias." @@ -301,21 +337,36 @@ pt: one: "Não é possível eliminar esta categoria porque contém 1 tópico. O tópico mais antigo é %{topic_link}." other: "Não é possível eliminar esta categoria porque contém %{count} tópicos. O tópico mais antigo é %{topic_link}." topic_exists_no_oldest: "Não é possível eliminar esta categoria porque a contagem de tópicos é de %{count}." + uncategorized_description: "Tópicos que não precisam de uma categoria ou que não se encaixam em nenhuma outra categoria existente." trust_levels: newuser: title: "novo utilizador" basic: title: "utilizador básico" - regular: + member: title: "membro" - leader: + regular: title: "habitual" - elder: + leader: title: "líder" change_failed_explanation: "Tentou despromover %{user_name} para '%{new_trust_level}'. Contudo o Nível de Confiança é atualmente '%{current_trust_level}'. %{user_name} irá permanecer em '%{current_trust_level}' - se deseja despromover o utilizador, bloqueie o Nível de Confiança primeiro" rate_limiter: - slow_down: "Realizou esta ação demasiadas vezes, tente novamente mais tarde" + slow_down: "Realizou esta ação demasiadas vezes, tente novamente mais tarde." too_many_requests: "Possuímos um limite diário de número de vezes que uma ação pode ser tomada. Por favor aguarde %{time_left} antes de tentar novamente." + by_type: + first_day_replies_per_day: "Atingiu o número máximo de respostas que um novo utilizador pode criar no seu primeiro dia. Por favor espere %{time_left} antes de tentar novamente." + first_day_topics_per_day: "Atingiu o número máximo de tópicos que um novo utilizador pode criar no seu primeiro dia. Por favor espere %{time_left} antes de tentar novamente." + create_topic: "Está a criar tópicos demasiado rápido. Por favor espere %{time_left} antes de tentar novamente." + create_post: "Está a responder demasiado rápido. Por favor espere %{time_left} antes de tentar novamente." + delete_post: "Está a apagar mensagens demasiado rápido. Por favor espere %{time_left} antes de tentar novamente." + topics_per_day: "Atingiu o número máximo de novos tópicos de hoje. Por favor espere %{time_left} antes de tentar novamente." + pms_per_day: "Atingiu o número máximo de mensagens de hoje. Por favor espere %{time_left} antes de tentar novamente." + create_like: "Atingiu o número máximo de gostos de hoje. Por favor espere %{time_left} antes de tentar novamente." + create_bookmark: "Atingiu o número máximo de marcações de hoje. Por favor espere %{time_left} antes de tentar novamente." + edit_post: "Atingiu o número máximo de edições de hoje. Por favor espere %{time_left} antes de tentar novamente." + live_post_counts: "Tem estado a pedir contagens de mensagens em directo demasiado rápido. Por favor espere %{time_left} antes de tentar novamente." + unsubscribe_via_email: "Atingiu o número máximo de cancelamentos de subscrições por email de hoje. Por favor espere %{time_left} antes de tentar novamente." + topic_invitations_per_day: "Atingiu o número máximo de convites para tópicos de hoje. Por favor espere %{time_left} antes de tentar novamente." hours: one: "1 hora" other: "%{count} horas" @@ -410,6 +461,11 @@ pt: confirmed: "O seu email foi atualizado." please_continue: "Continuar para %{site_name}" error: "Ocorreu um erro ao alterar o seu endereço de email. Talvez o endereço já esteja a ser utilizado?" + error_staged: "Ocorreu um erro ao alterar o seu endereço de email. O endereço de email já está a ser utilizado por um utilizador temporário." + already_done: "Pedimos desculpa, esta hiperligação de confirmação já não é valida. Talvez o seu email já foi alterado?" + authorizing_old: + title: "Obrigado por confirmar o seu endereço de email atual." + description: "Estamos a enviar um email, para o seu novo endereço de email, para confirmação." activation: action: "Clique aqui para ativar a sua conta" already_done: "Pedimos desculpa, esta hiperligação de confirmação já não está válida. Talvez a sua conta já esteja ativa?" @@ -434,16 +490,16 @@ pt: description: 'Esta mensagem contém conteúdo que uma pessoa sensata iria considerar ofensivo, abusivo, ou como uma violação das diretrizes da nossa comunidade.' long_form: 'sinalizou isto como inapropriado' notify_user: - title: 'Mensagem @{{username}}' - description: 'Esta mensagem contém algo sobre o qual quero falar com esta pessoa diretamente e em privado. Não representa motivo para ter alguma sinalização.' + title: 'Enviar uma mensagem a @{{username}}' + description: 'Quero falar com esta pessoa diretamente e em privado acerca da sua mensagem.' long_form: 'utilizador com mensagens' email_title: 'A sua mensagem em "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Algo Mais" - description: 'Esta mensagem requer a atenção do moderador por outro motivo não mencionado acima.' - long_form: 'sinalizou isto para obter a atenção do moderador.' - email_title: 'Uma mensagem em "%{title}" requer a atenção do moderador' + description: 'Esta mensagem requer a atenção do pessoal por outra razão não listada acima.' + long_form: 'marcou isto para ser alvo da atenção do pessoal' + email_title: 'Uma mensagem em "%{title}" requer a atenção do pessoal' email_body: "%{link}\n\n%{message}" bookmark: title: 'Adicionar Marcador' @@ -468,7 +524,7 @@ pt: long_form: 'sinalizou isto como inapropriado' notify_moderators: title: "Algo Mais" - description: 'Este tópico requer a atenção geral do moderador baseado nas diretrizes, TDS, ou por outro motivo não mencionado acima.' + description: 'Este tópico requer a atenção geral do pessoal baseado nas diretrizes, TDS, ou por outra razão não listada acima.' long_form: 'sinalizou isto para obter a atenção do moderador' email_title: 'O tópico "%{title}" requer a atenção do moderador' email_body: "%{link}\n\n%{message}" @@ -504,6 +560,10 @@ pt: title: "Novos Utilizadores" xaxis: "Dia" yaxis: "Número de novos utilizadores" + profile_views: + title: "Visualizações do Perfil de Utilizador" + xaxis: "Dia" + yaxis: "Número de perfis de utilizador vistos" topics: title: "Tópicos" xaxis: "Dia" @@ -655,42 +715,16 @@ pt: consumer_email_warning: "O seu sítio está configurado para usar Gmail (ou outro serviço de email)O Gmail limita a quantidade de emails que pode enviar. Considere usar um serviço de envio de emails como mandrill.com para assegurar a entregabilidade dos emails enviados." site_contact_username_warning: "Introduza o nome de uma conta de utilizador de um membro do pessoal de onde possam ser enviadas mensagens importantes automatizadas. Atualize sítio_contacto_nomedeutilizador nas Configurações do Sítio." notification_email_warning: "Não estão a ser enviados emails de notificação a partir de um endereço de email válido no seu domínio; a entrega do email será errática e não fiável. Por favor configure notificaçao_email para um endereço de email local válido nas Configurações do Sítio." - content_types: - education_new_reply: - title: "Educação do Novo Utilizador: Primeiras Respostas" - description: "Pop up de orientação automaticamente exibido em cima do compositor quando novos utilizadores começam a escrever as suas duas primeiras respostas." - education_new_topic: - title: "Educação do Novo Utilizador: Primeiros Tópicos" - description: "Pop up de orientação automaticamente exibido em cima do compositor quando novos utilizadores começam a escrever os seus dois primeiros tópicos." - usage_tips: - title: "Orientação para o Novo Utilizador" - description: "Orientação e informação essencial para novos utilizadores." - welcome_user: - title: "Bem-vindo: Novo Utilizador" - description: "Uma mensagem enviada automaticamente para todos os novos utilizadores quando estes se inscrevem." - welcome_invite: - title: "Bem-vindo: Utilizador Convidado" - description: "Uma mensagem enviada automaticamente para todos os novos utilizadores assim que aceitam o convite de outro utilizador para participar." - login_required_welcome_message: - title: "Início de Sessão Obrigatório: Mensagem de Boas-vindas" - description: "Mensagem de boas-vindas exibida a utilizadores que não têm sessão iniciada quando a configuração 'início de sessão obrigatório' está ativa." - login_required: - title: "Início de Sessão Obrigatório: Página Principal" - description: "Texto exibido a utilizadores não autorizados quando se exige início de sessão no sítio." - head: - title: "Cabeçalho HTML" - description: "HTML que será inserido dentro do código ." - top: - title: "Topo das páginas" - description: "HTML que será adicionado no topo de cada página (depois do cabeçalho, antes da navegação ou do título do tópico)." - bottom: - title: "Final das páginas" - description: "HTML que será adicionado antes do código ." + subfolder_ends_in_slash: "A configuração da sua sub-página está incorreta; o DISCOURSE_RELATIVE_URL_ROOT termina com um traço." + email_polling_errored_recently: + one: "A consulta automática de emails gerou um erro nas últimas 24 horas. Consulte em os registos para mais detalhes." + other: "A consulta automática de emails gerou %{count} erros nas últimas 24 horas. Consulte em os registos para mais detalhes." site_settings: censored_words: "Palavras que serão automaticamente substituídas por ■■■■" delete_old_hidden_posts: "Eliminar automaticamente quaisquer mensagens ocultas que permaneçam escondidas por mais de 30 dias." default_locale: "Idioma padrão para esta instância do Discourse (ISO 639-1 Code)" allow_user_locale: "Permitir aos utilizadores escolherem a sua própria língua preferencial para a interface." + set_locale_from_accept_language_header: "defina a língua de interface para utilizadores anónimos com base nos cabeçalhos de língua dos seus navegadores. (EXPERIMENTAL, não funciona com cache anónima)" min_post_length: "Tamanho mínimo permitido por mensagem, em caracteres" min_first_post_length: "Tamanho mínimo permitido para a primeira mensagem (corpo do tópico), em caracteres" min_private_message_post_length: "Tamanho mínimo permitido para mensagens, em caracteres" @@ -699,8 +733,8 @@ pt: max_topic_title_length: "Tamanho máximo permitido por título de cada tópico, em caracteres" min_private_message_title_length: "Tamanho mínimo permitido por título nas mensagens, em caracteres" min_search_term_length: "Tamanho mínimo válido para termos de pesquisa, em caracteres" + search_tokenize_chinese_japanese_korean: "Forçar pesquisa para atomizar Chinês/Japonês/Coreano mesmo em sites que não sejam CJC" allow_uncategorized_topics: "Permitir a criação de tópicos sem categoria. AVISO: Se houver quaisquer tópicos não categorizados, tem que re-categorizá-los antes de desligar isto." - uncategorized_description: "Descrição da categoria sem classificação. Deixar em branco para nenhuma descrição." allow_duplicate_topic_titles: "Permitir tópicos com títulos idênticos e duplicados." unique_posts_mins: "Quantos minutos antes que um utilizador possa criar uma mensagem com o mesmo conteúdo outra vez?" educate_until_posts: "Quando um utilizador começar a escrever as primeiras (n) novas mensagens, mostrar o painel pop-up de educação do novo utilizador no editor." @@ -713,7 +747,7 @@ pt: download_remote_images_to_local: "Converter imagens remotas em imagens locais ao descarregá-las; isto previne imagens corrompidas." download_remote_images_threshold: "Espaço mínimo necessário em disco para descarregar imagens remotas localmente (em percentagem)" disabled_image_download_domains: "Imagens remotas não serão descarregadas destes domínios. " - ninja_edit_window: "Durante (n) segundos após a publicação da mensagem, editá-la não irá criar uma nova versão no histórico de mensagens." + editing_grace_period: "Por (n) segundos após publicar, a edição não irá criar uma nova versão no histórico da mensagem." post_edit_time_limit: "O autor pode editar ou eliminar a sua mensagem por um período de (n) minutos após a publicação da mesma. Definir a 0 para ser para sempre." edit_history_visible_to_public: "Permitir que todos vejam versões anteriores de uma mensagem editada. Quando desativado, apenas membros do pessoal podem ver." delete_removed_posts_after: "Mensagens removidas pelo autor serão automaticamente eliminadas após um período de (n) horas. Se estiver definido a 0, as mensagens serão eliminadas imediatamente." @@ -722,7 +756,7 @@ pt: category_featured_topics: "Número de tópicos visíveis por categoria na página de /categorias. Após a alteração deste valor, irá demorar até 15 minutos para que a página de categorias fique atualizada." show_subcategory_list: "Mostrar lista de subcategorias em vez de lista de tópicos quando inserida uma categoria." fixed_category_positions: "Se estiver marcado, irá conseguir organizar as categorias por uma ordem fixa. Se não estiver marcado, as categorias são listadas por ordem de actividade." - fixed_category_positions_on_create: "Se marcado, a ordenação de categorias irá ser mantida no diálogo de criação do tópico (requere fixed_category_positions)" + fixed_category_positions_on_create: "Se marcado, a ordenação de categorias irá ser mantida no diálogo de criação do tópico (requer fixed_category_positions)" add_rel_nofollow_to_user_content: "Adicionar a etiqueta rel nofollow em todos os conteúdos submetidos pelo utilizador, excepto para hiperligações internas (incluindo domínios pai). Se mudar isto, terá que atualizar todas as suas mensagens com: \"rake posts:rebake\"" exclude_rel_nofollow_domains: "Uma lista de domínios em que nofollow não deve ser adicionado a linkls.tld.com irá permitir automaticamente sub.tld.com. Como mínimo, deve adicionar o domínio de alto nível deste sítio para ajudar os rastreadores da internet a encontrarem todo o conteúdo. Se outras partes do seu sítio estão em outros domínicios, adicione-os também." post_excerpt_maxlength: "Tamanho máximo do excerto/sumário de uma mensagem." @@ -743,7 +777,7 @@ pt: summary_likes_required: "Número mínimo de gostos num tópico antes que 'Resumir Este Tópico' seja ativo." summary_percent_filter: "Quando um utilizador clica em 'Resumir Este Tópico', mostrar as melhores % de mensagens" summary_max_results: "Número máximo de mensagens devolvidas por 'Resumo deste Tópico'" - enable_private_messages: "Permitir que utilizadores de nível de confiança 1 possam criar e responder a mensagens" + enable_private_messages: "Permitir que utilizadores de nível de confiança 1 (configurável através do nível de confiança mínimo para enviar mensagens) criem mensagens e respostas a mensagens." enable_long_polling: "O sistema de mensagens usado para notificações pode fazer solicitações longas" long_polling_base_url: "URL base usada para solicitação ao servidor (quando um CDN serve conteúdo dinâmico, certifique-se de configurá-lo para a 'pull' original) ex: http://origem.sítio.com" long_polling_interval: "Quantidade de tempo que um servidor deve esperar antes de notificar os clientes quando não há dados para serem enviados (apenas utilizadores ligados)" @@ -762,9 +796,10 @@ pt: notify_mods_when_user_blocked: "Se um utilizador for bloqueado de forma automática, enviar uma mensagem a todos os moderadores." flag_sockpuppets: "Se um novo utilizador responde a um tópico a partir do mesmo endereço IP do novo utilizador que iniciou o tópico, sinalizar ambas as mensagens como potencial spam." traditional_markdown_linebreaks: "Utilize tradicionais quebras de linha no Markdown, que requer dois espaços no final para uma quebra de linha." - allow_html_tables: "Permitir inserção de tabelas em Markdown utilizando tags HTML, TABLE,THEAD, TD, TR,TH fazem parte da lista branca (requer que todas as mensagens antigas que contém tabelas sejam refeitas)" + allow_html_tables: "Permitir inserção de tabelas em Markdown utilizando tags HTML. TABLE,THEAD, TD, TR,TH fazem parte da lista branca (requer que todas as mensagens antigas que contém tabelas sejam refeitas)" post_undo_action_window_mins: "Número de minutos durante o qual os utilizadores têm permissão para desfazer ações numa mensagem (gostos, sinalizações, etc)." must_approve_users: "O pessoal deve aprovar todas as novas contas de utilizador antes destas terem permissão para aceder ao sítio. AVISO: ativar isto para um sítio ativo irá revogar o acesso aos utilizadores existentes que não fazem parte do pessoal!" + pending_users_reminder_delay: "Notificar moderadores se novos utilizadores estiverem à espera de aprovação por mais que esta quantidade de horas. Configurar com -1 para desativar notificações." ga_tracking_code: "Código de acompanhamento do Google Analytics (ga.js), ex: UA-12345678-9; ver http://google.com/analytics" ga_domain_name: "Nome de domínio da Google Analytics (ga.js), ex: omeusitio.com; ver http://google.com/analytics" ga_universal_tracking_code: "Código de acompanhamento do Google Universal Analytics (analytics.js), ex: UA-12345678-9; ver http://google.com/analytics" @@ -773,6 +808,7 @@ pt: enable_noscript_support: "Ativar o suporte básico para pesquisas em motores de pesquisa através da etiqueta noscript" allow_moderators_to_create_categories: "Permitir que os moderadores criem novas categorias" cors_origins: "Permitidos compartilhamentos de recursos de origem-cruzada (CORS). Cada origem deve incluir http:// ou https://. A variável de ambiente DISCOURSE_ENABLE_CORS tem que estar configurada a verdadeiro para ativar o CORS." + use_admin_ip_whitelist: "Os Administradores só podem iniciar sessão se estiverem num endereço IP definido na lista de IPs Rastreados (Admin > Logs > IPs Rastreados)." top_menu: "Determinar que elementos aparecem na navegação da página principal, e em que ordem. Exemplo últimos|novos|não lidos|categorias|topo|lidos|publicados|marcadores" post_menu: "Determine que itens irão aparecer no menu de mensagens, e em que ordem. Exemplo\ngostar|editar|sinalizar|eliminar|partilhar|marcar|responder" post_menu_hidden_items: "Os elementos do menu a serem escondidos por defeito no menu de mensagens a não ser que se clique na elipse de expansão." @@ -784,15 +820,15 @@ pt: suppress_reply_directly_above: "Não mostrar em-resposta-a expansível quando há apenas uma única resposta diretamente acima desta publicação." suppress_reply_when_quoting: "Não mostraR em-resposta-a expansível numa mensagem quando esta cita uma resposta." max_reply_history: "Número máximo de respostas a serem expandidas quando se expande em-resposta-a" - experimental_reply_expansion: "Esconder respostas intermédias ao expandir uma resposta-a (experimental)" topics_per_period_in_top_summary: "Número de tópicos principais mostrados no resumo padrão de tópicos principais." topics_per_period_in_top_page: "Número de tópicos principais mostrados em 'Mostrar Mais' tópicos principais expandido." redirect_users_to_top_page: "Redirecionar automaticamente os utilizadores novos e ausentes por períodos longos para o topo da página." + top_page_default_timeframe: "Intervalo de tempo por defeito para a página de visualizações do topo." show_email_on_profile: "Mostrar o email do utilizador no seu perfil (apenas visível para si próprio e para o pessoal)" email_token_valid_hours: "Os símbolos para palavra-passe esquecida /conta ativada são válidos por (n) horas." email_token_grace_period_hours: "Os símbolos para palavra-passe esquecida /conta ativada são válidos por um período de carência de (n) horas após serem recuperados" enable_badges: "Ativar o sistema de distintivos" - enable_whispers: "Permitir que os utilizadores sussurrem ao pessoal" + enable_whispers: "Permitir comunicação privada do pessoal dentro de tópico (experimental)" allow_index_in_robots_txt: "Especificar em robots.txt que este sítio permite ser indexado pelos motores de pesquisa." email_domains_blacklist: "Lista de domínios de email que os utilizadores não podem usar para registo de contas. Exemplo: mailinator.com|trashmail.net" email_domains_whitelist: "Lista de domínios de email que os utilizadores DEVEM usar para registar contas. AVISO: Utilizadores com domínios de email diferentes dos listados não serão permitidos!" @@ -810,6 +846,7 @@ pt: max_username_length: "Comprimento máximo do nome de utilizador, em caracteres." reserved_usernames: "Nomes de utilizadores para os quais o registo não é permitido." min_password_length: "Tamanho mínimo da palavra-passe." + min_admin_password_length: "Tamanho mínimo da palavra-passe para Administração." block_common_passwords: "Não permitir palavras-passe que estejam nas 10,000 palavras-passe mais comuns." enable_sso: "Ativar inscrição única através de um sítio externo (AVISO: OS ENDEREÇOS DE EMAIL DOS UTILIZADORES *DEVEM* SER VALIDADOS PELO SÍTIO EXTERNO!)" enable_sso_provider: "Implementar o protocolo do provedor SSO do Discourse no caminho /session/sso_provider, requer que sso_secret seja configurado" @@ -830,6 +867,9 @@ pt: enable_twitter_logins: "Ativar autenticação pelo Twitter, requer twitter_consumer_key e twitter_consumer_secret" twitter_consumer_key: "Chave de consumidor para autenticação pelo Twitter, registada em http://dev.twitter.com" twitter_consumer_secret: "Chave do Consumidor para a autenticação pelo Twitter, registada em http://dev.twitter.com" + enable_instagram_logins: "Ativar autenticação pelo Instagram, requer instagram_consumer_key e instagram_consumer_secret" + instagram_consumer_key: "Chave de cliente para a autenticação via Instagram" + instagram_consumer_secret: "Segredo de cliente para a autenticação via Instagram" enable_facebook_logins: "Ativar autenticação pelo Facebook, requer facebook_app_id e facebook_app_secret" facebook_app_id: "Id App usado para autenticação pelo Facebook, registado em https://developers.facebook.com/apps" facebook_app_secret: "Chave da App para autenticação com o Facebook, registado em https://developers.facebook.com/apps" @@ -842,9 +882,15 @@ pt: backup_frequency: "Com que frequência criamos cópias de segurança do sítio, em dias." enable_s3_backups: "Carregar cópias de segurança para S3 quando completo. IMPORTANTE: requer credenciais S3 válidas inseridas nas configurações dos ficheiros." s3_backup_bucket: "Balde remoto para guardar cópias de segurança. AVISO: Certifique-se que este é um balde privado." + s3_disable_cleanup: "Desative a remoção das cópias de segurança do S3 quando removidas localmente." + backup_time_of_day: "Altura do dia UTC em que a cópia de segurança deve ocorrer." + backup_with_uploads: "Incluir carregamentos em cópias de segurança agendadas. Desativar isto irá salvaguardar apenas a base de dados." active_user_rate_limit_secs: "Qual a frequência de atualização do campo 'última vez visto em', em segundos." verbose_localization: "Mostrar extensas dicas de localização na IU" previous_visit_timeout_hours: "Quanto tempo dura uma visita antes de a considerarmos como 'visita anterior', em horas." + top_topics_formula_log_views_multiplier: "fórmula do multiplicador (n) de visualizações logarítmica nos melhores tópicos: `log(views_count) * (n) + op_likes_count * 0.5 + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_first_post_likes_multiplier: "fórmula do multiplicador (n) de primeiros gostos nos melhores tópicos: `log(views_count) * 2 + op_likes_count * (n) + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_least_likes_per_post_multiplier: "fórmula do multiplicador (n) de menos gostos nos melhores tópicos: `log(views_count) * 2 + op_likes_count * 0.5 + LEAST(likes_count / posts_count, (n)) + 10 + log(posts_count)`" rate_limit_create_topic: "Após a criação de um tópico, os utilizadores devem esperar (n) segundos antes de criarem um novo tópico." rate_limit_create_post: "Após a publicação, os utilizadores devem esperar (n) segundos antes de criarem outra mensagem." rate_limit_new_user_create_topic: "Após a criação de um tópico, os novos utilizadores devem esperar (n) segundos antes de criarem um novo tópico." @@ -857,6 +903,8 @@ pt: max_private_messages_per_day: "Número máximo de mensagens que os utilizadores podem criar por dia." max_invites_per_day: "Número máximo de convites que um utilizador pode enviar por dia." max_topic_invitations_per_day: "Número máximo de convites para tópicos que um utilizador pode enviar por dia." + alert_admins_if_errors_per_minute: "O número de erros por minuto necessários para disparar um alerta de administração. Um valor maior que 0 desativa esta funcionalidade. NOTA: requer reinício." + alert_admins_if_errors_per_hour: "O número de erros por hora necessários para disparar um alerta de administração. Um valor maior que 0 desativa esta funcionalidade. NOTA: requer reinício." suggested_topics: "Número de tópicos sugeridos mostrados no final de um tópico." limit_suggested_to_category: "Apenas mostrar tópicos da categoria atual nos tópicos sugeridos." clean_up_uploads: "Remover carregamentos orfãos não referenciados para prevenir alojamento ilegal. AVISO: poderá querer criar uma cópia de segurança da diretoria /uploads antes de ativar esta configuração." @@ -873,6 +921,8 @@ pt: avatar_sizes: "Lista de tamanhos de avatar gerados automaticamente." external_system_avatars_enabled: "Utilize o serviço do sistema externo de avatars." external_system_avatars_url: "URL do serviço do sistema externo de avatars. Substituições permitidas são {nome_de_utilizador} {primeira_letra} {cor} {tamanho}" + default_opengraph_image_url: "URL da imagem opengraph por defeito." + allow_all_attachments_for_group_messages: "Permitir qualquer anexo de email nas mensagens de grupo." enable_flash_video_onebox: "Ativar a incorporação de hiperligações swf e flv (Adobe Flash) em caixas únicas. AVISO: pode introduzir riscos de segurança." default_invitee_trust_level: "Nível de Confiança padrão (0-4) para utilizadores convidados." default_trust_level: "Nível de Confiança padrão (0-4) para todos os novos utilizadores. AVISO! Alterar isto irá colocá-lo em sério risco de spam." @@ -886,32 +936,38 @@ pt: tl2_requires_likes_received: "Quantos gostos um utilizador deve receber antes de ser promovido para o Nível de Confiança 2." tl2_requires_likes_given: "Quantos gostos um utilizador deve atribuir antes de ser promovido para o Nível de Confiança 2." tl2_requires_topic_reply_count: "Quantos tópicos um utilizador deve responder antes de ser promovido para o Nível de Confiança 2." - tl3_requires_days_visited: "Número mínimo de dias que o utilizador necessita de ter visitado o sítio nos últimos 100 dias para se qualificar à promoção para o Nível de Confiança 3. (0 a 100)" - tl3_requires_topics_replied_to: "Número mínimo de tópicos que o utilizador necessita de ter respondido nos últimos 100 dias para se qualificar à promoção para o Nível de Confiança 3. (0 ou mais)" - tl3_requires_topics_viewed: "Percentagem de tópicos criados nos últimos 100 dias que o utilizador precisa de ter visto para se qualificar à promoção para o Nível de Confiança 3. (0 a 100)" - tl3_requires_posts_read: "Percentagem de mensagens criadas nos últimos 100 dias que o utilizador precisa de ter visto para se qualificar à promoção para o Nível de Confiança 3. (0 a 100)" + tl3_time_period: "Período de tempo (em dias) dos requisitos do nível de confiança 3" + tl3_requires_days_visited: "Número mínimo de dias que o utilizador necessita de ter visitado o sítio nos últimos dias (período nc3) para se qualificar à promoção para o Nível de Confiança 3. Configure um período de tempo maior que nc3 para desativar promoções para nc3. (0 ou maior)" + tl3_requires_topics_replied_to: "Número mínimo de tópicos que o utilizador necessita de ter respondido nos últimos dias (período nc3) para se qualificar à promoção para o Nível de Confiança 3. (0 ou mais)" + tl3_requires_topics_viewed: "Percentagem de tópicos criados nos últimos dias (perídio nc3) que o utilizador precisa de ter visto para se qualificar à promoção para o Nível de Confiança 3. (0 a 100)" + tl3_requires_posts_read: "Percentagem de mensagens criadas nos últimos dias (perídio nc3) que o utilizador precisa de ter visto para se qualificar à promoção para o Nível de Confiança 3. (0 a 100)" tl3_requires_topics_viewed_all_time: "Número mínimo total de tópicos que o utilizador deve ter visto para se qualificar ao Nível de Confiança 3." tl3_requires_posts_read_all_time: "Número mínimo total de mensagens que o utilizador deve ter lido para se qualificar ao Nível de Confiança 3." - tl3_requires_max_flagged: "O utilizador não deverá ter mais do que x mensagens marcadas por x diferentes utilizadores nos últimos 100 dias para se qualificar à promoção para o nível de confiança 3, onde x é o valor definido. (0 ou superior)" + tl3_requires_max_flagged: "O utilizador não deverá ter mais do que x mensagens marcadas por x diferentes utilizadores nos últimos dias (período nc3) para se qualificar à promoção para o nível de confiança 3, onde x é o valor definido. (0 ou superior)" tl3_promotion_min_duration: "Número mínimo de dias em que a promoção para Nível de Confiança 3 dura antes que o utilizador possa ser despromovido para o Nível de Confiança 2." - tl3_requires_likes_given: "Número mínimo de gostos que o utilizador deve ter atribuído nos últimos 100 dias para se qualificar à promoção para o Nível de Confiança 3." - tl3_requires_likes_received: "Número mínimo de gostos que o utilizador deve ter recebido nos últimos 100 dias para se qualificar à promoção para o Nível de Confiança 3." + tl3_requires_likes_given: "Número mínimo de gostos que o utilizador deve ter atribuído nos últimos dias (período nc3) para se qualificar à promoção para o Nível de Confiança 3." + tl3_requires_likes_received: "Número mínimo de gostos que o utilizador deve ter recebido nos últimos dias (período nc3) para se qualificar à promoção para o Nível de Confiança 3." tl3_links_no_follow: "Não remover rel=nofollow das hiperligações publicadas por utilizadores com Nível de Confiança 3." min_trust_to_create_topic: "O Nível de Confiança mínimo necessário para criar um novo tópico." min_trust_to_edit_wiki_post: "O nível mínimo de confiança necessário para editar mensagens marcadas como wiki." + min_trust_to_allow_self_wiki: "O nível mínimo de confiança necessário para criar mensagens wiki próprias." + min_trust_to_send_messages: "O nível de confiança mínimo necessário para criar mensagens privadas." newuser_max_links: "Quantas hiperligações um novo utilizador pode adicionar a uma mensagem." newuser_max_images: "Quantas imagens um novo utilizador pode adicionar a uma mensagem." newuser_max_attachments: "Quantos anexos um novo utilizador pode adicionar a uma mensagem." newuser_max_mentions_per_post: "Número máximo de notificações @nome que um novo utilizador pode usar numa mensagem." newuser_max_replies_per_topic: "Número máximo de respostas que um novo utilizador pode fazer num único tópico até alguém lhe responder." max_mentions_per_post: "Número máximo de notificações @nome que qualquer pessoa pode usar numa mensagem." + max_users_notified_per_group_mention: "Número máximo de utilizadores que podem receber uma notificação se um grupo é mencionado (se o limite é atingido, nenhuma notificação será levantada)" create_thumbnails: "Criar imagens miniatura e lightbox que são demasiado largas para caber numa mensagem." email_time_window_mins: "Esperar (n) minutos antes de enviar quaisquer emails de notificação, para dar aos utilizadores a hipótese de editarem e finalizarem as suas mensagens." + private_email_time_window_seconds: "Espere (n) segundos antes de enviar emails de notificação privados, para dar aos utilizadores a oportunidade de editar e finalizar as suas mensagens." email_posts_context: "Quantas respostas prévias a serem incluídas como contexto em emails de notificação." flush_timings_secs: "Com que frequência o servidor é alimentado com dados de sincronização, em segundos." title_max_word_length: "Tamanho máximo permitido de comprimento de palavras, em caracteres, no título de um tópico." title_min_entropy: "Entropia mínima (caracteres únicos, contagem não-inglesa para mais) necessária para o título de um tópico." body_min_entropy: "Entropia mínima (caracteres únicos, contagem não-inglesa para mais) necessária para o corpo de uma mensagem." + allow_uppercase_posts: "Permitir tudo em maiúsculas num título de tópico ou corpo de mensagem." title_fancy_entities: "Converter caracteres ASCII comuns em entidades HTML nos títulos dos tópicos, ala SmartyPants http://daringfireball.net/projects/smartypants/" min_title_similar_length: "Tamanho mínimo do título antes de ser verificado por tópicos semelhantes." min_body_similar_length: "Tamanho mínimo do corpo de uma mensagem antes de ser verificado por tópicos semelhantes." @@ -941,6 +997,7 @@ pt: white_listed_spam_host_domains: "Lista de domínios excluídos dos testes de spam. Novos utilizadores nunca irão ser restritos da criação de mensagens com hiperligações a esses domínios." staff_like_weight: "Quanto é o fator de ponderação extra a dar aos gostos provenientes do pessoal." topic_view_duration_hours: "Contar uma nova visualização do tópico uma vez por IP/Utilizador a cada N horas" + user_profile_view_duration_hours: "Contar visualização de novo perfil de utilizador uma vez por IP/utilizador a cada N horas" levenshtein_distance_spammer_emails: "Ao fazer a correspondência de e-mails de spam, o número de caracteres de diferença que ainda permitirá uma correspondência difusa." max_new_accounts_per_registration_ip: "Se já há (n) contas com nível de confiança 0 a partir deste IP (e nenhum é um membro do pessoal ou em nível de confiança 2 ou superior), parar de aceitar novos registos a partir desse IP." min_ban_entries_for_roll_up: "Ao clicar no botão Agrupar, irá criar uma nova entrada de sub-rede banida se houver pelo menos (N) entradas." @@ -958,6 +1015,12 @@ pt: disable_emails: "Impedir que Discourse envie qualquer tipo de emails" strip_images_from_short_emails: "Remover imagens de emails cujo tamanho seja inferior a 2800 Bytes" short_email_length: "Comprimento de email curto, em Bytes" + display_name_on_email_from: "Exibir nomes completos em campos do formulário de email" + unsubscribe_via_email: "Permitir aos utilizadores cancelar a subscrição de emails enviando um email com \"unsubscribe\" no assunto ou no corpo do email" + unsubscribe_via_email_footer: "Adicionar uma hiperligação de cancelamento de subscrição ao rodapé de emails enviados" + delete_email_logs_after_days: "Apagar registos de email após (N) dias. 0 para os manter indefinidamente" + max_emails_per_day_per_user: "Número máximo de emails para enviar aos utilizadores. 0 para desligar o limite" + manual_polling_enabled: "Enviar emails utilizando a API de resposta por email." pop3_polling_enabled: "Solicitação através de POP3 para respostas de emails" pop3_polling_ssl: "Utilize SSL ao ligar a um servidor POP3. (Recomendado)" pop3_polling_period_mins: "Período em minutos entre a verificação da conta POP3 para o email. NOTA: requer reinicialização." @@ -984,7 +1047,7 @@ pt: automatically_download_gravatars: "Descarregar Gravatars para os utilizadores após criação de conta ou mudança de email." digest_topics: "Número máximo de tópicos a serem apresentados no resumo do email." digest_min_excerpt_length: "Tamanho mínimo do excerto da mensagem no resumo do email, em caracteres." - suppress_digest_email_after_days: "Suprimir emails de resumos para utilizadores não vistos no sítio por mais de (n) dias." + delete_digest_email_after_days: "Suprimir emails de resumos para utilizadores não vistos no sítio por mais de (n) dias." disable_digest_emails: "Desativar os emails de resumo para todos os utilizadores." detect_custom_avatars: "Se deve ou não verificar que os utilizadores carregaram fotografias de perfil personalizadas." max_daily_gravatar_crawls: "Número máximo de vezes que o Discourse irá verificar o Gravatar para avatars personalizados, por dia" @@ -994,15 +1057,19 @@ pt: allow_anonymous_posting: "Permitir que os utilizadores alterem para o modo anónimo" anonymous_posting_min_trust_level: "Nível de confiança mínimo necessário para ativar publicações anónimas" anonymous_account_duration_minutes: "Para proteger o anonimato crie uma nova conta anónima a cada N minutos para cada utilizador. Exemplo: se configurado para 600, assim que passarem 600 minutos desde a última mensagem E o utilizador altere para anónimo, uma nova conta anónima é criada." + hide_user_profiles_from_public: "Desativar cartões de utilizador, perfis de utilizador e diretoria de utilizadores para utilizadores anónimos." allow_profile_backgrounds: "Permitir que os utilizadores carreguem fundos de perfil." - sequential_replies_threshold: "Número de mensagens que um utilizador tem que fazer em linha num tópico antes de ser relembrado acerca de demasiadas respostas sequenciais." + sequential_replies_threshold: "Número de mensagens que um utilizador tem que fazer em linha num tópico antes de ser lembrado acerca de demasiadas respostas sequenciais." enable_mobile_theme: "Os dispositivos móveis usam um tema mobile-friendly, com a possibilidade de mudar para o sítio completo. Desative isto se quer usar um estilo personalizado que é totalmente responsivo." dominating_topic_minimum_percent: "Que percentagem de mensagens um utilizador tem que fazer num tópico antes de ser relembrado sobre dominar demasiado um tópico." + disable_avatar_education_message: "Desativar mensagem educativa para alteração de avatar." daily_performance_report: "Analise os logs diários NGINX e publique um tópico visível apenas para o pessoal com detalhes" suppress_uncategorized_badge: "Não mostrar distintivos para tópicos sem categoria nas listagens de tópicos." - permalink_normalizations: "Utilize a seguinte expressão regular antes de combinar hiperligações permanentes, por exemplo: /(\\/topic.*)\\?.*/\\1 irá retirar sequências de consulta de rotas de tópicos. O formato é regex+sequência utilize \\1 etc. para aceder a capturas." + permalink_normalizations: "Aplicar a seguinte expressão regular antes de igualar hiperligações permanentes, por exemplo: /(topic.*)\\?.*/\\1 irá remover parâmetros de roteamento para tópicos. O formato é regex+sequência utilize \\1 etc. para aceder a capturas.O formato é regex+string utilize \\1 etc. para aceder a capturas." global_notice: "Exibir um banner global URGENTE, EMERGÊNCIA a todos os visitantes, mudar para branco para esconder (HTML permitido)." disable_edit_notifications: "Desativa notificações de edição do sistema quando 'download_remote_images_to_local' está ativo." + automatically_unpin_topics: "Desafixar tópicos automaticamente quando um utilizador chega ao final." + read_time_word_count: "Contagem de palavras por minuto para calcular tempo estimado de leitura." full_name_required: "O nome completo é um campo obrigatório no perfil de utilizador." enable_names: "Mostrar o nome completo do utilizador no seu perfil, cartão de utilizador, e emails. Desativar para esconder o nome completo em todos os locais." display_name_on_posts: "Mostrar o nome completo de um utilizador nas suas mensagens em adição ao seu @nome-de-utilizador." @@ -1019,27 +1086,31 @@ pt: embed_username_key_from_feed: "Chave para recuperar o nome de utilizador discourse do feed." embed_truncate: "Truncar mensagens incorporadas." embed_post_limit: "Número máximo de mensagens a serem incorporadas." + embed_username_required: "O nome de utilizador para a criação de tópico é necessário." embed_whitelist_selector: "Seletor CSS para elementos permitidos em incorporações." embed_blacklist_selector: "Seletor CSS para elementos que foram removidos de incorporações." notify_about_flags_after: "Se houver sinalizações que não tenham sido tratadas após tantas horas, envie um email para 'contact_email'. Configurar a 0 para desativar." enable_cdn_js_debugging: "Permitir que /logs exiba erros próprios ao adicionar permissões de origem-cruzada em todos os js incluídos." show_create_topics_notice: "Se o sítio tem menos de 5 tópicos públicos, mostrar um aviso pedindo aos administradores a criação de mais tópicos." delete_drafts_older_than_n_days: Eliminar rascunhos mais antigos que (n) days. - show_logout_in_header: "Mostrar Terminar Sessão no menu suspenso do utilizador no cabeçalho" - vacuum_db_days: "Executar VACUUM FULL ANALYZE para reclamar espaço na Base de Dados após a migração (configurar a 0 para desativar)" + vacuum_db_days: "Executar VACUUM ANALYZE para reclamar espaço na BD após as migrações (configurar a 0 para desativar)" prevent_anons_from_downloading_files: "Previna que utilizadores anónimos descarreguem anexos. AVISO: isto irá fazer com que quaisquer atributos (que não sejam imagens) publicados como anexos não funcionem." slug_generation_method: "Escolha um método de geração slug. 'encoded' irá gerar sequências de caracteres com código percentual. 'none' irá desativar slug por completo." enable_emoji: "Ativar emoji" emoji_set: "Como gostaria de ter o seu emoji?" enforce_square_emoji: "Forçar uma relação de aspecto quadrado para todos os emojis." - approve_post_count: "A quantidade de mensagens de um novo utilizador que devem ser aprovadas" + approve_post_count: "A quantidade de mensagens de um novo utilizador ou utilizador básico que devem ser aprovadas" approve_unless_trust_level: "Mensagens para utilizadores abaixo deste nível de confiança devem ser aprovados" notify_about_queued_posts_after: "Se não houver mensagens que estiveram à espera de revisão por mais do que estas horas, um email será enviado para o email de contacto. Configure para 0 para desativar estes emails." default_email_digest_frequency: "Por defeito, quantas vezes os utilizadores recebem emails de resumo." + default_include_tl0_in_digests: "Incluir mensagens de novos utilizadores nos emails de resumo por defeito. Utilizadores podem alterar isto nas suas preferências." default_email_private_messages: "Por defeito, enviar um email quando alguém envia mensagens ao utilizador." default_email_direct: "Por defeito, enviar um email quando alguém cita/responde a/menciona ou convida o utilizador." default_email_mailing_list_mode: "Por defeito, enviar um email por cada nova mensagem." + disable_mailing_list_mode: "Não permitir aos utilizadores habilitar o modo de lista de distribuição." default_email_always: "Por defeito, enviar notificações por email mesmo quando o utilizador está ativo." + default_email_previous_replies: "Incluir respostas previas nos emails por defeito." + default_email_in_reply_to: "Por defeito Incluir excerto de mensagem de resposta nos email." default_other_new_topic_duration_minutes: "Condição global por defeito para o qual um tópico é considerado novo." default_other_auto_track_topics_after_msecs: "Tempo global por defeito antes de um tópico ser automaticamente acompanhado." default_other_external_links_in_new_tab: "Por defeito, abrir hiperligações externas num novo separador." @@ -1047,6 +1118,8 @@ pt: default_other_dynamic_favicon: "Mostrar contagem de tópicos novos / atualizados no ícone do browser." default_other_disable_jump_reply: "Por defeito, não saltar para a mensagem do utilizador após ter respondido." default_other_edit_history_public: "Por defeito, realizar revisões públicas das mensagens." + default_other_like_notification_frequency: "Notificar por defeito os utilizadores quando alguém gostar" + default_topics_automatic_unpin: "Desafixar automaticamente tópicos quando um utilizador chega ao final, por defeito." default_categories_watching: "Lista de categorias que por defeito são vigiadas." default_categories_tracking: "Lista de categorias que por defeito são acompanhadas." default_categories_muted: "Lista de categorias que por defeito são mudas." @@ -1064,7 +1137,15 @@ pt: invalid_string_min: "Deve ser pelo menos %{min} caracteres." invalid_string_max: "Não deve ser mais que %{max} caracteres." invalid_reply_by_email_address: "O valor deve conter '%{reply_key}' e ser diferente do email de notificação." + pop3_polling_host_is_empty: "Deve configurar um 'pop3 polling host' antes de ativar o polling POP3." + pop3_polling_username_is_empty: "Deve configurar um 'nome de utilizador de polling pop3' antes de ativar o polling POP3." + pop3_polling_password_is_empty: "Deve configurar uma 'palavra-passe de polling pop3' antes de ativar o polling POP3." + pop3_polling_authentication_failed: "Autenticação POP3 falhada. Por favor verifique as suas credenciais pop3." + reply_by_email_address_is_empty: "Tem que definir um 'respostas por endereço de email' antes de habilitar a reposta por email." + email_polling_disabled: "Tem de habilitar a consulta manual ou automática de emails via POP antes de habilitar a reposta por email." + user_locale_not_enabled: "Tem de habilitar 'permitir definições regionais do utilizador' antes de habilitar esta configuração." notification_types: + group_mentioned: "%{group_name} foi mencionado em %{link}" mentioned: "%{display_username} mencionou-o em %{link}" liked: "%{display_username} gostou da sua mensagem %{link}" replied: "%{display_username} repondeu à sua mensagem em %{link}" @@ -1074,7 +1155,7 @@ pt: moved_post: "%{display_username} moveu a sua mensagem para %{link}" private_message: "%{display_username} enviou-lhe uma mensagem: %{link}" invited_to_private_message: "%{display_username} convidou-o para uma mensagem: %{link}" - invited_to_topic: "%{display_username} convidou-o para um tópico: %{link}" + invited_to_topic: "%{display_username} convidou-o para %{link}" invitee_accepted: "%{display_username} aceitou o seu convite" linked: "%{display_username} hiperligou-o em %{link}" granted_badge: "Ganhou %{link}" @@ -1084,11 +1165,6 @@ pt: category: 'Categorias' topic: 'Resultados' user: 'Utilizadores' - sso: - not_found: "Não foi possível encontrar ou criar uma conta, contacte a administração do sítio" - account_not_approved: "A conta está pendente de aprovação, irá receber uma notificação por email assim que for aprovada." - unknown_error: "Erro ao atualizar a informação, contacte a administração do sítio" - timeout_expired: "Tempo para início de sessão de conta expirado, por favor tente entrar novamente" original_poster: "Participante Original" most_posts: "Maior parte das mensagens" most_recent_poster: "Participante Mais Recente" @@ -1163,6 +1239,7 @@ pt: reserved_username: "Esse nome de utilizador não é permitido." missing_user_field: "Não completou todos os campos de utilizador." close_window: "A autenticação está completa. Feche esta janela para continuar." + already_logged_in: "Oops, parece que tentou aceitar um convite para outro utilizador. Se não é o %{current_user}, por favor saia e tente novamente." user: no_accounts_associated: "Sem contas associadas" username: @@ -1171,16 +1248,33 @@ pt: characters: "pode incluir apenas números, letras e sublinhados" unique: "tem que ser único" blank: "tem que estar preenchido" - must_begin_with_alphanumeric: "tem que começar com uma letra ou número ou um sublinhado" - must_end_with_alphanumeric: "tem que terminar com uma letra ou número ou um sublinhado" + must_begin_with_alphanumeric_or_underscore: "tem de começar por uma letra, um número ou o carácter sublinhado" + must_end_with_alphanumeric: "tem de terminar com uma letra ou um número" must_not_contain_two_special_chars_in_seq: "não deve conter uma sequência de 2 ou mais caracteres especiais (.-_)" - must_not_contain_confusing_suffix: "não deve conter um sufixo confuso tal como .json ou .png etc." + must_not_end_with_confusing_suffix: "não deve terminar com um sufixo confuso tal como .json ou .png etc." email: not_allowed: "este provedor de emails não é permitido. Por favor utilize outro endereço de email." blocked: "não é permitido." ip_address: blocked: "Novos registos não são permitidos a partir do seu endereço IP." max_new_accounts_per_registration_ip: "Novos registos não são permitidos a partir do seu endereço IP (limite máximo atingido).Contacte um membro do pessoal." + flags_reminder: + flags_were_submitted: + one: "Sinalizações foram submetidas há 1 hora atrás. Por favor analise-as. " + other: "Sinalizações foram submetidas há %{count} horas atrás. Por favor analise-as. " + subject_template: + one: "1 sinalização à espera de ser tratada" + other: "%{count} sinalizações à espera de serem tratadas" + unsubscribe_mailer: + subject_template: "Confirme que não quer receber emails com actualizações de %{site_title}" + text_body_template: | + Alguém (possivelmente você?) pediu para não receber mais emails com com actualizações de %{site_domain_name} neste endereço. + Se confirma este pedido por favor carregue nesta hiperligação: + + %{confirm_unsubscribe_link} + + + Se quiser continuar a receber emails com actualizações pode ignorar este email. invite_mailer: subject_template: "%{invitee_name} convidou-o a juntar-se a '%{topic_title}' em %{site_domain_name}" text_body_template: | @@ -1224,24 +1318,11 @@ pt: (Se a hiperligação acima tiver expirado, escolha "Esqueci a minha palavra-passe" ao iniciar sessão com o seu endereço de email.) test_mailer: subject_template: "[%{site_name}] Teste de entrega de email" - text_body_template: "Este é um email de teste de\n\n[**%{base_url}**][0]\n\nA entrega do email é complicada. Aqui estão alguns pontos importantes a verificar primeiro:\n\n - *Certifique-se* que configurou o `email de notificação` de: endereço correto nas configurações do seu sítio. **O domínio especificado no endereço “de” nos emails que envia é o domínio que será validado**. \n\n- Conhecer como observar o código fonte dos emails no seu email cliente, de modo a que possa examinar cabeçalhos de email à procura de pistas importantes. No Gmail, é a opção “mostrar original” no menu drop down no canto superior direito de cada email.\n\n- **IMPORTANTE:** O seu ISP tem um registo de DNS inverso inserido para associar os nomes de domínio aos endereços IP de onde envia o seu email? [Teste o seu registo de PTR Inverso][2] aqui. Se o seu ISP não inserir o DNS inverso apropriado, é muito improvável que qualquer um dos seus emails seja entregue.\n\n- Estará o seu domínio [registo SPF][8] correto? [Teste o seu registo SPF][1] aqui. Note que TXT é o tipo de registo oficial para SPF. \n\n- Estará o seu domínio [registo DKIM][3] correto? Isto irá melhorar significativamente a entrega de emails. [Teste o seu registo DKIM][7] aqui.\n\n- Se correr o seu próprio servidor de email, certifique-se que os IPs do seu servidor de email não [estão em nenhuma lista negra de email] [4]. Verifique também que é enviado um nome de servidor qualificado que resolve o DNS na sua mensagem HELO. Se não for, isto irá fazer com que o seu email seja rejeitado por muitos serviços de email.\n\n(A maneira *fácil* é criar uma conta gratuita em [Mandrill][md] ou [Mailgun][mg] ou [Mailjet][mj], que tem vários planos de email gratuitos e será bom para pequenas comunidades. Irá precisar na mesma de configurar os registos SPF e o DKIM no seu DNS!) \n\nEsperamos que tenha recebido este teste de entrega de email sem problemas! \n\nBoa sorte, \n\nOs seus amigos em [Discourse](http://www.discourse.org)\n\n[0]: %{base_url}\n[1]: http://www.kitterman.com/spf/validate.html\n[2]: http://mxtoolbox.com/ReverseLookup.aspx\n[3]: http://www.dkim.org/\n[4]: http://whatismyipaddress.com/blacklist-check\n\ - [7]: http://dkimcore.org/tools/dkimrecordcheck.html\n[8]: http://www.openspf.org/SPF_Record_Syntax\n[md]: http://mandrill.com\n[mg]: http://www.mailgun.com/\n[mj]: https://www.mailjet.com/pricing\n" + text_body_template: "Este é um email de teste de\n\n[**%{base_url}**][0]\n\nA entrega do email é complicada. Aqui estão alguns pontos importantes a verificar primeiro:\n\n- *Certifique-se* que configurou o `email de notificação` de: endereço correto nas configurações do seu sítio. **O domínio especificado no endereço “de” nos emails que envia é o domínio que será validado**.\n\n- Conhecer como observar o código fonte dos emails no seu email cliente, de modo a que possa examinar cabeçalhos de email à procura de pistas importantes. No Gmail, é a opção “mostrar original” no menu drop down no canto superior direito de cada email.\n\n- **IMPORTANTE:** O seu ISP tem um registo de DNS inverso inserido para associar os nomes de domínio aos endereços IP de onde envia o seu email? [Teste o seu registo de PTR Inverso][2] aqui. Se o seu ISP não inserir o DNS inverso apropriado, é muito improvável que qualquer um dos seus emails seja entregue.\n\n- Estará o seu domínio [registo SPF][8] correto? [Teste o seu registo SPF][1] aqui. Note que TXT é o tipo de registo oficial para SPF.\n\n- Estará o seu domínio [registo DKIM][3] correto? Isto irá melhorar significativamente a entrega de emails. [Teste o seu registo DKIM][7] aqui.\n\n- Se correr o seu próprio servidor de email, certifique-se que os IPs do seu servidor de email não [estão em nenhuma lista negra de email] [4]. Verifique também que é enviado um nome de servidor qualificado que resolve o DNS na sua mensagem HELO. Se não for, isto irá fazer com que o seu email seja rejeitado por muitos serviços de email.\n\n- Recomendamos vivamente que **envie um email de teste para [mail-tester.com][mt]** para verificar que tudo mencionado em cima está a funcionar correctamente.\n\n(A maneira *fácil* é criar uma conta grátis em [SendGrid][sg], [SparkPost][sp], [Mailgun][mg] ou [Mailjet][mj], que fornecem grátis, generosamente grátis, pacotes de envio de emails e será suficiente para pequenas comunidades. Irá precisar na mesma de configurar os registos SPF e o DKIM no seu DNS!)\n\nEsperamos que tenha recebido este teste de entrega de email sem problemas!\n\nBoa sorte, \n\nDos seus amigos em [Discourse](http://www.discourse.org)\n\n[0]: %{base_url}\n[1]: http://www.kitterman.com/spf/validate.html\n[2]: http://mxtoolbox.com/ReverseLookup.aspx\n[3]: http://www.dkim.org/\n[4]: http://whatismyipaddress.com/blacklist-check\n[7]: http://dkimcore.org/tools/dkimrecordcheck.html\n[8]: http://www.openspf.org/SPF_Record_Syntax\n[sg]: https://sendgrid.com/\n[sp]: https://www.sparkpost.com/\n[mg]: http://www.mailgun.com/\n[mj]: https://www.mailjet.com/pricing\n[mt]: http://www.mail-tester.com/\n" new_version_mailer: subject_template: "[%{site_name}] Nova versão Discourse, atualização disponível" - text_body_template: "Uma nova versão de [Discourse](http://www.discourse.org) está disponível. \n\nA sua versão: %{installed_version}\nNova versão: **%{new_version}**\n\nPode desejar: \n\n- Ver o que há de novo em [GitHub changelog](https://github.com/discourse/discourse/commits/master).\n\n- Atualizar a partir do seu navegador em [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade).\n\n- Visitar [meta.discourse.org](http://meta.discourse.org) para notícias, debates, e suporte para o Discourse.\n" new_version_mailer_with_notes: subject_template: "[%{site_name}] atualização disponível" - text_body_template: "Uma nova versão de [Discourse](http://www.discourse.org) está disponível. \n\nA sua versão: %{installed_version}\nNova versão: **%{new_version}**\n\nPode desejar: \n\n- Ver o que há de novo em [GitHub changelog](https://github.com/discourse/discourse/commits/master).\n\n- Atualizar a partir do seu navegador em [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade).\n\n- Visitar [meta.discourse.org](http://meta.discourse.org) para notícias, debates, e suporte para o Discourse.\n\n### Release notes\n\n%{notes}\n" - flags_reminder: - flags_were_submitted: - one: "Estas sinalizações foram submetidas há 1 hora atrás." - other: "Estas sinalizações foram submetidas há %{count} horas atrás." - please_review: "Por favor examine-os." - post_number: "mensagem" - how_to_disable: 'Pode desativar ou mudar a frequência deste email notificativo através de "notify about flags after" nas configurações.' - subject_template: - one: "1 sinalização à espera de ser tratada" - other: "%{count} sinalizações à espera de serem tratadas" queued_posts_reminder: subject_template: one: "[%{site_name}] 1 mensagem à espera de revisão" @@ -1267,9 +1348,7 @@ pt: subject_template: "Mensagem oculta devido a sinalizações da comunidade" text_body_template: "Olá,\n\nEsta é uma mensagem automática de %{site_name} para informá-lo que a sua mensagem foi oculta. \n\n%{base_url}%{url} \n\n%{flag_reason}\n\nMúltiplos membros da comunidade sinalizaram esta mensagem antes de ser escondida, por isso considere como poderá rever a sua mensagem para refletir o seu feedback. **Pode editar a sua mensagem após %{edit_delay} minutos, e esta será automaticamente exibida.**\n\nContudo, se a mensagem for escondida pela comunidade uma segunda vez, irá manter-se escondida até ser tratada pelo pessoal – e poderão ainda ocorrer ações, incluindo uma possível suspensão da sua conta.\n\nPara orientação adicional, por favor consulte as [diretrizes da comunidade](%{base_url}/guidelines).\n" usage_tips: - text_body_template: "Aqui ficam algumas dicas para que possa começar: \n\n## Leitura\n\nPara ler mais, **simplesmente continue a arrastar para baixo!**\n\nÀ medida que novas mensagens ou novos tópicos vão chegando, estes irão surgir automaticamente – não é necessário atualizar a página. \n\n## Navegação \n\n- Para pesquisar, a sua página de utilizador, ou o menu , utilize **o ícone no canto superior direito**. \n\n- Selecionar o título de um tópico irá levá-lo sempre à **próxima mensagem não lida** no tópico. Para inserir no início ou no final, selecione a contagem de respostas ou alternativamente, a data da última resposta. \n\n\n\n - Ao ler um tópico, selecione a barra de progresso no canto inferior direito para controlos de navegação completos. Salte rapidamente para o topo ao selecionar o título do tópico. Pressione ? para uma lista rápida de atalhos do teclado. \n\n\n\n## Responder \n\n– Para responder ao **tópico em geral**, utilize no final de cada tópico. \n\n- Para responder a uma **pessoa específica**, utilize nas suas mensagens. \n\n- Para responder com um **novo tópico**, utilize à direita desta mensagem. Tanto os tópicos antigos como os novos serão ligados automaticamente. \n\nPara inserir uma citação, selecione o texto que deseja citar e de seguida pressione qualquer botão de Resposta. Repetir para múltiplas citações! \n\n\n\nPara notificar alguém da sua resposta, mencione o seu nome. Digite `@` para começar a selecionar um nome de utilizador. \n\n\n\nPara utilizar [Emoji padrão](http://www.emoji.codes/), simplesmente digite `:` para encontrar por nome, ou os tradicionais risonhos `;)` \n\n\n\nPara gerar um sumário para uma hiperligação, cole-o numa linha por si só:\n\n\n\n## Ações \n\nExistem botões de ação no final de cada mensagem. \n\n\n\nPara deixar alguém saber que gostou e apreciou as suas mensagens, utilize o botão **gosto**. Partilhe o amor! \n\nSe vir um problema com uma mensagem de alguém, avise a pessoa em privado, ou avise [o nosso pessoal](%{base_url}/about), sobre a mesma utilizando o botão **sinalizar**. Pode também **partilhar** uma hiperligação para uma mensagem, ou **marcá-la** para mais tarde ter a referência na sua página de utilizador. \n\n## Notificações \n\nQuando alguém lhe responde, cita a sua mensagem ou menciona o seu `@nome-de-utilizador`, um número irá aparecer imediatamente no canto superior direito na página. Utilize-o para aceder às suas **notificações**. \n\n\n\n Não se preocupe em falhar uma resposta – irá receber notificações por email que chegam quando está ausente. \n\n## As Suas Preferências \n\n- Todos os tópicos com menos de **dois dias** são considerados novos. \n\n- Qualquer tópico em que tenha **participado ativamente** (respondido, criado, ou lido por um extenso período) será acompanhado automaticamente. \n\nVerá o indicador numérico e o indicador azul (novo) junto desses tópicos: \n\n \n\nPode alterar as suas notificações para qualquer tópico através do controlo de notificações no final do tópico.\n\n\n\nPode também configurar\ - \ estados de notificação por categoria, se quer observar cada novo tópico numa categoria específica. \n\nPara alterar qualquer uma destas configurações, consulte [as suas preferências] (%{base_url}/my/preferences). \n\n##Confiança da Comunidade \n\nÀ medida que for participando aqui, irá ganhar confiança por parte da comunidade, tornar-se um cidadão completo e limitações de novos utilizadores serão automaticamente removidas. Com um [nível de confiança] suficientemente alto (https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), irá ganhar novas capacidades para ajudar-nos a gerir a comunidade em conjunto.\n" + text_body_template: "Aqui ficam algumas dicas para que possa começar:\n\n## Leitura \n\nPara ler mais, **simplesmente continue a arrastar para baixo!** \n\nÀ medida que novas mensagens ou novos tópicos surgem, estes irão surgir automaticamente – não é necessário actualizar a página.\n\n## Navegação\n\nPara pesquisar, a sua página de utilizador, ou o menu , utilize **o ícone no canto superior direito**.\n\n- A selecção de um título do tópico leva-o sempre para a **próxima resposta não lida** no tópico. Para entrar na parte superior ou inferior, seleccione a contagem de resposta ou última data de resposta em seu lugar.\n\n \n\n- Ao ler um tópico, selecione a barra de progresso no canto inferior direito para controlos de navegação completos. Salte rapidamente para o topo ao selecionar o título do tópico. Pressione ? para uma lista rápida de atalhos do teclado.\n\n \n\n## Responder\n\n- Para responder ao **tópico em geral**, utilize no final de cada tópico.\n\n- Para responder a uma **pessoa específica**, utilize nas suas mensagens.\n\n- Para responder com um **novo tópico**, utilize à direita desta mensagem. Tanto os tópicos antigos como os novos serão ligados automaticamente.\n\nA sua resposta pode ser formatada com HTML simplificado, BBCode ou [Markdown](http://commonmark.org/help/):\n\n Isto é **negrito**.\n Isto é negrito.\n Isto é [b]negrito[/b].\n\nQuer aprender Markdown [Faça o nosso curso interactivo de 10 minutos!](http://commonmark.org/help/tutorial/)\n\nPara inserir uma citação, seleccione o texto que deseja citar e de seguida pressione qualquer botão de Resposta. Repetir para múltiplas citações.\n\n\n\nPara notificar alguém da sua resposta, mencione o seu nome. Digite `@` para começar a seleccionar um nome de utilizador.\n\n\n\nPara utilizar [Emoji padrão](http://www.emoji.codes/), simplesmente digite `:` para encontrar por nome, ou os tradicionais risonhos `;)`\n\n\n\nPara gerar um sumário para uma hiperligação, cole-o numa linha por si só:\n\n\n\n## Acções\n\nExistem botões de acção no final de cada mensagem:\n\n\n\nPara deixar alguém saber que gostou e apreciou as suas mensagens, utilize o botão **gosto**. Partilhe o amor!\n\nSe vir um problema com uma mensagem de alguém, avise a pessoa em privado, ou avise [o nosso pessoal](%{base_url}/about), sobre a mesma utilizando o botão **sinalizar**. Pode também **partilhar** uma hiperligação para uma mensagem, ou **marcá-la** para mais tarde ter a referência na sua página de utilizador.\n\n## Notificações\n\nQuando alguém lhe responde, cita a sua mensagem ou menciona o seu `@nome-de-utilizador`, um número irá aparecer imediatamente no canto superior direito na página. Utilize-o para aceder às suas **notificações**.\n\n\n\nNão se preocupe em falhar uma resposta – irá receber notificações por email que chegam quando está ausente.\n\n## As Suas Preferências\n\n - Todos os tópicos com menos de **dois dias** são considerados novos.\n\n - Qualquer tópico em que tenha **participado activamente** (respondido, criado, ou lido por um extenso período) será acompanhado automaticamente.\n\nVerá o indicador numérico e o indicador azul novo junto desses tópicos:\n\n\n\nPode alterar as suas notificações para qualquer tópico através do controlo de notificações no final do tópico.\n\n\n\nPode também configurar estados de notificação por categoria, se quer observar cada novo tópico numa categoria específica.\n\nTo change any of these settings, see [your user preferences](%{base_url}/my/preferences).\n\n## Confiança da Comunidade\n\nÀ medida que for participando aqui, irá ganhar confiança por parte da comunidade, tornar-se um cidadão completo e limitações de novos utilizadores serão automaticamente removidas. Com um [nível de confiança] suficientemente alto (https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), irá ganhar novas capacidades para ajudar-nos a gerir a comunidade em conjunto.\n" welcome_user: subject_template: "Bem-vindo a %{site_name}!" text_body_template: | @@ -1285,7 +1364,7 @@ pt: welcome_invite: subject_template: "Bem-vindo a %{site_name}!" text_body_template: | - Obrigado por ter aceite o convite para %{site_name} -- bem-vindo! + Obrigado por ter aceitado o convite para %{site_name} -- bem-vindo! Criámos uma nova conta **%{username}** para si, e neste momento encontra-se com sessão iniciada. Pode mudar o seu nome ao visitar [o seu perfil de utilizador][prefs]. @@ -1354,18 +1433,39 @@ pt: csv_export_failed: subject_template: "A exportação dos dados falhou" text_body_template: "Pedimos desculpa mas a sua exportação de dados falhou. Por favor verifique os registos do log ou contacte um membro do pessoal." - email_reject_trust_level: - subject_template: "[%{site_name}] Problema de email -- Nível de Confiança Insuficiente" + email_reject_insufficient_trust_level: + subject_template: "[%{site_name}] Problema com Email -- Insuficiente nível de confiança" text_body_template: | - Pedimos desculpa mas a sua mensagem de email para %{destination} (titled %{former_title}) não funcionou. + Pedimos desculpa mas a sua mensagem de email para %{destination} (titled %{former_title}) falhou. - A sua conta não tem o nível de confiança necessário para publicar novos tópicos para este endereço de email. Se acredita que isto é um erro, contacte um membro do pessoal. - email_reject_no_account: - subject_template: "[%{site_name}] Problema de email -- Conta Desconhecida" + A sua conta não possui o nível de confiança necessário para criar novos tópicos para este endereço de email. Se acredita que isto é um erro contacte alguém do pessoal. + email_reject_inactive_user: + subject_template: "[%{site_name}] Problema de email -- Utilizador inactivo" text_body_template: | Pedimos desculpa mas a sua mensagem de email %{destination} (titled %{former_title}) não funcionou. - Não há nenhuma conta de utilizador conhecida com este endereço de email. Tente enviar a partir de um endereço de email diferente, ou contacte um membro do pessoal. + A sua conta associada com este email não está activa. Por favor active a sua conta antes de enviar emails. + email_reject_blocked_user: + subject_template: "[%{site_name}] Problema de email -- Utilizador bloqueado" + text_body_template: |+ + Pedimos desculpa mas a sua mensagem de email %{destination} (titled %{former_title}) não funcionou. + + A sua conta associada com este endereço de email foi bloqueada. + + email_reject_reply_user_not_matching: + subject_template: "[%{site_name}] Problema de email -- Utilizador de resposta não encontrado" + text_body_template: |+ + Pedimos desculpa mas a sua mensagem de email %{destination} (titled %{former_title}) não funcionou. + + A sua resposta foi enviada de um email diferente daquele que esperávamos, por esta razão não temos a certeza que seja a mesma pessoa. Tente enviar de outro endereço de email ou contacte um membro do pessoal. + + email_reject_no_account: + subject_template: "[%{site_name}] Problema de email -- Conta Desconhecida" + text_body_template: |+ + Pedimos desculpa mas a sua mensagem de email %{destination} (titled %{former_title}) não funcionou. + + Não conseguimos encontrar nenhuma conta com combine com o seu endereço de email. Tente enviar de outro endereço de email ou contacte um membro do pessoal. + email_reject_empty: subject_template: "[%{site_name}] Problema de email -- Sem Conteúdo" text_body_template: | @@ -1386,13 +1486,20 @@ pt: Pedimos desculpa, mas a sua mensagem de email para %{destination} (título %{former_title}) não funcionou. A sua conta não tem privilégios para publicar novos tópicos nessa categoria. Se acredita que isto é um erro, contacte um membro do pessoal. - email_reject_post_error: + email_reject_strangers_not_allowed: + subject_template: "[%{site_name}] Problema de email -- Acesso Inválido" + text_body_template: |+ + Pedimos desculpa mas a sua mensagem de email para %{destination} (titled %{former_title}) não funcionou. + + A categoria que enviou neste email apenas permite respostas de utilizadores com contas validadas e endereços de email conhecidos. Se acredita ser um erro contacto um membro do pessoal. + + email_reject_invalid_post: subject_template: "[%{site_name}] Problema de email -- Erro de publicação" text_body_template: | Pedimos desculpa mas a sua mensagem de email para %{destination} (titled %{former_title}) não funcionou. Algumas causas possíveis são: formatação complexa, mensagem demasiado grande, mensagem demasiado pequena. Por favor tente novamente, ou publique através do sítio se isto continuar. - email_reject_post_error_specified: + email_reject_invalid_post_specified: subject_template: "[%{site_name}] Problema de email -- Erro de publicação" text_body_template: | Pedimos desculpa mas a sua mensagem de email para %{destination} (titled %{former_title}) não funcionou. @@ -1402,24 +1509,36 @@ pt: %{post_error} Se conseguir corrigir o problema, tente novamente. - email_reject_reply_key: - subject_template: "[%{site_name}] Problema de email -- Chave de Resposta Desconhecida" + email_reject_rate_limit_specified: + subject_template: "[%{site_name}] Problema de email -- Envios limitados" + text_body_template: | + Pedimos desculpa mas a sua mensagem de email %{destination} (titled %{former_title}) não funcionou. + + Razão: %{rate_limit_description} + email_reject_invalid_post_action: + subject_template: "[%{site_name}] Problema de email -- Acção de Post inválida" text_body_template: | Pedimos desculpa mas a sua mensagem de email para %{destination} (titled %{former_title}) não funcionou. - A chave de resposta fornecida é inválida ou desconhecida, por isso não sabemos a que resposta corresponde este email. Contacte um membro do pessoal. - email_reject_destination: + A acção Post não foi reconhecida. Por favor tente novamente, ou publique através do sítio se isto continuar. + email_reject_reply_key: + subject_template: "[%{site_name}] Problema de email -- Chave de Resposta Desconhecida" + text_body_template: | + Pedimos desculpa, mas a sua mensagem de email para %{destination} (título %{former_title}) não funcionou. + + A chave de resposta no email é inválida ou desconhecida e por isso não conseguimos determinar a que email estava a responder. Contacte um membro do pessoal. + email_reject_bad_destination_address: subject_template: "[%{site_name}] Problema de email -- Endereço Para: Desconhecido" text_body_template: | Pedimos desculpa mas a sua mensagem de email para %{destination} (titled %{former_title}) não funcionou. - Nenhum dos endereços de destino é reconhecido. Por favor, certifique-se que o endereço do sítio está na linha Para: (não em Cc: ou em Bcc:), e que está a enviar para o endereço de email correto fornecido pelo pessoal. + Nenhum dos endereços de destino é reconhecido. Por favor, certifique-se que está a enviar o endereço de email correcto fornecido pelo pessoal. email_reject_topic_not_found: subject_template: "[%{site_name}] Problema de email -- Tópico Não Encontrado" text_body_template: | Pedimos desculpa, mas a sua mensagem de email para %{destination} (título %{former_title}) não funcionou. - O tópico ao qual está a responder já não existe, talvez tenha sido eliminado? Se acredita que isto é um erro, contacte um membro do pessoal. + O tópico ao qual está a responder já não existe -- talvez tenha sido apagado. Se acredita que isto é um erro, contacte um membro do pessoal. email_reject_topic_closed: subject_template: "[%{site_name}] Problema de email -- Tópico Encerrado" text_body_template: | @@ -1431,13 +1550,15 @@ pt: text_body_template: | Pedimos desculpa, mas a sua mensagem de email para %{destination} (título %{former_title}) não funcionou. - O seu email foi marcado como "auto gerado", o qual não podemos aceitar. Se acredita que isto é um erro, contacte um membro do pessoal. + O seu email foi marcado como "gerado automaticamente", o que quer dizer que foi automaticamente criado por um computador em vez de ser escrito por uma pessoa; não podemos aceitar esse tipo de emails. Se acredita que isto é um erro, contacte um membro do pessoal. email_error_notification: subject_template: "[%{site_name}] Problema de email -- Erro de autenticação POP" text_body_template: | - Ocorreu um erro de autenticação ao recuperar emails do servidor POP. + Ocorreu um erro de autenticação ao recuperar emails do servidor POP. - Por favor certifique-se que configurou corretamente as credenciais POP em [configurações do sítio](%{base_url}/admin/site_settings/category/email). + Por favor certifique-se que configurou correctamente as credenciais POP em [configurações do sítio](%{base_url}/admin/site_settings/category/email). + + Se existe uma interface web para a sua conta de POP de email pode necessitar se iniciar sessão na interface web e verificar a suas configurações aí. too_many_spam_flags: subject_template: "Nova conta bloqueada" text_body_template: | @@ -1455,27 +1576,24 @@ pt: Esta é uma mensagem automática de %{site_name} para informá-lo de que a sua conta foi bloqueada por um membro do pessoal. + Por favor tome atenção que não poderá criar novas respostas ou tópicos até um membro do pessoal desbloquear a sua conta. + + Se tem questões sobre este bloqueio, por favor contacte um [membro do pessoal](%{base_url}/about) + Para orientação adicional, por favor consulte as [diretrizes da comunidade](%{base_url}/guidelines). user_automatically_blocked: subject_template: "Novo utilizador %{username} bloqueado devido a sinalizações da comunidade." text_body_template: | Esta é uma mensagem automática. - O novo utilizador [%{username}](%{base_url}%{user_url}) foi automaticamente bloqueado devido a múltiplos utilizadores terem sinalizado a(s) mensagen(s) de %{username}. + O novo utilizador [%{username}](%{user_url}) foi automaticamente bloqueado porque múltiplos utilizadores marcaram mensagem(ns) de %{username}. - Por favor [reveja as sinalizações](%{base_url}/admin/flags). Se %{username} foi incorretamente bloqueado de publicar, carregue no botão de desbloqueio em [a página de administração para este utilizador](%{base_url}%{user_url}). + Por favor [reveja as sinalizações](%{base_url}/admin/flags). Se %{username} foi incorretamente bloqueado de publicar, carregue no botão de desbloqueio em [a página de administração para este utilizador](%{user_url}) Este limite pode ser alterado através de `block_new_user` nas configurações do sítio. spam_post_blocked: subject_template: "Novas mensagens do novo utilizador %{username} foram bloqueadas devido a hiperligações repetidas" - text_body_template: | - Esta é uma mensagem automática. - - O novo utilizador [%{username}](%{base_url}%{user_url}) tentou criar múltiplas mensagens com hiperligações para %{domains}, mas estas foram bloqueadas para evitar spam. O utilizador ainda pode criar novas mensagens sem hiperligação a %{domains}. - - Por favor [reveja o utilizador](%{base_url}%{user_url}). - - Isto pode ser modificado através de `newuser_spam_host_threshold` e `white_listed_spam_host_domains`nas configurações do sítio. + text_body_template: "Esta é uma mensagem automática.\n\nO novo utilizador [%{username}](%{user_url}) tentou criar múltiplas mensagens com hiperligações para %{domains}, mas estas foram bloqueadas para evitar spam. O utilizador ainda pode criar novas mensagens sem hiperligação a %{domains}. \n\nPor favor [reveja o utilizador](%{user_url}).\n\nIsto pode ser modificado através de `newuser_spam_host_threshold` e `white_listed_spam_host_domains` nas configurações do sítio.\n" unblocked: subject_template: "Conta desbloqueada" text_body_template: | @@ -1496,52 +1614,48 @@ pt: subject_template: "Descarregamento de imagens remotas desativado" text_body_template: "A configuração `download_remote_images_to_local` foi desativada porque o limite de espaço em disco em `download_remote_images_threshold` foi alcançado." unsubscribe_link: | - Para cancelar a subscrição destes emails, visite as suas [preferências de utilizador](%{user_preferences_url}). - - Para parar de receber notificações acerca deste tópico específico, [clique aqui](%{unsubscribe_url}). + Para parar de receber notificações para este tópico em particular, [clique aqui](%{unsubscribe_url}). Para cancelar a subscrição destes emails, altere as suas [preferências de utilizador](%{user_preferences_url}). + unsubscribe_via_email_link: | + ou, [carregue aqui](mailto:reply@%{hostname}?subject=unsubscribe) para cancelar a subscrição via email. subject_re: "Re:" subject_pm: "[MP]" user_notifications: previous_discussion: "Respostas Anteriores" + reached_limit: + one: "AVISO: atingiu o número máximo de emails por dia. Próximas notificações será suprimidas." + other: "AVISO: atingiu o número máximo de %{count} emails por dia. Próximas notificações será suprimidas." + in_reply_to: "Em Resposta A" unsubscribe: title: "Cancelar a Subscrição" description: "Não está interessado em receber estes emails? Não há problema! Clique em baixo para cancelar a subscrição instantaneamente:" - reply_by_email: "Para responder, responda a este email ou visite %{base_url}%{url} no seu navegador." - visit_link_to_respond: "Para responder visite %{base_url}%{url} no seu navegador." + reply_by_email: "[Consultar Tópico](%{base_url}%{url}) ou responda a este email para responder" + reply_by_email_pm: "[Consultar Mensagem](%{base_url}%{url}) ou responda a este email para responder" + only_reply_by_email: "Responda a este email para responder" + visit_link_to_respond: "[Consultar Tópico](%{base_url}%{url}) para responder" + visit_link_to_respond_pm: "[Consultar Mensagem](%{base_url}%{url}) para responder" posted_by: "Publicado por %{username} em %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} convidou-o para uma mensagem '%{topic_title}'" - text_body_template: |2 - - %{username} convidou-o para uma mensagem - - >%{username} - > - > %{topic_excerpt} - - at - - > %{site_title} -- %{site_description} - - Por favor visite esta hiperligação para visualizar a mensagem: %{base_url}%{url} + user_invited_to_private_message_pm_staged: + subject_template: "[%{site_name}] %{username} convidou-o para uma mensagem '%{topic_title}'" user_invited_to_topic: - subject_template: "[%{site_name}] %{username} convidou-o para um tópico '%{topic_title}'" - text_body_template: |2 - - %{username} convidou-o para uma discussão - - > **%{topic_title}** - > - > %{topic_excerpt} - - em - - > %{site_title} -- %{site_description} - - Por favor visite esta hiperligação para visualizar a mensagem: %{base_url}%{url} + subject_template: "[%{site_name}] %{username} convidou-o para '%{topic_title}'" user_replied: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_replied_pm: + subject_template: "[%{site_name}] [MP] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1551,6 +1665,19 @@ pt: user_quoted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_linked: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1560,6 +1687,19 @@ pt: user_mentioned: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1569,6 +1709,8 @@ pt: user_posted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1578,10 +1720,20 @@ pt: user_posted_pm: subject_template: "[%{site_name}] [MP] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} + --- + %{respond_instructions} + user_posted_pm_staged: + subject_template: "%{optional_re}%{topic_title}" + text_body_template: |2 + + %{message} + --- %{respond_instructions} digest: @@ -1630,12 +1782,32 @@ pt: Clique na hiperligação seguinte para escolher uma palavra-passe para a sua nova conta. %{base_url}/users/password-reset/%{email_token} - authorize_email: + confirm_new_email: subject_template: "[%{site_name}] Confirme o seu novo endereço de email" text_body_template: | Confirme o seu novo endereço de email para %{site_name} ao clicar na seguinte hiperligação: %{base_url}/users/authorize-email/%{email_token} + confirm_old_email: + subject_template: "[%{site_name}] Confirme o seu endereço de email atual" + text_body_template: | + Antes de podermos alterar o seu endereço de email precisámos de confirmar que + controla a conta de email atual. Após completar este passo, iremos confirmar + o seu novo endereço de email. + + Confirme o seu endereço de email para o %{site_name} ao clicar na seguinte hiperligação: + + %{base_url}/users/authorize-email/%{email_token} + notify_old_email: + subject_template: "[%{site_name}] O seu endereço de email foi alterado" + text_body_template: | + Isto é uma mensagem automática para o informar que o seu endereço de email para + %{site_name} foi alterado. Se isto foi feito em erro, por favor contacte + o administração do sítio. + + O seu endereço de email foi alterado para: + + %{new_email} signup_after_approval: subject_template: "Foi aprovado no %{site_name}!" text_body_template: | @@ -1665,7 +1837,7 @@ pt: Se a hiperligação não for clicável, tente copiá-la e colá-la na barra de endereço do seu navegador de internet. page_not_found: - title: "A página que solicitou não existe ou é privada." + title: "Oops! Essa página não existe or é privada." popular_topics: "Popular" recent_topics: "Recente" see_more: "Mais" @@ -1690,8 +1862,6 @@ pt: images: too_large: "Pedimos desculpa, a imagem que está a tentar carregar é muito grande (o tamanho máximo é %{max_size_kb}KB), por favor redimensione-a e tente novamente." size_not_found: "Pedimos desculpa, mas não conseguimos determinar o tamanho da imagem. É possível que seu ficheiro de imagem esteja corrompido?" - avatar: - missing: "Desculpe, mas o avatar que selecionou não está presente no servidor. Pode tentar carregá-lo novamente?" flag_reason: sockpuppet: "Um novo utilizador criou um tópico, no qual um outro novo utilizador com o mesmo IP respondeu. Veja as configurações de flag_sockpuppets" spam_hosts: "Este novo utilizador tentou criar múltiplas mensagens com hiperligações ao mesmo domínio. Verifique as configurações do sítio em newuser_spam_host_threshold." @@ -1706,6 +1876,7 @@ pt: post_deleted: "a mensagem foi eliminada pelo autor" user_suspended: "o utilizador foi suspenso" already_read: "o utilizador já leu esta mensagem" + exceeded_limit: "Excedeu max_emails_per_day_per_user" message_blank: "a mensagem está em branco" message_to_blank: "message.to está em branco" text_part_body_blank: "text_part.body está em branco" @@ -1723,101 +1894,41 @@ pt: Edite a primeira mensagem neste tópico para alterar os conteúdos da página %{page_name}. guidelines_topic: title: "FAQ/Diretrizes" - body: "\n\n## [Este é um Local Civilizado para Discussão Pública](#civilizado) \n\nPor favor trate este fórum de discussão com o mesmo respeito com que trataria um parque público. Nós somos também uma comunidade de partilha de recursos — um local para partilhar habilidades, conhecimento e interesses através de conversações. \n\nEstas não são regras rígidas e rápidas, meramente ajuda para o julgamento humano da nossa comunidade. Utilize estas diretrizes para manter este local limpo e iluminado para discussões públicas civilizadas. \n\n\n\n## [Melhorar a Discussão](#melhorar) \n\nAjude-nos a fazer deste um óptimo local para debates ao trabalhar constantemente para melhorar esses debates de alguma maneira, mesmo que pequena. Se não tem a certeza que a sua mensagem adiciona algo à conversação, pense novamente no que quer dizer e tente novamente mais tarde. \n\nOs tópicos discutidos aqui têm importância para nós, e queremos agir como se também fossem importantes para si. Seja respeitador dos tópicos e das pessoas que o debatem, mesmo que discorde do que está a ser dito. \n\nUma maneira de melhorar o debate é descobrindo os que já estão a ocorrer. Por favor perca algum tempo a pesquisar os tópicos existentes aqui antes de responder ou começar um novo, e terá melhores hipóteses de conhecer outros que partilhem os mesmos interesses que você. \n\n\n\n ## [Seja Agradável, Mesmo Que Discorde](#agradável) \n\nPode desejar responder a algo ao discordar do mesmo. Não há qualquer problema nisso. Mas lembre-se de _criticar ideias, não pessoas_. Por favor, evite: \n\n*Chamar Nomes. \n*Adicionar ataques pessoais. \n* Responder ao tom de uma mensagem e não ao seu conteúdo. \n*Contradições instintivas \n\nPelo contrário, forneça contra-argumentos que melhorem a conversação. \n\n\n\n## [A Sua Participação Conta](#participe) \n\nAs conversações que temos aqui definem o tom para toda a gente. Ajude-nos a influenciar o futuro desta comunidade ao escolher comprometer-se nos debates que tornam este fórum um local interessante\ - \ para se estar — e evite os que não o fazem. \n\nO Discourse fornece ferramentas que permitem que a comunidade identifique as melhores (e piores) contribuições: favoritos, marcadores, gostos, sinalizações, respostas, edições, e por aí em diante. Utilize estas ferramentas para melhorar a sua própria experiência e de todos os outros também.\n\nVamos tentar deixar o nosso parque melhor do que quando o encontrámos. \n\n\n\n ## [Se vir um Problema, Sinalize-o](#sinalize-problemas) \n\nOs moderadores têm uma autoridade especial; estes são responsáveis por este fórum. Assim como você o é. Com a sua ajuda, os moderadores podem ser facilitadores da comunidade, não apenas zeladores ou polícias. \n\nQuando vir mau comportamento, não responda. O reconhecimento encoraja o mau comportamento, consome a sua energia e gasta o tempo de todos. Apenas sinalize-o. Se houver sinalizações suficientes, ações irão ser tomadas, seja automaticamente ou por intervenção dos moderadores.\n\nDe maneira a manter a ordem da comunidade, os moderadores reservam-se ao direito de remover qualquer conteúdo e qualquer conta de utilizador por qualquer razão em qualquer altura. Os moderadores não prevêem novas mensagens em qualquer maneira; os moderadores e os operadores do sítio não têm qualquer responsabilidade por qualquer conteúdo publicado pela comunidade. \n\n\n\n## [Seja sempre civilizado](#seja-civilizado) \n\nNada estraga mais uma conversação saudável do que insolências: \n\n*Seja civilizado. Não publique nada que uma pessoa sensata consideraria ofensiva, abusiva ou de ódio. \n*Mantenha-o limpo. Não publique nada obsceno ou sexualmente explicito.\n*Respeite os outros. Não assedie ou magoe ninguém, não personifique pessoas, e não exponha as suas informações pessoais. \n*Respeite o fórum. Não publique spam ou qualquer outra coisa que vandalize o fórum. \n\nEstes não são termos concretos com definições precisas — evite até a _aparência_ de qualquer uma destas coisas. Se não tem certeza, pergunte-se a si próprio como se sentiria se a sua mensagem fosse capa do New York Times.\ - \ \n\nEste é um fórum público, e motores de pesquisa indexam estes debates. Mantenha a linguagem, hiperligações e imagens seguras para família e amigos. \n\n\n\n## [Mantenha-o Organizado](#manter-organizado) \n\nFaça o esforço para colocar as coisas no local certo, para que possamos passar mais tempo a debater e menos a limpar. Por isso: \n\n*Não comece um tópico na categoria errada. \n*Não cruze mensagens sobre o mesmo tema em múltiplos tópicos. \n*Não publique respostas sem conteúdo. \n*Não desvie um tópico ao mudar o seu centro de atenção. \n*Não assine as suas mensagens — qualquer mensagem tem a sua informação de perfil anexada à mesma. \n\nEm vez de publicar “+1” ou “Concordo”, utilize o botão Gosto. Em vez de levar um tópico existente para uma direção completamente diferente, utilize Responder como Novo Tópico. \n\n\n \n## [Publique Apenas As Suas Próprias Coisas](#roubo) \n\nNão pode publicar nada digital que pertença a qualquer outra pessoa, sem a sua permissão. Não pode publicar descrições de, hiperligações a, ou métodos para roubar propriedade intelectual de outras pessoas (software, vídeo, áudio, imagens), ou para quebrar qualquer outra lei. \n\n\n## [Patrocinado Por Si](#poder) \n\nEste sítio é operado pelos seus [membros locais amigáveis](/sobre) e por *si*, a comunidade. Se tem alguma questão adicional sobre como as coisas funcionam por aqui, abra um novo tópico em [site feedbackcategory](/c/site-feedback) e iremos debatê-lo. Se ocorrer algum assunto crítico ou urgente que pode ser tratado por um tópico meta ou por uma sinalização, contacte-nos através do [página do pessoal](/sobre). \n\n \n\n## [Termos de Serviço](#tds) \n\nSim, a legalidade é chata, mas temos que nos proteger – e por extensão, protegê-lo a si e aos seus dados – contra companheiros inimigos. Temos os [Termos de Serviço](/tds) que descrevem o seu (e o nosso) comportamento e direitos relativamente a conteúdo, privacidade e leis. Para usar este serviço tem que concordar em cumprir os nossos [TDS](/tds).\n" + body: "\n\n## [Este é um Local Civilizado para Discussão Pública](#civilizado) \n\nPor favor trate este fórum de discussão com o mesmo respeito com que trataria um parque público. Nós somos também uma comunidade de partilha de recursos — um local para partilhar habilidades, conhecimento e interesses através de conversações. \n\nEstas não são regras rígidas e rápidas, meramente ajuda para o julgamento humano da nossa comunidade. Utilize estas diretrizes para manter este local limpo e iluminado para discussões públicas civilizadas. \n\n\n\n## [Melhorar a Discussão](#melhorar) \n\nAjude-nos a fazer deste um óptimo local para debates ao trabalhar constantemente para melhorar esses debates de alguma maneira, mesmo que pequena. Se não tem a certeza que a sua mensagem adiciona algo à conversação, pense novamente no que quer dizer e tente novamente mais tarde. \n\nOs tópicos discutidos aqui têm importância para nós, e queremos agir como se também fossem importantes para si. Seja respeitador dos tópicos e das pessoas que o debatem, mesmo que discorde do que está a ser dito. \n\nUma maneira de melhorar o debate é descobrindo os que já estão a ocorrer. Por favor perca algum tempo a pesquisar os tópicos existentes aqui antes de responder ou começar um novo, e terá melhores hipóteses de conhecer outros que partilhem os mesmos interesses que você. \n\n\n\n ## [Seja Agradável, Mesmo Que Discorde](#agradável) \n\nPode desejar responder a algo ao discordar do mesmo. Não há qualquer problema nisso. Mas lembre-se de _criticar ideias, não pessoas_. Por favor, evite: \n\n*Chamar Nomes. \n*Adicionar ataques pessoais. \n* Responder ao tom de uma mensagem e não ao seu conteúdo. \n*Contradições instintivas \n\nPelo contrário, forneça contra-argumentos que melhorem a conversação. \n\n\n\n## [A Sua Participação Conta](#participe) \n\nAs conversações que temos aqui definem o tom para toda a gente. Ajude-nos a influenciar o futuro desta comunidade ao escolher comprometer-se nos debates que tornam este fórum um local interessante para se estar — e evite os que não o fazem. \n\nO Discourse fornece ferramentas que permitem que a comunidade identifique as melhores (e piores) contribuições: favoritos, marcadores, gostos, sinalizações, respostas, edições, e por aí em diante. Utilize estas ferramentas para melhorar a sua própria experiência e de todos os outros também.\n\nVamos tentar deixar o nosso parque melhor do que quando o encontrámos. \n\n\n\n ## [Se vir um Problema, Sinalize-o](#sinalize-problemas) \n\nOs moderadores têm uma autoridade especial; estes são responsáveis por este fórum. Assim como você o é. Com a sua ajuda, os moderadores podem ser facilitadores da comunidade, não apenas zeladores ou polícias. \n\nQuando vir mau comportamento, não responda. O reconhecimento encoraja o mau comportamento, consome a sua energia e gasta o tempo de todos. Apenas sinalize-o. Se houver sinalizações suficientes, ações irão ser tomadas, seja automaticamente ou por intervenção dos moderadores.\n\nDe maneira a manter a ordem da comunidade, os moderadores reservam-se ao direito de remover qualquer conteúdo e qualquer conta de utilizador por qualquer razão em qualquer altura. Os moderadores não prevêem novas mensagens em qualquer maneira; os moderadores e os operadores do sítio não têm qualquer responsabilidade por qualquer conteúdo publicado pela comunidade. \n\n\n\n## [Seja sempre civilizado](#seja-civilizado) \n\nNada estraga mais uma conversação saudável do que insolências: \n\n*Seja civilizado. Não publique nada que uma pessoa sensata consideraria ofensiva, abusiva ou de ódio. \n*Mantenha-o limpo. Não publique nada obsceno ou sexualmente explicito.\n*Respeite os outros. Não assedie ou magoe ninguém, não personifique pessoas, e não exponha as suas informações pessoais. \n*Respeite o fórum. Não publique spam ou qualquer outra coisa que vandalize o fórum. \n\nEstes não são termos concretos com definições precisas — evite até a _aparência_ de qualquer uma destas coisas. Se não tem certeza, pergunte-se a si próprio como se sentiria se a sua mensagem fosse capa do New York Times. \n\nEste é um fórum público, e motores de pesquisa indexam estes debates. Mantenha a linguagem, hiperligações e imagens seguras para família e amigos. \n\n\n\n## [Mantenha-o Organizado](#manter-organizado) \n\nFaça o esforço para colocar as coisas no local certo, para que possamos passar mais tempo a debater e menos a limpar. Por isso: \n\n*Não comece um tópico na categoria errada. \n*Não cruze mensagens sobre o mesmo tema em múltiplos tópicos. \n*Não publique respostas sem conteúdo. \n*Não desvie um tópico ao mudar o seu centro de atenção. \n*Não assine as suas mensagens — qualquer mensagem tem a sua informação de perfil anexada à mesma. \n\nEm vez de publicar “+1” ou “Concordo”, utilize o botão Gosto. Em vez de levar um tópico existente para uma direção completamente diferente, utilize Responder como Novo Tópico. \n\n\n \n## [Publique Apenas As Suas Próprias Coisas](#roubo) \n\nNão pode publicar nada digital que pertença a qualquer outra pessoa, sem a sua permissão. Não pode publicar descrições de, hiperligações a, ou métodos para roubar propriedade intelectual de outras pessoas (software, vídeo, áudio, imagens), ou para quebrar qualquer outra lei. \n\n\n## [Patrocinado Por Si](#poder) \n\nEste sítio é operado pelos seus [membros locais amigáveis](/sobre) e por *si*, a comunidade. Se tem alguma questão adicional sobre como as coisas funcionam por aqui, abra um novo tópico em [site feedbackcategory](/c/site-feedback) e iremos debatê-lo. Se ocorrer algum assunto crítico ou urgente que pode ser tratado por um tópico meta ou por uma sinalização, contacte-nos através do [página do pessoal](/sobre). \n\n \n\n## [Termos de Serviço](#tds) \n\nSim, a legalidade é chata, mas temos que nos proteger – e por extensão, protegê-lo a si e aos seus dados – contra companheiros inimigos. Temos os [Termos de Serviço](/tds) que descrevem o seu (e o nosso) comportamento e direitos relativamente a conteúdo, privacidade e leis. Para usar este serviço tem que concordar em cumprir os nossos [TDS](/tds).\n" tos_topic: title: "Termos de Serviço" - body: "Os seguintes termos e condições governam todo o uso do sítio %{company_domain} e todo o conteúdo, serviços e produtos disponíveis no ou através do sítio, incluindo mas não limitado a, %{company_domain} Software do Fórum, %{company_domain} Fóruns de Suporte e serviço de alojamento %{company_domain} (\"Alojamento\"), (em conjunto, o Sítio). O Sítio é propriedade e operado por %{company_full_name} (\"%{company_name}\"). O Sítio oferecido está sujeito à sua aprovação sem nenhuma modificação de todos os termos e condições contidos aqui e todas as outras regras de operação políticas (incluindo, sem limitação, %{company_domain}’s [Política de Privacidade](/privacy) e [Diretrizes da Comunidade](/faq)) e procedimentos que possam ser publicados de tempos em tempos neste Sítio por %{company_name} (coletivamente, the \"Acordo\"). \n\nPor favor leia este Acordo com cuidado antes de aceder ou usar o Sítio. Ao aceder ou usar qualquer parte do Sítio, concorda em estar limitado pelos termos e condições deste acordo. Se não concorda com todos os termos e condições deste acordo, então não deve aceder ao Sítio ou usar qualquer um dos serviços. Se estes termos e condições são considerados uma oferta de %{company_name}, a sua aceitação é expressamente limitada a estes termos. O Sítio está disponível apenas a indíviduos que têm pelo menos 13 anos de idade. \n\n \n\n## [1. A Sua Conta %{company_domain} ](#1) \n\nSe criar uma conta no Sítio, será responsável por manter a segurança da sua conta e será totalmente responsável por todas as atividades que ocorrerem sob a sua conta. Deve notificar imediatamente %{company_name} de qualquer uso não autorizado da sua conta ou qualquer outra falha de segurança. %{company_name} não será passível de quaisquer atos ou omissões da sua parte, incluindo danos de qualquer tipo que incorram como resultado de tais atos ou omissões. \n\n \n\n## [2.Responsabilidade dos Participantes](#2) \n\nSe publicar material no Sítio, publicar hiperligações no Sítio, ou de outra maneira disponibilizar (ou permitir que qualquer terceira parte o faça) material no Sítio (qualquer\ - \ material, “Conteúdo”), será inteiramente responsável pelo conteúdo de, e qualquer dano resultante de tal Conteúdo. Esse é o caso independentemente de o Conteúdo em questão constituir texto, gráficos, ficheiros áudio, ou programas de computadores. Ao tornar o Conteúdo disponível, está a representar e garantir que: \n\n* o descarregamento, cópia e uso do Conteúdo não irá infringir os direitos do proprietário, incluindo mas não limitado aos direitos de autor, patentes, marcas registadas ou direitos de segredos de troca, de qualquer terceira parte; \n* se o seu empregado tem direitos sob a propriedade intelectual que criou, terá que (i) ou ter recebido permissões do seu empregado para publicar ou tornar o Conteúdo disponível, incluindo mas não limitado a qualquer software, ou (ii) ter garantido uma renúncia do seu empregado a todos os direitos no e para o Conteúdo; \n* está de acordo com licenças de qualquer terceira-parte relacionada com o Conteúdo, e fez todas as coisas necessárias para passar corretamente quaisquer termos requeridos aos utilizadores finais; \n* o Conteúdo não contém ou instala quaisquer vírus, minhocas ou malware, cavalos de Tróia ou outro conteúdo destrutivo; \n* o Conteúdo não é spam, não é gerado por máquina, e não contém conteúdo indesejado sem ética ou comercial com intuito de conduzir o tráfico de sítios terceiros ou aumentar a posição de sítios terceiros em motores de pesquisa, ou ainda outros atos ilegais (tais como phishing) ou destinatários enganadores relativamente à origem do material (tais como spoofing); \n* o Conteúdo não é pornográfico, nem contém ameaças ou incita violência, e não viola os direitos de privacidade ou publicidade de qualquer terceira parte; \n* o conteúdo não está a ser anunciado através de quaisquer mensagens eletrónicas tais como hiperligações de spam ou grupos de notícias, listas de email, blogs e sítios, e similares métodos promocionais não solicitados; \n* o seu conteúdo não está nomeado de nenhuma maneira que leve os seus leitores a pensarem que é outra pessoa ou empresa; e \n* terá, no caso do Conteúdo incluir código de computador, categorizado e/ou\ - \ descrito o tipo, natureza, uso e efeito dos materiais, quer tenha sido pedido para fazê-lo por %{company_name} ou pelo contrário. \n\n \n\n## [3. Licença do Conteúdo do Utilizador](#3) \n\nAs contribuições dos utilizadores estão licenciadas sob a [Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US). Sem qualquer limitação de qualquer dessas representações ou garantias, %{company_name} tem o direito (embora não tenha a obrigação) de, em critério exclusivo de %{company_name} (i) recusar ou remover qualquer conteúdo que, na sensata opinião de %{company_name} viola qualquer política de %{company_name} ou é de alguma maneira prejudicial ou censurável, ou (ii) terminar ou negar acesso ao Sítio e ao uso do mesmo a qualquer indivíduo ou entidade por alguma razão, em critério exclusivo de %{company_name}. %{company_name} não terá obrigação de fornecer uma compensação de quaisquer montantes previamente pagos. \n\n \n\n## [4. Pagamento e Renovação](#4) \n\n### Termos Gerais \n\nAtualizações ou serviços opcionais pagos podem estar disponíveis no Sítio. Ao utilizar uma atualização ou serviço opcional pago, está a concordar em pagar a %{company_name} as taxas de subscrição mensais ou anuais indicadas. Os pagamentos serão cobrados numa base pré-paga no dia em que utilizar o serviço ou a atualização e irá cobrir o uso desse serviço ou atualização por um período de subscrição mensal ou anual tal como indicado. Estas taxas não são reembolsáveis. \n\n### Renovação Automática \n\nA não ser que notifique %{company_name} antes do final do período da subscrição que quer cancelar, a sua subscrição será automaticamente renovada e você autoriza-nos a colecionar as taxas anuais ou mensais (assim como outras taxas) usando qualquer cartão de crédito ou outro mecanismo de pagamento que tivermos no seu registo. As subscrições podem ser canceladas em qualquer altura. \n\n \n\n## [5. Serviços](#5) \n\n### Serviços de Alojamento, Suporte \n\nServiços opcionais de Alojamento e Suporte podem ser fornecidos\ - \ por %{company_name} sob os termos e condições para cada serviço. Ao inscrever-se numa conta com serviços de Alojamento ou Suporte, irá concordar e agir sob tais termos e condições. \n\n \n\n## [6. Responsabilidade dos Visitantes do Sítio](#6) \n\n%{company_name} não reviu, nem pode rever, todo o material, incluindo programas de computador, publicado no Sítio, e não pode portanto ser responsável pelo conteúdo do mesmo, pelo seu uso ou efeitos. Ao operar o Sítio, %{company_name} não representa ou implica que corrobora com o material publicado, ou que acredita que o material seja preciso, útil e não prejudicial. Será responsável por tomar as precauções necessárias para proteger-se a si próprio e o seu sistema computacional de vírus, minhocas, cavalos de Tróia e outros conteúdos destrutivos. O Sítio pode ter conteúdo ofensivo, indecente assim como também imprecisões técnicas, erros tipográficos entre outros erros. O Sítio pode também ter material que viola os direitos de privacidade e publicidade, ou que infringe a propriedade intelectual e outros direitos do proprietário, de terceiras partes, ou o descarregamento, cópia ou uso que é sujeito a termos e condições adicionais, estabelecidos ou não. %{company_name} está isenta de qualquer responsabilidade de qualquer dano resultante do uso por parte dos visitantes do Sítio, ou de qualquer descarregamento feito por esses visitantes do conteúdo lá publicado. \n\n \n\n## [7. Conteúdo Publicado Noutros Sítios](#7) \n\nNão revimos nem podemos rever todo o material, incluindo programas de computador, disponibilizado através de sítios e páginas em %{company_domain} no qual existem hiperligações e que se hiperligam a %{company_domain}. %{company_name} não tem qualquer controlo dos sítios e páginas não-%{company_domain}, e não é responsável pelo seu conteúdo ou o seu uso. Ao clicar num sítio ou página não--%{company_domain}, %{company_name} não representa ou implica que corrobora com tais sítios ou páginas. Você é responsável por tomar ações necessárias para proteger-se a si próprio ou o seu sistema computacional de vírus, minhocas,\ - \ cavalos de Tróia e outros conteúdos destrutivos. %{company_name} renuncia qualquer responsabilidade por qualquer dano resultante do uso de sítios e páginas não-%{company_domain}. \n\n \n\n## [8. Violação de Direitos de Autor e Política DCMA](#8) \n\nAssim como %{company_name} pede aos outros para respeitarem os direitos de propriedade intelectual, a mesma respeita os direitos de propriedade intelectual dos outros. Se acredita que material localizado em ou com hiperligação para, por %{company_domain} viola os seus direitos de autor, e se este sítio reside nos EUA, encorajamo-lo a notificar a %{company_name} em concordância com a Política (“DMCA”) [Digital Millennium Copyright Act](http://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act) da %{company_name}. %{company_name} irá responder por tais notícias, incluindo tal como requerido ou apropriado por remover o material ilícito ou desativando as hiperligações para o material ilícito. %{company_name} irá terminar o acesso a e o uso do Sítio se, sob circunstâncias apropriadas, o visitante é determinado como sendo um infrator repetido dos direitos de autor e de outros direitos de propriedade intelectual de %{company_name} ou outros. No caso de tal terminação, %{company_name} não terá qualquer obrigação de fornecer uma compensação de qualquer valor previamente pago a %{company_name}. \n\n \n\n## [9. Propriedade Intelectual](#9) \n\nEste Acordo não transfere totalmente de %{company_name} para si qualquer propriedade intelectual de %{company_name} ou de terceiras partes, e todos os direitos, títulos e interesse na e para a propriedade irá permanecer (entre as partes) apenas com %{company_name}. %{company_name}, %{company_domain}, o logótipo %{company_domain} e todos as outras marcas, marcas de serviço, gráficos, logótipos usados na ligação com %{company_domain}, ou o Sítio é marca registada de %{company_name} ou licenciadores de %{company_name}. Outras marcas, marcas de serviço, gráficos e logótipos usados na hiperligação com o Sítio podem ser marcas de terceiras partes. O seu uso do Sítio não lhe concede direitos ou\ - \ licença para reproduzir ou de outra forma usar quaisquer marcas de %{company_name} ou de terceiras partes. \n\n \n\n## [10. Anúncios](#10) \n\n%{company_name} reserva-se ao direito de mostrar anúncios no seu conteúdo a não ser que tenha comprado a Atualização Ad-free ou uma conta de Serviços. \n\n \n\n## [11. Atribuição](#11) \n\n%{company_name} reserva-se ao direito de mostrar hiperligações de atribuição tais como ‘Patrocinado por %{company_domain},’ e atribuição de fontes ao conteúdo do rodapé ou da sua ferramenta. Os créditos do rodapé e a ferramenta de %{company_domain} não poderão ser removidas independentemente das atualizações compradas. \n\n \n\n## [12. Alterações](#12) \n\n%{company_name} reserva-se ao direito, por critério exclusivo, de modificar ou substituir qualquer parte deste Acordo. É sua responsabilidade verificar periodicamente o Acordo e verificar as suas alterações. O seu uso ou acesso contínuo ao Sítio seguido da publicação de qualquer alteração a este Acordo constitui aceitação a essas mudanças. %{company_name} pode também, no futuro, oferecer novos serviços e/ou funcionalidades através do Sítio (incluindo, o lançamento de novas ferramentas e recursos). Estas novas funcionalidades e/ou serviços devem ser sujeitos aos termos e condições deste Acordo. \n\n \n\n## [13. Terminação](#13) \n\n%{company_name} pode terminar o seu acesso a todas ou alguma parte do Sítio em qualquer altura, com ou sem motivo, com ou sem aviso, com efeitos imediatos. Se desejar terminar este Acordo ou a sua conta %{company_domain} (se tiver uma), pode simplesmente deixar de usar o Sítio. Todas as provisões para este Acordo que pela sua natureza deverão sobreviver à terminação, incluindo, sem limitações, provisões de propriedade, isenções de garantia, indemnizações e limitações de responsabilidade. \n\n \n\n## [14. Isenção de Garantias](#14) \n\nO Sítio é fornecido “tal como está”. %{company_name} e os seus fornecedores e licenciadores ficam aqui isentos de garantias de qualquer tipo, expressas ou implícitas, sem\ - \ limitação, as garantias de comerciabilidade, adequadas a uma finalidade específica. Nem %{company_name} nem os seus fornecedores e licenciadores, fazem garantias de que o Sítio está livre de erros ou que o acesso seja contínuo e ininterrupto. Se está a ler isto, aqui está [uma ajuda] (http://www.newyorker.com/online/blogs/shouts/2012/12/the-hundred-best-lists-of-all-time.html). Compreende que descarregou de, ou de outra maneira obteve conteúdo ou serviços através do Sítio a seu próprio risco e descrição. \n\n \n\n## [15. Limitação da Responsabilidade](#15) \n\nEm nenhum evento %{company_name} ou os seus fornecedores ou licenciadores, serão responsáveis em respeito a qualquer assunto deste acordo sob qualquer contrato, negligência, estrita responsabilidade ou outras teorias legais para: (i) quaisquer danos especiais, de incidentes ou consequenciais; (ii) o custo de procura de produtos ou serviços substitutos; (iii) por interrupção do uso, perda ou corrupção dos dados; ou (iv) por quaisquer valores que excedem as taxas pagas por si a %{company_name} sob este acordo durante um período doze (12) meses anterior à causa da ação. %{company_name} não deverá ter qualquer responsabilidade de qualquer falha ou atraso devido a matérias para além do seu razoável controlo. O disposto neste artigo não se aplica nas medidas proibidas pela lei aplicável. \n\n \n\n## [16. Representações Gerais e Garantia](#16) \n\nRepresenta e garante que (i) o seu uso do Sítio irá estar em estrita concordância com a [Política de Privacidade](/privacy) e das [Diretrizes da Comunidade](/diretrizes) da %{company_name}, com este Acordo e com as leis e regulações aplicáveis (incluindo sem limitação de quaisquer leis ou regulações locais no seu país, estado, cidade ou outras áreas governamentais, relativamente à conduta online e ao conteúdo aceitável, e incluindo quaisquer leis aplicáveis relativamente à transmissão de dados técnicos exportados de qualquer país em que o sítio reside ou do país em que você reside) e (ii) o seu uso do Sítio não irá infringir os direitos de propriedade intelectual de qualquer\ - \ terceira parte. \n\n \n\n## [17. Indemnização](#17) \n\nConcorda em indemnizar e não prejudicar %{company_name}, os seus contratados, e os seus licenciadores, os seus respetivos diretores, empregados e agentes de e contra quaisquer reivindicações e despesas, incluindo taxas de advogados, decorrentes do seu uso do Sítio, incluindo mas não limitado à sua violação deste Acordo. \n\n \n\n## [18. Diversos](#18) \n\nEste Acordo constitui o acordo integral entre si e %{company_name} em relação ao assunto em questão, e poderá ser modificado apenas por uma emenda escrita assinada por um executivo autorizado da %{company_name}, ou pela publicação por parte da %{company_name}, de uma versão revista. Excepto o definido na lei, se houver, disposição em contrário, o presente Acordo, qualquer acesso ou uso do sítio será governado pelas leis do estado da Califórnia, E.U.A, excluindo aos conflitos das disposições da lei, e a receita própria por qualquer disputa emergente de ou relativa a qualquer do mesmo será o tribunal federal e estatal localizado em São Francisco, Califórnia. Exceto para os pedidos de medida cautelar ou equitativa ou reclamações relativas aos direitos de propriedade intelectual (que podem ser introduzidos em qualquer tribunal competente, sem a prestação de uma caução), qualquer litígio decorrente do presente acordo será resolvido de acordo com as Regras de Arbitragem de \"Judicial Arbitration and Mediation Service, Inc.” (“JAMS”) por três árbitros apontados em concordância com tais Regras. A arbitragem deverá ter lugar em São Francisco, Califórnia, em língua Inglesa e a decisão arbitral pode ser forçada em qualquer tribunal. A parte prevalecente em qualquer ação ou processo para executar este Acordo terá direito a custos e honorários dos advogados. Se qualquer parte deste Acordo for considerada inválida ou inexequível, essa parte será interpretada de forma a refletir a intenção original das partes e as porções restantes permanecerão em pleno vigor e efeito. A renúncia por qualquer das partes de qualquer termo ou condição deste Acordo ou qualquer violação dos mesmos,\ - \ em qualquer instância, não vai renunciar a tal termo ou condição ou qualquer violação subsequente. Pode atribuir os seus direitos sob este acordo a qualquer parte que consente a, e concorda em ficar vinculado pelos seus termos e condições; %{company_name} pode assignar os seus direitos sob este Acordo sem condição. O presente Acordo será vinculativo e reverterá em benefício das partes, dos seus sucessores e signatários autorizados. \n\nEste documento é CC-BY-SA. Foi atualizado pela última vez em 31 de Maio de 2013. \n\nOriginalmente adaptado de [Termos de Serviço WordPress](http://en.wordpress.com/tos/).\n" + body: "Os seguintes termos e condições governam todo o uso do sítio %{company_domain} e todo o conteúdo, serviços e produtos disponíveis no ou através do sítio, incluindo mas não limitado a, %{company_domain} Software do Fórum, %{company_domain} Fóruns de Suporte e serviço de alojamento %{company_domain} (\"Alojamento\"), (em conjunto, o Sítio). O Sítio é propriedade e operado por %{company_full_name} (\"%{company_name}\"). O Sítio oferecido está sujeito à sua aprovação sem nenhuma modificação de todos os termos e condições contidos aqui e todas as outras regras de operação políticas (incluindo, sem limitação, %{company_domain}’s [Política de Privacidade](/privacy) e [Diretrizes da Comunidade](/faq)) e procedimentos que possam ser publicados de tempos em tempos neste Sítio por %{company_name} (coletivamente, the \"Acordo\"). \n\nPor favor leia este Acordo com cuidado antes de aceder ou usar o Sítio. Ao aceder ou usar qualquer parte do Sítio, concorda em estar limitado pelos termos e condições deste acordo. Se não concorda com todos os termos e condições deste acordo, então não deve aceder ao Sítio ou usar qualquer um dos serviços. Se estes termos e condições são considerados uma oferta de %{company_name}, a sua aceitação é expressamente limitada a estes termos. O Sítio está disponível apenas a indíviduos que têm pelo menos 13 anos de idade. \n\n \n\n## [1. A Sua Conta %{company_domain} ](#1) \n\nSe criar uma conta no Sítio, será responsável por manter a segurança da sua conta e será totalmente responsável por todas as atividades que ocorrerem sob a sua conta. Deve notificar imediatamente %{company_name} de qualquer uso não autorizado da sua conta ou qualquer outra falha de segurança. %{company_name} não será passível de quaisquer atos ou omissões da sua parte, incluindo danos de qualquer tipo que incorram como resultado de tais atos ou omissões. \n\n \n\n## [2.Responsabilidade dos Participantes](#2) \n\nSe publicar material no Sítio, publicar hiperligações no Sítio, ou de outra maneira disponibilizar (ou permitir que qualquer terceira parte o faça) material no Sítio (qualquer material, “Conteúdo”), será inteiramente responsável pelo conteúdo de, e qualquer dano resultante de tal Conteúdo. Esse é o caso independentemente de o Conteúdo em questão constituir texto, gráficos, ficheiros áudio, ou programas de computadores. Ao tornar o Conteúdo disponível, está a representar e garantir que: \n\n* o descarregamento, cópia e uso do Conteúdo não irá infringir os direitos do proprietário, incluindo mas não limitado aos direitos de autor, patentes, marcas registadas ou direitos de segredos de troca, de qualquer terceira parte; \n* se o seu empregado tem direitos sob a propriedade intelectual que criou, terá que (i) ou ter recebido permissões do seu empregado para publicar ou tornar o Conteúdo disponível, incluindo mas não limitado a qualquer software, ou (ii) ter garantido uma renúncia do seu empregado a todos os direitos no e para o Conteúdo; \n* está de acordo com licenças de qualquer terceira-parte relacionada com o Conteúdo, e fez todas as coisas necessárias para passar corretamente quaisquer termos requeridos aos utilizadores finais; \n* o Conteúdo não contém ou instala quaisquer vírus, minhocas ou malware, cavalos de Tróia ou outro conteúdo destrutivo; \n* o Conteúdo não é spam, não é gerado por máquina, e não contém conteúdo indesejado sem ética ou comercial com intuito de conduzir o tráfico de sítios terceiros ou aumentar a posição de sítios terceiros em motores de pesquisa, ou ainda outros atos ilegais (tais como phishing) ou destinatários enganadores relativamente à origem do material (tais como spoofing); \n* o Conteúdo não é pornográfico, nem contém ameaças ou incita violência, e não viola os direitos de privacidade ou publicidade de qualquer terceira parte; \n* o conteúdo não está a ser anunciado através de quaisquer mensagens eletrónicas tais como hiperligações de spam ou grupos de notícias, listas de email, blogs e sítios, e similares métodos promocionais não solicitados; \n* o seu conteúdo não está nomeado de nenhuma maneira que leve os seus leitores a pensarem que é outra pessoa ou empresa; e \n* terá, no caso do Conteúdo incluir código de computador, categorizado e/ou descrito o tipo, natureza, uso e efeito dos materiais, quer tenha sido pedido para fazê-lo por %{company_name} ou pelo contrário. \n\n \n\n## [3. Licença do Conteúdo do Utilizador](#3) \n\nAs contribuições dos utilizadores estão licenciadas sob a [Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US). Sem qualquer limitação de qualquer dessas representações ou garantias, %{company_name} tem o direito (embora não tenha a obrigação) de, em critério exclusivo de %{company_name} (i) recusar ou remover qualquer conteúdo que, na sensata opinião de %{company_name} viola qualquer política de %{company_name} ou é de alguma maneira prejudicial ou censurável, ou (ii) terminar ou negar acesso ao Sítio e ao uso do mesmo a qualquer indivíduo ou entidade por alguma razão, em critério exclusivo de %{company_name}. %{company_name} não terá obrigação de fornecer uma compensação de quaisquer montantes previamente pagos. \n\n \n\n## [4. Pagamento e Renovação](#4) \n\n### Termos Gerais \n\nAtualizações ou serviços opcionais pagos podem estar disponíveis no Sítio. Ao utilizar uma atualização ou serviço opcional pago, está a concordar em pagar a %{company_name} as taxas de subscrição mensais ou anuais indicadas. Os pagamentos serão cobrados numa base pré-paga no dia em que utilizar o serviço ou a atualização e irá cobrir o uso desse serviço ou atualização por um período de subscrição mensal ou anual tal como indicado. Estas taxas não são reembolsáveis. \n\n### Renovação Automática \n\nA não ser que notifique %{company_name} antes do final do período da subscrição que quer cancelar, a sua subscrição será automaticamente renovada e você autoriza-nos a colecionar as taxas anuais ou mensais (assim como outras taxas) usando qualquer cartão de crédito ou outro mecanismo de pagamento que tivermos no seu registo. As subscrições podem ser canceladas em qualquer altura. \n\n \n\n## [5. Serviços](#5) \n\n### Serviços de Alojamento, Suporte \n\nServiços opcionais de Alojamento e Suporte podem ser fornecidos por %{company_name} sob os termos e condições para cada serviço. Ao inscrever-se numa conta com serviços de Alojamento ou Suporte, irá concordar e agir sob tais termos e condições. \n\n \n\n## [6. Responsabilidade dos Visitantes do Sítio](#6) \n\n%{company_name} não reviu, nem pode rever, todo o material, incluindo programas de computador, publicado no Sítio, e não pode portanto ser responsável pelo conteúdo do mesmo, pelo seu uso ou efeitos. Ao operar o Sítio, %{company_name} não representa ou implica que corrobora com o material publicado, ou que acredita que o material seja preciso, útil e não prejudicial. Será responsável por tomar as precauções necessárias para proteger-se a si próprio e o seu sistema computacional de vírus, minhocas, cavalos de Tróia e outros conteúdos destrutivos. O Sítio pode ter conteúdo ofensivo, indecente assim como também imprecisões técnicas, erros tipográficos entre outros erros. O Sítio pode também ter material que viola os direitos de privacidade e publicidade, ou que infringe a propriedade intelectual e outros direitos do proprietário, de terceiras partes, ou o descarregamento, cópia ou uso que é sujeito a termos e condições adicionais, estabelecidos ou não. %{company_name} está isenta de qualquer responsabilidade de qualquer dano resultante do uso por parte dos visitantes do Sítio, ou de qualquer descarregamento feito por esses visitantes do conteúdo lá publicado. \n\n \n\n## [7. Conteúdo Publicado Noutros Sítios](#7) \n\nNão revimos nem podemos rever todo o material, incluindo programas de computador, disponibilizado através de sítios e páginas em %{company_domain} no qual existem hiperligações e que se hiperligam a %{company_domain}. %{company_name} não tem qualquer controlo dos sítios e páginas não-%{company_domain}, e não é responsável pelo seu conteúdo ou o seu uso. Ao clicar num sítio ou página não--%{company_domain}, %{company_name} não representa ou implica que corrobora com tais sítios ou páginas. Você é responsável por tomar ações necessárias para proteger-se a si próprio ou o seu sistema computacional de vírus, minhocas, cavalos de Tróia e outros conteúdos destrutivos. %{company_name} renuncia qualquer responsabilidade por qualquer dano resultante do uso de sítios e páginas não-%{company_domain}. \n\n \n\n## [8. Violação de Direitos de Autor e Política DCMA](#8) \n\nAssim como %{company_name} pede aos outros para respeitarem os direitos de propriedade intelectual, a mesma respeita os direitos de propriedade intelectual dos outros. Se acredita que material localizado em ou com hiperligação para, por %{company_domain} viola os seus direitos de autor, e se este sítio reside nos EUA, encorajamo-lo a notificar a %{company_name} em concordância com a Política (“DMCA”) [Digital Millennium Copyright Act](http://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act) da %{company_name}. %{company_name} irá responder por tais notícias, incluindo tal como requerido ou apropriado por remover o material ilícito ou desativando as hiperligações para o material ilícito. %{company_name} irá terminar o acesso a e o uso do Sítio se, sob circunstâncias apropriadas, o visitante é determinado como sendo um infrator repetido dos direitos de autor e de outros direitos de propriedade intelectual de %{company_name} ou outros. No caso de tal terminação, %{company_name} não terá qualquer obrigação de fornecer uma compensação de qualquer valor previamente pago a %{company_name}. \n\n \n\n## [9. Propriedade Intelectual](#9) \n\nEste Acordo não transfere totalmente de %{company_name} para si qualquer propriedade intelectual de %{company_name} ou de terceiras partes, e todos os direitos, títulos e interesse na e para a propriedade irá permanecer (entre as partes) apenas com %{company_name}. %{company_name}, %{company_domain}, o logótipo %{company_domain} e todos as outras marcas, marcas de serviço, gráficos, logótipos usados na ligação com %{company_domain}, ou o Sítio é marca registada de %{company_name} ou licenciadores de %{company_name}. Outras marcas, marcas de serviço, gráficos e logótipos usados na hiperligação com o Sítio podem ser marcas de terceiras partes. O seu uso do Sítio não lhe concede direitos ou licença para reproduzir ou de outra forma usar quaisquer marcas de %{company_name} ou de terceiras partes. \n\n \n\n## [10. Anúncios](#10) \n\n%{company_name} reserva-se ao direito de mostrar anúncios no seu conteúdo a não ser que tenha comprado a Atualização Ad-free ou uma conta de Serviços. \n\n \n\n## [11. Atribuição](#11) \n\n%{company_name} reserva-se ao direito de mostrar hiperligações de atribuição tais como ‘Patrocinado por %{company_domain},’ e atribuição de fontes ao conteúdo do rodapé ou da sua ferramenta. Os créditos do rodapé e a ferramenta de %{company_domain} não poderão ser removidas independentemente das atualizações compradas. \n\n \n\n## [12. Alterações](#12) \n\n%{company_name} reserva-se ao direito, por critério exclusivo, de modificar ou substituir qualquer parte deste Acordo. É sua responsabilidade verificar periodicamente o Acordo e verificar as suas alterações. O seu uso ou acesso contínuo ao Sítio seguido da publicação de qualquer alteração a este Acordo constitui aceitação a essas mudanças. %{company_name} pode também, no futuro, oferecer novos serviços e/ou funcionalidades através do Sítio (incluindo, o lançamento de novas ferramentas e recursos). Estas novas funcionalidades e/ou serviços devem ser sujeitos aos termos e condições deste Acordo. \n\n \n\n## [13. Terminação](#13) \n\n%{company_name} pode terminar o seu acesso a todas ou alguma parte do Sítio em qualquer altura, com ou sem motivo, com ou sem aviso, com efeitos imediatos. Se desejar terminar este Acordo ou a sua conta %{company_domain} (se tiver uma), pode simplesmente deixar de usar o Sítio. Todas as provisões para este Acordo que pela sua natureza deverão sobreviver à terminação, incluindo, sem limitações, provisões de propriedade, isenções de garantia, indemnizações e limitações de responsabilidade. \n\n \n\n## [14. Isenção de Garantias](#14) \n\nO Sítio é fornecido “tal como está”. %{company_name} e os seus fornecedores e licenciadores ficam aqui isentos de garantias de qualquer tipo, expressas ou implícitas, sem limitação, as garantias de comerciabilidade, adequadas a uma finalidade específica. Nem %{company_name} nem os seus fornecedores e licenciadores, fazem garantias de que o Sítio está livre de erros ou que o acesso seja contínuo e ininterrupto. Se está a ler isto, aqui está [uma ajuda] (http://www.newyorker.com/online/blogs/shouts/2012/12/the-hundred-best-lists-of-all-time.html). Compreende que descarregou de, ou de outra maneira obteve conteúdo ou serviços através do Sítio a seu próprio risco e descrição. \n\n \n\n## [15. Limitação da Responsabilidade](#15) \n\nEm nenhum evento %{company_name} ou os seus fornecedores ou licenciadores, serão responsáveis em respeito a qualquer assunto deste acordo sob qualquer contrato, negligência, estrita responsabilidade ou outras teorias legais para: (i) quaisquer danos especiais, de incidentes ou consequenciais; (ii) o custo de procura de produtos ou serviços substitutos; (iii) por interrupção do uso, perda ou corrupção dos dados; ou (iv) por quaisquer valores que excedem as taxas pagas por si a %{company_name} sob este acordo durante um período doze (12) meses anterior à causa da ação. %{company_name} não deverá ter qualquer responsabilidade de qualquer falha ou atraso devido a matérias para além do seu razoável controlo. O disposto neste artigo não se aplica nas medidas proibidas pela lei aplicável. \n\n \n\n## [16. Representações Gerais e Garantia](#16) \n\nRepresenta e garante que (i) o seu uso do Sítio irá estar em estrita concordância com a [Política de Privacidade](/privacy) e das [Diretrizes da Comunidade](/diretrizes) da %{company_name}, com este Acordo e com as leis e regulações aplicáveis (incluindo sem limitação de quaisquer leis ou regulações locais no seu país, estado, cidade ou outras áreas governamentais, relativamente à conduta online e ao conteúdo aceitável, e incluindo quaisquer leis aplicáveis relativamente à transmissão de dados técnicos exportados de qualquer país em que o sítio reside ou do país em que você reside) e (ii) o seu uso do Sítio não irá infringir os direitos de propriedade intelectual de qualquer terceira parte. \n\n \n\n## [17. Indemnização](#17) \n\nConcorda em indemnizar e não prejudicar %{company_name}, os seus contratados, e os seus licenciadores, os seus respetivos diretores, empregados e agentes de e contra quaisquer reivindicações e despesas, incluindo taxas de advogados, decorrentes do seu uso do Sítio, incluindo mas não limitado à sua violação deste Acordo. \n\n \n\n## [18. Diversos](#18) \n\nEste Acordo constitui o acordo integral entre si e %{company_name} em relação ao assunto em questão, e poderá ser modificado apenas por uma emenda escrita assinada por um executivo autorizado da %{company_name}, ou pela publicação por parte da %{company_name}, de uma versão revista. Excepto o definido na lei, se houver, disposição em contrário, o presente Acordo, qualquer acesso ou uso do sítio será governado pelas leis do estado da Califórnia, E.U.A, excluindo aos conflitos das disposições da lei, e a receita própria por qualquer disputa emergente de ou relativa a qualquer do mesmo será o tribunal federal e estatal localizado em São Francisco, Califórnia. Exceto para os pedidos de medida cautelar ou equitativa ou reclamações relativas aos direitos de propriedade intelectual (que podem ser introduzidos em qualquer tribunal competente, sem a prestação de uma caução), qualquer litígio decorrente do presente acordo será resolvido de acordo com as Regras de Arbitragem de \"Judicial Arbitration and Mediation Service, Inc.” (“JAMS”) por três árbitros apontados em concordância com tais Regras. A arbitragem deverá ter lugar em São Francisco, Califórnia, em língua Inglesa e a decisão arbitral pode ser forçada em qualquer tribunal. A parte prevalecente em qualquer ação ou processo para executar este Acordo terá direito a custos e honorários dos advogados. Se qualquer parte deste Acordo for considerada inválida ou inexequível, essa parte será interpretada de forma a refletir a intenção original das partes e as porções restantes permanecerão em pleno vigor e efeito. A renúncia por qualquer das partes de qualquer termo ou condição deste Acordo ou qualquer violação dos mesmos, em qualquer instância, não vai renunciar a tal termo ou condição ou qualquer violação subsequente. Pode atribuir os seus direitos sob este acordo a qualquer parte que consente a, e concorda em ficar vinculado pelos seus termos e condições; %{company_name} pode assignar os seus direitos sob este Acordo sem condição. O presente Acordo será vinculativo e reverterá em benefício das partes, dos seus sucessores e signatários autorizados. \n\nEste documento é CC-BY-SA. Foi atualizado pela última vez em 31 de Maio de 2013. \n\nOriginalmente adaptado de [Termos de Serviço WordPress](http://en.wordpress.com/tos/).\n" privacy_topic: title: "Política de Privacidade" - body: " \n\n## [Que informações reunimos?](#reunião) \n\nReunimos informação sobre si assim que se regista no nosso sítio e juntamos dados quando participa no fórum ao ler, escrever e avaliar o conteúdo aqui partilhado. \n\nAo inscrever-se no nosso sítio, pode ser-lhe pedido para inserir o seu nome e endereço de email. Pode contudo, visitar o nosso sítio sem se registar. O seu endereço de email será verificado por um email contendo uma hiperligação única. Se essa hiperligação for visitada, sabemos que tem controlo do seu endereço de email. \n\nAo inscrever-se e publicar, recordamos o endereço IP de onde a publicação é originária. Podemos também reter logs de servidores que incluem endereços IP de todos os pedidos feitos ao servidor. \n\n \n\n## [Para que usamos as suas informações?](#usar) \n\nTodas as informações que reunimos sobre si podem ser usadas numa das seguintes maneiras: \n\n* Para personalizar a sua experiência — a sua informação ajuda-nos a responder melhor às suas necessidades individuais. \n* Para melhorar o nosso sítio — continuamos a lutar por melhorar as ofertas do nosso sítio com base na informação e feedback que recebemos de si. \n* Para melhorar o serviço ao cliente — a sua informação ajuda-nos a responder mais eficazmente aos pedidos de serviço ao cliente e pedidos de suporte. \n* Para enviar emails periodicamente — O endereço de email que nos fornece pode ser usado para lhe enviar informação, notificações que peça sobre mudanças em tópicos ou em resposta ao seu nome de utilizador, respostas a inquéritos e/ou outros pedidos ou questões. \n\n \n\n## [Como protegemos a sua informação?](#protect)\n\nImplementamos uma variedade de medidas de precaução para manter as suas informações pessoais em segurança quando insere, submete ou acede à sua informação pessoal. \n\n \n\n## [Qual é a sua política de retenção de dados?](#retenção-dados)\n\nIremos fazer um esforço de boa fé para: \n\n* Reter logs de servidores contendo o endereço IP de todos os pedidos para este servidor\ - \ não mais que 90 dias. \n* Reter endereços IP associados a utilizadores registados e às suas publicações por não mais que 5 anos. \n\n \n\n## [Usamos cookies?](#cookies) \n\nSim. Os cookies são pequenos ficheiros que um sítio ou um fornecedor de serviços transfere para o disco do seu computador através do navegador de Internet (se assim o permitir). Estes cookies permitem que o sítio reconheça o seu navegador e, se tiver uma conta registada, associá-lo a essa. \n\nUsamos cookies para entender e guardar as suas preferências para visitas futuras e compilar dados agregados sobre o tráfego do sítio e a interação com o mesmo para lhe podermos oferecer as melhores experiências e ferramentas no futuro. Podemos contratar fornecedores de serviços para nos ajudarem a entender melhor os visitantes do nosso sítio. Estes fornecedores de serviços não têm permissão para usar a informação reunida em nosso nome excepto para nos ajudar a conduzir e melhorar o nosso negócio. \n\n \n\n## [Divulgamos informação com partes exteriores?](#divulgar) \n\nNão vendemos, trocamos ou de outra maneira transferimos a sua informação pessoal para partes exteriores. Isto não inclui terceiras partes confiáveis que nos ajudam a operar sítio, conduzir o nosso negócio, ou servi-lo, enquanto estas partes acordarem em manter a informação confidencial. Podemos também partilhar a sua informação quando acreditamos que é apropriado para estar de acordo com a lei, reforçar as políticas do nosso sítio ou proteger os nossos, ou de outros, direitos, propriedades ou segurança. Contudo, informação não-pessoal do visitante pode ser fornecida a outras partes para marketing, publicidade ou outros usos. \n\n \n\n## [Hiperligações de Terceiras Partes](#terceira-parte) \n\nOcasionalmente, à nossa descrição, podemos incluir ou oferecer serviços ou produtos de terceiros no nosso sítio. Estes sítios de terceiros têm políticas de privacidade separadas e independentes. Por este motivo, não temos responsabilidade no conteúdo ou atividades destes sítios hiperligados. No entanto, procuramos\ - \ proteger a integridade do nosso sítio e damos as boas-vindas a qualquer feedback sobre estes sítios. \n\n \n\n## [Cumprimento da Proteção da Privacidade Online Infantil](#coppa) \n\nO nosso sítio, produtos e serviços são direcionados a pessoas com pelo menos 13 anos de idade. Se este servidor está nos EUA e tem menos de 13 anos de idade, como parte dos requisitos do COPPA ([Proteção da Privacidade Online Infantil]( https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act)), não utilize este sítio. \n\n \n\n## [Política de Privacidade Online](#online) \n\nEstas políticas de privacidade online aplicam-se apenas à informação reunida através do nosso sítio e não à informação reunida offline. \n\n \n\n## [O seu consentimento](#consentimento) \n\nAo utilizar o nosso sítio, está a consentir a política de privacidade do nosso sítio. \n\n \n\n## [Mudanças à nossa Política de Privacidade](#mudanças) \n\nSe decidirmos alterar a nossa política de privacidade, iremos publicar as mudanças nesta página. \n\nEste documento é CC-BY-SA. Foi atualizado pela última vez em 31 de Maio de 2013.\n" + body: " \n\n## [Que informações reunimos?](#reunião) \n\nReunimos informação sobre si assim que se regista no nosso sítio e juntamos dados quando participa no fórum ao ler, escrever e avaliar o conteúdo aqui partilhado. \n\nAo inscrever-se no nosso sítio, pode ser-lhe pedido para inserir o seu nome e endereço de email. Pode contudo, visitar o nosso sítio sem se registar. O seu endereço de email será verificado por um email contendo uma hiperligação única. Se essa hiperligação for visitada, sabemos que tem controlo do seu endereço de email. \n\nAo inscrever-se e publicar, recordamos o endereço IP de onde a publicação é originária. Podemos também reter logs de servidores que incluem endereços IP de todos os pedidos feitos ao servidor. \n\n \n\n## [Para que usamos as suas informações?](#usar) \n\nTodas as informações que reunimos sobre si podem ser usadas numa das seguintes maneiras: \n\n* Para personalizar a sua experiência — a sua informação ajuda-nos a responder melhor às suas necessidades individuais. \n* Para melhorar o nosso sítio — continuamos a lutar por melhorar as ofertas do nosso sítio com base na informação e feedback que recebemos de si. \n* Para melhorar o serviço ao cliente — a sua informação ajuda-nos a responder mais eficazmente aos pedidos de serviço ao cliente e pedidos de suporte. \n* Para enviar emails periodicamente — O endereço de email que nos fornece pode ser usado para lhe enviar informação, notificações que peça sobre mudanças em tópicos ou em resposta ao seu nome de utilizador, respostas a inquéritos e/ou outros pedidos ou questões. \n\n \n\n## [Como protegemos a sua informação?](#protect)\n\nImplementamos uma variedade de medidas de precaução para manter as suas informações pessoais em segurança quando insere, submete ou acede à sua informação pessoal. \n\n \n\n## [Qual é a sua política de retenção de dados?](#retenção-dados)\n\nIremos fazer um esforço de boa fé para: \n\n* Reter logs de servidores contendo o endereço IP de todos os pedidos para este servidor não mais que 90 dias. \n* Reter endereços IP associados a utilizadores registados e às suas publicações por não mais que 5 anos. \n\n \n\n## [Usamos cookies?](#cookies) \n\nSim. Os cookies são pequenos ficheiros que um sítio ou um fornecedor de serviços transfere para o disco do seu computador através do navegador de Internet (se assim o permitir). Estes cookies permitem que o sítio reconheça o seu navegador e, se tiver uma conta registada, associá-lo a essa. \n\nUsamos cookies para entender e guardar as suas preferências para visitas futuras e compilar dados agregados sobre o tráfego do sítio e a interação com o mesmo para lhe podermos oferecer as melhores experiências e ferramentas no futuro. Podemos contratar fornecedores de serviços para nos ajudarem a entender melhor os visitantes do nosso sítio. Estes fornecedores de serviços não têm permissão para usar a informação reunida em nosso nome excepto para nos ajudar a conduzir e melhorar o nosso negócio. \n\n \n\n## [Divulgamos informação com partes exteriores?](#divulgar) \n\nNão vendemos, trocamos ou de outra maneira transferimos a sua informação pessoal para partes exteriores. Isto não inclui terceiras partes confiáveis que nos ajudam a operar sítio, conduzir o nosso negócio, ou servi-lo, enquanto estas partes acordarem em manter a informação confidencial. Podemos também partilhar a sua informação quando acreditamos que é apropriado para estar de acordo com a lei, reforçar as políticas do nosso sítio ou proteger os nossos, ou de outros, direitos, propriedades ou segurança. Contudo, informação não-pessoal do visitante pode ser fornecida a outras partes para marketing, publicidade ou outros usos. \n\n \n\n## [Hiperligações de Terceiras Partes](#terceira-parte) \n\nOcasionalmente, à nossa descrição, podemos incluir ou oferecer serviços ou produtos de terceiros no nosso sítio. Estes sítios de terceiros têm políticas de privacidade separadas e independentes. Por este motivo, não temos responsabilidade no conteúdo ou atividades destes sítios hiperligados. No entanto, procuramos proteger a integridade do nosso sítio e damos as boas-vindas a qualquer feedback sobre estes sítios. \n\n \n\n## [Cumprimento da Proteção da Privacidade Online Infantil](#coppa) \n\nO nosso sítio, produtos e serviços são direcionados a pessoas com pelo menos 13 anos de idade. Se este servidor está nos EUA e tem menos de 13 anos de idade, como parte dos requisitos do COPPA ([Proteção da Privacidade Online Infantil]( https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act)), não utilize este sítio. \n\n \n\n## [Política de Privacidade Online](#online) \n\nEstas políticas de privacidade online aplicam-se apenas à informação reunida através do nosso sítio e não à informação reunida offline. \n\n \n\n## [O seu consentimento](#consentimento) \n\nAo utilizar o nosso sítio, está a consentir a política de privacidade do nosso sítio. \n\n \n\n## [Mudanças à nossa Política de Privacidade](#mudanças) \n\nSe decidirmos alterar a nossa política de privacidade, iremos publicar as mudanças nesta página. \n\nEste documento é CC-BY-SA. Foi atualizado pela última vez em 31 de Maio de 2013.\n" static: search_help: |

    Dicas

      -
    • A correspondência de títulos está priorizada – em caso de dúvida, pesquise por títulos
    • -
    • Palavras únicas e incomuns irão sempre produzir os melhores resultados
    • -
    • Tente pesquisar dentro de uma categoria, utilizador ou tópico em particular
    • +
    • A correspondência de títulos está priorizada – em caso de dúvida, pesquise por títulos
    • +
    • Palavras únicas e incomuns irão sempre produzir os melhores resultados
    • +
    • Tente pesquisar dentro de uma categoria, utilizador ou tópico em particular

    Opções

    - - - - - - -
    order:viewsorder:latestorder:likes
    status:openstatus:closedstatus:archivedstatus:norepliesstatus:single_user
    category:foouser:foogroup:foobadge:foo
    in:likesin:postedin:watchingin:trackingin:private
    in:bookmarksin:first
    posts_count:nummin_age:daysmax_age:days
    + + + + + + + +
    order:viewsorder:latestorder:likes
    status:openstatus:closedstatus:archivedstatus:norepliesstatus:single_user
    category:foouser:foogroup:foobadge:foo
    in:likesin:postedin:watchingin:trackingin:private
    in:bookmarksin:firstin:pinnedin:unpinned
    posts_count:numbefore:days or dateafter:days or date

    +

    Exemplos

    - rainbows category:parks status:open order:latest irá retornar uma pesquisa por tópicos que contêm a palavra "rainbows" na categoria "parks" que não estão fechados ou arquivados, ordenados pela data da última mensagem. +

      +
    • rainbows category:parks status:open order:latest irá retornar uma pesquisa por tópicos que contêm a palavra "rainbows" na categoria "parks" que não estão fechados ou arquivados, ordenados pela data da última mensagem.
    • +
    • rainbows category:"parks and gardens" in:bookmarks irá retornar uma pesquisa de tópicos que contêm a palavra “rainbows” na categoria “parks and gardens” e que estão marcados por si.
    • +

    - badges: - long_descriptions: - autobiographer: | - Este distintivo é concedido por preencher o seu perfil de utilizador e por selecionar uma imagem de perfil. Deixar a comunidade saber mais sobre quem você é e no que está interessado torna a comunidade melhor e mais ligada. - first_like: | - Este distintivo é concedido na primeira vez que gosta de uma mensagem utilizando o botão :heart:. Gostar de mensagens é uma excelente maneira de deixar os seus companheiros membros da comunidade saberem que o que eles postaram foi interessante, útil, giro, ou divertido. Partilhe o amor! - first_link: | - Este distintivo é concedido na primeira vez que coloca uma hiperligação para outro tópico numa resposta. Ligar tópicos ajuda os leitores a encontrarem conversas relacionadas interessantes, ao exibir ligação entre tópicos em ambas as direções. - first_quote: | - Este distintivo é concedido na primeira vez que cita uma mensagem na sua resposta. Citar secções relevantes de mensagens anteriores na sua resposta ajuda a manter as discussões focadas e no tópico. - first_share: | - Este distintivo é concedido na primeira vez que partilha uma hiperligação para uma mensagem ou tópico utilizando o botão de partilha. Partilhar hiperligações é uma excelente maneira de mostrar discussões interessantes com o resto do mundo e de fazer crescer a sua comunidade. - read_guidelines: | - Este distintivo é concedido por ler as diretrizes da comunidade. Seguir e partilhar estas simples diretrizes ajuda a construir uma comunidade segura, divertida e sustentável. - reader: | - Este distintivo é concedido ao ler um tópico longo. Ler é fundamental. Ler atentamente ajuda-o a seguir a conversação e leva-o a respostas melhores e mais completas. - editor: | - Este distintivo é concedido ao editar a sua mensagem. Não hesite em editar as suas mensagens em qualquer altura para melhorá-las, corrigir pequenos erros, ou adicionar algo que se tenha esquecido. - first_flag: | - Este distintivo é concedido ao sinalizar uma mensagem. Sinalizar é crítico para a saúde da sua comunidade. Se notar em alguma mensagem que necessite de atenção do moderador por favor - não hesite em sinalizá-la. Pode também utilizar o diálogo de sinalização para enviar mensagens para colegas utilizadores. - nice_share: | - Este distintivo é concedido ao partilhar uma hiperligação para uma mensagem que seja visitada por 25 visitantes externos. Bom trabalho! Partilhar hiperligações para discussões interessantes com amigos é uma excelente maneira de fazer crescer a nossa comunidade. - welcome: | - Este distintivo é concedido quando recebe o seu primeiro gosto numa mensagem. Parabéns, publicou algo que os colegas membros da comunidade acham interessante, giro, ou útil! - anniversary: | - Este distintivo é concedido quando tiver sido membro por um ano com pelo menos uma mensagem nesse ano. Obrigado por ficar por cá e por contribuir para a nossa comunidade! - good_share: | - Este distintivo é concedido por partilhar uma hiperligação para uma mensagem que seja visitada por 300 visitantes externos. Bom trabalho! Mostrou uma discussão interessante a lotnovas pessoas e ajudou-nos a crescer. - great_share: | - Este distintivo é concedido por partilhar uma hiperligação para uma mensagem que seja visitada por 100 visitantes externos. Uau! Promoveu uma discussão interessante junto de uma enorme nova audiência para esta comunidade, e ajudou-nos a crescer de uma forma exponencial. - nice_post: | - Este distintivo é concedido ao criar uma resposta que obtém 10 gostos. Bom trabalho! - nice_topic: | - Este distintivo é concedido ao criar um tópico que obtém 10 gostos. Bom trabalho! - good_post: | - Este distintivo é concedido ao criar uma resposta que obtém 25 gostos. Bom trabalho! - good_topic: |+ - Este distintivo é concedido ao criar um tópico que obtém 25 gostos. Bom trabalho! - - great_post: | - Este distintivo é concedido ao criar uma mensagem que obtém 50 gostos. Uau! - great_topic: | - Este distintivo é concedido ao criar uma resposta que obtém 50 gostos. Uau! - basic: | - Este distintivo é concedido quando atinge o nível de confiança 1. Obrigado por ficar por cá durante algum tempo e por ler alguns tópicos para aprender do que se trata a nossa comunidade. As suas restrições de novo utilizador foram removidas, e foram-lhe atribuídas habilidades essenciais da comunidade, tais como mensagens pessoais, sinalização, edição da wiki, e a habilidade de publicar imagens e múltiplas hiperligações. - member: | - Este distintivo é concedido quando atinge o nível de confiança 2. Obrigado por participar durante um período de semanas para se juntar à nossa comunidade. Agora pode enviar convites pessoais da sua página de utilizador ou tópicos individuais, criar mensagens de grupo, e mais alguns gostos por dia! - regular: | - Este distintivo é concedido quando atingir o nível de confiança 3. Obrigado por ser uma parte regular da nossa comunidade por um período de meses, um dos leitores mais ativos e um contribuinte fiável no que torna a comunidade fantástica. Agora pode recategorizar e renomear tópicos, aceder à área do salão privado, sinalizações de spam mais poderosas, e muitos mais gostos por dia. - leader: | - Este distintivo é concedido quando atinge o nível de confiança 4. É um líder nesta comunidade, selecionado pelo pessoal, e define um exemplo positivo para a comunidade nos seus trabalhos e palavras. Tem a habilidade de editar todas as mensagens, realizar ações de moderador de tópicos tais como fixar, fechar, arquivar, dividir e unir, e toneladas de gostos por dia. admin_login: success: "Email Enviado" error: "Erro!" @@ -1828,3 +1939,10 @@ pt: performance_report: initial_post_raw: Este tópico inclui relatórios diários de desempenho para o seu sítio. initial_topic_title: Relatórios de desempenho do sítio + topic_invite: + user_exists: "Pedimos desculpa, esse utilizador já foi convidado. Pode apenas convidar um utilizador para um tópico uma vez." + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml index 1bd2070eeaf..a4520fde35a 100644 --- a/config/locales/server.pt_BR.yml +++ b/config/locales/server.pt_BR.yml @@ -10,18 +10,39 @@ pt_BR: short_date_no_year: "D MMM" short_date: "D MMM, YYYY" long_date: "D de MMMM de YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%d/%m/%Y" + short_no_year: "%B %-d" + date_only: "%b %-d, %Y" + date: + month_names: [null, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro] + <<: *datetime_formats title: "Discourse" topics: "Tópicos" posts: "postagens" loading: "Carregando" powered_by_html: 'Desenvolvido por Discourse, melhor visualizado com JavaScript ativado' log_in: "Entrar" - via: "%{username} via %{site_name}" - is_reserved: "está reservado" purge_reason: "A conta não verificada, foi excluída." disable_remote_images_download_reason: "Download de imagens remotas foi desativado porque não havia espaço suficiente em disco disponível." anonymous: "Anônimo" - errors: + emails: + incoming: + default_subject: "Email recebido de %{email}" + errors: + empty_email_error: "Ocorre quando o email bruto recebido estiver em branco." + no_message_id_error: "Ocorre quando o email não possui cabeçalho 'id-mensagem'." + auto_generated_email_error: "Ocorre quando o cabeçalho 'precedência' estiver definido como: lista, lixo eletrônico, lote ou resposta_automática, ou quando outro cabeçalho contiver: enviado_automaticamente, respondido_automaticamente ou gerado_automaticamente." + no_body_detected_error: "Ocorre quando não foi possível extrair o corpo de texto e não havia anexos." + inactive_user_error: "Ocorre quando o remetente não está ativo." + blocked_user_error: "Ocorre quando o remetente foi bloqueado." + bad_destination_address: "Ocorre quando nenhum dos endereços de email nos campos Para/Cc/Cco era correspondente ao endereço de email recebido." + strangers_not_allowed_error: "Ocorre quando um usuário tentou criar um novo tópico em uma categoria da qual não é membro." + reply_user_not_matching_error: "Ocorre quando uma resposta chega em um endereço de email diferente ao da notificação enviada." + topic_not_found_error: "Ocorre quando uma resposta foi enviada mas o tópico relacionado foi excluído." + topic_closed_error: "Ocorre quando uma resposta foi enviada mas o tópico relacionado foi fechado." + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "está limitado para %{max} caracteres; você entrou com %{length}." @@ -37,8 +58,10 @@ pt_BR: exclusion: está reservado greater_than: precisar ser maior que %{count} greater_than_or_equal_to: precisa ser maior ou igual à %{count} + has_already_been_used: "já está sendo usado" inclusion: não está incluído na lista invalid: é inválido + is_invalid: "é inválido; tente ser um pouco mais descritivo" less_than: precisa ser menor que %{count} less_than_or_equal_to: deve ser menor ou igual à %{count} not_a_number: não é um número @@ -65,6 +88,13 @@ pt_BR: other: '%{count} erros impediram este %{model} de ser salvo' embed: load_from_remote: "Houve um erro ao carregar essa mensagem." + site_settings: + min_username_length_exists: "Você não pode definir o comprimento mínimo de nome de usuário como maior do que o nome de usuário mais curto." + min_username_length_range: "Você não pode colocar o mínimo acima do máximo." + max_username_length_exists: "Você não pode definir o comprimento máximo de nome de usuário como abaixo do nome de usuário mais longo." + max_username_length_range: "Você não pode definir o máximo abaixo no mínimo." + default_categories_already_selected: "Você não pode selecionar uma categoria usada noutra lista." + s3_upload_bucket_is_required: "Você não pode habilitar uploads para o S3 a não ser que tenha provido o 's3_upload_bucket'." bulk_invite: file_should_be_csv: "O arquivo enviado deve ser do formado csv ou txt." backup: @@ -75,6 +105,8 @@ pt_BR: not_found: "A URL ou recurso solicitado não pôde ser encontrado." invalid_access: "Você não tem permissão para ver o recurso solicitado." read_only_mode_enabled: "O site está em modo somente leitura. As interações estão desativadas." + reading_time: "Tempo de leitura" + likes: "Curtidas" too_many_replies: one: "Lamentamos, mas usuários novos estão temporariamente limitados a 1 resposta no mesmo tópico." other: "Lamentamos, mas usuários novos estão temporariamente limitados a %{count} respostas no mesmo tópico." @@ -91,25 +123,25 @@ pt_BR: replies: one: "1 resposta" other: "%{count} respostas" + no_mentions_allowed: "Desculpe, você não pode mencionar outros usuários." too_many_mentions: - zero: "Desculpe, você não pode mencionar outros usuários." - one: "Desculpe, você pode mencionar apenas um outro usuário em um post." + one: "Desculpe, você pode mencionar apenas %{count} usuário em um post." other: "Desculpe, você pode mencionar apenas %{count} usuários em um post." + no_mentions_allowed_newuser: "Desculpe, usuários novos não podem mencionar outros usuários." too_many_mentions_newuser: - zero: "Desculpe, usuários novos não podem mencionar outros usuários." - one: "Desculpe, usuários novos podem mencionar apenas um outro usuário em um post." - other: "Desculpe, usuários novos podem mencionar apenas %{count} usuários em um post." + one: "Desculpe, usuários novos podem mencionar apenas %{count} usuário em uma postagem." + other: "Desculpe, usuários novos podem mencionar apenas %{count} usuários em uma postagem." + no_images_allowed: "Desculpe, usuários novos não podem colocar imagens nas postagens." too_many_images: - zero: "Desculpe, usuários novos não podem colocar imagens nas postagens." - one: "Desculpe, usuários novos podem colocar apenas uma imagem nas postagens." + one: "Desculpe, usuários novos podem colocar apenas %{count} imagem nas postagens." other: "Desculpe, usuários novos podem colocar apenas %{count} imagens nas postagens." + no_attachments_allowed: "Desculpe, novos usuários não podem colocar anexos nas postagens." too_many_attachments: - zero: "Desculpe, novos usuários não podem colocar anexos nas postagens." - one: "Desculpe, novos usuários podem colocar apenas um anexo nas suas postagens." + one: "Desculpe, novos usuários podem colocar apenas %{count} anexo nas suas postagens." other: "Desculpe, novos usuários podem colocar apenas %{count} anexos nas suas postagens." + no_links_allowed: "Desculpe, usuários novos não podem colocar links nas postagens." too_many_links: - zero: "Desculpe, usuários novos não podem colocar links nas postagens." - one: "Desculpe, usuários novos podem colocar apenas um link nas postagens." + one: "Desculpe, usuários novos podem colocar apenas %{count} link nas postagens." other: "Desculpe, usuários novos podem colocar apenas %{count} links nas postagens." spamming_host: "Desculpe, você não pode colocar um link para este site." user_is_suspended: "Usuários suspensos não tem permissão para postar." @@ -133,6 +165,7 @@ pt_BR: rss_description: latest: "Últimos tópicos" hot: "Tópicos quentes" + top: "Principais tópicos" posts: "Últimos tópicos" too_late_to_edit: "Essa mensagem foi criada há muito tempo. Ela não pode mais ser editada ou apagada." excerpt_image: "imagem" @@ -142,6 +175,7 @@ pt_BR: errors: can_not_modify_automatic: "Você não pode modificar um grupo automático" member_already_exist: "'%{username}' já é um membro deste grupo." + invalid_domain: "'%{domain}' não é um domínio válido." default_names: everyone: "todos" admins: "admins" @@ -176,6 +210,14 @@ pt_BR: - Críticas construtivas são bem-vindas, mas critique *idéias*, não pessoas. Para mais, [veja nosso guia da comunidade](/guidelines). Esta mensagem aparecerá somente para o seu primeiro %{education_posts_text}. + avatar: | + ### Que tal uma imagem para a sua conta? + + Você postou alguns tópicos e respostas, mas a sua imagem de perfil não é tão original como você é -- é apenas uma carta. + + Você já considerou ** [visitando o seu perfil de usuário](%{profile_path})** e carregar uma imagem que representa você? + + É mais fácil seguir as discussões e encontrar pessoas interessantes em conversas quando todo mundo tem uma imagem de perfil única! sequential_replies: | ### Considere responder a várias mensagens simultaneamente @@ -201,9 +243,6 @@ pt_BR: user_profile: bio_raw: "Sobre Mim" errors: - messages: - is_invalid: "é inválido; tente ser um pouco mais descritivo" - has_already_been_used: "já está sendo usado" models: topic: attributes: @@ -224,6 +263,7 @@ pt_BR: attributes: hex: invalid: "Não é uma cor válida" + <<: *errors user_profile: no_info_me: "
    o campo Sobre mim do seu perfil está em branco, quer completar?
    " no_info_other: "
    %{name} ainda não colocou nada no campo Sobre Mim
    " @@ -259,13 +299,11 @@ pt_BR: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Sobre a categoria %{category} " - replace_paragraph: "[Substitua este primeiro parágrafo com uma breve descrição de sua nova categoria. Esta orientação será exibida na área de seleção de categoria, assim, tente mantê-lo abaixo de 200 caracteres. Até que você edite o texto ou crie tópicos, esta categoria não aparecerá na página de categorias.]" - post_template: "%{replace_paragraph}\n\nUse os parágrafos a seguir para uma descrição longa, assim como para estabelecer diretrizes ou regras da categoria.\n\nAlgumas coisas para se considerar em qualquer resposta de discussão:\n\n- Para que serve esta categoria? Porque algum usaria esta categoria para seu tópico?\n\n- Como esta categoria se difere das demais categorias já existentes?\n\n- Nós precisamos desta categoria?\n\n- Deveríamos mesclar esta categoria com outra, ou dividir esta categoria em mais categorias?\n" + replace_paragraph: "(Substitua este primeiro parágrafo por uma curta descrição da sua nova categoria. Este guia vai aparecer na área de seleção de categoria, então tente usar menos que 200 caracteres. **Até você editar essa descrição ou criar tópicos, esta categoria não aparece na página de categorias.**)" errors: uncategorized_parent: "Sem categoria não pode ter uma categoria pai" self_parent: "A subcategoria mãe não pode ser ela mesma" depth: "Você não pode aninhar uma subcategoria sob outra" - email_in_already_exist: "Endereço de email de entrada '%{email_in}' já está em uso para categoria '%{category_name}'." cannot_delete: uncategorized: "Não é possível excluir Sem categoria" has_subcategories: "Não é possível excluir essa categoria porque tem subcategorias." @@ -273,21 +311,32 @@ pt_BR: one: "Não é possível excluir esta categoria porque ela tem um tópico. O tópico mais velho é %{topic_link}." other: "Não é possível excluir essa categoria porque ela tem %{count} tópicos. O tópico mais velho é %{topic_link}." topic_exists_no_oldest: "Não é possível excluir esta categoria porque contagem tópico é %{count}." + uncategorized_description: "Tópicos que não precisam de uma categoria, ou que não se encaixam em nenhuma outra categoria existente." trust_levels: newuser: title: "usuário novo" basic: title: "utilizador básico" - regular: + member: title: "membro" - leader: + regular: title: "regular" - elder: + leader: title: "líder" change_failed_explanation: "Você tentou rebaixar %{user_name} para '%{new_trust_level}'. No entanto o nível de confiança dele já é '%{current_trust_level}'. %{user_name} permanecerá em '%{current_trust_level}' - se você deseja rebaixar um usuário, tranque o nível de confiança primeiro" rate_limiter: - slow_down: "Você executou esta ação muitas vezes, tente novamente mais tarde" + slow_down: "Você fez essa ação demais, tente novamente mais tarde." too_many_requests: "Nós possuímos um limite diário do número de vezes que uma ação pode ser tomada. Por favor aguarde %{time_left} antes de tentar novamente." + by_type: + first_day_replies_per_day: "Você atingiu o número máximo de respostas que um novo usuário pode criar em seu primeiro dia. Por favor aguarde %{time_left} antes de tentar novamente." + first_day_topics_per_day: "Você atingiu o número máximo de tópicos que um novo usuário pode criar em seu primeiro dia. Por favor aguarde %{time_left} antes de tentar novamente." + create_topic: "Você está criando tópicos muito rápido. Por favor aguarde %{time_left} antes de tentar novamente." + create_post: "Você está respondendo muito rápido. Por favor aguarde %{time_left} antes de tentar novamente." + topics_per_day: "Você atingiu o número máximo de novos tópicos hoje. Por favor aguarde %{time_left} antes de tentar novamente." + pms_per_day: "Você alcançou o número máximo de mensagens por hoje. Por favor aguarde %{time_left} antes de tentar de novo." + create_like: "Você atingiu o número máximo de curtidas hoje. Por favor aguarde% {time_left} antes de tentar novamente." + create_bookmark: "Você atingiu o número máximo de marcadores hoje. Por favor aguarde% {time_left} antes de tentar novamente." + edit_post: "Você atingiu o número máximo de edições hoje. Por favor aguarde% {tempo} esquerda antes de tentar novamente." hours: one: "1 hora" other: "%{count} horas" @@ -369,6 +418,7 @@ pt_BR: one: "há quase 1 ano atrás" other: "há quase %{count} anos atrás" password_reset: + no_token: "Desculpe, essa alteração de senha é muito antiga. Selecione o botão Login e use 'Esqueci minha senha' para obter um novo link." choose_new: "Por favor escolhe uma password nova" choose: "Por favor, escolha uma senha" update: 'Atualizar Senha' @@ -382,6 +432,7 @@ pt_BR: please_continue: "Continuar no %{site_name}" error: "Houve um erro ao alterar o seu endereço de email. Talvez o endereço já esteja sendo utilizado?" activation: + action: "Clique aqui para ativar sua conta" already_done: "Desculpe, este link de confirmação não está mais válido. Talvez a sua conta já esteja ativa?" please_continue: "Sua conta agora está confirmada; você vai ser redirecionado para a página inicial." continue_button: "Continuar no %{site_name}" @@ -404,16 +455,16 @@ pt_BR: description: 'Este post contém conteúdo que uma pessoa razoável consideraria ofensivo, abusivo, ou uma violação das nossas diretrizes da comunidade.' long_form: 'sinalizado como inapropriado' notify_user: - title: 'Mensagem @{{username}}' - description: 'Este post contém algo que eu quero falar com essa pessoa diretamente e em particular sobre. Não lançar uma flag.' + title: 'Envie ao(à) @ {{nome de usuário}} uma mensagem' + description: 'Eu quero falar com essa pessoa diretamente e em particular sobre o seu post.' long_form: 'mensagem privada' email_title: 'Sobre a sua postagem "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Algo mais" - description: 'Essa mensagem requer atenção da moderação por outra razão não listada acima.' - long_form: 'sinalizar isso para atenção da moderação' - email_title: 'Uma postagem em "%{title}" requer atenção do moderador' + description: 'Esta postagem requer atenção da moderação por outra razão não listada acima.' + long_form: 'sinalizou isto para a atenção da equipe' + email_title: 'Um post em "%{title}" requer a atenção da equipe' email_body: "%{link}\n\n%{message}" bookmark: title: 'Adicionar Marcador' @@ -438,7 +489,7 @@ pt_BR: long_form: 'sinalizar como impróprio' notify_moderators: title: "Algo mais" - description: 'Este tópico requer atenção moderadora geral, com base na diretrizes, TOS , ou por outro motivo não listados acima.' + description: 'Este tópico requer a atenção geral da equipe baseado nas diretrizes da comunidade, no Termos de Serviço, ou em outra razão não listada acima.' long_form: 'sinalizar isso para atenção da moderação' email_title: 'O tópico "%{title}" requer atenção do moderador' email_body: "%{link}\n\n%{message}" @@ -474,6 +525,10 @@ pt_BR: title: "Novos Usuários" xaxis: "Dia" yaxis: "Número de usuários novos" + profile_views: + title: "Visualizações de Perfil de Usuário" + xaxis: "Dia" + yaxis: "Número de perfis de usuários vistos" topics: title: "Tópicos" xaxis: "Dia" @@ -623,37 +678,6 @@ pt_BR: consumer_email_warning: "Seu site está configurado para usar Gmail (ou outro serviço de email para pessoas). Gmail limita a quantidade de emails que você pode enviar. Considere o uso de um serviço de envio de emails como mandrill.com para assegurar a entregabilidade dos emails enviados." site_contact_username_warning: "Digite o nome de um membro interno para enviar mensagens importantes automaticamente a partir dele. Atualize site_contact_username em Configurações do Site." notification_email_warning: "Emails de notificação não estão sendo enviados por um endereço de email válido no seu domínio; entrega de email será errática e não confiável. Por favor configure notification_email com um endereço de email local válido nas Configurações do Site." - content_types: - education_new_reply: - title: "Educação do Usuário Novo: Primeiras Respostas" - description: "Pop up de orientação automaticamente exibido em cima do composer quando usuário novo começa a escrever as suas duas primeiras respostas." - education_new_topic: - title: "Educação do Usuário Novo: Primeiros Tópicos" - description: "Pop up de orientação automaticamente exibido em cima do composer quando usuário novo começa a escrever os seus dois primeiros tópicos." - usage_tips: - title: "Dicas para Usuários Novos" - description: "Dicas de uso comuns, informações essenciais do fórum, e orientação básica para usuários novos." - welcome_user: - title: "Boas-vindas: Usuário Novo" - description: "Uma mensagens enviada automaticamente para todos novos usuários quando se registrarem." - welcome_invite: - title: "Boas-vindas: Usuário Convidado" - description: "Uma mensagem enviada automaticamente para todos novos usuários convidados quando eles aceitarem o convite de outro usuário para participar." - login_required_welcome_message: - title: "Boas-vindas: Login Solicitado" - description: "Mensagem de boas-vindas que é exibida para usuários que não estão logados quando a configuração de 'login requerido' está ativada." - login_required: - title: "É requerido que você entre em sua conta: Página Inicial" - description: "Texto exibido para usuários não autorizados quando é se exige entrar na conta para acessar o site." - head: - title: "cabeçalho HTML" - description: "HTML que será inserido dentro das marcações ." - top: - title: "Topo das páginas" - description: "HTML que será adicionado no topo de cada página (após o cabeçalho, antes da navegação ou o título do tópico)." - bottom: - title: "Rodapé das páginas" - description: "HTML que será adicionado antes da tag " site_settings: censored_words: "Palavras que serão substituídos automaticamente por ■■■■" delete_old_hidden_posts: "Auto-apagar todas as mensagens ocultas que ficar oculta por mais de 30 dias." @@ -668,7 +692,6 @@ pt_BR: min_private_message_title_length: "Comprimento mínimo de caracteres permitido para o título de uma mensagem" min_search_term_length: "Comprimento mínimo válido para o termo de pesquisa em caracteres" allow_uncategorized_topics: "Permitir criação de tópicos sem uma categoria. NOTA: Se existe algum tópico sem nenhuma categoria, você deve movê-los para uma categoria antes de desabilitar esta opção." - uncategorized_description: "A descrição da categoria Sem categoria. Deixe em branco para nenhuma descrição." allow_duplicate_topic_titles: "Permitir tópicos com títulos duplicados, idênticos." unique_posts_mins: "Quantos minutos antes para um utilizador poder criar uma postagem com o mesmo conteúdo outra vez?" educate_until_posts: "Quando o usuário começa a digitar suas primeiras (n) novos posts, mostrar o novo painel pop-up de educação do usuário no compositor." @@ -681,7 +704,6 @@ pt_BR: download_remote_images_to_local: "Converta imagens remotas para imagens locais, transferindo-as; isto evita imagens quebradas." download_remote_images_threshold: "Espaço mínimo necessário para download das imagens ( em % )" disabled_image_download_domains: "Imagens hospedadas nestes domínios nunca serão baixadas. \nLista delimitada por |" - ninja_edit_window: "Pelos próximos (n) segundos após a postagem, as edições não terão histórico." post_edit_time_limit: "O autor pode editar ou apagar o seu post para (n) minutos após a postagem. Defina como 0 para sempre." edit_history_visible_to_public: "Permitir que todos vejam as versões anteriores de uma postagem editada. Quando desativado, somente membros da equipe podem ver o histórico de alterações." delete_removed_posts_after: "Postagens removidas pelo autor serão automaticamente deletadas depois de (n) horas. Se o valor definido for 0, as postagens serão deletadas imediatamente." @@ -706,7 +728,6 @@ pt_BR: summary_likes_required: "Curtidas mínimas em um tópico antes de 'Resumir este tópico, ficar habilitado" summary_percent_filter: "Quando um usuário clicar em 'Resumor este tópico', mostrar os melhores % mensagens" summary_max_results: "Máximo número de posts quando resumidos por Categoria " - enable_private_messages: "Permitir a usuários de nível 1 criar e responder mensagens" enable_long_polling: "O sistema de mensagens das notificações pode fazer solicitações longas." long_polling_base_url: "URL Utilizada para \"long polling\" ( Quando um CDN for configurado, tenha certeza que essa configuração seja a padrão) ex: http://origin.site.com" long_polling_interval: "Tempo que o servidor deve aguardar antes de responder quando não existe nenhum dado para ser enviado. (apenas usuários logados)" @@ -746,7 +767,6 @@ pt_BR: suppress_reply_directly_above: "Não mostrar a em-resposta-à expansível em um post quando há apenas uma única resposta diretamente acima deste post." suppress_reply_when_quoting: "Não mostrar a em-resposta-à expansível em um post quando o post cita a resposta." max_reply_history: "Número máximo de respostas para expandir quando expandindo em-resposta-à" - experimental_reply_expansion: "Esconder respostas intermediárias quando expandindo uma resposta à (experimental)" topics_per_period_in_top_summary: "Número de melhores tópicos mostrados no sumário padrão de melhores tópicos." topics_per_period_in_top_page: "Número de melhores tópicos mostrados no 'Exibir Mais' melhores tópicos quando expandido." redirect_users_to_top_page: "Automaticamente redirecionar usuários novos e há muito ausentes para a página melhores." @@ -827,6 +847,7 @@ pt_BR: s3_region: "O nome da região da Amazon S3 que será usada para fazer upload de imagens." s3_cdn_url: "O endereço do CDN para usar para todos artefatos do s3 (por exemplo: https://cdn.algumlugar.com). AVISO: depois de mudar esta configuração você deve reconverter todas mensagens antigas." avatar_sizes: "Lista de tamanhos de avatar gerados automaticamente." + external_system_avatars_enabled: "Usar serviço de avatar externo." enable_flash_video_onebox: "Habilitar o embutir de links swf e flv (Adobe Flash) em oneboxes. AVISO: pode introduzir riscos de segurança." default_invitee_trust_level: "Nível de confiança (0-4) padrão para usuários convidados." default_trust_level: "Nível de confiança (0-4) para todos novos usuários. CUIDADO! Mudar irá colocar em sérios riscos de spam." @@ -840,16 +861,9 @@ pt_BR: tl2_requires_likes_received: "Quantos likes um usuário deve receber antes de ser promovido a nível de confiança 2." tl2_requires_likes_given: "Quantos likes um usuário deve dar antes de ser promovido a nível de confiança 2." tl2_requires_topic_reply_count: "Quantos tópicos um usuário deve responder antes de ser promovido a nível de confiança 2." - tl3_requires_days_visited: "Número mínimo de dias que um usuário precisa ter visitado o site nos últimos 100 dias para se qualificar a promoção ao nível de confiança 3. (0 até 100)" - tl3_requires_topics_replied_to: "Número mínimo de tópicos que um usuário precisa ter respondido o site nos últimos 100 dias para se qualificar a promoção ao nível de confiança 3. (0 ou mais)" - tl3_requires_topics_viewed: "O percentual de tópicos criados nos últimos 100 dias que um usuário precisa ter visto para se qualificar a promoção ao nível de confiança 3. (0 até 100)" - tl3_requires_posts_read: "O percentual de posts criados nos últimos 100 dias que um usuário precisa ter visto para se qualificar a promoção ao nível de confiança 3. (0 até 100)" tl3_requires_topics_viewed_all_time: "O mínimo total de tópicos que um usuário precisa ter visto para se qualificar a promoção ao nível de confiança 3." tl3_requires_posts_read_all_time: "O mínimo total de postagens que um usuário precisa ter lido para se qualificar a promoção ao nível de confiança 3." - tl3_requires_max_flagged: "Usuário precisa não ter mais que x postagens sinalizadas por x usuários diferentes nos últimos 100 dias para se qualificar à promoção ao nível de confiança 3, onde x é o valor dessa configuração. (0 ou mais)" tl3_promotion_min_duration: "O número mínimo de dias que uma promoção ao nível 3 dura antes que um usuário possa ser rebaixado novamente ao nível de confiança 2." - tl3_requires_likes_given: "O número mínimo de likes que devem ser dados nos últimos 100 dias para qualificar para promoção ao nível de confiança 3." - tl3_requires_likes_received: "O número mínimo de likes que devem ser recebidos nos últimos 100 dias para se qualificar para promoção ao nível de confiança 3." tl3_links_no_follow: "Não remover rel=nofollow de links postados por usuários do nível de confiança 3." min_trust_to_create_topic: "O nível de confiança mínimo necessário para criar um novo tópico." min_trust_to_edit_wiki_post: "O nível de confiança mínimo necessário para editar uma postagem marcada como wiki." @@ -925,12 +939,13 @@ pt_BR: username_change_period: "O número de dias após o registro para que as contas possam mudar o seu nome de usuário (0 para não permitir a mudança de nome de usuário)." email_editable: "Permitir que os usuários alterem o seu endereço de e-mail após o registro." logout_redirect: "Local para onde redirecionar o navegador após o logout EX: (http://somesite.com/logout)" + allow_uploaded_avatars: "Permitir aos usuários carregar fotos em seu perfil personalizado." + allow_animated_avatars: "Permitir que os usuários usem GIF animados na foto do perfil. ATENÇÃO: executar os avatares: atualizar tarefa rake após alterar essa configuração." allow_animated_thumbnails: "Gera thumbnails animados a partir de gifs animados." default_avatars: "URLs para avatars que serão usadas por padrão para novos usuários até que sejam alteradas por eles." automatically_download_gravatars: "Fazer download de Gravatars dos usuários ao criar conta ou mudança de email." digest_topics: "O número máximo de tópicos a serem mostrados no resumo via email." digest_min_excerpt_length: "O excerto mínimo de post no resumo via email, em caracteres." - suppress_digest_email_after_days: "Suprimir emails de resumo para usuários não vistos no site há mais do que (n) dias." disable_digest_emails: "Desabilitar emails de resumo para todos os usuários." max_daily_gravatar_crawls: "Número máximo de vezes que o Discourse irá checar o Gravatar por avatares personalizados em um dia" public_user_custom_fields: "Um conjunto de campos personalizados para um usuário que podem ser apresentados publicamente." @@ -939,14 +954,15 @@ pt_BR: allow_anonymous_posting: "Permitir usuários trocar para modo anônimo" anonymous_posting_min_trust_level: "Nível de confiança mínimo necessária para habilitar mensagens anônimas" anonymous_account_duration_minutes: "Para proteger anonimidade cria uma conta anônima a cada N minutos para cada usuário. Exemplo: se configurado para 600, assim que passar 600 minutos da última mensagem E o usuário trocar para anônimo, uma nova conta anônima será criada." + hide_user_profiles_from_public: "Desativar cartões de usuários, perfis de usuário e diretório de usuário para usuários anônimos." allow_profile_backgrounds: "Permitir usuários de fazerem upload de backgrounds para o perfil" - sequential_replies_threshold: "Número de posts que um usuário precisa fazer em seguida num tópico antes de ser relembrado sobre muitas respostas sequenciais." enable_mobile_theme: "Os dispositivos móveis usam um tema mobile-friendly, com a possibilidade de mudar para o site completo. Desative isso se você quiser usar um estilo personalizado que é totalmente responsivo." dominating_topic_minimum_percent: "Qual o percentual de postagens que um usuário precisa fazer em um tópico antes de ser relembrado sobre ser excessivamente dominante em um tópico." daily_performance_report: "Analiza logs do NGINX diariamente e cria um tópico na categoria Somente Equipe com os detalhes." suppress_uncategorized_badge: "Não mostrar emblema para assuntos não categorizados em listas de tópicos" global_notice: "Mostrar um banner global URGENTE, de EMERGÊNCIA para todos os visitantes, mude para branco para esconder (HTML permitido)." disable_edit_notifications: "Desabilitar modificação de notificações pelo sistema quando 'download_remote_images_to_local' estiver ativado." + automatically_unpin_topics: "Desafixar automaticamente os tópicos quando o usuário atinge o fundo." full_name_required: "Nome completo é um campo obrigatório do perfil do usuário." enable_names: "Mostrar o nome completo do usuário em seu perfil, cartão de usuário, e emails. Desabilitar para esconder o nome completo em todos os lugares." display_name_on_posts: "Também exibir o nome completo do usuário em suas mensagens" @@ -969,13 +985,11 @@ pt_BR: enable_cdn_js_debugging: "Permitir /logs de mostrar os devidos erros ao adicionar permissões de crossorigin em todos os includes de js." show_create_topics_notice: "Se o site tem menos de 5 tópicos públicos, mostrar um aviso pedindo para os administradores criarem alguns tópicos." delete_drafts_older_than_n_days: Apagar rascunhos mais antigos do que (N) dias. - vacuum_db_days: "Executar VACUUM FULL ANALYZE para recuperar o espaço do DB após migrações (definir como 0 para desabilitar)" prevent_anons_from_downloading_files: "Impedir que usuários anônimos façam download de arquivos anexados. AVISO: isso irá impedir quaisquer componentes do site que não sejam imagens, tendo sido postados como anexos, de funcionar." slug_generation_method: "Escolha um método para geração de slug. 'Codificado' irá gerar strings com '%'. 'Nenhum' irá desabilitar a geração de slugs." enable_emoji: "Habilitar emoji" emoji_set: "Como você gostaria do seu emoji?" enforce_square_emoji: "Forçar proporção quadrangular para todos emojis." - approve_post_count: "Quantidade de mensagens de novos usuários que devem ser aprovadas" approve_unless_trust_level: "Mensagens para os usuários abaixo deste nível de confiança devem ser aprovados" notify_about_queued_posts_after: "Se existirem tópicos aguardando revisão a mais de N horas, um e-mail será enviado para o e-mail de contato. Coloque 0 para cancelar estes e-mails." errors: @@ -1002,7 +1016,6 @@ pt_BR: moved_post: "%{display_username} moveu a sua postagem para %{link}" private_message: "%{display_username} enviou-te uma mensagem particular: %{link}" invited_to_private_message: "%{display_username} convidou-te para uma conversa privada: %{link}" - invited_to_topic: "%{display_username} convidou você para um tópico: %{link}" invitee_accepted: "%{display_username} aceitou o seu convite" linked: "%{display_username} linkou você em %{link}" granted_badge: "Você ganhou %{link}" @@ -1012,11 +1025,6 @@ pt_BR: category: 'Categorias' topic: 'Resultados' user: 'Utilizadores' - sso: - not_found: "Não foi possível procurar ou criar conta, contate o administrador do site" - account_not_approved: "A conta está pendente de aprovação, você receberá uma notificação por email assim que for aprovada" - unknown_error: "Erro ao fazer update de informação, contate o administrador do site" - timeout_expired: "O tempo de login ultrapassou o limite, por favor tente logar de novo" original_poster: "Postador original" most_posts: "Maior parte das postagens" most_recent_poster: "Maior parte das Postagens Recentes" @@ -1026,6 +1034,7 @@ pt_BR: not_seen_in_a_month: "Bem-vindo de volta! Nós não o vemos a um tempo. Estes são os principais tópicos de discussão desde que você foi embora." change_owner: post_revision_text: "Autoria transferida de %{old_user} para %{new_user}" + deleted_user: "um usuário deletado" emoji: errors: name_already_exists: "Desculpe, o nome '%{name}' já está sendo usado por outro emoji." @@ -1079,6 +1088,7 @@ pt_BR: omniauth_error_unknown: "Algo deu errado no processamento do seu login, por favor tente novamente." new_registrations_disabled: "Novas contas não são permitidas neste momento." password_too_long: "Senhas são limitadas a 200 caracteres." + email_too_long: "O email fornecido é muito longo. Os endereços de email não devem ter mais de 254 caracteres e nomes de domínio devem ter no máximo 253 caracteres." reserved_username: "Este nome de usuário não é permitido." missing_user_field: "Você não completou todos campos de usuário" close_window: "A autenticação está completa. Feche esta janela para continuar." @@ -1090,12 +1100,17 @@ pt_BR: characters: "deve incluir apenas números, letras e sublinhados" unique: "tem que ser único" blank: "tem que ser preenchido" + must_not_contain_two_special_chars_in_seq: "não deve conter uma seqüência de 2 ou mais caracteres especiais (.-_)" email: not_allowed: "este provedor de emails não é permitido. Por favor utilize outro endereço de email." blocked: "não é permitido." ip_address: blocked: "Novos registros não são permitidos a partir do seu endereço de IP." max_new_accounts_per_registration_ip: "Novos registros não são permitidos a partir do seu endereço de IP (quantidade máxima alcançada). Contate um membro da equipe." + flags_reminder: + subject_template: + one: "1 sinalização aguardando a ser controlada" + other: "%{count} sinalizações aguardando a ser controladas" invite_mailer: subject_template: "%{invitee_name} convidou você para '%{topic_title}' em %{site_domain_name}" text_body_template: | @@ -1130,59 +1145,19 @@ pt_BR: Este convite vem de um usuário confiável, então você não precisa se logar. invite_password_instructions: subject_template: "Defina uma senha para a sua %{site_name} conta" + text_body_template: | + Obrigado por aceitar o seu convite para %{site_name} -- Bem-Vindo! + + Clique neste link para escolher uma senha agora: + %{base_url}/users/password-reset/%{email_token} + + (Se o link acima expirou, escolha a opção "Esqueci minha senha" quando efetuar o login com o seu endereço de e-mail.) test_mailer: subject_template: "[%{site_name}] Teste de entrega de email" - text_body_template: | - Este é um email de teste de - - [**%{base_url}**][0] - - Entregabilidade de Email é complicada. Seguem algumas coisas importantes que você deve verificar primeiro: - - - Tenha *certeza* de definir o endereço de remetente `email de notificação` corretamente nas configurações do site. **O domínio especificado no endereço de remetente "from" dos emails enviados é o domínio que seus emails serão validados**. - - - Aprenda a verificar o conteúdo completo do email no seu cliente de email, para que possa examinar os cabeçalhos do email para pistas importantes. No Gmail, é a opção "mostrar original" no menu de seleção no canto superior direito de cada email. - - - **IMPORTANTE:** Seu provedor de internet (ISP) tem um registro de DNS reverso configurado para associar os nomes de domínio e os endereços de IP que você enviou os emails? [Testar seu registro reverso PTR][2] aqui. Se seu provedor (ISP) não entrou o registro de apontamento de DNS reverso apropriadamente, é muito improvável que qualquer email seja entregue. - - - O [registro SPF][8] de seu domínio está correto? [Teste seu registro SPF][1] aqui. Observe que TXT é o typo de registro correto para SPF. - - - O [registro DKIM][3] de seu domínio está correto? Isto irá melhorar significativamente a entregabilidade de email. [Teste seu registro DKIM][7] aqui. - - - Se você utiliza seu próprio servidor de email, verifique que os IPs de seu servidor de email [não estão em nenhuma lista negra][4]. Também verifique que está definitivamente enviando um nome de domínio totalmente qualificado resolvido por DNS em sua mensagem HELO. Se não estiver, irá fazer com que email seja rejeitado por muitos serviços de mail. - - (A maneira *fácil* é criar uma conta no [Mandrill][md] ou [Mailgun][mg] ou [Mailjet][mj], que tem generosos planos gratuitos e serão suficientes para comunidades pequenas. Entretanto você ainda terá que configurar os registros SPF e DKIM no seu DNS!) - - Esperamos que tenha recebido este email de verificação de entrega com sucesso! - - Boa sorte, - - Seus amigos do [Discourse](http://www.discourse.org) - - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: https://www.mailjet.com/pricing new_version_mailer: subject_template: "[%{site_name}] Nova versão do Discourse, atualização disponível" new_version_mailer_with_notes: subject_template: "[%{site_name}] atualização disponível" - flags_reminder: - flags_were_submitted: - one: "Essas sinalizações foram submetidos mais de 1 hora." - other: "Essas sinalizações foram submetidos mais de %{count} horas." - please_review: "Por favor, revise eles." - post_number: "mensagem" - how_to_disable: 'Você pode desabilitar ou modificar a frequência deste lembrete de email através da configuração "notificar sobre sinalizações após".' - subject_template: - one: "1 sinalização aguardando a ser controlada" - other: "%{count} sinalizações aguardando a ser controladas" queued_posts_reminder: subject_template: one: "[%{site_name}] 1 mensagem aguardando revisão" @@ -1290,16 +1265,8 @@ pt_BR: csv_export_failed: subject_template: "A exportação de dados falhou" text_body_template: "Nos desculpamos, mas sua exportação de dados falhou. Por favor verifique os logs ou entre em contato com um membro da staff." - email_reject_trust_level: - subject_template: "[%{site_name}] Problema com email -- Nível de Confiabilidade Insuficiente" - text_body_template: | - Lamentamos, mas o seu e-mail para%{destination} (intutulado %{former_title}) não funcionou. - - Sua conta não tem o nível de confiança necessário para criar novos tópicos para este endereço de e-mail. Se você acredita que isso é um erro, entre em contato com um membro da equipe. email_reject_no_account: subject_template: "[%{site_name}] Problema com Email -- Conta Desconhecida" - text_body_template: | - Lamentamos, mas o seu e-mail para%{destination} (intutulado %{former_title}) não funcionou. Não há nenhum relato conhecido com este endereço de e-mail. Tente enviar a partir de um endereço de e-mail diferente, ou entre em contato com um membro da equipe. email_reject_empty: subject_template: "[%{site_name}] Problema com email -- Sem conteúdo" email_reject_parsing: @@ -1310,32 +1277,8 @@ pt_BR: Desculpe, mas a mensagem do email %{destination} (titled %{former_title}) não funcionou. Sua conta não possui privilégios para postar novos topicos nessa categoria. Se acredita que isso esteja errado, entre em contato com um dos membros responsáveis.. - email_reject_post_error: - subject_template: "[%{site_name}] Problema com email -- Erro de postagem" - text_body_template: | - Desculpe-nos, mas seu e-mail para %{destination} (entitulado %{former_title}) não funcionou. - - Algumas possíveis causas são: formatação complexa, mensagem muito grande, mensagem muito pequena. Por favor tente novamente, ou poste através do site se persistir. - email_reject_post_error_specified: - subject_template: "[%{site_name}] Problema com email -- Erro de postagem" - text_body_template: | - Desculpe-nos, mas seu e-mail para %{destination} (entitulado %{former_title}) não funcionou. - - Razão: - - %{post_error} - - Se você puder corrigir, por favor tente novamente. email_reject_reply_key: subject_template: "[%{site_name}] Problema com email -- Chave de Resposta Desconhecida" - text_body_template: | - Pedimos desculpas, mas seu email para %{destination} (titled %{former_title}) não foi enviado. - - O endereço de email do destinatário é desconhecido ou inválido, Contate um dos moderadores para relatar esse problema - email_reject_destination: - subject_template: "[%{site_name}] Problema com email -- Email destinatário desconhecido" - text_body_template: | - Desculpe-nos, mas seu e-mail para %{destination} (entitulado %{former_title}) não funcionou. Nenhum dos endereços de destinatário são reconhecidos pelo fórum. Por favor tenha certeza que o fórum está na linha To: (não CC ou BCC), e que você está enviando para o endereço de e-mail fornecido pelos administradores. email_reject_topic_not_found: subject_template: "[%{site_name}] Problema com email -- Tópico Não Encontrado" email_reject_topic_closed: @@ -1344,10 +1287,6 @@ pt_BR: subject_template: "[%{site_name}] Problema com email -- Resposta Gerada Automaticamente" email_error_notification: subject_template: "[%{site_name}] Problema com email -- Erro de autenticação POP" - text_body_template: | - Erro de autenticação ao baixar e-mails através do servidor POP. - - Por favor verifique se você configurou corretamente suas credenciais de POP nos [ajustes](%{base_url}/admin_site_settings/category/email). too_many_spam_flags: subject_template: "Nova conta bloqueada" text_body_template: | @@ -1360,27 +1299,10 @@ pt_BR: Para informações adicionais, por favor consulte as nossas [diretrizes da comunidade](%{base_url}/guidelines). blocked_by_staff: subject_template: "Conta bloqueada" - text_body_template: "Olá, \n\nEsta é uma mensagem automática do %{site_name} para informá-lo de que a sua conta foi bloqueada por um membro da administração. \n\nPara informações adicionais, por favor consulte as nossas [diretrizes da comunidade](%{base_url}/guidelines).\n" user_automatically_blocked: subject_template: "Novo usuário %{username} foi bloqueado devido a denúncias da comunidade" - text_body_template: | - Essa é uma mensagem automática. - - O novo usuário [%{username}](%{base_url}%{user_url}) foi automaticamente bloqueado por ter recebido múltiplas sinalizações %{username}'s postagem(ns). - - Por favor [reveja as sinalzações](%{base_url}/admin/flags). Se %{username} foi bloqueado injustamente, clique no botão de desbloquear na [página de administração desse usuário](%{base_url}%{user_url}). - - Este limite pode ser alterado através da configuração `block_new_user` do site. spam_post_blocked: subject_template: "Novo usuário %{username} teve postagem bloqueada por repetidos links" - text_body_template: | - Essa é uma mensagem automática. - - O novo usuário [%{username}](%{base_url}%{user_url}) tentou criar múltiplas postagens com link para %{domains}, mas essas postagens foram bloqueadas para evitar spam. O usuário ainda está apto a criar novas postagens que não tenham links para %{domains}. - - Por favor, [reveja esse usuário](%{base_url}%{user_url}). - - Isso pode ser modificado na configuração `newuser_spam_host_threshold` e `white_listed_spam_host_domains` do site. unblocked: subject_template: "Conta desbloqueada" text_body_template: | @@ -1404,88 +1326,21 @@ pt_BR: unsubscribe: title: "Desinscrever" description: "Não está interessado em receber estes emails? Não tem problema! Clique em baixo para se desinscrever instantaneamente:" - reply_by_email: "Para responder, responda este email ou visite %{base_url}%{url} no seu navegador." - visit_link_to_respond: "Para responder visite %{base_url}%{url} no seu navegador." posted_by: "Postado por %{username} em %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} convidou você para uma mensagem '%{topic_title}'" - text_body_template: |2 - - %{username} convidou você para uma mensagem - - > **%{topic_title}** - > - > %{topic_excerpt} - - a - - > %{site_title} -- %{site_description} - - Por favor visitar este link para visualizar a mensagem: %{base_url}%{url} - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} convidou você para um tópico '%{topic_title}'" - text_body_template: |2 - - %{username} convidou você para uma discussão - - > **%{topic_title}** - > - > %{topic_excerpt} - - em - - > %{site_title} -- %{site_description} - - Por favor visitar o link para visualizar a mensagem: %{base_url}%{url} user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{username} respondeu à sua postagem no tópico '%{topic_title}' de %{site_name}: - - --- - %{message} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{username} citou você no tópico '%{topic_title}' de %{site_name}: - - --- - %{message} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{username} mencionou você no tópico '%{topic_title}' de %{site_name}: - - --- - %{message} - - --- - %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{username} postou no tópico '%{topic_title}' de %{site_name}: - - --- - %{message} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "Um breve resumo de %{site_link} desde que viu pela última vez em %{last_seen_at}." subject_template: "Resumo [%{site_name}]" @@ -1519,12 +1374,6 @@ pt_BR: Clique no link a seguir para escolher uma senha para a sua nova conta: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Confirma o seu novo endereço de email" - text_body_template: | - Confirma o seu endereço de email novo para %{site_name} clicando no seguinte link: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "Você foi aprovado no %{site_name}!" text_body_template: | @@ -1545,6 +1394,7 @@ pt_BR: (Se precisar se comunicar com um [membro interno](%{base_url}/about) como um novo usuário, só responder a esta mensagem.) signup: + subject_template: "[%{site_name}] Confirme sua nova conta" text_body_template: | Ben-vindo ao %{site_name}! @@ -1553,7 +1403,6 @@ pt_BR: Se não conseguires clicar no link em cima, tenta copia-lo e cola-lo na barra de endereções do seu browser de internet. page_not_found: - title: "A página solicitada não existe ou é privativa." popular_topics: "Popular" recent_topics: "Recente" see_more: "Mais" @@ -1572,6 +1421,7 @@ pt_BR: unauthorized: "Desculpe-nos, o arquivo que você está tentando enviar não é autorizado (extensões autorizadas: %{authorized_extensions})." pasted_image_filename: "Imagem colada" store_failure: "Falha ao arquivar o upload #%{upload_id} do usuário #%{user_id}." + file_missing: "Desculpe, você deve fornecer um arquivo para upload." attachments: too_large: "Desculpe, o arquivo que você está tentando enviar é muito grande (o tamanho máximo é %{max_size_kb}KB)." images: @@ -1611,57 +1461,6 @@ pt_BR: title: "Termos de Serviço" privacy_topic: title: "Política de Privacidade" - badges: - long_descriptions: - autobiographer: | - Este emblema é concedido por preencher seu perfil e selecionar uma foto de perfil. Deixar a comunidade conhecer mais sobre quem você é, e, quais são seus interesses, a torna melhor e mais conectada. - first_like: | - Este emblema é concedito na primeira vez que você curtir uma m,ensagem usando o botão :heart: . Curtir mensagens é uma ótima maneira de dizer aos membros da sua comunidade que suas mensagens foram interessantes, úteis, legais ou divertidas. Compatilhe o amor! - first_link: | - Este emblema é concedido na primeira vez que você põe um link para outro tópico numa mensagem. Linkar tópicos ajuda outros leitores a encontrar conversas interessantes relacionadas, monstrando ligações entre tópicos em ambas direções. - first_quote: | - Este emblema é concedido na primeira vez que você cita uma mensagem na sua resposta. Citar seções relevantes de mensagens anteriories na sua resposta ajuda a manter a discussão focada e no assunto original. - first_share: | - Este emblema é concedido na primeira vez que você compartilha um link para uma mensagem ou tópico usando o botão compartilhar. Compartilhar links é uma ótima maneira de mostrar discussões interessantes com o resto do mundo e assim, crescer sua comunidade. - read_guidelines: | - Este emblema é concedido por ler o guia da comunidade. Seguir e compartilhar estas simples regras ajuda a construir uma segura, divertida e sustentável comunidade. - reader: | - Este emblema é concedido por ler um tópico longo. Ler é fundamental. Ler atentamente ajuda a seguir a conversa e leva a melhores, e mais completas, respostas. - editor: | - Este emblema é concedido por editar sua mensagem. Não exite em editar sua mensagem a qualquer tempo para melhora-la , consertar pequenos enganos, ou adicionar qualquer coisa que você tenha esquecido. - first_flag: | - Este emblema é concedido por sinalizar uma mensagem. Sinalizar é critico para saúde da comunidade. Se você notar qualquer mensagem que necessita de atenção da moderação, por favor, não exite em sinalizar. Você pode também usar o diálogo de sinalização para enviar mensagem para outros usuários. - nice_share: | - Este emblema é concedido por compartilhar um link para uma mensagem que foi visitada por 25 visitantes externos. Bom trabalho! Compartilhar links para discussões interessantes é uma excelente forma de crescer sua comunidade. - welcome: | - Este emblema é concedido quando você recebe sua primeira curtida numa mensagem. Parabéns, você postou algo que sua comunidade achou interessante, legal ou divertido! - anniversary: | - Este emblema é concedido quanto você é membro por um ano com pelo menos uma mensagem nesse ano. Obrigado por fica por aqui e contribuir com nossa comunidade! - good_share: | - Este emblema é concedido por compartilhar um link de uma mensagem que foi visitada por 300 visitantes externos. Bom Trabalho! Você mostrou uma discussão interessante para um monte de novas pessoas e nos ajudou a crescer. - great_share: | - Este emblema é concedido por compartilhar um link de uma mensagem que foi visitada por 100 visitantes externos. Nossa! Você promoveu uma discussão interessante para uma grande nova audiência para esta comunidade, e nos ajudou a crescer bastante. - nice_post: | - Este emblema é concedido por criar uma resposta que conseguiu 10 curtidas. Bom trabalho! - nice_topic: | - Este emblema é concedido por criar um tópico que conseguiu 10 curtidas. Bom trabalho! - good_post: | - Este emblema é concedido por criar uma resposta que conseguiu 25 curtidas. Bom trabalho! - good_topic: | - Este emblema é concedido por criar um tópico que conseguiu 25 curtidas. Bom trabalho! - great_post: | - Este emblema é concedido por criar um tópico que conseguiu 50 curtidas. Uau! - great_topic: | - Este emblema é concedido por criar uma resposta que conseguiu 50 curtidas. Uau! - basic: | - Este emblema é concedido quando você alcança o nível de confiança 1. Obrigado por permanecer por aqui e ler alguns tópicos para aprender sobre o que é nossa comunidade. Suas restrições de novo usuário foram suspensas, e você ganhou todas habilidades essenciais de comunidade, como mensagens pessoais, sinalizações, edições de wiki, e habilidade de postar imagens e múltiplos links. - member: | - Este emblema é concedido quando você alcança o nível de confiança 2. Obrigado por participar durante essas semanas da nossa comuniadde. Você pode agora enviar convites pessoais da sua página de usuário ou de tópocos individuais, criar mensagens de grupo, e algumas curtidas a mais por dia. - regular: |+ - Este emblema é concedido quando você alcança o nível de confiança 3. Obrigado por ser parte regular da nossa comunidade durante todos esses meses, um dos mais ativos leitores e colaborador confiável para o que faz essa comunidade grande. Você pode agora recategorizar e renomear tópicos, acessar a área privada do lounge, sinalizações mais fortes de spam, e muito mais curtidas por dia. - - leader: | - Este emblema é concedido quando você alcança o nível de confiança 4. Você é um líder desta comunidade selecionado pela equipe, e define um exemplo positivo em suas ações e palavras. Você tem habilidade de editar todos tópicos, agir como moderador nas ações como fixar, fechar, delistar, arquivar, separar, agrupar e vários curtidas a mais por dia. admin_login: success: "Email Enviado" error: "Erro!" @@ -1672,3 +1471,8 @@ pt_BR: performance_report: initial_post_raw: Este tópico inclui relatórios de performance diários de seu site. initial_topic_title: Relatórios de performance do Site + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.ro.yml b/config/locales/server.ro.yml index e132b927559..0337cb7d429 100644 --- a/config/locales/server.ro.yml +++ b/config/locales/server.ro.yml @@ -16,12 +16,10 @@ ro: loading: "Încarcă" powered_by_html: 'Prin intermediul Discourse, Vizualizare optimă cu JavaScript activat' log_in: "Autentificare" - via: "%{username} prin %{site_name}" - is_reserved: "este rezervat" purge_reason: "Cont automat şters ca abandonat, neactivat" disable_remote_images_download_reason: "Descărcarea de imagini la distanţă a fost dezactivată deoarece nu mai era spaţiu pe disc suficient." anonymous: "Anonim" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "este limitat la %{max} de caractere; ați introdus %{length}." @@ -75,6 +73,7 @@ ro: not_found: "Adresa URL sau resursă cerută nu pot fi găsite." invalid_access: "Nu aveţi permisiunea să vedeţi această resursă." read_only_mode_enabled: "Site-ul este în modul doar-citire. Interacțiunile sunt dezactivate." + likes: "Aprecieri" too_many_replies: one: "Ne pare rău, dar utilizatori noi sunt limitaţi la 1 răspuns pe discuţie." few: "Ne pare rău, dar utilizatori noi sunt limitaţi la %{count} răspunsuri pe discuţie." @@ -90,26 +89,6 @@ ro: one: "1 răspuns" few: "răspunsuri" other: "%{count} răspunsuri" - too_many_mentions: - zero: "Ne pare rău, nu poți menționa alți utilizatori" - one: "Ne pare rău, poți menționa doar un utilizator într-o postare." - other: "Ne pare rău, poți menționa doar %{count} de utilizatori într-o postare." - too_many_mentions_newuser: - zero: "Ne pare rău, utilizatorii noi nu pot face mențiuni catre alți utilizatori." - one: "Ne pare rău, utilizatorii noi pot menționa doar un alt utilizator într-o postare." - other: "Ne pare rău, utilizatorii noi pot menționa doar %{count} de utilizatori într-o postare." - too_many_images: - zero: "Ne pare rău, utilizatorii noi nu pot urca imagini în postări." - one: "Ne pare rău, utilizatorii noi pot urca doar o imagine într-o postare." - other: "Ne pare rău, utilizatorii noi pot urca doar %{count} de imagini într-o postare." - too_many_attachments: - zero: "Ne pare rău, utilizatorii noi nu pot pune atașamente în postări." - one: "Ne pare rău, utilizatorii noi pot pune doar un atașament într-o postare." - other: "Ne pare rău, utilizatorii noi pot pune doar %{count} de atașamente într-o postare." - too_many_links: - zero: "Ne pare rău, utilizatorii noi nu pot adăuga adrese în postări." - one: "Ne pare rău, utilizatorii noi pot adăuga doar o adresă într-o postare'." - other: "Ne pare rău, utilizatorii noi pot adăuga doar %{count} de adrese într-o postare." spamming_host: "Ne pare rău, nu puteți adăuga o adresă acestei gazde." user_is_suspended: "Utilizatorii suspendați nu au dreptul de a posta." just_posted_that: "este prea similar cu ceea ce ați postat recent" @@ -191,9 +170,6 @@ ro: user_profile: bio_raw: "Despre Mine" errors: - messages: - is_invalid: "invalid; încercați să fiți unpic mai explicit" - has_already_been_used: "deja este folosit" models: topic: attributes: @@ -212,6 +188,7 @@ ro: attributes: hex: invalid: "nu este o culoare validă" + <<: *errors user_profile: no_info_me: "
    câmpul despre mine din profilul dvs este gol momentan, Doriți să-l completați?
    " no_info_other: "
    %{name} nu a introdus înca nimic în câmpul despre mine din profil
    " @@ -247,8 +224,6 @@ ro: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Despre categoria %{category}" - replace_paragraph: "[Înlocuiește acest paragraf cu o scurtă descriere despre categorie. Acest îndemn va apărea în aria de selectare a categoriei, deci încercați să aibă sub 200 caractere. Pană nu editați acest text sau creați o nouă discuție, Această categorie nu v-a apărea în pagina de categorii.]" - post_template: "%{replace_paragraph}\n\n Folosește următoarele paragrafe pentru o descriere mai lungă, cât și pentru a stabili orice regulă de bază sau de ajutor a categoriei.\n\n Câteva lucruri de avut în vedere în orice discuție mai jos: \n\n- Pentru ce este această categorie? De ce ar selecta alte persoane această categorie pentru discuțiile lor?\n\n- În ce fel este diferită față de celălalte existente?\n\n- Avem nevoie de această categorie?\n\n- Ar trebuii unită cu o altă categorie, sau divizată în alte 2?\n" errors: uncategorized_parent: "ce nu este categorisit nu poate avea categorie părinte" self_parent: "Părintele unei subcategorii nu poate fi ea însăși" @@ -261,12 +236,6 @@ ro: title: "utilizator nou" basic: title: "utilizator de bază" - regular: - title: "utilizator normal" - leader: - title: "lider" - elder: - title: "bătrân" change_failed_explanation: "Ați încercat să retrogradați utilizatorul %{user_name} la nivelul '%{new_trust_level}'. Totuși nivelul este deja '%{current_trust_level}'. %{user_name} va rămâne la '%{current_trust_level}'" rate_limiter: too_many_requests: "Există o limită zilnică de executare a acelei acțiuni. Vă rugăm așteptați %{time_left} până încercați iar." @@ -388,14 +357,10 @@ ro: description: 'Această postare are conținut pe care o persoană normală l-ar numii ofesator, abuziv, sau o violare a regulilor comune.' long_form: 'marcat ca necorespunzător' notify_user: - description: 'Această postare conține ceva despre care aș vrea să discut direct și privat cu acestă persoană.' email_title: 'Despre postarea dvs din "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Notifică moderatorii" - description: 'Această postare necesită atenția generală a moderatorilor bazat pe guidelines, TOS, sau pentru un alt motiv ne-listat mai sus.' - long_form: 'moderatori notificați' - email_title: 'O postare din "%{title}" necesită atenția moderatorilor' email_body: "%{link}\n\n%{message}" bookmark: title: 'Semn de carte' @@ -420,7 +385,6 @@ ro: long_form: 'marcat ca necorespunzător' notify_moderators: title: "Notifică moderatori" - description: 'Această discuție necesită atenția generală a moderatorilor bazat pe guidelines, TOS, sau pentru un alt motiv ne-listat mai sus.' long_form: 'moderatori notificați' email_title: 'discuția "%{title}" necesită atenția moderatorilor' email_body: "%{link}\n\n%{message}" @@ -567,35 +531,6 @@ ro: site_description_missing: "Opțiunea descriere_site nu este completată. Scrieți o scurtă descriere a forum-ului în setările site-ului." consumer_email_warning: "Site-ul dvs e configurat să folosească Gmail(sau alt serviciu de email) pentru a trimite emailuri. Gmail limitează numărul de email-uri trimise. Folosiți un provider de mailuri ca mandrill.com pentru a asigura trimiterea mail-urilor." notification_email_warning: "Opțiunea notificare_email este goală. Vă rugăm modificați-o în Setările site-ului." - content_types: - education_new_reply: - title: "Insturirea noului utilizator: Primele răspunsuri" - description: "Apar ghidările automat deasupra spațiului de compus când noul utilizator începe să scrie primele două răspunsuri." - education_new_topic: - title: "Insturirea noului utilizator: Primele Discuții" - description: "Apar ghidările automat deasupra spațiului de compus când noul utilizator începe să scrie primele două discuții." - usage_tips: - title: "Sfaturile noului utilizator" - description: "Sfaturile comune, informațiile esențiale forumului și intruirile cheie pentru utilizatorii noi." - welcome_user: - title: "Bine ai venit: Utilizator nou" - welcome_invite: - title: "Bine ai venit: Utilizator invitat" - login_required_welcome_message: - title: "Autentificare necesară: Mesaj de întâmpinare" - description: "Mesaj de întâmpinare afișat tuturor utilizatorilor delogați când setarea 'Autentificare necesară' este activată." - login_required: - title: "Autentificare necesară: Pagina principală" - description: "Textul afișat pentru utilizatorii neautorizați când autentificarea e necesară în site." - head: - title: "Cap HTML" - description: "HTML inserat între tagurile ." - top: - title: "Capătul paginilor" - description: "HTML ce va fi adăugat în capătul fiecărei pagini (după header, îainte de navigarea către titlul discuției)." - bottom: - title: "Sfârșitul paginilor" - description: "HTML ce va fi adăugat la sfârșitul fiecărei pagini." site_settings: default_locale: "Limba oficială a acestei instanțe de discurs (ISO 639-1 Code)" allow_user_locale: "Permite utilizatorilor să aleagă preferința de limbă pentru interfață" @@ -604,7 +539,6 @@ ro: min_topic_title_length: "Minimul de caractere permis per discuție" max_topic_title_length: "Maximul de caractere permis per discuție" min_search_term_length: "Minimul de caractere permis pentru o căutare validă" - uncategorized_description: "Descrierea categoriei necategorisite. Lăsați liber pentru nicio descriere." allow_duplicate_topic_titles: "Permite discuții cu titluri duplicate sau identice." unique_posts_mins: "Câte minute până un utilizator poate posta iar cu același conținut" educate_until_posts: "Când utilizatorul începe să scrie primele (n) postări, arată panelul de instruire în spațiul pentru compunere." @@ -615,7 +549,6 @@ ro: download_remote_images_to_local: "Transformă imaginile de legătură în imagini locale downloadându-le; asta previne stricarea imaginilor." download_remote_images_threshold: "Spațiul mimin necesar pentru download-ul imaginilor de legătura local (în procente)" disabled_image_download_domains: "Imagini de legătură nu vor mai fi downloadate din aceste domenii. Listă delimitata-vertical." - ninja_edit_window: "Pentru (n) secunde după postare, editarea nu va crea o versune nouă în istoricul postării." post_edit_time_limit: "Autorul poate edita sau șterge postarea până la (n) minute după postare. Setați 0 pentru totdeauna." edit_history_visible_to_public: "Permite oricui să vadă versiunea precedentă a unei postări editate. Când e dezactivat, doar membrii personalului pot vedea." delete_removed_posts_after: "Postările înlăturate de către autor vor fi automat șterse după (n) de ore." @@ -725,7 +658,7 @@ ro: newuser_max_mentions_per_post: "Numărul maxim de notificări de @nume poate folosii un utilizator nou într-o postare." newuser_max_replies_per_topic: "Numărul maxim de răspunsuri un utilizator nou poate adăuga într-o singură discuție până când cineva le răspunde." max_mentions_per_post: "Numărul maxim de notificări de @nume oricine poate folosii într-o postare." - create_thumbnails: "Crează previzualizari de tipul thumbnail și lightbox ale imaginilor ce sunt prea mari să încapă într-o postare." + create_thumbnails: "Creează previzualizari de tipul thumbnail și lightbox ale imaginilor ce sunt prea mari să încapă într-o postare." email_time_window_mins: "Așteaptă (n) minute până să trimiți orice email de notificare, pentru a da utilizatorilor șansa să-și editeze și să-și finalizeze postările." email_posts_context: "Câte răspunsuri precedente să fie incluse ca context în email-urile de notificare." flush_timings_secs: "Cât de frecvent se resetează timpul de pe server, în secunde." @@ -765,7 +698,6 @@ ro: digest_min_excerpt_length: "Numărul minimum de extrase din postări din email-ul rezumat, în caractere." max_daily_gravatar_crawls: "Numărul maxim de verificări făcute de Discourse pentru existența unui gravatar preferențial într-o zi" allow_profile_backgrounds: "Permite utilizatorilor să încarce fundaluri de profil." - sequential_replies_threshold: "Numărul de postări la rând într-o discuție până să-i fie amintit utilizatorului că sunt prea multe răspunsuri secvențiale. " enable_mobile_theme: "Dispozitivele mobile folosesc o temă cu abilitatea de a schimba la întregul site. Dezactivați pentru a folosii un foiae de stil preferențiala ce este total compatibilă." dominating_topic_minimum_percent: "Ce procent din postări într-o discuție trebuie să facă un utilizator înainte de ai fi amintit că domină discuția." suppress_uncategorized_badge: "Nu arăta insigna pentru discuțiile fără categorie în lista de discuții." @@ -779,7 +711,7 @@ ro: autohighlight_all_code: "Forțează aplicarea de iluminat cod către toate preformatările de blocări de cod chiar când este explicit specificată limba." feed_polling_enabled: "DOAR ÎNCORPOREAZĂ: Să încorporeze un RSS/ATOM ca postare." feed_polling_url: "DOAR ÎNCORPOREAZĂ: URL de RSS/ATOM să încorporeze." - embed_by_username: "Numele de utilizator Discourse al utilizatorului ce crează discuții încorporate." + embed_by_username: "Numele de utilizator Discourse al utilizatorului ce creează discuții încorporate." embed_username_key_from_feed: "Discourse username of the user who creates the embedded topics.." embed_truncate: "Truncate the embedded posts." embed_post_limit: "Numărul maxim de postări de încorporat." @@ -788,7 +720,6 @@ ro: notify_about_flags_after: "Dacă sunt marcaje ce nu au fost aranjate după atâtea ore, Trimite un email la email-ul de contact . Setați 0 pentru a dezactiva." enable_cdn_js_debugging: "Permite /rapoarte să afișeze erori adăugând permisiune crossorigin tuturor js-urilor incluse." show_create_topics_notice: "Dacă site-ul are mai puțin de 5 discuții publice, afișează o notificare ce cere adminilor să creeze discuții." - vacuum_db_days: "Pornește ANALIZĂ COMPLETĂ VACUUM pentru a re-obține spațiul DB după migrări (setează 0 pt dezactivare)" enable_emoji: "Activează emoji" errors: invalid_email: "Adresa de email invalidă." @@ -900,10 +831,6 @@ ro: subject_template: "[%{site_name}] O nouă versiune de Discourse, reactializare valabilă" new_version_mailer_with_notes: subject_template: "[%{site_name}] update Actualizare valabilă" - flags_reminder: - please_review: "Vă rugăm revizionați-le." - post_number: "postarea" - how_to_disable: 'Arata acest email schimbând setarea notify_about_flags_after la valoarea 0.' flags_dispositions: agreed: "Mulțumim pentru avertizare. Suntem de acord că există o problemă și ne vom interesa." agreed_and_deleted: "Mulțumim pentru avertizare. Suntem de acord că este o problemă și postarea v-a fi eliminată." @@ -932,40 +859,6 @@ ro: ``` %{logs} ``` - email_reject_trust_level: - text_body_template: | - Ne pare rău, dar emailul dvs către %{destination} (cu titlul %{former_title}) nu a funcționat. - - Contul dvs nu are nivelul de încredere necesat pentru a poșta noi discuții pe această adresă de email. Dacă sunteți de părere că este o greșeală, contactați un membru din personal. - email_reject_no_account: - text_body_template: | - Ne pare rău, dar emailul trimis de dvs către %{destination} (cu titlul %{former_title}) nu a funcționat. - - Nu există niciun cont corelat cu această adresă Email. Încercați să trimiteți de pe o altă adresa de email, sau contactați un membru al personalului. - email_reject_post_error: - text_body_template: | - Ne pare rău, dar emailul către %{destination} (cu titlul %{former_title}) nu a funcționat. - - Cauzele posibile sunt: formatul complex, mesajul prea lung, mesajul prea scurt. Încercați din nou, sau postați prin website dacă problema persistă. - email_reject_post_error_specified: - text_body_template: | - Ne pare rău, dar emailul către %{destination} (cu titlul %{former_title}) nu a funcționat. - - Respingerea mesajului: - - %{post_error} - - Încearcă să repari eroarea și încearcă din nou. - email_reject_reply_key: - text_body_template: | - Ne pare rău, dar emailul către %{destination} (cu titlul %{former_title}) nu a funcționat. - - Cheia de răspuns este ori invalidă ori nefuncționabilă, deci nu știm la ce răspunde aces email. Contactați un membru al personalului. - email_error_notification: - text_body_template: | - S-a semnalat o eroare la sustragerea mailurilor din serverul POP. - - Asigurați-vă că ați setat serverul POP în [setările site-ului](%{base_url}/admin/setări_de_site/categorie/email). too_many_spam_flags: subject_template: "Cont nou blocat" text_body_template: | @@ -978,32 +871,10 @@ ro: Pentru ajutor adițional, faceți referie la [regulile de comunitate](%{base_url}/). blocked_by_staff: subject_template: "Cont blocat" - text_body_template: | - Salut, - - Acesta e un mesaj automat din partea %{site_name} pentru a vă informa de blocarea contului dvs de către un membru al personalului. - - Pentru ajutor adițional, faceți referie la [regulile de comunitate](%{base_url}).. user_automatically_blocked: subject_template: "Noul utilizator %{username} a fost blocat datorită marcajelor date de comunitate" - text_body_template: | - Acesta este un mesaj automat. - - Noul utilizator [%{username}](%{base_url}%{user_url}) a fost automat blocat fiindcă mai mulți utilizatori au marcat postările lui %{username}. - - Vă rugăm [revizuiți marcajele](%{base_url}/admin/flags). Dacă %{username} a fost incorect blocat în a posta, faceți click pe butonul de deblocare pe [pagina de admin a acestui utilizator](%{base_url}%{user_url}). - - Acest prag poate fi schimbat prin setarea `block_new_user` a site-ului . spam_post_blocked: subject_template: "Utilizatorul nou %{username} are postările blocate datorită adreselor repetate" - text_body_template: | - Acesta este un mesaj automat. - - Noul utilizator [%{username}](%{base_url}%{user_url}) a încercat să creeze postări multiple cu adrese către %{domains}, dar aceste postări au fost blocate pentru a evita spamul. Acest utilizator este capabil încă să creeze postări ce nu conțin adrese către %{domains}. - - Vă rugăm [revizionati utilizatorul](%{base_url}%{user_url}). - - Aceasta poate fi modificat prin setările `newuser_spam_host_threshold` și `white_listed_spam_host_domains` din site. unblocked: subject_template: "Cont deblocat" text_body_template: | @@ -1027,54 +898,17 @@ ro: unsubscribe: title: "Dezabonare" description: "Nu sunteți interesat în a primii aceste email-uri? Nicio problemă! Faceți clic dedesubt pentru a vă dezabona imediat:" - reply_by_email: "Pentru a răspunde, răspundeți la acest email sau vizitați %{base_url}%{url} în browser-ul dvs." - visit_link_to_respond: "Pentru a răspunde, vizitați %{base_url}%{url} în browserul dvs." posted_by: "Postat de %{username} pe data %{post_date}" user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [MP] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "Un sumar scurt al %{site_link} de ultima oară când ați fost prezent %{last_seen_at}." subject_template: "Rezumatul [%{site_name}]" @@ -1107,12 +941,6 @@ ro: %{base_url}/users/password-reset/%{email_token} admin_login: subject_template: "[%{site_name}] Autentificare" - authorize_email: - subject_template: "[%{site_name}] Confirmă noua adresă de email" - text_body_template: | - Confirmă noua adresă de email pentru %{site_name} făcând click pe următoarea adresă: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "Ați fost aprobat pe site-ul %{site_name}!" signup: @@ -1124,7 +952,6 @@ ro: Dacă adresa de mai sus nu e accesibilă, încercați să o copiați și să o lipiți în bară de adrese a propriului browser. page_not_found: - title: "Pagina cerută nu există sau este privată." popular_topics: "Populare" recent_topics: "Recente" see_more: "Mai multe" @@ -1185,3 +1012,6 @@ ro: error: "Eroare!" email_input: "Email Admin" submit_button: "Trimite Email" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml index 02b701b952e..708dbc1310a 100644 --- a/config/locales/server.ru.yml +++ b/config/locales/server.ru.yml @@ -10,18 +10,31 @@ ru: short_date_no_year: "D MMM" short_date: "D MMM YYYY" long_date: "D MMMM YYYY, HH:mm" + datetime_formats: &datetime_formats + formats: + short: "%m-%d-%Y" + date: + month_names: [null, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь] + <<: *datetime_formats title: "Discourse" topics: "Темы" posts: "сообщения" loading: "Загрузка..." powered_by_html: 'При поддержке Discourse, лучше всего использовать с включенным JavaScript' log_in: "Войти" - via: "%{username} на %{site_name}" - is_reserved: "зарезервировано" purge_reason: "Автоматически удален, как неактивная, неактивированная учетная запись" disable_remote_images_download_reason: "Загрузка картинок была отключена из-за недостаточности места на диске." anonymous: "Гость" - errors: + emails: + incoming: + default_subject: "Входящее письмо от %{email}" + show_trimmed_content: "Показывать урезанное содержимое" + errors: + empty_email_error: "Происходит, когда мы получаем пустое письмо." + no_message_id_error: "Происходит, когда письмо не имеет заголовка 'Message-Id'." + inactive_user_error: "Происходит, когда отправитель неактивен." + blocked_user_error: "Происходит, когда отправитель заблокирован." + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "не может быть длиннее %{max} символов, а введено %{length}." @@ -37,8 +50,10 @@ ru: exclusion: зарезервировано greater_than: должно быть больше чем %{count} greater_than_or_equal_to: должно быть больше или равно %{count} + has_already_been_used: "уже было использовано" inclusion: не включен в список invalid: неверный + is_invalid: "- неверно; попробуйте описать подробнее." less_than: должен быть меньше %{count} less_than_or_equal_to: должен быть меньше или равен %{count} not_a_number: не число @@ -69,6 +84,13 @@ ru: other: '%{count} ошибок препятствуют сохранению %{model}' embed: load_from_remote: "Произошла ошибка при загрузке сообщения." + site_settings: + min_username_length_exists: "Нельзя установить минимальную длину псевдонимов, превышующую самый короткий уже существующий псевдоним." + min_username_length_range: "Нельзя установить минимум больше максимума." + max_username_length_exists: "Нельзя установить максимальную длину псевдонимов меньше, чем длина уже существующего самого длинного псевдонима." + max_username_length_range: "Нельзя установить максимум ниже минимума." + default_categories_already_selected: "Нельзя выбрать раздел, используемый в другом списке." + s3_upload_bucket_is_required: "Нельзя включить загрузки на S3, пока не задана настройка 's3_upload_bucket'." bulk_invite: file_should_be_csv: "Загружаемый файл должен быть в формате CSV или TXT." backup: @@ -79,6 +101,8 @@ ru: not_found: "Запрашиваемая страница или ресурс не найден." invalid_access: "У вас нет прав для просмотра запрашиваемого ресурса." read_only_mode_enabled: "Сайт в режиме только для чтения. Взаимодействия отключены." + reading_time: "Время на прочтение" + likes: "Лайков" too_many_replies: one: "Извините, новые пользователи могут оставлять только один ответ к теме." few: "Извините, новые пользователи могут оставлять только %{count} ответов к одной теме." @@ -101,25 +125,35 @@ ru: few: "%{count} ответа" many: "%{count} ответов" other: "%{count} ответов" + no_mentions_allowed: "Извините, но вы не можете упоминать других пользователей." too_many_mentions: - zero: "Извините, но вы не можете упоминать других пользователей." one: "Извините, но вы можете упоминать только одного пользователя в сообщении." + few: "Извините, но вы можете упоминать только %{count} пользователей в сообщении." + many: "Извините, но вы можете упоминать только %{count} пользователей в сообщении." other: "Извините, но вы можете упоминать только %{count} пользователей в сообщении." + no_mentions_allowed_newuser: "Извините, новые пользователи не могут упоминать других пользователей." too_many_mentions_newuser: - zero: "Извините, новые пользователи не могут упоминать других пользователей." one: "Извините, новые пользователи могут упоминать только одного пользователя в каждом сообщении." + few: "Извините, новые пользователи могут упоминать только %{count} пользователей в сообщении." + many: "Извините, новые пользователи могут упоминать только %{count} пользователей в сообщении." other: "Извините, новые пользователи могут упоминать только %{count} пользователей в сообщении." + no_images_allowed: "Извините, новые пользователи не могут прикреплять изображения." too_many_images: - zero: "Извините, новые пользователи не могут прикреплять изображения." one: "Извините, новые пользователи могут прикреплять только одно изображение к сообщению." + few: "Извините, новые пользователи могут прикреплять только %{count} изображений к сообщению." + many: "Извините, новые пользователи могут прикреплять только %{count} изображений к сообщению." other: "Извините, новые пользователи могут прикреплять только %{count} изображений к сообщению." + no_attachments_allowed: "К сожалению, загрузка файлов недоступна новым пользователям." too_many_attachments: - zero: "К сожалению, загрузка файлов недоступна новым пользователям." one: "К сожалению, новые пользователи могут добавить только одно вложение в сообщение." + few: "К сожалению, новые пользователи могут добавить только %{count} вложений в сообщение." + many: "К сожалению, новые пользователи могут добавить только %{count} вложений в сообщение." other: "К сожалению, новые пользователи могут добавить только %{count} вложений в сообщение." + no_links_allowed: "Извините, новые пользователи не могут размещать ссылки." too_many_links: - zero: "Извините, новые пользователи не могут размещать ссылки." one: "Извините, новые пользователи могут размещать только одну ссылку в сообщении." + few: "Извините, новые пользователи могут размещать только %{count} ссылок в сообщении." + many: "Извините, новые пользователи могут размещать только %{count} ссылок в сообщении." other: "Извините, новые пользователи могут размещать только %{count} ссылок в сообщении." spamming_host: "Извините, вы не можете разместить ссылку в этом сообщении." user_is_suspended: "Заблокированным пользователям запрещено писать." @@ -152,6 +186,7 @@ ru: errors: can_not_modify_automatic: "Нельзя изменять автоматическую группу." member_already_exist: "'%{username}' уже является членом этой группы." + invalid_domain: "'%{domain}' является некорректным доменом." default_names: everyone: "все" admins: "администраторы" @@ -192,14 +227,22 @@ ru: - Конструктивная критика приветствуется, но не забывайте критиковать *идеи*, а не людей. Больше информации вы найдете в нашем [руководстве пользователя](/guidelines). Данное окно будет показываться пока вы создаете свои первые %{education_posts_text}. + avatar: | + ### Как насчет вашей личной картинки? + + Мы видим, что вы уже написали несколько тем и сообщений, но ваша аватарка не особо привлекает - сейчас на ней просто изображена буква из вашего псевдонима или имени. + + Рекомендуем проследовать на **[страницу вашей учетной записи](%{profile_path})** и загрузить картинку, которая что-то о вас говорит. Это может быть или смайлик, или ваша фотография, или любая другая картинка. + + На самом деле, следить за дискуссиями и находить интересных собеседников намного проще, когда у всех форумчан есть своя уникальная картинка профиля! Ваша аватарка - это ваш характер и облик на форуме. sequential_replies: | - ### Рекомендуем вам совмещать ответы в одном сообщении + ### Лучше совмещать несколько ответов в один - Вместо множества отдельных сообщений с ответами, пожалуйста, используйте одно сообщение, которое включает в себя цитирование предыдущих сообщений или обращения по имени участника через механизм @имя. + Вместо того, чтобы писать и отправлять много отдельных ответов подряд, можно ответить всем по порядку в одном сообщении. Для этого нужно вставлять цитату, затем ответ на нее, затем снова цитату, затем ответ, и т.д. Также, можно упоминать участников диалога через их @псевдонимы. - Вы можете изменить свой предыдущий ответ добавив цитирование просто выделяя требуемый текст и нажимая на всплывающую кнопку ответить цитированием. + Вместо нового ответа, сейчас можно начать редактировать свой предыдущий ответ и просто добавить в него новые цитаты и ответы та них. Для этого нужно выделить требуемый текст и нажать на появившуюся кнопку ответить цитированием. - Для большинства участников проще читать темы, где есть небольшое число больших ответов вместо большого числа маленьких индивидуальных. + Для большинства читатей, намного проще читать темы, в которых длинные ответы и их мало, чем когда много коротеньких ответов. dominating_topic: |2 Данная тема является для вас важной – количество ваших ответов превышает %{percent}% процентов. @@ -225,9 +268,6 @@ ru: user_profile: bio_raw: "Обо мне" errors: - messages: - is_invalid: "слишком короткий" - has_already_been_used: "уже было использовано" models: topic: attributes: @@ -248,6 +288,7 @@ ru: attributes: hex: invalid: "не является цветом" + <<: *errors user_profile: no_info_me: "
    Поле Обо мне в вашем профиле не заполнено, не желаете ли что-нибудь написать в нем?
    " no_info_other: "
    %{name} еще не заполнил поле «Обо мне» в своём профайле.
    " @@ -260,17 +301,15 @@ ru: assets_topic_body: "Это постоянная тема, для хранения изображений и файлов, используемых в дизайне сайта, доступная только сотрудникам. Не удаляйте её! \n\n\nВаши действия:\n\n\n1. Ответьте в эту тему.\n2. Загрузите все изображения, которые вы хотите использовать для логотипов, значков и т.д. сюда. (Используйте значок на панели инструментов в редакторе сообщений, перетащите мышкой, или вставьте изображения из буфера.) \n3. Сохраните свое сообщение.\n4. Щелкните правой кнопкой мыши изображении в новом сообщении, чтобы получить путь к загруженным изображениям, или щелкните значок редактирования и получите путь к изображениям. Скопируйте пути к изображениям.\n5. Вставьте эти пути в [Настройки сайта] (/admin/site_settings/category/required) .\n\n\nЕсли Вам нужно активировать дополнительные типы файлов, отредактируйте `authorized_extensions` во вкладке [Файлы] (/admin/site_settings/category/files)." lounge_welcome: title: "Добро пожаловать в Фойе" - body: "\nПоздравляем! :confetti_ball:\n\nЕсли вы видите данное сообщение, вы достигли уровня **regular** (уровень доверия 3).\n\nУвас появились новые возможности …\n\n* Вы можете редактировать заголовок любого обсуждения\n* Вы можете менять категорию обсуждения\n* С ваших ссылок снимается ограничения nofollow ([automatic nofollow](http://en.wikipedia.org/wiki/Nofollow) is removed)\n* Вы получили доступ к закрытым категориям, которые доступны только для уровня доверия 3 и выше \n* Вы можете скрывать нежелательные сообщения в один клик\n\nС полным списком привелегий вы можете ознакомиться тут [current list of fellow regulars](/badges/3/regular). Пожалуйста прочитайте это.\n\nСпасибо Вам за то что являетесь важным членом нашего сообщества!\n\n(Для получения более детальной информации об уронях доверия посмотрите тут [see this topic][trust]. Напоминаем что данный уровень доверия сохраняется\ - \ до тех пор пока вы придерживаетесь этих правил.)\n\n[trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924\n" + body: "\nПоздравляем! :confetti_ball:\n\nЕсли вы видите данное сообщение, вы достигли уровня **regular** (уровень доверия 3).\n\nУвас появились новые возможности …\n\n* Вы можете редактировать заголовок любого обсуждения\n* Вы можете менять категорию обсуждения\n* С ваших ссылок снимается ограничения nofollow ([automatic nofollow](http://en.wikipedia.org/wiki/Nofollow) is removed)\n* Вы получили доступ к закрытым категориям, которые доступны только для уровня доверия 3 и выше \n* Вы можете скрывать нежелательные сообщения в один клик\n\nС полным списком привелегий вы можете ознакомиться тут [current list of fellow regulars](/badges/3/regular). Пожалуйста прочитайте это.\n\nСпасибо Вам за то что являетесь важным членом нашего сообщества!\n\n(Для получения более детальной информации об уронях доверия посмотрите тут [see this topic][trust]. Напоминаем что данный уровень доверия сохраняется до тех пор пока вы придерживаетесь этих правил.)\n\n[trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924\n" category: topic_prefix: "Описание раздела %{category}" - replace_paragraph: "[Замените данный текст кратким описанием нового раздела. Это описание будет отображаться в списке разделов, поэтому постарайтесь сделать его коротким (не более 200 символов).]" - post_template: "%{replace_paragraph}\n\nВ следующих абзацах введите более подробное описание раздела, а также возможные правила опубликования тем в нем.\n\nНесколько аспектов, которые следует учитывать:\n\n- Для чего нужен этот раздел? Почему люди выберут этот раздел для размещения своей темы?\n\n- Чем данные раздел отличается от тех, которые у нас уже есть?\n\n- Нужен ли нам этот раздел?\n\n- Стоит ли нам объединить его с другим разделом или разбить на несколько?\n" + replace_paragraph: "(Замените первый параграф лаконичным описанием новой категории. Данное описание будет отражено в области выбора категории, поэтому желательно ограничиться 200 символами. ** Пока вы не измените данное описание или создадите темы, данная категория не появится на странице категорий.**)" + post_template: "%{replace_paragraph}\n\nИспользуйте следующий текст для подробного описания или для определения правил раздела:\n\n- Почему нужно использовать этот раздел? Зачем он?\n\n- Насколько раздел отличается от ранее созданных?\n\n- Что должны содержать темы в этом разделе?\n\n- Действительно ли нужен этот раздел? Можем ли мы объединить его с другой категорией или подкатегорией?\n\n" errors: uncategorized_parent: "Разделу для тем вне разделов нельзя назначать родительский раздел." self_parent: "Подраздел не может быть родительским для самого себя." depth: "Подраздел не может быть родительским, т.к. допустим только один уровень вложенности разделов. " - email_in_already_exist: "Данный имейл адрес '%{email_in}' уже используется для уведомлений в категории '%{category_name}'" cannot_delete: uncategorized: "Нельзя удалить раздел, предназначенный для тем вне разделов" has_subcategories: "Невозможно удалить этот раздел, т.к. в нем есть подразделы." @@ -285,16 +324,19 @@ ru: title: "новый пользователь" basic: title: "базовый пользователь" - regular: + member: title: "участник" + regular: + title: "активный" leader: - title: "регулярный пользователь" - elder: title: "лидер" change_failed_explanation: "Вы пытаетесь понизить пользователя %{user_name} до уровня доверия '%{new_trust_level}'. Однако, его уровень доверия уже '%{current_trust_level}'. %{user_name} останется с уровнем доверия '%{current_trust_level}'. Если вы все же хотите понизить пользователя, заблокируйте вначале уровень доверия." rate_limiter: - slow_down: "Вы выполняете это действие слишком часто; пожалуйста, попробуйте еще раз позже" too_many_requests: "Вы повторяете действие слишком часто. Пожалуйста, подождите %{time_left} до следующей попытки." + by_type: + first_day_replies_per_day: "Вы достигли лимита на создание ответов для нового пользователя в первый день на сайте. Пожалуйста, попробуйте через %{time_left}." + first_day_topics_per_day: "Вы достигли лимита на создание тем для нового пользователя в первый день на сайте. Пожалуйста, попробуйте через %{time_left}." + edit_post: "Вы достигли лимита редактирования сообщений на сегодня. Пожалуйста, подождите %{time_left} перед следующей попыткой." hours: one: "1 час" few: "1 часа" @@ -426,6 +468,7 @@ ru: many: "почти %{count} лет назад" other: "почти %{count} лет назад" password_reset: + no_token: "К сожалению, данная ссылка на изменение пароля устарела. Нажмите на кнопку \"Войти\", а затем на \"Я забыл свой пароль\", чтобы сгенерировать новую ссылку для изменения пароля." choose_new: "Придумайте новый пароль" choose: "Придумайте пароль" update: 'Обновить пароль' @@ -438,7 +481,12 @@ ru: confirmed: "Ваш адрес электронной почты обновлен." please_continue: "Перейти на %{site_name}" error: "При смене электронного адреса произошла ошибка. Возможно, этот адрес уже используется?" + already_done: "Извините, ссылка для подтверждения устарела. Возможно, ваш email уже изменен?" + authorizing_old: + title: "Спасибо за подтверждение вашего email-адреса" + description: "Мы отправили сообщение с ссылкой для подтверждения вашего нового адреса." activation: + action: "Нажмите сюда, чтобы активировать вашу учетную запись" already_done: "Извините, ссылка на активацию учетной записи устарела. Возможно, ваша учетная запись уже активирована?" please_continue: "Ваша новая учетная запись успешно активирована, вы будете перенаправлены на главную страницу." continue_button: "Перейти на %{site_name}" @@ -447,31 +495,31 @@ ru: missing_session: "В данный момент, мы не можем подтвердить, была ли учетная запись создана. Убедитесь что в вашем браузере включены cookies и повторите попытку. В случае неудачи, обратитесь в техническую поддержку сайта." post_action_types: off_topic: - title: 'Не по теме' - description: 'Это сообщение не имеет отношения к данному обсуждению. Возможно, его стоит перенести в соответствующий раздел.' - long_form: 'отмечена как не по теме' + title: 'Офтопик (не по теме)' + description: 'Это сообщение не имеет отношения к теме, учитывая ее название и текст. Возможно, его стоит перенести.' + long_form: 'отметили это как офтопик (не по теме)' spam: - title: 'СПАМ' - description: 'Это реклама! Данное сообщение не представляет особого интереса или не относится к начальной теме. ' - long_form: 'отмечено как СПАМ' - email_title: '"%{title}" отмечено как спам' + title: 'Спам' + description: 'Это сообщение носит рекламный характер и не представляет особого интереса для темы.' + long_form: 'отметили это как спам' + email_title: 'Отмечено как спам: "%{title}"' email_body: "%{link}\n\n%{message}" inappropriate: - title: 'Неуместно' + title: 'Неприемлемо' description: 'Это сообщение может быть оскорбительным или нарушает правила поведения.' long_form: 'отметить как неуместное' notify_user: - title: 'Отправить сообщение @{{username}}' - description: 'Это сообщение содержит что-то, на что я хочу обратить внимание автора в приватном диалоге. Не отправлять жалобу модераторам.' + title: 'Отправить @{{username}} личное сообщение' + description: 'Я хочу обсудить это сообщение с автором приватно и не привлекая внимания модераторов.' long_form: 'оповещаемый пользователь' email_title: 'Ваше сообщение в теме "%{title}"' email_body: "%{link}\n\n%{message}\n" notify_moderators: - title: "Другое" - description: 'Это сообщение требует внимания модератора по другой причине.' - long_form: 'жалоба модератору' - email_title: 'Сообщение в теме "%{title}" требует внимания модератора' - email_body: "%{link}\n\n%{message}\n" + title: "Другая причина" + description: 'Это сообщение требует модерации по иной причине, которая отсутствует в списке выше.' + long_form: 'отметили это для модерации' + email_title: 'Сообщение в теме "%{title}" требует модерации' + email_body: "%{link}\n\n%{message}" bookmark: title: 'Добавить в закладки' description: 'Добавить сообщение в закладки' @@ -495,7 +543,6 @@ ru: long_form: 'отмеченно как неуместное' notify_moderators: title: "Другое" - description: 'Эта тема требует внимания модератора, т.к. нарушает правила поведения или пользовательское соглашение, или по другой причине.' long_form: 'жалоба модератору' email_title: 'Тема "%{title}" требует внимания модератора' email_body: "%{link}\n\n%{message}" @@ -531,6 +578,10 @@ ru: title: "Регистрации" xaxis: "Дата" yaxis: "Количество регистраций" + profile_views: + title: "Просмотры профилей" + xaxis: "Дата" + yaxis: "Количество просмотров профилей пользователей" topics: title: "Темы" xaxis: "Дата" @@ -680,37 +731,6 @@ ru: consumer_email_warning: "Сайт настроен на использование Gmail (или другого почтового сервиса) для отправки сообщений. Gmail имеет ограничения на количество отправляемых сообщений. Вы можете рассмотреть возможность использования альтернативного поставщика услуг (например, mandrill.com) для обеспечения бесперебойности доставки почтовых сообщений." site_contact_username_warning: "Введите псевдоним учетной записи персонала, от чьего имени будут отправляться важные автоматические сообщения. Обновите параметр site_contact_username в Настройках сайта." notification_email_warning: "Email уведомления отправляются с некорректного адреса электронной почты на вашем домене; доставка сообщений будет ненадежна. Пожалуйста, установите в параметре notification_email правильный локальный адрес электронной почты в Настройках сайта." - content_types: - education_new_reply: - title: "Обучение нового пользователя: Первые ответы" - description: "Всплывающие подсказки автоматически появляются над окном ввода текста, когда новый пользователь начинает создавать два своих первых ответа." - education_new_topic: - title: "Обучение нового пользователя: Первые темы" - description: "Всплывающие подсказки автоматически появляются над окном ввода текста, когда новый пользователь начинает создавать две первых темы." - usage_tips: - title: "Руководство для новых пользователей" - description: "Руководство и необходимая информация для новых пользователей." - welcome_user: - title: "Приветствие: новый пользователь" - description: "Сообщение, автоматически отправляемое каждому новому пользователю после регистрации." - welcome_invite: - title: "Приветствие: Приглашенный пользователь" - description: "Сообщение, автоматически отправляемое каждому новому приглашенному пользователю после того, как он примет приглашение." - login_required_welcome_message: - title: "Требуется вход: приветствие" - description: "Приветствие, отображаемое пользователям, не вошедшим на сайт, если опция 'требуется вход' включена." - login_required: - title: "Требуется вход: Начальная страница" - description: "Текст, показываемый неавторизованным пользователям, когда требуется вход на сайт." - head: - title: "Заголовок HTML" - description: "HTML, который будет добавлен внутри тэгов " - top: - title: "Топ страниц" - description: "HTML, который будет добавлен в начале страницы (после заголовка, перед панелью навигации или заголовком темы)." - bottom: - title: "Внизу страниц" - description: "HTML код, который будет добавлен перед тегом ." site_settings: censored_words: "Слова, которые будут автоматически заменены на ■■■■" delete_old_hidden_posts: "Автоматически удалять сообщения, скрытые дольше чем 30 дней." @@ -724,7 +744,6 @@ ru: max_topic_title_length: "Максимально допустимое количество символов в названии темы." min_private_message_title_length: "Минимально допустимое количество символов в заголовке сообщения в беседе." min_search_term_length: "Минимальное количество символов в поисковом запросе." - uncategorized_description: "Описание раздела для тем \"без раздела\". Будет скрыто есть оставить пустым." allow_duplicate_topic_titles: "Разрешить создание тем с одинаковыми названиями." unique_posts_mins: "Количество минут до того, как пользователь сможет разместить сообщение с тем же содержанием." educate_until_posts: "Количество первых сообщений новых пользователей, для которых необходимо показывать всплывающую подсказку с советами для новичков." @@ -737,7 +756,6 @@ ru: download_remote_images_to_local: "Скачивать картинки, вставленные в сообщения ссылками на другие сайты, и хранить их локально, чтобы предотвратить их изменения или утерю." download_remote_images_threshold: "Минимальное доступное место на диске (в процентах), при котором разрешено автоматическое скачивание картинок для локального хранения." disabled_image_download_domains: "Список доменов, разделенный знаком \"|\", в которых не нужно скачивать картинки." - ninja_edit_window: "Количество секунд после отправки соощения, в течении которых правка сообщения не будет записываться в историю правок." post_edit_time_limit: "Сколько минут после отправки сообщения автор может удалять или редактировать его. 0 - без ограничений." edit_history_visible_to_public: "Позволить обычным пользователям просматривать старые версии сообщений. Если исключено, история редакций будет видима только персоналу." delete_removed_posts_after: "Сообщение, которое удалено автором, будет автоматически удалено через (n) часов. Если установлено 0, то сообщение будет удалено немедленно." @@ -760,7 +778,6 @@ ru: summary_likes_required: "Минимальное количество симпатий в теме для активации кнопки \"Сводка по теме\"" summary_percent_filter: "При нажатии на кнопку \"Сводка по теме\", показывать лучшие % сообщений" summary_max_results: "Максимальное количество сообщений, выводимых в 'Обзоре темы'" - enable_private_messages: "Разрешить пользователям 1-го уровеня доверия писать и отвечать на личные сообщения" enable_long_polling: "Использовать механизм long polling для уведомлений о событиях" long_polling_base_url: "Базовый URL, используемый для long polling (при использовании CDN для раздачи динамического контента установите в этом параметре адрес origin pull), например: http://origin.site.com" long_polling_interval: "Время, которое ожидает сервер до ответа клиентам, когда нет данных для отправки (только для пользователей, вошедших на сайт)" @@ -773,7 +790,7 @@ ru: max_replies_in_first_day: "Максимальное количество ответов, которое пользователь может сделать в первый день на сайте" tl2_additional_likes_per_day_multiplier: "Увеличить лимит лайков в день для tl2 (member) до" tl3_additional_likes_per_day_multiplier: "Увеличить лимит лайков в день для tl3 (member) до" - tl4_additional_likes_per_day_multiplier: "Увеличить лимит лайков в день для tl4 (member) до" + tl4_additional_likes_per_day_multiplier: "Увеличить лимит лайков в день для tl4 (leader) до" num_flags_to_block_new_user: "Если сообщения нового пользователя получат данное количество жалоб на спам от num_users_to_block_new_user различных пользователей, скрыть все сообщения этого пользователя и отказать ему в публикации новых сообщений. 0 отключает данную функцию." num_users_to_block_new_user: "Если сообщения нового пользователя получат num_flags_to_block_new_user жалоб на спам от такого количества различных пользователей, скрыть все сообщения этого пользователя и отказать ему в публикации новых сообщений. 0 отключает данную функцию." notify_mods_when_user_blocked: "Отправить сообщение всем модераторам, если пользователь заблокирован автоматически." @@ -781,6 +798,7 @@ ru: traditional_markdown_linebreaks: "Использовать стандартный способ переноса строки в Markdown: строка должна заканчиваться двумя пробелами, чтобы перенос строки после нее сработал." post_undo_action_window_mins: "Количество минут, в течение которых пользователь может отменить действия, связанные с сообщениями: 'Мне нравится', 'Жалоба' и др." must_approve_users: "Персонал должен подтвердить регистрации новых пользователей перед тем, как им будет разрешен доступ к сайту.\nВНИМАНИЕ: включая данную функцию на существуещем сайте будет закрыт доступ к сайту для всех пользователей, кроме персонала." + pending_users_reminder_delay: "Уведомлять модераторов, если новые пользователи ждут одобрения больше чем столько часов. Установите в -1 для отключения уведомлений." ga_tracking_code: "Google analytics (ga.js) tracking code код, например: UA-12345678-9; смотрите http://google.com/analytics" ga_domain_name: "Google analytics (ga.js) доменное имя, например: mysite.com; смотрите http://google.com/analytics" ga_universal_tracking_code: "Google Universal Analytics (analytics.js) tracking code код, например: UA-12345678-9; больше информации можно узнать на странице http://google.com/analytics" @@ -800,7 +818,6 @@ ru: suppress_reply_directly_above: "Не показывать разворачивемый блок \"в ответ на\" для сообщения, если есть всего лишь одно сообщение непосредственно выше." suppress_reply_when_quoting: "Не показывать разворачивемый блок \"в ответ на\", если сообщение уже содержит цитату." max_reply_history: "Максимальное число разворачивающихся ответов в блоке \"в ответ на\"" - experimental_reply_expansion: "Скрыть промежуточные ответы, когда раскрывается все ответы (эксперементальная функция)" topics_per_period_in_top_summary: "Количество рекомендованных тем, отображаемых внизу текущей темы." topics_per_period_in_top_page: "Количество рекомендованных тем, отображаемых при нажатии 'Показать больше' в низу текущей темы." redirect_users_to_top_page: "Автоматически перенаправлять новых и давно отсутствующих пользователей к началу страницы." @@ -821,13 +838,17 @@ ru: invite_passthrough_hours: "Как долго пользователь может воспользоваться ключем приглашения для входа на сайт, указывается в часах" invite_only: "Публичная регистрация отключена. Регистрация только по приглашениям. Новые пользователи могут получить приглашения для регистрации от существующих пользователей или от редакции сайта." login_required: "Требовать авторизации для доступа к сайту, анонимный доступ запретить." + min_username_length: "Минимально допустимая длина псевдонима, символов." + max_username_length: "Максимально допустимая длина псевдонима, символов." reserved_usernames: "Псевдонимы, запрещенные для регистрации" min_password_length: "Минимальная длина пароля" + min_admin_password_length: "Минимальная длина пароля для Администратора." block_common_passwords: "Не позволять использовать пароли из списка 10 000 самых частоиспользуемых паролей." enable_sso_provider: "Реализация протокола SSO провайдера через /session/sso_provider , необходимо установить sso_secret" sso_url: "URL точки единого входа" sso_secret: "Секретный набор символов, используемый для проверки подлинности зашиврованного входа с помощью SSO, убедитесь, что это 10 или более символов" sso_overrides_avatar: "Использовать аватары предоставляемые внешним SSO провайдером. При этом настоятельно рекомендуется отключить функцию: разрешить закгрузку аватаров." + sso_not_approved_url: "Перенаправлять неподтвержденные SSO-аккаунты на этот URL" enable_local_logins: "Включить внутреннюю систему учетных записей пользователей по логину и паролю. (Требуется для работы системы приглашений.)" allow_new_registrations: "Разрешить регистрацию новых пользователей. Выключите, чтобы запретить посетителям создавать новые учетные записи." enable_yahoo_logins: "Разрешить идентификацию с Yahoo" @@ -845,6 +866,7 @@ ru: github_client_secret: "Клиентский секрет для идентификации с Github, зарегистрированный на https://github.com/settings/applications" allow_restore: "Позволить импорт, который может заменить ВСЕ данные сайта. Оставьте выключенным, если не планируете восстанавливать резервную копию" maximum_backups: "Максимальное количество резервных копий к сохранению. Более старые резервные копии будут автоматически удалены." + backup_frequency: "Как часто создавать резервные копии форума, в днях" enable_s3_backups: "Загружать резервные копии на S3 по завершению. Убедитесь, что настройки S3 заполнены." s3_backup_bucket: "Адрес папки удаленного сервера для резервных копий. ВНИМАНИЕ: Убедитесь, что место назначения защищено от посторонних." active_user_rate_limit_secs: "Как часто мы обновляем поле 'last_seen_at', в секундах" @@ -875,6 +897,7 @@ ru: s3_secret_access_key: "Amazon S3 secret key для загрузки и хранения изображений" s3_region: "Географический регион Amazon S3, который будет использоваться для хранения изображений" avatar_sizes: "Список автоматически сгенерированных размеров аватар." + default_opengraph_image_url: "URL картинки opengraph по-умолчанию." enable_flash_video_onebox: "Разрешить умную вставку ссылок sqf и flv (Adobe Flash). ВНИМАНИЕ: повышает риски безопасности сайта." default_invitee_trust_level: "Уровень доверия приглашенных пользователей по-умолчанию (от 0 до 4)." default_trust_level: "Уровень доверия по умолчанию для всех новых пользователей (0-4). ВНИМАНИЕ! Повышая уровень доверия для новых пользователей, Вы можете столкнуться с большим колличеством спама." @@ -888,16 +911,9 @@ ru: tl2_requires_likes_received: "Сколько симпатий пользователь должен получить для продвижения до уровня доверия 2." tl2_requires_likes_given: "Сколько симпатий пользователь должен выразить для продвижения до уровня доверия 2." tl2_requires_topic_reply_count: "В скольких темах пользователь должен ответить для продвижения до уровня доверия 2." - tl3_requires_days_visited: "Минимальное количество дней посещения сайта пользователем за последние 100 дней, необходимое для продвижения до уровня доверия 3. (от 0 до 100)" - tl3_requires_topics_replied_to: "Минимальное количество тем, в которых пользователь должен ответить за последние 100 дней, для возможности продвижения до уровня доверия 3. (0 и больше)" - tl3_requires_topics_viewed: "Какой процент тем созданных за последние 100 дней, должен просмотреть пользовательзователь для повышения уровня доверия до 3. (0 to 100)" - tl3_requires_posts_read: "Какой процент сообщений написанных за последние 100 дней, должен просмотреть пользовательзователь для повышения уровня доверия до 3. (0 to 100)" tl3_requires_topics_viewed_all_time: "Сколько сообщений пользователь должен прочитать для поднятия уровня доверия до 3." tl3_requires_posts_read_all_time: "Сколько сообщений пользователь должен прочитать для поднятия уровня доверия до 3." - tl3_requires_max_flagged: "Допустимое колличество сообщений пользователя, на которые пожаловалось x разных пользователей за последние 100 дней, для того чтобы была возможность поднять уровень доверия до 3, где x это значение (от 0 и выше)" tl3_promotion_min_duration: "Минимальное количество дней , в течении которых пользователь с уровнем доверия 3 не может быть понижен до урованя доверия 2." - tl3_requires_likes_given: "Минимальное количество лайков, которое должен получить пользователь за последние 100 дней, для возможности продвижения до уровня доверия 3." - tl3_requires_likes_received: "Минимальное количество лайков, которое должен получить пользователь за последние 100 дней, для возможности продвижения до уровня доверия 3." tl3_links_no_follow: "Не удалять rel=nofollow из ссылок от пользователей с уровнем доверия 3." min_trust_to_create_topic: "Минимальный уровень доверия для создания новой темы." min_trust_to_edit_wiki_post: "Минимальный уровень доверия, требуемый для редактирования вики-сообщения." @@ -955,6 +971,7 @@ ru: disable_emails: "Запретить форуму отсылать какие-либо письма." strip_images_from_short_emails: "Удалять картинки из писем размером менее 2800 байт" short_email_length: "Какие письма считать короткими, в байтах" + unsubscribe_via_email_footer: "Прикреплять ссылку для отписки от рассылки в футер отправляемых email'ов" pop3_polling_enabled: "Загружать ответы в форум в виде писем с учетной записи POP3." pop3_polling_ssl: "Использовать SSL при подключениик POP3 серверу. (Рекомендовано)" pop3_polling_period_mins: "Периодичность загрузки e-mail учетной записи POP3. ВНИМАНИЕ: требует перезапуска." @@ -973,13 +990,14 @@ ru: username_change_period: "Количество дней после регистрации, когда пользователь сможет изменить свой псевдоним (0 - запретить изменение псевдонима)." email_editable: "Позволять пользователям изменять свой адрес электронной почты после регистрации." logout_redirect: "Страница на которую будет перенаправлен пользователь после выхода, т.е. перейдет по ссылке (http://somesite.com/logout)" + allow_uploaded_avatars: "Разрешить пользователям загружать свои собственные картинки профиля." allow_animated_thumbnails: "Генерировать анимированные миниатюры gif-картинок." default_avatars: "URL для аватара, который будет использован по умолчанию для новых пользователей, пока они не изменят его." automatically_download_gravatars: "Скачивать аватарку Gravatar пользователя во время создания учетной записи или изменения e-mail." digest_topics: "Максимальное количество тем в письме - сводке новостей." digest_min_excerpt_length: "Минимальная длина (в символах) вытяжки из сообщения в письме - сводке новостей." - suppress_digest_email_after_days: "Не рассылать новости для пользователей, которые не заходили на сайт в течении (n) дней." disable_digest_emails: "Отключить рассылку новостей для всех пользователей." + detect_custom_avatars: "Проверять ли, что пользователи загрузили свои собственные картинки профиля (аватарки)." max_daily_gravatar_crawls: "Максимальное количество загрузок аватаорок с Gravatar за один день" public_user_custom_fields: "Список разрешенных дополнительных полей пользователей, которые могут быть отображены публично." staff_user_custom_fields: "Список разрешенных дополнительных полей пользователей, которые могут быть отображены для модераторов." @@ -988,9 +1006,9 @@ ru: anonymous_posting_min_trust_level: "Минимальный уровень доверия для возможности создавать темы от имени анонимного пользователя." anonymous_account_duration_minutes: "Защита от создания анонимных аккаунтов каждые N минут для каждого пользователя. Пример: Если установлено 600, означает что должно пройти 600 минут с момента последнего поста юзера И юзер вышел из системы, для того чтобы он смог создать новоый аккаунт." allow_profile_backgrounds: "Разрешить пользователям загружать фоновые картинки для своих страниц профиля." - sequential_replies_threshold: "Количество сообщений, отправленных пользователем подряд в одной теме, прежде чем ему будет показано предупреждение о слишком частых ответах." enable_mobile_theme: "Мобильные устройства используют адаптированную тему с возможностью переключения в обычный вид. Отключите данную настройку если вы хотите использовать собственный стиль для мобильных устройств." dominating_topic_minimum_percent: "Количество сообщений, отправленных пользователем подряд в одной теме, прежде чем ему будет показано предупреждение о слишком частых ответах." + disable_avatar_education_message: "Отключить обучающее сообщение при смене аватара." daily_performance_report: "Ежедневно анализировать логи сервера NGINX и отправлять сообщение с результатами анализа в тему, видимую только персоналу." suppress_uncategorized_badge: "Не показывать награду в списках тем для тех тем, которые вне разделов." global_notice: "Показать СРОЧНОЕ ВАЖНОЕ объявление на сайте всем пользователям и посетителям. Удалите содержание, чтобы отменить объявление. Разрешено использование HTML." @@ -1017,13 +1035,11 @@ ru: enable_cdn_js_debugging: "Добавить права crossorigin для всех js включений для правильного отображения ошибок в /logs " show_create_topics_notice: "Если общее количество тем меньше 5, показывать персоналу соощбение с просьбой создать новые темы." delete_drafts_older_than_n_days: Удалять черновики, которые старше (n) дней. - vacuum_db_days: "Запускать VACUUM FULL ANALYZE для восстановления базы данных после миграций ( 0 отключает)" prevent_anons_from_downloading_files: "Запретить анонимным пользователям скачивать вложенные файлы. ВНИМАНИЕ: при этом будут недоступны любые вложения кроме картинок." slug_generation_method: "Выберите метод генерации URL. 'encoded' будет изпользовать русские буквы в URL закодированные через проценты. 'none' не будет использовать перегенирацию." enable_emoji: "Активировать смайлы Emoji" emoji_set: "Какую коллекцию Emoji использовать?" enforce_square_emoji: "Принудительно использовать квадратные пропорции для смайликов." - approve_post_count: "Колличество постов от новых пользователей, которые должны быть проверены и одобрены." approve_unless_trust_level: "Сообщения для пользователей ниже этого уровня доверия подлежат проверки" errors: invalid_email: "Неправильный адрес электронной почты." @@ -1049,7 +1065,6 @@ ru: moved_post: "%{display_username} перенес ваш пост в тему %{link}" private_message: "%{display_username} написал вам сообщение: %{link}" invited_to_private_message: "%{display_username} пригласил вас обсудить сообщение: %{link}" - invited_to_topic: "%{display_username} пригласил вас поучаствовать в беседе: %{link}" invitee_accepted: "%{display_username} принял ваше приглашение" linked: "пользователь %{display_username} упомянул вас в %{link}" granted_badge: "Вы награждены: %{link}" @@ -1059,11 +1074,6 @@ ru: category: 'Разделы' topic: 'Результаты' user: 'Пользователи' - sso: - not_found: "Мы не можем найти или создать данный аккаунт, свяжитесь с администратором сайта." - account_not_approved: "Аккаунт ожидает проверки. Вы получите уведомление на почту, когда ваш аккаунт будет одобрен." - unknown_error: "Ошибка обновления информации, сообщите об этом администратору сайта." - timeout_expired: "Закончилась сессия авторизации, пожалуйста войдите заново на сайт." original_poster: "Автор" most_posts: "Большинство сообщений" most_recent_poster: "Последний автор" @@ -1071,6 +1081,17 @@ ru: redirected_to_top_reasons: new_user: "Добро пожаловать в наше сообщество! Вот самые популярные недавние темы." not_seen_in_a_month: "С возвращением! Т.к. вас не было какое-то время, мы собрали список популярных тем за время вашего отсутсвия. Вот они." + move_posts: + new_topic_moderator_post: + one: "Сообщение перенесено в новую тему: %{topic_link}" + few: "%{count} сообщения перенесены в новую тему: %{topic_link}" + many: "%{count} сообщений перенесены в новую тему: %{topic_link}" + other: "%{count} сообщений перенесены в новую тему: %{topic_link}" + existing_topic_moderator_post: + one: "Сообщение перенесено в тему %{topic_link}" + few: "%{count} сообщения перенесены в тему %{topic_link}" + many: "%{count} сообщений перенесены в тему %{topic_link}" + other: "%{count} сообщений перенесены в тему %{topic_link}" change_owner: post_revision_text: "Владелец сменен с %{old_user} на %{new_user}" deleted_user: "Удаленный пользователь" @@ -1156,6 +1177,14 @@ ru: ip_address: blocked: "Новые регистрации запрещены с вашего IP-адреса." max_new_accounts_per_registration_ip: "Новые регистрации запрещены с вашего IP-адреса (достигнут лимит регистраций). Свяжитесь с администрацией." + flags_reminder: + subject_template: + one: "1 жалоба ожидает рассмотрения" + few: "%{count} жалобы ожидают рассмотрения" + many: "%{count} жалоб ожидают рассмотрения" + other: "%{count} жалоб ожидают рассмотрения" + unsubscribe_mailer: + subject_template: "Подтвердите, что вы больше не желаете получать обновления по электронной почте от %{site_title}" invite_mailer: subject_template: "%{invitee_name} приглашает вас присоединиться к '%{topic_title}' на сайте %{site_domain_name}" text_body_template: | @@ -1190,90 +1219,19 @@ ru: Это персональное приглашение от зарегистрированного пользователя, которому мы доверяем, поэтому вам не понадобиться авторизоваться на сайте. invite_password_instructions: subject_template: "Задайте пароль для вашей учетной записи на сайте %{site_name}" + text_body_template: | + Спасибо, что приняли приглашение на сайт "%{site_name}" и добро пожаловать! + + Нажмите на следующую ссылку, чтобы установить свой пароль: + %{base_url}/users/password-reset/%{email_token} + + Если срок действия этой ссылки истек, нажмите на кнопку "Войти", а затем "Я забыл свой пароль" и введите ваш e-mail. test_mailer: subject_template: "[%{site_name}] Проверка доставки писем" - text_body_template: | - Это тестовое письмо - - [**%{base_url}**][0] - - Доставка почты это комплексная задача. Вот некоторые вещи которые необходимо проверить: - - - *Убедитесь* в том что в поле От: указан домен, который указан в настройках сайта `email для уведомлений`. ** Проверьте так же что домен указанный в поле "От" вашего письма это тот же домен на котором расположен сайт**. - - - Для этого вам необходимо знать, как посмотреть заголовки письма в почтовом клиенте. в Gmail, это вариант "показать оригинал" в выпадающем меню в правом верхнем углу каждого сообщения. - - - **ВАЖНО:** Проверьте настроена ли reverse DNS запись для связи IP c деменным именем у вашего провайдера. [проверьте Reverse PTR record][2] тут. - Если ваш провайдер не правильно указывает reverse DNS запись то скорее всего доставка почты не будет работать. - - - Указана ли для вашего домена [SPF запись][8] правильно? [Протестировать вашу SPF запись][1] вы можете тут. Помните что TXT это правильный официальный тип для записи SPF. - - - Указанна ли для вашего домена [DKIM запись][3] правильно? Это невероятно увеличивает шансы на доставку вашей почты. [Протестировать DKIM запись][7] пожно тут. - - - Если вы используете для рассылки собственный почтовый сервер, проверьте и убедитесь в том что IP вашего почтового сервера не попал в [черные списки][4]. Также проверьте что корректно отправляется полное имя хоста, который разрешен в DNS в поле HELO сообщения. В противном случае многие почтовые сервисы откажутся принимать ваши письма. - - (Самый *простой* путь это создать бесплатный аккаунт на [Mandrill][md] или [Mailgun][mg] или [Mailjet][mj], и выбрать бесплатный план, который отлично подойдет для малиньких сообществ. Вам также придется указать SPF и DKIM запись в настройках вашего DNS!) - - Мы надеимся что Вы получили данное тестовое сообщение! - - Удачи вам во всем, хорошего настроения, - - Ваши друзья на [Discourse](http://www.discourse.org) - - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: https://www.mailjet.com/pricing new_version_mailer: subject_template: "[%{site_name}] Ихууу, доступна новая версия Discourse!" - text_body_template: | - Доступна новая версия [движка вашего форума](http://www.discourse.org). - - Ваша версия: %{installed_version} - Новая версия: **%{new_version}** - - - Узнать, что нового (на английском) - на сайте [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - Обновить движок прямо из браузера - по ссылке [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Посетить сайт [англоязычного сообщества Discourse](http://meta.discourse.org), где можно почитать новости и задать вопросы. new_version_mailer_with_notes: subject_template: "[%{site_name}] новые обновления" - text_body_template: | - Доступна новая версия [движка вашего форума](http://www.discourse.org). - - Ваша версия: %{installed_version} - Новая версия: **%{new_version}** - - - Узнать, что нового (на английском) - на сайте [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - Обновить движок прямо из браузера - по ссылке [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Посетить сайт [англоязычного сообщества Discourse](http://meta.discourse.org), где можно почитать новости и задать вопросы. - - ### Что новенького - - %{notes} - flags_reminder: - flags_were_submitted: - one: "Эти жалобы были отправлены более 1 час назад." - few: "Эти жалобы были отправлены более %{count} часов назад." - many: "Эти жалобы были отправлены более %{count} часов назад." - other: "Эти жалобы были отправлены более %{count} часов назад." - please_review: "Пожалуйста, рассмотрите их" - post_number: "сообщение" - how_to_disable: 'Вы можете отключить или изменить частоту получения данных писем в настройках "уведомлений"' - subject_template: - one: "1 жалоба ожидает рассмотрения" - few: "%{count} жалобы ожидают рассмотрения" - many: "%{count} жалоб ожидают рассмотрения" - other: "%{count} жалоб ожидают рассмотрения" queued_posts_reminder: subject_template: one: "[%{site_name}] 1 сообщение ожидает проверки" @@ -1315,6 +1273,8 @@ ru: Тем не менее, если сообщение окажется скрытым второй раз, об этом будут оповещены модераторы, которые могут отреагировать на жалобы, вплоть до приостановления доступа к вашей учетной записи. Дополнительная информация доступна в [часто задаваемых вопросах](%{base_url}/guidelines). + usage_tips: + text_body_template: "Несколько советов, чтобы помочь вам освоиться на форуме:\n\n## Чтение\n\nЗдесь нет кнопок \"Следующая страница\" или номеров страниц -- чтобы читать дальше, просто прокручивайте страницу вниз, и следующие темы и сообщения будут автоматически подгружаться.\n\n## Навигация\n\n- Обратите внимание на **иконки в правом верхнем углу страницы**. Там есть поиск по форуму, меню и ссылка на вашу пользовательскую страницу с индивидуальными настройками. \n\n- Если нажать на заголовок любой темы в списке тем, вы попадёте к **первому непрочитанному сообщению** в этой теме. Если же вы хотите перейти в начало или конец темы, то вместо заголовка следует кликнуть на количество ответов или на дату последнего ответа в этой теме, соответственно:\n\n \n\n- Для быстрого перемещения к нужному сообщению внутри темы используйте индикатор с номерами постов в правом нижнем углу страницы:\n\n \n\n- Чтобы перейти в самое начало темы, можно кликнуть на заголовок наверху.\n\n- Перемещаться по форуму можно также с помощью \"горячих клавиш\". Нажмите ?, чтобы ознакомиться с их списком.\n\n## Как отвечать\n\n- Чтобы **ответить в теме**, без привязки к какому-либо предыдущему комментарию в ней, следует нажать на кнопку в самом низу на странице темы.\n\n- Чтобы ответить **конкретному человеку**, надо нажать на иконку внизу поста, на который вы хотите ответить.\n\n- Ещё есть возможность ответить на сообщение новой темой. Так имеет смысл делать, когда обсуждение значительно отклоняется от темы, заявленной в заголовке. Чтобы ответить **новой темой**, нажмите на знак справа от поста, на который вы отвечаете. Система автоматически свяжет старую и новую темы между собой ссылками.\n\nДля форматирования текста в сообщениях можно использовать HTML, BBCode и [Markdown](https://ru.wikipedia.org/wiki/Markdown). Например, чтобы выделить фрагмент текста жирным шрифтом, можно использовать любой из следующих вариантов разметки:\n\n Этот текст **будет жирным**.\n Этот текст будет жирным.\n Этот текст [b]будет жирным[/b].\n\nЧтобы при ответе использовать цитату из другого сообщения, выделите текст, который вы хотите процитировать, и нажмите кнопку \"Ответить\". И так можно проделать для нескольких цитат.\n\n\n\nЧтобы оповестить определённого участника форума о вашем сообщении, упомяните в тексте его имя пользователя (\"ник\"), начиная со знака @. Наберите `@`, и откроется список пользователей, из которого вы сможете выбрать адресата.\n\n\n\nЧтобы использовать [иконки Emoji](http://www.emoji.codes/), достаточно ввести с клавиатуры символ `:`, и откроется меню с выбором иконок. Разумеется, можно и вручную вводить традиционные смайлики `;)`\n\n\n\nЕсли вы хотите поделиться ссылкой, то можно сделать так, чтобы в сообщении автоматически показывался небольшой фрагмент с той страницы, куда ведёт ссылка. Для этого надо эту ссылку размещать в отдельной строке сообщения, не внутри текста:\n\n\n\n## Дополнительные возможности\n\nВнизу каждого сообщения есть кнопки действий:\n\n\n\nЕсли вам понравился чей-либо пост, обязательно поблагодарите автора, нажав на кнопочку с сердечком (**\"мне нравится\"**).\n\nЕсли же какое-либо сообщение вам кажется неприемлемым или нарушающим [правила форума](%{base_url}/guidelines), пожалуйста, сообщите об этом приватно автору этого сообщения или [команде форума](%{base_url}/about) (по вашему усмотрению) с помощью кнопки c флажком (\"**пожаловаться**\").\n\nКнопка с цепочкой позволяет получить ссылку на пост, чтобы сохранить её или **поделиться** через социальную сеть.\n\nИ, наконец, есть кнопка с изображением книжной закладки, которая позволяет сохранить пост в **избранное** и потом быстро вернуться к нему со своей страницы пользователя.\n\n## Оповещения\n\nКогда кто-нибудь отвечает вам, цитирует ваше сообщение или упоминает по `@имени_пользователя`, в правом верхнем углу страницы появится иконка с цифрой. Эта цифра означает количество ожидаемых вас **оповещений**. Кликните на неё, чтобы увидеть список.\n\n\n\nЕсли новое оповещение появится когда вас нет на сайте, то оно продублируется на электронную почту. На всякий случай, проверьте свои [настройки оповещений](%{base_url}/my/preferences), чтобы убедиться, что там всё как вам удобно.\n\n## Настройки\n\n - По умолчанию, темы будут считаться новыми, если они созданы **за последние два дня**.\n\n - Любая тема, в которой вы **активно участвовали** (отвечали, создали эту тему или просто читали её достаточно долгое время) будет автоматически отслеживаться на предмет новых сообщений.\n\nВы увидите синий индикатор \"новый\" и число новых сообщений рядом с отслеживаемыми темами.\n\n\n\nВы можете изменить настройки уведомлений и отслеживания отдельно для любой темы с помощью меню внизу этой темы:\n\n\n\nАналогичным образом можно настроить желаемый режим оповещений для разделов форума, чтобы получать оповещения о новых темах в этих разделах.\n\nОбщие для всех тем настройки отслеживания и классификация тем как \"новые\" задаются в [пользовательских настройках](%{base_url}/my/preferences).\n" welcome_user: subject_template: "Добро пожаловать на %{site_name}!" text_body_template: | @@ -1324,13 +1284,13 @@ ru: Пожалуйста, старайтесь придерживаться [этики и правил вежливости](%{base_url}/guidelines). - Приятного времяпровождения! + (Если у вас имеются вопросы, то их можно задать [персоналу](%{base_url}/about)) - (Если у вас имеются вопросы к [персоналу](%{base_url}/about), то можете задать их ответив на это личное сообщение.) + Приятного времяпровождения! welcome_invite: subject_template: "Добро пожаловать на %{site_name}!" text_body_template: | - Спасибо за то, что приняли приглашение присоединиться к сайту %{site_name}, и добро пожаловать на наш форум! + Спасибо, что приняли приглашение присоединиться к сайту %{site_name} и добро пожаловать! Мы автоматически дали вам имя пользователя: **%{username}**, но вы можете изменить его в любое время в [вашем профиле][prefs]. @@ -1399,22 +1359,12 @@ ru: csv_export_failed: subject_template: "Экспорт не удался" text_body_template: "Мы сожалеем, но возникли неполадки с экспортом ваших данных. Свяжитесь с администратором сайта." - email_reject_trust_level: - subject_template: "[%{site_name}] Неполадки с письмом - недостаточный уровень доверия" - text_body_template: | - К сожалению, ваше письмо к %{destination} (под названием %{former_title}) не может быть обработано. - - Уровень доверия вашей учетной записи недостаточен, чтобы создавать новые темы с помощью отправки писем на этот почтовый ящик. - - Если вы считаете, что произошла ошибка, свяжитесь с персоналом (модератором или администратором). + email_reject_inactive_user: + subject_template: "[%{site_name}] Неполадки с e-mail -- неактивный пользователь" + email_reject_blocked_user: + subject_template: "[%{site_name}] Неполадки с e-mail -- заблокированный пользователь" email_reject_no_account: subject_template: "[%{site_name}] Неполадки с письмом - не найдена учетная запись" - text_body_template: | - К сожалению, ваше письмо к %{destination} (под названием %{former_title}) не может быть обработано. - - Мы не смогли найти учетную запись с электронным адресом, с которого пришло ваше письмо. - - Попробуйте отправить с другого почтового ящика, или, если вы считаете, что произошла ошибка, свяжитесь с персоналом - модератором или администратором. email_reject_empty: subject_template: "[%{site_name}] Неполадки с письмом - отсутствует текст" email_reject_parsing: @@ -1433,41 +1383,10 @@ ru: Уровень доверия вашей учетной записи недостаточен, для создания тем в этой категории. Если вы считаете, что произошла ошибка, свяжитесь администратором сайта. - email_reject_post_error: - subject_template: "[%{site_name}] Неполадки с e-mail -- ошибка отправки" - text_body_template: |+ - К сожалению, ваше письмо к %{destination} (под названием %{former_title}) не может быть обработано. - - Возможные причины: слишком сложное форматирование, слишком длинное или слишком короткое сообщение. Попробуйте еще раз, или попробуйте через сайт, если ошибка будет повторятся. - - email_reject_post_error_specified: - subject_template: "[%{site_name}] Системное сообщение -- ошибка размещения поста" - text_body_template: | - К сожалению, Ваше сообщение, адресованное %{destination} (с заголовком %{former_title}) не может быть обработано. - - Причина: - - %{post_error} - - Если вы не можете исправить ошибку, попробуйте снова. email_reject_reply_key: subject_template: "[%{site_name}] Системное сообщение -- Неизвестный ключ для ответа" - text_body_template: | - К сожалению, ваше письмо к %{destination} (под названием %{former_title}) не может быть обработано. - - Ключ ответа неверный, поэтому мы не можем определить, кому адресован ваш ответ. Пожалуйста, свяжитесь с персоналом (модератором или администратором). - email_reject_destination: - subject_template: "[%{site_name}] Системное сообщенеие -- Неизвестный адресат Кому: Адресс" - text_body_template: | - К сожалению, Ваше сообщение, адресованное %{destination} (с заголовком %{former_title}) не может быть обработано. - - Мы не смогли найти адресата. Убедитесь что адресат указан в поле To: (а не в Cc: или Bcc:), и то что имейл указа верно. email_reject_topic_not_found: subject_template: "[%{site_name}] Системное сообщение -- Тема не найдена" - text_body_template: | - К сожалению, ваше письмо к %{destination} с заголовком %{former_title} не может быть обработано. - - Тема, в которую вы пишите, не существует. Возможно, она была удалена. Если вы считаете, что произошла ошибка при обработке письма, обратитесь к модератору или администратору. email_reject_topic_closed: subject_template: "[%{site_name}] Неполадки с письмом - Топик закрыт" text_body_template: | @@ -1476,18 +1395,8 @@ ru: Тема, в которую вы пишите, была закрыта, и поэтому новые сообщения не разрешены. Если вы считаете, что произошла ошибка при обработке письма, обратитесь к модератору или администратору. email_reject_auto_generated: subject_template: "[%{site_name}] системное сообщение - Автоматически сгенерирован ответ" - text_body_template: | - К сожалению, ваше письмо к %{destination} с заголовком %{former_title} не может быть обработано. - - Система обнаружила, что оно было сгенерировано автоматически, а такие письма не допустимы для автоматической отправки сообщений в форуме через электронную почту. - - Если вы считаете, что произошла ошибка при обработке письма, обратитесь к модератору или администратору. email_error_notification: subject_template: "[%{site_name}] Системное сообщение -- ошибка POP аутентификации" - text_body_template: | - При получении почты с почтового POP сервера, была обнаружена ошибка. - - Убедитесь в том что аутентификация для POP сервера настроена правильно в [the site settings](%{base_url}/admin/site_settings/category/email). too_many_spam_flags: subject_template: "Новый аккаунт заблокирован" text_body_template: | @@ -1500,32 +1409,10 @@ ru: За дополнительной информацией обратитесь к [инструкции пользователя](%{base_url}/guidelines). blocked_by_staff: subject_template: "Учетная запись заблокирована" - text_body_template: | - Здравствуйте! - - Это автоматическое сообщение с сайта %{site_name} для информирования вас о том, что ваша учетная запись заблокирована администратором или модератором. - - Получить дополнительную информацию вы можете в нашей [инструкции пользователя](%{base_url}/guidelines). user_automatically_blocked: subject_template: "Пользователь %{username} заблокирован участниками сообщества" - text_body_template: | - This is an automated message. - - The new user [%{username}](%{base_url}%{user_url}) was automatically blocked because multiple users flagged %{username}'s post(s). - - Please [review the flags](%{base_url}/admin/flags). If %{username} was incorrectly blocked from posting, click the unblock button on [the admin page for this user](%{base_url}%{user_url}). - - This threshold can be changed via the `block_new_user` site settings. spam_post_blocked: subject_template: "Сообщения нового пользователя %{username} заблокированы из-за повторяющихся ссылок" - text_body_template: | - Это автоматическое уведомление. - - Новый пользователь [%{username}](%{base_url}%{user_url}) пытается создать множество постов с ссылками на %{domains}, но система заблокировала эти посты как спам. Пользователь все еще может создавать посты не содержащие ссылки на %{domains}. - - Пожайлуйста [проверьте пользователя](%{base_url}%{user_url}). - - Решить данный вопрос можно также добавив домен в настройки `newuser_spam_host_threshold` и `white_listed_spam_host_domains` . unblocked: subject_template: "Учетная запись разблокирована" text_body_template: | @@ -1545,6 +1432,8 @@ ru: download_remote_images_disabled: subject_template: "Загрузка копий изображений выключена" text_body_template: "Настройка `download_remote_images_to_local` была отключена, т.к. диск заполнился до отменки, указанной в настройке `download_remote_images_threshold`." + unsubscribe_link: | + Отписаться от подобных писем можно в ваших [настройках профиля](%{user_preferences_url}). Чтобы больше не получать письма с оповещениями по этой конкретной теме, [нажмите здесь](%{unsubscribe_url}). subject_re: "Re:" subject_pm: "[PM]" user_notifications: @@ -1552,42 +1441,27 @@ ru: unsubscribe: title: "Отписаться" description: "Не заинтересованы в получении данных писем? Нет проблем! Нажмите на ссылку ниже, чтобы мгновенно отписаться от рассылки:" - reply_by_email: "Чтобы отреагировать на сообщение, ответьте на данное письмо или перейдите по ссылке %{base_url}%{url} в вашем браузере." - visit_link_to_respond: "Чтобы отреагировать на сообщение, перейдите по ссылке %{base_url}%{url} в вашем браузере." + reply_by_email: "[Посмотреть тему на сайте](%{base_url}%{url}), чтобы ответить. Или можно просто ответить на это письмо, и ваш ответ попадёт в эту тему на форуме." + visit_link_to_respond: "[Посмотреть тему на сайте](%{base_url}%{url}), чтобы ответить" posted_by: "Отправлено %{username} %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} приглашает вас к обсуждению сообщения '%{topic_title}'" - text_body_template: |2 - - %{username} написал Вам сообщение - - > **%{topic_title}** - > - > %{topic_excerpt} - - на сайте - - > %{site_title} -- %{site_description} - - Просмотреть сообщение вы можете по ссылке: %{base_url}%{url} - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} Приглашает вас к обсуждению темы: '%{topic_title}'" - text_body_template: |2 - - %{username} приглашает вас к обсуждению - - > **%{topic_title}** - > - > %{topic_excerpt} - - на сайте: - - > %{site_title} -- %{site_description} - - Просмотреть сообщение вы можете по ссылке: %{base_url}%{url} user_replied: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_replied_pm: + subject_template: "[%{site_name}] [ЛС] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1597,6 +1471,19 @@ ru: user_quoted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_linked: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1606,6 +1493,19 @@ ru: user_mentioned: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1615,6 +1515,8 @@ ru: user_posted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1624,10 +1526,20 @@ ru: user_posted_pm: subject_template: "[%{site_name}] [Личное сообщение] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} + --- + %{respond_instructions} + user_posted_pm_staged: + subject_template: "%{optional_re}%{topic_title}" + text_body_template: |2 + + %{message} + --- %{respond_instructions} digest: @@ -1676,12 +1588,16 @@ ru: Чтобы установить пароль, пройдите по следующей ссылке: %{base_url}/users/password-reset/%{email_token} - authorize_email: + confirm_new_email: subject_template: "[%{site_name}] Подтвердите новый адрес электронной почты" text_body_template: | Подтвердите ваш новый адрес электронной почты для сайта %{site_name}, перейдя по следующей ссылке: %{base_url}/users/authorize-email/%{email_token} + confirm_old_email: + subject_template: "[%{site_name}] Подтвердите текущий адрес электронной почты" + notify_old_email: + subject_template: "[%{site_name}] Ваш адрес электронной почты был подтвержден" signup_after_approval: subject_template: "Ваша учетная запись на сайте %{site_name} одобрена!" text_body_template: | @@ -1703,6 +1619,7 @@ ru: (Если вам требуется помощь [администрации](%{base_url}/about), вы можете задать свой вопрос, просто ответив на данное письмо.) signup: + subject_template: "[%{site_name}] Активируйте свою учетную запись" text_body_template: | Добро пожаловать на сайт %{site_name}! @@ -1711,7 +1628,7 @@ ru: Если данная ссылка не работает, попробуйте скопировать её и вставить в строку адреса вашего браузера. page_not_found: - title: "Запрашиваемая страница не существует или необщедоступна." + title: "Упс! Эта страница не существует или скрыта от публичного просмотра." popular_topics: "Популярные" recent_topics: "Недавние" see_more: "Еще" @@ -1770,23 +1687,6 @@ ru: title: "Пользовательское соглашение" privacy_topic: title: "Политика конфиденциальности" - badges: - long_descriptions: - autobiographer: | - Эта награда выдается за заполнение - своей страницы профиля и выбор картинки профиля. Возможность узнать больше о дуг друге позволяет форумчанам сплотиться в тесное сообщество. - nice_post: | - Эта награда выдается за сообщение, собравшее 10 симпатий. Отличная работа! - nice_topic: | - Эта награда выдается за тему, собравшую 10 симпатий. Отличная работа! - good_post: | - Эта награда выдается за сообщение, собравшее 25 симпатий. Превосходная работа! - good_topic: | - Эта награда выдается за тему, собравшую 25 симпатий. Превосходная работа! - great_post: | - Эта награда выдается за сообщение, собравшее 50 симпаний. Вау! - great_topic: | - Эта награда выдается за тему, собравшую 50 симпаний. Вау! admin_login: success: "письмо отправлено" error: "Ошибка!" @@ -1797,3 +1697,8 @@ ru: performance_report: initial_post_raw: Эта тема содержит ежедневные отчеты активности форума. initial_topic_title: Отчеты активности форума + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.sk.yml b/config/locales/server.sk.yml new file mode 100644 index 00000000000..4a6ad4d30e6 --- /dev/null +++ b/config/locales/server.sk.yml @@ -0,0 +1,1860 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +sk: + dates: + short_date_no_year: "MMM D" + short_date: "YYYY MMM D" + long_date: "YYYY MMM D h:mma" + datetime_formats: &datetime_formats + formats: + short: "%Y-%m-%d" + short_no_year: "%B %-d" + date_only: "%Y, %B %-d" + date: + month_names: [null, Január, Február, Marec, Apríl, Máj, Jún, Júl, August, September, Október, November, December] + <<: *datetime_formats + title: "DIscourse" + topics: "Témy" + posts: "príspevky" + loading: "Načítava sa" + powered_by_html: 'Systém beží na Discourse, najlepšie funguje so zapnutým JavaScriptom' + log_in: "Prihlásenie" + purge_reason: "Automaticky vymazaný ako opustený, neaktivovaný účet" + disable_remote_images_download_reason: "Sťahovanie vzdialených obrázkov je vypnuté kvôli nedostatku diskového priestoru." + anonymous: "Anonymný" + emails: + incoming: + default_subject: "Prijatý email od %{email}" + errors: + inactive_user_error: "Nastane, keď odosielateľ nie je aktívny." + blocked_user_error: "Nastane, keď odosielateľ bol zablokovaný." + errors: &errors + format: '%{attribute} %{message}' + messages: + too_long_validation: "je obmedzený na %{max} znakov, zadali ste %{length}." + invalid_boolean: "Neplatná logická hodnota." + taken: "je už použité" + accepted: sa musí akceptovať + blank: nesmie byť prázdne + present: musí byť prázdne + confirmation: "sa nerovná %{attribute}" + empty: nesmie byť prázdne + equal_to: sa musí rovnať %{count} + even: musí byť párne + exclusion: je rezervované + greater_than: musí byť viac ako %{count} + greater_than_or_equal_to: musí byť väčšie alebo rovné %{count} + has_already_been_used: "je už použité" + inclusion: nie je v zozname + invalid: je nesprávne + is_invalid: "je nesprávne; skúste opísať lepšie" + less_than: musí byť menej ako %{count} + less_than_or_equal_to: musí byť menej alebo rovné %{count} + not_a_number: nie je číslo + not_an_integer: musí byť číslo + odd: musí byť nepárne + record_invalid: 'Validácia zlyhala s chybami: %{errors}' + restrict_dependent_destroy: + one: "Nedá sa zmazať záznam pretože existuje %{record} závislých záznamov" + many: "Záznam nemôže byť zmazaný z dôvodu zavislosti na zázname: %{record} " + too_long: + one: príliš dlhé (maximálne 1 znak) + few: príliiš dlhé (maximum je %{count} znaky) + other: príliiš dlhé (maximum je %{count} znakov) + too_short: + one: príliiš krátke (minimum je 1 znak) + few: príliiš krátke (minimum je %{count} znaky) + other: príliiš krátke (minimum je %{count} znakov) + wrong_length: + one: nesprávna dĺžka (musí byť 1 znak) + few: nesprávna dĺžka (musí byť %{count} znaky) + other: nesprávna dĺžka (musí byť %{count} znakov) + other_than: "musí byť iný než %{count}" + template: + body: 'Nastal problém s nasledujúcimi položkami:' + header: + one: Uloženie %{model} zlyhalo kôli chybe + few: Uloženie %{model} zlyhalo kôli %{count} chybám + other: 'Uloženie %{model} zlyhalo kôli %{count} chybám ' + embed: + load_from_remote: "Nastala chyba pri načítaní príspevku" + site_settings: + min_username_length_exists: "Nemôžete nastaviť minimálnu dĺžku používateľského mena viac ako najkratšie používateľské meno." + min_username_length_range: "Nemôžete nastaviť minimum viac ako maximum." + max_username_length_exists: "Nemôžete nastaviť maximálnu dĺžku používateľského mena kratšiu ako najdlhšie používateľské meno." + max_username_length_range: "Nemôžete nastaviť maximum menšie ako minimum." + default_categories_already_selected: "Nemôžete vybrať kategóriu použitú v inom zozname." + s3_upload_bucket_is_required: "Nemôžete nahrávať na S3 pokiaľ ste nezadali 's3_upload_bucket'." + bulk_invite: + file_should_be_csv: "Nahrávaný súbor by mal byť vo formáte csv alebo txt." + backup: + operation_already_running: "Prebieha spracovanie inej operácie. Momentálne sa nová úloha nedá spustiť. " + backup_file_should_be_tar_gz: "Záložný súbor musí byť archív .tar.gz" + not_enough_space_on_disk: "Na disku nie je dosť miesta na uloženie zálohy" + not_logged_in: "K tejto akcii musíte byť prihlásený." + not_found: "Požadovaná URL alebo zdroj sa nenašiel" + invalid_access: "Nemáte oprávnenie na zobrazenie požadovaných údajov!" + read_only_mode_enabled: "Táto stránka je v móde na čítanie. Zapisovanie je vypnuté" + reading_time: "Doba čítania" + likes: "Páči sa mi" + too_many_replies: + one: "Lutujeme, noví užívatelia majú dočasne obmedzený počet príspevkov na jeden v rámci jednej témy." + few: "Lutujeme, noví užívatelia majú dočasne obmedzený počet príspevkov na %{count} v rámci jednej témy." + other: "Lutujeme, noví užívatelia majú dočasne obmedzený počet príspevkov na %{count} v rámci jednej témy." + embed: + start_discussion: "Začať diskusiu" + continue: "Pokračovať v diskusii" + more_replies: + one: "1 ďalšia odpoveď" + few: "%{count} ďalšie odpovede" + other: "%{count} ďalších odpovedí" + loading: "Nahrávanie Diskusie ..." + permalink: "Trvalý odkaz" + imported_from: "Toto je sprievodná diskusia k pôvodnej téme na %{link}" + in_reply_to: "▶ %{username}" + replies: + one: "1 odpoveď" + few: "%{count} odpovede" + other: "%{count} odpovedí" + no_mentions_allowed: "Ľutujeme, nesmiete menovať iných užívateľov" + too_many_mentions: + one: "Ľutujeme, v príspevku môžte menovat maximálne jedného užívateľa." + few: "Ľutujeme, v príspevku môžte menovat maximálne %{count} užívatelov." + other: "Ľutujeme, v príspevku môžte menovat maximálne %{count} užívatelov." + no_mentions_allowed_newuser: "Ľutujeme, noví užívatelia nesmú zmieňovať iných uživateľov" + too_many_mentions_newuser: + one: "Ľutujeme, noví užívatelia môžu menovat v príspevku maximálne jedného užívateľa." + few: "Ľutujeme, noví užívatelia môžu menovat v príspevku maximálne %{count} užívatelov." + other: "Ľutujeme, noví užívatelia môžu menovat v príspevku maximálne %{count} užívatelov." + no_images_allowed: "Ľutujeme, noví užívatelia nemôžu vkladať obrázky do príspevkov." + too_many_images: + one: "Ľutujeme, noví užívatelia môžu vložiť maximálne jeden obrázok do príspevku." + few: "Ľutujeme, noví užívatelia môžu vložiť maximálne %{count} obrázky do príspevku." + other: "Ľutujeme, noví užívatelia môžu vložiť maximálne %{count} obrázkov do príspevku." + no_attachments_allowed: "Ľutujeme, noví užívatelia nemôžu vkladať prílohy do príspevkov." + too_many_attachments: + one: "Ľutujeme, noví užívatelia môžu vložiť maximálne jednu prílohu do príspevku." + few: "Ľutujeme, noví užívatelia môžu vložiť maximálne %{count} prílohy do príspevku." + other: "Ľutujeme, noví užívatelia môžu vložiť maximálne %{count} príloh do príspevku." + no_links_allowed: "Ľutujeme, noví užívatelia nemôžu vkladať odkazy do príspevkov." + too_many_links: + one: "Ľutujeme, noví užívatelia môžu vložiť maximálne jeden odkaz do príspevku." + few: "Ľutujeme, noví užívatelia môžu vložiť maximálne %{count} odkazy do príspevku." + other: "Ľutujeme, noví užívatelia môžu vložiť maximálne %{count} odkazov do príspevku." + spamming_host: "Prepáčte, nemôžte publikovať odkazy na tento zdroj" + user_is_suspended: "Suspendovaní užívatelia nemôžu vkladať príspevky" + topic_not_found: "Niečo sa pokazilo. Téma mohla byť napríklad uzavretá, alebo zmazaná kým ste ju prezerali." + just_posted_that: "je to príliš podobné Vášmu predchádzajúcemu príspevku" + has_already_been_used: "je už použité" + invalid_characters: "obsahuje neplatné znaky" + is_invalid: "je nesprávne; skúste opísať lepšie" + next_page: "nasledujúca stránka →" + prev_page: "← predchádzajúca stránka" + page_num: "Stránka %{num}" + home_title: "Domov" + topics_in_category: " '%{category}' tém v tejto kategórii" + rss_posts_in_topic: "RSS čítačka na %{topic}'" + rss_topics_in_category: "RSS čítačka na tému v kategórii: '%{category}'" + author_wrote: "%{author} napísal:" + num_posts: "Príspevky:" + num_participants: "Prispievatelia:" + read_full_topic: "Čítať celý príspevok" + private_message_abbrev: "Správa" + rss_description: + latest: "Najnovšie témy" + hot: "Horúce témy" + posts: "Najnovšie príspevky" + too_late_to_edit: "Tento príspevok bol vytvorený príliš dávno. Už nemôže byť upravovaný či zmazaný" + excerpt_image: "Obrázok" + queue: + delete_reason: "Zmazané moderátorom" + groups: + errors: + can_not_modify_automatic: "Nemôžte upravovať automatickú skupinu" + member_already_exist: "'%{username}' už je členom tejto skupiny." + invalid_domain: "'%{domain}' nie je platnou doménou." + default_names: + everyone: "všetci" + admins: "administrátori" + moderators: "moderátori" + staff: "zamestnanci" + trust_level_0: "stupen_dovery_0" + trust_level_1: "stupen_dovery_1" + trust_level_2: "stupen_dovery_2" + trust_level_3: "stupen_dovery_3" + trust_level_4: "stupen_dovery_4" + education: + until_posts: + one: "jeden príspevok" + few: "%{count} príspevky" + other: "%{count} príspevkov" + new-topic: | + Víitajte na %{site_name} — **Ďakujeme za založenie novej konverzácie!** + + - Znie titulok zaujímavo ak ho čítate nahlas ? Zodpovedá obsahu ? + + - Koho by to mohlo zaujímať ? Prečo je to dôležité ? Akú reakciu očakávate ? + + - Vložte často používane slová vo vašej téme aby ju ostatní vedeli "nájsť". Pre zlúčenie vašej témy so súvisiacimi témami vyberte kategóriu . + + Pre viac informácií, [pozri návody](/guidelines). Tento panel sa zobrazí iba raz %{education_posts_text}. + new-reply: | + Vitajte na %{site_name} — **Ďakujeme za príspevok!** + + - Vylepší vaša odpoveď nejakým spôsobom diskusiu ? + + - Buďte ohľaduplní k ostatným členom komunity. + + - Konštruktívna kritika je vítana, avšak kritizujte "nápady", nie ľudí. + + Pre viac informácií, [pozri návody](/guidelines). Tento panel sa zobrazí iba raz %{education_posts_text}. + avatar: | + ### Čo tak pridať fotku k svojmu účtu? + + Už ste pridali zopár tém a odpovedi, ale Váš profil nie je taký jedinečný ako Vy -- Je to len písmeno. + + Zvážili ste **[pozrieť váš profil](%{profile_path})** a pridať obrázok , ktorý Vás vystihuje? + + Je jednoduchšie sledovať diskusie a nájsť zaujímave osoby v konverzácii pokiaľ ma každý z nich v profile jedinečný obrázok ! + sequential_replies: | + ### Zvážte možnosť odpovedať na viacero príspevkov naraz + + Namiesto množstva postupných odpovedí na tému prosím zvážte použitie jednej odpovede, ktorá bude obsahovať citácie z predchádzajúcich príspevkov, alebo odkazy na @meno + + Ak chcete dať časť svojho vloženého príspevku do úvodzoviek, stačí označiť text a stlačiť tlačidlo quote reply , ktoré sa následne objaví. + + Pre všetkých je jednoduchšie čítať témy, ktoré majú menšiu hĺbku vnorených odpovedi v porovnaní s množstvom malých individuálnych odpovedí. + dominating_topic: | + ### Umožnite ostatným nech sa zapoja do debaty + + Táto téma je pre Vás zjavne dôležitá – prispeli ste do nej viac než %{percent}% odpovedí. + + Ste si istí, že posktujete dostatok času aj ostatným aby prezentovali svoj názor ? + too_many_replies: | + ### Dosiahli ste limit počtu odpovedí na túto tému + + Ľutujeme, noví užívatelia môžu dočasne vložiť len %{newuser_max_replies_per_topic} odpovedí na jednu tému. + + Namiesto nového príspevku zvážte možnosť úpravy predchádzajúcich odpovedí, alebo skúste inú tému. + reviving_old_topic: | + ### Oživiť túto tému ? + + Posledná odpoveď k tejto téme je staršia ako %{days} dní. Vaša odpoveď posunie tému na vrchol tém a upozorní všetkých, ktorí sa zapojili do diskusie. + + Ste si istí, že chcete pokračovať v tejto starej diskusii? + activerecord: + attributes: + category: + name: "Názov kategórie" + post: + raw: "Telo" + user_profile: + bio_raw: "O mne" + errors: + models: + topic: + attributes: + base: + warning_requires_pm: "Výstraha môže byť pripojená len k súkromným spravam" + too_many_users: "Výstraha môže byť zaslaná len jednej osobe" + cant_send_pm: "Ľutujeme, nemôžte zaslať súkromnú správu tomuto užívateľovi" + no_user_selected: "Musíte zadať existujúceho užívateľa" + user: + attributes: + password: + common: "Toto je jedno z 10000 najbežnejších hesiel. Prosím použite bezpečnejšie heslo" + same_as_username: "je také isté ako vaše užívateľské meno. Prosím použite bezpečnejšie heslo" + same_as_email: "je také isté ako Váš email. Prosím použite bezpečnejšie heslo" + ip_address: + signup_not_allowed: "Registrácia z tohto účtu nie je povolená-" + color_scheme_color: + attributes: + hex: + invalid: "nesprávna farba" + <<: *errors + user_profile: + no_info_me: "
    Položka \"O mne\" vo Vašom profile je prázdna, želáte si ju doplníť?
    " + no_info_other: "
    %{name} nevložil zatiaľ nič do profilu \"O mne\"
    " + vip_category_name: "Salón" + vip_category_description: "Kategória výhradne pre členov s dôveryhodnosťou 3 a vyššou" + meta_category_name: "Podnety pre tvorcov stránky" + meta_category_description: "Diskusia o stránke, organizácii, ako funguje a ako ju môžme vylepšit" + staff_category_name: "Zamestnanci" + staff_category_description: "Súkromna kategória pre zamestnaneckú diskusiu. Témy su viditeľné len pre správcov a moderátorov diskusie" + assets_topic_body: "Toto je permanentná téma, viditeľná len pre redaktorov, na uchovávanie obrázkov a súborov použitých v dizajne tohto webu. Nezmazávajte ju!\n\n\nTu je návod:\n\n\n1. Odpovedzte na túto tému.\n2. Nahrajte sem všetky obrázky, ktoré si prajete použit pre logá, favikony a pod. (Použite ikonku „nahrať“ v paneli nástrojov editora, alebo obrázky potiahnite alebo „vložte“)\n3. Odošlite svoju odpoveď.\n4. Pre získanie adresy k nahratým obrázkom kliknite pravým tlačítkom na obrázky vo svojom novom príspevku, alebo kliknite na ikonku úpravy príspevku a následne si adresu skopírujte. \n5. Cesty k obrázkom vložte do [základného nastavenia](/admin/site_settings/category/required).\n\n\nAk potrebujete povoliť nahratie pre iné typy súborov, upravte `authorized_extensions` v [nastavení súborov](/admin/site_settings/category/files)." + lounge_welcome: + title: "Vítajte v Salóne" + body: |2 + + Gratulácia! :confetti_ball: + + Ak vidíte túto tému, boli ste nedávno povýšený na **pravidelný** (úroveň dôvery 3). + + Teraz môžete … + + * Upravovať nadpis akejkoľvek témy + * Meniť kategóriu akejkoľvek témy + * Mať sledované všetky Vaše odkazy ([automatické nofollow](http://en.wikipedia.org/wiki/Nofollow) je odstránené) + * Prístup do privátnej katogógie Lounge prístupnej iba členom s úrovňou dôvery 3 a vyššou + * Skryť spam pomocou vlajky + + Tu je [aktuálny zoznam pravidelných členov](/badges/3/regular). Určite ich pozdravte. + + Ďakujeme, že ste dôležitou súčasťou našej komunity! + + (Pre viac informácií o úrovniach dôvery, [pozrite túto tému][trust]. Prosím nezabudnite, že iba členovia, ktorý neustále spĺňajú požiadavky zostanú platnými členmy.) + + [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 + category: + topic_prefix: "O kategórii: %{category} " + replace_paragraph: "(Nahraďte tento prvý odstavec stručným popisom Vašej novej kategórie. Tento návod sa objaví v zozname kategórií, tak sa snažte ho udržať pod 200 znakov. **Kategória sa neobjaví v zozname kategórií pokým neupravíte tento popis alebo v nej nevytvoríte témy.**)" + post_template: "%{replace_paragraph}\n\nDo tohoto odstavce dajte dlhší popis kategórie, alebo popíšte pokyny alebo pravidlá:\n\n- Prečo by ľudia mali použiť túto kategóriu? Na čo je určená?\n\n- V čom sa líši od ostatných existujúcich kategórií ktoré už máte?\n\n- Čo by vo všeobecnosti mala obsahovať téma v tejto kategórií?\n\n- Potrebujeme túto kategóriu? Môžeme ju spojiť s inóu kategóriou alebo pod-kategóriou?\n" + errors: + uncategorized_parent: "Nekategorizovaná nemôže mať nadradenú kategóriu" + self_parent: "Podkategória si nemôže byť zároveň kategóriou " + depth: "Nemôžte umiestniť podkategóriu pod inú podkategóriu" + cannot_delete: + uncategorized: "Nemôžte vymazať nekategorizované" + has_subcategories: "Nemôžte vymazať kategóriu pretože obsahuje podkategórie" + topic_exists: + one: "Nemôžte vymazať kategóriu pretože obsahuje tému %{topic_link}." + few: "Nemôžte vymazať kategóriu pretože obsahuje %{count} témy. Najstaršia téma je %{topic_link}." + other: "Nemôžte vymazať kategóriu pretože obsahuje %{count} tém. Najstaršia téma je %{topic_link}." + topic_exists_no_oldest: "Nemôžte vymazať túto kategóriu pretože obsahuje %{count} tém." + uncategorized_description: "Témy, ktoré nepotrebujú kategóriu, alebo sa do žiadnej existujúcej nehodia." + trust_levels: + newuser: + title: "nový používateľ" + basic: + title: "základný používateľ" + member: + title: "člen" + regular: + title: "bežný" + leader: + title: "vodca" + change_failed_explanation: "Pokúsili ste sa znížiť úroveň %{user_name} na '%{new_trust_level}'. Ale jeho/jej aktuálna úroveň už je '%{current_trust_level}'. %{user_name} zostane na úrovni '%{current_trust_level}' - Ak chcete znížiť úroveň používateľa, najskôr uzamknite úroveň" + rate_limiter: + slow_down: "Vykonali ste túto akciu príliš veľa krát, skúste neskôr" + too_many_requests: "Na vykonávanie tejto akcie máme nastavený denný limit. Prosím počkajte %{time_left} než skúsite znovu." + by_type: + first_day_replies_per_day: "Dosiahli ste maximálny počet odpovedí stanovený pre nového používateľa v jeho prvý deň. Prosím čakajte %{time_left} , než skúsite znova" + first_day_topics_per_day: "Dosiahli ste maximálny počet tém stanovený pre nového používateľa v jeho prvý deň. Prosím čakajte %{time_left} , než skúsite znova" + create_topic: "Výtvárate témy príliš rýchlo. Prosím čakajte %{time_left} , než skúsite znova" + create_post: "Odpovedáte príliš rýchlo. Prosím čakajte %{time_left} , než skúsite znova" + topics_per_day: "Dosiahli ste maximálny počet nových tém na tento deň. Prosím čakajte %{time_left} , než skúsite znova" + pms_per_day: "Dosiahli ste maximálny počet správ na tento deň. Prosím čakajte %{time_left} , než skúsite znova" + create_like: "Dosiahli ste maximálny počet \"Páči sa\" na tento deň. Prosím čakajte %{time_left} , než skúsite znova" + create_bookmark: "Dosiahli ste maximálny počet záložiek na tento deň. Prosím čakajte %{time_left} , než skúsite znova" + edit_post: "Dosiahli ste maximálny počet úprav na tento deň. Prosím čakajte %{time_left} , než skúsite znova" + hours: + one: "1 hodina" + few: "%{count} hodiny" + other: "%{count} hodín" + minutes: + one: "1 minútu" + few: "%{count} minúty" + other: "%{count} minút" + seconds: + one: " 1 sekundu" + few: "%{count} sekundy" + other: "%{count} sekúnd" + datetime: + distance_in_words: + half_a_minute: "< 1m" + less_than_x_seconds: + one: "< 1s" + few: "< %{count}s" + other: "< %{count}s" + x_seconds: + one: "1s" + few: "%{count}s" + other: "%{count}s" + less_than_x_minutes: + one: "< 1m" + few: "< %{count}m" + other: "< %{count}m" + x_minutes: + one: "1m" + few: "%{count}m" + other: "%{count}m" + about_x_hours: + one: "1h" + few: "%{count}h" + other: "%{count}h" + x_days: + one: "1d" + few: "%{count}d" + other: "%{count}d" + about_x_months: + one: " 1mes" + few: "%{count}mes" + other: "%{count}mes" + x_months: + one: "1mes" + few: "%{count}mes" + other: "%{count}mes" + about_x_years: + one: "1r" + few: "%{count}r" + other: "%{count}r" + over_x_years: + one: "> 1r" + few: "> %{count}r" + other: "> %{count}r" + almost_x_years: + one: "1r" + few: "%{count}r" + other: "%{count}r" + distance_in_words_verbose: + half_a_minute: "práve teraz" + less_than_x_seconds: + one: "práve teraz" + few: "práve teraz" + other: "práve teraz" + x_seconds: + one: "pred sekundou" + few: "pred %{count} sekundami" + other: "pred %{count} sekundami" + less_than_x_minutes: + one: "menej ako pred minútou" + few: "menej ako pred %{count} minútami" + other: "menej ako pred %{count} minútami" + x_minutes: + one: "pred minútou" + few: "pred %{count} minútami" + other: "pred %{count} minútami" + about_x_hours: + one: "pred hodinou" + few: "pred %{count} hodinami" + other: "pred %{count} hodinami" + x_days: + one: "včera" + few: "pred %{count} dňami" + other: "pred %{count} dňami" + about_x_months: + one: "približne pred mesiacom" + few: "približne pred %{count} mesiacmi" + other: "približne pred %{count} mesiacmi" + x_months: + one: "pred mesiacom" + few: "pred %{count} mesiacmi" + other: "pred %{count} mesiacmi" + about_x_years: + one: "približne pred rokom" + few: "približne pred %{count} rokmi" + other: "približne pred %{count} rokmi" + over_x_years: + one: "pred vyše rokom" + few: "pred vyše %{count} rokmi" + other: "pred vyše %{count} rokmi" + almost_x_years: + one: "pred takmer rokom" + few: "pred takmer %{count} rokmi" + other: "pred takmer %{count} rokmi" + password_reset: + no_token: "Prepáčte, táto linka na zmenu hesla je už príliš stará. Stlačte tlačitlo Prihlásiť a použite \"Zabudol som heslo\" pre vytvorenie novej linky" + choose_new: "Prosim zadajte nové heslo" + choose: "Prosím zadajte heslo" + update: 'Aktualizujte heslo' + save: 'Nastavte heslo' + title: 'Obnoviť heslo' + success: "Heslo bolo úspešne zmenené a ste prihlasený do systému. " + success_unapproved: "Heslo bolo úspešne zmenené." + continue: "Pokračujte na %{site_name}" + change_email: + confirmed: "Vaša emailova adresa bola aktualizovaná" + please_continue: "Pokračujte na %{site_name}" + error: "Nastala chyba pri aktualizácii emailu. Nieje už náhodou použitý?" + activation: + action: "Pre aktiváciu účtu kliknite sem" + already_done: "Prepáčte, táto potvrdzovacia linka je už neplatná. Nie je už účet aktivny ?" + please_continue: "Váš nový účet je potvrdený. Budete presmerovaní na domovskú stránku." + continue_button: "Pokračujte na %{site_name}" + welcome_to: "Vitajte na %{site_name}!" + approval_required: "Moderátor musí manuálne povoliť Váš prístup na toto fórum. O schválení prístupu budete upovedomení emailom." + missing_session: "Nevieme zistiť či Váš účet bol vytvorený, prosím uistite sa že máte v prehliadači povolené cookies." + post_action_types: + off_topic: + title: 'Mimo témy' + description: 'Tento príspevok nesúvisí s danou témou popísanou v názve a prvom príspevku a pravdepodobne by mal byť presunutý niekam inam' + long_form: 'toto je označené ako "Mimo témy"' + spam: + title: 'Spam' + description: 'Tento príspevok je reklama. Nijako nesúvisí s danou témou, má propagačný charakter.' + long_form: 'označiť toto ako spam' + email_title: '"%{title}" bol označený ako spam' + email_body: "%{link}\n\n%{message}" + inappropriate: + title: 'Nevhodné' + description: 'Obsah tohto príspevku môže byť nektorými osobami považovaný za urážlivý, hanlivý, alebo porušujúci pravidlá slušného správania.' + long_form: 'toto označ ako nevhodné' + notify_user: + title: 'Poslať @{{username}} správu' + description: 'Chcem sa s touto osobou rozprávať o jeho príspevku priamo a súkromne.' + long_form: 'úživateľovi bola zaslaná správa' + email_title: 'Váš príspevok v "%{title}"' + email_body: "%{link}\n\n%{message}" + notify_moderators: + title: "Niečo iné" + description: 'Tento príspevok vyžaduje pozornosť obsluhy z iného dôvodu ako je uvedené vyššie.' + long_form: 'označené do pozornosti obsluhy' + email_title: 'Príspevok "%{title}" vyžaduje pozornosť obsluhy' + email_body: "%{link}\n\n%{message}" + bookmark: + title: 'Záložka' + description: 'Vytvor záložku na tento príspevok' + long_form: 'záložka na tento príspevok bola vytvorená ' + like: + title: 'Páči sa mi' + description: 'Páči sa mi tento príspevok' + long_form: 'páčilo sa' + vote: + title: 'Hlasovať' + description: 'Hlasovať pre tento príspevok' + long_form: 'hlasoval pre tento príspevok' + topic_flag_types: + spam: + title: 'Spam' + description: 'Tento príspevok je reklama. Nijako nesúvisí s danou stránkou, má propagačný charakter.' + long_form: 'označiť toto ako spam' + inappropriate: + title: 'Nevhodné' + description: 'Táto téma môže byť nektorými osobami považovaná za urážlivú, hanlivú, alebo porušujúcu pravidlá slušného správania.' + long_form: 'toto označ ako nevhodné' + notify_moderators: + title: "Niečo iné" + description: 'Táto téma vyžaduje pozornosť obsluhy na základe pravidiel, TOS, alebo z iného dôvodu ako je uvedené vyššie.' + long_form: 'označené do pozornosti moderátora' + email_title: 'Téma "%{title}" vyžaduje pozornosť moderátora' + email_body: "%{link}\n\n%{message}" + flagging: + you_must_edit: '

    Váš príspevok bol označený komunitou. Prosim pozrite si Vaše správy.

    ' + user_must_edit: '

    Tento príspevok bol označený komunitou a je dočasne skrytý

    ' + archetypes: + regular: + title: "Bežná téma" + banner: + title: "Banerová téma" + message: + make: "Téma je odteraz baner. Bude sa zobrazovať navrchu každej stránky, pokiaľ ju používateľ nezavrie." + remove: "Téma odteraz nie je baner. Už sa nebude viac zobrazovat navrchu každej stránky." + unsubscribed: + title: 'Odhlásiť' + description: "Boli ste odhlásený. Už vás znovu nebudeme kontaktovať." + oops: "V prípade že ste to tak nemysleli, kliknite nižšie" + error: "Chyba pri odhlasovaní" + preferences_link: "Zo súhrnných emailov sa môžete odhlásiť na stránke nastavení" + different_user_description: "Aktuálne ste prihlásený ako iný používateľ než ten, komu bol zaslaný súhrnný email. Prosíme odhláste sa a skúste znovu." + not_found_description: "Prepáčte, nedokázali sme Vás odhlásiť. Je možné, že platnosť odkazu vo Vašom emaile vypršala." + resubscribe: + action: "Znovu-prihlásiť" + title: "Znovu-prihlásený!" + description: "Boli ste znovu prihlásený." + reports: + visits: + title: "Používateľské návštevy" + xaxis: "Deň" + yaxis: "Počet návštev" + signups: + title: "Noví používatelia" + xaxis: "Deň" + yaxis: "Počet nových používateľov" + profile_views: + title: "Prezreté používateľské profily" + xaxis: "Deň" + yaxis: "Počet prezretých používateľských profilov" + topics: + title: "Témy" + xaxis: "Deň" + yaxis: "Počet nových tém" + posts: + title: "Príspevky" + xaxis: "Deň" + yaxis: "Počet nových príspevkov" + likes: + title: "Páči sa mi" + xaxis: "Deň" + yaxis: "Počet nových páči sa mi" + flags: + title: "Označenia" + xaxis: "Deň" + yaxis: "Počet označení" + bookmarks: + title: "Záložky" + xaxis: "Deň" + yaxis: "Počet nových záložiek" + starred: + title: "Obľúbené" + xaxis: "Deň" + yaxis: "Počet nových ohviezdičkovaných tém" + users_by_trust_level: + title: "Užívatelia podľa stupňa dôvery" + xaxis: "Stupeň dôvery" + yaxis: "Počet použivateľov" + emails: + title: "Emaily odoslané" + xaxis: "Deň" + yaxis: "Počet emailov" + user_to_user_private_messages: + title: "Užívateľ užívateľovi" + xaxis: "Deň" + yaxis: "Počet správ" + system_private_messages: + title: "Systém" + xaxis: "Deň" + yaxis: "Počet správ" + moderator_warning_private_messages: + title: "Upozornenie od moderátora" + xaxis: "Deň" + yaxis: "Počet správ" + notify_moderators_private_messages: + title: "Upozorniť moderátora" + xaxis: "Deň" + yaxis: "Počet správ" + notify_user_private_messages: + title: "Upozorniť užívateľa" + xaxis: "Deň" + yaxis: "Počet správ" + top_referrers: + title: "Najlepší referenti" + xaxis: "Používateľ" + num_clicks: "Klinutia" + num_topics: "Témy" + top_traffic_sources: + title: "Najlepšie zdroje" + xaxis: "Doména" + num_clicks: "Klinutia" + num_topics: "Témy" + num_users: "Používatelia" + top_referred_topics: + title: "Najlepšie témy" + xaxis: "Témy" + num_clicks: "Klinutia" + page_view_anon_reqs: + title: "Anonymný" + xaxis: "Deň" + yaxis: "Anonymné požiadavky API" + page_view_logged_in_reqs: + title: "Prihlásený" + xaxis: "Deň" + yaxis: "Zaznamenané API požiadavky" + page_view_crawler_reqs: + title: "Webové prehľadávače" + xaxis: "Deň" + yaxis: "API dotazy web robota" + page_view_total_reqs: + title: "Celkovo" + xaxis: "Deň" + yaxis: "Všetky API požiadavky" + page_view_logged_in_mobile_reqs: + title: "Zaznamenané API požiadavky" + xaxis: "Deň" + yaxis: "Zaznamenané API požiadavky cez mobil" + page_view_anon_mobile_reqs: + title: "Anonymné požiadavky API" + xaxis: "Deň" + yaxis: "Zaznamenané API požiadavky cez mobil" + http_background_reqs: + title: "Pozadie" + xaxis: "Deň" + yaxis: "Požiadavky použité na aktívne aktualizácie a sledovanie" + http_2xx_reqs: + title: "Status 2xx (OK)" + xaxis: "Deň" + yaxis: "Úspešné požiadavky (Status 2xx)" + http_3xx_reqs: + title: "HTTP 3xx (Presmerovanie)" + xaxis: "Deň" + yaxis: "Presmerované požiadavky (Status 3xx)" + http_4xx_reqs: + title: "HTTP 4xx (Chyba na strane klienta)" + xaxis: "Deň" + yaxis: "Chyby na strane klienta (Status 4xx)" + http_5xx_reqs: + title: "HTTP 5xx (Chyba na strane servera)" + xaxis: "Deň" + yaxis: "Chyby na strane servera (Status 5xx)" + http_total_reqs: + title: "Celkovo" + xaxis: "Deň" + yaxis: "celkový počet žiadostí" + time_to_first_response: + title: "Čas do prvej odpovede" + xaxis: "Deň" + yaxis: "Priemerný čas (hodiny)" + topics_with_no_response: + title: "Témy bez odozvy" + xaxis: "Deň" + yaxis: "Celkovo" + mobile_visits: + title: "Používateľské návštevy" + xaxis: "Deň" + yaxis: "Počet návštev" + dashboard: + rails_env_warning: "Váš server beží v %{env} móde" + ruby_version_warning: "Používate Ruby 2.0.0, ktorá má známe problémy. Aktualizujte prosím na záplatu 247, alebo novšiu." + host_names_warning: "Váš súbor config/database.yml používa lokálne meno hostiteľa. Aktualizujte ho menom Vašej stránky." + gc_warning: 'Váš server používa východzie nastavenia ruby garbage collectora, ktorý neposktytuje najlepší výkon. Prečítajte si tento príspevok ohľadom ladenia výkonu Ladenie Ruby and Rails pre Discourse.' + sidekiq_warning: 'Sidekiq neni spustený. Množstvo úloh, ako napríklad posielanie emailov, je vykonávaných asynchrónne prostrednictvom sidekiq. Prosim zabezpečte aby bol spustený aspoň jeden proces sidekiq Viac o Sidekiq.' + queue_size_warning: 'Počet úloh v zásobníku je %{queue_size}, čo je dosť veľa. To môže byť príznakom problému s procesom (procesmi) Sidekiq, alebo by ste mali spustiť viac Sidekiq procesov.' + memory_warning: 'Váš server beží s menej než 1 GB pamäte. Odporúča sa minimálne 1GB. ' + google_oauth2_config_warning: 'Server má nakonfigurovanú podporu registrácie a prihlásenia pomocou Google OAuth2 (enable_google_oauth2_logins), ale identifikačné údaje klienta a jeho tajné hodnoty nie sú nastavené. Navštívte Nastavenia stránky a aktualizujte nastavenia. Chcete vedieť viac? Pozrite si tento návod.' + facebook_config_warning: 'Server má nakonfigurovanú podporu registrácie a prihlásenia pomocou Facebooku (enable_facebook_logins), ale údaje "app Id" a tajné hodnoty nie sú nastavené. Navštívte Nastavenia stránky a aktualizujte nastavenia. Chcete vedieť viac? Pozrite si tento návod.' + twitter_config_warning: 'Server má nakonfigurovanú podporu registrácie a prihlásenia pomocou Twitteru (enable_twitter_logins), ale kľúč a tajné hodnoty nie sú nastavené. Navštívte Nastavenia stránky a aktualizujte nastavenia. Chcete vedieť viac? Pozrite si tento návod.' + github_config_warning: 'Server má nakonfigurovanú podporu registrácie a prihlásenia pomocou GitHub (enable_github_logins), ale identifikačné údaje klienta a jeho tajné hodnoty nie sú nastavené.. Navštívte Nastavenia stránky a aktualizujte nastavenia.Chcete vedieť viac? Pozrite si tento návod.' + s3_config_warning: 'Server má nakonfigurované nahrávanie súborov na S3, ale minimálne jedna z nasledujúcich hodnôt nie je nastavená: s3_access_key_id, s3_secret_access_key, alebo s3_upload_bucket. Navštívte Nastavenia stránky a aktualizujte nastavenia. Chcete vedieť viac? Pozrite si návod ako nastaviť nahrávanie súborov na S3.' + s3_backup_config_warning: 'Server má nakonfigurované nahrávanie záloh na S3, ale minimálne jedna z nasledujúcich hodnôt nie je nastavená: s3_access_key_id, s3_secret_access_key, alebo s3_backup_bucket. Navštívte Nastavenia stránky a aktualizujte nastavenia. Chcete vedieť viac? Pozrite si návod ako nastaviť nahrávanie súborov na S3.' + image_magick_warning: 'Server je nakonfigurovaný na vytváranie náhľadov z veľkých obrázkov, ale ImageMagick nie je nainštalovaný. Nainštalujte ImageMagick pomocou Vášho správcu balíčkov, alebo Stiahnite najnovšiu verziu.' + failing_emails_warning: 'Existuje %{num_failed_jobs} neuspešných emailých pokusov. Skontrolujte Váš app.yml a uistite sa, že nastavenia email serveru máte správne. Pozrieť neúspešné pokusy v Sidekiq.' + default_logo_warning: "Nastavte grafické logo Vašej stránky. Aktualizujte logo_url, logo_small_url, a favicon_url na Ňastaveniach stránky." + contact_email_missing: "Vložte kontaktnú email adresu aby ste mohli byť kontaktovaný v urgentných prípadov týkajúcich sa stránok. Vložte na Stránke nastavení." + contact_email_invalid: "Kontaktný email na stránke je neplatný. Aktualizujte ho v Nastavenia stránky." + title_nag: "Zadajte meno stránky. Aktualizujte ho v Nastavenia stránky." + site_description_missing: "Vložte jednovetný popis Vašej stránky, ktorý sa zobrazí vo výsledkoch vyhľadávania. Aktualizujte ho v Nastavenia stránky." + consumer_email_warning: "Vaše stránky sú nastavené tak aby na posielanie emailov používali Gmail (alebo iné služby pre spotrebiteľov). Gmail obmedzuje počet odoslaných emailov. Na zaistenie doručiteľonosti emailov zvážte použitie emailového poskytovateľa ako napríklad mandrill.com." + site_contact_username_warning: "Vložte názov účtu kolegu z personálu pre zasielanie dôležitých automatických správ. Aktualizujte kontakt v Nastavenia stránky." + notification_email_warning: "Notifikačné emaily sú posielané z neplatnej emailovej adresy vo Vašej doméne. Doručovanie emailov môže byť chybné a nespoľahlivé. Prosím nastavte platnú lokálnu emailovú adresu \"notification_email\" v Nastavenia stránky." + subfolder_ends_in_slash: "Vaše nastavenie podadresára je chybné, DISCOURSE_RELATIVE_URL_ROOT je ukončené lomítkom." + site_settings: + censored_words: "Slová, ktoré budu automatický nahradené znakmi ■■■■" + delete_old_hidden_posts: "Automatické zmazanie príspevkov, ktoré ostali skryté viac ako 30 dní" + default_locale: "Predvolený jazyk tejto inštancie Discourse je (ISO 639-1 Code)" + allow_user_locale: "Povoliť užívateľom zvoliť si vlastný jazyk" + min_post_length: "Minimálny povolený počet znakov v príspevkoch" + min_first_post_length: "Minimálny povolený počet znakov pre prvý príspevok (obsah témy)" + min_private_message_post_length: "Minimálny povolený počet znakov v správe" + max_post_length: "Maximálny povolený počet znakov v príspevkoch" + min_topic_title_length: "Minimálny povolený počet znakov v názve témy" + max_topic_title_length: "Maximálny povolený počet znakov v názve témy" + min_private_message_title_length: "Minimálny povolený počet znakov v správe" + min_search_term_length: "Minimálny povolený počet znakov vo vyhľadávaní" + search_tokenize_chinese_japanese_korean: "Prinúť vyhľádávanie rozložiť Čínštinu/Japončinu/Kórejčinu dokonca i pre nie CJK stránky" + allow_uncategorized_topics: "Pvoliť vytváranie tém bez kategórií. UPOZORNENIE: Pokiaľ existujú nekategorizované témy, musíte ich zaradiť do kategórii skôr než túto možnosť vypnete." + allow_duplicate_topic_titles: "Povoliť témy s rovnakými, duplikovanými názvami" + unique_posts_mins: "Koľko minút musí byť medzi dvomi rovnakými príspevkami od jedného užívateľa." + educate_until_posts: "Ked užívateľ začne písať svojich prvých (n) príspevkov, zobraz sprievodcu vzdelávania pre nového užívateľa. " + title: "Meno stránok, tak ako je použité v značke title." + site_description: "Popíšte stránky v jednej vete, tak ako sa popisujú v tagu meta." + contact_email: "Emailová adresa kľúčovej kontaktnej osoby zodpovednej za túto stránku. Používa sa pri kritických situáciach, ako napríklad neošetrené návestia a tiež pri kontaktnom formulári pre dôležité prípady." + contact_url: "Kontaktná URL adresa pre túto stránku. Použitá tiež pri kontaktnom formulári pre dôležité prípady." + queue_jobs: "IBA VÝVOJÁRI VAROVANIE! Štandardne, požiadavky fronty v sidekiq. Ak je vypnuté, vaše stránky budú rozbité." + crawl_images: "Načítať obrázky z URL pre vloženie správnej výšky a šírky." + download_remote_images_to_local: "Stiahnuť obrázky zo vzdialených zdrojov na lokálne. Zabráni poškodeniu obrázkov. " + download_remote_images_threshold: "Minimálne miesto na lokálnom disku potrebné na stiahnutie obrázkov zo vzdialených zdrojov (v percentách)" + disabled_image_download_domains: "Nikdy nesťahovať obrázky z týchto domén. Zoznam oddeleny pipou \"|\"." + editing_grace_period: "Nevytvárať nové verzie editovaných príspevkov do (n) sekúnd po odoslaní príspevku." + post_edit_time_limit: "Autor môže upravovať alebo mazať svoje príspevky do (n) minút po ich odoslaní. Nastavte 0 pre nekonečno" + edit_history_visible_to_public: "Povoliť všetkým zobrazenie predchádzajúcich verzií upraveného príspevku. Pokiaľ je to vypnuté, verzie vidí iba obslužný personál" + delete_removed_posts_after: "Príspevky zmazané autorom budú automaticky zmazané po (n) hodinách. Pokiaľ je nastavená 0, príspevky budú zmazané okamžite." + max_image_width: "Maximálna šírka náhľadu obrázkov v príspevku" + max_image_height: "Maximálna výška náhľadu obrázkov v príspevku" + category_featured_topics: "Počet zobrazených tém na jednu kategóriu na stránke /katgórie. Zmena hodnoty sa na stránkach prejaví do 15 minút." + show_subcategory_list: "Zobraz zoznam podkategórií namiesto zoznamu tém po vstupe do menu kategórií" + fixed_category_positions: "Ak je to označené, budete môcť zoraďovať kategórie v pevnom poradí. Ak je neoznačené, kategórie budu zoradené podlľa aktivity." + fixed_category_positions_on_create: "Ak je označené, triedenie kategórií bude spravované v dialógu na vytváranie témy (vyžaduje fixed_category_positions)." + add_rel_nofollow_to_user_content: "Pridať rel nofollow ku všetkému zaslanému používateľskému kontextu s výnimkou interných odkazov (zahrňuje rodičovskú doménu). Ak to zmeníte, musíte vykonať prípaz rebake na všetky príspevky pomocou: \"rake posts:rebake\"" + exclude_rel_nofollow_domains: "Zoznam domén, na ktorých odkazy nebude pridávaný nofollow . tld.com automaticky umožní sub.tld.com. Aby ste umožnili internetovým vyhľadávačom nájsť kompletný obsah mali by ste pridať minimálne doménu najvyššej úrovne týchto stránok. Ak je nejaká časť stránok na iných doménach, pridajte ich tiež." + post_excerpt_maxlength: "Maximálna dĺžka príspevku okrem zhrnutia." + post_onebox_maxlength: "Maximálna dĺžka vloženého Discourse príspevku v znakoch." + onebox_domains_whitelist: "Zoznam domén, pre ktoré je umožnené vkladanie. Tieto domény by mali podporovať OpenGraph alebo oEmbed. Overte ich pomocou http://iframely.com/debug" + logo_url: "Obrázok loga na ľavej hornej časti stránky, mal by byť tvaru širokého obdĺžnika. Ak nebude uvedený, zobrazí sa nadpis stránok." + digest_logo_url: "Obrázok loga na začiatku sumarizačného emailu stránok. Mal by byť tvaru širokého obdĺžnika. Ak nebude uvedený, použije sa logo_url." + logo_small_url: "Malý obrázok loga na ľavej hornej strane stránok, mal by mať tvar štvorca a bude zobrazený pri skrolovaní nadol. Ak nebude uvedený, zobrazí sa piktogram domu." + favicon_url: "Favicon pre Vaše stránky, pozrite http://en.wikipedia.org/wiki/Favicon. Aby fungoval správne s CDN, musí byť vo formáte png" + mobile_logo_url: "Obrázok loga zobrazený na fixnej pozícií v ľavom hornom rohu mobilnej verzie. Mal byť mať tvar štvorca. Ak nie je uvedené, použije sa `logo_url`. Napríklad: http://example.com/uploads/default/logo.png" + apple_touch_icon_url: "Ikona použitá na zariadeniach Apple touch. Doporučovaná veľkosť je 144px na 144px." + notification_email: "Odosieľateľ: email adresa použitá na zasielanie všetkých systémových emailov. Uvedená doména musí mať správne nastavené záznamy SPF, DKIM a opačný PTR aby email dorazil." + email_custom_headers: "Zoznam voliteľných emailových hlavičiek oddelených |" + email_subject: "Voliteľný formát predmetu emailu pre štandardné emaily. Pozrite https://meta.discourse.org/t/customize-subject-format-for-standard-emails/20801" + use_https: "Má byť url stránok (Discourse.base_url) http alebo https? NEZAPÍNAJTE MOŽNOSŤ AK HTTPS NIE JE NASTAVENÉ A FUNKČNÉ!" + summary_score_threshold: "Minimálne požadované skóre príspevku na to aby bol zahrnutý do 'Sumarizuj túto tému'" + summary_posts_required: "Minimálny počet príspevkou predtým ako je zapnuté 'Sumarizuj túto tému'" + summary_likes_required: "Minimálny počet páči sa mi predtým ako je zapnuté 'Sumarizuj túto tému'" + summary_percent_filter: "Ak používateľ klikne na 'Sumarizuj túto tému', zobraz najlepších % príspevkov" + summary_max_results: "Maximálny počet príspevkov vrátených pomocou 'Sumarizuj túto tému'" + enable_private_messages: "Umožni používateľom s úrovňou dôvery 1 (nastaviteľné pomocou min úroveň dôvery na posielanie správ) vytvárať správy a odpovedať na ne" + enable_long_polling: "Zbernica správ pre upozornenia môže používať techniku long-polling" + long_polling_base_url: "Base URL used for long polling (when a CDN is serving dynamic content, be sure to set this to origin pull) eg: http://origin.site.com" + long_polling_interval: "Ako dlho má server čakať pred odpovedaním klientom ak nie sú na zaslanie žiadne dáta (iba pre prihlásených používateľov)" + polling_interval: "Ak sa nepoužíva technika long-polling, ako často majú byť klienti dotazovaný v milisekundách" + anon_polling_interval: "Ako často majú byť dotazovaný anonymný klienti v milisekundách" + background_polling_interval: "Ako často majú byť dotazovaný klienti v milisekundách (ak je okno v pozadí)" + flags_required_to_hide_post: "Počet značiek ktoré automaticky príspevok skryjú a používateľovi bude zaslaná správa (0 pre nikdy)" + cooldown_minutes_after_hiding_posts: "Počet minút koľko musí používateľ počkať pred tým než môže upraviť príspevok skytý pomocou komunitných značiek" + max_topics_in_first_day: "Maximálny počet tém, ktoré používateľ môže vytvoriť v jeho prvý deň ." + max_replies_in_first_day: "Maximálny povolený počet odpovedí, ktoré môže používateľa vytvoriť v jeho prvý deň." + tl2_additional_likes_per_day_multiplier: "Zvýšiť počet páči sa mi na deň pre úroveň dôvery 2 (člen) vynásobením týmto číslom" + tl3_additional_likes_per_day_multiplier: "Zvýšiť počet páči sa mi na deň pre úroveň dôvery 3 (bežný) vynásobením týmto číslom" + tl4_additional_likes_per_day_multiplier: "Zvýšiť počet páči sa mi na deň pre úroveň dôvery 4 (vedúci) vynásobením týmto číslom" + num_flags_to_block_new_user: "Ak príspevky nového používateľa dostanú takéto množstvo spamových vlajok od num_users_to_block_new_user rôznych používateľov, skry všetky jeho príspevky a zabráň vytváraniu príspevkov v budúcnosti. 0 na vypnutie." + num_users_to_block_new_user: "Ak príspevky nového používateľa dostanú num_flags_to_block_new_user spamových vlajok od takéhoto množstva rôznych používateľov, skry všetky jeho príspevky a zabráň vytváraniu príspevkov v budúcnosti. 0 na vypnutie." + notify_mods_when_user_blocked: "Ak je používateľ automaticky zablokovaný, pošli správu všetkým moderátorom." + flag_sockpuppets: "Ak nový používateľ odpovedá na tému z rovnakej IP adresy, ako nový používateľ, ktorý danú tému vytvoril, označ oba ich príspevky ako potencionálny spam." + traditional_markdown_linebreaks: "V Markdown použiť tradičné oddeľovače riadkov, čo vyžaduje dve koncové medzery ako oddeľovač riadku." + allow_html_tables: "V Markdown umožniť použitie tabuliek pomocou HTML značiek. TABLE, THEAD, TD, TR, TH budú umožnené (vyžaduje \"full rebake\" na všetkých starých príspevkoch ktoré obsahujú tabuľky)" + post_undo_action_window_mins: "Počet minút počas ktorých môžu užívatelia zrušiť poslednú akciu na príspevku (\"Páči sa\", označenie, atď..)." + must_approve_users: "Obsluha musí povoliť účty všetkým novým užívateľom skôr než im bude povolený prístup na stránku. UPOZORNENIE: zapnutie na živej stránke spôsobí zrušenie prístupu pre existujúcich používateľov, okrem obsluhy!" + pending_users_reminder_delay: "Upozorni moderátora ak nový užívateľ čaká na schválenie dlhšie ako tento počet hodín. Nastavte -1 pre vypnutie upozornenia." + ga_tracking_code: "Google analytics (ga.js) sledovaní kód, napr: UA-12345678-9; pozri http://google.com/analytics" + ga_domain_name: "Google analytics (ga.js) názov domény, napr: mysite.com; pozri http://google.com/analytics" + ga_universal_tracking_code: "Google Universal Analytics (analytics.js) sledovaní kód, napr: UA-12345678-9; pozri http://google.com/analytics" + ga_universal_domain_name: "Google Universal Analytics (analytics.js) názov domény, napr: mysite.com; pozri http://google.com/analytics" + enable_escaped_fragments: "Ak nie je zistený vyhľadávač, použi Google's Ajax-Crawling API. Viac na https://support.google.com/webmasters/answer/174992?hl=en" + enable_noscript_support: "Zapnúť štandardnú podporu prehľadávačov pomocou značky noscript" + allow_moderators_to_create_categories: "Povoliť moderátorom vytváranie nových kategórií" + cors_origins: "Povoľ prameňom/origins použitie cross-origin dotazov (CORS). Každý prameň/origin musí obsahovať http:// alebo https://. Aby ste umožnili CORS, systémové premenná DISCOURSE_ENABLE_CORS musí byť nastavená na true." + use_admin_ip_whitelist: "Správcovia sa môťu prihlásiť iba pokiaľ pristupujú z adresy uvedenej v zozname kontrolovaných IP adries (Admin > Logs > Screened Ips)" + top_menu: "Určuje, ktoré položky sa zobrazia na navigácií na domovskej stránke a v akom poradí. Napríklad posledné|neprečítané|kategórie|naj|prečítané|záložky" + post_menu: "Určuje, ktoré položky sa objavia v menu príspevku a v akom poradí. Napríklad páči sa mi|upraviť|označiť|vymazať|zdieľať|záložka|odpovedať" + post_menu_hidden_items: "Položky vo východzích nastaveniach menu schované pri príspevkovom menu, dokiaľ neni kliknuté na rozbaľovaciu elipsu." + share_links: "Uveďte, ktoré položky sa maju zobraziť v zdieľacom dialógu a v akom poradí." + track_external_right_clicks: "Sledovať externé odkazy na ktore sa klkne pravým tlačidlom (npar. otvorenie v novej záložke) Vypnuté vo východzích nastaveniach, pretože to prepisuje URL adresy" + site_contact_username: "Platné uťívateľské meno obsluhy, ktorá bude posielať automatizované správy. Pokiaľ je vynechané, použije sa východzí systémový účet. " + send_welcome_message: "Poslač všetkým novým užívateľom uvítaciu správu s príručkou ako začať. " + suppress_reply_directly_below: "Nezobrazovať rozbaľovacie tlačidlo s počtom odpovedí ak je k príspevku len jedna odpoveď priamo pod ním." + suppress_reply_directly_above: "Nezobrazovať rozbaľovacie tlačidlo v-odpovedi-na ak je len jedna odpoveď priamo nad príspevkom." + suppress_reply_when_quoting: "Nezobrazovať rozbaľovacie tlačidlo v-odpovedi-na ak príspevok cituje odpoveď." + max_reply_history: "Maximálny počet odpovedí ktoré sa zobrazia po rozbalení v-odpovedi-na" + topics_per_period_in_top_summary: "Zobrazovaný počet najlepších tém vo východzom zozname najlepších tém." + topics_per_period_in_top_page: "Zobrazovaný počet najlepších tém vzozname po rozbalení 'Ukáž viac' najlepších tém." + redirect_users_to_top_page: "Automaticky presmeruj nových a dlho neprihlásených užívateľov na hlavnú stránku. " + top_page_default_timeframe: "Východzí interval pre presmerovanie na hlavnú stránku." + show_email_on_profile: "Zobraziť užívateľov email na ich profile (viditeľné len nimi samotnými a obsluhou)" + email_token_valid_hours: "Platnosť tokenov pre Zabudnuté heslo a aktiváciu účtu v (n) hodinách." + email_token_grace_period_hours: "Platnosť tokenov pre Zabudnuté heslo a aktiváciu účtu v (n) hodinách po ich uplatnení." + enable_badges: "Povoliť systém odznakov" + enable_whispers: "Povoliť súkromnú konverzáciu pre redakciu vrámci témy. (experimantálne)" + allow_index_in_robots_txt: "V súbore robots.txt nastaviť, že tieto stránky je povolené indexovať vyhľadávačmi." + email_domains_blacklist: "Rúrou oddelený zoznam emailových domén, ktorých použitie nie je povolené pri registrácií. Napríklad: mailinator.com|trashmail.net" + email_domains_whitelist: "Rúrou oddelený zoznam emailových domén, s použitím ktorých sa používateľ MUSÍ zaregistrovať. VAROVANIE: registrácia použivatelia s neuvedenými doménami nebude povolená!" + forgot_password_strict: "Neinformovať užívateľov o existencii účtu ked použíjú dialóg pre zabudnuté heslo." + log_out_strict: "Pri odhlasovaní odhlásiť VŠETKY sessiony používateľa, na všetkých zariadeniach." + version_checks: "Zisťovať aktualizácie na Discourse Hub a zobrazovať správy o novej verzii na stránke admina" + new_version_emails: "Poslať email na kontaktnú emailovú adresu ak je zistená nová verzia Discourse." + port: "POZOR! LEN PRE VÝVOJÁROV! Použiť tento HTTP port namiesto predvoleného portu 80. Nechajte prázdne pre port 80." + force_hostname: "POZOR! LEN PRE VÝVOJÁROV! V URL zadajte hostname. Ak chcete použiť predvolené, nechajte políčko prázdne." + invite_expiry_days: "Ako dlho je platná pozvánka pre používateľa, v dňoch" + invite_passthrough_hours: "Ako dlho môže užívateľ používať získaný pozývací kľúč na prihlasovanie, v hodinách" + invite_only: "Verejná registrácia je vypnutá, všetci noví užívatelia musia byť explicitne pozvaní ostatnými členmi alebo obsluhou." + login_required: "Požadovať prihlásenie pre čítanie obshau tejto stránky, zakáž anonymný prístup. " + min_username_length: "Minimálna dĺžka používateľského mena v znakoch." + max_username_length: "Maximálna dĺžka používateľského mena v znakoch." + reserved_usernames: "Používateľské mená, ktorých registrácia nie je povolená." + min_password_length: "Minimálna dĺžka hesla." + min_admin_password_length: "Minimálna dĺžka hesla pre Administrátora." + block_common_passwords: "Nepovoliť heslá, ktoré sú v zozname 10 000 najbežnejších hesiel." + enable_sso: "Povolit prihlasovanie pomocou externej stránky (VAROVANIE: POUŽÍVATEĽSKÉ EAMILOVÉ ADRESY *MUSIA* BYŤ OVERENÉ EXTERNOU STRÁNKOU)" + enable_sso_provider: "Implementácia protokolu Discourse SSO poskytovateľa na koncovom bode /session/sso_provider, vyžaduje nastavenie sso_secret" + sso_url: "URL pre single sign on." + sso_secret: "Tajný text, použitý na kryptografické overenie SSO informácie, uistite sa, že má 10 alebo viac znakov" + sso_overrides_email: "Nahrádzať lokálne emaily pomocou emailov z externej stránky pomocou dát z SSO dotazu pri každom logine a zamedziť lokálnym zmenám. (VAROVANIE: z dôvodu normálizácie lokálnych emailov sa môžu objaviť nezrovnalosti)" + sso_overrides_username: "Nahrádzať lokálne použivateľské mená pomocou použivateľských mien z externej stránky pomocou dát z SSO dotazu pri každom logine a zamedziť lokálnym zmenám. (VAROVANIE: z dôvodu rozdielov v požiadavkách na používateľské meno a jeho dĺžku sa môžu objaviť nezrovnalosti)" + sso_overrides_name: "Nahrádzať lokálne plné mená pomocou plných mien z externej stránky pomocou dát z SSO dotazu pri každom logine a zamedziť lokálnym zmenám." + sso_overrides_avatar: "Nahrádzať používateľský avatar pomocou avatara z externej stránky pomocou dát z SSO dotazu. V prípade zapnutia veľmi doporučujeme vypnúť allow_uploaded_avatars" + sso_not_approved_url: "Presmeruj nepovolené SSO účty na URL" + enable_local_logins: "Povoliť pouťívanie lokálnych účtov a hesiel. (Poznámka: musí to byť zapnuté pre fungovanie pozvánok)" + allow_new_registrations: "Povoliť registráciu nových užívateľov. Odznačte to ak chcete zabrániť vytváraniu nových účtov. " + enable_signup_cta: "Zobraz oznámenie pre navrátilých anonymných užívateľov s výzvou na registráciu účtu. " + enable_yahoo_logins: "Povoliť autentifikáciu pomocou Yahoo." + enable_google_oauth2_logins: "Povoliť Google Oauth2 autentifikáciu. Táto métoda je podporovaná Googlom. Vyžaduje kľúč a šifru." + google_oauth2_client_id: "Client ID Vašej Google aplikácie." + google_oauth2_client_secret: "Client secret Vašej Google aplikácie." + enable_twitter_logins: "Povoliť autentifikáciu cez Twitter, vyžaduje twitter_consmer_key a twiiter_consumer_secret" + twitter_consumer_key: "Consumer key pre Twitter autentifikáciu, registrovaný na http://dev.twitter.com" + twitter_consumer_secret: "Consumer secret pre Twitter autentifikáciu, registrované na http://dev.twitter.com" + enable_facebook_logins: "Povoliť autentifikáciu pomocou Facebook, vyžaduje facebook_app_id a facebook_app_secret." + facebook_app_id: "App id pre Facebook autentifikáciu, registrované na https://developers.facebook.com/apps" + facebook_app_secret: "App secret pre Facebook autentifikáciu, registrované na https://developers.facebook.com/apps" + enable_github_logins: "Povoliť autentifikáciu cez Github, vyžaduje github_client_id a github_client_secret" + github_client_id: "Client id pre Github autentifikáciu, registrované na https://github.com/settings/applications" + github_client_secret: "Client secret pre Github autentifikáciu, registrované na https://github.com/settings/applications" + allow_restore: "Umožniť obnovu, ktorá nahradí VŠETKY data na stránkach! Ponechajte prázdne okrem prípadu ak chcete obnoviť zo zálohy." + maximum_backups: "Maximálny počet záloh udržiavaných na disku. Staršie zálohy budu automaticky vymazané" + automatic_backups_enabled: "Spustiť automatické zálohy podľa nastavenia intervalu záloh" + backup_frequency: "Ako často máme vytvárať zálohu stránok, v dňoch." + enable_s3_backups: "Po dokončení nahrať zálohy na S3. DÔLEŽITÉ: požaduje správne nastavenie prístupových údajov na S3 v menu Súbory." + s3_backup_bucket: "Vzdialený S3 bucket na uloženie záloh. VAROVANIE: Uistite sa, že ide o súkromný S3 bucket." + backup_time_of_day: "Čas v UTC, kedy sa má spustiť záloha." + backup_with_uploads: "Do pravidelných záloh ulož i nahrané súbory. Pri vypnutej voľbe sa uloží iba záloha databázy." + active_user_rate_limit_secs: "Ako často máme aktualizovať pole 'naposledy videný o', v sekundách" + verbose_localization: "Zobraziť rozšírené lokalizačné tipy v rozhraní" + previous_visit_timeout_hours: "Ako dlho trvá návšteva predtým, ako ju pokladáme za 'predchádzajúcu' návštevu, v hodinách" + top_topics_formula_log_views_multiplier: "hodnota násobku (n) pre počet zobrazení v najznámejších témach: `log(views_count) * (n) + op_likes_count * 0.5 + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_first_post_likes_multiplier: "hodnota násobku (n) pre počet páči sa mi na prvom príspevku v najznámejších témach: `log(views_count) * 2 + op_likes_count * (n) + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_least_likes_per_post_multiplier: "hodnota násobku (n) pre najmenej páči sa mi pre prísprvok v najznámejších témach: `log(views_count) * 2 + op_likes_count * 0.5 + LEAST(likes_count / posts_count, (n)) + 10 + log(posts_count)`" + rate_limit_create_topic: "Po vytvorení témy musí používateľ počkať (n) sekúnd pred vytvorením ďalšej témy." + rate_limit_create_post: "Po odoslaní prísprevku používateľ počkať (n) sekúnd pred vytvorením ďalšieho príspevku." + rate_limit_new_user_create_topic: "Po vytvorení témy musí používateľ počkať (n) sekúnd pred vytvorením ďalšej témy." + rate_limit_new_user_create_post: "Po odoslaní príspevku používateľ počkať (n) sekúnd pred vytvorením ďalšieho príspevku." + max_likes_per_day: "Maximálny počet páči sa mi používateľa denne." + max_flags_per_day: "Maximálny počet príznakov používateľa denne." + max_bookmarks_per_day: "Maximálny počet záložiek na jedného používateľa denne." + max_edits_per_day: "Maximálny počet úprav používateľa denne." + max_topics_per_day: "Maximálny počet tém používateľa denne." + max_private_messages_per_day: "Maximálny počet správ ktoré môže používateľ denne vytvoriť." + max_invites_per_day: "Maximálny počet pozvánok ktoré môže používateľ denne zaslať." + max_topic_invitations_per_day: "Maximálny počet pozvánok do tém ktoré môže používateľ denne zaslať." + suggested_topics: "Zobrazovaný počet navrhovaných tém na konci témy." + limit_suggested_to_category: "V navrhovaných témach zobraziť iba témy z aktuálnej kategórie." + clean_up_uploads: "Na zamedzenie nezákonného uloženia odstrániť opustené nahrané súbory na ktoré nevedie žiadny odkaz. VAROVANIE: pred zapnutím tohoto nastavenie možno chcete zálohovať Váš adresár s nahranými súbormi." + clean_orphan_uploads_grace_period_hours: "Doba (v hodinách) pred odstránením opustených nahraných súborov." + purge_deleted_uploads_grace_period_days: "Doba (v dňoch) pred úplným vymazaním odstráneného nahraného súboru." + purge_unactivated_users_grace_period_days: "Doba (v dňoch) pred tým, než je užívateľ, ktorý si neaktivoval svoj účet vymazaný." + enable_s3_uploads: "Ukladať nahrávané súbory na úložište S3. DÔLEŽITÉ: vyžaduje platné prístupové údaje S3 (id prístupového kľúča (access key id) a tajný prístupový kľúč (secret access key))." + s3_use_iam_profile: 'Použiť rolu AWS EC2 IAM na načítanie kľúčov. POZNÁMKA: zapnutie prepíše nastavený "s3 prístupový kľúč id (s3 access key id)" a "s3 tajný prístupový kľúč (s3 secret access key)".' + s3_upload_bucket: "Amazon S3 bucket name, do ktorého budú nahraté súbory. POZOR: musí byť malými písmenami, žiadne bodky a žiadne podtržítka." + s3_access_key_id: "Amazon S3 access key id, ktoré bude použité pre nahrávanie obrázkov." + s3_secret_access_key: "Amazon S3 secret access key, ktorý bude použitý pre nahrávanie obrázkov." + s3_region: "Amazon S3 region name, ktorý bude použitý pre nahrávanie súborov." + s3_cdn_url: "CDN URL ktoré sa použije na všetky dáta v s3 (napríklad https://cdn.niekde.com). VAROVANIE: po zmene tohoto nastavenia musíte použiť príkaz rebake na všetky staré príspevky." + avatar_sizes: "Zoznam automaticky generovaných veľkostí avatarov." + external_system_avatars_enabled: "Použiť externú avatar službu." + external_system_avatars_url: "URL externej avatar služby. Dostupné náhrady sú {username} {first_letter} {color} {size}" + default_opengraph_image_url: "URL štandardného opengraph obrázku." + enable_flash_video_onebox: "Povolenia vkladania odkazov na swf a flv (Adobe Flash) v onebox. VAROVANIE: môže vniesť bezpečnostné riziká." + default_invitee_trust_level: "Predvolená úroveň dôvery (0-4) pre pozvaných používateľov." + default_trust_level: "Východzí stupeň dôvery (0-4) pre všekých nových užívateľov. UPOZORNENIE: Zmena nastavenia Vás môže vystaviť riziku spamovania. " + tl1_requires_topics_entered: "Koľko tém musí nový užívateľ zadať pred povýšením na stupeň dôvery 1." + tl1_requires_read_posts: "Koľko príspevkov musí nový užívateľ prečítať pred povýšením na stupeň dôvery 1." + tl1_requires_time_spent_mins: "Koľko minút musí nový užívateľ čítať príspevky pred povýšením na stupeň dôvery 1." + tl2_requires_topics_entered: "Koľko tém musí nový užívateľ zadať pred povýšením na stupeň dôvery 2." + tl2_requires_read_posts: "Koľko príspevkov musí nový užívateľ prečítať pred povýšením na stupeň dôvery 2." + tl2_requires_time_spent_mins: "Koľko minút musí nový užívateľ čítať príspevky pred povýšením na stupeň dôvery 2." + tl2_requires_days_visited: "Koľko dní musí nový užívateľ navštevovať stránku pred povýšením na stupeň dôvery 2." + tl2_requires_likes_received: "Koľko \"Páči sa\" musí nový užívateľ dostať pred povýšením na stupeň dôvery 2." + tl2_requires_likes_given: "Koľko \"Páči sa\" musí nový užívateľ rozdať pred povýšením na stupeň dôvery 2." + tl2_requires_topic_reply_count: "Na koľko tém musí nový užívateľ odpovedať pred povýšením na stupeň dôvery 2." + tl3_requires_topics_viewed_all_time: "Minimálny počet všetkých tém, ktoré musí mať užívateľ pozreté pre kvalifikáciu na dosiahnute 3 levelu dôvery. " + tl3_requires_posts_read_all_time: "Minimálny počet všetkých príspevkov, ktoré musí mať užívateľ prečítané pre kvalifikáciu na 3 level dôvery. " + tl3_promotion_min_duration: "MInimálny počet dní po pridelení 3 levelu dôvery než môže byť užívateľ degradovaný späť na 3 level dôvery." + tl3_links_no_follow: "Neodstraňujte rel = nofollow z odkazov pridaných užívateľmi s úrovňou dôveryhodnosti 3 ." + min_trust_to_create_topic: "MInimálna úroveň dôvery na vytvorenie novej témy." + min_trust_to_edit_wiki_post: "MInimálna úroveň dôvery na úpravu wiki príspevku." + min_trust_to_allow_self_wiki: "MInimálna úroveň dôvery k tomu aby mohol používateľ svoje témy meniť na wiki." + min_trust_to_send_messages: "MInimálna úroveň dôvery na vytvorenie novej osobnej správy." + newuser_max_links: "Koľko odkazov môže nový používateľ pridať do príspevku." + newuser_max_images: "Koľko obrázkov môže nový používateľ pridať do príspevku." + newuser_max_attachments: "Koľko príloh môže nový používateľ pridať do príspevku." + newuser_max_mentions_per_post: "Maximálny počet notifikácií typu @meno môže nový užívateľ použiť v príspevku." + newuser_max_replies_per_topic: "Maximálny počet odpovedí ktoré môže nový používateľ pridať do jednej témy pokiaľ na ne niekto neodpovie." + max_mentions_per_post: "Maximálný počet notifikácií typu @meno, ktoré môže ktokoľvek použiť v rámci jedného príspevku." + max_users_notified_per_group_mention: "Maximálny počet používateľov, ktorý môžu dostať notifikácie, v prípade notifikovania celej skupiny (ak sa dosiahne maximum, žiadne ďalšie notifikácie nebudú zaslané)" + create_thumbnails: "Vytvor náhľad a okraje pre obrázoky, ktoré sú príliš veľké aby sa zmestili do príspevku." + email_time_window_mins: "Počkať (n) minút pred poslaním akýchkoľvek notifikačných emailov, aby mali používatelia čas úpraviť a dokončiť svoje príspevky." + email_posts_context: "Koľko posledných odpovedí zahrnúť do obsahu v notifikačných emailoch." + flush_timings_secs: "Ako často posielať časové dáta na server, v sekundách." + title_max_word_length: "Maximálna povolená dĺžka slov v názve témy, v znakoch." + title_min_entropy: "Minimálna entropia (unikátne znaky, znaky s diakritikou sa počítajú za dva) vyžadovaná na nadpis témy." + body_min_entropy: "Minimálna entropia (unikátne znaky, znaky s diakritikou sa počítajú za dva) vyžadovaná pre telo príspevku." + allow_uppercase_posts: "Povoliť kapitálky v názve témy, alebo tele príspevku." + title_fancy_entities: "Zameniť v nadpisoch tém bežné ASCII znaky za zábavné HTML znaky, ala SmartyPants http://daringfireball.net/projects/smartypants/" + min_title_similar_length: "Minimálna dĺžka nadpisu na spustenie kontroly na podobné témy." + min_body_similar_length: "Minimálna dĺžka tela príspevku na spustenie kontoly na podobné témy." + category_colors: "Zoznam hexadecimálnych hodnôt farieb povolených pre kategórie." + category_style: "Vizuálny štýl pre odznaky za kategórie." + max_image_size_kb: "Mmaximálna veľkosť vloženého obrázku v kB. Rovnako musí byť nastavená v nginx (client_max_body_size) / apache alebo na proxy." + max_attachment_size_kb: "Mmaximálna veľkosť vloženej prílohy v kB. Rovnako musí byť nastavená v nginx (client_max_body_size) / apache alebo na proxy." + authorized_extensions: "Zoznam povolených príloh súborov ktoré je umožnené vkladať (použite '*' na vkladanie súborov všetkých typov)" + max_similar_results: "Koľko podobných tém sa má zobraziť nad editorom ak vytvára novú tému. Porovnanie je založené na nadpise a tele správy." + title_prettify: "Predchádzať bežným malým preklepom a chybám, zapnutým kapitálkam, malému prvému znaku, duplikácií ! a ?, extra . na konci a podobne." + topic_views_heat_low: "Počet zobrazení aby bolo pole zobrazení jemne zvýraznené." + topic_views_heat_medium: "Počet zobrazení aby bolo pole zobrazení stredne zvýraznené." + topic_views_heat_high: "Počet zobrazení aby bolo pole zobrazení výrazne zvýraznené." + cold_age_days_low: "Po koľkých dňoch je dátum poslednej aktivity danej konverzácie jemne tlmený." + cold_age_days_medium: "Po koľkých dňoch je dátum poslednej aktivity danej konverzácie stredne tlmený." + cold_age_days_high: "Po koľkých dňoch je dátum poslednej aktivity danej konverzácie silne tlmený." + history_hours_low: "Po koľkých hodinách od poslednej úpravy je ikona úprav príspevku jemne zvýraznená." + history_hours_medium: "Po koľkých hodinách od poslednej úpravy je ikona úprav príspevku stredne zvýraznená." + history_hours_high: "Po koľkých hodinách od poslednej úpravy je ikona úprav príspevku veľmi zvýraznená." + topic_post_like_heat_low: "Po prekročení akého pomeru likes:post je pole počtu na príspevku jemne zvýraznené." + topic_post_like_heat_medium: "Po prekročení akého pomeru likes:post je pole počtu na príspevku stredne zvýraznené." + topic_post_like_heat_high: "Po prekročení akého pomeru likes:post je pole počtu na príspevku veľmi zvýraznené." + faq_url: "Ak máte FAQ stránku uloženú na iných stránkach, napište sem plný odkaz na ňu." + tos_url: "Ak máte stránku s Podmienkami uloženú na iných stránkach, napište sem plný odkaz na ne." + privacy_policy_url: "Ak máte stránku s Podmienkami súkromia uloženú na iných stránkach, napište sem plný odkaz na ne." + newuser_spam_host_threshold: "Koľkokrát môže nový používateľ pridať odkaz na rovnaký server v jeho `newuser_spam_host_posts` príspevkoch predtým, než to bude považované za spam." + white_listed_spam_host_domains: "Zoznam domén vylúčených z testovania spamových zdrojov. Novým používateľom nebude nikdy zabránené vytvárať príspevky s odkazmi na tieto domény." + staff_like_weight: "Koľkonásobne viac sa má dať zamestnaneckým páči sa mi." + topic_view_duration_hours: "Započítaj nové pozretie témy raz za IP/používateľa každých N hodín." + user_profile_view_duration_hours: "Započítaj nové pozretie používateľského profilu raz za IP/používateľa každých N hodín." + levenshtein_distance_spammer_emails: "Počet rozdielnych znakov, ktoré stále umožnia fuzzy zhodu, keď sa hľadájú emaily od spammerov." + max_new_accounts_per_registration_ip: "Neakceptovať ďalšie prihlásenia z IP adresy v prípade, ak už existuje (n) účtov s úrovňou dôvery 0 z danej IP adresy (a žiadny nie je zamestnancec alebo s úrovňou dôvery 2 a vyššou)." + min_ban_entries_for_roll_up: "Ak existuje minimálne (N) položiek a kliknete na Zrolovať, vytvorí sa nový obmedzujúci záznam podsiete." + max_age_unmatched_emails: "Zmazať nevyskytujúce sa kontrolované emailové adresy po (N) dňoch." + max_age_unmatched_ips: "Zmazať nevyskytujúce sa kontrolované IP adresy po (N) dňoch." + num_flaggers_to_close_topic: "Minimálny počet rôznych oznamovateľov potrebný na automatické pozastavenie témy pre intervenciu." + num_flags_to_close_topic: "Minimálny počet aktívnych príznakov potrebný na automatické pozastavenie témy pre intervenciu." + auto_respond_to_flag_actions: "Zapnúť automatickú odpoveď pri odstránení označenia." + min_first_post_typing_time: "Minimalny čas písania prvého príspevku v milisekundách, ak je čas kratší ako je limit, príspevok bude automaticky zaradený do fronty na schválenie. Nastav 0 pre vypnutie (Neoporúča sa)" + auto_block_fast_typers_on_first_post: "Automaticky blokovať užívateľov, ktorí nesplnili podmienku minimálneho času pre prvý príspevok min_first_post_typing_time" + auto_block_fast_typers_max_trust_level: "Maximálny level dôvery pre automatické blokovanie rýchlo-písačov" + auto_block_first_post_regex: "Regulárny výraz bez rozlíšenia veľkých a malých písmen, ktorého splnenie zablokuje prvý príspevok užívateľa a pošle ho do fronty na schválenie. Napriklad: raging|a[bc]a , zablokuje príspevky obsahujúce raging alebo aba alebo aca. Aplikuje sa len na prvý príspevok. " + reply_by_email_enabled: "Povoliť odpoveď na tému prostredníctvom emailu." + reply_by_email_address: "Šablóna pre príchodziu emailovú adresu emailových odpovedí. Napríklad : %{reply_key}@reply.example.com or replies+%{reply_key}@example.com" + disable_emails: "Zabrániť Discoursu v odosielaní akýchkoľvek e-mailov" + strip_images_from_short_emails: "Odobrať obrázky z e-mailov s veľkosťou menšou ako 2800 bajtov" + short_email_length: "Dĺžka krátkeho emailu v bytoch." + display_name_on_email_from: "V emailovom poli Od zobraziť plné mená" + unsubscribe_via_email: "Umožniť používateľom odhlásiť sa z emailov pomocou zaslania emailu s textom 'unsubscribe' v predmete alebo v tele emailu" + unsubscribe_via_email_footer: "Do päty stránky posielaných emailov pridať odkaz na odhlásenie sa" + delete_email_logs_after_days: "Zmazať logy o emailoch po (N) dňoch. 0 pre neobmedzene. " + pop3_polling_enabled: "Získavať emailové odpovede pomocou POP3" + pop3_polling_ssl: "Na spojenie s POP3 serverom použiť SSL. (Doporučované)" + pop3_polling_period_mins: "Doba v minutách medzi POP3 kontrolami emailov. POZNÁMKA: vyžaduje reštart." + pop3_polling_port: "Port na ktorom kontrolovať POP3 účet." + pop3_polling_host: "Adresa na ktorej kontrolovať POP3 účet." + pop3_polling_username: "Používateľské meno na kontrolu emailového POP3 účtu." + pop3_polling_password: "Heslo na kontrolu emailového POP3 účtu." + log_mail_processing_failures: "Zaznamenávať všetky chyby pri spracovaní emailov do http://yoursitename.com/logs" + email_in: "Umožniť používateľom posielať nové príspevky pomocou emailu (vyžaduje POP3 kontrolu). Adresy nastavte v záložke \"Nastavenia\" pre každú kategóriu." + email_in_min_trust: "MInimálna úroveň dôveru použivateľa, ktorý môže posielať nové príspevky pomocou emailu." + email_prefix: "[Menovka], ktorá má byť použitá ako predmet emailov. Ak nie je nastavená bude nahradená 'nadpisom'." + email_site_title: "Názov stránok, použitý ako odosieľateľ emailov zo stránok. Ak nie ne nastavený bude použitý 'nadpis'. Použite toto nastavenie, ak Váš nadpis obsahuje nepovolené znaky pre emailový reťazec odosieľateľ." + minimum_topics_similar: "Koľko tém musí existovať predtým, ako sa začnú zobraznovať podobné témy pri zakladaní novej témy." + relative_date_duration: "Počet dní, po uplynutí ktorých sa doba príspevkov začne zobrazovať relatívne (7d) miesto ablolútnej (20 Feb)." + delete_user_max_post_age: "Neumožniť vymazanie použivateľov, ktorých prvý príspevok je starší ako (x) dní." + delete_all_posts_max: "Maximálny počet príspevkov, ktoré môžu byť vymazané naraz pomocou tlačítka Vymaž všetky príspevky. Ak má používateľ viac ako uvedený počet, príspevky nemôžu byť vymazané naraz a používateľ nemôže byť vymazaný." + username_change_period: "Počet dní od registrácie po ktorých môžu účty zmeniť používateľské meno (Na vypnutie zmeny používateľského mena nastavte 0)." + email_editable: "Povoliť užívateľom zmenu ich emailovej adresy po registrácii." + logout_redirect: "Adresa na presmerovanie prehliadača po odhlásení napr. (http://somesite.com/logout)" + allow_uploaded_avatars: "Povoliť používateľom nahranie profilovej fotky." + allow_animated_avatars: "Umožniť používateľom, použiť ako profilový obrázok animovaný gif. VAROVANE: na zmenu tohoto nastavenia spustite rake task avatars:refresh." + allow_animated_thumbnails: "Generovať animované náhľady anomovaných gifov." + default_avatars: "URL na avatara, ktorý bude štandardne použitý pre nových používateľov pokiaľ si ho nezmenia." + automatically_download_gravatars: "Po vytvorení účtu alebo zmene heslo stiahnuť používateľov Gravatar." + digest_topics: "Maximálny počet tém, ktoré sa zobrazia v súhrnnom emaile." + digest_min_excerpt_length: "Minimálny výťah príspevku v sumarizačnom emaile, v znakoch." + delete_digest_email_after_days: "Zakázat súhrnný email používateľom, ktorí neboli na stránkach viac ako (n) dní." + disable_digest_emails: "Vypnúť sumárny email pre všetkých používateľov." + detect_custom_avatars: "Má alebo nemá sa kontrolovať nahratie vlastného profilového obrázka používateľa?" + max_daily_gravatar_crawls: "Koľkokrát denne má Discourse kontrolovať Gravatar na zistenie vlastného avatara." + public_user_custom_fields: "Schválený zoznam vlastných polí používateľa, ktoré budú verejne zobrazené." + staff_user_custom_fields: "Schválený zoznam vlastných polí používateľa, ktoré budú zobrazené zamestnancom." + enable_user_directory: "Povoliť prezeranie zoznamu používateľov." + allow_anonymous_posting: "Povoliť používateľom prepnutie do anonymného režimu." + anonymous_posting_min_trust_level: "Minimálna úroveň dôvery na zapnutie anonymného prispievania." + anonymous_account_duration_minutes: "Každých N minút vytvor nový anonymný účet na ochranu používateľskej anonymity. Príklad: Ak je nastavené na 600, akonáhle uplynie 600 minút od posledného príspevku A používateľ prepne do anonymného režimu, vytvorí sa nový anonymný účet." + hide_user_profiles_from_public: "Vypnúť používateľské karty, profily a adresár pre anonymných používateľov." + allow_profile_backgrounds: "Povoliť používateľov nahranie pozadia do profilu." + sequential_replies_threshold: "Po koľkých po sebe idúcich príspevkov v rade za sebou sa má používateľovi zobraziť varovanie o nadmernom množstve odpovedí?" + enable_mobile_theme: "Mobilné zariadenia používajú tému pre mobilné zariadenia s možnosťou prepnutia na plnú verziu stránok. Vypnite, ak chcete použiť vlastný štýl, ktorý podporuje mobilné zariadenia." + dominating_topic_minimum_percent: "Koľko percent príspevkou musí pouťívateľ pridať do témy než sa mu zobrazí pripomienka o dominovaní témy." + disable_avatar_education_message: "Vypnúť informatívnu hlášku na zmenu avatara." + daily_performance_report: "Denne analyzuj NGINX logy a z detailov vytváraj témy iba pre zamestnancov." + suppress_uncategorized_badge: "V zozname tém nezobrazuj odznak za nekategorizované príspevky." + global_notice: "Pre všetkých návštevníkov zobraz URGENTNÉ, KRÍZOVÉ globálné záhlavie, zmeň na čierne a schovaj (HTML povolené)." + disable_edit_notifications: "Ak je premenná 'download_remote_images_to_local' aktívna, vypnúť notifikácie o úpravách systémového používateľa." + automatically_unpin_topics: "Automaticky odopnúť témy ak používateľ dostanie posledný príspevok." + read_time_word_count: "Počet slov za minútu určený na výpočet odkazovaného času čítania." + full_name_required: "Na používateľskom profile je vyžadované plné meno." + enable_names: "Na profile zobraziť plné používateľské meno, karty a emaily používateľa. Vypnite na schovanie plného mena všade." + display_name_on_posts: "Na príspevkoch zobraziť okrem @loginpoužívateľa i plné meno používateľa." + show_time_gap_days: "Koľko dní musí uplynúť medzi dvoma príspevkami v téme, aby sa medzi nimi zobrazila časová medzera." + invites_per_page: "Na stránke používateľa sú zobrazené štandardné pozvánky." + short_progress_text_threshold: "Ak počet príspevkov v téme presiahne toto číslo, ukazateľ priebehu zobrazí iba aktuálne číslo príspevku. Túto hodnotu možno budete potrebovať zmeniť, ak zmeníte šírku ukazateľa priebehu." + default_code_lang: "Vysvietenie syntaxe pre štandardné programovacie jazyky, aplikované na GitHub bloky kódu (lang-auto, ruby, python etc.)" + warn_reviving_old_topic_age: "Zobrazenie varovania, ak niekto začne odpovedať na tému, kde je posledná odpoveď staršia ako uvedený počet dní. Na vypnutie varozania zadajte 0." + autohighlight_all_code: "Zapnúť vysvietenie syntaxe kódu na všetky formátované bloky kódu, i keď nie je explicitne zadaný jazyk." + highlighted_languages: "Vložte pravidlá pre vysvietenie syntaxe. (Varovanie: zahrnutie príliš veľa pravidiel môže mať doapd na výkon) pozrite si demo na https://highlightjs.org/static/demo/." + feed_polling_enabled: "IBA VKLADANIE: Či sa má vkladať RSS/ATOM kanál ako príspevok." + feed_polling_url: "IBA VKLADANIE: URL RSS/ATOM kanálu na vloženie" + embed_by_username: "Discourse používateľské meno pre používateľa, ktorý vkladá vložené príspevky." + embed_username_key_from_feed: "Kľúč na načítanie discourse používateľského mena z RSS/ATOM kanálu." + embed_truncate: "Orezať vkladané príspevky." + embed_post_limit: "Maximálny počet príspevkov na vloženie." + embed_username_required: "Na vytvorenie téme je vyžadované používateľské meno." + embed_whitelist_selector: "CSS prepínač na elementy, ktoré sú povolené pri vkladaní." + embed_blacklist_selector: "CSS prepínač na elementy, ktoré sú vymazané pri vkladaní." + notify_about_flags_after: "Ak existujú príznaky ktoré neboli vyriešené po uvedenom počte hodín, pošli email na contact_email. Pre vypnutie nastavte 0." + enable_cdn_js_debugging: "Pomocou pridania \"crossorigin\" práv pre všetky vložené js umožniť /logs riadne zobrazenie chýb." + show_create_topics_notice: "Zobraz výzvu žiadajúcu administrátorov o vytvorenie nejakých tém, ak majú stránky menej ako 5 verejných tém." + delete_drafts_older_than_n_days: Vymazať návrhy staršie ako (n) dní. + vacuum_db_days: "Spustiť VACUUM ANALYZE na získanie DB miesto po migráciách (pre vypnutie nastavte na 0)" + prevent_anons_from_downloading_files: "Zabrániť anonymným používateľom sťahovať prílohy. VAROVANIE: toto nastavenie zneprístupní akékoľvek neobrázkové súbory na stánkach uložené ako prílohy." + slug_generation_method: "Vybrať metódu generovania koncovej časti adresy. 'encoded' vygeneruje percentami zakódovaní reťazec. 'none' vypne koncovú časť adresy úplne." + enable_emoji: "Zapnúť emoji" + emoji_set: "Aké emoji chcete mať?" + enforce_square_emoji: "Vynútiť švorcový pomer strán na všetkých emoji." + approve_unless_trust_level: "Príspevky používateľov pod touto úrovňou důvery musia byť schválené" + notify_about_queued_posts_after: "Ak existujú príspevky, ktoré čakali na schválenie viac ako uvedený počet hodín, na kontaktný email bude zaslaná správa. Na vypnutie emailov nastavte 0." + default_email_digest_frequency: "Ako často štandardne používatelia dostávajú sumárny email." + default_email_private_messages: "Štandardne poslať email použivateľovi, ktorému niekto poslal správu." + default_email_direct: "Štandardne poslať email ak niekto cituje/odpovedá/uvednie alebo pozve používateľa." + default_email_mailing_list_mode: "Štandardne poslať email pre každý nový príspevok." + default_email_always: "Štandardne poslať emailovú správu dokonca i vtedy, ak je používateľ aktívny." + default_other_new_topic_duration_minutes: "Globálna šandardná podmienka kedy sa téma považuje za novú." + default_other_auto_track_topics_after_msecs: "Globálny šandardný čas pred tým ako je téma automaticky sledovaná." + default_other_external_links_in_new_tab: "Štandardne otvárať externé odkazy v novej záložke." + default_other_enable_quoting: "Štandardne na vybraný text zapnúť citované odpovede." + default_other_dynamic_favicon: "Štandardne zobraziť počet nových/aktualizovaných tém v ikone prehliadača." + default_other_disable_jump_reply: "Štandardne po odpovedi neskákať na používateľov príspevok." + default_other_edit_history_public: "Štandardne zobraziť revízie príspevku verejne." + default_topics_automatic_unpin: "Štandardne automaticky odopnúť témy ak používateľ dosiahne posledný príspevok." + default_categories_watching: "Štandardný zoznam kategórií, ktoré sú sledované." + default_categories_tracking: "Štandardný zoznam kategórií, ktoré sú sledované." + default_categories_muted: "Štandardný zoznam kategórií, ktoré sú vypnuté." + errors: + invalid_email: "Nesprávna emailová adresa." + invalid_username: "S daným používateľským menom neexistuje žiadny používateľ." + invalid_integer_min_max: "Hodnota musí byť medzi %{min} a %{max}." + invalid_integer_min: "Hodnota musí byť %{min} alebo viac." + invalid_integer_max: "Hodnota nemôže byť viac ako %{max}." + invalid_integer: "Hodnota musí byť celé číslo." + regex_mismatch: "Hodnota nevyhovuje požadovanému formátu." + must_include_latest: "Horné menu musí obsahovať záložku 'posledné'." + invalid_string: "Nesprávna hodnota." + invalid_string_min_max: "Musí byť medzi %{min} a %{max} znakmi." + invalid_string_min: "Musí byť minimálne %{min} znakov." + invalid_string_max: "Nesmie byť viac ako %{max} znakov." + invalid_reply_by_email_address: "Hodnota musí obsahovať '%{reply_key}' a byť odlišná od notifikačného emailu." + pop3_polling_host_is_empty: "Pred nastavením POP3 sťahovania musíte nastaviť 'pop3 adresu'." + pop3_polling_username_is_empty: "Pred nastavením POP3 sťahovania musíte nastaviť 'pop3 používateľské meno'." + pop3_polling_password_is_empty: "Pred nastavením POP3 sťahovania musíte nastaviť 'pop3 heslo'." + pop3_polling_authentication_failed: "POP3 autentikácia zlyhala. Prosíme overte zadané pop3 nastavenia." + notification_types: + group_mentioned: "%{group_name} bola spomenutá v %{link}" + mentioned: "%{display_username} sa o Vás zmienil v %{link}" + liked: "%{display_username} sa páčil Váš príspevok v %{link}" + replied: "%{display_username} odpovedal na Váš príspevok v %{link}" + quoted: "%{display_username} citoval Váš príspevok v %{link}" + edited: "%{display_username} upravil Váš príspevok v %{link}" + posted: "%{display_username} prispel do %{link}" + moved_post: "%{display_username} presunul Váš príspevok do %{link}" + private_message: "%{display_username} vám poslal správu: %{link}" + invited_to_private_message: "%{display_username} Vás pozval k správe: %{link}" + invitee_accepted: "%{display_username} prijal vaše pozvanie" + linked: "%{display_username} odkazuje na Vás v %{link}" + granted_badge: "Získali ste %{link}" + search: + within_post: "#%{post_number} od %{username}" + types: + category: 'Kategórie' + topic: 'Výsledky' + user: 'Používatelia' + original_poster: "Pôvodný autor" + most_posts: "Najviac príspevkov" + most_recent_poster: "Najaktuálnejší prispievateľ" + frequent_poster: "Častý prispievateľ" + redirected_to_top_reasons: + new_user: "Vitajte v našej komunite! Toto sú najpopulárnejšie z posledných tém." + not_seen_in_a_month: "Vitajte späť! Nevideli sme Vás už nejaký čas. Toto sú najpopulárnejšie témy odkedy ste boli preč." + move_posts: + new_topic_moderator_post: + one: "Príspevok bol oddelený do novej témy: %{topic_link}" + few: "%{count} príspevky boli oddelené do novej témy: %{topic_link}" + other: "%{count} príspevkov bolo oddelených do novej témy: %{topic_link}" + existing_topic_moderator_post: + one: "Príspevok bol pripojený k existujúcej téme: %{topic_link}" + few: "%{count} príspevky boli pripojené k existujúcej téme: %{topic_link}" + other: "%{count} príspevkov bolo pripojených k existujúcej téme: %{topic_link}" + change_owner: + post_revision_text: "Vlástníctvo bolo prenesené z %{old_user} na %{new_user}" + deleted_user: "vymazaný užívateľ" + emoji: + errors: + name_already_exists: "Prepáčte, meno '%{name}'je už použité iným emoji." + error_while_storing_emoji: "Prepáčte, pri ukladaní emoji nastala chyba." + topic_statuses: + archived_enabled: "Táto téma je archivovaná. Je zmrazená a už sa nedá nijako meniť. " + archived_disabled: "Táto téma je vyňatá z archivu. Už nie je zmrazená a môže sa opäť meniť. " + closed_enabled: "Táto téma je už uzavretá. Nové odpovede už nie sú povolené." + closed_disabled: "Táto téma je teraz otvorená. Nové odpovede sú povolené." + autoclosed_enabled_days: + one: "Táto téma bola automaticky uzavretá po 1 dni . Nové odpovede už nie sú povolené." + few: "Táto téma bola automaticky uzavretá po %{count} dňoch . Nové odpovede už nie sú povolené." + other: "Táto téma bola automaticky uzavretá po %{count} dňoch . Nové odpovede už nie sú povolené." + autoclosed_enabled_hours: + one: "Táto téma bola automaticky uzavretá po hodine. Nové odpovede už nie sú povolené." + few: "Táto téma bola automaticky uzavretá po %{count} hodinách. Nové odpovede už nie sú povolené." + other: "Táto téma bola automaticky uzavretá po %{count} hodinách. Nové odpovede už nie sú povolené." + autoclosed_enabled_minutes: + one: "Táto téma bola automaticky uzavretá po minúte. Nové odpovede už nie sú povolené." + few: "Táto téma bola automaticky uzavretá po %{count} minútach. Nové odpovede už nie sú povolené." + other: "Táto téma bola automaticky uzavretá po %{count} minútach. Nové odpovede už nie sú povolené." + autoclosed_enabled_lastpost_days: + one: "Táto téma bola automaticky uzavretá po 1 dni od poslednej odpovede. Nové odpovede už nie sú povolené." + few: "Táto téma bola automaticky uzavretá po %{count} dňoch od poslednej odpovede. Nové odpovede už nie sú povolené." + other: "Táto téma bola automaticky uzavretá po %{count} dňoch od poslednej odpovede. Nové odpovede už nie sú povolené." + autoclosed_enabled_lastpost_hours: + one: "Táto téma bola automaticky uzavretá po1 hodine od poslednej odpovede. Nové odpovede už nie sú povolené." + few: "Táto téma bola automaticky uzavretá po %{count} hodinách od poslednej odpovede. Nové odpovede už nie sú povolené." + other: "Táto téma bola automaticky uzavretá po %{count} hodinách od poslednej odpovede. Nové odpovede už nie sú povolené." + autoclosed_enabled_lastpost_minutes: + one: "Táto téma bola automaticky uzavretá po 1 minúte od poslednej odpovede. Nové odpovede už nie sú povolené." + few: "Táto téma bola automaticky uzavretá po %{count} minútach od poslednej odpovede. Nové odpovede už nie sú povolené." + other: "Táto téma bola automaticky uzavretá po %{count} minútach od poslednej odpovede. Nové odpovede už nie sú povolené." + autoclosed_disabled: "Táto téma je teraz otvorená. Nové odpovede sú povolené." + autoclosed_disabled_lastpost: "Táto téma je teraz otvorená. Nové odpovede sú povolené." + pinned_enabled: "Táto téma je teraz pripnutá. Bude zobrazená na vrchu danej kategórie pokiaľ ju neodopnú zamestnanci pre všetkých alebo samostatne každý používateľ." + pinned_disabled: "Táto téma je teraz odopnutá. Ďalej sa nebude zobrazovať na vrchu danej kategórie." + pinned_globally_enabled: "Táto téma je teraz pripnutá globálne. Zobrazí sa na vrchu danej kategórie a vrchu všetkých tém pokiaľ ju neodopnú zamestnanci pre všetkých alebo samostatne každý používateľ." + pinned_globally_disabled: "Táto téma je teraz odopnutá. Ďalej sa nebude zobrazovať na vrchu danej kategórie." + visible_enabled: "Táto téma je teraz uvedená v zozname. Bude zobrazená v zozname tém." + visible_disabled: "Táto téma odteraz nie je uvedená v zozname. Odteraz sa nebude zobrazovať v žiadnom zozname tém. Jediný spôsob ako pristúpiť na danú tému je priamym odkazom." + login: + not_approved: "Váš účet zatiaľ nebol schválený. Ak bude pripravený na prihlásenie, dostanete upozorňujúci email." + incorrect_username_email_or_password: "Nesprávne meno, email, alebo heslo" + wait_approval: "Ďakujeme za registráciu. O schválení účtu Vás budeme informovať." + active: "Váš účet je aktivovaný a pripravený na používanie." + activate_email: "

    Skoro hotovo! Poslali sme Vám aktivačný email na %{email}. Pre aktiváciu účtu prosíme splňte inštrukcie v emaile.

    Ak nedorazí, skontrolujte si zložku s nevyžiadanou poštou, alebo sa prihláste znovu, aby ste si zaslali ďalší aktivačný email.

    " + not_activated: "Systém vás nemôže prihlásiť. Poslali sme vám aktivačný email. Prosím, postupujte podľa inštrukcií na aktiváciu účtu, ktoré sú uvedené v tomto emaile." + not_allowed_from_ip_address: "Nie je možné prihlásenie ako %{username} z tejto IP adresy." + admin_not_allowed_from_ip_address: "Nie je možné prihlásenie ako admin z tejto IP adresy." + suspended: "Nemôžte sa prihlásiť do %{date}." + suspended_with_reason: "Tento účet je suspendovaný do %{date}: %{reason}" + errors: "%{errors}" + not_available: "Nie je k dispozícii. Skúste %{suggestion}?" + something_already_taken: "Niečo sa pokazilo, možno je tento užívateľ, alebo e-mail už registrovaný, vyskúšajte odkaz pre zabudnuté heslo" + omniauth_error: "Ľutujeme, nastala chyba pri autorizácii Vášho účtu. Povolili ste autorizáciu?" + omniauth_error_unknown: "Niečo sa pokazilo počas prihlasovania, prosím skúste sa prihlásiť znova." + new_registrations_disabled: "Registrácia nových účtov momentálne nie je povolená." + password_too_long: "Dĺžka hesla je obmedzená na 200 znakov. " + email_too_long: "Emailová adresa je príliš dlhá. Meno priečinka musí byť kratšie ako 254 znakov a meno domény musí byť kratšie ako 253 znakov." + reserved_username: "Toto užívateľské meno nie je povolené." + missing_user_field: "Nevyplnili ste všetky užívateľké polia." + close_window: "Autentifikácia je dokončená. Pre pokračovanie zavrite toto okno. " + user: + no_accounts_associated: "Žiadne pripojené účty " + username: + short: "musí mať minimálne %{min} znakov" + long: "nesmie byť dlhší než %{max} znakov" + characters: "musí obsahovať len čísla, písmená a podržníky" + unique: "musí byť jedinečné" + blank: "musí existovať" + must_not_contain_two_special_chars_in_seq: "nesmie obsahovať reťazec 2 alebo viac špeciálnych znakov po sebe (.-_)" + must_not_end_with_confusing_suffix: "nesmie byť ukončené mätúcou príponou ako napríklad .json alebo .png a podobne." + email: + not_allowed: "nie je povolená od tohto poskytovateľa emailu. Prosím použite inú emailovú adresu. " + blocked: "nie je povolená." + ip_address: + blocked: "Nové registrácie nie sú povolené z Vašej IP adresy." + max_new_accounts_per_registration_ip: "Nové registrácie nie sú povolené z Vašej IP adresy (dosiahnutý limit). Kontaktujte člena obsluhy. " + flags_reminder: + subject_template: + one: "1 značká čaká na zpracovanie" + few: "%{count} značky čakajú na zpracovanie" + other: "%{count} značiek čaká na zpracovanie" + unsubscribe_mailer: + subject_template: "Potvrďte, že už ďalej nechcete dostávať aktualizácie z %{site_title}" + text_body_template: | + Niekto (pravdepodobne vy?) požiadal aby ďalej na túto adresu neboli zasielané emailové aktualizácie z %{site_domain_name}. + Ak si prajete potvrdiť, prosíme kliknite na odkaz: + + %{confirm_unsubscribe_link} + + + Ak chcete pokračovať v prijímaní emailových aktualizácií, môžete tento email ignorovať. + invite_mailer: + subject_template: "%{invitee_name} Vás pozval '%{topic_title}' na %{site_domain_name}" + text_body_template: | + %{invitee_name} Vás pozval do diskusie + + > **%{topic_title}** + > + > %{topic_excerpt} + + na + + > %{site_title} -- %{site_description} + + Ak Vás to zaujalo, kliknite na odkaz nižšie: + + %{invite_link} + + Táto pozvánka je od dôveryhodného užívateľa, takže môžete okamžite odpovedať na diskusiu . + invite_forum_mailer: + subject_template: "%{invitee_name} Vás pozval na %{site_domain_name}" + text_body_template: | + %{invitee_name} Vás pozval, aly ste sa pripojili na + + > **%{site_title}** + > + > %{site_description} + + Ak Vás to zaujíma, kliknite na nižšie uvedený odkaz: + + %{invite_link} + + Toto pozvanie je od dôveryhodného používateľa, takze sa nebudete musieť prihlasovať. + invite_password_instructions: + subject_template: "Nastavte heslo pre účet na %{site_name}" + text_body_template: | + Ďakujeme za akceptovanie Vašej pozvánky na %{site_name} -- vitajte! + + Kliknite na odkaz aby ste si vybrali heslo: + %{base_url}/users/password-reset/%{email_token} + + (Ak vyššie uvedený odkaz vyexpiroval, vyberte "Zabudol som heslo" keď sa prihlasujete pomocou svojej emailovej adresy.) + test_mailer: + subject_template: "[%{site_name}] Overenie doručiteľnosti emailu" + new_version_mailer: + subject_template: "[%{site_name}] Nové verzia Discourse, dostupná aktualizácia" + new_version_mailer_with_notes: + subject_template: "[%{site_name}] aktualizácia dostupná" + queued_posts_reminder: + subject_template: + one: "%{site_name}] 1 príspevok čaká na revíziu" + few: "[%{site_name}] %{count} príspevky čakajú na revíziu" + other: "[%{site_name}] %{count} príspevkov čaká na revíziu" + text_body_template: | + Ahoj, + + Existujú príspevky nových používateľov, ktoré čakajú na revíziu. [Schválené alebo zamietnuté môžu byť tu](%{base_url}/queued-posts). + flag_reasons: + off_topic: "Váš príspevok bol označený ako \"mimo-témy\": komunita cíti, že nie je vhodný do témy tak, ako je definovaná nadpisom a prvým príspevkom" + inappropriate: "Váš príspevok bol označený ako **nevhodný**: komunita cíti, že je úrážlivý, nemiestny alebo porušuje [naše pravidlá komunity](/guidelines)." + spam: "Váš príspevok bol označený ako **spam**: komunita cíti, že je to reklama, niečo čo je vo spojej podstate príliš propagačné, miesto toho, aby bolo užitočné alebo relevantné k danej téme, tak ako je očakávané." + notify_moderators: "Váš príspevok bol označený **na kontrolu pre moderátora**: komunita cíti, že nečo v príspevku vyžaduje manuálny zásah niektorým zo zamestnancov." + flags_dispositions: + agreed: "Ďakujeme za upozornenie. Súhlasíme s tým, že je tam problém a pracujeme na ňom." + agreed_and_deleted: "Ďakujeme za upozornenie. Súhlasíme s tým, že je tam problém a príspevok sme odstránili." + disagreed: "Ďakujeme za upozornenie. Práve to riešime." + deferred: "Ďakujeme za upozornenie. Práve to riešime." + deferred_and_deleted: "Ďakujeme za upozornenie. Daný príspevok sme odstránili." + temporarily_closed_due_to_flags: "Tento príspevok je dočasne uzamknutý z dôvodu veľkého množstva vlajok od komunity." + system_messages: + post_hidden: + subject_template: "Príspevok skrytý z dôvodu konumitného označenia vlajkou" + text_body_template: | + Dobrý deň, + + toto je automaticky generovaná správa od %{site_name}, aby ste boli informovaní, že váš príspevok bol skrytý. + + %{base_url}%{url} + + %{flag_reason} + + Viacero členov komunity označilo tento príspevok predtým, ako bol skrytý, takže skúste, prosím, zvážiť, ako by ste mohli príspevok upraviť, aby odrážal ich spätnú väzbu. **Váš príspevok môžete upraviť po %{edit_delay} minútach a bude automaticky opäť zobrazený.** + + Avšak pokiaľ bude príspevok skrytý komunitou druhýkrát, ostane skrytý dovtedy, pokiaľ sa o to nepostarajú moderátori – a tam môže dôjsť k ďalším akciám, ako napr. možné pozastavenie vášho účtu. + + Ohľadom ďalšieho poradenstva si, prosím, pozrite naše [community guidelines](%{base_url}/pokyny). + usage_tips: + text_body_template: | + Tu je niekoľko rád, ako začať: + + ## Čítanie + + Ak chcete pokračovať v čítaní, **jednoducho pokračujte v skrolovaní!** + + V prípade, že dorazia nové odpovede alebo témy, automaticky sa zobrazia - žiadna nutnosť obnovovať stránku. + + ## Navigácia + + - Použite **ikonu s tlačítkom vpravo hore** pr vyhľadávanie, Vašu používateľskú stránku a menu. + + - Ak vyberiete nádpis témy, vždy sa zobrazí **prvá neprečítaná odpoveď** danej témy. Vyberte počet odpovedí alebo dátum poslednej odpovede na zobrazenie začiatku alebo konca. + + + + - K plnej kontrole navigácie v priebehu čítania témy použite ukazovateľ priebehu v pravom spodnom časti stránky. Rýchlo skočte na začiatok kliknutím na nadpis témy. Na zobrazenie zoznamu klávesových skratiek stlačte ?. + + + + ## Odpovede + + - K odpovedi na **tému celkovo**, použite na úplnom konci témy. + + - K odpovedi pre **konkrétnu osobu**, použite na ich príspevkoch. + + - K odpovedi pomocou **novej témya**, použite na pravej strane od príspevku. Oba príspevky, pôvodný i nový budú spojené odkazom. + + Vaša odpoveď môže byť formátovaná pomocou jednoduchého HTML, BBCode alebo [Markdown](http://commonmark.org/help/): + + Toto je **tučné**. + Toto je tučné. + Toto je [b]tučné[/b]. + + Chcete sa naučiť Markdown? [Prejdite si tento zábavný 10 minutový interaktívny tutotiál!](http://commonmark.org/help/tutorial/) + + Na vloženie citácie, vyberte text k citovaniu a stlačte tlačítko Odpovedať. Opakujte pre viacnásobné citovanie. + + + + Zmieňte meno, ak chcete niekoho upozorniť na Vašu odpoveď. Napíšte `@` aby ste mohli vybrať používateľské meno. + + + + Na použitie [štandardných Emoji](http://www.emoji.codes/), napíšte jednoducho `:` na vyhľadanie podľa mena, alebo použite tradičných smajlíkov `;)` + + + + Na vygenerovanie náhľadu a sumáru pre odkaz ho jednoducho vložte na samostatný riadok: + + + + ## Akcie + + Na spodu každého príspevku sú akčné tlačítka: + + + + Ak chcete niekomu dať vedieť, že ste s príspevkom spokojný a oceňujete ho, použite tlačítko **páči sa mi**. Zdieľajte lásku! + + Ak vidíte možný problém na príspevku niehoho, dajte im súkromne vedieť, alebo dajte vedieť [našim zamestnancom](%{base_url}/about), pomocou tlačítka **označiť**. Odkaz na príspevok môžete tiež **zdieľať**, alebo **založiť** na neskoršie použitie na vašej používateľskej stránke. + + ## Oznámenia + + Ak Vám niekto odpovedá, cituje Váš príspevok, alebo váš zmieni pomocou `@používateľskémeno`, zobrazí sa číslo na pravej vrchnej časti stránky. Použite ho na prístup k Vašim **oznámeniam**. + + + + Nebojte sa, že zmeškáte nejakú odpoveď - ak budete preč, všetky notifikácie Vám dorazia emailom. + + ## Vaše nastavenia + + - Všetky témy menej ako **dna dni staré** sú považované za nové. + + - Každá téma, do ktorej ste **aktívne prispeli** (vytvorením, odpovedaním, alebo čítaním dlhšiu dobu) budú automaticky sledované. + + Ako indikátor uvidíte modré kolečko, alebo počet neprečítaných u týchto tém: + + + + Nastavenia oznámení sa dajú zmeniť pre akúkoľvek tému pomocou ovladania na spodnej časti témy. + + + + Ak chcete sledovať každú novú tému v danej kategórií môžete nastaviť notifikácie v rámci kategórie. + + Na zmenu si pozrite [Vaše používateľské nastavenia](%{base_url}/my/preferences). + + ## Dôvera v komunite + + Ak tu prispievate, v priebehu času získate dôveru komunity, stanete sa právoplatným občanom a Vaše používateľské oprávnenia budú navýšené. Ak budete mať dostatočne vysokú [úroveň dôvery](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), získate nové možnosti ako nám pomôcť spravovať našu komunitu spoločne s nami. + welcome_user: + subject_template: "Vitajte na %{site_name}!" + welcome_invite: + subject_template: "Vitajte na %{site_name}!" + backup_succeeded: + subject_template: "Záloha skončila úspešne" + text_body_template: "Záloha bola úspešná.\nNavštívte [admin > sekcia záloha](%{base_url}/admin/backups) na stiahnutie Vašej novej zálohy." + backup_failed: + subject_template: "Záloha sa nepodarila" + text_body_template: | + Zaloha sa nepodarila. + + Tu je zápis: + + ``` + %{logs} + ``` + restore_succeeded: + subject_template: "Obnova skončila úspešne" + text_body_template: "Obnova bola úspešná." + restore_failed: + subject_template: "Obnova zlyhala" + text_body_template: | + Obnova zlyhala. + + Tu je zápis: + + ``` + %{logs} + ``` + bulk_invite_succeeded: + subject_template: "Zpracovanie pozvania viacerých používateľov bolo úspešné" + text_body_template: "Váš súbor na hromadné pozvanie používateľov bol zpracovaný, emailom bolo poslaných %{sent} prihlášok." + bulk_invite_failed: + subject_template: "Zpracovanie pozvania viacerých používateľov dopadlo s chybami" + text_body_template: | + Váš súbor na hromadné pozvanie používateľov bol zpracovaný, emailom bolo poslaných %{sent} prihlášok s %{failed} chybou(chybami). + + Tu je záznam: + + ``` + %{logs} + ``` + csv_export_succeeded: + subject_template: "Export dát kompletný" + csv_export_failed: + subject_template: "Export dát zlyhal" + email_reject_insufficient_trust_level: + subject_template: "[%{site_name}] Problém s emailom -- Nízka úroveň dôvery" + email_reject_inactive_user: + subject_template: "[%{site_name}] Problém s emailom -- Neaktívny užívateľ" + email_reject_no_account: + subject_template: "[%{site_name}] Problém s emailom -- Neznámy účet" + email_reject_empty: + subject_template: "[%{site_name}] Problém s emailom -- Žiadny obsah" + text_body_template: | + Prepáčte, ale Vaša emailová správa na %{destination} (titled %{former_title}) nefungovala. + + Vo Vašom emaile sa nám nepodarilo nájsť žiadny pridávaný obsah. + + Ak ste si istý, že ste obsah pridali, pokúste sa znovu a použite jednoduchšie formátovanie. + email_reject_parsing: + subject_template: "[%{site_name}] Problém s emailom -- Nerozpoznaný obsah" + text_body_template: | + Prepáčte, ale Vaša emailová správa na %{destination} (titled %{former_title}) nefungovala. + + Vo Vašom emaile se nepodarilo nájsť pridávaný obsah. **Uistite sa, že ste odpoveď uviedli na začiatku emailu** -- nedokážeme spracovať vložené odpovede. + email_reject_invalid_access: + subject_template: "[%{site_name}] Problém s emailom -- Nesprávny prístup" + text_body_template: | + Prepáčte, ale Vaša emailová správa na %{destination} (titled %{former_title}) nefungovala. + + Na založenie novej témy v tejto kategórií Váš účet nemá dostatočné oprávnenia. Ak si myslíte, že ide o chybu, kontaktujte zamestnanca stránok. + email_reject_strangers_not_allowed: + subject_template: "[%{site_name}] Problém s emailom -- Nesprávny prístup" + email_reject_invalid_post: + subject_template: "[%{site_name}] Problém s emailom -- Chyba pri uverejnení" + email_reject_invalid_post_specified: + subject_template: "[%{site_name}] Problém s emailom -- Chyba pri uverejnení" + email_reject_invalid_post_action: + subject_template: "[%{site_name}] Problém s emailom -- Neplatná akcia k príspevku" + email_reject_reply_key: + subject_template: "[%{site_name}] Problém s emailom -- Neznámy kľúč odpovede" + email_reject_bad_destination_address: + subject_template: "[%{site_name}] Problém s emailom -- Neznáma adresa príjemcu - Komu:" + email_reject_topic_not_found: + subject_template: "[%{site_name}] Problém s emailom -- Téma nebola nájdená" + email_reject_topic_closed: + subject_template: "[%{site_name}] Problém s emailom -- Téma je uzavretá" + text_body_template: | + Prepáčte, ale Vaša emailová správa na %{destination} (titled %{former_title}) nefungovala. + + Téma, na ktorú odpovedáte je s súčasnosti uzavretá a ďalelšie odpovede nie sú akceptované. Ak si myslíte, že ide o chybu, kontaktujte zamestnanca stránok. + email_reject_auto_generated: + subject_template: "[%{site_name}] Problém s emailom -- Automaticky generovaná odpoveď" + email_error_notification: + subject_template: "[%{site_name}] Problém s emailom -- Chyba pri POP autentifikácií" + too_many_spam_flags: + subject_template: "Nový účet je zablokovaný" + blocked_by_staff: + subject_template: "Účet je zablokovaný" + user_automatically_blocked: + subject_template: "Nový uživateľ %{username} je zablokovaný kôli označeniu komunitou" + spam_post_blocked: + subject_template: "Nový uživateľ %{username} je zablokovaný kôli opakovaným odkazom" + unblocked: + subject_template: "Učet je odblokovaný" + text_body_template: | + Dobrý deň, + + Toto je automatická správa z %{site_name} . Oznamujeme Vám, že Váš účet bol odblokovaný po kontrole obsluhou. + + Znova môžete vytvárať nové témy a odpovede. + pending_users_reminder: + subject_template: + one: "1 užívateľ čaká na schválenie" + few: "%{count} užívateľia čakajú na schválenie" + other: "%{count} užívateľov čaká na schválenie" + download_remote_images_disabled: + subject_template: "Sťahovanie vzdialených obrázkov je zablokované." + unsubscribe_via_email_link: |+ + alebo, [kliknite sem](mailto:reply@%{hostname}?subject=unsubscribe) pre odhlásenie prostredníctvom emailu. + + subject_re: "Re:" + subject_pm: "[PM]" + user_notifications: + previous_discussion: "Prechádzajúce odpovede" + unsubscribe: + title: "Odhlásiť" + description: "Nezaujímajú Vás už tieto emaily? Žiadny problém! Pre okamžité odhlásenie kliknite nižšie: " + reply_by_email: "[Pozrite tému](%{base_url}%{url}), alebo zareagujte odpoveďou na tento email" + reply_by_email_pm: "[Pozrite správu](%{base_url}%{url}), alebo zareagujte odpoveďou na tento email" + visit_link_to_respond: "[Pozrite tému](%{base_url}%{url}) pre reakciu" + visit_link_to_respond_pm: "[Pozrite správu](%{base_url}%{url}) pre reakciu" + posted_by: "Príspevok od %{username} dňa %{post_date}" + user_invited_to_private_message_pm: + subject_template: "[%{site_name}] %{username} Vás pozval k správe '%{topic_title}'" + user_invited_to_private_message_pm_staged: + subject_template: "[%{site_name}] %{username} Vás pozval k správe '%{topic_title}'" + user_replied: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_replied_pm: + subject_template: "[%{site_name}] [PM] %{topic_title}" + text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_quoted: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_posted: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_posted_pm: + subject_template: "[%{site_name}] [PM] %{topic_title}" + text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_posted_pm_staged: + subject_template: "%{optional_re}%{topic_title}" + text_body_template: |2 + + %{message} + + --- + %{respond_instructions} + digest: + why: "Krátky súhrn zo stránky %{site_link} od Vašej poslednej návštevy %{last_seen_at}" + subject_template: "[%{site_name}] Výber" + new_activity: "Nová aktivita na Vašich témach a príspevkoch:" + top_topics: "Populárne príspevky" + other_new_topics: "Populárne témy" + click_here: "kliknite tu" + from: "%{site_name} výber" + read_more: "Čítať viac" + more_topics: "Boli vytvorené %{new_topics_since_seen} ďalšie nové témy." + more_topics_category: "Viac nových tém:" + forgot_password: + subject_template: "[%{site_name}] Obnovenie hesla" + text_body_template: | + Niekto si vyžiadal reset Vášho hesla na [%{site_name}](%{base_url}). + + Ak ste to neboli Vy, môžte ignorovať tento email. + + Pre zmenu hesl kliknite na nasledujúci odkaz + %{base_url}/users/password-reset/%{email_token} + set_password: + subject_template: "[%{site_name}] Nastaviť heslo" + admin_login: + subject_template: "[%{site_name}] Prihlásenie" + account_created: + subject_template: "[%{site_name}] Váš nový účet" + text_body_template: | + Nový účet bol pre Vás vytvorený na %{site_name} + + Kliknite na nasledujúci odkaz pre nastavenie hesla k Vášmu novému účtu: + %{base_url}/users/password-reset/%{email_token} + signup_after_approval: + subject_template: "Váš účet bol schválený na %{site_name}!" + signup: + subject_template: "[%{site_name}] Potvrďte Váš nový účet" + page_not_found: + title: "Stránka neexistuje alebo je privátna." + popular_topics: "Populárne" + recent_topics: "Nedávne" + see_more: "Viac" + search_title: "Prehľadať tieto stránky" + search_google: "Google" + terms_of_service: + title: "Podmienky používania" + signup_form_message: 'Prečítal som si Podmienky používania a súhlasím s nimi.' + deleted: 'vymazané' + upload: + edit_reason: "stiahnuté lokálne kópie obrázkov" + unauthorized: "Ľutujeme, súbor, ktorý sa pokúšate nahrať nemá povolenú príponu (povolené prípony sú: %{authorized_extensions})." + pasted_image_filename: "Vložený obrázok" + store_failure: "Zlyhalo uloženie #%{upload_id} pre užívateľa #%{user_id}." + file_missing: "Ľutujeme, ale musíte poskytnúť súbor na nahranie." + attachments: + too_large: "Ľutujeme, súbor, ktorý sa pokúšate nahrať, je príliš veľký (maximálna veľkosť je %{max_size_kb}KB)." + images: + too_large: "Ľutujeme, obrázok, ktorý sa pokúšate nahrať, je príliš veľký (maximálna veľkosť je %{max_size_kb}KB), prosím zmenšite ho a skúste znovu. " + size_not_found: "Ľutujeme, ale nepodarilo sa nám zistiť veľkosť obrázku. Nie je nahodou poškodený?" + flag_reason: + sockpuppet: "Nový užívateľ vytvoril tému, a iný nový užívateľ odpovedal z tej istej adresy. Pozrite flag_sockpuppets v nastaveniach stránky." + spam_hosts: "Tento nový užívateľ sa pokúsil vytvoriť viacero príspevkov s odkazom na rovnakú doménu. Pozrite newuser_spam_host_threshold v nastaveniach stránky." + email_log: + no_user: "Nepodarilo sa nájsť užívateľa s id %{user_id}" + anonymous_user: "Používateľ je anonymný" + suspended_not_pm: "Užívateľ je suspendovaný, správa nebude poslaná" + seen_recently: "Používateľ bol nedávno online" + post_not_found: "Nepodarilo sa nájsť príspevok s id %{post_id}" + notification_already_read: "Upozornenie o ktorom je tento email už bolo prečítané" + topic_nil: "post.topic je prázdny" + post_deleted: "príspevok bol zmazaný autorom" + user_suspended: "užívateľ bol suspendovaný" + already_read: "používateľ si už prečítal tento príspevok" + message_blank: "správa je prázdna" + message_to_blank: "message.to je prázdne" + text_part_body_blank: "text_part.body je prázdne" + body_blank: "telo je prázdne" + color_schemes: + base_theme_name: "Základ" + about: "O stránke" + guidelines: "Pravidlá" + privacy: "Súkromie" + edit_this_page: "Upraviť túto stránku" + csv_export: + boolean_yes: "Áno" + boolean_no: "Nie" + static_topic_first_reply: |+ + Upravte prvý príspevok v téme pre zmenu obsahu %{page_name} stránky. + + guidelines_topic: + title: "FAQ/Pravidlá" + body: | + + + ## [Toto je miesto pre civilizovanú diskusiu](#civilized) + + Prosíme majte k tejto diskusii rešpekt podobný ako k verejnému parku. My, sme tiež zdieľaný zdroj — miesto na zdieľanie znalostí, vedomostí a záujmov pomocou nepretržitej diskusie. + + Toto nie sú jednoznačné pravidlá, skôr návod ľudskému úsudku naše komunity. Použite tieto pravidlá na udržanie prehľadnú a svetlého miesta pre civilizovanú verejnú diskusiu. + + + + ## [Vylepšujte diskusiu](#improve) + + Pomôžte nám tvoriť toto skvelé miesto akýmkoľvek snahou o zlepšenie diskuzie, stačí drobnosť. Ak nie ste si istý že Váš príspevok posúva diskuziu, premyslite si čo chcete povedať a skúste neskôr. + + Diskutované témy sú nám blízke a chceme, aby ste sa správali tak, akoby Vám boli blízke tiež. Rešpektujte témy a diskutujúcich dokonca i v prípade, ak nesúhlasíte s tým, čo bolo povedané. + + Jedným zo spôsobov ako vylepšiť diskusiu je objavenie tej ktoré už prebieha. Prosíme, venujte trochu času zoznámeniu sa s témami predtým, ako začnete odpovedať alebo začínať svoje vlastné a budete mať vačšiu šancu stretnúť tých, ktorý s Vami zdieľajú záujmy. + + + + ## [Buďte príjemný i keď nesúhlasíte](#agreeable) + + Môžete mať túžbu odpovedať na niečo s čím nesúhlasíte. To je v poriadku. Ale pamätajte _kritizujte myšienky a nie ľudí_. Prosíme, vyvarujte sa: + + * Posmeškom. + * Útokom na konkrétnu osobu. + * Odpovediam na tón príspevku miesto skutočného obsahu. + * Impulzívnym reakciám. + + Namiesto toho poskytnite logické proti argumenty, ktoré zlepšia konverzáciu. + + + + ## [Vaša účasť sa počíta](#participate) + + Konverzácie, ktoré tu máme nastavujú tón pre všetkých. Pomôžte nám ovplyvniť budúcnosť tejto komunity zapojením sa do diskusií ktoré z tohoto fóra robia zaujímavé miesto a vyhýbaním sa tým ktoré to nerobia. + + Discourse poskytuje nástroje, ktoré komunite spoločne umožňujú identifikovať najlepšie (a najhoršie) príspevky, záložky, páči sa mi, značky, odpovede, úpravy a podobne. Použite ich na vylepšenie Vašej skúsenosti i skúsenosti kohokoľvek iného. + + Poďme náš park zanechať v lepšom stave než v akom sme ho našli. + + + + ## [Ak vidíte problém označte ho](#flag-problems) + + Moderátori majú špeciálnu autoritu, sú zodpovedný za fórum. Ale Vy tiež. S Vašou pomocou sa moderátori môžu stať sprostredkovateľmi a nie iba školníkmi alebo políciou. + + Ak vidíte nevhodné chovanie, neodpovedajte. Reakciou naň ho posiľujete, míňate svoju energiu a strácate čas nás všetkých. _Oba ho označte_. Ak sa zíde viačej značiek, budú prijaté opatrenia, či už automatické alebo zásahom moderátora. + + Na správu komunity majú moderátori vyhradené práva na odstránenie akéhokoľvek obsahu a používateľského účtu kedukoľvek z akéhokoľvek dôvodu. Moderátori žiadnym spôsobom nekontrolujú príspevky, moderátori a vlastníci stránky nepreberajú žiadku zodpovednosť za obsah publikovaný komunitou. + + + + ## [Buďte civilizovaný](#be-civil) + + Nič nesabotuje zdravú diskusiu tak ako hrubosť: + + * Buďte zdvorilí, Neuverejňujte nič, čo by múdra osoba považovala za urážlivé, znevažujúce alebo nenávistné. + * Udržujte poriadok. Neuverejnujte nič nemravné alebo explicitne sexuálne. + * Rešpektujte iných. Neprenasledujte alebo nezarmucujte ostatných, nenapodobnujte ľudí, alebo nezverejňujte ich súkromné informácie. + * Rešpektujte naše fórum. Neuverejňujte spam alebo iným spôsobom nevandalizujte fórum. + + Toto nie sú jednoznačné pravidlá s presnými definiciami — vyhnite sa čo i len _náznaku_ akejkoľvek z týchto vecí. Ak nie ste si istý, spýtajte sa, či by Váš príspevok bol zverejnený na hlavnej strane New York Times. + + Toto je verejné fórum a diskusie sú indexované vyhľadávačmi. Udržujte jazyk, odkazy a obrázky bezpečné pre rodinu a priateĺov. + + + + ## [Udržujte poriadok](#keep-tidy) + + Vynaložte snahu dať veci na správne miesto, tak môžeme stráviť viac času diskusiou a menej udržiavaním poriadku. Takže: + + * Nezačínajte tému v nesprávnej kategórií. + * Neuverejňujte rovnaké veci vo viacetých témach. + * Nepublikujte príspevky bez obsahu. + * Nepresmerujte tému zmenou uprostred. + * Nepodpisujte sa — každý príspevok má pripojený odkaz na Váš profil. + + Namiesto poslania “+1” or “Súhlasím”, radšej použite tlačítko Páči sa mi. Namiesto radikálnej zmeny témy v priebehu diskusie radšej odpovedzte spojenou témou. + + + + ## [Uverejňujte iba svoj obsah](#stealing) + + Bez dovolenia nemôžete publikovať nič digitálne, čo patrí niekomu inému. Nemôžete publikovať popis, odkazy alebo metódy na kradnutie niekoho intelektuálneho vlastníctva (softvéru, videa, audia, obrázkov), alebo porušovať akýkoľvek iný zákon. + + + + ## [Založené na Vás](#power) + + Táto stránka je prevádzkovaná [miestnym priateľským personálom](/about) a *Vami*, komunitou. Ak máte akékoľvek ďalšie otázky ako by tu veci mali fungovať, založte novú tému v [kategórií spätná väzba](/c/site-feedback) a poďme diskutovať! Ak ste narazili na kritický alebo urgentný problém ktorý nemôže byť riešený pomocou tém v meta alebo príznakom, kontaktujte nás pomocou [stránky personálu](/about). + + + + ## [Podmienky](#tos) + + Áno, právnický žargón je nudný, ale musíme chrániť seba – tým následne i Vás a vaše dáta – voči nepriateľským ľuďom. Máme [Podmienky](/tos) popisujúce Vaše (a naše ) správanie a práva súvisiace s obsahom, súkromým a legislatívou. K používaniu tejto služby musíte dodžiavať naše [Pravidlá](/tos). + tos_topic: + title: "Podmienky používania" + privacy_topic: + title: "Ochrana súkromia" + admin_login: + success: "Email odoslaný" + error: "Chyba !" + email_input: "Email administrátora" + submit_button: "Poslať email" + discourse_hub: + access_token_problem: "Povedzte administrátorovi: Prosím aktualizujte nastavenia stránky, aby obsahovali správny discourse_org_access_key." + performance_report: + initial_post_raw: Táto téma obsahuje denné reporty rýchlosti Vašich stránok. + initial_topic_title: Reporty rýchlosti stránok + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.sq.yml b/config/locales/server.sq.yml index d3a52c980c2..09361c7070e 100644 --- a/config/locales/server.sq.yml +++ b/config/locales/server.sq.yml @@ -16,12 +16,10 @@ sq: loading: "Loading" powered_by_html: 'Mundësuar nga Discourse, për një eksperience më të mirë aktivizoni JavaScript' log_in: "Identifikohu" - via: "%{username} \tnëpër %{site_name}" - is_reserved: "është i rezervuar" purge_reason: "Automatically deleted as abandoned, unactivated account" disable_remote_images_download_reason: "Remote images download was disabled because there wasn't enough disk space available." anonymous: "Anonim" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "is limited to %{max} characters; you entered %{length}." @@ -91,26 +89,6 @@ sq: replies: one: "1 përgjigje" other: "%{count} përgjigje" - too_many_mentions: - zero: "Na vjen keq, por s'mund të citosh anëtarë të tjerë." - one: "Na vjen keq, you can only mention one other user in a post." - other: "Na vjen keq, you can only mention %{count} users in a post." - too_many_mentions_newuser: - zero: "Sorry, new users can't mention other users." - one: "Na vjen keq, new users can only mention one other user in a post." - other: "Na vjen keq, new users can only mention %{count} users in a post." - too_many_images: - zero: "Na vjen keq, new users can't put images in posts." - one: "Na vjen keq, new users can only put one image in a post." - other: "Na vjen keq, new users can only put %{count} images in a post." - too_many_attachments: - zero: "Na vjen keq, new users can't put attachments in posts." - one: "Na vjen keq, new users can only put one attachment in a post." - other: "Na vjen keq, new users can only put %{count} attachments in a post." - too_many_links: - zero: "Na vjen keq, new users can't put links in posts." - one: "Na vjen keq, new users can only put one link in a post." - other: "Na vjen keq, new users can only put %{count} links in a post." spamming_host: "Na vjen keq, you cannot post a link to that host." user_is_suspended: "Suspended users are not allowed to post." topic_not_found: "Something has gone wrong. Perhaps this topic was closed or deleted while you were looking at it?" @@ -219,9 +197,6 @@ sq: user_profile: bio_raw: "Rreth Meje" errors: - messages: - is_invalid: "is invalid; try to be a little more descriptive" - has_already_been_used: "është përdorur më parë" models: topic: attributes: @@ -242,6 +217,7 @@ sq: attributes: hex: invalid: "nuk është një ngjyrë e vlefshme" + <<: *errors user_profile: no_info_me: "
    the About Me field of your profile is currently blank, would you like to fill it out?
    " no_info_other: "
    %{name} hasn't entered anything in the About Me field of their profile yet
    " @@ -277,13 +253,10 @@ sq: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Rreth kategorisë %{category}" - replace_paragraph: "[Replace this first paragraph with a short description of your new category. This guidance will appear in the category selection area, so try to keep it below 200 characters. Until you edit this text or create topics, this category won't appear on the categories page.]" - post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, as well as to establish any category guidelines or rules.\n\nSome things to consider in any discussion replies below:\n\n- What is this category for? Why should people select this category for their topic?\n\n- How is this different than the other categories we already have?\n\n- Do we need this category?\n\n- Should we merge this with another category, or split it into more categories?\n" errors: uncategorized_parent: "Uncategorized can't have a parent category" self_parent: "A subcategory's parent cannot be itself" depth: "You can't nest a subcategory under another" - email_in_already_exist: "Incoming email address '%{email_in}' is already in use for '%{category_name}' category." cannot_delete: uncategorized: "Can't delete Uncategorized" has_subcategories: "Can't delete this category because it has sub-categories." @@ -296,15 +269,8 @@ sq: title: "anëtar i ri" basic: title: "anëtar basic" - regular: - title: "anëtarë" - leader: - title: "i rregullt" - elder: - title: "udhëheqës" change_failed_explanation: "You attempted to demote %{user_name} to '%{new_trust_level}'. However their trust level is already '%{current_trust_level}'. %{user_name} will remain at '%{current_trust_level}' - if you wish to demote user lock trust level first" rate_limiter: - slow_down: "You have performed this action too many times, try again later" too_many_requests: "We have a daily limit on how many times that action can be taken. Please wait %{time_left} before trying again." hours: one: "1 hour" @@ -423,16 +389,11 @@ sq: description: 'This post contains content that a reasonable person would consider offensive, abusive, or a violation of our community guidelines.' long_form: 'flagged this as inappropriate' notify_user: - title: 'Mezazh @{{username}}' - description: 'This post contains something I want to talk to this person directly and privately about. Does not cast a flag.' long_form: 'messaged user' email_title: 'Postimi juaj në "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Diçka tjetër" - description: 'This post requires moderator attention for another reason not listed above.' - long_form: 'shënoje për vëmendjen e moderatorëve' - email_title: 'A post in "%{title}" requires moderator attention' email_body: "%{link}\n\n%{message}" bookmark: title: 'Bookmark' @@ -457,7 +418,6 @@ sq: long_form: 'flagged this as inappropriate' notify_moderators: title: "Diçka Tjetër" - description: 'This topic requires general moderator attention based on the guidelines, TOS, or for another reason not listed above.' long_form: 'shënoje për vëmendjen e moderatorëve' email_title: 'The topic "%{title}" requires moderator attention' email_body: "%{link}\n\n%{message}" @@ -643,37 +603,6 @@ sq: consumer_email_warning: "Your site is configured to use Gmail (or another consumer email service) to send email. Gmail limits how many emails you can send. Consider using an email service provider like mandrill.com to ensure email deliverability." site_contact_username_warning: "Enter the name of a friendly staff user account to send important automated messages from. Update site_contact_username in Site Settings." notification_email_warning: "Notification emails are not being sent from a valid email address on your domain; email delivery will be erratic and unreliable. Please set notification_email to a valid local email address in Site Settings." - content_types: - education_new_reply: - title: "New User Education: First Replies" - description: "Pop up just-in-time guidance automatically displayed above the composer when new users begin typing their first two new replies." - education_new_topic: - title: "New User Education: First Topics" - description: "Pop up just-in-time guidance automatically displayed above the composer when new users begin typing their first two new topics." - usage_tips: - title: "New User Guidance" - description: "Guidance and essential information for new users." - welcome_user: - title: "Welcome: New User" - description: "A message automatically sent to all new users when they sign up." - welcome_invite: - title: "Welcome: Invited User" - description: "A message automatically sent to all new invited users when they accept the invitation from another user to participate." - login_required_welcome_message: - title: "Login Required: Welcome Message" - description: "Welcome message that is displayed to logged out users when the 'login required' setting is enabled." - login_required: - title: "Login Required: Homepage" - description: "The text displayed for unauthorized users when login is required on the site." - head: - title: "HTML head" - description: "HTML that will be inserted inside the tags." - top: - title: "Top of the pages" - description: "HTML that will be added at the top of every page (after the header, before the navigation or the topic title)." - bottom: - title: "Bottom of the pages" - description: "HTML that will be added before the tag." site_settings: censored_words: "Fjalët do të zhvendosen automatikisht me ■■■■" delete_old_hidden_posts: "Auto-delete any hidden posts that stay hidden for more than 30 days." @@ -688,7 +617,6 @@ sq: min_private_message_title_length: "Minimum allowed title length for a message in characters" min_search_term_length: "Minimum valid search term length in characters" allow_uncategorized_topics: "Allow topics to be created without a category. WARNING: If there are any uncategorized topics, you must recategorize them before turning this off." - uncategorized_description: "The description of the uncategorized category. Leave blank for no description." allow_duplicate_topic_titles: "Allow topics with identical, duplicate titles." unique_posts_mins: "How many minutes before a user can make a post with the same content again" educate_until_posts: "When the user starts typing their first (n) new posts, show the pop-up new user education panel in the composer." @@ -701,7 +629,6 @@ sq: download_remote_images_to_local: "Convert remote images to local images by downloading them; this prevents broken images." download_remote_images_threshold: "Minimum disk space necessary to download remote images locally (in percent)" disabled_image_download_domains: "Remote images will never be downloaded from these domains. Pipe-delimited list." - ninja_edit_window: "For (n) seconds after posting, editing will not create a new version in the post history." post_edit_time_limit: "The author can edit or delete their post for (n) minutes after posting. Set to 0 for forever." edit_history_visible_to_public: "Allow everyone to see previous versions of an edited post. When disabled, only staff members can view." delete_removed_posts_after: "Posts removed by the author will be automatically deleted after (n) hours. If set to 0, posts will be deleted immediately." @@ -730,7 +657,6 @@ sq: summary_likes_required: "Minimum likes in a topic before 'Summarize This Topic' is enabled" summary_percent_filter: "When a user clicks 'Summarize This Topic', show the top % of posts" summary_max_results: "Maximum posts returned by 'Summary This Topic'" - enable_private_messages: "Allow trust level 1 users to create messages and reply to messages" enable_long_polling: "Message bus used for notification can use long polling" long_polling_base_url: "Base URL used for long polling (when a CDN is serving dynamic content, be sure to set this to origin pull) eg: http://origin.site.com" long_polling_interval: "Amount of time the server should wait before responding to clients when there is no data to send (logged on users only)" @@ -770,7 +696,6 @@ sq: suppress_reply_directly_above: "Don't show the expandable in-reply-to on a post when there is only a single reply directly above this post." suppress_reply_when_quoting: "Don't show the expandable in-reply-to on a post when post quotes reply." max_reply_history: "Maximum number of replies to expand when expanding in-reply-to" - experimental_reply_expansion: "Hide intermediate replies when expanding a reply to (experimental)" topics_per_period_in_top_summary: "Number of top topics shown in the default top topics summary." topics_per_period_in_top_page: "Number of top topics shown on the expanded 'Show More' top topics." redirect_users_to_top_page: "Automatically redirect new and long absent users to the top page." @@ -865,16 +790,9 @@ sq: tl2_requires_likes_received: "How many likes a user must receive before promotion to trust level 2." tl2_requires_likes_given: "How many likes a user must cast before promotion to trust level 2." tl2_requires_topic_reply_count: "How many topics user must reply to before promotion to trust level 2." - tl3_requires_days_visited: "Minimum number of days that a user needs to have visited the site in the last 100 days to qualify for promotion to trust level 3. (0 to 100)" - tl3_requires_topics_replied_to: "Minimum number of topics a user needs to have replied to in the last 100 days to qualify for promotion to trust level 3. (0 or higher)" - tl3_requires_topics_viewed: "The percentage of topics created in the last 100 days that a user needs to have viewed to qualify for promotion to trust level 3. (0 to 100)" - tl3_requires_posts_read: "The percentage of posts created in the last 100 days that a user needs to have viewed to qualify for promotion to trust level 3. (0 to 100)" tl3_requires_topics_viewed_all_time: "The minimum total number of topics a user must have viewed to qualify for trust level 3." tl3_requires_posts_read_all_time: "The minimum total number of posts a user must have read to qualify for trust level 3." - tl3_requires_max_flagged: "User must not have had more than x posts flagged by x different users in the last 100 days to qualify for promotion to trust level 3, where x is this setting's value. (0 or higher)" tl3_promotion_min_duration: "The minimum number of days that a promotion to trust level 3 lasts before a user can be demoted back to trust level 2." - tl3_requires_likes_given: "The minimum number of likes that must be given in the last 100 days to qualify for promotion to trust level 3." - tl3_requires_likes_received: "The minimum number of likes that must be received in the last 100 days to qualify for promotion to trust level 3." tl3_links_no_follow: "Do not remove rel=nofollow from links posted by trust level 3 users." min_trust_to_create_topic: "The minimum trust level required to create a new topic." min_trust_to_edit_wiki_post: "The minimum trust level required to edit post marked as wiki." @@ -962,7 +880,6 @@ sq: automatically_download_gravatars: "Download Gravatars for users upon account creation or email change." digest_topics: "The maximum number of topics to display in the email digest." digest_min_excerpt_length: "Minimum post excerpt in the email digest, in characters." - suppress_digest_email_after_days: "Suppress digest emails for users not seen on the site for more than (n) days." disable_digest_emails: "Disable digest emails for all users." detect_custom_avatars: "Whether or not to check that users have uploaded custom profile pictures." max_daily_gravatar_crawls: "Maximum number of times Discourse will check Gravatar for custom avatars in a day" @@ -973,12 +890,10 @@ sq: anonymous_posting_min_trust_level: "Minimum trust level required to enable anonymous posting" anonymous_account_duration_minutes: "To protect anonymity create a new anonymous account every N minutes for each user. Example: if set to 600, as soon as 600 minutes elapse from last post AND user switches to anon, a new anonymous account is created." allow_profile_backgrounds: "Allow users to upload profile backgrounds." - sequential_replies_threshold: "Number posts a user has to make in a row in a topic before being reminded about too many sequential replies. " enable_mobile_theme: "Mobile devices use a mobile-friendly theme, with the ability to switch to the full site. Disable this if you want to use a custom stylesheet that is fully responsive." dominating_topic_minimum_percent: "What percentage of posts a user has to make in a topic before being reminded about overly dominating a topic." daily_performance_report: "Analyze NGINX logs daily and post a Staff Only topic with details" suppress_uncategorized_badge: "Don't show the badge for uncategorized topics in topic lists." - permalink_normalizations: "Apply the following regex before matching permalinks, for example: /(\\/topic.*)\\?.*/\\1 will strip query strings from topic routes. Format is regex+string use \\1 etc. to access captures" global_notice: "Display an URGENT, EMERGENCY global banner notice to all visitors, change to blank to hide it (HTML allowed)." disable_edit_notifications: "Disables edit notifications by the system user when 'download_remote_images_to_local' is active." full_name_required: "Full name is a required field of a user's profile." @@ -1003,13 +918,11 @@ sq: enable_cdn_js_debugging: "Allow /logs to display proper errors by adding crossorigin permissions on all js includes." show_create_topics_notice: "If the site has fewer than 5 public topics, show a notice asking admins to create some topics." delete_drafts_older_than_n_days: Delete drafts older than (n) days. - vacuum_db_days: "Run VACUUM FULL ANALYZE to reclaim DB space after migrations (set to 0 to disable)" prevent_anons_from_downloading_files: "Prevent anonymous users from downloading attachments. WARNING: this will prevent any non-image site assets posted as attachments from working." slug_generation_method: "Choose a slug generation method. 'encoded' will generate percent encoding string. 'none' will disable slug at all." enable_emoji: "Enable emoji" emoji_set: "How would you like your emoji?" enforce_square_emoji: "Force a square aspect ratio to all emojis." - approve_post_count: "The amount of posts from a new user that must be approved" approve_unless_trust_level: "Posts for users below this trust level must be approved" notify_about_queued_posts_after: "If there are posts that have been waiting to be reviewed for more than this many hours, an email will be sent to the contact email. Set to 0 to disable these emails." errors: @@ -1036,7 +949,6 @@ sq: moved_post: "%{display_username} moved your post to %{link}" private_message: "%{display_username} sent you a message: %{link}" invited_to_private_message: "%{display_username} invited you to a message: %{link}" - invited_to_topic: "%{display_username} invited you to a topic: %{link}" invitee_accepted: "%{display_username} accepted your invitation" linked: "%{display_username} linked you in %{link}" granted_badge: "You earned %{link}" @@ -1046,11 +958,6 @@ sq: category: 'Categories' topic: 'Results' user: 'Users' - sso: - not_found: "Unable to lookup or create account, contact site admin" - account_not_approved: "Account is pending approval, you will receive an email notification once approved" - unknown_error: "Error updating information, contact site admin" - timeout_expired: "Account login timed out, please try logging in again" original_poster: "Original Poster" most_posts: "Most Posts" most_recent_poster: "Most Recent Poster" @@ -1139,6 +1046,10 @@ sq: ip_address: blocked: "New registrations are not allowed from your IP address." max_new_accounts_per_registration_ip: "New registrations are not allowed from your IP address (maximum limit reached). Contact a staff member." + flags_reminder: + subject_template: + one: "1 flag waiting to be handled" + other: "%{count} flags waiting to be handled" invite_mailer: subject_template: "%{invitee_name} invited you to '%{topic_title}' on %{site_domain_name}" text_body_template: | @@ -1182,87 +1093,10 @@ sq: (If the link above has expired, choose "I forgot my password" when logging in with your email address.) test_mailer: subject_template: "[%{site_name}] Email Deliverability Test" - text_body_template: | - This is a test email from - - [**%{base_url}**][0] - - Email deliverability is complicated. Here are a few important things you should check first: - - - Be *sure* to set the `notification email` from: address correctly in your site settings. **The domain specified in the "from" address of the emails you send is the domain your email will be validated against**. - - - Know how to view the raw source of the email in your mail client, so you can examine email headers for important clues. in Gmail, it is the "show original" option in the drop-down menu at the top right of each mail. - - - **IMPORTANT:** Does your ISP have a reverse DNS record entered to associate the domain names and IP addresses you send mail from? [Test your Reverse PTR record][2] here. If your ISP does not enter the proper reverse DNS pointer record, it's very unlikely any of your email will be delivered. - - - Is your domain's [SPF record][8] correct? [Test your SPF record][1] here. Note that TXT is the correct official record type for SPF. - - - Is your domain's [DKIM record][3] correct? This will significantly improve email deliverability. [Test your DKIM record][7] here. - - - If you run your own mail server, check to make sure the IPs of your mail server are [not on any email blacklists][4]. Also verify that it is definitely sending a fully-qualified hostname that resolves in DNS in its HELO message. If not, this will cause your email to be rejected by many mail services. - - (The *easy* way is to create a free account on [Mandrill][md] or [Mailgun][mg] or [Mailjet][mj], which have free generous free mailing plans and will be fine for small communities. You'll still need to set up the SPF and DKIM records in your DNS, though!) - - We hope you received this email deliverability test OK! - - Good luck, - - Your friends at [Discourse](http://www.discourse.org) - - [0]: %{base_url} - [1]: http://www.kitterman.com/spf/validate.html - [2]: http://mxtoolbox.com/ReverseLookup.aspx - [3]: http://www.dkim.org/ - [4]: http://whatismyipaddress.com/blacklist-check - [7]: http://dkimcore.org/tools/dkimrecordcheck.html - [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com - [mg]: http://www.mailgun.com/ - [mj]: https://www.mailjet.com/pricing new_version_mailer: subject_template: "[%{site_name}] verion i ri i Discourse, përditësoje!" - text_body_template: | - A new version of [Discourse](http://www.discourse.org) is available. - - Your version: %{installed_version} - New version: **%{new_version}** - - You may want to: - - - See what's new in the [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - Upgrade from your browser at [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Visit [meta.discourse.org](http://meta.discourse.org) for news, discussion, and support for Discourse. new_version_mailer_with_notes: subject_template: "[%{site_name}] ka perditesime" - text_body_template: | - A new version of [Discourse](http://www.discourse.org) is available. - - Your version: %{installed_version} - New version: **%{new_version}** - - You may want to: - - - See what's new in the [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - Upgrade from your browser at [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Visit [meta.discourse.org](http://meta.discourse.org) for news, discussion, and support for Discourse. - - ### Release notes - - %{notes} - flags_reminder: - flags_were_submitted: - one: "These flags were submitted over 1 hour ago." - other: "These flags were submitted over %{count} hours ago." - please_review: "Please review them." - post_number: "postim" - how_to_disable: 'You can disable or change the frequency of this email reminder via the "notify about flags after" setting.' - subject_template: - one: "1 flag waiting to be handled" - other: "%{count} flags waiting to be handled" queued_posts_reminder: subject_template: one: "[%{site_name}] 1 post waiting to be reviewed" @@ -1300,91 +1134,6 @@ sq: However, if the post is hidden by the community a second time, it will remain hidden until handled by staff – and there may be further action, including the possible suspension of your account. For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines). - usage_tips: - text_body_template: | - Here are a few quick tips to get you started: - - ## Reading - - To read more, **just keep scrolling down!** - - As new replies or new topics arrive, they will appear automatically – no need to refresh the page. - - ## Navigation - - - For search, your user page, or the menu, use the **icon buttons at upper right**. - - - Selecting a topic title will always take you to the **next unread reply** in the topic. To enter at the top or bottom, select the reply count or last reply date instead. - - - - - While reading a topic, select the progress bar at the bottom right for full navigation controls. Quickly jump back to the top by selecting the topic title. Press ? for a list of super-speedy keyboard shortcuts. - - - - ## Replying - - - To reply to the **topic in general**, use at the very bottom of the topic. - - - To reply to a **specific person**, use on their post. - - - To reply with **a new topic**, use to the right of the post. Both old and new topics will be automatically linked together. - - To insert a quote, select the text you wish to quote, then press any Reply button. Repeat for multiple quotes! - - - - To notify someone about your reply, mention their name. Type `@` to begin selecting a username. - - - - To use [standard Emoji](http://www.emoji.codes/), just type `:` to match by name, or use the traditional smileys `;)` - - - - To generate a summary for a link, paste it on a line by itself: - - - - ## Actions - - There are action buttons at the bottom of each post: - - - - To let someone know that you enjoyed and appreciated their post, use the **like** button. Share the love! - - If you see a problem with someone's post, privately let them, or [our staff](%{base_url}/about), know about it with the **flag** button. You can also **share** a link to a post, or **bookmark** it for later reference on your user page. - - ## Notifications - - When someone replies to you, quotes your post, or mentions your `@username`, a number will immediately appear at the top right of the page. Use it to access your **notifications**. - - - - Don't worry about missing a reply – you'll be emailed any notifications that arrive when you are away. - - ## Your Preferences - - - All topics less than **two days old** are considered new. - - - Any topic you've **actively participated in** (by creating, replying, or reading for an extended period) will be automatically tracked. - - You will see the blue new and unread number indicators next to these topics: - - - - You can change your notifications for any topic via the notification control at the bottom of the topic. - - - - You can also set notification state per category, if you want to watch every new topic in a specific category. - - To change any of these settings, see [your user preferences](%{base_url}/my/preferences). - - ## Community Trust - - As you participate here, over time you'll gain the trust of the community, become a full citizen, and new user limitations will be lifted. At a high enough [trust level](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), you'll gain new abilities to help us manage our community together. welcome_user: subject_template: "Mirë se vini tek %{site_name}!" text_body_template: | @@ -1469,18 +1218,8 @@ sq: csv_export_failed: subject_template: "Data export failed" text_body_template: "We're sorry, but your data export failed. Please check the logs or contact a staff member." - email_reject_trust_level: - subject_template: "[%{site_name}] Email issue -- Insufficient Trust Level" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - Your account does not have the required trust level to post new topics to this email address. If you believe this is in error, contact a staff member. email_reject_no_account: subject_template: "[%{site_name}] Email issue -- Unknown Account" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - There is no known user account with this email address. Try sending from a different email address, or contact a staff member. email_reject_empty: subject_template: "[%{site_name}] Email issue -- No Content" email_reject_parsing: @@ -1495,40 +1234,10 @@ sq: We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. Your account does not have the privileges to post new topics in that category. If you believe this is in error, contact a staff member. - email_reject_post_error: - subject_template: "[%{site_name}] Email issue -- Posting error" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - Some possible causes are: complex formatting, message too large, message too small. Please try again, or post via the website if this continues. - email_reject_post_error_specified: - subject_template: "[%{site_name}] Email issue -- Posting error" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - Reason: - - %{post_error} - - If you can correct the problem, please try again. email_reject_reply_key: subject_template: "[%{site_name}] Email issue -- Unknown Reply Key" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - The provided reply key is invalid or unknown, so we don't know what this email is in reply to. Contact a staff member. - email_reject_destination: - subject_template: "[%{site_name}] Email issue -- Unknown To: Address" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - None of the destination addresses are recognized. Please make sure that the site address is in the To: line (not Cc: or Bcc:), and that you are sending to the correct email address provided by staff. email_reject_topic_not_found: subject_template: "[%{site_name}] Email issue -- Topic Not Found" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - The topic you are replying to no longer exists, perhaps it was deleted? If you believe this is in error, contact a staff member. email_reject_topic_closed: subject_template: "[%{site_name}] Email issue -- Topic Closed" text_body_template: | @@ -1537,16 +1246,8 @@ sq: The topic you are replying to is currently closed and no longer accepting replies. If you believe this is in error, contact a staff member. email_reject_auto_generated: subject_template: "[%{site_name}] Email issue -- Auto Generated Reply" - text_body_template: | - We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work. - - Your email was marked as "auto generated", which we can't accept. If you believe this is in error, contact a staff member. email_error_notification: subject_template: "[%{site_name}] Email issue -- POP authentication error" - text_body_template: | - There has been an authentication error while polling mails from the POP server. - - Please make sure you have properly configured the POP credentials in [the site settings](%{base_url}/admin/site_settings/category/email). too_many_spam_flags: subject_template: "New account blocked" text_body_template: | @@ -1559,32 +1260,10 @@ sq: For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines). blocked_by_staff: subject_template: "Account blocked" - text_body_template: | - Hello, - - This is an automated message from %{site_name} to inform you that your account has been blocked by a staff member. - - For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines). user_automatically_blocked: subject_template: "New user %{username} blocked due to community flags" - text_body_template: | - This is an automated message. - - The new user [%{username}](%{base_url}%{user_url}) was automatically blocked because multiple users flagged %{username}'s post(s). - - Please [review the flags](%{base_url}/admin/flags). If %{username} was incorrectly blocked from posting, click the unblock button on [the admin page for this user](%{base_url}%{user_url}). - - This threshold can be changed via the `block_new_user` site settings. spam_post_blocked: subject_template: "New user %{username} posts blocked due to repeated links" - text_body_template: | - This is an automated message. - - The new user [%{username}](%{base_url}%{user_url}) tried to create multiple posts with links to %{domains}, but those posts were blocked to avoid spam. The user is still able to create new posts that do not link to %{domains}. - - Please [review the user](%{base_url}%{user_url}). - - This can be modified via the `newuser_spam_host_threshold` and `white_listed_spam_host_domains` site settings. unblocked: subject_template: "Account unblocked" text_body_template: | @@ -1611,84 +1290,19 @@ sq: unsubscribe: title: "Unsubscribe" description: "Not interested in getting these emails? No problem! Click below to unsubscribe instantly:" - reply_by_email: "To respond, reply to this email or visit %{base_url}%{url} in your browser." - visit_link_to_respond: "To respond, visit %{base_url}%{url} in your browser." posted_by: "Posted by %{username} on %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} invited you to a message '%{topic_title}'" - text_body_template: |2 - - %{username} invited you to a message - - > **%{topic_title}** - > - > %{topic_excerpt} - - at - - > %{site_title} -- %{site_description} - - Please visit this link to view the message: %{base_url}%{url} - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} invited you to a topic '%{topic_title}'" - text_body_template: |2 - - %{username} invited you to a discussion - - > **%{topic_title}** - > - > %{topic_excerpt} - - at - - > %{site_title} -- %{site_description} - - Please visit this link to view the message: %{base_url}%{url} user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "A brief summary of %{site_link} since your last visit on %{last_seen_at}" subject_template: "[%{site_name}] Digest" @@ -1735,12 +1349,6 @@ sq: Click the following link to choose a password for your new account: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Confirm your new email address" - text_body_template: | - Confirm your new email address for %{site_name} by clicking on the following link: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "You've been approved on %{site_name}!" text_body_template: | @@ -1770,7 +1378,6 @@ sq: If the above link is not clickable, try copying and pasting it into the address bar of your web browser. page_not_found: - title: "The page you requested doesn't exist or is private." popular_topics: "Popular" recent_topics: "Recent" see_more: "More" @@ -2062,57 +1669,6 @@ sq: Originally adapted from the [WordPress Terms of Service](http://en.wordpress.com/tos/). privacy_topic: title: "Politika e Privatësisë" - badges: - long_descriptions: - autobiographer: | - This badge is granted for filling out your user profile and selecting a profile picture. Letting the community know more about who you are and what you're interested in makes for a better, more connected community. - first_like: | - This badge is granted the first time you like a post using the :heart: button. Liking posts is a great way to let your fellow community members know that what they posted was interesting, useful, cool, or fun. Share the love! - first_link: | - This badge is granted the first time you place a link to another topic in a reply. Linking topics helps fellow readers find interesting related conversations, by showing connections between topics in both directions. - first_quote: | - This badge is granted the first time you quote a post in your reply. Quoting relevant sections of earlier posts in your reply helps keep discussions focused and on topic. - first_share: | - This badge is granted the first time you share a link to a reply or topic using the share button. Sharing links is a great way to show off interesting discussions with the rest of the world and grow your community. - read_guidelines: | - This badge is granted for reading the community guidelines. Following and sharing these simple guidelines helps build a safe, fun, and sustainable community. - reader: | - This badge is granted for reading a long topic. Reading is fundamental. Reading closely helps you follow the conversation and leads to better, more complete replies. - editor: | - This badge is granted for editing your post. Don't hesitate to edit your posts any time to improve them, fix small mistakes, or add anything you forgot. - first_flag: | - This badge is granted for flagging a post. Flagging is critical to the health of your community. If you notice any posts that require moderator attention please - do not hesitate to flag. You may also use the flagging dialog to send messages to fellow users. - nice_share: | - This badge is granted for sharing a link to a post that's visited by 25 outside visitors. Nice job! Sharing links to interesting discussions with friends is an excellent way to grow our community. - welcome: | - This badge is granted when you receive your first like on a post. Congratulations, you've posted something that your fellow community members found interesting, cool, or useful! - anniversary: | - This badge is granted when you've been a member for a year with at least one post in that year. Thanks for sticking around and contributing to our community! - good_share: | - This badge is granted for sharing a link to a post that's visited by 300 outside visitors. Good work! You've shown off an interesting discussion to a lot of new people and helped us grow. - great_share: | - This badge is granted for sharing a link to a post that's visited by 100 outside visitors. Wow! You've promoted an interesting discussion to a huge new audience for this community, and helped us grow in a big way. - nice_post: | - This badge is granted for creating a reply that gets 10 likes. Nice job! - nice_topic: | - This badge is granted for creating a topic that gets 10 likes. Nice job! - good_post: | - This badge is granted for creating a reply that gets 25 likes. Good work! - good_topic: | - This badge is granted for creating a topic that gets 25 likes. Good work! - great_post: | - This badge is granted for creating a post that gets 50 likes. Wow! - great_topic: | - This badge is granted for creating a reply that gets 50 likes. Wow! - basic: | - This badge is granted when you reach trust level 1. Thanks for sticking around a little while and reading a few topics to learn what our community is about. Your new user restrictions have been lifted, and you've been granted all essential community abilities, such as personal messaging, flagging, wiki editing, and the ability to post images and multiple links. - member: | - This badge is granted when you reach trust level 2. Thanks for participating over a period of weeks to more join our community. You can now send personal invitations from your user page or individual topics, create group messages, and a few more likes per day. - regular: | - This badge is granted when you reach trust level 3. Thanks for being a regular part of our community over a period of months, one of the most active readers and a reliable contributor to what makes this community great. You can now recategorize and rename topics, access a private lounge area, more powerful spam flags, and lots more likes per day. - leader: | - This badge is granted when you reach trust level 4. You're a leader in this community as selected by staff, and set a positive example for the community in your deeds and words. You have the ability to edit all posts, take topic moderator actions such as pin, close, unlist, archive, split, and merge, and tons of likes per day. admin_login: success: "Email Sent" error: "Error!" @@ -2123,3 +1679,6 @@ sq: performance_report: initial_post_raw: This topic includes daily performance reports for your site. initial_topic_title: Raportet e performancës se faqes + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.sv.yml b/config/locales/server.sv.yml index 28d96fba602..2648fa087eb 100644 --- a/config/locales/server.sv.yml +++ b/config/locales/server.sv.yml @@ -10,18 +10,24 @@ sv: short_date_no_year: "D MMM" short_date: "D MMM, YYYY" long_date: "MMMM D, YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%m-%d-%Y" + short_no_year: "%B %-d" + date_only: "%B %-d, %Y" + date: + month_names: [null, Januari, Februari, Mars, April, Maj, Juni, Juli, Augusti, September, Oktober, November, December] + <<: *datetime_formats title: "Discourse" topics: "Ämnen" posts: "inlägg" loading: "Laddar" powered_by_html: 'Drivs av Discourse, visas bäst med JavaScript påslaget' log_in: "Logga in" - via: "%{username} via %{site_name}" - is_reserved: "är reserverat" purge_reason: "Automatiskt raderat i och med att kontot var övergivet och icke-aktiverat" disable_remote_images_download_reason: "Fjärrbilds nedladdning är inaktiverad eftersom det inte fanns tillräckligt mycket lagringsutrymme tillgängligt." anonymous: "Anonym" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "är begränsad till %{max} karaktärer; du skrev in %{length}. " @@ -37,8 +43,10 @@ sv: exclusion: är reserverad greater_than: måste vara större än %{count} greater_than_or_equal_to: måste vara större eller lika med %{count} + has_already_been_used: "har redan använts" inclusion: är inte inkluderad i listan invalid: är ogiltig + is_invalid: "är ogiltig; försök att skriva lite mer detaljerad" less_than: måste vara mindre än %{count} less_than_or_equal_to: måste vara mindre eller lika med %{count} not_a_number: är inte ett nummer @@ -62,6 +70,9 @@ sv: other: '%{count} stycken fel förhindrade %{model} från att sparas' embed: load_from_remote: "Det uppstod ett fel vid laddning av artikeln." + site_settings: + min_username_length_range: "Du kan inte sätta minimum högre än maximum" + s3_upload_bucket_is_required: "Du kan inte aktivera uppladdning till S3 innan du har angivit 's3_upload_bucket'." bulk_invite: file_should_be_csv: "Den uppladdade filen ska vara i csv eller txt format." backup: @@ -72,6 +83,7 @@ sv: not_found: "Den efterfrågade URL:en eller resursen kan inte hittas." invalid_access: "Du har inte behörighet att visa den efterfrågade resursen." read_only_mode_enabled: "Webbplatsen är i read only läge. Interaktioner är inaktiverade." + reading_time: "Lästid" too_many_replies: one: "Vi är ledsna men nya användare är tillfälligt begränsade till 1 svar i samma diskussion." other: "Vi är ledsna men nya användare är tillfälligt begränsade till &{count} svar i samma ämne." @@ -88,33 +100,21 @@ sv: replies: one: "1 svar" other: "%{count} svar" - too_many_mentions: - zero: "Tyvärr, du kan inte omnämna andra användare." - one: "Tyvärr, du kan bara omnämna en annan användare i ett inlägg." - other: "Tyvärr, du kan bara omnämna %{count} användare i ett inlägg." - too_many_mentions_newuser: - zero: "Tyvärr, besökare kan inte omnämna andra användare." - one: "Tyvärr, besökare kan bara omnämna en annan användare i ett inlägg." - other: "Tyvärr, besökare kan bara omnämna %{count} användare i ett inlägg." + no_images_allowed: "Tyvärr, nya användare kan inte infoga bilder i inlägg." too_many_images: - zero: "Tyvärr, besökare kan inte ha bilder i inlägg." - one: "Tyvärr, besökare kan bara ha en bild i ett inlägg." - other: "Tyvärr, besökare kan bara ha %{count} bilder i ett inlägg." + one: "Tyvärr, nya användare kan bara infoga en bild i ett inlägg." + other: "Tyvärr, nya användare kan bara infoga %{count} bilder i ett inlägg." + no_attachments_allowed: "Tyvärr, nya användare kan inte bifoga filer i inlägg." too_many_attachments: - zero: "Tyvärr, nya användare kan inte bifoga filer i inlägg." - one: "Tyvärr, nya användare kan bara bifoga en fil i ett inlägg." - other: "Tyvärr, nya användare kan bara lägga till %{count} bifogade filer i ett inlägg." - too_many_links: - zero: "Tyvärr, besökare kan inte ha länkar i inlägg." - one: "Tyvärr, besökare kan bara ha en länk i ett inlägg." - other: "Tyvärr, besökare kan bara ha %{count} länkar i ett inlägg." + one: "Tyvärr, nya användare kan bara bifoga en filer i ett inlägg." + other: "Tyvärr, nya användare kan bara bifoga %{count} filer i ett inlägg." spamming_host: "Tyvärr, du kan inte posta en länk till det värdnamnet." user_is_suspended: "Avstängda användare är inte tillåtna att göra inlägg" topic_not_found: "Något har gått fel. Kanske ämnet stängts eller raderats medan du tittade på det?" just_posted_that: "är för likt det du nyligen postade" has_already_been_used: "har redan använts" invalid_characters: "innehåller otillåtna tecken" - is_invalid: "är otillåtet; försök att vara lite mer beskrivande" + is_invalid: "är ogiltig; försök att skriva lite mer detaljerad" next_page: "nästa sida →" prev_page: "← föregående sida" page_num: "Sida %{num}" @@ -126,6 +126,7 @@ sv: num_posts: "Inlägg:" num_participants: "Deltagare" read_full_topic: "Läs hela ämnet" + private_message_abbrev: "Meddelande" rss_description: latest: "Aktuella ämnen" hot: "Heta ämnen" @@ -207,9 +208,6 @@ sv: user_profile: bio_raw: "Om mig" errors: - messages: - is_invalid: "är ogiltig; försök att vara lite mer beskrivande" - has_already_been_used: "har redan använts" models: topic: attributes: @@ -230,6 +228,7 @@ sv: attributes: hex: invalid: "är inte en giltig färg" + <<: *errors user_profile: no_info_me: "
    Din profils Om Mig-fält är för närvarande tomt, skulle du vilja fylla i det?
    " no_info_other: "
    %{name} har inte skrivit någonting i dess profils Om Mig-fält ännu
    " @@ -243,7 +242,6 @@ sv: title: "Välkommen till loungen" category: topic_prefix: "Om kategorin %{category}" - post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, as well as to establish any category guidelines or rules.\n\nSome things to consider in any discussion replies below:\n\n- What is this category for? Why should people select this category for their topic?\n\n- How is this different than the other categories we already have?\n\n- Do we need this category?\n\n- Should we merge this with another category, or split it into more categories?\n" errors: uncategorized_parent: "Kategorin \"Okategoriserat\" kan inte ha en föräldrar kategori." self_parent: "En underkategori kan inte ha sig själv som förälder." @@ -260,15 +258,15 @@ sv: title: "besökare" basic: title: "vanlig användare" - regular: + member: title: "medlem" - leader: + regular: title: "vanlig" - elder: + leader: title: "ledare" change_failed_explanation: "Du försökte degradera %{user_name} till '%{new_trust_level}'. Användarens förtroendenivå är redan '%{current_trust_level}'. %{user_name} kommer behålla '%{current_trust_level}'. Om du vill degradera användaren, lås förtroendenivån först" rate_limiter: - slow_down: "Du har utfört den här handlingen för många gånger, var vänligen och försök igen senare." + slow_down: "Du har utfört den här handlingen för många gånger, försök igen senare." too_many_requests: "Du gör det där för ofta. Var god vänta %{time_left} innan du försöker igen." hours: one: "1 timme" @@ -364,6 +362,7 @@ sv: please_continue: "Fortsätt till %{site_name}" error: "Det uppstod ett fel med ändringen av din e-postadress. Adressen kanske redan används?" activation: + action: "Klicka här för att aktivera ditt konto" already_done: "Tyvärr, denna kontoaktiveringslänk är inte längre giltig. Kanske är ditt konto redan aktiverat?" please_continue: "Ditt nya konto är verifierat; du kommer att skickas till startsidan." continue_button: "Fortsätt till %{site_name}" @@ -386,15 +385,10 @@ sv: description: 'Detta inläggs innehåll är inkluderar saker som som en förnuftig person skulle betrakta som stötande, kränkande eller överträdelse av våra community riktlinjerr.' long_form: 'flagga detta som olämpligt' notify_user: - title: 'Meddela @{{username}}' - description: 'Detta inlägg innehåller något som jag, direkt och privat, vill tala med denna person om. Detta ger ingen flagga.' email_title: 'Du postade i "%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Övrigt" - description: 'Detta inlägg kräver en moderators uppmärksamhet av ett annat skäl än de som nämns ovan.' - long_form: 'flaggade det här för granskning av moderator' - email_title: 'Ett inlägg i "%{title}" kräver uppmärksamhet från en moderator' email_body: "%{link}\n\n%{message}" bookmark: title: 'Bokmärk' @@ -419,7 +413,6 @@ sv: long_form: 'flaggad som olämplig' notify_moderators: title: "Annat" - description: 'Detta ämne kräver en moderators uppmärksamhet baserat på riktlinjerna, användarvillkoren, eller an annat skäl som inte nämns ovan.' long_form: 'flaggade det här för granskning av moderator' email_title: 'Ämnet "%{title}" kräver moderators uppmärksamhet' email_body: "%{link}\n\n%{message}" @@ -453,6 +446,9 @@ sv: title: "Nya användare" xaxis: "Dag" yaxis: "Antalet nya användare" + profile_views: + title: "Användarprofilvisningar" + xaxis: "Dag" topics: title: "Ämnen" xaxis: "Dag" @@ -546,10 +542,12 @@ sv: title: "Status 2xx (OK)" xaxis: "Dag" http_3xx_reqs: + title: "HTTP 3xx (omdirigera)" xaxis: "Dag" http_4xx_reqs: xaxis: "Dag" http_5xx_reqs: + title: "HTTP 5xx (Serverfel)" xaxis: "Dag" http_total_reqs: title: "Totala" @@ -561,6 +559,10 @@ sv: title: "Ämnen med ingen respons" xaxis: "Dag" yaxis: "Totalt" + mobile_visits: + title: "Användarbesök" + xaxis: "Dag" + yaxis: "Antal besök" dashboard: rails_env_warning: "Your server is running in %{env} mode." ruby_version_warning: "Du använder en version av Ruby 2.0.0 som är känd för att ha problem. Uppgradera till patch-nivå 247 eller senare." @@ -575,36 +577,6 @@ sv: title_nag: "Ange namnet på webbplatsen. Uppdatera titel i Inställningar." site_description_missing: "Ange en beskrivning om din webbplats i en mening, som dyker upp i sökresultat. Uppdatera site_description i Inställningar." consumer_email_warning: "Din sida är konfigurerad till att använda Gmail (eller någon annan konsumenttjänst) för att skicka email. Gmail limits how many emails you can send. Consider using an email service provider like mandrill.com to ensure email deliverability." - content_types: - education_new_reply: - title: "New User Education: First Replies" - description: "Pop up just-in-time guidance automatically displayed above the composer when new users begin typing their first two new replies." - education_new_topic: - title: "New User Education: First Topics" - description: "Pop up just-in-time guidance automatically displayed above the composer when new users begin typing their first two new topics." - usage_tips: - description: "Guidning och viktig information för nya användare." - welcome_user: - title: "Välkommen: Ny användare" - description: "Ett meddelande som skickas automatiskt till alla nya användare vid registrering." - welcome_invite: - title: "Välkommen: Inbjuden användare" - description: "Ett meddelande som skickas automatiskt till alla nya inbjudna användare när de accepterar inbjudan från en annan användare." - login_required_welcome_message: - title: "Inloggning krävs: Välkomstmeddelande" - description: "Välkomstmeddelande som visas för utloggade användare när inställningen för 'inloggning krävs' är aktiv. " - login_required: - title: "Inloggning krävs: Huvudsida" - description: "Texten som visas för obehöriga användare när inloggning krävs på webbplatsen." - head: - title: "HTML-sidhuvud" - description: "HTML som kommer infogas mellan taggarna och ." - top: - title: "Längst upp på sidorna" - description: "HTML som läggs till i toppen på varje sida (efter sidhuvudet, före navigeringen av ämnets titel)." - bottom: - title: "Botten av sidorna" - description: "HTML som läggs till före taggen ." site_settings: censored_words: "Ord som automatiskt ersätts med ■■■■" delete_old_hidden_posts: "Auto-radera alla dolda inlägg som varit dolda i mer än 30 dagar." @@ -614,7 +586,6 @@ sv: min_first_post_length: "Minst antal tillåtna tecken i första inlägget (ämnestext)" min_private_message_post_length: "Minst antal tillåtna tecken i inlägg för meddelanden" min_search_term_length: "Minsta giltiga teckenlängd på sökterm" - uncategorized_description: "Beskrivningen av den okategoriserade kategorin. Lämna tomt för ingen beskrivning." allow_duplicate_topic_titles: "Tillåt ämnen med identiska rubriker." unique_posts_mins: "Hur många minuter innan en användare kan göra ett inlägg med precis samma innehåll igen" title: "Namnet på denna webbplats som används i titel-taggen." @@ -681,11 +652,8 @@ sv: tl2_requires_likes_received: "Antalet gillningar en användare måste mottaga innan en befordran till förtroendenivå 2." tl2_requires_likes_given: "Antalet gillningar en användare måste ge innan en befordran till förtroendenivå 2." tl2_requires_topic_reply_count: "Antalet ämnen en användare måste svara på innan en befordran till förtroendenivå 2." - tl3_requires_days_visited: "Minsta antal dagar en användare måste ha besökt webbplatsen de senaste 100 dagarna för att bli kvalificerad till en befordran till förtroendenivå 3. (0 till 100)" - tl3_requires_topics_replied_to: "Minsta antalet ämnen en användare behöver ha svarat på de senaste 100 dagarna för att bli kvalificerad till en befordran till förtroendenivå 3. (0 eller högre)" tl3_requires_topics_viewed_all_time: "Minsta antalet ämnen en användare måste ha tittat på för att bli kvalificerad för förtroendenivå 3." tl3_requires_posts_read_all_time: "Minsta antalet inlägg en användare måste ha läst för att bli kvalificerad för förtroendenivå 3." - tl3_requires_likes_received: "Minsta antalet mottagna gillningar under de senaste 100 dagarna för att bli kvalificerad för en befordran till förtroendenivå 3." min_trust_to_create_topic: "Lägsta förtroendenivå som krävs för att skapa ett nytt ämne." newuser_max_links: "Antalet länkar en ny användare kan lägga till i ett inlägg." newuser_max_images: "Antalet bilder en ny användare kan lägga till i ett inlägg." @@ -745,7 +713,6 @@ sv: moved_post: "%{display_username} flyttade ditt inlägg till %{link}" private_message: "%{display_username} har skickat ett meddelande till dig: %{link}" invited_to_private_message: "%{display_username} har bjudit in dig till en privat konversation: %{link}" - invited_to_topic: "%{display_username} har bjudit in dig till ett ämne: %{link}" invitee_accepted: "%{display_username} accepterade din inbjudan" linked: "%{display_username} länkade dig i %{link}" granted_badge: "Du förtjänade %{link}" @@ -755,8 +722,6 @@ sv: category: 'Kategorier' topic: 'Resultat' user: 'Användare' - sso: - account_not_approved: "Konto inväntar godkännande. Du kommer att få ett e-postmeddelande när kontot väl är godkänt." original_poster: "Ursprunglig skribent" most_posts: "Mest inlägg" most_recent_poster: "Senaste skribent" @@ -818,6 +783,10 @@ sv: ip_address: blocked: "Nya registreringar är inte tillåtna från din IP-adress." max_new_accounts_per_registration_ip: "Nya registreringar är inte tillåtet från din IP-adress (maxgräns uppnådd). Kontakta personal." + flags_reminder: + subject_template: + one: "1 flagga väntar på att bli hanterad" + other: "%{count} flaggor väntar på att bli hanterade" invite_mailer: subject_template: "%{invitee_name} har bjudit in dig till '%{topic_title}' på %{site_domain_name}" text_body_template: | @@ -856,47 +825,8 @@ sv: subject_template: "[%{site_name}] Email Deliverability Test" new_version_mailer: subject_template: "[%{site_name}] Ny version av Discourse, uppdatering tillgänglig" - text_body_template: | - En ny version av [Discourse](http://www.discourse.org) finns tillgängligt. - - Din version: %{installed_version} - Ny version: **%{new_version}** - - Du kanske vill: - - - Se vad som är nytt i [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - Uppgradera från din webbläsare på [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Besöka [meta.discourse.org](http://meta.discourse.org) för nyheter, diskussioner och support för Discourse. new_version_mailer_with_notes: subject_template: "[%{site_name}] uppdatering tillgänglig" - text_body_template: | - En ny version av [Discourse](http://www.discourse.org) finns tillgängligt. - - Din version: %{installed_version} - Ny version: **%{new_version}** - - Du kanske vill: - - - Se vad som är nytt i [GitHub changelog](https://github.com/discourse/discourse/commits/master). - - - Uppgradera från din webbläsare på [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade). - - - Besöka [meta.discourse.org](http://meta.discourse.org) för nyheter, diskussioner och support för Discourse. - - ### Release notes - - %{notes} - flags_reminder: - flags_were_submitted: - one: "Dessa flaggor skickades in för mer än 1 timme sedan." - other: "Dessa flaggor skickades in för mer än %{count} timmar sedan." - please_review: "Var god och granska dessa." - post_number: "inlägg" - subject_template: - one: "1 flagga väntar på att bli hanterad" - other: "%{count} flaggor väntar på att bli hanterade" flag_reasons: off_topic: "Ditt inlägg blev flaggat som **off-topic**. Medlemmarna i forumet kände att det inte är passande för ämnet, som definieras av titeln och det första inlägget." inappropriate: "Ditt inlägg blev flaggat som **olämpligt**. Medlemmarna i forumet kände att det är störande, kränkande eller att det strider mot [våra riktlinjer](/guidelines)." @@ -977,49 +907,17 @@ sv: unsubscribe: title: "Unsubscribe" description: "Inte intresserad av att få dessa mejl? Inga problem! Klicka nedan för att avprenumerera." - reply_by_email: "För att svara, svara på detta mejl eller besök %{base_url}%{url} i din webbläsare." - visit_link_to_respond: "För att svara, besök %{base_url}%{url} i din webbläsare." posted_by: "Postat av %{username} den %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} har bjudit in dig till en privat konversation '%{topic_title}'" - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} har bjudit in dig till ett ämne '%{topic_title}'" user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: new_activity: "Ny aktivitet i dina ämnen och inlägg:" top_topics: "Populära inlägg" @@ -1043,18 +941,11 @@ sv: subject_template: "[%{site_name}] Logga in" account_created: subject_template: "[%{site_name}] Ditt nya konto" - authorize_email: - subject_template: "[%{site_name}] Confirm your new email address" - text_body_template: | - Confirm your new email address for %{site_name} by clicking on the following link: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "Du har blivit godkänd på %{site_name}!" signup: text_body_template: "Välkommen till %{site_name}!\n\nKlicka på följande länk för att bekräfta och aktivera ditt nya konto:\n%{base_url}/users/activate-account/%{email_token}\n\nOm länken ovan inte går att klicka på kan du kopiera och klistra in länken i adressfältet i din webbläsare. \n" page_not_found: - title: "Sidan du sökte existerar inte eller är privat." popular_topics: "Populära" recent_topics: "Senaste" see_more: "Mer" @@ -1099,3 +990,8 @@ sv: error: "Fel!" email_input: "E-post till administratör" submit_button: "Skicka e-post" + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.te.yml b/config/locales/server.te.yml index 2a40ce42127..eb970fe9d54 100644 --- a/config/locales/server.te.yml +++ b/config/locales/server.te.yml @@ -16,11 +16,9 @@ te: loading: "లోడవుతోంది" powered_by_html: ' డిస్కౌర్స్ చేత శక్తివంతం చేయబడింది, జావాస్క్రిప్ట్ చేతనం చేస్తే బాగా కనిపిస్తుంది. ' log_in: "లాగిన్" - via: "%{site_name} నుండి %{username}" - is_reserved: "రక్షితము" purge_reason: "వదిలేసినదిగా స్వీయంగా కనుగొను, చేతనం చేయని ఖాతా" disable_remote_images_download_reason: "సుదూర బొమ్మల దిగుమతి అచేతనమైంది ఎందుకంటే డిస్క్ జాగా తక్కువగా ఉంది." - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "%{max} అక్షరాలకే పరిమితము. మీరు %{length} అక్షరాలు రాసారు." @@ -90,26 +88,6 @@ te: replies: one: "ఒక జవాబు" other: "%{count} జవాబులు" - too_many_mentions: - zero: "క్షమించాలి. మీరు ఇతర సభ్యులను ప్రస్తావించలేరు" - one: "క్షమించాలి. మీరు ఒక టపాలో ఒక సభ్యుడిని మాత్రమే ప్రస్తావించవచ్చు" - other: "క్షమించాలి. మీరు ఒక టపాలో కేవలం %[count] సభ్యులను మాత్రమే ప్రస్తావించవచ్చు" - too_many_mentions_newuser: - zero: "క్షమించాలి. కొత్త సభ్యులు ఇతర సభ్యులను ప్రస్తావించలేరు." - one: "క్షమించాలి. కొత్త సభ్యులు ఒక టపాలో కేవలం ఒక సభ్యుడిని మాత్రమే ప్రస్తావించవచ్చు." - other: "క్షమించాలి. కొత్త సభ్యులు ఒక టపాలో కేవలం %{count} సభ్యులను మాత్రమే ప్రస్తావించవచ్చు." - too_many_images: - zero: "క్షమించాలి. కొత్త సభ్యులు టపాలో బొమ్మలు ఉంచలేరు." - one: "క్షమించాలి. కొత్త సభ్యులు టపాలో ఒక బొమ్మ మాత్రమే ఉంచవచ్చు." - other: "క్షమించాలి. కొత్త సభ్యులు ఒక టపాలో కేవలం %{count} బొమ్మలను మాత్రమే ఉంచవచ్చు." - too_many_attachments: - zero: "క్షమించాలి. కొత్త సభ్యులు టపాలో జోడింపులు ఉంచవీలవదు." - one: "క్షమించాలి. కొత్త సభ్యులు ఒక టపాలో కేవలం ఒక జోడింపు మాత్రమే ఉంచ వీలవుతుంది." - other: "క్షమించాలి. కొత్త సభ్యులు ఒక టపాలో కేవలం %{count} జోడింపులు మాత్రమే ఉంచ వీలవుతుంది." - too_many_links: - zero: "క్షమించాలి, కొత్త సభ్యులు టపాలో లంకెలు ఉంచవీలవదు." - one: "క్షమించాలి. కొత్త సభ్యులు ఒక టపాలో కేవలం ఒక లంకె మాత్రమే ఉంచ వీలవుతుంది." - other: "క్షమించాలి. కొత్త సభ్యులు ఒక టపాలో కేవలం %[count] లంకెలు మాత్రమే ఉంచ వీలవుతుంది." spamming_host: "క్షమించాలి. ఆ అతిధికి మీరు లంకె టపా చెయ్యలేరు." user_is_suspended: "సస్పెండైన సభ్యులు టపా రాయుట వీలవదు" topic_not_found: "ఏదో తప్పు జరిగింది. బహుశా ఈ అంశం ముగిసింది లేదా మీరు చూస్తూ ఉండగా తొలగించబడింది?" @@ -168,9 +146,6 @@ te: user_profile: bio_raw: "నా గురించి" errors: - messages: - is_invalid: "చెల్లనిది. మరింత వివరణాత్మకంగా ఉండటానికి ప్రయత్నించండి" - has_already_been_used: "ఇప్పటికే వాడుకలో ఉంది" models: topic: attributes: @@ -191,6 +166,7 @@ te: attributes: hex: invalid: "ఇది చెల్లని రంగు" + <<: *errors user_profile: no_info_other: "
    %{పేరు} ఇంకా వారి ప్రొఫైల్ లో ఎబౌట్ మీ స్థానంలో ఏమీ చేర్చలేదు
    " vip_category_name: "అడ్డా" @@ -218,14 +194,7 @@ te: title: "కొత్త సభ్యుడు" basic: title: "ప్రాథమిక సభ్యుడు" - regular: - title: "మెంబరు" - leader: - title: "రెగ్యులర్" - elder: - title: "లీడర్" rate_limiter: - slow_down: "ఈ చర్చ మీరు చాలాసార్లు జరిపారు. కొంతసేపటితర్వాత ప్రయత్నించండి" too_many_requests: "ఈ చర్యకు రోజువారీపరిమితి ఉంది. దయచేసి %{time_left} సమయం తర్వాత ప్రయత్నించండి" hours: one: "ఒక గంట" @@ -342,14 +311,10 @@ te: description: 'ఈ టపాలో విషయం కొంతమందికి అభ్యంతరకరమైనది, అగౌరవపరిచేది లేదా మా కమ్యునిటీ మార్గదర్శకాలకు లోబడినది కాదు.' long_form: 'దీన్ని అసమంజసమైనదిగా కేతనించాము' notify_user: - description: 'ఈ టపా నేను సభ్యునితో వ్యక్తిగతంగా మాట్లాడాలనుకున్న విషయం కలిగి ఉంది. కేతనం అవ్వసరంలేదు.' email_title: '"%{title}" లో మీ టపా' email_body: "%{link}\n\n%{message}" notify_moderators: title: "వేరే ఏదో" - description: 'ఇక్కడ ప్రదర్శిచని వేరే కారణంగా ఈ టపా నిర్వాహకుని దృష్టికి తీసుకెళ్లాలి' - long_form: 'దీన్ని నిర్వాహకుని దృష్టికి కేతనించాము' - email_title: '"%{title}" లోని ఒక టపా నిర్వాహకుని చర్య కోసం వేచిఉంది. ' email_body: "%{link}\n\n%{message}" bookmark: title: 'పేజీక' @@ -374,7 +339,6 @@ te: long_form: 'దీన్ని అసమంజసమైనదిగా కేతనించారు' notify_moderators: title: "వేరే ఏదో" - description: 'మార్గదర్శకాల ఆధారంగా ఈ అంశానికి సాధారణ పరిశీలకుల శ్రధ్ధ అవసరం, TOS, లేదా పైన జాబితాలో పేర్కొనబడని మరొక కారణం కావచ్చు.' long_form: 'దీన్ని నిర్వాహకుల దృష్టికి తెచ్చారు' email_title: '"%{title}" విషయం నిర్వాహకుల దృష్టిలో ఉంది.' email_body: "%{link}\n\n%{message}" @@ -518,35 +482,6 @@ te: title_nag: "సైట్ పేరు నమోదు చేయండి.శీర్షికను సైట్ సెట్టింగ్స్‌ లో అప్‌డేట్ చేయండి" site_description_missing: "శోధన ఫలితాల్లో కనిపించడానికి మీ సైట్ యొక్క ఏకవాక్య వివరణ నమోదు చేయండి.సైట్ వివరణను సైట్ సెట్టింగ్స్‌ లో అప్‌డేట్ చేయండి." notification_email_warning: "ఈ-మెయిల్ ప్రకటనలు మీ డొమైన్ లో ఒక చెల్లుబాటు అయ్యే ఈ-మెయిల్ చిరునామా నుండి పంపలేదు :ఈ-మెయిల్ బట్వాడా అనిశ్చిత మరియు నమ్మలేనిదిగా ఉంటుంది.దయచేసి ప్రకటనను ఉంచండి_ఒక చెల్లుబాటు అయ్యే స్థానిక ఈమెయిల్ చిరునామాకు ఈ-మెయిల్ చేయండిసైట్ సెట్టింగ్స్ లో." - content_types: - education_new_reply: - title: "కొత్త వాడుకరి విద్య: మొదటి ప్రత్యుత్తరాలు" - description: "వినియోగదారులు వారి మొదటి రెండు కొత్త ప్రత్యుత్తరాలు టైప్ చేయడం ప్రారంభించిన సమయంలో పాప్‌అప్ మార్గదర్శకత్వం స్వయంచాలకంగా కంపోజర్ పైన కనిపిస్తుంది. " - education_new_topic: - title: "కొత్త వాడుకరి విద్య: మొదటి విషయాలు" - description: "వినియోగదారులు వారి మొదటి రెండు కొత్త విషయాలు టైప్ చేయడం ప్రారంభించిన సమయంలో పాప్‌అప్ మార్గదర్శకత్వం స్వయంచాలకంగా కంపోజర్ పైన కనిపిస్తుంది. " - usage_tips: - title: "కొత్త వాడుకరి మార్గదర్శకత్వం" - description: "కొత్త వాడుకరుల కోసం మార్గదర్శకత్వం మరియు అవసరమైన సమాచారం" - welcome_user: - title: "సుస్వాగతం: కొత్త సభ్యుడు" - welcome_invite: - title: "స్వాగతం : ఆహ్వానించబడిన వాడుకరి" - login_required_welcome_message: - title: "లాగిన్ అవసరం: స్వాగత సందేశం" - description: "'లాగిన్ అవసరం' సెట్టింగ్ ప్రారంభించబడి ఉన్నప్పుడు లాగ్ అవుట్ వినియోగదారులకు స్వాగతసందేశం ప్రదర్శించబడుతుంది." - login_required: - title: "లాగిన్ అవసరం: హోమ్‌పేజ్" - description: "లాగిన్ సైట్లో అవసరం ఉన్నప్పుడు టెక్స్ట్ అనధికార వినియోగదారులకు ప్రదర్శించబడుతుంది." - head: - title: "HTML హెడ్" - description: "ట్యాగ్‌ల లోపల HTML ప్రవేశపెట్టబడింది." - top: - title: "పుటల యొక్క పై భాగంలో" - description: "HTML ప్రతి పేజీ ఎగువన చేర్చబడుతుంది(హెడర్ తర్వాత , దిశా నిర్దేశనానికి ముందు లేదా శీర్షికలో)" - bottom: - title: "పుటల అడుగు భాగం" - description: "ట్యాగ్ చెయ్యక ముందే HTML ను కలుపుతారు." site_settings: censored_words: "వీటితో పదాలు స్వయంచాలకంగా భర్తీ చేయబడతాయి ■■■■" delete_old_hidden_posts: "30 రోజుల కంటే ఎక్కువ దాగివున్న టపాలు స్వయంసిధ్ధంగా తొలగింపబడతాయి." @@ -557,14 +492,12 @@ te: min_topic_title_length: "శీర్షిక కు అనుమతించే అక్షరాల కనిష్ఠ పొడవు" max_topic_title_length: "శీర్షిక కు అనుమతించే అక్షరాల గరిష్ఠ పొడవు" min_search_term_length: "శోధనకు అవసరమయ్యే అక్షరాల కనీస పొడవు" - uncategorized_description: "వర్గీకరించని వర్గం యొక్క వివరణ. ఎటువంటి వివరణ లేని వాటిని ఖాళీగా వదిలివేయండి." allow_duplicate_topic_titles: "సమరూపమైన,నకిలీ శీర్షికలతో విషయాలను అనుమతించు." unique_posts_mins: "ఒక వినియోగదారు ఎన్ని నిమిషాల తర్వాత మళ్ళీ అదే విషయంతో ఒక టపా చేయవచ్చు " educate_until_posts: "వినియోగదారు వారి మొదటి (n) కొత్త టపాలు చేయడం మొదలుపెట్టినప్పుడు, కంపోజర్‌లో పాప్-అప్ కొత్త యూజర్ విద్య ప్యానెల్ చూపించు." title: "ఈ సైట్ యొక్క పేరు ,టైటిల్ ట్యాగ్ లో ఉపయోగించారు." site_description: "మెటా వివరణ ట్యాగ్ ఉపయోగించి ఈ సైట్‌ని ఒక వాక్యంలో వివరించండి." download_remote_images_threshold: "సుదూర చిత్రాలను స్థానికంగా దిగుమతి చేయడానికి అవసరమయ్యే కనీస డిస్క్ స్థలం (శాతం లో)" - ninja_edit_window: "టపా చేసిన తర్వాత (n) సెకన్లు, టపా చరిత్రలో ఒక కొత్త కధనం సృష్టించడానికి సవరింపు కుదరదు." post_edit_time_limit: "రచయిత వారు చేసిన టపా (n) నిమిషాల తర్వాత సవరించవచ్చు లేదా తొలగించవచ్చు. ఎప్పటికీ 0 అమర్చుము." max_image_width: "ఒక టపాలో థంబ్నైల్ గరిష్ట వెడల్పు" max_image_height: "ఒక టపాలో థంబ్నైల్ గరిష్ట ఎత్తు" @@ -634,9 +567,6 @@ te: email: not_allowed: "ఆ ఈమెయిల్ ప్రొవైడరును అనుమంతిచుటలేదు. దయచేసి మరో ఈమెయిల్ చిరునామా రాయండి" blocked: "అనుమతించుటలేదు" - flags_reminder: - please_review: "దయచేసి వాటిని సమీక్షించండి." - post_number: "టపా" system_messages: welcome_user: subject_template: "%{site_name} కు సుస్వాగతం!" @@ -693,3 +623,6 @@ te: title: "సేవా నిబంధనలు" privacy_topic: title: "ప్రైవసీ పోలసీ" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.tr_TR.yml b/config/locales/server.tr_TR.yml index b47160534cd..e232bd02ef9 100644 --- a/config/locales/server.tr_TR.yml +++ b/config/locales/server.tr_TR.yml @@ -10,18 +10,24 @@ tr_TR: short_date_no_year: "G AAA" short_date: "D MMM, YYYY" long_date: "MMMM D, YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%d-%m-%Y" + short_no_year: "%B %-d" + date_only: "%B %-d, %Y" + date: + month_names: [null, Ocak, Şubat, Mart, Nisan, Mayıs, Haziran, Temmuz, Ağustos, Eylül, Ekim, Kasım, Aralık] + <<: *datetime_formats title: "Discourse" topics: "Konular" posts: "gönderiler" loading: "Yükleniyor" powered_by_html: 'Gücünü Discourse ''tan alır, en iyi görünüm için JavaScript etkinleştirmeniz gerekir' log_in: "Giriş Yap" - via: "%{site_name} sitesinden %{username}" - is_reserved: "rezerve edilmiş" purge_reason: "Bırakılmış, etkinleştirilmemiş hesap olarak otomatik silindi" disable_remote_images_download_reason: "Yeterli disk alanı kalmaması sebebiyle uzaktan görüntü indirme devre dışı bırakıldı." anonymous: "Anonim" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "%{max} karakter ile limitli; siz %{length} karakter girdiniz." @@ -37,8 +43,10 @@ tr_TR: exclusion: rezerve edildi greater_than: '%{count} rakamından fazla olmalı' greater_than_or_equal_to: '%{count} rakamına eşit veya daha fazla olmalı' + has_already_been_used: "önceden kullanıldı" inclusion: listeye dahil edilmemiş invalid: geçersiz + is_invalid: "geçersiz; biraz daha açıklayıcı olmaya çalışın" less_than: '%{count} rakamından az olmalı' less_than_or_equal_to: '%{count} rakamına eşit veya daha az olmalı' not_a_number: sayı değil @@ -67,6 +75,7 @@ tr_TR: max_username_length_exists: "En uzun kullanıcı adının altında en büyük kullanıcı adı uzunluğu ayarlayamazsınız." max_username_length_range: "En küçük değer altında en büyük değer ayarlayamazsınız." default_categories_already_selected: "Bir başka listede kullanılan bir kategoriyi seçemezsiniz." + s3_upload_bucket_is_required: "Bir 's3_upload_bucket' tanımlamadıysanız, S3 yüklemelerini etkinleştiremezsiniz." bulk_invite: file_should_be_csv: "Yüklenen dosya csv veya txt formatında olmalı. " backup: @@ -77,6 +86,8 @@ tr_TR: not_found: "İstenilen URL ya da kaynak bulunamadı." invalid_access: "İstenilen kaynağı görüntüleyebilmeniz için izniniz yok." read_only_mode_enabled: "Bu site sadece okuma modunda. Etkileşimler etkisizleştirildi." + reading_time: "Okuma Zamanı" + likes: "Beğeniler" too_many_replies: other: "Üzgünüz, yeni kullanıcılar geçici olarak aynı konu içinde sadece %{count} cevap ile sınırlılar. " embed: @@ -90,25 +101,20 @@ tr_TR: in_reply_to: "▶ %{username}" replies: other: "%{count} cevap" + no_mentions_allowed: "Üzgünüz, diğer kullanıcılardan bahsedemezsiniz." too_many_mentions: - zero: "Üzgünüz, diğer kullanıcılardan bahsedemezsiniz." - one: "Üzgünüz, bir gönderide sadece bir kullanıcıdan bahsedebilirsiniz." other: "Üzgünüz, bir gönderide sadece %{count} kullanıcıdan bahsedebilirsiniz." + no_mentions_allowed_newuser: "Üzgünüz, yeni kullanıcılar diğer kullanıcılardan bahsedemezler." too_many_mentions_newuser: - zero: "Üzgünüz, yeni kullanıcılar diğer kullanıcılardan bahsedemezler." - one: "Üzgünüz, yeni kullanıcılar bir gönderide sadece bir kullanıcıdan bahsedebilirler." other: "Üzgünüz, yeni kullanıcılar bir gönderide sadece %{count} kullanıcıdan bahsedebilirler." + no_images_allowed: "Üzgünüz, yeni kullanıcılar gönderilere resim ekleyemezler." too_many_images: - zero: "Üzgünüz, yeni kullanıcılar gönderilere resi ekleyemezler." - one: "Üzgünüz, yeni kullanıcılar bir gönderiye sadece bir resim ekleyebilirler." other: "Üzgünüz, yeni kullanıcılar bir gönderiye sadece %{count} resim koyabilirler. " + no_attachments_allowed: "Üzgünüz, yeni kullanıcılar gönderilere bir şey ekleyemezler." too_many_attachments: - zero: "Üzgünüz, yeni kullanıcılar gönderilere bir şey ekleyemezler." - one: "Üzgünüz, yeni kullanıcılar bir gönderiye sadece bir eklenti koyabilirler. " other: "Üzgünüz, yeni kullanıcılar bir gönderiye sadece %{count} eklenti koyabilirler." + no_links_allowed: "Üzgünüz, yeni kullanıcılar gönderilere bağlantı ekleyemezler." too_many_links: - zero: "Üzgünüz, yeni kullanıcılar gönderilere bağlantı ekleyemezler." - one: "Üzgünüz, yeni kullanıcılar bir gönderiye sadece bir bağlantı ekleyebilirler. " other: "Üzgünüz, yeni kullanıcılar bir gönderiye sadece %{count} bağlantı ekleyebilirler." spamming_host: "Üzgünüz bu sunucuya bağlantı veremezsiniz." user_is_suspended: "Uzaklaştırılmış kullanıcılar gönderi yapamazlar." @@ -141,6 +147,7 @@ tr_TR: errors: can_not_modify_automatic: "Otomatik oluşturulan grubu düzenleyemezsiniz" member_already_exist: "'%{username}' zaten grubun bir üyesi." + invalid_domain: "'%{domain}' geçerli bir alan adı değil." default_names: everyone: "herkes" admins: "adminler" @@ -191,9 +198,6 @@ tr_TR: user_profile: bio_raw: "Hakkımda" errors: - messages: - is_invalid: "geçersiz; biraz daha açıklayıcı olmaya çalışın" - has_already_been_used: "önceden kullanıldı" models: topic: attributes: @@ -214,6 +218,7 @@ tr_TR: attributes: hex: invalid: "geçerli bir renk değil" + <<: *errors user_profile: no_info_me: "
    Profilinizdeki Hakkımda bölümü boş, doldurmak ister misiniz?
    " no_info_other: "
    %{name} profilinde Hakkımda kısmına henüz bir şey girmedi
    " @@ -249,13 +254,12 @@ tr_TR: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "%{category} kategorisi hakkında " - replace_paragraph: "[Bu paragrafın yerine kategorinizin kısa bir açıklamasını girin. Buraya yazılanlar kategori seçim alanında görüneceği için, açıklamanızı 200 karakterin altında tutmaya çalışın. Siz bu metni düzenleyene veya herhangi bir konu yaratana kadar bu kategori, kategoriler sayfasında gözükmeyecek.]" - post_template: "%{replace_paragraph}\n\nDaha uzun bir açıklama, kategori yönergeleri veya kuralları oluşturmak için aşağıdaki paragrafları kullanın.\n\nHerhangi bir tartışma için düşünülebilecek bazı maddeler:\n\n- Bu kategorinin amacı ne? İnsanlar konu oluştururken neden bu kategoriyi seçmeliler?\n\n- Bu kategorinin sahip olduğumuz diğer mevcut kategorilerden farkı ne?\n\n- Bu kategoriye ihtiyacımız var mı?\n\n- Bunu başka bir kategoriyle birleştirmeli miyiz, yoksa daha fazla kategoriye mi bölmeli miyiz?\n" + replace_paragraph: "(Bu paragrafın yerine yeni kategorinizin kısa bir açıklamasını girin. Buraya yazılanlar kategori seçim alanında görüneceği için, açıklamanızı 200 karakterin altında tutmaya çalışın.**Siz bu metni düzenleyene veya herhangi bir konu oluşturana kadar bu kategori, kategori sayfasında gözükmeyecek.**)" + post_template: "%{replace_paragraph}\n\nAşağıdaki satırları daha uzun açıklama, kategori yönergeleri ya da kurallar oluşturmak için kullanın:\n\n-Bu kategorinin amacı ne? İnsanlar konu oluştururken neden bu kategoriyi kullanmalılar?\n\n-Bu kategorinin mevcut diğer kategorilerden farkı ne?\n\n- Bu kategorideki konular neleri içermeli?\n\n- Bu kategoriye gerçekten ihtiyacımız var mı? Bu kategoriyi bir başka kategori ya da alt kategori ile birleştirmeli miyiz?\n" errors: uncategorized_parent: "Kategorisizin üst kategorisi olamaz" self_parent: "Alt kategorinin üst kategorisi kendisi olamaz" depth: "Bir alt kategori başka bir alt kategorinin altında yer alamaz" - email_in_already_exist: "Gelen e-posta adresi '%{email_in}' %{category_name}' kategorisi için zaten kullanılıyor." cannot_delete: uncategorized: "Kategorisiz silinemez" has_subcategories: "Alt kategorileri bulunduğu için bu kategori silinemez." @@ -267,16 +271,26 @@ tr_TR: title: "yeni kullanıcı" basic: title: "acemi kullanıcı" - regular: + member: title: "üye" + regular: + title: "müdavim" leader: - title: "Müdavim" - elder: title: "lider" change_failed_explanation: " %{user_name} adlı kullanıcıyı '%{new_trust_level}' seviyesine düşürmeye çalıştınız. Ancak, halihazırda kullanıcının güven seviyesi zaten '%{current_trust_level}'. %{user_name} '%{current_trust_level}' seviyesinde kalacak - eğer seviyesini düşürmek istiyorsanız öncelikle güven seviyesini kilitlemelisiniz" rate_limiter: - slow_down: "Bu işlemi çok fazla kere tekrar ettiniz, lütfen daha sonra tekrar deneyin" + slow_down: "Bu eylemi birçok sefer gerçekleştirdiniz, daha sonra tekrar deneyin." too_many_requests: "Bu işlem için günlük limitinizi aştınız. Lütfen tekrar denemek için %{time_left} bekleyin. " + by_type: + first_day_replies_per_day: "Yeni bir kullanıcının ilk gününde verebileceği maksimum cevap sayısına ulaştınız. Lütfen tekrar denemek için %{time_left} bekleyin." + first_day_topics_per_day: "Yeni bir kullanıcının ilk gününde oluşturabileceğiz maksimum konu sayısına ulaştınız. Lütfen tekrar denemek için %{time_left} bekleyin." + create_topic: "Kısa sürede çok sayıda konu oluşturmaya çalıştınız. Lütfen tekrar denemek için %{time_left} bekleyin." + create_post: "Kısa sürede çok sayıda cevap yazmaya çalıştınız. Lütfen tekrar denemek için %{time_left} bekleyin." + topics_per_day: "Bugün oluşturabileceğiniz maksimum konu sayısına ulaştınız. Lütfen tekrar denemek için %{time_left} bekleyin." + pms_per_day: "Bugün oluşturabileceğiniz maksimum mesaj sayısına ulaştınız. Lütfen tekrar denemek için %{time_left} bekleyin." + create_like: "Bugün yapabileceğiniz maksimum beğeni sayısına ulaştınız. Lütfen tekrar denemek için %{time_left} bekleyin." + create_bookmark: "Bugün yapabileceğiniz maksimum işaretleme sayısına ulaştınız. Lütfen tekrar denemek için %{time_left} bekleyin." + edit_post: "Bugün yapabileceğiniz maksimum düzenleme sayısına ulaştınız. Lütfen tekrar denemek için %{time_left} bekleyin." hours: other: "%{count} saat" minutes: @@ -371,15 +385,15 @@ tr_TR: long_form: 'uygunsuz olarak bayraklanmış' notify_user: title: '@{{username}} adlı kullanıcıya mesaj gönder' - description: 'Bu gönderi, bu kişiyle doğrudan veya özel olarak konuşmamı gerektiren içeriğe sahip. Bayraklanacak bir durum yok.' + description: 'Bu kişiyle gönderisi hakkında doğrudan ve gizli olarak konuşmak istiyorum.' long_form: 'mesaj gönderilen kullanıcı' email_title: '"%{title}" başlıklı gönderiniz' email_body: "%{link}\n\n%{message}" notify_moderators: title: "Başka Bir Şey" - description: 'Bu gönderinin, yukarıda belirtilmeyen bir nedenden ötürü moderatör tarafından kontrol edilmesi gerekiyor.' - long_form: 'moderatör tarafından kontrol edilmesi için bayraklandı' - email_title: '"%{title}" başlığındaki bir gönderinin moderatör tarafından kontrol edilmesi gerekiyor.' + description: 'Bu gönderinin, yukarıda belirtilmeyen bir nedenden ötürü yetkililer tarafından kontrol edilmesi gerekiyor.' + long_form: 'moderatörün ilgisi için bayraklandı' + email_title: '"%{title}" konu başlığının moderatör tarafından kontrol edilmesi gerekiyor' email_body: "%{link}\n\n%{message}" bookmark: title: 'İşaretle' @@ -404,7 +418,7 @@ tr_TR: long_form: 'uygunsuz olarak bayraklandı' notify_moderators: title: "Başka Bir Şey" - description: 'Bu gönderi yönergeler, kullanıcı sözleşmesi veya yukarıda belirtilmeyen bir nedenden dolayı genel bir moderatör kontrolü gerektiriyor.' + description: 'Bu gönderi yönergeler, hizmet şartları veya başka herhangi bir nedenden dolayı moderatör incelemesi gerektirmektedir.' long_form: 'moderatörün ilgisi için bayraklandı' email_title: '"%{title}" konu başlığının moderatör tarafından kontrol edilmesi gerekiyor' email_body: "%{link}\n\n%{message}" @@ -440,6 +454,10 @@ tr_TR: title: "Yeni Kullanıcılar" xaxis: "Gün" yaxis: "Yeni kullanıcı sayısı" + profile_views: + title: "Kullanıcı Profil Görüntülemeleri" + xaxis: "Gün" + yaxis: "Görüntülenen kullanıcı profili sayısı" topics: title: "Konular" xaxis: "Gün" @@ -582,6 +600,7 @@ tr_TR: s3_config_warning: 'Sunucu s3''e dosya yüklenebilmesi için yapılandırılmış, fakat şunlardan en az biri henüz ayarlanmamış: s3_access_key_id, s3_secret_access_key or s3_upload_bucket. Site Ayarları sayfasına gidin ve ayarları güncelleyin. Daha fazla bilgi için "How to set up image uploads to S3?" konulu gönderiye bakın.' s3_backup_config_warning: 'Sunucu s3''e yedekleme yüklenebilmesi için yapılandırılmış, fakat şunlardan en az biri henüz ayarlanmamış: s3_access_key_id, s3_secret_access_key or s3_backup_bucket. Site Ayarları sayfasına gidin ve ayarları güncelleyin. Daha fazla bilgi için "How to set up image uploads to S3?" konulu gönderiye bakın.' image_magick_warning: 'Sunucu büyük resimlerin küçük boylarının oluşturulması için yapılandırılmış, fakat ImageMagick henüz kurulmamış. Favori paket yöneticinizi kullanarak ImageMagick kurun veya son sürümünü indirin.' + failing_emails_warning: 'Başarısızlıkla sonuçlanmış %{num_failed_jobs} e-posta işlemi bulunuyor. app.yml dosyanızı kontrol edin ve e-posta sunucu ayarlarınızın doğru olduğundan emin olun. Sidekiq''deki başarısız işlemlere gözatın.' default_logo_warning: "Siteniz için logo grafikleri yükleyin. Site Ayarları'nda logo_url, logo_small_url, ve favicon_url güncellemelerini yapın." contact_email_missing: "Sitenizle alakalı acil durumlar için size ulaşabileceğimiz bir iletişim e-postası girin. Lütfen Site Ayarları'nda iletişim e-postanızı güncelleyin." contact_email_invalid: "Site iletişim e-postası geçersiz. İletişim e-postanızı Site Ayarları sayfasından güncelleyin." @@ -590,37 +609,7 @@ tr_TR: consumer_email_warning: "Sitenizde e-posta gönderimleri için Gmail (ya da başka bir e-posta hizmeti) kurulumu yapılmış. Gmail ile gönderebileceğiniz e-posta sayısı limitlidir. Onun yerine, e-postalarınızın ulaştırılabildiğinden emin olmak için mandrill.com benzeri bir hizmet sağlayıcısını kullanın." site_contact_username_warning: "Önemli otomatik mesajları gönderen kişi olarak gözükecek adminin kullanıcı adını girin. Site Ayarları&lt;/a> sayfasından site_contact_username parametresini güncelleyin." notification_email_warning: "Bildiri e-postaları alan adınıza bağlı geçerli bir e-posta adresinden yollanmıyor; e-postalar düzenli ve güvenilir bir şekilde ulaşmayabilir. Lütfen Site Ayarları sayfasından notification_email değeri için geçerli bir yerel e-posta adresi girin." - content_types: - education_new_reply: - title: "Yeni Kullanıcı Eğitimi: İlk Cevaplar" - description: "Yeni kullanıcılar, ilk iki cevaplarını yazmaya başladıklarında, pop-up son-dakika yardım kılavuzu metin düzenleyecisinin üstünde otomatik olarak çıksın." - education_new_topic: - title: "Yeni Kullanıcı Eğitimi: İlk Konular" - description: "Yeni kullanıcılar, ilk iki cevaplarını yazmaya başladıklarında, pop-up son-dakika yardım kılavuzu metin düzenleyecisinin üstünde otomatik olarak çıksın." - usage_tips: - title: "Yeni Kullanıcı Kılavuzu" - description: "Yeni kullanıcılar için kılavuz ve gerekli bilgiler." - welcome_user: - title: "Hoşgeldiniz: Yeni Kullanıcı" - description: "Tüm yeni kullanıcılara, üye olduklarında otomatik olarak gönderilen mesaj." - welcome_invite: - title: "Hoşgeldiniz: Davetli Kullanıcı" - description: "Bir başka kullanıcı tarafından davet edilen yeni kullanıcılara, daveti kabul ettiklerinde gönderilen otomatik mesaj." - login_required_welcome_message: - title: "Giriş Yapmak Zorunlu: Hoşgeldiniz Mesajı" - description: "'Giriş yapmak zorunlu' ayarı etkinleştirildiğinde, sisteme giriş yapmamış olan ziyaretçilere gözüken hoşgeldiniz mesajı. " - login_required: - title: "Giriş Yapmak Zorunlu: Anasayfa" - description: "Siteye giriş yapmanın zorunlu olduğu durumlarda izin almamış kullanıcılara çıkan mesaj." - head: - title: "HTML başlık" - description: " etiketleri arasına eklenecek HTML." - top: - title: "Sayfaların en üstü" - description: "Her sayfanın en üstüne eklenecek HTML (sayfa başlığından sonra, navigasyondan ya da konu başlığından önce)." - bottom: - title: "Sayfaların en altı" - description: " etiketinden önce eklenecek HTML" + subfolder_ends_in_slash: "Alt dizin ayarlarınız hatalı, DISCOURSE_RELATIVE_URL_ROOT sonunda slaş bulunmalı" site_settings: censored_words: " ■■■■ yerine otomatik olarak kullanılacak kelimeler" delete_old_hidden_posts: "30 günden fazla süreyle gizli kalan gizlenmiş gönderileri otomatik olarak sil." @@ -634,8 +623,8 @@ tr_TR: max_topic_title_length: "Konu başlığında izin verilen en fazla karakter sayısı" min_private_message_title_length: "Mesaj başlıkları için izin verilen en az karakter sayısı" min_search_term_length: "Arama için girilecek kelimede olması gereken en az karakter sayısı" + search_tokenize_chinese_japanese_korean: " CJK olmayan siteler dahil, -Çince/Japonca/Korece için aramayı bilgileri sıfırlamaya zorla" allow_uncategorized_topics: "Konuların kategori seçmeden oluşturulmasına izin ver. DİKKAT: Bu özelliği kapamadan önce kategorisiz tüm konuları kategorize etmeniz lazım." - uncategorized_description: "Kategorisiz kategorisinin tanıtımı. Boş bırakabilirsiniz." allow_duplicate_topic_titles: "Aynı başlık ile birden çok konu açılmasına izin ver." unique_posts_mins: "Kullanıcının aynı içerikle yeni bir gönderi oluşturmadan önce geçmesi gereken dakika" educate_until_posts: "Kullanıcılar, ilk (n) gönderilerini yazmaya başladıklarında, pop-up yeni kullanıcı eğitim paneli metin düzenleyecisinin üstünde çıksın." @@ -648,7 +637,7 @@ tr_TR: download_remote_images_to_local: "Uzaktaki resimler yerel resimlere çevirmek için indirilsin; bu ayar resim bağlantılarının kırılmasını önleyecektir" download_remote_images_threshold: "Uzaktaki resimlerin yerele indirilmesi için gereken en az disk alanı (yüzdesel)" disabled_image_download_domains: "Bu alan adlarından hiç bir zaman uzaktan resim indirme. Sınırlandırılmış liste." - ninja_edit_window: "Gönderi oluşturulduktan (n) saniye içerisinde bir düzenleme yapıldığında, gönderi tarihinde yeni bir versiyon yaratma." + editing_grace_period: "Gönderi oluşturulduktan (n) saniye içerisinde bir düzenleme yapıldığında, gönderi geçmişinde yeni bir versiyon oluşturma." post_edit_time_limit: "Yazar gönderiyi yayınladıktan sonra (n) dakika içerisinde gönderiyi düzenleyebilir ya da silebilir. Sonsuz için 0 girin." edit_history_visible_to_public: "Düzenlenmiş gönderinin eski versiyonlarını herkesin görmesine izin ver. Bu özellik kapatıldığında, eski versiyonları sadece görevliler görebilir." delete_removed_posts_after: "Yazar tarafından kaldırılan gönderiler (n) saat sonra otomatik olarak silinecektir. 0 olarak ayarlanırsa, gönderiler beklemeden hemen silinir." @@ -678,7 +667,7 @@ tr_TR: summary_likes_required: "'Bu Konuyu Özetle'nin etkinleştirilmesi için konuda olması gereken en az beğeni sayısı" summary_percent_filter: "Kullanıcı 'Bu Konuyu Özetle'ye tıkladığında, gönderinin ilk % kısmını göster" summary_max_results: "'Bu Konuyu Özetle'den dönen en fazla gönderi sayısı" - enable_private_messages: "Güven seviyesi 1 olan kullanıcıların mesaj oluşturmasına ve mesajlara cevap vermesine izin ver" + enable_private_messages: "Güven seviyesi 1 (mesaj göndermek için gereken minimum güven düzeyi seçeneğinden ayarlanabilir) olan kullanıcıların mesaj oluşturmasına ve mesajlara ve cevap verebilmesine izin ver." enable_long_polling: "Bildiri için kullanılan message bus uzun sorgular yapabilir" long_polling_base_url: "Uzun sorgular için kullanılan baz URL (CDN dinamik içerik sunuyorsa, bunu origin olarak ayarladığına emin ol) ör: http://origin.site.com" long_polling_interval: "Gönderilecek bilgi olmadığı zaman sunucunun kullanıcılara geri dönmeden önce beklemesi gereken zaman (sadece giriş yapmış kullanıcın için)" @@ -697,9 +686,10 @@ tr_TR: notify_mods_when_user_blocked: "Eğer bir kullanıcı otomatik olarak engellendiyse, tüm moderatörlere mesaj yolla." flag_sockpuppets: "Eğer, yeni kullanıcı konuya, konuyu başlatan yeni kullanıcı ile aynı IP adresinden cevap yazarsa, her iki gönderiyi de potansiyel spam olarak işaretle. " traditional_markdown_linebreaks: "Markdown'da, satır sonundan önce yazının sağında iki tane boşluk gerektiren, geleneksel satır sonu metodunu kullan kullan." - allow_html_tables: "Çizelgelerin HTML etiketleri kullanılarak Markdown ile oluşturulmasına izin verin, TABLE, THEAD, TD, TR, TH kabul edilir (çizelge içeren tüm eski gönderilerin yenilenmesini gerektirir)" + allow_html_tables: "Tabloların HTML etiketleri kullanılarak Markdown ile oluşturulmasına izin verin. TABLE, THEAD, TD, TR, TH kabul edilir (tablo içeren tüm eski gönderilerin yenilenmesini gerektirir) " post_undo_action_window_mins: "Kullanıcıya tanınan, bir gönderide yapılan yeni aksiyonları (beğenme, bayraklama, vs) geri alabilme dakika süresi" must_approve_users: "Siteye erişimlerine izin verilmeden önce tüm yeni kullanıcı hesaplarının görevliler tarafından onaylanması gerekir. UYARI: yayındaki bir site için bunu etkinleştirmek görevli olmayan hesapların erişimini iptal edecek." + pending_users_reminder_delay: "Belirtilen saatten daha uzun bir süredir onay bekleyen yeni kullanıcılar mevcutsa moderatörleri bilgilendir. Bilgilendirmeyi devre dışı bırakmak için -1 girin." ga_tracking_code: "Google analytics (ga.js) takip kodu, ör: UA-12345678-9; bakınız http://google.com/analytics" ga_domain_name: "Google analytics (ga.js) alan adı, ör: mysite.com; bakınız http://google.com/analytics" ga_universal_tracking_code: "Google Universal Analytics (analytics.js) takip kodu, ör: UA-12345678-9; bakınız http://google.com/analytics" @@ -708,6 +698,7 @@ tr_TR: enable_noscript_support: "Noscript etiketi üzerinden standart webcrawler arama motoru desteğini etkinleştir" allow_moderators_to_create_categories: "Moderatörlerin yeni kategoriler oluşturmasına izin ver" cors_origins: "Cross-origin isteklerin (CORS) izin verilen originler. Her origin http:// veya https:// içermeli. CORS'u etkinleştirebilmek için DISCOURSE_ENABLE_CORS env değişkeni doğru olarak ayarlanmalı." + use_admin_ip_whitelist: "Yöneticiler, sadece Taranmış IP listesinde tanımlanmış bir IP adresinden erişim sağlıyorlarsa giriş yapabilirler. (Yönetici > Kayıtlar > Taranmış IP'ler)" top_menu: "Anasayfa navigasyonunda nelerin, hangi sırada yer alacağını belirleyin. Örneğin en sonIyeniIokunmamışIkategorilerIen popülerIokunmuşlarIgönderilenlerIişaretlenenler" post_menu: "Gönderi menüsündeki öğelerin hangi sırada yer alacağını belirleyin. Örnek: beğen|düzenle|bayrakla|sil|paylaş|işaretle|cevapla" post_menu_hidden_items: "Gönderi menüsündeki maddeler, genişletme üç noktasına tıklanmadığı takdirde otomatik olarak gizlenir. " @@ -719,14 +710,15 @@ tr_TR: suppress_reply_directly_above: "Bu gönderinin direk üstünde sadece tek bir cevap varsa, gönderideki açılabilir hangi-cevaba-istinaden-cevapla bölümünü gösterme." suppress_reply_when_quoting: "Gönderi cevabı alıntılarsa, gönderideki açılabilir hangi-cevaba-istinaden-cevapla bölümünü gösterme." max_reply_history: "Hangi-cevaba-istinaden-cevapla bölümü açılınca gösterilecek en fazla cevap sayısı" - experimental_reply_expansion: "Hangi-cevaba-istinaden-cevapla bölümü açılınca ara cevapları gizle (deneysel)" topics_per_period_in_top_summary: "Popüler konular özetinde gösterilen popüler konu sayısı." topics_per_period_in_top_page: "'Daha Fazla Göster' ile genişletilen popüler konular bölümünde gösterilecek popüler konu sayısı. " redirect_users_to_top_page: "Yeni ve uzun süredir giriş yapmamış kullanıcıları otomatik olarak Popüler sayfasına yönlendir." + top_page_default_timeframe: "Üst sayfa görünümü için varsayılan zaman aralığı" show_email_on_profile: "Kullanıcının e-posta adresini profilinde göster (sadece kendilerine ve site görevlilerine gözükür)" email_token_valid_hours: "Parolamı unuttum / hesap etkinleştirme jetonları (n) saat geçerlidir." email_token_grace_period_hours: "Parolamı unuttum / hesabı etkinleştir jetonları kullanıldıktan sonra (n) saat boyunca hala geçerlidir." enable_badges: "Rozet sistemini etkinleştir" + enable_whispers: "Bu konu içerisinde yetkililerin birbirleriyle gizli olarak iletişim kurmasına izin ver. (deneyseldir)" allow_index_in_robots_txt: "robots.txt dosyasında bu sitenin arama motorları tarafından indekslenmesine izin verildiğini belirt." email_domains_blacklist: "Kullanıcıların kayıt olurken kullanamayacağı e-posta alan adlarının, dikey çizgilerle ayrıştırılmış listesi. Örneğin: mailinator.com|trashmail.net" email_domains_whitelist: "Kullanıcıların kayıt olurken kullanmak ZORUNDA olduğu e-posta alan adlarının, dikey çizgilerle ayrıştırılmış listesi. UYARI: Bu listede yer almayan e-posta alan adları kabul edilmeyecektir!" @@ -756,6 +748,7 @@ tr_TR: sso_not_approved_url: "Bu bağlantıya onaylanmamış SSO hesaplarını yönlendir." enable_local_logins: "Yerel kullanıcı adı ve parola bazlı hesap girişlerini etkinleştir. (Not: davetiyelerin çalışabilmesi için bu ayarın etkinleştirilmesi gerekli)" allow_new_registrations: "Yeni kayıtlara izin ver. Yeni hesap oluşturulmasını engellemek için burayı işaretlemeyin." + enable_signup_cta: "Geri dönen anonim kullanıcılara hesap oluşturmaları için bir uyarı göster." enable_yahoo_logins: "Yahoo doğrulamasını etkinleştir" enable_google_oauth2_logins: "Google Oauth2 doğrulamasını etkinleştir. Bu Google'ın şu an desteklediği doğrulama metodu. Anahtar ve secret gerektirir." google_oauth2_client_id: "Google uygulamanıza ait Müşteri ID'si." @@ -775,6 +768,8 @@ tr_TR: backup_frequency: "Hangi sıklıkta bir site yedeği oluştururuz, gün olarak." enable_s3_backups: "Tamamlanınca yedeklemeleri S3'e yükle. ÖNEMLİ: Dosyalar ayarında doğru S3 girilmesini gerektirir" s3_backup_bucket: "Yedeklemelerin yüklenmesi için uzak biriktirme yeri. UYARI: Özel bir biriktirme yeri olduğundan emin olun" + backup_time_of_day: "Yedeklemenin yapılacağı UTC zaman" + backup_with_uploads: "Yüklemeleri planlanmış yedeklemlere dahil et. Etkisizleştirilirse sadece veritabanı yedeklenecek." active_user_rate_limit_secs: "'last_seen_at' alanını ne kadar sıklıkta güncelliyoruz, saniye olarak" verbose_localization: "UI'da genişletilmiş yerelleştirme ipuçlarını göster" previous_visit_timeout_hours: "Ziyaretin üzerinden burada belirtilen saat kadar süre geçtiğinde, ziyareti \"bir önceki\" olarak nitelendir" @@ -806,6 +801,7 @@ tr_TR: avatar_sizes: "Otomatik üretilen avatar ölçülerinin listesi." external_system_avatars_enabled: "Dışsal sistem avatarları hizmeti kullan." external_system_avatars_url: "Dışsal sistem avatarları hizmetinin URL'i. İzin verilen değiştirimler şunlardır: {username} {first_letter} {color} {size}" + default_opengraph_image_url: "Varsayılan opengraph imajının URL'si." enable_flash_video_onebox: "Kutularda swf ve flv (Adobe Flash) yerleştirmelerine izin ver. UYARI: güvenlik açıkları doğurabilir" default_invitee_trust_level: "Davet edilen kullanıcılar için varsayılan güven seviyesi (0-4)." default_trust_level: "Tüm yeni kullanıcılar için varsayılan güven seviyesi (0-4). DİKKAT! Bu ayarı değiştirmeniz ciddi spam riski doğurabilir." @@ -819,25 +815,20 @@ tr_TR: tl2_requires_likes_received: "Bir kullanıcının güven seviyesi 2'ye yükseltilmeden önce alması gereken beğeni sayısı." tl2_requires_likes_given: "Bir kullanıcının güven seviyesi 2'ye yükseltilmeden önce vermesi gereken beğeni sayısı." tl2_requires_topic_reply_count: "Bir kullanıcının güven seviyesi 2'ye yükseltilmeden önce cevaplaması gereken konu sayısı." - tl3_requires_days_visited: "Bir kullanıcının güven seviyesi 3'e yükseltimeye hak kazanması için, son 100 günde siteyi ziyaret etmesi gereken en az gün sayısı. (0 - 100)" - tl3_requires_topics_replied_to: "Bir kullanıcının güven seviyesi 3'e yükseltilmeye hak kazanması için son 100 günde cevap yazması gereken en az konu sayısı. (0 ya da daha fazla)" - tl3_requires_topics_viewed: "Bir kulanıcının güven seviyesi 3'e yükseltilmeye hak kazanması için, son 100 gün içinde oluşturulmuş konulardan görüntülemesi gereken yüzde oranı. (0 ile 100 arası)" - tl3_requires_posts_read: "Bir kulanıcının güven seviyesi 3'e yükseltilmeye hak kazanması için, son 100 gün içinde oluşturulmuş gönderilerden görüntülemesi gereken yüzde oranı. (0 ile 100 arası)" tl3_requires_topics_viewed_all_time: "Bir kullanıcının güven seviyesi 3'e yükselmeye hak kazanması için görüntülemesi gereken toplam en az konu sayısı." tl3_requires_posts_read_all_time: "Bir kullanıcının güven seviyesi 3'e yükselmeye hak kazanması için görüntülemesi gereken toplam en az gönderi sayısı." - tl3_requires_max_flagged: "Bir kullanıcının güven seviyesi 3'e yükseltilmeye hak kazanması için, son 100 gün içinde x farklı kullanıcı tarafından x adetten fazla gönderisinin bayraklanmamış olmaması gerekir. x bu ayara verilen değerdir. (0 ya da daha yüksek) " tl3_promotion_min_duration: "Bir kullanıcının güven seviyesi 2'ye düşürülebilmesi için güven seviyesi 3'te geçirmesi gereken en az gün sayısı." - tl3_requires_likes_given: "Bir kullanıcının güven seviyesi 3'e yükseltilmeye hak kazanması için son 100 günde vermesi gereken en az beğeni sayısı. " - tl3_requires_likes_received: "Bir kullanıcının güven seviyesi 3'e yükseltilmeye hak kazanması için son 100 günde alması gereken en az beğeni sayısı. " tl3_links_no_follow: "Güven seviyesi 3'teki kullanıcılar tarafından paylaşılan linklerdeki rel=nofollow'u kaldırma." min_trust_to_create_topic: "Yeni bir konu oluşturmak için gereken en az güven seviyesi. " min_trust_to_edit_wiki_post: "Wiki olarak işaretlenmiş bir gönderiyi düzenleyebilmek için gereken en az güven seviyesi." + min_trust_to_send_messages: "Özel bir mesaj oluşturabilmek için gerekli olan güven düzeyi." newuser_max_links: "Yeni bir kullanıcının bir gönderiye ekleyebileceği bağlantı sayısı." newuser_max_images: "Yeni bir kullanıcının bir gönderiye ekleyebileceği resim sayısı." newuser_max_attachments: "Yeni bir kullanıcının bir gönderiye ekleyebileceği dosya sayısı." newuser_max_mentions_per_post: "Yeni bir kullanıcının bir gönderi içinde kullanabileceği en fazla @isim bildiri sayısı." newuser_max_replies_per_topic: "Yeni bir kullanıcının tek bir konu içerisinde, başka bir kullanıcı ona cevap yazana kadar, girebileceği en fazla cevap sayısı. " max_mentions_per_post: "Bir kullanıcının bir gönderi içinde kullanabileceği en fazla @isim bildiri sayısı." + max_users_notified_per_group_mention: "Grubun bahsi geçtiğinde bildirim alabilecek maksimum kullanıcı sayısı (Eğer eşik uyuşursa bildirim yapılmayacak)" create_thumbnails: "Gönderiye sığmayacak kadar büyük olan görseller için küçük resimler ve lightbox resimleri oluştur." email_time_window_mins: "Kullanıcılara, gönderilerini düzenlemelerine ve tamamlamalarına fırsat vermek için herhangi bir bildiri e-postası göndermeden önce (n) dakika bekleyin." email_posts_context: "Genel durumu göstermek amaçlı, bildiri e-postalarında yer alacak önceki cevap sayısı." @@ -845,6 +836,7 @@ tr_TR: title_max_word_length: "Konu başlığında kullanılan bir kelime için izin verilen en fazla karakter sayısı" title_min_entropy: "Konu başlığı için gereken en az entropi (tekil karakter, ingilizce-dışı karakterler daha fazla sayılır)" body_min_entropy: "Gönderi içeriği için gereken en az entropi (tekil karakter, ingilizce-dışı karakterler daha fazla sayılır)" + allow_uppercase_posts: "Konu başlığı yada gönderi metninin tümünün büyük harf kullanılarak girilebilmesine izin ver." title_fancy_entities: "SmartyPants tarzında, konu başlıklarında ASCII karakterlerini süslü HTML öğelerine çevir: http://daringfireball.net/projects/smartypants/" min_title_similar_length: "Bir başlığın benzer konular için kontrolünün yapılmasından önce sahip olması gereken en az uzunluk." min_body_similar_length: "Bir gönderi metninin benzer konular için kontrolünün yapılmasından önce sahip olması gereken en az uzunluk." @@ -873,6 +865,8 @@ tr_TR: newuser_spam_host_threshold: "Yeni bir kullanıcı, `newuser_spam_host_posts` gönderileri içerisinde aynı makineye, kaç kere bağlantı paylaşınca spam olarak algılansın." white_listed_spam_host_domains: "Spam barındırma testinden hariç tutulan alan adı listesi. Yeni kullanıcıların, bu alan adlarına bağlantı içeren gönderi oluşturmaları hiç bir zaman engellenmeyecek." staff_like_weight: "Görevlilerin beğenilere verilecek ekstra ağırlık faktörü." + topic_view_duration_hours: "Her N saatte IP/Kullanıcı başına bir kez yeni konu görüntülemesi say" + user_profile_view_duration_hours: "Her N saatte IP/Kullanıcı başına bir kez yeni profil görüntülemesi say" levenshtein_distance_spammer_emails: "Spam e-postaları eşleştirilirken, bulanık eşleşme için tahammül edilecek karakter sayısı farklılığı." max_new_accounts_per_registration_ip: "Eğer bu IP'den güven seviyesi 0 olan halihazırda (n) hesap varsa (hiçbiri görevli, GS2 ya da daha yüksek seviyede biri değilse), bu IP'den yeni üyelik kabul etme. " min_ban_entries_for_roll_up: "Topla butonuna tıklandığında, (N) adetten fazla giriş varsa yeni bir subnet engelleme girişi yaratılacak." @@ -916,7 +910,6 @@ tr_TR: automatically_download_gravatars: "Hesap oluşturma veya e-posta değişikliği esnasında kullanıcılar için Gravatarları indir" digest_topics: "Özet e-postalarda yer alacak en fazla konu sayısı. " digest_min_excerpt_length: "Özet e-postalarında, gönderi alıntılarında olması gereken en az karakter sayısı." - suppress_digest_email_after_days: "Siteye (n) günden fazla süredir uğramayan kullanıcılar için özet e-posta gönderimini durdur" disable_digest_emails: "Tüm kullanıcılar için özet e-postalarını devre dışı bırak." detect_custom_avatars: "Kullanıcıların özel profil resimleri yükleyip yüklemediklerini kontrol et ya da etme." max_daily_gravatar_crawls: "Discourse'un gün içinde özel avatarlar için Gravatar'ı en fazla kaç kere kontrol edeceği." @@ -926,15 +919,15 @@ tr_TR: allow_anonymous_posting: "Kullanıcıların anonim moda geçebilmelerine izin ver" anonymous_posting_min_trust_level: "Anonim gönderi oluşturabilmeyi etkinleştirebilmek için gereken en az güven seviyesi" anonymous_account_duration_minutes: "Anonimliği koruyabilmek için, her kulanıcı için her N dakikada bir yeni bir anonim hesap oluştur. Örnek: 600'e ayarlanırsa, son gönderi üzerinden 600 dakika geçer geçmez VE kullanıcı anonim moddaysa, yeni bir anonim hesap oluşturulur." + hide_user_profiles_from_public: "Anonim kullanıcılar için kullanıcı kartlarını, kullanıcı profillerini ve kullanıcı dizinini devre dışı bırak" allow_profile_backgrounds: "Kullanıcıların profillerine arkaplan eklemesine izin ver." - sequential_replies_threshold: "Kullanıcının ardarda çok fazla cevap gönderdiğine dair uyarı alması için, bir konuda üstüste yapması gereken gönderi sayısı. " enable_mobile_theme: "Mobil cihazlar mobil uyumlu temayı kullanır, dilerse masaüstü görünüme geçebilirler. Eğer özel, duyarlı bir stil kullanıyorsanız bunu devredışı bırakın." dominating_topic_minimum_percent: "Konuyu domine ettiğine dair uyarı almadan önce konudaki gönderilerin yüzde kaçının kullanıcıya ait olması gerekir." daily_performance_report: "NGINX kayıtlarını analiz edip detaylı bir şekilde günlük Yetkili kategorisinde bir konu içerisinde paylaş." suppress_uncategorized_badge: "Kategorisiz konular için olan rozeti konu listesinde gösterme." - permalink_normalizations: "Kalıcı bağlantıları eşleştirmeden önce aşağıdaki regex'i uygula, mesela: /(\\/topic.*)\\?.*/\\1 konu yönlendirmelerindeki sorgu dizelerini kaldırır. Formatlama regex+string, yakalamalara erişmek \\1 vs." global_notice: "Tüm ziyaretçilere İVEDİ ACİL DURUM global manşet uyarısı göster, saklamak için boş bırakın (HTML kullanılabilir)." disable_edit_notifications: " 'download_remote_images_to_local' etkin olduğunda, sistem kullanıcısından gelen düzenleme bildirilerini devre dışı bırakır" + automatically_unpin_topics: "Kullanıcı sayfa sonuna eriştiğinde tutturulmuş konuları otomatik olarak sayfadan ayır." full_name_required: "Kullanıcı profili için tam ad zorunlu bir alandır." enable_names: "Kullanıcıların tam adlarını profillerde, kullanıcı kartlarında ve e-postalarda göster. Tam adların hiç bir yerde görünmemesi için devre dışı bırak." display_name_on_posts: "Gönderilerde @kullanıcıadı'na ek olarak kullanıcının tam adını da göster." @@ -951,20 +944,19 @@ tr_TR: embed_username_key_from_feed: "Beslemeden Discourse kullanıcı adını çekmek için kullanılacak anahtar" embed_truncate: "Yerleştirilmiş gönderileri kırp." embed_post_limit: "Yerleştirilecek en fazla gönderi sayısı." + embed_username_required: "Konu olşuturmak için kullanıcı gereklidir." embed_whitelist_selector: "Yerleştirmelerde kullanılmasına izin verilen öğeler için CSS seçicisi." embed_blacklist_selector: "Yerleştirmelerden çıkartılmış öğeler için CSS seçicisi." notify_about_flags_after: "Bu kadar saat geçmesine rağmen hala ilgilenilmemiş bayraklar varsa, contact_email adresine e-posta gönder. Devre dışı bırakmak için 0 girin. " enable_cdn_js_debugging: "/logs 'ların asli hataları tüm js içeriklerine crossorigin izinleri ekleyerek göstermesine izin ver." show_create_topics_notice: "Eğer sitede herkese açık konu sayısı 5'den az ise, adminden yeni konular oluşturmasını isteyen bir uyarı mesajı göster. " delete_drafts_older_than_n_days: (n) günden eski taslakları sil. - show_logout_in_header: "Başlık çubuğundaki kullanıcı açılır listesinde oturumu kapatı göster" - vacuum_db_days: "Geçiş sonra DB alanı geri kazanmak için TAM VAKUM ANALİZİ'ni çalıştırın (devre dışı bırakmak için 0 girin)" + vacuum_db_days: "Geçiş sonrası DB alanı geri kazanmak için TAM VAKUM ANALİZİ'ni çalıştırın (devre dışı bırakmak için 0 girin)" prevent_anons_from_downloading_files: "Anonim kullanıcıların eklenti indirebilmesini önle. DİKKAT: Bu ayar, eklenti olarak gönderilen resim-dışı site içeriklerinin de çalışmasını engelleyebilir." slug_generation_method: "Slug üretim yöntemi seçin. 'kodlanmış' seçeneği yüzde kodlamalı metin oluşturur. 'hiçbiri' seçeneği slug'ı devre dışı bırakır." enable_emoji: "Emojiyi aktifleştir" emoji_set: "Emojinizi nasıl isterdiniz?" enforce_square_emoji: "Tüm emojileri kare en-boy oranına zorla" - approve_post_count: "Yeni bir kullanıcıdan onaylanması gereken gönderi sayısı" approve_unless_trust_level: "Bu güven seviyesi altındaki kullanıcılardan gelen gönderilerin onaylanması gerekir" notify_about_queued_posts_after: "Bu kadar saat geçmesine rağmen hala incelenmemiş konular varsa, iletişim adresine e-posta gönder. Devre dışı bırakmak için 0 girin." default_email_digest_frequency: "Öntanımlı olarak kullanıcılar hangi sıklıkta özet e-postalar alırlar." @@ -979,6 +971,7 @@ tr_TR: default_other_dynamic_favicon: "Tarayıcı simgesinde, öntanımlı olarak, yeni/güncellenmiş konu sayısını göster." default_other_disable_jump_reply: "Kullanıcılar cevapladıktan sonra, öntanımlı olarak, onların gönderilerine atlama." default_other_edit_history_public: "Gönderi değişikliklerini, öntanımlı olarak, herkese açık yap." + default_topics_automatic_unpin: "Kullanıcı sayfa sonuna eriştiğinde tutturulmuş konuları otomatik olarak sayfadan ayır." default_categories_watching: "Öntanımlı olarak, izlenen kategorilerin listesi." default_categories_tracking: "Öntanımlı olarak, takip edilen kategorilerin listesi." default_categories_muted: "Öntanımlı olarak, sesi kısılan kategorilerin listesi." @@ -997,6 +990,7 @@ tr_TR: invalid_string_max: "En fazla %{max} karakter olabilir." invalid_reply_by_email_address: "Değer '%{reply_key}' içermeli ve bildiri e-postasından farklı olmalı." notification_types: + group_mentioned: "%{link} sayfasında %{group_name} hakkında bahsedildi." mentioned: "%{display_username} sizden bahsetti: %{link}" liked: "%{display_username} gönderinizi beğendi: %{link}" replied: "%{display_username} gönderinize cevap verdi: %{link}" @@ -1006,7 +1000,6 @@ tr_TR: moved_post: "%{display_username} gönderinizi buraya taşıdı: %{link}" private_message: "%{display_username} sana bir mesaj gönderdi: %{link}" invited_to_private_message: "%{display_username} seni bir mesaja davet etti: %{link}" - invited_to_topic: "%{display_username} seni bir konuya davet etti: %{link}" invitee_accepted: "%{display_username} davetinizi kabul etti" linked: "%{display_username} size %{link} sayfasında bağlantı verdi" granted_badge: "%{link} kazandınız" @@ -1016,11 +1009,6 @@ tr_TR: category: 'Kategoriler' topic: 'Sonuçlar' user: 'Kullanıcılar' - sso: - not_found: "Hesap aranamıyor ya da oluşturulamıyor, site admini ile iletişime geçin" - account_not_approved: "Hesap henüz onaylanmamış, onaylandığında e-posta ile haberdar edileceksiniz" - unknown_error: "Bilgi güncellenirken hata oluştu, site admini ile iletişime geçin" - timeout_expired: "Seansınız zaman aşımına uğradı, lütfen tekrar giriş yapmayı deneyin" original_poster: "Orjinal Poster" most_posts: "En Çok Gönderi" most_recent_poster: "En Son Gönderen" @@ -1095,16 +1083,16 @@ tr_TR: characters: "sadece rakam, harf ve altçizgi bulundurabilir " unique: "özgün olmalı" blank: "bulunmalı" - must_begin_with_alphanumeric: "bir harf, rakam ya da alt çizgi ile başlamalı" - must_end_with_alphanumeric: "bir harf, sayı yada alt tire ile bitmeli" must_not_contain_two_special_chars_in_seq: "2 ya da daha fazla uzunlukta özel karakter dizisi (.-_) içermemeli" - must_not_contain_confusing_suffix: ".json ya da .png gibi kafa karıştırıcı bir son ek içermemeli" email: not_allowed: "için o e-posta sağlayıcısına izin verilmiyor. Lütfen başka bir email adresi kullanın. " blocked: "için izin yok." ip_address: blocked: "Mevcut IP adresiniz üzerinden yeni kayıt işlemine izin verilmiyor." max_new_accounts_per_registration_ip: "Mevcut IP adresiniz üzerinden yeni kayıt işlemine izin verilmiyor. (Belirlenen maksimum limit aşıldı.) Bir yetkili ile iletişime geçin." + flags_reminder: + subject_template: + other: "İlgilenilmesi gereken %{count} bayrak var" invite_mailer: subject_template: "%{invitee_name} sizi %{site_domain_name} sitesindeki '%{topic_title}' adlı konuya davet etti. " text_body_template: "%{invitee_name} sizi \n\n> %{site_title} -- %{site_description} \n\nsitesindeki\n\n> **%{topic_title}**\n>\n> %{topic_excerpt}\n\ntartışmasına davet ediyor.\n\nEğer ilgileniyorsanız, aşağıdaki bağlantıya tıklayın:\n\n%{invite_link}\n\nBu davet güvenilir bir kullanıcı tarafından gönderilmiştir, cevap yazarak tartışmaya hemen katılabilirsiniz.\n" @@ -1133,25 +1121,10 @@ tr_TR: (Eğer yukarıdaki bağlantının süresi dolmuşsa e-posta adresinizle giriş yaparken "Parolamı unuttum" bağlantısına tıklayınız.) test_mailer: subject_template: "[%{site_name}] E-posta Ulaştırma Testi" - text_body_template: "Bu aşağıdaki adresten gönderilen bir test e-postasıdır.\n\n[**%{base_url}**][0]\n\nE-postaların ulaştırılması karışık bir meseledir. Öncelikle dikkat etmeniz gereken bir kaç önemli nokta:\n\n- Site ayarlarınızda 'bildiri e-postaları' için gönderen adresini doğru ayarladığınıza emin olun. **Yolladığınız e-postalarda \"gönderen\" adresi olarak belirlediğiniz alan adı, e-postalarınızın doğrulanacağı alan adıdır.**\n\n- E-posta başlıklarındaki önemli ipuçlarını yakalayabilmek için e-posta istemcinizde e-postaların kaynak kodunu nasıl görüntüleyebileceğinizi öğrenin. Gmail'da, her e-postanın sağ üstündeki açılır menüden \"show original\" opsiyonuna tıklayabilirsiniz.\n\n- **ÖNEMLİ:** ISP'nizde e-posta yollamak için kullanıdığınız alan adlarıyla IP adreslerinin eşleşmesini sağlayacak bir reverse DNS kaydı var mı? Buradan [reverse PTR kayıtlarınızı test edin][2]. Eğer ISP'niz doğru\ - \ reverse DNS pointer kaydı girmezse, büyük ihtimal e-postalarınızın hiç biri yerine ulaşmayacaktır.\n\n- Alan adınızın [SPF kaydı][8] doğru mu? Buradan [SPF kaydınızı test edin][1]. SPF için doğru resmi kayıt tipinin TXT olduğunu unutmayın. \n\n- Alan adınızın [DKIM kaydı][3] doğru mu? Bu e-postaların ulaştırılabilirliğini ciddi şekilde artıracaktır. Buradan [DKIM kaydınızı test edin][7].\n\n- Kendi e-posta sunucunuzu kullanıyorsanız, e-posta sunucunuzun IPlerinin [hiç bir e-posta karalistesine][4] alınmadığına emin olun. Sunucunuzun, kesinlikle, HELO mesajında DNS olarak çözümlenen tam tanımlanmış bilgisayar adı da gönderdiğinden emin olun. Göndermemesi, e-postanızın bir çok e-posta servisi tarafından reddedilmesine sebep olacaktır. \n\n(En kolayı, küçük topluluklar için rahat rahat yetecek sayıda bedava email yollama paketleri içeren, [Mandrill][md] veya [Mailgun][mg] veya [Mailjet][mj]'te\ - \ ücretsiz hesap açmak. Tabi, gene, DNS ayarlarınızda SPF ve DKIM kayıtlarını oluşturmanız gerekecek!) \n\nUmarız bu e-posta ulaştırma testini başarıyla atlatmışsınızdır. \n\nİyi şanslar, \n\n[Discourse](http://www.discourse.org)'tan arkadaşlarınız \n\n[0]: %{base_url} \n[1]: http://www.kitterman.com/spf/validate.html \n[2]: http://mxtoolbox.com/ReverseLookup.aspx \n[3]: http://www.dkim.org/ \n[4]: http://whatismyipaddress.com/blacklist-check \n[7]: http://dkimcore.org/tools/dkimrecordcheck.html \n[8]: http://www.openspf.org/SPF_Record_Syntax [md]: http://mandrill.com [mg]: http://www.mailgun.com/ [mj]: https://www.mailjet.com/pricing\n" new_version_mailer: subject_template: "[%{site_name}] Yeni Discourse versiyonu, güncelleme var" - text_body_template: | - [Discourse'un](http://www.discourse.org) yeni versiyonu hazır. Sizin kullandığınız versiyon: %{installed_version} Yeni versiyon: **%{new_version}** Aşağıdakileri uygulayabilirsiniz: - Yenilikleri [GitHub değişiklikler listesinde] görüntüleyebilirsiniz (https://github.com/discourse/discourse/commits/master). - [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade) sayfasını ziyaret ederek ve "Güncelle" butonuna basarak yeni versiyona geçebilirsiniz. - Haberler, tartışmalar ve Discourse ile ilgili destek için burayı ziyaret edebilirsiniz: [meta.discourse.org](http://meta.discourse.org) new_version_mailer_with_notes: subject_template: "[%{site_name}] güncellemesi var" - text_body_template: | - [Discourse'un](http://www.discourse.org) yeni bir versiyonu hazır. Sizin kullandığınız versiyon: %{installed_version} Yeni versiyon: **%{new_version}** Aşağıdakileri uygulayabilirsiniz: - Yenilikleri [GitHub değişiklikler listesinde] görüntüleyebilirsiniz (https://github.com/discourse/discourse/commits/master). - [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade) sayfasını ziyaret ederek ve "Güncelle" butonuna basarak yeni versiyona geçebilirsiniz. - Haberler, tartışmalar ve Discourse ile ilgili destek için burayı ziyaret edebilirsiniz: [meta.discourse.org](http://meta.discourse.org) ### Yeni sürüm notları %{notes} - flags_reminder: - flags_were_submitted: - other: "Bu bayraklar %{count} saat önce verildi." - please_review: "Lütfen onları inceleyin." - post_number: "gönderi" - how_to_disable: '"Bayraklarla ilgili bilgilendirme süresi" ayarından bu hatırlatma e-postasının gönderimini devre dışı bırakabilir ya da sıklığını değiştirebilirsiniz. ' - subject_template: - other: "İlgilenilmesi gereken %{count} bayrak var" queued_posts_reminder: subject_template: other: "[%{site_name}] %{count} konu incelenmeyi bekliyor." @@ -1187,13 +1160,6 @@ tr_TR: Ancak, eğer gönderiniz kullanıcılar tarafından ikinci kere gizlenirse, görevliler tarafından incelenene kadar gizli kalacaktır - ve hesabınızın askıya alınması dahil olmak üzere farklı önlemler alınabilir. Daha fazla bilgi için, lütfen [topluluk yönergelerine bakın](%{base_url}/guidelines). - usage_tips: - text_body_template: "Hemen başlayabilmeniz için bir kaç pratik tavsiye: \n\n## Okuma\n\nDaha fazla okumak için, **sayfayı aşağı kaydırmanız yeterli!** \n\nYeni cevaplar ve konular oluşturuldukça, otomatik olarak görünecekler. \n\n## Gezinme\n\n- Arama, kullanıcı sayfanız veya menü için **sağ üstteki ikonlu butona** tıklayın. \n\n- Herhangi bir konu başlığı sizi bir sonraki okunmamış gönderiye götürür. En üst veya en alta gitmek için gönderi sayısına veya son cevap tarihini tıklayın.\n\n \n\n- Bir konuyu okurken, tüm navigasyonla ilgili kontroller için sağ alttaki yeşil ilerleme barını seçin. Hızlıca en yukarıya gitmek için konu başlığına tıklayın. Klavye kısayollarını görüntülemek için ? tuşuna basın. \n\n \n\n## Cevaplama \n\n- **Genel olarak konuya** cevap vermek için, sayfanın en altındaki Cevapla butonunu kullanın. \n\n- **Belirli bir kişiye** cevap vermek için, o gönderinin altında bulunan Cevapla butonunu kullanın. \n\n- **Yeni bir konu\" oluşturarak cevaplamak için, gönderinin sağında çıkan ikonuna tıklayın. Eski ve yeni konular birbirleriyle otomatik olarak ilişkilendirilecek.\n\nAlıntı yapmak için, alıntı yapmak istediğiniz metni seçin ve sonrasında herhangi bir Cevapla butonuna tıklayın. Çoklu alıntılar için adımları tekrarlayın! \n\n \n\nBirine cevabınızla ilgili bildiri gitmesini istiyorsanız, o kişinin isminden bahsedin. Kullanıcı adı seçimine başlamak için `@` yazın. \n\n \n\n[Standart Emoji](http://www.emoji.codes/) için, `:` yazın ya da gülücük `;)` atın \n\nBir bağlantı için özet oluşturmak istiyorsanız, bağlantıyı kopyalayıp tek başına bir satıra yapıştırın:\n\n\n\n## Aksiyonlar\n\nHer gönderinin altında aksiyon butonları vardır. \n\nBirine gönderisini beğendiğinizi belirtmek istiyorsanız, **beğen** butonunu\ - \ kullanın. Sevginizi paylaşın!\n\nBirinin gönderisiyle ilgili bir sorun görüyorsanız, özelden bu kişileri veya [görevlileri](%{base_url}/about) uyarmak için **bayrakla** butonunu kullanın. **Paylaş** butonu aracılığıyla gönderiye bir bağlantı paylaşabilir, veya **işaretle** butonu ile gönderiyi işaretleyip sonrasında kullanıcı sayfanızdan kolayca ulaşabilirsiniz. \n\n## Bildiriler \n\nBiri gönderinize cevap verir, gönderinizi alıntılar ya da `@kullanıcıadı` nızdan bahsederse, sayfanızın en sağ üstünde bir sayı hemen beliriverir. Bu sayıya tıklayarak **bildiriler**inize ulaşabilirsiniz. \n\n\n\nBir cevabı kaçıracaksınız diye kaygılanmayın – çevrimiçi olmadığınız zaman gelen bildiriler size e-postalanır.\n\n## Seçenekleriniz\n\nÜzerinden henüz **iki gün geçmemiş** tüm konular yeni sayılır. \n\n**Aktif\ - \ olarak katıldığınız** (oluşturduğunuz, cevapladığınız, veya uzun bir süre okuduğunuz) tüm sohbetler otomatik olarak takip edilir. \n\nBu konuların yanında, yeni ve okunmamışlar gönderilerin sayılarını gösteren mavi işaretler göreceksiniz: \n\n \n\nHerhangi bir konunun bildiri ayarını o konunun altında bulunan bildiri kontrolü aracılığıyla değiştirebilirsiniz. \n\n \n\nBildiri ayarlarını kategori bazında da değiştirebilirsiniz, eğer belirli bir kategorideki her yeni konuyu gözlemek istiyorsanız. Bu ayarların herhangi birini değiştirmek için, [kullanıcı ayarlarınıza](%{base_url}/my/preferences) göz atın. \n\n## Topluluğun Güveni\n\nBurada sohbetlere katıldıkça, topluluğun güvenini kazanırsınız,\ - \ onun tam bir parçası haline gelirsiniz ve yeni kullanıcılar için konulan limitler kalkar. Yeterli yükseklikteki [güvenlik seviyelerinde](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924) ise topluluğumuzu birlikte yönetmemize yardımcı olabilmenizi sağlayacak yetkiler kazanırsınız.\n" welcome_user: subject_template: "%{site_name} sitesine hoşgeldiniz!" text_body_template: "%{site_name} sitesine katıldığınız için teşekkür ederiz, hoşgeldiniz!\n\n%{new_user_tips}\n\nBiz her zaman [medeni topluluk davranışına](%{base_url}/guidelines) inanıyoruz. \n\nZiyaretinizin keyfini çıkarın!\n\n(Eğer yeni bir kullanıcı olarak [görevlilerle](%{base_url}/about) iletişim kurmak isterseniz, bu mesajı cevaplamanız yeterli.)\n" @@ -1249,20 +1215,11 @@ tr_TR: csv_export_failed: subject_template: "Dışarı veri aktarımı başarısız oldu" text_body_template: "Üzgünüz, dışarı veri aktarımı başarısız oldu. Lütfen kayıtları inceleyin veya bir görevli ile iletişime geçin." - email_reject_trust_level: - subject_template: "[%{site_name}] E-posta sorunu -- Yetersiz Güven Seviyesi" - text_body_template: | - Üzgünüz, ama %{destination} (titled %{former_title}) adresine göndermeye çalıştığınız e-posta başarısız oldu. - - Bu e-posta adresine yeni gönderiler oluşturmanız için, hesabınız yeterli güven seviyesine sahip değil. Yanlışlık olduğunu düşünüyorsanız, bir görevli ile iletişime geçin. email_reject_no_account: subject_template: "[%{site_name}] E-posta sorunu -- Bilinmeyen Hesap" - text_body_template: | - Üzgünüz, ama %{destination} (titled %{former_title}) adresine göndermeye çalıştığınız e-posta başarısız oldu. - - Bu e-posta adresine sahip bir kullanıcı bulunamadı. Başka bir e-posta adresinden göndermeyi deneyin ya da bir görevli ile iletişime geçin. email_reject_empty: subject_template: "[%{site_name}] E-posta sorunu -- İçerik Yok" + text_body_template: "Üzgünüz, ama %{destination} (titled %{former_title}) adresine göndermeye çalıştığınız e-posta başırısız oldu. \n\nE-postada herhangi bir cevap bulamadık.\n\nEğer bu mesajı alıyorsanız ve cevap eklediyseniz, daha basit bir biçimleme ile yeniden deneyin.\n\n\n\n" email_reject_parsing: subject_template: "[%{site_name}] E-posta sorunu -- Tanımlanamayan içerik" text_body_template: | @@ -1273,52 +1230,18 @@ tr_TR: Üzgünüz, ama %{destination} (titled %{former_title}) adresine göndermeye çalıştığınız e-posta başarısız oldu. Hesabınız o kategoride yeni konu oluşturabilmeniz için gereken ayrıcalıklara sahip değil. Yanlışlık olduğunu düşünüyorsanız, bir görevli ile iletişime geçin. - email_reject_post_error: - subject_template: "[%{site_name}] E-posta sorunu -- Gönderim hatası" - text_body_template: | - Üzgünüz, ama %{destination} (titled %{former_title}) adresine göndermeye çalıştığınız e-posta başarısız oldu. - - Bir kaç muhtemel neden: karmaşık format, çok uzun mesaj, çok kısa mesaj. Lütfen tekrar deneyin, sorun devam ederse websitesi üzerinden gönderin. - email_reject_post_error_specified: - subject_template: "[%{site_name}] E-posta sorunu -- Gönderim hatası" - text_body_template: | - Üzgünüz, ama %{destination} (titled %{former_title}) adresine göndermeye çalıştığınız e-posta başarısız oldu. - - Sebep: - - %{post_error} - - Sorunu düzeltebilirseniz, lütfen tekrar deneyin. email_reject_reply_key: subject_template: "[%{site_name}] E-posta sorunu -- Bilinmeyen Cevap Anahtarı" - text_body_template: | - Üzgünüz, ama %{destination} (titled %{former_title}) adresine göndermeye çalıştığınız e-posta başarısız oldu. - - Cevap anahtarı geçersiz ya da bulunamıyor, bu nedenle de bu mesajın neye cevaben gönderildiğini bilemiyoruz. Bir görevli ile iletişime geçin. - email_reject_destination: - subject_template: "[%{site_name}] E-posta sorunu -- Bilinmeyen Alıcı Adresi" - text_body_template: | - Üzgünüz, ama %{destination} (titled %{former_title}) adresine göndermeye çalıştığınız e-posta başarısız oldu. - - Gönderilen adreslerinin hiçbiri bilinmiyor. Site adresinin To: kısmında olduğundan (Cc: ya da Bcc: değil) ve görevliler tarafından sağlanan doğru email adresine yolladığınızdan emin olun. email_reject_topic_not_found: subject_template: "[%{site_name}] E-posta sorunu -- Konu Bulunamadı" - text_body_template: | - Üzgünüz, ama %{destination} (titled %{former_title}) adresine göndermek istediğiniz e-posta başarısız oldu. Konu bulunamadı, silinmiş olabilir. Yanlışlık olduğunu düşünüyorsanız, bir görevli ile iletişime geçin. email_reject_topic_closed: subject_template: "[%{site_name}] E-posta sorunu -- Konu Kapatıldı" text_body_template: | Üzgünüz, ama %{destination} (titled %{former_title}) adresine göndermek istediğiniz e-posta başarısız oldu. Konu kapatılmış. Yanlışlık olduğunu düşünüyorsanız, bir görevli ile iletişime geçin. email_reject_auto_generated: subject_template: "[%{site_name}] E-posta sorunu -- Otomatik Üretilmiş Cevap" - text_body_template: | - Üzgünüz, ama %{destination} (titled %{former_title}) adresine yollamak istediğiniz e-posta başarısız oldu. Otomatik olarak üretilmiş e-posta cevaplarını kabul edemiyoruz. Bir hata olduğuna inanıyorsanız, lütfen bir görevli ile iletişime geçin. email_error_notification: subject_template: "[%{site_name}] E-posta sorunu -- POP doğrulama hatası" - text_body_template: | - Mailler POP sunucusundan çağrılırken bir doğrulama hatası oluştu. - - Lütfen, [site ayarlarında](%{base_url}/admin/site_settings/category/email) POP bilgilerinin doğru şekilde düzenlendiğinden emin olun. too_many_spam_flags: subject_template: "Yeni hesap engellendi" text_body_template: | @@ -1331,25 +1254,10 @@ tr_TR: Daha fazla bilgi için lütfen [topluluk yönergelerine](%{base_url}/guidelines) bakın. blocked_by_staff: subject_template: "Hesap engellendi" - text_body_template: | - Merhaba. - - Bu, %{site_name} sitesinin, hesabınızın bir görevli tarafından engellendiğini bildirmek için gönderdiği otomatik bir mesajdır. - - Daha fazla bilgi için lütfen [topluluk yönergelerine](%{base_url}/guidelines) bakın. user_automatically_blocked: subject_template: "Topluluk bayrakları nedeniyle yeni kullanıcı %{username} engellendi" - text_body_template: | - Bu bir otomatik mesajdır. - - Yeni kullanıcı [%{username}](%{base_url}%{user_url}), gönderisi(leri) farklı kullanıcılar tarafından bayrakladığı için otomatik olarak engellendi. - - Lütfen [bayrakları inceleyin](%{base_url}/admin/flags). %{username} adlı kullancının haksız yere gönderi oluşturabilmesi engellendiyse, [bu kullanıcıya ait admin sayfasında](%{base_url}%{user_url}) engeli kaldır butonuna tıklayın. - - Bu tür engellemeleri tetikleyen eşik, site ayarları sayfasında `block_new_user` bölümünden değiştirilebilir. spam_post_blocked: subject_template: "Üst üste aynı bağlantıların paylaşılmasından ötürü %{username} adlı yeni kullanıcının gönderileri engelledi" - text_body_template: "Bu bir otomatik mesajdır.\n\n[%{username}](%{base_url}%{user_url}) adlı yeni kullanıcı %{domains} sitelerine bağlantı içeren birçok farklı gönderi oluşturmaya çalıştı, ancak bu gönderiler spam yaratmamaları için engellendi. Kullanıcı hala %{domains} sitelerine bağlantılı içermeyen yeni gönderiler oluşturabiliyor. \n\nLütfen [kullanıcıyı inceleyin](%{base_url}%{user_url}).\n\nBu tür engellemeleri tetikleyen `newuser_spam_host_threshold` ve `white_listed_spam_host_domains` değerleri site ayarları sayfasından değiştirilebilir.\n" unblocked: subject_template: "Hesabın engeli kaldırıldı" text_body_template: | @@ -1365,10 +1273,6 @@ tr_TR: download_remote_images_disabled: subject_template: "Uzaktaki resimlerin indirilmesi devre dışı bırakıldı" text_body_template: "`download_remote_images_to_local` ayarı harddisk alanı limiti `download_remote_images_threshold` aşıldığı için devre dışı bırakıldı." - unsubscribe_link: | - Bu e-postaların üyeliklerinden çıkmak için [user preferences](%{user_preferences_url})'i ziyaret edin. - - Bu belirli konuda bildirim almayı durdurmak için [buraya tıklayın](%{unsubscribe_url}). subject_re: "Cvp:" subject_pm: "[ÖM]" user_notifications: @@ -1376,95 +1280,21 @@ tr_TR: unsubscribe: title: "Aboneliği İptal Et" description: "Bu e-postalarla ilgilenmiyor musunuz? Sorun değil! Aşağıya tıklayarak aboneliğinizi hemen iptal edebilirsiniz:" - reply_by_email: "Karşılık vermek için, bu e-postayı cevaplayın ya da %{base_url}%{url} sayfasını internet tarayıcınızda ziyaret edin." - visit_link_to_respond: "Karşılık vermek için, %{base_url}%{url} sayfasını internet tarayıcınızda ziyaret edin." posted_by: "%{post_date} tarihinde %{username} tarafından gönderildi" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} sizi bir mesaja davet etti '%{topic_title}'" - text_body_template: |2 - - %{username} sizi bir mesaja davet etti - - > %{site_title} -- %{site_description} - - adresinde - - > **%{topic_title}** - > - > %{topic_excerpt} - - Mesajı görüntülemek için lütfen bu bağlantıyı ziyaret edin: %{base_url}%{url} - user_invited_to_topic: - subject_template: "[%{site_name}] %{username} sizi bir konuya davet etti '%{topic_title}'" - text_body_template: |2 - - %{username} sizi bir tartışmaya davet etti - - > %{site_title} -- %{site_description} - - adresinde - - > **%{topic_title}** - > - > %{topic_excerpt} - - Mesajı görüntülemek için lütfen bu bağlantıyı ziyaret edin: %{base_url}%{url} user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - - %{context} - - - --- - - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - - %{context} - - --- - - %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - - %{context} - - - --- - - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [ÖM] %{topic_title}" - text_body_template: | - %{message} - - - %{context} - - - --- - - %{respond_instructions} digest: why: "%{last_seen_at} tarihindeki son girişinizden beri %{site_link} sitesine olanların kısa bir özeti" subject_template: "[%{site_name}] Özet" @@ -1511,12 +1341,6 @@ tr_TR: Yeni hesabınıza ait bir parola oluşturmak için aşağıdaki bağlantıya tıklayın: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Yeni e-posta adresinizi onaylayın" - text_body_template: | - Aşağıdaki bağlantıya tıklayarak %{site_name} sitesindeki yeni e-posta adresinizi onaylayın: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "%{site_name} sitesinde hesabınız onaylandı!" text_body_template: "%{site_name} sitesine hoşgeldiniz! \n\n%{site_name} sitesindeki hesabınız bir görevli tarafından onaylandı.\n\nAşağıdaki linke tıklayın ve yeni hesabınızı aktive edin: %{base_url}/users/activate-account/%{email_token} \n\nEğer link tıklanabilir değilse, linki kopyalayıp tarayıcınızın adres çubuğuna yapıştırmayı deneyebilirsiniz. \n\n%{new_user_tips} \n\nBiz her zaman [medeni topluluk davranışına](%{base_url}/guidelines) inanıyoruz. \n\nZiyaretinizin keyfini çıkarın!\n\n(Eğer yeni bir kullanıcı olarak [görevlilerle](%{base_url}/about) iletişim kurmak isterseniz, bu mesajı cevaplamanız yeterli.)\n" @@ -1530,7 +1354,6 @@ tr_TR: Eğer yukarıdaki bağlantı tıklanabilir değilse, bağlantıyı kopyalayıp tarayıcınızın adres çubuğuna yapıştırmayı deneyin. page_not_found: - title: "Aradığınız sayfa bulunmuyor ya da gizli." popular_topics: "Popüler" recent_topics: "Yeni" see_more: "Daha fazla" @@ -1590,56 +1413,6 @@ tr_TR: title: "Üyelik Sözleşmesi" privacy_topic: title: "Gizlilik İlkeleri" - badges: - long_descriptions: - autobiographer: | - Bu rozet profilini doldurduğunda ve profil resmini seçtiğinde verilir. Kim olduğun ve nelerle ilgilendiğin hakkında topluluğa daha fazla bilgi vermen daha iyi ve daha yakın bir topluluğun oluşmasına yardım eder. - first_like: | - Bu rozet :heart: tuşunu kullanarak bir gönderiyi ilk kez beğendiğinizde verilir. Gönderileri beğenmek hemcins topluluk üyelerinin ilgi çekici, faydalı, havalı ve eğlenceli nelerin gönderildiğini bilmelerini sağlamak için mükemmel bir yoldur. Sevgiyi paylaş! - first_link: | - Bu rozet bir cevapta başka bir konuya bir bağlantı verdiğinde verilir. Konuları bağlamak, her iki yönde konular arasındaki ilişkiyi göstererek, hemcins okuyucuların ilgi çekici ve ilgili konuşmaları bulmalarına yardım eder. - first_quote: | - Bu rozet bir cevapta ilk kez bir gönderiden alıntı yaptığınızda verilir. Cevabında önceki gönderilerin ilgili bölümlerinden alıntı yapmak tartışmaların odaklanmış halde ve konu içinde tutulmasına yardımcı olur. - first_share: | - Bu rozet paylaş tuşunu kullanarak bir cevaba ya da konuya ilk kez bir bağlantı paylaştığında verilir. Bağlantıları paylaşmak dünyanın geri kalanıyla yapılan ilginç tartışmalarla gösteriş yapmak ve topluluğunu büyütmek için mükemmel bir yoldur. - read_guidelines: | - Bu rozet topluluk kurallarını okunmasına verilir. Bu basit kuralları benimsemek ve paylaşmak güvenli, eğlenceli ve sürdürülebilir bir topluluğun inşa edilmesine yardım eder. - reader: | - Bu rozet uzun bir konuyu okumaya verilir. Okumak temeldir. Yakından okumak tartışmayı takip etmene ve daha iyi, daha eksiksiz cevaplar yazmana yardım eder. - editor: | - Bu rozet gönderini değiştirmene verilir. Geliştirmek, küçük hataları gidermek ya da unuttuğun bir şeyi eklemek için gönderilerini değiştirmekten hiçbir zaman çekinme. - first_flag: | - Bu rozet bir gönderinin işaretlenmesine verilir. İşaretleme, topluluğunun sağlığı için çok önemlidir. Yönetici incelemesi gereken herhangi bir gönderi görürseniz lütfen işaretlemekten çekinmeyin. Ayrıca hemcins kullanıcılara mesajlar göndermek için işaretleme diyaloğunu da kullanabilirsiniz. - nice_share: | - Bu rozet bir gönderide paylaşılan bir bağlantının 25 yabancı ziyaretçi tarafından ziyaret edilmesine verilir. Tebrikler! İlginç tartışmalara bağlantıları arkadaşlarla paylaşmak topluluğumuzu büyütmek için harika bir yoldur. - welcome: | - Bu rozet bir gönderide ilk beğeninizi aldığınızda verilir. Tebrikler, hemcins topluluk üyelerinin ilginç, havalı ya da kullanışlı bulduğu bir şeyler gönderdin. - anniversary: | - Bu rozet en az bir gönderiye sahip olunan bir yıllık üyeliğe verilir. Buralarda olup topluluğumuza katkıda bulunduğunuz için teşekkür ederiz. - good_share: | - Bu rozet bir gönderide paylaşılan bir bağlantı, 300 yabancı ziyaretçi tarafından ziyaret edildiğinde verilir. İyi iş! Bir sürü yeni kişiye ilgi çekici bir tartışma gösterdin ve böylece büyümemize yardımcı oldun. - great_share: | - Bu rozet bir gönderide paylaşılan bir bağlantının 100 yabancı ziyaretçi tarafından ziyaret edilmesine verilir. Vay be! Bu topluluk için ilginç bir tartışmayı yeni kocaman bir izleyici kitlesine terfi ettirdin ve büyümemize önemli bir katkı sağladın. - nice_post: | - Bu rozet bir cevap 10 beğeni aldığında verilir. İyi iş! - nice_topic: | - Bu rozet bir konu 10 beğeni aldığında verilir. İyi iş! - good_post: | - Bu rozet bir cevap 25 beğeni aldığında verilir. İyi iş! - good_topic: | - Bu rozet bir konu 25 beğeni aldığında verilir. İyi iş! - great_post: | - Bu rozet bir gönderi 50 beğeni aldığında verilir. Vay be! - great_topic: | - Bu rozet bir cevap 50 beğeni aldığında verilir. Vay be! - basic: | - Bu rozet güven seviyesi 1'e ulaştığında verilir. Bir süredir buralarda olduğun ve topluluğumuzun ne hakkında olduğu konusunda birkaç konu okuduğun için teşekkür ederiz. Yeni kullanıcı kısıtlamaların kaldırıldı ve kişisel mesajlaşma, işaretleme, wiki düzenleme, resim ve birden çok bağlantı gönderme yeteneği gibi ana topluluk yeteneklerini aldın. - member: | - Bu rozet güven seviyesi 2'ye ulaştığında verilir. Haftalar boyunca buralarda olup katkıda bulunduğun için teşekkür ederiz. Artık kullanıcı sayfandan ya da konularından kişisel davetler gönderebilir, grup mesajları oluşturabilir ve günlük birkaç daha fazla beğeni ekleyebilirsin. - regular: | - Bu rozet güven seviyesi 3'e ulaştığında verilir. Aylardır topluluğumuzun düzenli bir parçası, bu topluluğu harika yapan en etkin okuyucu ve güvenilir katkıcılardan biri olduğun için teşekkür ederiz. Artık konuların kategorilerini ve isimlerini değiştirebilirsin, özel bir lobi alanına erişebilir, daha güçlü spam işaretleri koyabilir ve günlük çok daha fazla beğeni ekleyebilirsin. - leader: | - Bu rozet güven seviyesi 4'e ulaştığında verilir. Eylem ve kelimelerin ile topluluk için olumlu bir izlenim bırakman sebebiyle forum kadrosu tarafından bu topluluğun bir önderi seçildin. Artık tüm gönderileri düzenleyebilir, sabitleme, kapatma, listelememe, arşivleme, ayırma ve birleştirme gibi yönetici eylemlerini yapabilir ve günlük yığınca beğeni ekleyebilirsiniz. admin_login: success: "E-posta Gönderildi" error: "Hata!" @@ -1650,3 +1423,8 @@ tr_TR: performance_report: initial_post_raw: Bu konu siteniz hakkında günlük performans raporlarını içerir. initial_topic_title: Site performansı raporları + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.uk.yml b/config/locales/server.uk.yml index b187edd567a..ed14a3c8964 100644 --- a/config/locales/server.uk.yml +++ b/config/locales/server.uk.yml @@ -15,8 +15,6 @@ uk: posts: "дописи" loading: "Завантаження" powered_by_html: 'Створено за допомогою технології Discourse, бажано переглядати з увімкненим JavaScript' - via: "%{username} через %{site_name}" - is_reserved: "is reserved" backup: operation_already_running: "An operation is currently running. Can't start a new job right now." backup_file_should_be_tar_gz: "The backup file should be a .tar.gz archive." @@ -29,21 +27,6 @@ uk: loading: "Завантаження обговорення..." permalink: "Постійне посилання" imported_from: "Discussion topic for the original blog entry at: %{link}" - too_many_mentions: - one: "Даруйте, Ви можете згадувати тільки одного іншого користувача у дописі." - other: "Даруйте, Ви можете згадувати %{count} користувачів у дописі." - too_many_mentions_newuser: - one: "Даруйте, нові користувачі можуть згадувати в дописі тільки одного користувача." - other: "Даруйте, нові користувачі можуть згадувати %{count} інших користувачів у дописі." - too_many_images: - one: "Даруйте, нові користувачі можуть вставляти в допис тільки одне зображення." - other: "Даруйте, нові користувачі можуть вставляти %{count} зображень у допис." - too_many_attachments: - one: "Даруйте, нові користувачі можуть вставляти в допис тільки одне прикріплення." - other: "Даруйте, нові користувачі можуть вставляти тільки %{count} прикріплень в допис." - too_many_links: - one: "Даруйте, нові користувачі можуть вставляти в допис тільки одне посилання." - other: "Даруйте, нові користувачі можуть вставляти тільки %{count} посилань в допис." spamming_host: "Даруйте, Ви не можете вставити посилання на цей хост." just_posted_that: "це дуже схоже на те, що ви нещодавно дописували" has_already_been_used: "вже було використано" @@ -100,9 +83,6 @@ uk: post: raw: "Тіло" errors: - messages: - is_invalid: "is invalid; try to be a little more descriptive" - has_already_been_used: "вже було використано" models: user: attributes: @@ -115,8 +95,6 @@ uk: staff_category_description: "Закрита категорія для обговорень між персоналом. Теми бачать тільки адміністратори та модератори." category: topic_prefix: "Про категорію %{category}" - replace_paragraph: "[Замініть цей перший абзац коротким описом Вашої нової категорії. Він з'являтиметься в області вибору категорій, тому намагайтеся, щоб він був коротшим за 200 символів. Поки Ви не відредагуєте цей текст або не створите тем, ця категорія не з'явиться на сторінці категорій.]" - post_template: "%{replace_paragraph}\n\nВикористовуйте наступні абзаци для довшого опису, а також для того, щоб встановити якісь правила категорії.\n\nДеякі речі, які можна обговорити у відповідях на цей допис:\n\n- Для чого потрібна ця категорія? Чому людям слід обирати цю категорію для своїх тем?\n\n- Чим вона відрізняється від інших категорій, що в нас є?\n\n- Чи потрібна нам ця категорія?\n\n- Чи потрібно об'єднати цю категорію з якоюсь іншою, або розбити її на декілька?\n" errors: depth: "Ви не можете вкладати підкатегорію під іншу" trust_levels: @@ -160,7 +138,6 @@ uk: notify_user: email_body: "%{link}\n\n%{message}" notify_moderators: - email_title: 'Допис у темі "%{title}" потребує уваги модератора' email_body: "%{link}\n\n%{message}" bookmark: title: 'Лишити закладку' @@ -281,31 +258,6 @@ uk: s3_config_warning: 'The server is configured to upload files to s3, but at least one the following setting is not set: s3_access_key_id, s3_secret_access_key or s3_upload_bucket. Go to the Site Settings and update the settings. See "How to set up image uploads to S3?" to learn more.' image_magick_warning: 'The server is configured to create thumbnails of large images, but ImageMagick is not installed. Install ImageMagick using your favorite package manager or download the latest release.' consumer_email_warning: "Your site is configured to use Gmail (or another consumer email service) to send email. Gmail limits how many emails you can send. Consider using an email service provider like mandrill.com to ensure email deliverability." - content_types: - education_new_reply: - title: "Навчання новачка: Перші відповіді" - description: "Спливні настанови, що одразу автоматично відображаються над редактором, коли новий користувач починає вводити свої перші дві нові відповіді." - education_new_topic: - title: "Навчання новачка: Перші теми" - description: "Спливні настанови, що одразу автоматично відображаються над редактором, коли новий користувач починає вводити свої перші дві нові теми." - welcome_user: - title: "Вітання: Новий користувач" - welcome_invite: - title: "Вітання: Запрошений користувач" - login_required_welcome_message: - title: "Потрібно увійти: Вітальне повідомлення" - description: "Вітальне повідомлення, що відображається для користувачів, що вийшли, коли налаштування 'потрібен вхід' увімкнено." - login_required: - title: "Потрібно увійти: Головна сторінка" - description: "Текст, що відображається для неавторизованих користувачів, коли потрібен вхід на сайт." - head: - title: "HTML head" - description: "HTML-код, що буде вставлятися всередину теґів ." - top: - title: "Верхній колонтитул сторінок" - description: "HTML-код, що буде додаватися на початку кожної сторінки (після заголовка, перед навігацією або назвою теми)." - bottom: - title: "Нижній колонтитул сторінок" site_settings: default_locale: "Мова за замовчуванням для цього екземпляра Discourse (Код ISO 639-1)" allow_user_locale: "Allow users to choose their own language interface preference" @@ -431,9 +383,6 @@ uk: subject_template: "[%{site_name}] Тест доставки електронної пошти" new_version_mailer_with_notes: subject_template: "оновлення [%{site_name}] доступно" - flags_reminder: - please_review: "Будь ласка, перегляньте його." - post_number: "допис" system_messages: post_hidden: subject_template: "Допис приховано через скарги спільноти" @@ -469,54 +418,17 @@ uk: unsubscribe: title: "Відпісатися" description: "Не зацікавлені в отриманні цих листів? Немає проблем! Натисніть нижче, щоб відписатися назавжди:" - reply_by_email: "Щоб відповісти, надішліть відповідь на цей лист або відвідайте %{base_url}%{url} у своєму веб-оглядачі." - visit_link_to_respond: "Щоб відповісти, відвідайте %{base_url}%{url} у своєму веб-оглядачі." posted_by: "Опубліковано %{username} %{post_date}" user_replied: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_quoted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_mentioned: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted: subject_template: "[%{site_name}] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} user_posted_pm: subject_template: "[%{site_name}] [ПП] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: new_activity: "Нова активність у ваших темах та дописах:" top_topics: "Популярні дописи" @@ -542,12 +454,6 @@ uk: Перейдіть за посиланням, щоб обрати пароль: %{base_url}/users/password-reset/%{email_token} - authorize_email: - subject_template: "[%{site_name}] Підтвердіть свою електронну скриньку" - text_body_template: | - Підтвердіть свою нову електронну скриньку для сайта %{site_name}, перейшовши за посиланням: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "Вас було схвалено на сайті %{site_name}!" signup: @@ -559,7 +465,6 @@ uk: Якщо наведене посилання не є клікабельним, спробуйте скопіювати та вставити його в адресний рядок Вашого веб-оглядача. page_not_found: - title: "Сторінка, яку Ви запитали, не існує або є приватною." popular_topics: "Популярні" recent_topics: "Останні" see_more: "Більше" diff --git a/config/locales/server.vi.yml b/config/locales/server.vi.yml new file mode 100644 index 00000000000..9951f5855ec --- /dev/null +++ b/config/locales/server.vi.yml @@ -0,0 +1,1160 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +vi: + dates: + short_date_no_year: "D MMM" + short_date: "D MMM, YYYY" + long_date: "MMMM D, YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%m-%d-%Y" + short_no_year: "%B %-d" + date_only: "%b %-d, %Y" + date: + month_names: [null, Tháng Một, Tháng Hai, Tháng Ba, Tháng Tư, Tháng Năm, Tháng Sáu, Tháng Bảy, Tháng Tám, Tháng Chín, Tháng Mười, Tháng Mười Một, Tháng Mười Hai] + <<: *datetime_formats + title: "Discourse" + topics: "Chủ đề" + posts: "bài viết" + loading: "Đang tải" + powered_by_html: 'Được hỗ trợ bởi Discourse, xem tốt nhất khi JavaScript được kích hoạt' + log_in: "Đăng nhập" + purge_reason: "Tự động xóa tài khoản không sử dụng, không kích hoạt." + disable_remote_images_download_reason: "Không thể tải ảnh về máy chủ vì thiếu dung lượng." + anonymous: "Ẩn danh" + emails: + incoming: + default_subject: "Email đến từ %{email}" + errors: &errors + format: '%{attribute} %{message}' + messages: + too_long_validation: "cho phép tối đa %{max} ký tự; bạn đã nhập %{length}." + invalid_boolean: "Giá trị logic không hợp lệ" + taken: "đã được lấy trước" + accepted: phải được chấp nhận + blank: không thể để rỗng + present: phải để rỗng + confirmation: "%{attribute} không khớp" + empty: không thể để trống + equal_to: phải bằng %{count} + even: phải là chắn + exclusion: được bảo lưu + greater_than: phải lớn hơn %{count} + greater_than_or_equal_to: phải lớn hơn hoặc bằng %{count} + has_already_been_used: "đã được sử dụng" + inclusion: không được bao gồm trong danh sách + invalid: là không hợp lệ + is_invalid: "không hợp lệ; cố gắng cụ thể hơn một chút" + less_than: phải nhỏ hơn %{count} + less_than_or_equal_to: phải nhỏ hơn hoặc bằng %{count} + not_a_number: không phải là số + not_an_integer: phải là một số nguyên + odd: phải là số lẻ + record_invalid: 'Xác nhận thất bại: %{errors}' + restrict_dependent_destroy: + one: "Không thể xóa bản ghi bởi vì một bản ghi %{record} phụ thuộc đang tồn tại" + many: "Không thể xóa bản ghi bởi vì %{record} phụ thuộc tồn tại" + too_long: + other: quá dài (tối đa %{count} ký tự) + too_short: + other: quá ngắn (tối thiểu %{count} ký tự) + wrong_length: + other: độ dài không hợp lệ (nên đặt %{count} ký tự) + other_than: "phải khác %{count}" + template: + body: 'Đã có vấn đề với những trường sau:' + header: + other: '%{count} lỗi đã ngăn cản không thể lưu %{model} này' + embed: + load_from_remote: "Đã xảy ra lỗi khi tải bài viết." + site_settings: + min_username_length_exists: "Bạn không thể thiết lập chiều dài tối thiểu của username nhỏ hơn chiều dài của username ngắn nhất" + min_username_length_range: "Bạn không thiết lập giá trị nhỏ nhất lớn hơn giá trị lớn nhất" + max_username_length_exists: "Bạn không thể thiết lập chiều dài tối đa của username nhỏ hơn username dài nhất" + max_username_length_range: "Bạn không thể thiết lập số tối đa nhỏ hơn số tối thiểu" + default_categories_already_selected: "Bạn không thể chọn một danh mục được sử dụng trong danh sách khác." + s3_upload_bucket_is_required: "Bạn không thể tải lên S3 mà chưa thiết lập 's3_upload_bucket'." + bulk_invite: + file_should_be_csv: "Tập tin tải lên nên ở dạng csv hoặc txt." + backup: + operation_already_running: "Một tiến trình đang được thực hiện. Không thể bắt đầu một tiến trình mới ngay bây giờ." + backup_file_should_be_tar_gz: "Tập tin sao lưu nên nên ở dạng .tar.gz." + not_enough_space_on_disk: "Không đủ không gian trên đĩa để tải lên bản sao lưu này." + not_logged_in: "Bạn cần phải đăng nhập để thực hiện việc đó." + not_found: "Không thể tìm thấy đường dẫn hoặc tài nguyên yêu cầu." + invalid_access: "Bạn không được phép xem tài nguyên đã yêu cầu." + read_only_mode_enabled: "Trang web đang ở chế độ chỉ đọc. Tất cả các tương tác đã bị tắt." + reading_time: "Thời gian đọc" + likes: "Lượt Thích" + too_many_replies: + other: "Xin lỗi bạn, người dùng mới tạm thời bị giới hạn với %{count} câu trả lời trong một chủ đề." + embed: + start_discussion: "Bắt đầu cuộc thảo luận" + continue: "Tiếp tục cuộc thảo luận" + more_replies: + other: "còn %{count} câu trả lời" + loading: "Đang tải cuộc thảo luận" + permalink: "Liên kết cố định" + imported_from: "Đây là cuộc thảo luận đi kèm chủ đề gốc tại %{link}" + in_reply_to: "▶ %{username}" + replies: + other: "%{count} câu trả lời" + no_mentions_allowed: "Xin lỗi, bạn không thể nhắc tới thành viên khác." + too_many_mentions: + other: "Xin lỗi, bạn chỉ có thể nhắc tới %{count} thành viên trong một bài viết." + no_mentions_allowed_newuser: "Xin lỗi, thành viên mới không thể nhắc tới thành viên khác." + too_many_mentions_newuser: + other: "Xin lỗi, thành viên mới chỉ có thể nhắc tới %{count} thành viên khác trong một bài viết." + no_images_allowed: "Xin lỗi, thành viên mới chưa được chèn hình ảnh vào bài viết." + too_many_images: + other: "Xin lỗi, thành viên mới chỉ có thể chèn %{count} hình ảnh trong một bài viết." + no_attachments_allowed: "Xin lỗi, thành viên mới chưa được chèn tập tin trong bài viết." + too_many_attachments: + other: "Xin lỗi, thành viên mới chỉ được chèn %{count} file đính kèm trong một bài viết." + no_links_allowed: "Xin lỗi, thành viên mới chưa được chèn liên kết trong bài viết." + too_many_links: + other: "Xin lỗi, thành viên mới chỉ được chèn %{count} liên kết trong một bài viết." + spamming_host: "Xin lỗi bạn không thể chèn liên kết tới trang đó." + user_is_suspended: "Người dùng đang bị treo không được phép đăng bài." + topic_not_found: "Có gì đó đã sai. Có lẽ chủ đề này đã bị đóng hoặc bị xóa trong khi bạn đang xem?" + just_posted_that: "rất giống với những gì bạn đã viết gần đây" + has_already_been_used: "đã được sử dụng" + invalid_characters: "chứa các kí tự không hợp lệ" + is_invalid: "không hợp lệ; cố gắng cụ thể hơn một chút" + next_page: "trang sau →" + prev_page: "← trang trước" + page_num: "Trang %{num}" + home_title: "Trang chủ" + topics_in_category: "Các chủ đề ở chuyên '%{category}'" + rss_posts_in_topic: "Nguồn cấp dữ liệu RSS của '%{topic}'" + rss_topics_in_category: "Nguồn cấp dữ liệu RSS của các chủ đề trong chuyên mục '%{category}'" + author_wrote: "%{author} đã viết:" + num_posts: "Bài đã đăng:" + num_participants: "Người tham gia:" + read_full_topic: "Đọc toàn bộ chủ đề" + private_message_abbrev: "Tin nhắn" + rss_description: + latest: "Chủ đề mới nhất" + hot: "Chủ đề nóng nhất" + posts: "Bài viết mới nhất" + too_late_to_edit: "Bài đăng đã được tạo từ rất lâu. Nó không thể được chỉnh sửa hoặc xóa nữa." + excerpt_image: "hình ảnh" + queue: + delete_reason: "Đã xóa thông qua hàng đợi kiểm duyệt" + groups: + errors: + can_not_modify_automatic: "Bạn không thể sửa đổi một nhóm tự động" + member_already_exist: "'%{username}' đã là thành viên của nhóm" + invalid_domain: "'%{domain}' không phải là tên miền hợp lệ." + default_names: + everyone: "Mọi người" + admins: "quản trị" + moderators: "điều hành" + staff: "nhân viên" + trust_level_0: "trust_level_0" + trust_level_1: "trust_level_1" + trust_level_2: "trust_level_2" + trust_level_3: "trust_level_3" + trust_level_4: "trust_level_4" + education: + until_posts: + other: "%{count} bài đăng" + new-topic: | + Chào mừng bạn đến với %{site_name} — **cảm ơn vì đã đăng cuộc thảo luận mới!** + + - Bạn có cảm thấy tiêu đề có thú vị không khi bạn đọc to nó? Đó có phải là một đoạn tóm tắt tốt không? + + - Những ai sẽ hứng thú với cuộc thảo luận này? Tại sao đó lại trở thành vấn đề? Bạn muốn những loại phản hồi thế nào? + + - Sử dụng những từ khóa phổ biến để người khác có thể tìm thấy chủ đề của bạn dễ hơn. Để nhóm chủ đề của bạn với các chủ đề liên quan khác, hãy chọn chuyên mục cho chủ đề của mình. + + Xem thêm, [hướng dẫn cộng đồng của chúng tôi](/guidelines). Bảng điều khiển này sẽ chỉ xuất hiện vào lần đầu %{education_posts_text}. + new-reply: | + Chào mừng bạn đến với %{site_name} — **cám ơn vì đã đóng góp!** + + - Câu trả lời của bạn có làm cuộc thảo luận tốt hơn về mặt nào đó? + + - Hãy đối xử tốt với các thành viên khác trong cộng đồng của bạn. + + - Lời phê bình mang tính đóng góp cũng được chào đón, nhưng bạn nên phê bình *ý tưởng* chứ không phải con người. + + [Đọc hướng dẫn cộng đồng](/guidelines) để có thêm thông tin. Bảng này chỉ xuất hiện cho bài viết đầu tiên của bạn %{education_posts_text}. + avatar: | + ### How about a picture for your account? + + You've posted a few topics and replies, but your profile picture isn't as unique as you are -- it's just a letter. + + Have you considered **[visiting your user profile](%{profile_path})** and uploading a picture that represents you? + + It's easier to follow discussions and find interesting people in conversations when everyone has a unique profile picture! + sequential_replies: | + ### Xem xét việc trả lời nhiều bài viết cùng lúc + + Thay vì trả lời nhiều tuần tự đến từng chủ đề, xin vui lòng xem xét một bài trả lời duy nhất mà bao gồm các trích dẫn từ bài viết trước hoặc dùng tham chiếu @name. + + Bạn có thể sửa bài trả lời trước đó của bạn để thêm một trích dẫn bằng cách bôi đen và nhấn chọn nút quote reply vừa xuất hiện. + + Sẽ dễ dàng hơn cho tất cả mọi người để đọc chủ đề mà có ít câu trả lời sâu với nhiều cấp, trả lời cá nhân + dominating_topic: "### Hãy để người khác tham gia vào cuộc thảo luận\n\nChủ đề này rõ ràng là quan trọng với bạn & ndash; bạn đã đăng nhiều hơn% %{percent}% của các câu trả lời tại đây.\n\nBạn có chắc chắn bạn đang cung cấp đủ thời gian cho những người khác để chia sẻ quan điểm của mình? \n" + too_many_replies: | + ### Bạn đã đạt đến giới hạn trả lời cho chủ đề này + + Chúng tôi xin lỗi, nhưng người dùng mới bị giới hạn %{newuser_max_replies_per_topic} trả lời trong cùng một chủ đề. + + Thay vì thêm một câu trả lời khác, xin vui lòng xem xét chỉnh sửa trả lời trước đó của bạn, hoặc truy cập vào các chủ đề khác. + reviving_old_topic: "### Xem lại chủ đề này? \n\nCâu trả lời cuối cùng cho chủ đề này đã hơn hơn %{days} ngày. Trả lời của bạn sẽ đẩy chủ đề đó lên đầu danh sách và thông báo cho bất cứ ai liên quan đến cuộc thảo luận.\n\nBạn có chắc chắn bạn muốn tiếp tục cuộc trò chuyện cũ này? \n" + activerecord: + attributes: + category: + name: "Tên chuyên mục" + post: + raw: "Thân" + user_profile: + bio_raw: "GIới thiệu bản thân" + errors: + models: + topic: + attributes: + base: + warning_requires_pm: "Bạn chỉ có thể đính kèm cảnh báo qua tin nhắn cá nhân" + too_many_users: "Bạn chỉ có thể gửi một cảnh báo tới một người dùng mỗi lần." + cant_send_pm: "Xin lỗi, bạn không thể gửi tin nhắn tới thành viên này" + no_user_selected: "Bạn phải chọn một thành viên phù hợp." + user: + attributes: + password: + common: "là một trong 10000 mật khẩu được sử dụng nhiều nhất. Vui lòng sử dụng một mật khẩu an toàn hơn." + same_as_username: "giống với tên đăng nhập của bạn. Vui lòng sử dụng mật khẩu bảo mật hơn." + same_as_email: "giống với email của bạn. Vui lòng sử dụng mật khẩu bảo mật hơn" + ip_address: + signup_not_allowed: "Đăng ký không cho phép tài khoản này" + color_scheme_color: + attributes: + hex: + invalid: "không phải là một màu không hợp lệ" + <<: *errors + user_profile: + no_info_me: "
    Mục nói về bản thân bạn trong hồ sơ của bạn hiện đang trống, bạn muốn điền vào nó? " + no_info_other: "
    %{name} đã không nhập bất cứ điều gì nói về bản thân của họ " + vip_category_name: "Phòng khách" + vip_category_description: "Một chuyên mục chỉ dành cho thành viên có mức tin tưởng 3 hoặc cao hơn" + meta_category_name: "Phản hồi" + meta_category_description: "Thảo luận về site này, tổ chức của nó, làm sao nó hoạt động, và làm sao chúng tôi có thể cải tiến nó tốt hơn." + staff_category_name: "Nhân viên" + staff_category_description: "Chuyên mục riêng dành cho nhân viên. Các chủ đề chỉ hiển thị với quản trị viên và điều hành viên." + assets_topic_body: "Chủ đề này tồn tại vĩnh viễn, chỉ xem được bởi nhân viên, dùng để chứa ảnh và file dành cho việc thiết kế. Vui lòng đừng xóa.\n\n\nHướng dẫn:\n\n\n1. Trả lời chủ đề này.\n2. Tải lên tất cả ảnh bạn cần cho logo, favicon, và các thứ khác. (Dùng nút tải lên trong công cụ viết bài, hoặc kéo-và-thả hoặc dán ảnh vào) \n3. Gửi trả lời của bạn.\n4. Bấm chuột phải lên ảnh trong bài đăng mới để chép đường dẫn của các ảnh đã được tải lên, hoặc sửa bài viết của bạn để lấy đường dẫn của ảnh. Sao chép các đường dẫn này.\n5. Dán các đường dẫn này vào [thiết lập chung](/admin/site_settings/category/required).\n\n\nNếu bạn cần tải lên các loại file khác, sửa `authorized_extensions` trong [thiết lập file](/admin/site_settings/category/files)." + lounge_welcome: + title: "Chào mừng bạn đến với Phòng khách" + body: |2 + + Chúc mừng! :confetti_ball: + + Nếu bạn có thể xem chủ đề này, bạn đã được thăng lên bậc **thường xuyên** (bậc tin tưởng 3). + + Bạn có thể … + + * Sửa tiêu đề của bất kì chủ đề nào + * Sửa chuyên mục của bất kì chủ đề nào + * Tất cả liên kết ở trạng thái follow ([những liên kết nofollow](http://en.wikipedia.org/wiki/Nofollow) sẽ được loại bỏ) + * Truy cập vào phòng khách dành riêng cho thành viên với bậc tin tưởng 3 hoặc cao hơn + * Ẩn bài viết spam với 1 lần đánh dấu. + + Đây là danh sách [của các thành viên thường xuyên](/badges/3/regular). Hãy chào họ đi nào. + + Cảm ơn vì đã trở thành một phần không thể thiếu đối với cộng đồng. + + (Để biết thêm chi tiết về bậc tin tưởng, [xem chủ đề này][trust]. Hãy nhớ rằng bạn phải tiếp tục đạt được các yêu cầu để duy trì bậc tin tưởng của mình.) + + [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 + category: + topic_prefix: "Giới thiệu chuyên mục %{category}" + replace_paragraph: "(Thay thế đoạn này với miêu tả về category mới. Bản hướng dẫn này sẽ được xuất hiện trong vùng chọn của category, vì thế nó chỉ giới hạn trong 200 kí tự. **Cho đến khi bạn chỉnh sửa phần miêu tả này hoặc tạo topic cho nó, category này sẽ không xuất hiện trên trang web.**)" + post_template: "%{replace_paragraph}\n\nSử dụng những đoạn sau để viết mô tả dài, hướng dẫn sử dụng hoặc điều luật sử dụng:\n\n- Mục đích sử dụng của category này là gì?\n\n- Category này khác với những cái khác như thế nào?\n\n- Những topic trong category này thường có nội dung gì?\n\n- Chúng ta có thể ghép với category khác không?\n" + errors: + uncategorized_parent: "Mục \"Chưa được phân loại\" không thể có một chuyên mục chính" + self_parent: "Cha của chủ đề phụ không thể nào là chính nó" + depth: "Bạn không thể để một chuyên mục con trong một chuyên mục con khác." + cannot_delete: + uncategorized: "Không thể xoá mục Chưa phân loại" + has_subcategories: "Không thể xoá chuyên mục này được vì nó có chuyên mục con." + topic_exists: + other: "Không thể xoá phân loại này được bởi vì nó có %{count} chủ đề. Các chủ đề cũ là %{topic_link}." + topic_exists_no_oldest: "Không thể xoá chuyên mục này vì nó có %{count} chủ để." + uncategorized_description: "Chủ đề không cần chuyên mục, hoặc không phù hợp với bất kỳ chuyên mục nào hiện có." + trust_levels: + newuser: + title: "thành viên mới" + basic: + title: "thành viên cơ bản" + member: + title: "thành viên" + regular: + title: "thường xuyên" + leader: + title: "người khởi xướng" + change_failed_explanation: "Bạn đã cố gắng để giảm hạng %{user_name} xuống '%{new_trust_level}'. Tuy nhiên cấp độ tin cậy hiện tại của họ đã là '%{current_trust_level}'. %{user_name} sẽ được giữ lại ở cấp độ '%{current_trust_level}' - nếu bạn muốn giảm hạng thành viên, trước tiên hãy khóa cấp độ tin cậy" + rate_limiter: + slow_down: "Hành động này đã được thực hiện quá nhiều lần. Bạn vui lòng thử lại sau." + too_many_requests: "Hành động bạn vừa thực hiện bị giới hạn theo ngày. Hãy chờ %{time_left} và thử lại." + by_type: + first_day_replies_per_day: "Bạn vừa vượt quá số lần trả lời tối đa trong ngày đầu của thành viên mới. Xin hãy chờ %{time_left} và thử lại sau." + first_day_topics_per_day: "Bạn vừa đạt tới số lần mở topic tối đa cho thành viên mới. Xin vui lòng chờ %{time_left} trước khi thử lại." + create_topic: "Bạn đang tạo topic quá nhanh. Vui lòng chờ %{time_left} trước khi thử lại." + create_post: "Bạn đang trả lời quá nhanh. Xin vui lòng chờ %{time_left} trước khi thử lại." + topics_per_day: "Bạn vừa đạt tới số lần mở topic mới tối đa trong ngày hôm nay. Vui lòng chờ %{time_left} trước khi thử lại." + pms_per_day: "Bạn vừa đạt tới số lần gửi tin nhắn tối đa trong ngày. Xin vui lòng chờ %{time_left} trước khi thử lại." + create_like: "Bạn vừa đạt tới số lần tối đa được Like trong ngày. Xin vui lòng chờ %{time_left} trước khi thử lại." + create_bookmark: "Bạn vừa đạt tới số lần đánh dấu tối đa trong ngày. Xin vui lòng chờ %{time_left} trước khi thử lại." + edit_post: "Bạn vừa đạt tới số lần chỉnh sửa tối đa trong ngày. Xin vui lòng chờ %{time_left} trước khi thử lại." + hours: + other: "%{count} giờ" + minutes: + other: "%{count} phút" + seconds: + other: "%{count} giây" + datetime: + distance_in_words: + half_a_minute: "< 1 phút" + less_than_x_seconds: + other: "< %{count} giây" + x_seconds: + other: "%{count} giây" + less_than_x_minutes: + other: "< %{count} phút" + x_minutes: + other: "%{count} phút" + about_x_hours: + other: "%{count} giờ" + x_days: + other: "%{count} ngày" + about_x_months: + other: "%{count} tháng" + x_months: + other: "%{count} tháng" + about_x_years: + other: "%{count} năm" + over_x_years: + other: "> %{count} năm" + almost_x_years: + other: "%{count} năm" + distance_in_words_verbose: + half_a_minute: "ngay bây giờ" + less_than_x_seconds: + other: "ngay bây giờ" + x_seconds: + other: "%{count} giây trước" + less_than_x_minutes: + other: "ít hơn %{count} phút trước" + x_minutes: + other: "%{count} phút trước" + about_x_hours: + other: "%{count} giờ trước" + x_days: + other: "%{count} ngày trước" + about_x_months: + other: "khoảng %{count} tháng trước" + x_months: + other: " %{count} tháng trước" + about_x_years: + other: "khoảng %{count} năm trước" + over_x_years: + other: "hơn %{count} năm trước" + almost_x_years: + other: "gần %{count} năm trước" + password_reset: + no_token: "Xin lỗi, liên kết đổi mật khẩu đã cũ. Chọn \"Đăng nhập\" và sử dụng chức năng \"Quên mật khẩu\" để lấy liên kết mới." + choose_new: "Vui lòng chọn mật khẩu mới" + choose: "Bạn phải nhập mật khẩu" + update: 'Cập nhật mật khẩu' + save: 'Nhập mật khẩu' + title: 'Thiết lập lại mật khẩu' + success: "Bạn đã thay đổi mật khẩu thành công và đã được đăng nhập." + success_unapproved: "Bạn đã thay đổi mật khẩu thành công." + continue: "Tiếp tục đến %{site_name}" + change_email: + confirmed: "Email của bạn đã được cập nhật." + please_continue: "Tiếp tục đến %{site_name}" + error: "Có một lỗi khi thay đổi địa chỉ email của bạn. Có lẽ email này đã được sử dụng rồi?" + activation: + action: "Nhấn vào đây để kích hoạt tài khoản của bạn" + already_done: "Xin lỗi, liên kết để xác nhận tài khoản này không còn hợp lệ. Có thể tài khoản của bạn được kích hoạt?" + please_continue: "Tài khoản của bạn đã được xác nhận; bạn sẽ được chuyển đến trang chủ." + continue_button: "Tiếp tục tới %{site_name}" + welcome_to: "Chào mừng bạn đến với %{site_name}!" + approval_required: "Một điều hành viên phải duyệt tài khoản của bạn trước khi bạn có thể đăng nhập diễn đàn này. Bạn sẽ nhận được email khi tài khoản của bạn được duyệt!" + missing_session: "Chúng tôi không thể xác" + post_action_types: + off_topic: + title: 'Không-đúng-chủ-đề' + description: 'Bài này không liên quan đến các cuộc thảo luận hiện nay theo quy định của các tiêu đề và bài đầu tiên, và có lẽ nó nên được di chuyển đến những nơi khác.' + long_form: 'đánh dấu không-đúng-chủ-đề' + spam: + title: 'Spam' + description: 'Bài đăng này là một bài quảng cáo. Không bổ ích hoặc liên quan tới chủ đề hiện tại, chỉ nhằm mục đích quảng cáo.' + long_form: 'đánh dấu là spam' + email_title: '"%{title}" đã bị gắn cờ spam' + email_body: "%{link}\n\n%{message}" + inappropriate: + title: 'Không thích hợp' + description: 'Chủ để này chứa nội dung mà bình thường được xem là xúc phạm, lạm dụng, hoặc vi phạm nguyên tắc cộng đồng.' + long_form: 'đánh dấu cái này không thích hợp' + notify_user: + title: 'Gửi tin nhắn cho @{{username}}.' + description: 'Tôi muốn trao đổi riêng, trực tiếp với người này về bài viết của họ.' + long_form: 'đã nhắn tin cho thành viên' + email_title: 'Bài đăng của bạn trong "%{title}"' + email_body: "%{link}\n\n%{message}" + notify_moderators: + title: "Một thứ khác" + description: 'Bài viết này cần được Ban quản trị chú ý. Lý do chưa được liệt kê trong danh sách.' + long_form: 'đã đánh dấu thông báo cho Ban quản trị' + email_title: 'Một bài viết trong "%{title}" cần Ban quản trị lưu ý' + email_body: "%{link}\n\n %{message}" + bookmark: + title: "Đánh dấu chỉ mục \x1C" + description: 'Đánh dấu chỉ mục bài viết này' + long_form: 'đã đánh dấu chỉ mục bài viết này' + like: + title: 'Thích' + description: 'Thích bài viết này' + long_form: 'đã thích cái này' + vote: + title: 'Bầu chọn' + description: 'Bầu cho bài viết này' + long_form: 'bầu cho bài viết này' + topic_flag_types: + spam: + title: 'Rác' + description: 'Chủ đề này mang bản chất quảng cáo, không có ích và không thích hợp với nơi này.' + long_form: 'đã đánh dấu bài này dạng bài viết rác' + inappropriate: + title: 'Không phù hợp' + description: 'Chủ để này chứa nội dung mà với lý lẽ thường nhật được xem là xúc phạm, lạm dụng, hoặc vi phạm chỉ dẫn chung của cộng đồng.' + long_form: 'đã đánh dấu bài này không phù hợp' + notify_moderators: + title: "Một cái khác" + description: 'Bài viết này cần Ban quản trị lưu ý theo dựa trên hướng dẫnđiều khoản sử dụng.' + long_form: 'đã đánh dấu cho điều hành viên xem xét' + email_title: 'Chủ đề "%{title}" cần được ban điều hành quan tâm' + email_body: "%{link}\n\n%{message}" + flagging: + you_must_edit: '

    Bài viết của bạn đã được gắn cờ bở cộng đồng. Vui lòngxem tin nhắn của bạn.

    ' + user_must_edit: '

    Bài viết này đã bị đánh dấu bởi cộng đồng và đang được ẩn tạm thời.

    ' + archetypes: + regular: + title: "Chủ đề thường" + banner: + title: "Banner chủ đề" + message: + make: "Chủ đề này trở thành một banner. Nó sẽ hiện ở đầu mọi trang tới khi nó được tắt bởi thành viên." + remove: "Chủ đề này không còn là một banner. Nó sẽ không hiện ở đầu mọi trang nữa." + unsubscribed: + title: 'Hủy bỏ đăng ký' + description: "Bạn đã ngừng đăng. Chúng tôi sẽ không liên lạc bạn nữa!" + oops: "Trong trường hợp bạn không có ý thực hiện thao tác này, bấm vào bên dưới." + error: "Lỗi hủy đăng kí" + preferences_link: "Bạn có thể hủy theo dõi bản tin tóm tắt tại trang thiết lập" + different_user_description: "Bạn đang đăng nhập như một người dùng khác, không phải là người dùng đã được gửi đến qua mail. Hãy thoát ra và thử lại." + not_found_description: "Xin lỗi, chúng tôi không thể ngừng đăng ký bạn. Có thể là do link trong email của bạn đã hết hạn." + resubscribe: + action: "Đăng ký lại" + title: "Đã đăng ký lại!" + description: "Bạn đã được đăng ký lại." + reports: + visits: + title: "Các thành viên truy cập" + xaxis: "Ngày" + yaxis: "Số lần truy cập" + signups: + title: "Thành viên mới" + xaxis: "Ngày" + yaxis: "Số lượng thành viên mới" + profile_views: + title: "Xem hồ sơ người dùng" + xaxis: "Ngày" + yaxis: "Số người đã xem hồ sơ người dùng" + topics: + title: "Các chủ đề" + xaxis: "Ngày" + yaxis: "Số lượng chủ đề mới" + posts: + title: "Bài viết" + xaxis: "Ngày" + yaxis: "Số lượng bài viết mới" + likes: + title: "Lượt thích" + xaxis: "Ngày" + yaxis: "Số lượt thích mới" + flags: + title: "Dấu cờ - Flags" + xaxis: "Ngày" + yaxis: "Số dấu cờ - flag" + bookmarks: + title: "Các đánh dấu" + xaxis: "Ngày" + yaxis: "Số đánh dấu mới" + starred: + title: "Bắt đầu" + xaxis: "Ngày" + yaxis: "Số chủ đề được tạo." + users_by_trust_level: + title: "Thành viên ở mõi bậc tin tưởng" + xaxis: "Bậc tin tưởng" + yaxis: "Số thành viên" + emails: + title: "Email đã gửi" + xaxis: "Ngày" + yaxis: "Số lượng emails" + user_to_user_private_messages: + title: "Người dùng tới người dùng" + xaxis: "Ngày" + yaxis: "Số lượng tin nhắn" + system_private_messages: + title: "Hệ thống" + xaxis: "Ngày" + yaxis: "Số lượng tin nhắn" + moderator_warning_private_messages: + title: "Cảnh báo của điều hành viên" + xaxis: "Ngày" + yaxis: "Số lượng tin nhắn" + notify_moderators_private_messages: + title: "Thông báo ban quản trị" + xaxis: "Ngày" + yaxis: "Số lượng tin nhắn" + notify_user_private_messages: + title: "Thông báo người dùng" + xaxis: "Ngày" + yaxis: "Số lượng tin nhắn" + top_referrers: + title: "Giới thiệu hàng đầu" + xaxis: "Người dùng" + num_clicks: "Clicks" + num_topics: "Chủ đề" + top_traffic_sources: + title: "Nguồn truy cập" + xaxis: "Tên miền" + num_clicks: "Clicks" + num_topics: "Chủ đề" + num_users: "Người dùng" + top_referred_topics: + title: "Top chủ đề giới thiệu" + xaxis: "Chủ đề" + num_clicks: "Clicks" + page_view_anon_reqs: + title: "Ẩn danh" + xaxis: "Ngày" + yaxis: "Truy cập API ẩn danh" + page_view_logged_in_reqs: + title: "Đã đăng nhập" + xaxis: "Ngày" + yaxis: "Đã đăng nhập truy cập API" + page_view_crawler_reqs: + title: "Thu thập thông tin web" + xaxis: "Ngày" + yaxis: "Truy cập API thu thập thông tin web" + page_view_total_reqs: + title: "Tổng số" + xaxis: "Ngày" + yaxis: "Tổng số truy cập API" + page_view_logged_in_mobile_reqs: + title: "Trong yêu cầu đăng nhập API" + xaxis: "Ngày" + yaxis: "Mobile yêu cầu Đăng nhập API" + page_view_anon_mobile_reqs: + title: "Anon API Requests" + xaxis: "Ngày" + yaxis: "Mobile Anon API Requests" + http_background_reqs: + title: "Hình nền" + xaxis: "Ngày" + yaxis: "Yêu cầu đã sử dụng cho cập nhật thời gian thực và thống kê" + http_2xx_reqs: + title: "Trạng thái 2xx (OK)" + xaxis: "Ngày" + yaxis: "Yêu cầu thành công (Trạng thái 2xx)" + http_3xx_reqs: + title: "HTTP 3xx (Chuyển hướng)" + xaxis: "Ngày" + yaxis: "Chuyển hướng yêu cầu (Trạng thái 3xx)" + http_4xx_reqs: + title: "HTTP 4xx (Trình khách lỗi)" + xaxis: "Ngày" + yaxis: "Trình khách lỗi (Trạng thái 4xx)" + http_5xx_reqs: + title: "HTTP 5xx (Máy chủ lỗi)" + xaxis: "Ngày" + yaxis: "Máy chủ lỗi (Trạng thái 5xx)" + http_total_reqs: + title: "Tổng số" + xaxis: "Ngày" + yaxis: "Tổng số yêu cầu" + time_to_first_response: + title: "Thời gian để phản hồi lần đầu" + xaxis: "Ngày" + yaxis: "Thời gian trung bình (giờ)" + topics_with_no_response: + title: "Chủ đề không có phản hồi" + xaxis: "Ngày" + yaxis: "Tổng số" + mobile_visits: + title: "Các thành viên truy cập" + xaxis: "Ngày" + yaxis: "Số lần truy cập" + dashboard: + rails_env_warning: "Máy chủ của bạn đang chạy trong chế độ %{env}." + ruby_version_warning: "Bạn đang dùng một phiên bản Ruby 2.0.0 được biết là có nhiều vấn đề. Hãy nâng cấp bản vá 247 hoặc mới hơn." + host_names_warning: "Cài đặt của bạn config/database.yml đang sử dụng hostname mặc định. Cập nhật lại để sử dụng hostname của bạn" + gc_warning: 'Máy chủ của bạn hiện tại sử dụng cơ chế dọn rác mặc định của ruby, điều này khiến cho hiệu năng của máy chủ không tốt lắm. Đọc chủ đề sau cho việc tối ưu hiệu năng Tối ưu Ruby and Rails cho Discourse.' + sidekiq_warning: ' Sidekiq đang không hoạt động. Rất nhiều tác vụ, như gửi email, là được thực thi không đồng bộ bởi sidekiq. Hãy chắc chắn rằng ít nhất một tiến trình sidekiq phải đang hoạt động. Đọc thêm về Sidekiq tại đây.' + queue_size_warning: 'Có %{queue_size} công việc đang chờ xử lý trong hàng đợi. Điều này chứng tỏ có vấn đề đã xảy ra với tiến trình Sidekiq, hoặc bạn cần tăng số lượng Sidekiq workers ().' + memory_warning: 'Máy chủ của bạn có bộ nhớ ít hơn 1 GB. Khuyến cáo sử dụng bộ nhớ tối thiểu 1 GB .' + google_oauth2_config_warning: 'Máy chủ được cấu hình cho phép đăng ký và đăng nhập với Google OAuth2 (enable_google_oauth2_logins), tuy nhiên giá trị của client id và client secret thì không được thiết lập. Truy cập Cấu hình Site và bổ sung các thiết lập đó. Xem hướng dẫn này để biết thêm chi tiết.' + facebook_config_warning: 'Máy chủ được cấu hình cho phép đăng ký và đăng nhập với Facebook (enable_facebook_logins), tuy nhiên giá trị của client id và client secret thì không được thiết lập. Truy cập Cấu hình Site và bổ sung các thiết lập đó. Xem hướng dẫn này để biết thêm chi tiết.' + twitter_config_warning: 'Máy chủ được cấu hình cho phép đăng ký và đăng nhập với Twitter (enable_twitter_logins), tuy nhiên giá trị của client id và client secret thì không được thiết lập. Truy cập Cấu hình Site và bổ sung các thiết lập đó. Xem hướng dẫn này để biết thêm chi tiết.' + github_config_warning: 'Máy chủ được cấu hình cho phép đăng ký và đăng nhập với GitHub (enable_github_logins), tuy nhiên giá trị của client id và client secret thì không được thiết lập. Truy cập Cấu hình Site và bổ sung các thiết lập đó. Xem hướng dẫn này để biết thêm chi tiết.' + s3_config_warning: 'Máy chủ được cấu hình để upload file lên s3, tuy nhiên ít nhất một trong các tùy chỉnh sau đây không được thiết lập: s3_access_key_id, s3_secret_access_key hoặc s3_upload_bucket. Truy cập Thiết lập Site và bổ sung các thiết lập đó. Xem bài viết "How to set up image uploads to S3?" để biết thêm chi tiết.' + s3_backup_config_warning: 'Máy chủ được cấu hình để upload các bản sao lưu dữ liệu lên s3, tuy nhiên ít nhất một trong các tùy chỉnh sau đây không được thiết lập: s3_access_key_id, s3_secret_access_key hoặc s3_backup_bucket. Truy cập Thiết lập Site và bổ sung các thiết lập đó. Xem bài viết "How to set up image uploads to S3?" để biết thêm chi tiết.' + image_magick_warning: 'Máy chủ đã cấu hình để tạo hình đại diện nhỏ từ những hình lới, nhưng ImageMagick chưa được cài đặt. Cài ImageMagick sử dụng trình quản lý package yêu thích của bạn hoặc tải về phiên bản mới nhất.' + failing_emails_warning: 'Có %{num_failed_jobs} email jobs thấ bại. Kiểm tra app.yml và chắc chắn rằng cấu hình máy chủ email đúng. Xem jobs thất bại ở Sidekiq.' + default_logo_warning: "Cập nhập logo của trang. Cập nhập logo_url, logo_small_url, và favicon_url trong Thiết lập trang." + contact_email_missing: "Điền địa chỉ email liên hệ để có thể nhận được các vấn đề cấp bách liên quan đến website của bạn, cập nhật trong Thiết lập website." + contact_email_invalid: "Email liên lạc của trang không hợp lệ. Cập nhật trong Thiết lập trang/a>." + title_nag: "Nhập tên trang của bạn. Cập nhập tiêu đề trong Thiết lập trang." + site_description_missing: "Điền một câu mô tả về website để hiển thị trên trang kết quả tìm kiếm, cập nhật site_description trong Thiết lập website." + consumer_email_warning: "Trang web của bạn được cài đặt sử dụng Gmail (hoặc một dịch vụ email khác) để gửi email. Gmail có giới hạn số lượng email bạn có thể gửi. Hãy xem xét sử dụng một dịch vụ email khác như mandrill.com để đảm bảo khả năng vận chuyển tất cả các email." + site_contact_username_warning: "Điền tên tài khoản điều hành viên để gửi tin nhắn tự động, cập nhật site_contact_username trong Thiết lập website." + notification_email_warning: "Email thông báo không thể gửi từ một địa chỉ email với tên miền của bạn, gửi email sẽ thất thường và không đáng tin cậy. Hãy thiết lập notification_email tới một địa chỉ tin cậy trong Thiết lập website." + subfolder_ends_in_slash: "Thư mục con của bạn được thiết lập không đúng, DISCOURSE_RELATIVE_URL_ROOT phải được kết thúc bằng dấu gạch chéo." + site_settings: + censored_words: "Từ sẽ tự động thay thế bằng ■■■■" + delete_old_hidden_posts: "Tự động ẩn bất kỳ bài viết ở ẩn hơn 30 ngày." + default_locale: "Ngôn ngữ mặc định của Discourse (Mã ISO 639-1)" + allow_user_locale: "Cho phép thành viên chọn ngôn ngữ của riêng trong thiết lập giao diện." + min_post_length: "Số kí tự tối thiểu trong bài đăng." + min_first_post_length: "Chiều dài tối thiểu cho bài viết đầu tiên (nội dung chủ đề) tính theo ký tự." + min_private_message_post_length: "Số kí tự tối thiểu trong tin nhắn." + max_post_length: "Số kí tự tối đa trong bài đăng." + min_topic_title_length: "Số kí tự tối thiểu trong tiêu đề chủ đề." + max_topic_title_length: "Số kí tự tối đa trong tiêu đề chủ đề." + min_private_message_title_length: "Chiều dài tối thiểu cho phép theo số kí tự của một thông điệp" + min_search_term_length: "Số kí tự tối thiểu trong từ khóa tìm kiếm." + search_tokenize_chinese_japanese_korean: "Bắt buộc tìm kiếm tách từ Chinese/Japanese/Korean ngay cả trên các site không phải là CJK" + allow_uncategorized_topics: "Cho phép các chủ đề được tạo ra mà không gán chuyên mục. LƯU Ý: Nếu có bất kỳ chủ đề nào chưa gán chuyên mục, bạn phải phân loại chúng trước khi thay đổi." + allow_duplicate_topic_titles: "Cho phép các chủ đề trùng tiêu đề." + unique_posts_mins: "Trong bao nhiêu phút người sử dụng có thể viết bài khác với nội dung giống nhau" + educate_until_posts: "Khi người dùng bắt đầu đăng (n) bài viết đầu tiên, hiện pop-up để hướng dẫn họ khi soạn thảo." + title: "Tên của trang này, sử dụng trong thẻ tiêu đề" + site_description: "Mô tả trang này trong một câu, nó sẽ được sử dụng trong thẻ meta description" + contact_email: "Địa chỉ email liên hệ của người chịu trách nhiệm trang này. Sử dụng cho những thông báo quan trọng giống như cờ không được quản lý, cũng giống form liện hệ /about cho những vấn đề cấp bách." + contact_url: "URL liên hệ trong trang này. Sử dụng trong form liên hệ /about cho những vấn đề cấp bách." + queue_jobs: "DEVELOPER ONLY! WARNING! By default, queue jobs in sidekiq. If disabled, your site will be broken." + crawl_images: "Lấy hình ảnh tử URL bên ngoài để thêm vào đúng chiều dài và chiều cao." + download_remote_images_to_local: "Tải ảnh về lưu trữ để tránh ảnh bị hư." + download_remote_images_threshold: "Dung lượng tối thiểu cần để tải ảnh từ xa về lưu trữ (tính bằng phần trăm)" + disabled_image_download_domains: "Tải ảnh từ xa sẽ không áp dụng với các tên miền sau. Phân cách bằng dấu |" + editing_grace_period: "Trong khoảng (n) giây sau khi gửi bài, chỉnh sửa sẽ không tạo ra một phiên bản mới trong bài lịch sử bài viết." + post_edit_time_limit: "Tác giả có thể sửa hoặc xóa bài viết của họ trong (n) phút sau khi đăng. 0 là mãi mãi." + edit_history_visible_to_public: "Cho phép mọi người nhìn thấy phiên bản trước khi chỉnh sửa bài viết. Khi không cho phép, chỉ nhân viên có thể xem." + delete_removed_posts_after: "Bài viết đã được xóa bởi tác giả sẽ được tự động xóa sau (n) giờ. Nếu cài là 0, bài viết sẽ được xóa ngay lập tức." + max_image_width: "Chiều rộng tối đa của ảnh thu nhỏ trong bài viết." + max_image_height: "Chiều cao tối đa của ảnh thu nhỏ trong bài viết." + category_featured_topics: "Số chủ đề hiện thị mỗi danh mục trong trang /categories. Sau khi thay đổi giá trị này, nó sẽ mất khoảng 15 phút để trang danh mục cập nhật." + show_subcategory_list: "Hiện danh sách chuyên mục con thay vì danh sách chủ đề khi truy cập vào chuyên mục." + fixed_category_positions: "Nếu được bật, bạn sẽ có thể sắp xếp chuyên mục theo một thứ tự cố định. Nếu không bật, chuyên mục sẽ được sắp xếp theo thứ tử hoạt động." + fixed_category_positions_on_create: "Nếu chọn, sắp xếp danh mục sẽ được thực hiện trong cửa sổ tạo chủ đề (yêu cầu fixed_category_positions)." + add_rel_nofollow_to_user_content: "Thêm rel='nofollow' cho tất cả các nội dung mà người dùng gửi, ngoại trừ các liên kết nội bộ (của tên miền chính). Nếu thay đổi, bạn phải thực hiện lại cho tất cả các bài viết với: \"rake posts:rebake\"" + exclude_rel_nofollow_domains: "Một danh sách tên miền mà rel='nofollow' không được thêm vào các liên kết, các tên miền con sẽ được tự động áp dụng như với tên miền chính. Tối thiểu, bạn nên thêm tên miền cấp cao nhất của website này để giúp search engine tìm kiếm tất cả các nội dung. Nếu các phần khác của website thuộc tên miền khác, cũng nên thêm vào." + post_excerpt_maxlength: "Chiều dài tối đa của đoạn trích / tóm tắt chủ đề." + post_onebox_maxlength: "Số ký tự tối đa của một bài onebox Discourse." + onebox_domains_whitelist: "Danh sách các tên miền cho phép onebox, các tên miền này phải hỗ trợ OpenGraph hoặc oEmbed. Kiểm tra tại http://iframely.com/debug" + logo_url: "Logo ở vị trí trên cùng của website nên là hình chữ nhật, nếu để trống thì tên website sẽ hiển thị." + digest_logo_url: "Logo thay thế đặt ở trên cùng của tập san email nên là hình chữ nhật, nếu để trống thì 'logo_url' sẽ được sử dụng." + logo_small_url: "Logo nhỏ ở vị trí trên cùng của website hiển thị khi cuộn xuống nên là hình vuông, nếu để trống thì icon trang chủ sẽ hiển thị." + favicon_url: "Favicon cho trang của bạn, xem tại http://en.wikipedia.org/wiki/Favicon, để chạy được với CDN ảnh phải là png" + mobile_logo_url: "Cố định vị trí hình logo sử dụng tại phía trên bên trái trang mobile của bạn. Nên là hình vuông. Nếu để trống, sẽ sử dụng `logo_url`. Ví dụ: http://example.com/uploads/default/logo.png" + apple_touch_icon_url: "Biểu tượng sử dụng trong các thiết bị cảm ứng của Apple. Kích thước gợi ý 144px x 144px" + notification_email: "Địa chỉ email 'Từ:' được dùng để gửi các email thiết yếu của hệ thống. Các tên miền quy định ở đây phải có SPF, DKIM và bản ghi PTR phải được thiết lập chính xác cho email đến." + email_custom_headers: "Danh sách xác định email header tùy chỉnh" + email_subject: "Tùy biến định dạng chủ đề cho chuẩn email. Xem tại https://meta.discourse.org/t/customize-subject-format-for-standard-emails/20801" + use_https: "URL đầy đủ đến trang (Discourse.base_url) là http hoặc https? KHÔNG BẬT NÓ CHO TỚI KHI HTTPS ĐÃ CÀI ĐẶT SẴN SẰNG VÀ ĐÃ CHẠY!" + summary_score_threshold: "Số điểm tối thiểu yêu cầu cho một bài viết bao gồm 'Tóm tắt chủ đề này'" + summary_posts_required: "Số bài viết tối thiểu trong một chủ đề trước khi 'Tóm tắt chủ đề này' được kích hoạt" + summary_likes_required: "Số lượt thích trong một chủ đề trước khi 'Tóm tắt chủ đề này' được kích hoạt" + summary_percent_filter: "Khi người dùng nhấn 'Tóm tắt chủ đề này', hiển thị phí trên % của bài viết" + summary_max_results: "Số bài viết tối đa trả ra bởi 'Tóm tắt chủ đề này'" + enable_private_messages: "Cho phép thành viên có cấp độ tin cậy mức 1 (cấu hình thông qua cấp độ tin cậy tối thiểu khi gửi tin nhắn) tạo và trả lời tin nhắn" + enable_long_polling: "Message Bus sử dụng để thông báo có thể sử dụng vòng gọi dài" + long_polling_base_url: "URL chính sử dụng cho vòng gọi dài (khi một CDN phục vụ nội dung động, hãy chắc chắn để thiết lập này là vòng gọi gốc), vd: http://origin.site.com" + long_polling_interval: "Thời gian server phải đợi trước khi gửi trả lời khi không có dữ liệu để gửi (chỉ với tài khoản đăng nhập)" + polling_interval: "When not long polling, how often should logged on clients poll in milliseconds" + anon_polling_interval: "How often should anonymous clients poll in milliseconds" + background_polling_interval: "How often should the clients poll in milliseconds (when the window is in the background)" + flags_required_to_hide_post: "Số lần đánh dấu để bài viết tự động ẩn và gửi tin nhắn đến người dùng (điền 0 để tắt)" + cooldown_minutes_after_hiding_posts: "Số phút một người dùng phải chờ trước khi họ có thể sửa một bài viết ẩn bởi gắn cờ cộng đồng" + max_topics_in_first_day: "Số chủ đề tối đa một thành viên được tạo trong ngày đầu tiên." + max_replies_in_first_day: "Số trả lời tối đa một thành viên được tạo trong ngày đầu tiên" + tl2_additional_likes_per_day_multiplier: "Tăng giới hạn thích mỗi ngày cho mức độ tin tưởng 2 (thành viên) bằng cách nhân với số này" + tl3_additional_likes_per_day_multiplier: "Tăng giới hạn thích mỗi ngày cho mức độ tin tưởng 3 (bình thường) bằng cách nhân với số này" + tl4_additional_likes_per_day_multiplier: "Tăng giới hạn thích mỗi ngày cho mức độ tin tưởng 4 (dẫn đầu) bằng cách nhân với số này" + num_flags_to_block_new_user: "Nếu bài viết của thành viên mới nhận được nhiều đánh dấu spam từ num_users_to_block_new_user thành viên khác, ẩn tất cả các bài viết của họ và ngăn chặn gửi bài trong tương lai, điền 0 để tắt." + num_users_to_block_new_user: "Nếu bài viết của thành viên mới nhận được num_flags_to_block_new_user đánh dấu spam từ các thành viên khác, ẩn tất cả các bài viết của họ và ngăn chặn gửi bài trong tương lai, điền 0 để tắt." + notify_mods_when_user_blocked: "Nếu một thành viên được khóa tự động, gửi tin nhắn đến tất cả các điều hành viên." + flag_sockpuppets: "Nếu thành viên mới trả lời chủ đề có cùng địa chỉ IP với thành viên mới tạo chủ đề, đánh dấu các bài viết của họ là spam tiềm năng." + traditional_markdown_linebreaks: "Sử dụng ngắt dòng truyền thống trong Markdown, đòi hỏi hai khoảng trống kế tiếp cho một ngắt dòng." + allow_html_tables: "Cho phép nhập bảng trong Markdown sử dụng các thẻ HTML. TABLE, THEAD, TD, TR, TH sẽ được sử dụng (đòi hỏi thực hiện lại cho các bài viết cũ có chứa bảng)" + post_undo_action_window_mins: "Số phút thành viên được phép làm lại các hành động gần đây với bài viết (like, đánh dấu...)." + must_approve_users: "Quản trị viên phải duyệt tất cả các tài khoản thành viên mới trước khi họ có quyền truy cập website. LƯU Ý: bật tính năng này trên site đang hoạt động sẽ hủy bỏ quyền truy cập đối với các tài khoản thành viên hiện tại!" + pending_users_reminder_delay: "Thông báo cho quản trị viên nếu thành viên mới đã chờ duyệt lâu hơn số giờ được thiết lập ở đây, đặt là -1 để tắt thông báo." + ga_tracking_code: "Mã theo dõi Google analytics (ga.js), ví dụu: UA-12345678-9; chi tiết http://google.com/analytics" + ga_domain_name: "Tên miền Google analytics (ga.js), ví dụ: mysite.com; chi tiết http://google.com/analytics" + ga_universal_tracking_code: "Mã theo dõi Google Universal Analytics (analytics.js) , Ví dụ: UA-12345678-9; chi tiết http://google.com/analytics" + ga_universal_domain_name: "Tên miền Google Universal Analytics (analytics.js), ví dụ: mysite.com; chi tiết http://google.com/analytics" + enable_escaped_fragments: "Trả lại tới Google's Ajax-Crawling API nếu không xác định được webcrawler. Xem chi tiết https://support.google.com/webmasters/answer/174992?hl=en" + enable_noscript_support: "Cho phép webcrawler search engine chuẩn hỗ trợ bằng thẻ noscript" + allow_moderators_to_create_categories: "Cho phép điều hành viên tạo danh mục mới" + cors_origins: "Cho phép CORS (Cross-Origin Requests). Mỗi nguyên gốc phải kèm theo http:// hoặc https://. Biến env DISCOURSE_ENABLE_CORS phải được đặt là 'true' để bật CORS." + use_admin_ip_whitelist: "Admin chỉ có thể đăng nhập nếu có địa chỉ IP được định nghĩa trước trong danh sách Screened IPs (Admin > Logs > Screened Ips)." + top_menu: "Xác định các mục nào hiển thị trong thanh điều hướng trang chủ, và theo thứ tự nào. Ví dụ latest|new|unread|categories|top|read|posted|bookmarks" + post_menu: "Xác định các mục nào hiển thị trên menu bài viết, và theo thứ tự nào. Ví dụ like|edit|flag|delete|share|bookmark|reply" + post_menu_hidden_items: "Các mục được để ẩn theo mặc định trong menu bài viết trừ khi click vào dấu '...' để mở rộng." + share_links: "Xác định các mục nào hiển thị trên hộp thoại chia sẻ, và theo thứ tự nào." + track_external_right_clicks: "Theo dõi các liên kết ngoài được click đúng (vd: mở trong tab mới) bị vô hiệu hóa theo mặc định do Rewrite URL." + site_contact_username: "Tên tài khoản quản trị viên hợp lệ để gửi tất cả các thông báo tự động. Nếu để trống, tài khoản mặc định của hệ thống sẽ được sử dụng." + send_welcome_message: "Gửi tất cả các thành viên mới một thông điệp chào mừng kèm theo hướng dẫn nhanh." + suppress_reply_directly_below: "Không hiện bộ đếm trả lời mở rộng cho bài viết chỉ có duy nhất một trả lời trực tiếp bên dưới bài viết này." + suppress_reply_directly_above: "Không hiện trả lời mở rộng cho bài viết chỉ có duy nhất một trả lời trực tiếp bên trên bài viết này." + suppress_reply_when_quoting: "Không hiện trả lời mở rộng cho bài viết chỉ trích dẫn trả lời." + max_reply_history: "Số tối đa trả lời được mở rộng khi trả lời mở rộng" + topics_per_period_in_top_summary: "Số lượng chủ đề top hiển thị trong tóm tắt các chủ đề top theo mặc định." + topics_per_period_in_top_page: "Số lượng chủ đề top hiển thị khi click 'Xem thêm'." + redirect_users_to_top_page: "Tự động chuyển thành viên mới và vắng mặt lâu ngày lên trên cùng trang." + top_page_default_timeframe: "Khung thời gian mặc định cho trang xem trên cùng." + show_email_on_profile: "Hiển thị email thành viên trên trang hồ hơ (chỉ cho họ và quản trị viên)" + email_token_valid_hours: "Token quyên mật khẩu / kích hoạt tài khoản có giá trị trong (n) giờ." + email_token_grace_period_hours: "Token quyên mật khẩu / kích hoạt tài khoản vẫn còn giá trị (n) giờ sau khi được gia hạn" + enable_badges: "Kích hoạt hệ thống huy hiệu" + enable_whispers: "Cho phép quản trị viên giao tiếp riêng trong chủ đề. (thực nghiệm)" + allow_index_in_robots_txt: "Chỉ rõ trong robots.txt trang web này cho phép tạo chỉ mục bởi web search engines." + email_domains_blacklist: "Một danh sách đuôi email mà người dùng không được phép dùng để đăng ký tài khoản. Ví dụ: maillinator.com|trashmail.net. Lưu ý mỗi tên miền cách nhau bởi dấu \"|\"." + email_domains_whitelist: "Danh sách tên miền người dùng ĐƯỢC PHÉP đăng ký tài khoản. CẢNH BÁO: người dùng với tên miền email khác trong danh sách sẽ không được phép đăng ký!" + forgot_password_strict: "Không thông báo cho người dùng tài không tồn tại khi họ dùng chức năng quyên mật khẩu." + log_out_strict: "Khi đăng xuất, đăng xuất TẤT CẢ session cho tất cả thiế bị" + version_checks: "Ping Discourse Hub để cập nhật phiên bản và hiện thông báo phiên bản mới trong bảng điều khiển quản trị" + new_version_emails: "Gửi email đến địa chỉ contact_email khi có phiên bản Discourse mới." + port: "DEVELOPER ONLY! WARNING! Sử dụng HTTP port thay vì mặc định port 80. Để trống mặc định port 80." + force_hostname: "DEVELOPER ONLY! LƯU Ý! Chỉ rõ hostname trong URL. Để trống là mặc định." + invite_expiry_days: "Key mời người dùng có giới hạn bao lâu? tính theo ngày" + invite_passthrough_hours: "Bao lâu người dùng có thể sử dụng mã lời mời trước đó để đăng nhập, theo giờ" + invite_only: "Đăng ký tự do đã khóa, tất cả người dùng phải được mời bởi những thành viên khác hoặc nhân viên." + login_required: "Yêu cầu chứng thực để đọc nội dung trên trang web, không cho phép người dùng nặc danh truy cập." + min_username_length: "Chiều dài username tối thiểu." + max_username_length: "Chiều dài username tối đa." + reserved_usernames: "Những username không được phép đăng ký." + min_password_length: "Chiều dài mật khẩu tối thiểu." + block_common_passwords: "Không cho phép mật khẩu trong danh sách 10.000 mật khẩu phổ biến." + enable_sso: "Cho phép dùng single sign on bằng trang ngoài (CẢNH BÁO: ĐỊA CHỈ EMAIL CỦA NGƯỜI DÙNG PHẢI ĐƯỢC CHỨNG THỰC BỞI TRANG NGOÀI!)" + enable_sso_provider: "Thực hiện giao thức cung cấp Discourse SSO tại điểm cuối /session/sso_provider, yêu cầu phải thiết lập sso_secret" + sso_url: "URL của single sign on enpoint" + sso_secret: "Chuỗi bảo mật đã được sử dụng để chứng thực thông tin SSO, chắc chắn nó có ít nhất 10 ký tự." + sso_overrides_email: "Ghi đè email cục bộ với email trang ngoài từ SSO cho tất cả các lần đăng nhập, và ngăn chặn những thay đổi cục bộ. (LƯU Ý: sự khác biệt có thể xảy ra do sự bình thường hóa các email cục bộ)" + sso_overrides_username: "Ghi đè tên tài khoản cục bộ với tài khoản trang ngoài từ SSO cho tất cả các lần đăng nhập, và ngăn chặn những thay đổi cục bộ. (LƯU Ý: sự khác biệt có thể xảy ra do yêu cầu độ dài tên tài khoản khác nhau)" + sso_overrides_name: "Ghi đè tên thành viên cục bộ với tên thành viên trang ngoài từ SSO cho tất cả các lần đăng nhập, và ngăn chặn những thay đổi cục bộ." + sso_overrides_avatar: "Ghi đè avatar thành viên cục bộ với avatar thành viên trang ngoài từ SSO. Nếu bật, bạn nên vô hiệu hóa allow_uploaded_avatars" + sso_not_approved_url: "Chuyển những tài khoản SSO chưa duyệt tới URL này" + enable_local_logins: "Bật tên tài khoản và mật khẩu đăng nhập cục bộ dựa trên tài khoản. (Chú ý: bật thiết lập này để kích hoạt chức năng gửi lời mời)" + allow_new_registrations: "Cho phép đăng ký người dùng mới. Bỏ chọn để bất cứ ai cũng có thể tạo tài khoản mới." + enable_signup_cta: "Hiện thông báo với thành viên ẩn danh khi họ quay lại để yêu cầu họ đăng ký tài khoản." + enable_yahoo_logins: "Cho phé chứng thực qua Yahoo" + enable_google_oauth2_logins: "Cho phép chứng thực qua Google Oauth2. Nó là cách chứng thực mà Google hỗ trợ. Yêu cầu key và secret." + google_oauth2_client_id: "Client ID ứng dụng Google của bạn." + google_oauth2_client_secret: "Client secret ứng dụng Google của bạn." + enable_twitter_logins: "Cho phép chứng thực qua Twitter, yêu cầu twitter_consumer_key và twitter_consumser_secret" + twitter_consumer_key: "Consumer key cho chứng thực Twitter, đăng ký tại http://dev.twitter.com" + twitter_consumer_secret: "Consumer secret cho chứng thực Twitter, đăng ký tại http://dev.twitter.com" + enable_facebook_logins: "Cho phép chứng thực Facebook, yêu cầu facebook_app_id và facebook_app_secret" + facebook_app_id: "App id cho chứng thực Facebook, đăng ký tại https://developers.facebook.com/apps" + facebook_app_secret: "App secret cho chứng thực Facebook, đăng ký tại https://developers.facebook.com/apps" + enable_github_logins: "Cho phép chứng thực Github, yêu cầu gitbug_client_id và githup_client_secret" + github_client_id: "Client id cho chứng thực Github, đăng ký tại https://github.com/settings/applications" + github_client_secret: "Client secret cho chứng thực Github, đăng ký tại https://github.com/settings/applications" + allow_restore: "Cho phép phục hồi, nó có thể thay thế TẤT CẢ dữ liệu trang web! Bỏ chọn, trừ khi bạn có kế hoạch phục hồi một bản sao lưu" + maximum_backups: "Số bản sao lưu tối đa lưu trong đĩa cứng. Những bản sao lưu cũ sẽ được xóa tự động" + automatic_backups_enabled: "Chạy sao lưu tự động như cấu hình trong tần số sao lưu" + backup_frequency: "Tần số sao lưu trang web, trong ngày." + enable_s3_backups: "Tải bản sao lưu lên S3 khi hoàn tất. QUAN TRỌNG: yêu cầu chứng thực S3 đã được nhập trong cấu hình File." + s3_backup_bucket: "Địa chỉ tách biệt lưu trữ backup. LƯU Ý: đây phải là địa chỉ được giành riêng." + backup_time_of_day: "Thời gian theo ngày UTC khi backup." + backup_with_uploads: "Kèm theo cả thư mục uploads theo lịch trình backup. Tắt tính năng này sẽ chỉ backup csdl." + active_user_rate_limit_secs: "Tần số cập nhật trường 'last_seen_at, tính theo giây" + verbose_localization: "Hiển thị các mẹo trong giao diện người dùng" + previous_visit_timeout_hours: "Bao lâu lần ghé thăm cuối cùng được coi như lần ghé thăm 'trước', theo giờ" + top_topics_formula_log_views_multiplier: "giá trị nhật ký lượt xem nhân với (n) trong công thức chủ đề top: `log(views_count) * (n) + op_likes_count * 0.5 + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_first_post_likes_multiplier: "giá trị của lượt like bài viết đầu tiên nhân với (n) trong công thức chủ đề top: `log(views_count) * 2 + op_likes_count * (n) + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_least_likes_per_post_multiplier: "giá trị số lượt like tối thiểu của mỗi bài viết nhân với (n) trong công thức chủ đề top: `log(views_count) * 2 + op_likes_count * 0.5 + LEAST(likes_count / posts_count, (n)) + 10 + log(posts_count)`" + rate_limit_create_topic: "Sau khi tạo một chủ đề, người dùng phải chờ (n) giây trước khi tạo một chủ đề khác." + rate_limit_create_post: "Sau khi đăn bài, người dùng phải chờ (n) giây trước khi đăng bài khác." + rate_limit_new_user_create_topic: "Sau khi tạo một chủ đề, người dùng mới phải chờ (n) giây trước khi tạo chủ đề khác." + rate_limit_new_user_create_post: "Sau khi đăng bài, người dùng mới phải chờ (n) giây trước khi đăng bài khác." + max_likes_per_day: "Số tối đa người dùng có thể like mỗi ngày." + max_flags_per_day: "Số tối đa mà người dùng có thể gắn cờ mỗi ngày." + max_bookmarks_per_day: "Số tối đa người dùng có thể đánh dấu mỗi ngày." + max_edits_per_day: "Số tối đa người dùng có thể chỉnh sửa mỗi ngày." + max_topics_per_day: "Số chủ đề tối đa người dùng có thể tạo mỗi ngày." + max_private_messages_per_day: "Số tin nhắn tối đa người dùng có thể tạo mỗi ngày." + max_invites_per_day: "Số tối đa người dùng có thể gửi lời mời mỗi ngày." + max_topic_invitations_per_day: "Số tối đa lời mời chủ đề thành viên có thể gửi mỗi ngày." + suggested_topics: "Số chủ đề gợi ý hiện ở cuối một chủ đề" + limit_suggested_to_category: "Chỉ hiện thị những chủ đề từ danh mục hiện tại trong chủ đề gợi ý." + clean_up_uploads: "Loại bỏ không triệt các dòng mồ côi khi upload để ngăn chặn hosting bất hợp pháp. LƯU Ý: bạn cần phải backup thư mục /uploads trước khi bật thiết lập này." + clean_orphan_uploads_grace_period_hours: "Thời gian gia hạn (theo giờ) trước khi dòng mồ côi upload được loại bỏ." + purge_deleted_uploads_grace_period_days: "Thời gian gia hạn (theo ngày) trước khi upload cần xóa được xóa." + purge_unactivated_users_grace_period_days: "Thời gian gia hạn (theo ngày) trước khi người dùng chưa kích hoạt tài khoản sẽ được xóa." + enable_s3_uploads: "Đặt thư mục upload trên Amazon S3. QUAN TRỌNG: yêu cầu chứng thực S3 (cả ID khóa truy cập & khóa bảo mật)." + s3_use_iam_profile: 'Sử dụng AWS EC2 IAM để lấy khóa. LƯU Ý: bật thiết lập này sẽ ghi đè thiết lập "s3 access key id" và "s3 secret access key".' + s3_upload_bucket: "Tên Amazon S3 để lưu trữ các file sẽ được upload. CHÚ Ý: phải là chữ thường, không cách và không gạch dưới." + s3_access_key_id: "Amazon S3 access key id này sẽ được sử dụng để tải lên ảnh." + s3_secret_access_key: "Amazon S3 secret access key này sẽ được sử dụng để tải lên ảnh." + s3_region: "Amazon S3 region name sẽ được sử dụng để tải lên ảnh." + s3_cdn_url: "CDN URL được sử dụng cho tất cả các tài nguyên S3 (vd: https://cdn.somewhere.com). CHÚ Ý: sau khi thay đổi thiết lập này bạn phải tạo lại các bài viết cũ." + avatar_sizes: "Danh sách những kích thước hình đại diện tự động khởi tạo." + external_system_avatars_enabled: "Sử dụng dịch vụ ảnh đại diện bên ngoài." + external_system_avatars_url: "URL của dịch vụ avatar ngoài, cho phép thay thế {username} {first_letter} {color} {size}" + default_opengraph_image_url: "URL của ảnh opengraph mặc định." + enable_flash_video_onebox: "Cho phép nhúng liên kết swf và flv (Adobe Flash). CHÚ Ý: có thể chứa đựng các rủi ro bảo mật." + default_invitee_trust_level: "Bậc tin tưởng mặc định (0-4) cho thành viên được mời." + default_trust_level: "Cấp độ tin cậy mặc định (0-4) cho tất cả các thành viên mới. CHÚ Ý! Thay đổi thiết lập này sẽ đặt bạn vào nguy cơ spam cao." + tl1_requires_topics_entered: "Số chủ đề một thành viên mới phải truy cập trước khi được lên bậc tin tưởng 1" + tl1_requires_read_posts: "Số chủ đề một thành viên mới phải đọc trước khi được lên bậc tin tưởng 1" + tl1_requires_time_spent_mins: "Số phút một thành viên mới phải đọc trước khi được lên bậc tin tưởng 1" + tl2_requires_topics_entered: "Số chủ đề một thành viên mới phải truy cập trước khi được lên bậc tin tưởng 2" + tl2_requires_read_posts: "Số chủ đề một thành viên mới phải đọc trước khi được lên bậc tin tưởng 2" + tl2_requires_time_spent_mins: "Số phút một thành viên mới phải đọc trước khi được lên bậc tin tưởng 2" + tl2_requires_days_visited: "Số ngày một thành viên phải ghé thăm site trước khi được thăng lên bậc tin cậy cấp 2." + tl2_requires_likes_received: "Số like một thành viên phải nhận được trước khi được thăng lên bậc tin cậy cấp 2." + tl2_requires_likes_given: "Số like một thành viên phải thực hiện trước khi được thăng lên bậc tin cậy cấp 2." + tl2_requires_topic_reply_count: "Số chủ đề thành viên phải trả lời trước khi được thăng lên bậc tin cậy cấp 2." + tl3_requires_topics_viewed_all_time: "Số lượng chủ đề tối thiểu mà thành viên phải xem trước khi được thăng lên độ tin cậy cấp 3." + tl3_requires_posts_read_all_time: "Tổng số bài viết tối thiểu mà thành viên phải đọc trước khi được thăng lên độ tin cậy cấp 3." + tl3_promotion_min_duration: "Số ngày tối thiểu chương trình thăng hạng cấp 3 kéo dài trước khi thành viên có thể bị giáng cấp xuống độ tin cậy cấp 2." + tl3_links_no_follow: "Không loại bỏ rel=nofollow khỏi các liên kết trong bài viết của thành viên có độ tin cậy cấp 3." + min_trust_to_create_topic: "Bậc tin tưởng tối thiểu để tạo một chủ đề mới." + min_trust_to_edit_wiki_post: "Bậc tin cậy tối thiểu cần thiết để có thể sửa bài viết được đánh dấu là wiki." + min_trust_to_allow_self_wiki: "Bậc tin cậy tối thiểu cần thiết để người dùng có thể đánh dấu bài viết của họ là wiki." + min_trust_to_send_messages: "Bậc tin cậy tối thiểu cần thiết để có thể tạo hội thoại riêng." + newuser_max_links: "Bao nhiêu liên kết tài khoản mới có thể thêm vào bài viết." + newuser_max_images: "Bao nhiêu hình tài khoản mới có thể thêm vào bài viết." + newuser_max_attachments: "Bao nhiêu đính kèm tài khoản mới có thể thêm vào bài viết" + newuser_max_mentions_per_post: "Số tối đa thông báo @name mà thành viên mới có thể sử dụng trong bài viết." + newuser_max_replies_per_topic: "Số lượng tối đa trả lời mà thành viên có thể thực hiện trong một chủ đề cho đến khi có ai đó gửi trả lời." + max_mentions_per_post: "Số tối đa thông báo @name mà tất cả mọi người có thể sử dụng trong bài viết." + email_time_window_mins: "Chờ (n) phút trước khi gửi bất kỳ một email thông báo nào, để cung cấp cho người dùng cơ hội để chỉnh sửa và hoàn tất bài viết của họ." + title_max_word_length: "Chiều dài tối đa chữ cho phép, tính theo ký tự, trong một tiêu đề chủ đề." + allow_uppercase_posts: "Cho phép viết hoa tất cả các chữ trong tên chủ đề hoặc nội dung bài viết." + title_fancy_entities: "Chuyển đổi các ký tự ASCII thành các đối tượng HTML trong tên chủ đề, http://daringfireball.net/projects/smartypants/" + min_title_similar_length: "Chiều dài tối thiểu của tiêu đề trước khi kiểm tra trùng chủ đề." + min_body_similar_length: "Chiều dài tối thiểu của nội dung bài viết trước khi kiểm trang chủ đề tương tự." + category_colors: "Danh sách mã màu hexa cho phép cho danh mục." + max_attachment_size_kb: "Kích thước file tải lên tối đa tính theo kB. đã cấu hình trong nginx (client_max_body_size) / apache hoặc proxy." + authorized_extensions: "Danh sách định dạng file cho phép tải lên (sử dụng '*' để cho phép tất cả loại tập tin)" + max_similar_results: "Số lượng chủ đề tương tự hiển thị phía trên bộ soạn thảo khi soạn chủ đề mới, so sánh dựa trên tiêu đề và nội dung." + reply_by_email_enabled: "Cho phép trả lời chủ đề qua email." + pop3_polling_ssl: "Sử dụng SSL khi kết nối tới POP3 server. (Đề nghị sử dụng)" + email_in_min_trust: "Bậc tin tưởng tối thiểu cho phép một thành viên gửi chủ đề mới qua email." + username_change_period: "Số ngày thành viên có thể thay đổi tên đăng nhập sau khi đăng kí (0 để vô hiệu hóa chức năng thay đổi tên thành viên)" + email_editable: "Cho phép thành viên thay đổi địa chỉ email sau khi đăng kí" + logout_redirect: "Trang chuyển hướng sau khi đăng xuất . Ví dụ : (http://somesite.com/logout)" + allow_uploaded_avatars: "Cho phép người dùng tải lên hình hồ sơ." + allow_animated_thumbnails: "Tạo ảnh động thu nhỏ cho ảnh .gif" + digest_min_excerpt_length: "Số kí tự tối thiểu của tóm tắt bài viết trong bản tin tóm tắt gửi qua email" + max_daily_gravatar_crawls: "Giới hạn số lần Discourse sẽ kiểm tra Gravatar mới trong một ngày" + allow_profile_backgrounds: "Cho phép người dùng tải lên ảnh nền" + suppress_uncategorized_badge: "Không hiển thị huy hiệu cho các chủ đề chưa phân loại trong danh sách chủ đề" + invites_per_page: "Lời mời mặc định hiển thị trên trang thành viên" + short_progress_text_threshold: "Sau khi số bài đăng của một chủ đề vượt qua giới hạn này, thanh tiến trình sẽ chỉ hiện số thứ tự của bài đăng hiện tại. Nếu bạn thay đổi chiều rộng của thanh tiến trình, bạn có thể cần thay đổi giá trị này" + show_create_topics_notice: "Nếu trang có ít hơn 5 chủ đề công khai, hiển thị một thông báo yêu cầu quản trị tạo thêm các chủ đề mới" + prevent_anons_from_downloading_files: "Cấm khách truy cập tải các tập tin đính kèm. CẢNH BÁO: việc này sẽ chặn những hình ảnh không thuộc giao diện trang hoạt động" + default_email_mailing_list_mode: "Mặc định gửi email cho mỗi bài viết mới." + default_email_always: "Mặc định gửi email thông báo mỗi khi người dùng kích hoạt." + default_other_external_links_in_new_tab: "Mặc định mở các liên kết ngoài trong thẻ mới " + errors: + invalid_email: "Địa chỉ email sai" + invalid_username: "Không có thành viên với tên đăng nhập này" + invalid_integer_min_max: "Giá trị phãi nằm giữa %{min} và %{max}." + invalid_integer_min: "Giá trị phải bằng %{min} hoặc lớn hơn" + invalid_integer_max: "Giá trị không thể cao hơn %{max}." + invalid_integer: "Giá trị phải là một số nguyên" + regex_mismatch: "Giá trị không giống với định dạng" + invalid_string: "Giá trị không hợp lệ." + invalid_string_min_max: "Phải nằm giữa %{min} và %{max} ký tự." + invalid_string_min: "Phải ít nhất %{min} ký tự." + invalid_string_max: "Không nhiều hơn %{max} ký tự." + invalid_reply_by_email_address: "Giá trị phải chứa '%{reply_key}' và phải khác với email thông báo." + notification_types: + mentioned: "%{display_username} đề cập bạn ở %{link}" + liked: "%{display_username} thích bài viết %{link} của bạn" + replied: "%{display_username} trả lời bài viết %{link} của bạn" + quoted: "%{display_username} trích dẫn bài viết %{link} của bạn" + edited: "%{display_username} sửa đổi bài viết %{link} của bạn" + posted: "%{display_username} viết bài ở %{link}" + moved_post: "%{display_username} di chuyển bài viết của bạn tới %{link}" + private_message: "%{display_username} gửi bạn một tin nhắn: %{link}" + invited_to_private_message: "%{display_username} mời bạn xem tin nhắn: %{link}" + invitee_accepted: "%{display_username} chấp nhận lời mời của bạn" + linked: "%{display_username} kết nối với bạn ở %{link}" + granted_badge: "Bạn kiếm được %{link}" + search: + within_post: "#%{post_number} bởi %{username}" + types: + category: 'Thư mục' + topic: 'Kết quả' + user: 'Thành viên' + original_poster: "Người viết gốc" + most_posts: "Bài viết Phỏ biến" + redirected_to_top_reasons: + new_user: "Chào mừng đến với cộng dồng của chúng tôi! Ở đây có những chủ để phổ biến." + not_seen_in_a_month: "Chào mừng quay trở lại! Chúng tôi thấy bạn truy cập một khoảng thời gian. Ở đây có những bài viết phổ biến từ lúc bạn đ." + change_owner: + deleted_user: "xóa người dùng" + topic_statuses: + archived_enabled: "Chủ đề này được đưa vào lưu trữ. Nó sẽ không được sửa đổi nữa. " + archived_disabled: "Chủ đề này được đưa khỏi lưu trữ. Nó có thể được sửa đổi." + closed_enabled: "Chủ đề này được đóng lại. Các trả lời mới sẽ không được chấp nhận." + closed_disabled: "Chủ đề này được mở ra. Các trả lời mới sẽ được chấp nhận." + autoclosed_enabled_lastpost_hours: + other: "Chủ đề này đã được đóng tự động %{count} giờ sau phản hồi cuối cùng. Không còn cho phép phản hồi mới." + autoclosed_disabled: "Chủ đề này đã được mở. Bạn có thể bình luận" + autoclosed_disabled_lastpost: "Chủ đề này đã được mở. Bạn có thể bình luận" + visible_enabled: "Chủ để này đã được lưu. Nó sẽ hiển thị trong danh sách chủ đề." + login: + not_approved: "Tài khoản của bạn chưa được kiểm duyệt. Bạn sẽ nhận được email thông báo khi bạn được phép đăng nhập." + incorrect_username_email_or_password: "Không đúng tài khoản, email hoặc mật khẩu" + wait_approval: "Cảm ơn bạn đã đăng ký. Chúng tôi sẽ thông báo sau khi tài khoản của bạn được kiểm duyệt." + active: "Tài khoản của bạn đã được kích hoạt và sẵn sàng để sử dụng." + not_activated: "Bạn không thể đăng nhập bây giờ. Chúng tôi đã gửi bạn một email kích hoạt tài khoản. Vui lòng làm theo hướng dẫn trong email để kích hoạt tài khoản của bạn." + not_allowed_from_ip_address: "Bạn không thể đăng nhập như là %{username} từ địa chỉ IP này." + admin_not_allowed_from_ip_address: "Bạn không thể đăng nhập như quản trị từ IP này." + suspended: "Bạn không thể đăng nhập cho tới ngày %{date}." + suspended_with_reason: "Tài khoản bị tạm khóa cho tới %{date}: %{reason}" + errors: "%{errors}" + not_available: "Không có sẵn. Thử %{suggestion}?" + something_already_taken: "Có lỗi xảy ra, tên đăng nhập hoặc email đã được đăng ký. Thử sử dụng chức năng quên mật khẩu." + omniauth_error: "Xin lỗi, có lỗi khi xác thực tài khoản của bạn. Bạn không được duyệt chứng thực?" + omniauth_error_unknown: "Cố lỗi xảy ra khi bạn đăng nhập, vui lòng thử lại." + new_registrations_disabled: "Đăng ký tài khoản mới không được cho phép tại thời điểm này." + password_too_long: "Mật khẩu giới hạn không quá 200 ký tự." + email_too_long: "Email bạn cung cấp quá dài. Địa chỉ email phải không quá 254 ký tự, và tên miền phải không quá 253 ký tự." + reserved_username: "Tên đăng nhập không được cho phép." + missing_user_field: "Bạn không hoàn tất tất cả các trường người dùng" + close_window: "Chứng thực hoàn tất. Đóng của sổ này để tiếp tụ." + user: + username: + characters: "chỉ bao gồm số, ký tự và dấu gạch dưới" + unique: "phải độc nhất" + blank: "phải hiện hành" + email: + not_allowed: "không được chấp nhận từ nhà cung cấp email đó. Vui long sử dụng địa chỉ email khác." + blocked: "không được chấp nhận." + ip_address: + blocked: "Đăng ký mới không cho phép từ địa chỉ IP của bạn." + invite_forum_mailer: + subject_template: "%{invitee_name} đã mời bạn gia nhập %{site_domain_name}" + text_body_template: | + %{invitee_name} đã mời bạn gia nhập + + > **%{site_title}** + > + > %{site_description} + + Nếu bạn không thích, nhấn vào link dưới đây: + + %{invite_link} + + Nó được mời từ một người dùng tin cập, bạn không cần đăng nhập. + invite_password_instructions: + subject_template: "Đặt mật khẩu cho tài khoản của bạn ở %{site_name}" + new_version_mailer: + subject_template: "[%{site_name}] Phiên bạn Discourse mới, cập nhật đã sẵn sàng" + new_version_mailer_with_notes: + subject_template: "[%{site_name}] cập nhật đã sẵn sàng" + flags_dispositions: + agreed: "Cảm ơn đã cho chúng tôi biết. Chúng thôi đồng ý nó là một vấn đề và chúng tôi sẽ xem xét nó." + agreed_and_deleted: "Cảm ơn đã cho chúng tôi biết thông tin. Chúng tôi đồng ý đây là một vấn đề và chúng tôi đã xóa bài viết này." + disagreed: "Cảm ơn đã cho chúng tôi biết thông tin. Chúng tôi đang xem xét nó." + deferred: "Cảm ơn đã cho chúng tôi biết thông tin. Chúng tôi đang xem xét nó." + system_messages: + welcome_user: + subject_template: "Chào mừng đến với %{site_name}!" + welcome_invite: + subject_template: "Chào mừng đến với %{site_name}!" + backup_succeeded: + subject_template: "Sản sao lưu hoàn tất thành công" + backup_failed: + subject_template: "Sao lưu lỗi." + text_body_template: | + Sao lưu lỗi. + + Đây là log: + + ``` + %{logs} + ``` + restore_succeeded: + subject_template: "Phục hồi thành công" + text_body_template: "Phục hồi đã thành công." + restore_failed: + subject_template: "Phục hồi thất bại." + text_body_template: | + Phục hồi thất bại. + + Đây là log: + + ``` + %{logs} + ``` + csv_export_succeeded: + subject_template: "Xuất dữ liệu hoàn tất" + csv_export_failed: + subject_template: "Xuất dữ liệu thất bại" + text_body_template: "Chúng tôi xin lỗi, những dữ liệu bạn xuất bị lỗi. Vui lòng xem log hoặc liên hệ nhân viên." + email_reject_no_account: + subject_template: "[%{site_name}] Vấn đề Email -- Không xác định tài khoản" + email_reject_empty: + subject_template: "[%{site_name}] Vấn đề Email -- Không có nội dung" + email_reject_parsing: + subject_template: "[%{site_name}] Vấn đề Email-- Không nhận dạng được nội dung" + email_reject_invalid_access: + subject_template: "[%{site_name}] Vấn đề Email -- truy cập không phù hợp" + email_reject_reply_key: + subject_template: "[%{site_name}] Vấn đề Email -- Không xác định được key trả lời" + email_reject_topic_not_found: + subject_template: "[%{site_name}] Vấn đề Email -- Không tìm thấy chủ đề" + email_reject_topic_closed: + subject_template: "[%{site_name}] Vấn đề Email -- Chủ đề đóng" + email_reject_auto_generated: + subject_template: "[%{site_name}] Vấn đề Email -- Tự động tạo trả lời" + email_error_notification: + subject_template: "[%{site_name}] Vấn đề Email -- chứng thực POP lỗi" + too_many_spam_flags: + subject_template: "Tài khoản mới bị chặn" + blocked_by_staff: + subject_template: "Tài khoản bị khóa" + unblocked: + subject_template: "Tài khoản được mở khóa" + pending_users_reminder: + subject_template: + other: "%{count} thành viên đang chờ duyệt" + subject_re: "Re:" + subject_pm: "[PM]" + user_notifications: + previous_discussion: "Các trả lời trước" + unsubscribe: + title: "Bỏ theo dõi" + description: "Bạn không thích nhận mail giống mail này? Nhấn vào bỏ theo dõi để bỏ đăng ký ngay lập tức:" + posted_by: "Đăng bởi %{{username} ngày %{post_date}" + user_invited_to_private_message_pm: + subject_template: "[%{site_name}] %{username} mời bạn trả lời thông điệp '%{topic_title}'" + user_replied: + subject_template: "[%{site_name}] %{topic_title}" + user_quoted: + subject_template: "[%{site_name}] %{topic_title}" + user_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + user_posted: + subject_template: "[%{site_name}] %{topic_title}" + user_posted_pm: + subject_template: "[%{site_name}] [PM] %{topic_title}" + digest: + why: "Tóm tắt %{site_link} từ lần cuối truy cập %{last_seen_at}" + subject_template: "[%{site_name}] Tóm tắt" + new_activity: "Hoạt động mới ở chủ đề và bài viết của bạn:" + top_topics: "Bài viết phổ biến" + other_new_topics: "Chủ đề phổ biến" + click_here: "bấm vào đây" + from: "%{site_name} tóm tắt" + read_more: "Đọc Tiếp" + more_topics: "Đây là %{new_topics_since_seen} những chủ đề mới khác." + more_topics_category: "Thêm chủ đề mới:" + forgot_password: + subject_template: "[%{site_name}] Đặt lại mật khẩu" + set_password: + subject_template: "[%{site_name}] Đặt Mật khẩu" + admin_login: + subject_template: "[%{site_name}] Đăng nhập" + account_created: + subject_template: "[%{site_name}] Tài khoản mới" + signup_after_approval: + subject_template: "Bạn đã được kiểm duyệt ở %{site_name}!" + signup: + subject_template: "[%{site_name}] Xác nhận tài khoản mới của bạn" + page_not_found: + popular_topics: "Phổ biến" + recent_topics: "Gân đây" + see_more: "Thêm" + search_title: "Tìm trang này" + search_google: "Goole" + login_required: + welcome_message: | + #[Chào mừng đến %{title}](#welcome) + Trang này yêu cầu phải có tài khoản. Vui lòng tạo một tài khoản hoặc đăng nhập để tiếp tục. + terms_of_service: + title: "Điều khoản Dịch vụ" + signup_form_message: 'Tôi đã đọc và đồng ý với Điều khoản dịch vụ.' + deleted: 'đã bị xóa ' + upload: + edit_reason: "tải về một bản sao của hình ảnh." + unauthorized: "Xin lỗi, tập tin của bạn tải lên không được cho phép (định dạng cho phép: %{authorized_extensions})." + pasted_image_filename: "Hình ảnh được chèn" + store_failure: "Tải lên lỗi #%{upload_id} cho tài khoản #%{user_id}." + file_missing: "Xin lỗi, bạn phải cung cấp tập tin để tải lên" + attachments: + too_large: "Xin lỗi, tập tin bạn tải lên quá lớn (kích thước tối đa %{max_size_kb}KB)." + images: + too_large: "Xin lỗi, hình bạn tải lên quá lớn (kích thước tối đa %{max_size_kb}KB), Vui lòng chỉnh lại kích thước và thử lại." + size_not_found: "Xin lỗi, không thể xác định kích thước hình. Có thể hình của bạn bị lỗi?" + email_log: + no_user: "không tìm thấy người dùng với id %{user_id}" + anonymous_user: "Người dùng là nặc danh" + suspended_not_pm: "Tài khoản bị tạm khóa, không có tin nhắn" + seen_recently: "Tài khoản đã xem gần đây" + post_not_found: "Không tìm thấy bài viết với id %{post_id}" + notification_already_read: "Thông báo email này đã được đọc" + topic_nil: "post.topic is nil" + post_deleted: "bài viết đã bị xóa bởi tác giả" + user_suspended: "người dùng đã bị tạm khóa" + already_read: "người dùng đã đọc bài viết này" + message_blank: "tin nhắn rỗng" + message_to_blank: "message.to rỗng" + text_part_body_blank: "text_part.body rỗng" + body_blank: "nội dung rỗng" + color_schemes: + base_theme_name: "Cơ bản" + about: "Giới thiệu" + guidelines: "Hướng dẫn" + privacy: "Riêng tư" + edit_this_page: "Sửa trang này" + csv_export: + boolean_yes: "Đồng ý" + boolean_no: "Không" + guidelines_topic: + title: "FAQ/Hướng dẫn" + tos_topic: + title: "Điều khoản Dịch vụ" + privacy_topic: + title: "Chính sách Riêng tư" + admin_login: + success: "Gửi mail lỗi" + error: "Lỗi!" + email_input: "Email quản trị" + submit_button: "Gửi email" + performance_report: + initial_topic_title: Báo cáo hiệu suất website + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml index 0fed9c04997..79675ff93b9 100644 --- a/config/locales/server.zh_CN.yml +++ b/config/locales/server.zh_CN.yml @@ -10,18 +10,41 @@ zh_CN: short_date_no_year: "MMMDo" short_date: "ll" long_date: "lll" + datetime_formats: &datetime_formats + formats: + short: "%Y 年 %-m 月 %-d 日" + short_no_year: "%-m 月 %-d 日" + date_only: "%Y 年 %-m 月 %-d 日" + date: + month_names: [null, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月] + <<: *datetime_formats title: "Discourse" topics: "主题列表" posts: "帖子" loading: "载入中" powered_by_html: '采用 Discourse,启用 JavaScript 以获得最佳效果' log_in: "登录" - via: "%{username} 自 %{site_name}" - is_reserved: "保留权利" purge_reason: "自动删除被遗弃、未激活账户" disable_remote_images_download_reason: "磁盘空间不足,远程图像下载已经被禁用。" anonymous: "匿名" - errors: + emails: + incoming: + default_subject: "来自%{email}的邮件" + show_trimmed_content: "显示被截短的内容" + errors: + empty_email_error: "当收到空白邮件时发生" + no_message_id_error: "当邮件头部没有 “Message-Id” 时发生" + auto_generated_email_error: "当邮件头部没有设置 “ precedence” 为:list、junk、bulk 或 auto_reply,或者当头部包含了:auto-submitted、auto-replied 或 auto-generated" + no_body_detected_error: "当无法提取内容或者没有附件时发生。" + inactive_user_error: "当发送者不活跃时发生。" + blocked_user_error: "当发送者被封禁时发生。" + bad_destination_address: "当发至/抄送/密送栏中的所有邮件都不匹配进站邮件地址时发生。" + strangers_not_allowed_error: "当用户尝试在他们不是成员的分类中创建主题时发生。" + insufficient_trust_level_error: "当用户尝试在用户等级不满足分类要求时发帖时发生。" + reply_user_not_matching_error: "当回复来自与通知发送至的邮件地址不同时发生。" + topic_not_found_error: "当回复到已经删除的相关主题时发生。" + topic_closed_error: "当回复到已经关闭的相关主题时发生。" + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "最多只能有 %{max} 个字符;你已经输入了 %{length} 个字符。" @@ -37,8 +60,10 @@ zh_CN: exclusion: 被保留 greater_than: 必须大于 %{count} greater_than_or_equal_to: 必须大于或等于 %{count} + has_already_been_used: "已经被使用" inclusion: 不包括在列表中 invalid: 无效 + is_invalid: "无效;请描述得更详尽些" less_than: 必须小于 %{count} less_than_or_equal_to: 必须小于等于 %{count} not_a_number: 不是数字 @@ -78,6 +103,8 @@ zh_CN: not_found: "请求的 URL 或资源未找到。" invalid_access: "你没有权限查看请求的资源。" read_only_mode_enabled: "这个站点正处于只读模式。交互功能已禁用。" + reading_time: "阅读时间" + likes: "赞" too_many_replies: other: "我们非常抱歉,但是新用户被临时限制为在同一个主题只能回复 %{count} 次" embed: @@ -91,25 +118,20 @@ zh_CN: in_reply_to: "▶ %{username}" replies: other: "%{count} 个回复" + no_mentions_allowed: "抱歉,你无法提到其他用户。" too_many_mentions: - zero: "抱歉,你无法提到其他用户。" - one: "抱歉,你一次仅能提到 1 个用户。" other: "抱歉,你一次仅能提到 %{count} 个用户。" + no_mentions_allowed_newuser: "抱歉,游客无法@用户。" too_many_mentions_newuser: - zero: "抱歉,新用户不能提到其他用户。" - one: "抱歉,新用户仅能提到 1 个用户。" - other: "抱歉,新用户仅能提到 %{count} 个用户。" + other: "抱歉,游客一次仅能@ %{count} 个用户。" + no_images_allowed: "抱歉,游客无法贴图。" too_many_images: - zero: "抱歉,新用户无法贴图。" - one: "抱歉,新用户一次仅能贴 1 张图。" - other: "抱歉,新用户一次仅能贴 %{count} 张图。" + other: "抱歉,游客一次仅能贴 %{count} 张图。" + no_attachments_allowed: "抱歉,新用户无法上传附件。" too_many_attachments: - zero: "抱歉,新用户无法上传附件。" - one: "抱歉,新用户一次仅能上传 1 个附件。" other: "抱歉,新用户一次仅能上传 %{count} 个附件。" + no_links_allowed: "抱歉,游客无法贴链接。" too_many_links: - zero: "抱歉,游客无法贴链接。" - one: "抱歉,游客一次仅能贴 1 条链接。" other: "抱歉,游客一次仅能贴 %{count} 条链接。" spamming_host: "抱歉,你不能添加一个链接到那个地址的链接。" user_is_suspended: "被封禁的用户不允许发贴。" @@ -133,8 +155,15 @@ zh_CN: rss_description: latest: "最新主题" hot: "最热主题" + top: "热门主题" posts: "最新帖子" + private_posts: "最近的私信" + group_posts: "%{group_name}组最近的帖子" + group_mentions: "%{group_name}组最近的提及" + user_posts: "最新贴子由@%{username}发表" + user_topics: "最新主题由@%{username}发表" too_late_to_edit: "这个主题在很早之前创建。不能被编辑或者被删除。" + revert_version_same: "目前的版本和你想要回退至的版本一样。" excerpt_image: "图片" queue: delete_reason: "通过帖子审核队列删除" @@ -142,11 +171,15 @@ zh_CN: errors: can_not_modify_automatic: "你不能修改一个自动组" member_already_exist: "“%{username}”已经是群组成员了。" + invalid_domain: "'%{domain}'不是一个有效域名。" + invalid_incoming_email: "'%{email}' 不是一个有效邮箱地址。" + email_already_used_in_group: "'%{email}' 已经被群组'%{group_name}'使用了。" + email_already_used_in_category: "'%{email}' 已经被分类'%{category_name}'使用了。" default_names: everyone: "任何人" admins: "管理面板" moderators: "版主" - staff: "员工" + staff: "管理人员" trust_level_0: "trust_level_0" trust_level_1: "trust_level_1" trust_level_2: "trust_level_2" @@ -218,9 +251,6 @@ zh_CN: user_profile: bio_raw: "关于我" errors: - messages: - is_invalid: "无效;试试写的更明确一些吧" - has_already_been_used: "已经被使用" models: topic: attributes: @@ -241,6 +271,7 @@ zh_CN: attributes: hex: invalid: "不是有效颜色值" + <<: *errors user_profile: no_info_me: "
    你的资料中,关于我部分目前还是空白,你想要写些什么吗?
    " no_info_other: "
    %{name} 尚未在他们的资料中的关于我部分填写任何信息
    " @@ -248,9 +279,9 @@ zh_CN: vip_category_description: "高于信任等级3的用户参与讨论的分类。" meta_category_name: "页面反馈" meta_category_description: "讨论该站点的站务、组织、如何运作和如何改善它。" - staff_category_name: "职员" - staff_category_description: "职员私有的分类。只有管理员和版主才能阅览主题。" - assets_topic_body: "这是一个永久主题,仅对职员可见,用于存储论坛设计使用的图像和文件。不要删除它!\n\n\n详细教程:\n\n\n1. 回复到这个主题。\n2. 上传你想用作站点标志、图标和其他所有图片到这儿。(使用帖子编辑器工具栏中的上传图标,或者拖拽或者粘贴图像。)\n3. 提交你的回复添加帖子。\n4. 在你的新帖子里右键点击图片获得这些已上传图片的链接,或者点击编辑按钮来编辑帖子,获得到图片的相对地址。复制这些相对地址。\n5. 粘贴这些图像的路径到[基础设置](/admin/site_settings/category/required)。\n\n\n如果你需要运行额外的上传文件类型,在[文件设置](/admin/site_settings/category/files)中编辑 `authorized_extensions`。" + staff_category_name: "管理人员" + staff_category_description: "管理人员私有的分类。只有管理员和版主才能阅览主题。" + assets_topic_body: "这是一个永久主题,仅对管理人员可见,用于存储论坛设计使用的图像和文件。不要删除它!\n\n\n详细教程:\n\n\n1. 回复到这个主题。\n2. 上传你想用作站点标志、图标和其他所有图片到这儿。(使用帖子编辑器工具栏中的上传图标,或者拖拽或者粘贴图像。)\n3. 提交你的回复添加帖子。\n4. 在你的新帖子里右键点击图片获得这些已上传图片的链接,或者点击编辑按钮来编辑帖子,获得到图片的相对地址。复制这些相对地址。\n5. 粘贴这些图像的路径到[基础设置](/admin/site_settings/category/required)。\n\n\n如果你需要运行额外的上传文件类型,在[文件设置](/admin/site_settings/category/files)中编辑 `authorized_extensions`。" lounge_welcome: title: "欢迎来到贵宾室" body: |2 @@ -276,34 +307,51 @@ zh_CN: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "关于分类:%{category}" - replace_paragraph: "[用一段简短的话描述分类,并替换这第一段的内容。这段文字将出现在分类选择区域,所以尽量不要超过200个字符。当你编辑了这段文字或者再次分类创建了一个主题后,分类才会出现在分类列表中。]" - post_template: "%{replace_paragraph}\n\n在接下来的一段文字中输入分类的详细描述信息,可以在这里包含在此分类下讨论的规则、内容导向等等。\n\n考虑这些事情:\n\n- 这个分类用来做什么? 为什么人们选择这个分类寻找主题?\n\n- 这个分类和其他已有分类有什么不同?\n\n- 我们需要这个分类么?\n\n- 我们应该和已有分类合并吗?还是分离成更多的分类?\n" + replace_paragraph: "(将第一段话修改成你的新分类的简述。这段文字将出现在用户选择分类的地方,所以尝试保持在 200 个字符内。 **除非你编辑了这段文字或者在这分类中创建了主题,这个分类不会出现在分类页面中。**)" + post_template: "%{replace_paragraph}\n\n在接下来的这段话中多写一些分类的用途,或者设定一个该分类的规则:\n\n- 为什么我们要用这个分类?它用来做什么?\n\n- 这个分类和我们已经有的分类究竟有什么不同?\n\n- 这个分类中一般会包含哪些主题?\n\n- 我们需要这个分类么?我们可以把它和别的分类、或者子分类合并吗?\n\n" errors: uncategorized_parent: "未分类不能有一个父分类" self_parent: "一个子分类不能属于它自己。" depth: "你不能在一个子分类下再包含一个子分类。" - email_in_already_exist: "入站邮件地址 “%{email_in}” 已经被用于 “%{category_name}” 分类了。" + invalid_email_in: "'%{email}'不是一个有效邮箱地址。" + email_already_used_in_group: "'%{email}' 已经被群组'%{group_name}'使用了。" + email_already_used_in_category: "'%{email}' 已经被分类'%{category_name}'使用了。" cannot_delete: uncategorized: "不能删除未分类。" has_subcategories: "不能删除该分类,因为它有子分类" topic_exists: other: "不能删除该分类,因为它有 %{count} 个主题。最老的主题是 %{topic_link}。" topic_exists_no_oldest: "不能删除该分类,因为主题数量为 %{count}。" + uncategorized_description: "不需要分类或者不适合放在现在的任何分类中的主题。" trust_levels: newuser: title: "新用户" basic: title: "初级用户" - regular: + member: title: "成员" + regular: + title: "活跃用户" leader: - title: "常规" - elder: - title: "领导" + title: "资深" change_failed_explanation: "你尝试将 %{user_name} 降至 '%{new_trust_level}'。然而他们的信任等级已经是 '%{current_trust_level}'。%{user_name} 将仍是 '%{current_trust_level}' —— 如果你想要降级用户,先锁定信任等级" rate_limiter: - slow_down: "你已经重复这一操作太多次了,请一会再重试" + slow_down: "你执行这个操作太多次了,请稍后再试。" too_many_requests: "你的请求过于频繁,请等待 %{time_left} 之后再试。" + by_type: + first_day_replies_per_day: "你回帖的数量已经超出身为新用户当天允许的上限,请等待%{time_left}之后再试。" + first_day_topics_per_day: "你创建新主题的数量已经超出身为新用户当天允许的上限,请等待%{time_left}之后再试。" + create_topic: "你创建新主题太快了,请等待%{time_left}之后再试。" + create_post: "你回帖太快了,请等待%{time_left}之后再试。" + delete_post: "你正在快速地删除帖子。请等 %{time_left}之后再试。" + topics_per_day: "你今天新主题的数量已经到达上限,请等待%{time_left}之后再试。" + pms_per_day: "你今天的消息数量已经到达上限,请等待%{time_left}之后再试。" + create_like: "你今天的“赞”数量已经到达上限,请等待%{time_left}之后再试。" + create_bookmark: "你今天的收藏已经到达上限,请等待%{time_left}之后再试。" + edit_post: "你今天编辑帖子的数量已经到达上限,请等待%{time_left}之后再试。" + live_post_counts: "你请求新帖子的速度太快了,请等待 %{time_left}之后再试。" + unsubscribe_via_email: "你已经达到了今日用邮件接触订阅的最大数量限制。请等 %{time_left}之后再试。" + topic_invitations_per_day: "你已经达到了今日主题邀请的最大数量限制。请等 %{time_left}之后再试。" hours: other: "%{count} 小时" minutes: @@ -373,6 +421,11 @@ zh_CN: confirmed: "你的电子邮箱已被更新。" please_continue: "转入到 %{site_name}" error: "在修改你的电子邮箱地址时出现了错误,可能此邮箱已经在论坛中使用了?" + error_staged: "在修改你的电子邮箱地址时出现了错误。这个邮箱已经被一个暂存用户占用了。" + already_done: "抱歉,此激活链接已经失效。可能你已经修改了邮箱?" + authorizing_old: + title: "感谢你确认你目前的邮箱地址" + description: "我们正向你的新地址发送确认邮件。" activation: action: "点击这儿激活你的账户" already_done: "抱歉,此帐号激活链接已经失效。可能你的帐号已经被激活了?" @@ -397,16 +450,16 @@ zh_CN: description: '此帖内容包含对他人的攻击、侮辱、仇视语言或违反了我们的社群准则。' long_form: '标记为不当内容' notify_user: - title: '消息 @{{username}}' - description: '此帖包含一些我想与该用户私下直接交流的内容。不能执行标记操作。' + title: '给@{{username}}发送一条消息' + description: '我想与此人私下交流他们的帖子。' long_form: '以发送消息给用户' email_title: '你在“%{title}”中的帖子' email_body: "%{link}\n\n%{message}" notify_moderators: title: "其他事项" - description: '此帖需要版主按照以上未列出的原因做出处理。' + description: '这个帖子需要版主的注意,原因没有列在上方。' long_form: '标记为需版主注意' - email_title: '"%{title}" 主题需要你的关注' + email_title: '"%{title}" 主题需要版主的注意' email_body: "%{link}\n\n%{message}" bookmark: title: '书签' @@ -431,7 +484,7 @@ zh_CN: long_form: '标记为不当内容' notify_moderators: title: "其他内容" - description: '该主题需要版主依据社群准则服务条款(TOS)或其它未列出的原因来给予关注。' + description: '此帖需要版主依据社群准则服务条款(TOS)或其它未列出的原因来给予关注。' long_form: '标记为需版主注意' email_title: '"%{title}" 主题需要你的关注' email_body: "%{link}\n\n%{message}" @@ -449,7 +502,7 @@ zh_CN: unsubscribed: title: '取消订阅' description: "你已经取消订阅,我们不会再发送邮件给你!" - oops: "如果你并非想要取消订阅,请点击下面。" + oops: "如果你并不想取消订阅,请点击下方的按钮。" error: "取消订阅时出错" preferences_link: "你也可以在你的参数设置页面取消订阅摘要邮件" different_user_description: "你现在正以另一个用户的身份登录,而非摘要邮件寄给的用户。请登出并再试一次。" @@ -467,6 +520,10 @@ zh_CN: title: "新用户" xaxis: "天" yaxis: "新用户数" + profile_views: + title: "查看用户资料" + xaxis: "天" + yaxis: "已看的用户资料数量" topics: title: "新发表主题" xaxis: "天" @@ -616,44 +673,17 @@ zh_CN: title_nag: "为站点指定一个名字。在站点设置中更新标题。" site_description_missing: "输入一句话作为你站点的简介,将出现在搜索结果中。在站点设置中更新 site_description。" consumer_email_warning: "你的站点被设置为使用 Gmail 或者其他客户邮箱服务发送邮件。Gmail 限制每日邮件发送数量。请考虑使用其他邮件服务商来保证邮件的成功发送,例如 mandrill.com。" - site_contact_username_warning: "输入一个友善的职员账户名,并以他的名义发送重要的自动消息。在站点设置中更新 site_contact_username。" + site_contact_username_warning: "输入一个友善的管理人员账户名,并以他的名义发送重要的自动消息。在站点设置中更新 site_contact_username。" notification_email_warning: "通知邮件不是从你域名的一个有效地址发出的;邮件分发将会变得危险和不可靠。请在站点设置中将 notification_email 设置为一个有效的本地邮件地址。" - content_types: - education_new_reply: - title: "新用户培训:第一个回复" - description: "在新用户发表前两个回复时,自动在编辑器上方弹出的帮助信息。" - education_new_topic: - title: "新用户培训:第一个主题" - description: "在新用户发表前两个主题时,自动在编辑器上方弹出的帮助信息。" - usage_tips: - title: "新用户指引" - description: "新用户指引和重要信息" - welcome_user: - title: "欢迎:新用户" - description: "当新用户注册后自动发送给他们的欢迎消息。" - welcome_invite: - title: "欢迎:受邀用户" - description: "当新用户通过接受用户邀请加入论坛后,自动发送给他们的欢迎消息。" - login_required_welcome_message: - title: "登录要求:欢迎信息" - description: "欢迎信息只有 'login required' 设置项被启用后才会向登出的用户显示。" - login_required: - title: "登录要求:首页" - description: "当要求登录时向未授权用户显示的文字。" - head: - title: "HTML 头部" - description: "将在 标签中插入的 HTML。" - top: - title: "页面顶部" - description: "将在每一个页面顶端(在头部之后,在导航或者主题标题前)插入的 HTML。" - bottom: - title: "页面底部" - description: "将在 标签前被插入的 HTML。" + subfolder_ends_in_slash: "你的子目录设置不正确;DISCOURSE_RELATIVE_URL_ROOT以斜杠结尾。" + email_polling_errored_recently: + other: "邮件轮询在过去的 24 小时内发生了 %{count} 个错误。看一看日志寻找详情。" site_settings: censored_words: "将被自动替换为 ■■■■" delete_old_hidden_posts: "自动删除被隐藏超过 30 天的帖子。" default_locale: "此论坛的缺省语言(ISO 639-1 代码)" allow_user_locale: "允许用户选择他们自己的语言界面" + set_locale_from_accept_language_header: "为未登录用户按照他们的浏览器发送的请求头部设置界面语言。(实验性,无法和匿名缓存共同使用)" min_post_length: "帖子允许的最少字符数" min_first_post_length: "第一帖(主题内容)允许的最少字符数" min_private_message_post_length: "消息允许的最小字符数" @@ -662,8 +692,8 @@ zh_CN: max_topic_title_length: "标题允许的最大字符数" min_private_message_title_length: "消息标题允许的最小字符数" min_search_term_length: "搜索条件允许的最少字符数" + search_tokenize_chinese_japanese_korean: "在非中/日/韩语站点强制切割中/日/韩语搜索分词" allow_uncategorized_topics: "允许发表没有分类的帖子。警告:如果又任何未分类的帖子,你必须给他们重新分类后才能关闭该选项。" - uncategorized_description: "未分类分类的描述。留空则无描述。" allow_duplicate_topic_titles: "允许主题有相同,重复的标题" unique_posts_mins: "多少分钟之后才允许一个用户再次发表包含相同内容的帖子" educate_until_posts: "当用户开始键入他们的前几个(n)新帖子时,在编辑器上显示教育面板弹窗。" @@ -676,9 +706,9 @@ zh_CN: download_remote_images_to_local: "下载一份主题中链接的外部图片到本地;以防图片损坏。" download_remote_images_threshold: "本地最小可用下载外部图片到本地的空间(百分比)" disabled_image_download_domains: "域名列表,链接到这些站点的图片不会被下载。用 | 分割。" - ninja_edit_window: "在多少秒钟(n)之内,对帖子的编辑不生成帖子历史" + editing_grace_period: "在 (n) 秒之内,对帖子的编辑不生成帖子历史。" post_edit_time_limit: "作者可以在发布帖子后的(n)分钟内编辑或删除他们的帖子。设置 0 为永远。" - edit_history_visible_to_public: "允许任何人查看编辑过的帖子的老版本。当禁用时,只有职员才能查看浏览。" + edit_history_visible_to_public: "允许任何人查看编辑过的帖子的老版本。当禁用时,只有管理人员才能查看浏览。" delete_removed_posts_after: "帖子被作者删除,将在(n)小时后被自动删除。" max_image_width: "帖子中图片允许的最大缩略图宽度" max_image_height: "帖子中图片允许的最大缩略图宽度" @@ -706,7 +736,7 @@ zh_CN: summary_likes_required: "在一个主题启用'摘要模式'的最小赞的数量" summary_percent_filter: "当用户点击摘要,显示前 % 几的帖子" summary_max_results: "“概括主题”返回的最大帖子数量" - enable_private_messages: "允许信任等级1的用户创建消息或者以消息回复" + enable_private_messages: "允许信任等级1(允许发信的最低等级)的用户创建消息和回复消息" enable_long_polling: "启用 Message bus 使通知功能可以使用长轮询(long polling)" long_polling_base_url: "长轮询的基本 URL(当用 CDN 分发动态能让时,请设置此至原始拉取地址)例如:http://origin.site.com" long_polling_interval: "当没有数据向客户端发送时服务器端应等待的时间(仅对已登录用户有效)" @@ -719,15 +749,16 @@ zh_CN: max_replies_in_first_day: "新用户在第一天内最大可以创建的回复数" tl2_additional_likes_per_day_multiplier: "增加信任等级 2(成员)的赞限制,可提供一个乘数与原始值相乘" tl3_additional_likes_per_day_multiplier: "增加信任等级 3(常规)的赞限制,可提供一个乘数与原始值相乘" - tl4_additional_likes_per_day_multiplier: "增加信任等级 4(领导)的赞限制,可提供一个乘数与原始值相乘" + tl4_additional_likes_per_day_multiplier: "增加信任等级 4(资深)的赞限制,可提供一个乘数与原始值相乘" num_flags_to_block_new_user: "如果一个新用户的帖子被其他 num_users_to_block_new_user 个用户标记为垃圾,隐藏他们的所有帖子并阻止其之后的发帖。0 表示禁用这个特性。" num_users_to_block_new_user: "如果一个新用户的帖子被许多其他用户 num_flags_to_block_new_user 标记为垃圾,隐藏他们的所有帖子并阻止其之后发帖。0 表示禁用这个特性。" notify_mods_when_user_blocked: "如果一个用户被自动封禁了,发送一个消息给所有管理员。" flag_sockpuppets: "如果一个新用户开始了一个主题,并且同时另一个新用户以同一个 IP 在该主题回复,他们所有的帖子都将被自动标记为垃圾。" traditional_markdown_linebreaks: "在 Markdown 中使用传统换行符,即用两个尾随空格来换行" - allow_html_tables: "允许在输入 Markdown 时输入表格 HTML 标签,TABLE、THEAD、TD、TR、TH 将被白名单(需要对所有包含表格的老帖子做彻底的 rebake)" + allow_html_tables: "允许在输入 Markdown 文本时使用表格 HTML 标签。标签 TABLE、THEAD、TD、TR、TH 将被允许使用,即白名单这些标签(需要重置所有包含表格的老帖子的 HTML)" post_undo_action_window_mins: "允许用户在帖子上进行撤销操作(赞、标记等)所需等待的间隔分钟数" - must_approve_users: "新用户在被允许访问站点前需要由职员批准。警告:在运行的站点中启用将解除所有非职员用户的访问权限!" + must_approve_users: "新用户在被允许访问站点前需要由管理人员批准。警告:在运行的站点中启用将解除所有非管理人员用户的访问权限!" + pending_users_reminder_delay: "如果新用户等待批准时间超过此小时设置则通知版主。设置-1关闭通知。" ga_tracking_code: "Google 分析追踪代码(ga.js),例如:UA-12345678-9。参考 http://google.com/analytics" ga_domain_name: "Google 分析域名(ga.js),例如:mysite.com;参考 http://google.com/analytics" ga_universal_tracking_code: "Google 通用分析追踪代码(analytics.js)追踪代码,例如:UA-12345678-9;参考 http://google.com/analytics" @@ -736,6 +767,7 @@ zh_CN: enable_noscript_support: "通过 no script 标签启用对标准爬虫的支持。" allow_moderators_to_create_categories: "允许版主创建新的分类" cors_origins: "允许跨源请求(CORS)。每个源必须包括 http:// 或 https://。DISCOURSE_ENABLE_CORS 环境变量必须设置为 true 才能启用 CORS 政策。" + use_admin_ip_whitelist: "当目前的IP刚好处于IP段禁止名单(Admin > Logs > Screened Ips)中的时候,只有管理员才可登入。" top_menu: "确定在主页导航条包含哪些条目,以及排列顺序。例如:latest|new|unread|categories|top|read|posted|bookmarks" post_menu: "确定在帖子菜单条包含哪些条目,以及排列顺序。例如:like|edit|flag|delete|share|bookmark|reply" post_menu_hidden_items: "帖子菜单中默认隐藏的按钮,点击省略号后显示。" @@ -747,15 +779,15 @@ zh_CN: suppress_reply_directly_above: "当一个帖子只有一个回复时,不显示回复到该贴的回复。" suppress_reply_when_quoting: "当帖子引用回复时,不显示可展开的回复到某贴的标记。" max_reply_history: "扩展回复至时显示的最大回复数量" - experimental_reply_expansion: "当展开回复至内容时隐藏直接回复(实验性)" topics_per_period_in_top_summary: "在一个主题底部显示的默认推荐主题的数量。" topics_per_period_in_top_page: "在展开“显示更多”推荐主题列表显示的主题数量。" redirect_users_to_top_page: "自动重定向至新用户或者长时间未登入的用户至热门页面。" - show_email_on_profile: "在用户页面显示用户的邮件地址(只有用户和职员可见)" + top_page_default_timeframe: "顶部查看页面的默认时间表" + show_email_on_profile: "在用户页面显示用户的邮件地址(只有用户和管理人员可见)" email_token_valid_hours: "“忘记密码”/“激活账户” token 有效的小时数(n)。" email_token_grace_period_hours: "“忘记密码”/“激活账户” token 在使用后仍旧有效的小时数(n)。" enable_badges: "启用徽章系统" - enable_whispers: "允许用户发送密语给职员" + enable_whispers: "允许在主题中给管理人员密频。(experimental)" allow_index_in_robots_txt: "在 robots.txt 中详细指出这个站点允许被网页搜索引擎检索。" email_domains_blacklist: "用管道符“|”分隔的邮箱域名黑名单列表,其中的域名将不能用来注册账户,例如:mailinator.com|trashmail.net" email_domains_whitelist: "用管道符“|”分隔的电子邮箱域名的列表,用户必须使用这些邮箱域名注册。警告:用户使用不包含在这个列表里的邮箱域名,将无法成功注册。" @@ -767,12 +799,13 @@ zh_CN: force_hostname: "仅限开发者设定!警告!指定 URL 里的主机名。留空为默认" invite_expiry_days: "多少天以内用户的邀请码是有效的" invite_passthrough_hours: "用户多久才能使用一个已经使用过的邀请代码,以小时计" - invite_only: "公开注册已禁用,新用户必须被其他成员或职员邀请。" + invite_only: "公开注册已禁用,新用户必须被其他成员或管理人员邀请。" login_required: "需要验证才能继续在该站阅读,不允许匿名访问。" min_username_length: "最小用户名长度。" max_username_length: "最大用户名长度。" reserved_usernames: "注册时不可使用的用户名。" min_password_length: "最小密码长度。" + min_admin_password_length: "管理员最短密码长度" block_common_passwords: "不允许使用 10,000 个最常用的密码。" enable_sso: "启用通过外部站点单点登录(警告:用户的邮件地址必须被外部站点验证!)" enable_sso_provider: "在 /session/sso_provider endpoint 实现 Discourse SSO 提供方协议,要求设置 sso_secret" @@ -793,9 +826,12 @@ zh_CN: enable_twitter_logins: "启用 Twitter 帐号验证登录,需要 twitter_consumer_key 和 twitter_consumer_secret" twitter_consumer_key: "Twitter 帐号验证的客户密匙(Consumer key),到 http://dev.twitter.com 来注册获取" twitter_consumer_secret: "Twitter 帐号验证的客户密码(Consumer secret),到 http://dev.twitter.com 来注册获取" + enable_instagram_logins: "启用 Instagram 验证,需要 instagram_consumer_key 和 instagram_consumer_secret" + instagram_consumer_key: "Instagram 验证的 Consumer key" + instagram_consumer_secret: "Instagram 验证的 Consumer secret" enable_facebook_logins: "启用 Facebook 帐号验证登录,需要 facebook_app_id 和 facebook_app_secret" facebook_app_id: "Facebook 帐号验证的应用帐号(App id),到 https://developers.facebook.com/apps 来注册获取" - facebook_app_secret: "脸书帐号验证的应用密码(App secret),到 https://developers.facebook.com/apps 来注册获取" + facebook_app_secret: "Facebook 帐号验证的应用密码(App secret),到 https://developers.facebook.com/apps 来注册获取" enable_github_logins: "启用 Github 帐号验证登录,需要 github_client_id 和 github_client_secret" github_client_id: "Github 帐号验证的客户端帐号(Client id),到 https://github.com/settings/applications 来注册获取" github_client_secret: "Github 帐号验证的客户端密码(Client secret),到 https://github.com/settings/applications 来注册获取" @@ -805,9 +841,15 @@ zh_CN: backup_frequency: "自动创建站点备份的频率,以天为单位。" enable_s3_backups: "当完成备份后上传备份到 S3。重要:需要在文件设置中填写有效的 S3 验证资料。" s3_backup_bucket: "远端备份 bucket。警告:确认它使私有的 bucket。" + s3_disable_cleanup: "当在本地删除备份时不删除 S3 上的备份。" + backup_time_of_day: "备份发送时的UTC时间" + backup_with_uploads: "在备份日程中包括上传。关闭此项仅备份数据库。" active_user_rate_limit_secs: "更新'最后一次见到'数据的间隔,单位为秒" verbose_localization: "在界面上显示详细的本地化提示" previous_visit_timeout_hours: "系统判断一次访问之后多少小时后为'上一次'访问" + top_topics_formula_log_views_multiplier: "热门主题公式中访问次数因子的值(n):`log(views_count) * (n) + op_likes_count * 0.5 + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_first_post_likes_multiplier: "热门主题公式中首贴赞的数量的因子的值(n):`log(views_count) * 2 + op_likes_count * (n) + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" + top_topics_formula_least_likes_per_post_multiplier: "热门主题公式中赞和帖子数量的比例的最小值(n):`log(views_count) * (n) + op_likes_count * 0.5 + LEAST(likes_count / posts_count, 3) + 10 + log(posts_count)`" rate_limit_create_topic: "在创建一个主题之后,用户必须间隔多少秒(n)才能创建另一个主题" rate_limit_create_post: "在创建一个帖子之后,用户必须间隔多少秒(n)才能创建另一个帖子" rate_limit_new_user_create_topic: "在创建一个主题后,新用户必须等待(n)秒才能创建另一个主题。" @@ -820,6 +862,8 @@ zh_CN: max_private_messages_per_day: "每个用户每天能发消息数量的最大值。" max_invites_per_day: "每个用户每天能创建的邀请数量的最大值。" max_topic_invitations_per_day: "每个用户每天能创建的邀请至主题数量的最大值。" + alert_admins_if_errors_per_minute: "激活管理员警告的每分钟错误的数量。0 会禁用这个特性。注意:需要重启。" + alert_admins_if_errors_per_hour: "激活管理员警告的每小时错误的数量。0 会禁用这个特性。注意:需要重启。" suggested_topics: "在一个主题底部显示的推荐主题的数量。" limit_suggested_to_category: "只在当前分类的推荐帖子列表中显示帖子。" clean_up_uploads: "移除孤立的已上传资料。警告:你可能想要在启用这个设定前备份一下 /uploads 目录。" @@ -836,6 +880,8 @@ zh_CN: avatar_sizes: "自动生成的头像大小列表。" external_system_avatars_enabled: "使用外部系统头像服务。" external_system_avatars_url: "外部系统头像服务的 URL 地址。可选参数是 {username} {first_letter} {color} {size}" + default_opengraph_image_url: "opengraph图像的缺省URL。" + allow_all_attachments_for_group_messages: "允许群组消息中包含任何邮件附近。" enable_flash_video_onebox: "在 Onebox 启用嵌入 swf 和 flv 链接(Adobe Flash)。警告:可能增加安全风险。" default_invitee_trust_level: "受邀用户的缺省信任等级(0-4)。" default_trust_level: "所有新用户的缺省信任等级(0-4)。警告!改变此项将提高广告泛滥的风险。" @@ -849,32 +895,38 @@ zh_CN: tl2_requires_likes_received: "一个初级用户升级到信任等级2所需要获得的赞数。" tl2_requires_likes_given: "一个初级用户升级到信任等级2所需要给出的赞数。" tl2_requires_topic_reply_count: "一个初级用户升级到信任等级2所需要回复的主题数量。" - tl3_requires_days_visited: "在最近 100 天内升至信任等级3所需的访问站点的天数。(0到100)" - tl3_requires_topics_replied_to: "在最近 100 天内升至信任等级3所需的回复主题的最小数量。(0或更高)" - tl3_requires_topics_viewed: "在最近 100 天内升至信任等级3所需的创建主题的百分比。(0到100)" - tl3_requires_posts_read: "在最近 100 天内升信任等级3所需的创建帖子的百分比。(0到100)" - tl3_requires_topics_viewed_all_time: "用户升至领导信任等级3所需查看的最小主题数量。" - tl3_requires_posts_read_all_time: "用户升至领导信任等级3所需查看的最小帖子数量。" - tl3_requires_max_flagged: "用户在最近 100 天内升至信任等级3所需的必须没有超过 x 个帖子被 x 个不同的用户标记数量,x为数量。(0或更高)" + tl3_time_period: "信任等级 3 考察期限(天数)" + tl3_requires_days_visited: "要升到信任等级 3 所需要的,在最近考察时间段内访问的最低天数。将其设置为高于信任等级 3 的考察时间可禁用信任等级 3。(设置为 0 或比考察期更长)" + tl3_requires_topics_replied_to: "要升到信任等级 3 所需要的,在最近考察时间段内回复的主题数量。(设置为 0 或更高)" + tl3_requires_topics_viewed: "要升到信任等级 3 所需要的,在最近考察时间段内所查看的新主题的百分比。将其设置为高于信任等级 3 的考察时间可禁用信任等级 3。(设置为 0 到 100)" + tl3_requires_posts_read: "要升到信任等级 3 所需要的,在最近考察时间段内所查看的新主题的百分比。将其设置为高于信任等级 3 的考察时间可禁用信任等级 3。(设置为 0 或比考察期更长)" + tl3_requires_topics_viewed_all_time: "用户升至信任等级 3 所需查看的最小主题数量。" + tl3_requires_posts_read_all_time: "用户升至信任等级 3 所需查看的最小帖子数量。" + tl3_requires_max_flagged: "要升到信任等级 3 所需要的,在最近考察时间段内,用户不得被 x 个不同用户标记 x 篇帖子的 x 值。(设置为 0 或更高)" tl3_promotion_min_duration: "信任等级3的用户可被降级至信任等级2前最小持续天数。" - tl3_requires_likes_given: "在最近 100 天内升至信任等级3所需给出的赞。" - tl3_requires_likes_received: "在最近 100 天内升至信任等级3所需收到的赞。" + tl3_requires_likes_given: "要升到信任等级 3 所需要的,在最近考察时间段内用户必须要给出的赞(设置为 0 或更高)" + tl3_requires_likes_received: "要升到信任等级 3 所需要的,在最近考察时间段内用户必须要收到的赞(设置为 0 或更高)" tl3_links_no_follow: "不移除信任等级3用户帖子中的链接中的 rel=nofollow 属性。" min_trust_to_create_topic: "创建主题所需的最低信任等级。" min_trust_to_edit_wiki_post: "能编辑维基模式帖子的最小信任等级" + min_trust_to_allow_self_wiki: "用户将自己的帖子设置为维基模式的最低信任等级。" + min_trust_to_send_messages: "发送消息所需的最低信任等级。" newuser_max_links: "一个访问者可以添加到一个帖子里的链接数量。" newuser_max_images: "一个访问者可以加入到一个帖子里的图片数量。" newuser_max_attachments: "一个新用户可以添加到一个帖子里的附件数量。" newuser_max_mentions_per_post: "一个访问者可以在一个帖子里使用 @name 提及的最大数量。" newuser_max_replies_per_topic: "直至有人回复他们前,新用户在一个帖子里的最大回复数量。" max_mentions_per_post: "你可以在一个帖子里使用 @name 提及的最大数量。" + max_users_notified_per_group_mention: "当整个群组被提及,用户可能收到的最多提醒数量(超过阈值后将不会有更多新提醒)" create_thumbnails: "为太大而无法恰当地显示在帖子里的图片创建 lightbox 缩略图。" email_time_window_mins: "等待多少(n)分钟才给用户发送通知电子邮件,好让他们有机会自己来编辑和完善他们的帖子。" + private_email_time_window_seconds: "等待多少(n)秒再给用户发送通知电子邮件,这可以让用户有时间来编辑和完善他们的消息。" email_posts_context: "在通知邮件中包含的作为上下文的回复数量。" flush_timings_secs: "向服务器刷新时间数据的频率,以秒为单位。" title_max_word_length: "在主题的标题中,允许的词语长度的最大字符数。" title_min_entropy: "在主题的标题中,允许的最低熵值(单个字符)。" body_min_entropy: "在一个帖子内文中,允许的最低熵值(单个字符)。" + allow_uppercase_posts: "允许标题和内容全大写" title_fancy_entities: "转换主题标题中的 HTML 实体,参考:SmartyPants http://daringfireball.net/projects/smartypants/" min_title_similar_length: "开始检查相似主题的帖子标题的最小长度。" min_body_similar_length: "开始检查相似主题的帖子内容的最小长度。" @@ -902,10 +954,11 @@ zh_CN: privacy_policy_url: "如果你的隐私政策文档在外部,那么请在此填写其完整 URL 地址。" newuser_spam_host_threshold: "用户在一篇帖子中能添加多少此指向同一主机的链接,取决于之前该用户有`newuser_spam_host_threshold`篇帖子被认为是垃圾帖。" white_listed_spam_host_domains: "广告主机白名单域名列表。新用户可以任意链接至这些域名。" - staff_like_weight: "职员赞时的额外权重。" + staff_like_weight: "管理人员赞时的额外权重。" topic_view_duration_hours: "按照每 IP/用户每 N 小时来记录一次新的主题访问" + user_profile_view_duration_hours: "按照每 IP/用户每 N 小时来记录用户资料访问数" levenshtein_distance_spammer_emails: "当匹配广告邮件时,模糊匹配判断差异的字符数。" - max_new_accounts_per_registration_ip: "如果已经有了从这个 IP 创建的(n)个信任等级0的账户(并且没有一个是职员或者是信任等级2以上的用户),不再允许来自该 IP 地址的注册请求。" + max_new_accounts_per_registration_ip: "如果已经有了从这个 IP 创建的(n)个信任等级0的账户(并且没有一个是管理人员或者是信任等级2以上的用户),不再允许来自该 IP 地址的注册请求。" min_ban_entries_for_roll_up: "当点击折叠按钮时,且至少 (N) 条记录时,将会创建一个子网封禁记录" max_age_unmatched_emails: "在 (N) 天后删除不匹配的邮件地址。" max_age_unmatched_ips: "在 (N) 天后删除不匹配的 IP 记录。" @@ -921,6 +974,13 @@ zh_CN: disable_emails: "禁止 Discourse 发送任何邮件" strip_images_from_short_emails: "从邮件中除去小于 2800 比特的图片" short_email_length: "短邮件地址长度(以比特作为单位)" + display_name_on_email_from: "在Email栏显示全名" + unsubscribe_via_email: "允许用户在发送的邮件的主题或正文中包含“unsubscribe”(未知中文版用什么)来退订邮件" + unsubscribe_via_email_footer: "在发出的邮件底部包含退订链接" + delete_email_logs_after_days: "在(N)天后删除邮件日志。设置为 0 无限期保留" + max_emails_per_day_per_user: "每日发送给用户的最大帖子数量。设置为 0 禁止限制" + enable_staged_users: "处理进站邮件时自动创建暂存用户。" + manual_polling_enabled: "用 API 推送邮件回复。" pop3_polling_enabled: "轮询 POP3 收取邮件回复。" pop3_polling_ssl: "连接至 POP3 服务器时使用 SSL。(推荐)" pop3_polling_period_mins: "查询用于邮件的 POP3 账户的间隔(以分钟计)。注意:需要重新启动。" @@ -947,25 +1007,30 @@ zh_CN: automatically_download_gravatars: "为注册或更改邮箱的用户下载 Gravatar 头像。" digest_topics: "邮件摘要中显示的最大主题数目。" digest_min_excerpt_length: "在邮件摘要中每个帖子最少显示的字符数量。" - suppress_digest_email_after_days: "不发送摘要邮件给超过 (n) 天未出现的用户。" + delete_digest_email_after_days: "不发送摘要邮件给超过(n)天没访问的用户" + digest_suppress_categories: "不在摘要邮件中显示关注这个分类的任何内容。" disable_digest_emails: "为所有用户禁用摘要邮件。" detect_custom_avatars: "检测用户是否上传了自定义个人头像。" max_daily_gravatar_crawls: "一天内 Discourse 将自动检查 gravatar 自定义头像的次数" public_user_custom_fields: "可公开显示的用户自定义属性白名单" - staff_user_custom_fields: "可给职员公开显示的用户自定义属性白名单。" + staff_user_custom_fields: "可给管理人员公开显示的用户自定义属性白名单。" enable_user_directory: "提供可供浏览的用户目录" allow_anonymous_posting: "允许用户切换至匿名模式" anonymous_posting_min_trust_level: "启用匿名发帖所需的最小信任等级" anonymous_account_duration_minutes: "为了匿名性,为每个用户每 N 分钟创建一个匿名账户。例如:如果设置为 600,只要发帖后 600 分钟到了,并且用户切换至了匿名模式,就会创建一个新的匿名账户。" + hide_user_profiles_from_public: "对来访用户关闭关闭用户信息卡,用户资料和用户目录。" allow_profile_backgrounds: "允许用户上传个人资料背景图片。" - sequential_replies_threshold: "用户可以在一个主题内多次回复而不被提醒连续发送多个回复的通知。" + sequential_replies_threshold: "在被提醒回复了太多连续的回复前,用户在主题中可以连续回复的帖子的数量。" enable_mobile_theme: "为移动设备启用移动友好的主题,但也能切换回完整站点。如果你想要使用自定义的响应式主题请禁用它。" dominating_topic_minimum_percent: "用户在主题中的帖子占到多少百分比时使得用户主导话题。" - daily_performance_report: "每日分析 NGINX 日志并且发布详情主题到职员才能看到的主题" + disable_avatar_education_message: "禁用更改头像操作的教育消息。" + daily_performance_report: "每日分析 NGINX 日志并且发布详情主题到管理人员才能看到的主题" suppress_uncategorized_badge: "不要为主题列表中的未分类主题显示徽章。" - permalink_normalizations: "在匹配永久链接之前应用如下正则表达式,例如:/(\\/topic.*)\\?.*/\\1 将去掉所有主题路径的参数字符串。格式为使用正则表达式,以及在字符串使用 \\1 等等来访问捕获内容" + permalink_normalizations: "在匹配永久链接之前应用如下正则表达式,例如:/(topic.*)\\?.*/\\1 将去掉所有主题路径的参数字符串。格式为使用正则表达式+使用 \\1 等字符串来访问捕获内容" global_notice: "为所有访客显示“紧急的”全局横幅,留空隐藏它(可以使用 HTML)" disable_edit_notifications: "当 'download_remote_images_to_local' 启用时禁用系统编辑提醒。" + automatically_unpin_topics: "当用户到达底部时自动解除主题置顶。" + read_time_word_count: "一分钟阅读的词的数量,用于估计阅读时间。" full_name_required: "全名是用户个人信息的必填项。" enable_names: "在用户的个人信息、用户卡片和邮件中显示全名。禁用将在所有地方隐藏全名。" display_name_on_posts: "在用户的帖子中显示他们的全名以及他们的 @username。" @@ -982,34 +1047,40 @@ zh_CN: embed_username_key_from_feed: "从流中获取 discourse 用户名的 Key。" embed_truncate: "截断嵌入的帖子。" embed_post_limit: "嵌入帖子的最大数量。" + embed_username_required: "创建主题需要用户名。" embed_whitelist_selector: "在嵌入页面加入元素 CSS 选择器。" embed_blacklist_selector: "在嵌入页面移除元素 CSS 选择器。" notify_about_flags_after: "如果有标记没有在设定小时后处理,发送一封邮件给 contact_email。设为 0 将禁用。" enable_cdn_js_debugging: "为包含的 js 启动跨源访问 /logs 权限以显示合适的错误。" show_create_topics_notice: "如果站点只有少于 5 篇的公开帖子时,显示一条请管理员创建帖子的提示。" delete_drafts_older_than_n_days: 删除超过 n 天得草稿。 - show_logout_in_header: "在顶栏的用户下拉菜单中显示登出" vacuum_db_days: "在数据库迁移后使用完整扫描回收数据库空间(设置 0 为禁用)" prevent_anons_from_downloading_files: "禁止匿名用户下载附件。警告:这将禁止他们访问任何发表在帖子中的非图片资源。" slug_generation_method: "选择一个链接生成方式。“encoded”将生成以百分号编码的链接。“none”将禁用自定义链接,只生成默认链接。" enable_emoji: "启用绘文字(emoji)" emoji_set: "你喜欢哪一种 emoji?" enforce_square_emoji: "强制为所有 emojis 设置正方形比例。" - approve_post_count: "新用户需要被审核的帖子数量" + approve_post_count: "新用户或基础用户需要被审核的帖子数量" approve_unless_trust_level: "该信任等级之下的用户的帖子必须被审核" notify_about_queued_posts_after: "如果有帖子等待了设定的小时数后仍在等候处理,发送一封邮件给联络邮件地址。设为 0 将禁用这些邮件。" default_email_digest_frequency: "用户默认收到摘要邮件的默认频率。" + default_include_tl0_in_digests: "用户在摘要邮件中是否收到新用户帖子的默认设置。用户可以在参数设置中更改这个设置。" default_email_private_messages: "默认在有人发消息给用户时发送一封邮件通知。" default_email_direct: "默认在有人引用、回复、提及或者邀请用户时发送一封邮件通知。" default_email_mailing_list_mode: "默认为每一个新帖子发送一封邮件通知。" + disable_mailing_list_mode: "禁止用户使用邮件列表模式。" default_email_always: "即使用户活跃时,仍默认发送邮件通知。" - default_other_new_topic_duration_minutes: "一个主题在多少分钟之内被系统判断为新主题的全局缺省设置" + default_email_previous_replies: "默认在邮件中包含之前的回复。" + default_email_in_reply_to: "默认在邮件中包含回复的摘要文本。" + default_other_new_topic_duration_minutes: "新主题条件的全局缺省设置" default_other_auto_track_topics_after_msecs: "经过多少毫秒之后一个主题就被自动追踪的全局缺省设置" default_other_external_links_in_new_tab: "默认在新的标签页打开外部链接" default_other_enable_quoting: "默认在高亮选择文字时启用引用回复" default_other_dynamic_favicon: "默认在浏览器图标上显示新/更新的主题数量" default_other_disable_jump_reply: "默认不在用户回复后跳转到新帖子位置" default_other_edit_history_public: "将帖子修订历史默认公开。" + default_other_like_notification_frequency: "默认通知用户赞的消息" + default_topics_automatic_unpin: "默认时当用户到达底部时自动解除主题置顶。" default_categories_watching: "分类列表默认跟踪。" default_categories_tracking: "分类列表默认追踪。" default_categories_muted: "分类列表默认不显示。" @@ -1027,7 +1098,15 @@ zh_CN: invalid_string_min: "必须超过 %{min} 个字符。" invalid_string_max: "必须不超过 %{max} 个字符。" invalid_reply_by_email_address: "值必须包含 '%{reply_key' 并且要与通知邮件不同。" + pop3_polling_host_is_empty: "在启用 POP3 轮询前,你必须设置 'pop3 polling host'。" + pop3_polling_username_is_empty: "在启用 POP3 轮询前,你必须设置 'pop3 polling username'。" + pop3_polling_password_is_empty: "在启用 POP3 轮询前,你必须设置 'pop3 polling password'。" + pop3_polling_authentication_failed: "POP3 验证失败。请验证你的 pop3 账户信息。" + reply_by_email_address_is_empty: "在启用邮件回复之前,你必须设置“reply by email address”。" + email_polling_disabled: "在启用邮件回复功能前,你必须启用手动或者 POP3 轮询。" + user_locale_not_enabled: "你必须先设置 'allow user locale' 再启用该设置。" notification_types: + group_mentioned: "%{group_name} 在 %{link} @ 了你" mentioned: "%{display_username} 在 %{link} @ 了你" liked: "%{display_username} 在 %{link} 赞了你的帖子 " replied: "%{display_username} 在 %{link} 回复了你的帖子" @@ -1037,7 +1116,7 @@ zh_CN: moved_post: "%{display_username} 把你的帖子移动到了 %{link}" private_message: "%{display_username} 发送给你一条消息:%{link}" invited_to_private_message: "%{display_username} 邀请你参与消息讨论:%{link}" - invited_to_topic: "%{display_username} 邀请你至主题:%{link}" + invited_to_topic: "%{display_username} 请你看看 %{link}" invitee_accepted: "%{display_username} 接受了你的邀请" linked: "%{display_username} 在 %{link} 里链接了你" granted_badge: "你获得了 %{link}" @@ -1048,10 +1127,10 @@ zh_CN: topic: '结果' user: '用户' sso: - not_found: "无法找到或创建账户,联系站点管理员" - account_not_approved: "账户正在等待验证,完成后你将收到一封邮件提醒" - unknown_error: "更新信息时错误,联系站点管理员" - timeout_expired: "账户登录超时,请重试登录" + not_found: "无法找到你的账户。请联系站点管理人员。" + account_not_approved: "你的帐号尚未被审核通过。一旦你的帐号获得批准,你就会收到一封电子邮件提醒。" + unknown_error: "你的账户发生了问题。请联系站点管理人员。" + timeout_expired: "账户登录超市,请重新尝试登录。" original_poster: "原始作者" most_posts: "大部分帖子" most_recent_poster: "当前大部分帖子作者" @@ -1063,7 +1142,7 @@ zh_CN: new_topic_moderator_post: other: "%{count} 个帖子被分离到了新主题:%{topic_link}" existing_topic_moderator_post: - other: "%{count} 个帖子被何明至已存在的主题:%{topic_link}" + other: "%{count} 个帖子被合并到现存主题:%{topic_link}" change_owner: post_revision_text: "所有权从 %{old_user} 转移至 %{new_user}" deleted_user: "已经删除的用户" @@ -1090,9 +1169,9 @@ zh_CN: other: "本主题在最后一个回复创建后 %{count} 分钟后自动关闭。不再允许添加新回复。" autoclosed_disabled: "本主题是开放的,可以添加新的回复。" autoclosed_disabled_lastpost: "本主题现在开放了。可以添加新的回复。" - pinned_enabled: "本主题已置顶,它将始终显示在它所属分类的顶部。可由职员对所有人解除置顶,或者由用户自己取消置顶。" + pinned_enabled: "本主题已置顶,它将始终显示在它所属分类的顶部。可由管理人员对所有人解除置顶,或者由用户自己取消置顶。" pinned_disabled: "本主题已被解除置顶,它将不再显示在它所属分类的顶部。" - pinned_globally_enabled: "本主题已全局置顶,它将始终显示在它所属分类的顶部。可由职员对所有人解除置顶,或者由用户自己取消置顶。" + pinned_globally_enabled: "本主题已全局置顶,它将始终显示在它所属分类的顶部。可由管理人员对所有人解除置顶,或者由用户自己取消置顶。" pinned_globally_disabled: "本主题已被解除置顶,它将不再显示在它所属分类的顶部。" visible_enabled: "本主题已设置为显示在主题列表中。" visible_disabled: "本主题设置为不显示在主题列表中。只能通过直达链接来访问。" @@ -1118,6 +1197,7 @@ zh_CN: reserved_username: "该用户名不可被使用。" missing_user_field: "你还没有填写完所有用户字段" close_window: "验证已经完成。关闭窗口以继续。" + already_logged_in: "喔,看起来你正尝试查看给另一个用户的邀请链接。如果你不是%{current_user},请登出再重试。" user: no_accounts_associated: "无关联账户" username: @@ -1126,16 +1206,31 @@ zh_CN: characters: "必须只包含字母、数字和下划线" unique: "必须是唯一的" blank: "必须存在" - must_begin_with_alphanumeric: "必须以一个字母或数字或下划线开头" - must_end_with_alphanumeric: "必须以字母或数字结尾或是下划线" + must_begin_with_alphanumeric_or_underscore: "必须以字母、数字或下划线开头" + must_end_with_alphanumeric: "必须以字母或数字结尾" must_not_contain_two_special_chars_in_seq: "必须不包括连续的 2 个或更多的特殊字符(.-_)" - must_not_contain_confusing_suffix: "必须不包含奇怪的后缀,例如 .json 或 .png 等等。" + must_not_end_with_confusing_suffix: "不能以难以分辨的后缀结尾,比如 .json 或者 .png 等" email: not_allowed: "本站不允许使用该邮箱服务商提供的电子邮箱,请使用其它邮箱地址。" blocked: "不被允许。" ip_address: blocked: "不允许从你的 IP 地址注册新用户。" - max_new_accounts_per_registration_ip: "不允许从你的 IP 地址注册新用户(达到上限)。联系一个职员。" + max_new_accounts_per_registration_ip: "不允许从你的 IP 地址注册新用户(达到上限)。联系一个管理人员。" + flags_reminder: + flags_were_submitted: + other: "这些标记在过去 %{count} 小时内被提交。请审核他们。" + subject_template: + other: "%{count} 个标记需要被处理" + unsubscribe_mailer: + subject_template: "确认你不想要收到%{site_title}的电子邮件更新" + text_body_template: | + 有人(可能是你?)请求不再接受来自%{site_domain_name}的邮件更新。 + 点击链接以确认退订: + + %{confirm_unsubscribe_link} + + + 如果你想要继续接受邮件更新,你可以忽略这封邮件。 invite_mailer: subject_template: "%{invitee_name} 邀请你参与 %{site_domain_name} 主题 '%{topic_title}' " text_body_template: | @@ -1184,23 +1279,25 @@ zh_CN: [**%{base_url}**][0] - 电子邮件分发很复杂。以下是一些重要的你应该检查的内容: + 电子邮件分发很复杂。以下是一些你应该检查的重点: - - 确定你设置了站点设置为 `notification email` 设置了正确的地址。**“来自”中指定的域名应和将要验证的域名一致。** + - 确定你在站点设置为 `notification email` 设置了正确的地址。**这是系统发送邮件里的“发自”地址,需要和你的 DNS 以及域名匹配**。 - - 确定你会使用你的邮件客户端查看*电子邮件源代码*,这样你可以通过查看邮件头来获取重要线索。在 Gmail 中,可以通过每一封邮件下拉菜单中的“显示原始消息”来查看。 + - 确定你用邮件客户端查看电子邮件源代码,这样你可以通过查看邮件头部来获取重要线索。在 Gmail 中,可以通过每一封邮件下拉菜单中的“显示原始消息”来查看。 - - **重要:** 你的 ISP 是否对你发送邮件的域名和IP作了反向DNS解析?你可以在此[测试你的反向枚举指针(PTR)记录][2]。如果你的 ISP 没有正确的反向 DNS 记录,那么很可能你的任何电子邮件都不会被成功发送。 + - **重要:** 你的 ISP 是否对你发送邮件的域名和 IP 作了反向 DNS 解析?你可以在此[测试你的反向枚举指针(PTR)记录][2]。如果你的 ISP 没有设置正确的反向 DNS 记录,那么很可能你的任何电子邮件都不会被成功发送。 - 你的域名的[发件人策略框架(SPF)记录][8]是否正确?你可以在此[测试你的SPF记录][1]。注意 TXT 是一种正确的官方 SPF 记录。 - - 你域名的[域名密钥身份识别邮件(DKIM)记录][3]正确?这将显著提高邮件分发的成功率。在此[测试你的 DKIM 记录]。 + - 你域名的[域名密钥身份识别邮件(DKIM)记录][3]设置是否正确?这将显著提高邮件分发的成功率。在此[测试你的 DKIM 记录][7]。 - - 如果你自己运行邮件服务器,检查确认你发送电子邮件的服务器IP [不在任何邮件黑名单中][4]。验证你的 DNS 记录的 HELO 消息中*确定无疑地*发送了符合要求的主机名。如果没有,那么会导致很多邮件服务商拒绝你的邮件。 + - 如果你自己运行邮件服务器,检查确认你发送电子邮件的服务器 IP [不在任何邮件黑名单中][4]。验证你的 DNS 记录的 HELO 消息中确定无疑地设置了符合要求的主机名。如果没有,那么会导致很多邮件服务商拒绝你的邮件。 - (最简单的方法是在[Mandrill][md]或[Mailgun][mg]或[Mailjet][mj]注册免费账户,他们的免费账户对一个小社群是足够的。如果你希望在中国大陆提供稳定的服务,你可以考虑[SendCloud][sc]不过你仍然需要在 DNS 设置中设定 SPF 和 DKIM 记录!) + - 我们强烈建议你**发送测试邮件至 [mail-tester.com][mt]**,这样可以检查上述设置是否正确。 - 我们衷心希望你收到这封邮件,成功完成邮件发送测试! + (最简单的方法是在 [SendGrid][sg]、[SparkPost][sp]、[Mailgun][mg] 和 [Mailjet][mj]注册免费账户,他们的免费账户对一个小社群是足够的。如果你希望在中国大陆提供稳定的服务,你可以考虑[SendCloud][sc]。不过你仍然需要在 DNS 设置中设定 SPF 和 DKIM 记录!) + + 我们衷心希望你成功完成邮件发送测试! 祝好运! @@ -1213,21 +1310,21 @@ zh_CN: [4]: http://whatismyipaddress.com/blacklist-check [7]: http://dkimcore.org/tools/dkimrecordcheck.html [8]: http://www.openspf.org/SPF_Record_Syntax - [md]: http://mandrill.com + [sg]: https://sendgrid.com/ + [sp]: https://www.sparkpost.com/ [mg]: http://www.mailgun.com/ - [mj]: http://www.mailjet.com/pricing + [mj]: https://www.mailjet.com/pricing + [mt]: http://www.mail-tester.com/ [sc]: http://sendcloud.sohu.com/ new_version_mailer: subject_template: "[%{site_name}] 有新的 Discourse 版本,可供升级" text_body_template: | - 有新版本的 [Discourse](http://www.discourse.org) 可供升级。 + 哇哦,有新版本的 [Discourse](http://www.discourse.org) 可以升级! 你的版本:%{installed_version} - 新版本:**%{new_version}** + 新的版本:**%{new_version}** - 你可能想要: - - - 查看[GitHub 改动日志](https://github.com/discourse/discourse/commits/master)中更新的内容。 + - 查看[GitHub 改动日志(英文)](https://github.com/discourse/discourse/commits/master)中更新的内容。 - 浏览器访问 [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade) 升级。 @@ -1235,30 +1332,16 @@ zh_CN: new_version_mailer_with_notes: subject_template: "[%{site_name}] 可以升级" text_body_template: | - 有新版本的 [Discourse](http://www.discourse.org) 可供升级。 + 哇哦,有新版本的 [Discourse](http://www.discourse.org) 可以升级! 你的版本:%{installed_version} - 新版本:**%{new_version}** + 新的版本:**%{new_version}** - 你可能想要: - - - 查看[GitHub 改动日志](https://github.com/discourse/discourse/commits/master)中更新的内容。 + - 查看[GitHub 改动日志(英文)](https://github.com/discourse/discourse/commits/master)中更新的内容。 - 浏览器访问 [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade) 升级。 - 访问 [meta.discourse.org(英文)](http://meta.discourse.org) 获取 Discourse 的最新资讯、讨论和支持。也可访问 [meta.discoursecn.org 非官方的中文支持论坛](http://meta.discoursecn.org) 获得支持。 - - ### 发行注记 - - %{notes} - flags_reminder: - flags_were_submitted: - other: "这些标记在过去 %{count} 内被提交。" - please_review: "请核查他们。" - post_number: "帖子" - how_to_disable: '你可以通过修改“notify about flags after”设置项以禁用或改变邮件提醒设置。' - subject_template: - other: "%{count} 个标记需要被处理" queued_posts_reminder: subject_template: other: "[%{site_name}] %{count} 个帖子等待审核" @@ -1270,11 +1353,11 @@ zh_CN: off_topic: "你的帖子被标记为 **偏离主题**:鉴于当前的主题标题和第一个帖子,社群成员们感觉它不适合处于这个主题中。" inappropriate: "你的帖子被标记为 **不恰当**:社群成员感觉它有冒犯或者侮辱的意味,亦或是它违反了[社群准则](/guidelines)。" spam: "你的帖子被标记为 **广告**:社群成员觉得它是广告,像是在过度地推广着什么,而不是预期中与主题有关的内容。" - notify_moderators: "你的帖子被标记为 **需要版主关注**:社群成员感觉帖子需要职员的人工干预。" + notify_moderators: "你的帖子被标记为 **需要版主关注**:社群成员认为帖子需要管理人员介入。" flags_dispositions: - agreed: "感谢通知我们。我们认为这是一个问题,并且我们正在了解情况。" + agreed: "谢谢你的消息。我们认为这是个问题。我们正在进行处理。" agreed_and_deleted: "感谢通知我们。我们认为这是一个问题,并且我们已经删除了帖子。" - disagreed: "感谢通知我们。我们正在了解情况。" + disagreed: "谢谢你的消息。我们正在进行处理。" deferred: "感谢通知我们。我们正在调查情况。" deferred_and_deleted: "感谢通知我们。我们已经删除了帖子。" temporarily_closed_due_to_flags: "主题因为大量的社群标记暂时关闭" @@ -1284,7 +1367,7 @@ zh_CN: text_body_template: | 你好, - 这是一封从%{site_name}自动发出的邮件,通知你的帖子已被隐藏。 + 这是%{site_name}自动发出的邮件,通知你的帖子已被隐藏。 %{base_url}%{url} @@ -1297,19 +1380,19 @@ zh_CN: 想了解更多,请查看我们的[社群指引](%{base_url}/guidelines)。 usage_tips: text_body_template: | - 这是一条包含了一些可以让你快速开始的技巧提示的消息: + 这一条消息是一些使用的小技巧: ## 阅读 要阅读更多,**只需要继续向下滚动页面!** - 当有新的回复或者新主题时,他们将自动地出现 —— 没有必要刷新页面。 + 当有新的回复或者新主题时,他们将自动出现 —— 不用刷新页面。 ## 导航 - - 要搜索,用你的用户页面,或者使用菜单,这个**右上角的图标**。 + - 想要搜索,用你的用户页面,或者点菜单,这个在页面**右上角的图标**。 - - 点击主题标题将引导你至该主题**下一个未读**的帖子。要跳至主题顶部或底部,分别点击回复数量或者最后一次回复时间。 + - 点击主题标题会跳转至至这个主题中**你还没有读的**那个帖子。要找主题顶部或底部,分别点击回复数量或者最后一次回复时间。 @@ -1319,21 +1402,29 @@ zh_CN: ## 回复 - - 要回复**整个主题**,使用页面最底下的 。 + - 要泛泛地回复**整个主题**,使用主题最底下的 。 - - 要回复**特定的人**,使用他们帖子的 。 + - 要回复**特定的人**,使用他们帖子里的 。 - - 要用**一个新主题**回复,使用帖子右边的 。老的和新的主题将自动被链接至一起。 + - 要用**一个新主题**回复,使用帖子右边的 。老的和新的主题将自动关联至一起。 - 要插入引用,选择想要引用的文字,然后点击任何回复按钮。重复以上操作创建多个引用! + 你可以用简单的 HTML 标签、BBCode 或者 [Markdown](http://commonmark.cn/help/) 来格式化: + + 这是**加粗**。 + 这是加粗。 + 这是[b]加粗[b]。 + + 想学习 Markdown?[试试我们有趣的 10 分钟交互教程!](http://commonmark.cn/help/tutorial/) + + 要插入引用,先选择想要引用的文字,然后点击任意地方的回复按钮。重复以上步骤创建多个引用! - 要提醒某人你的回复,提到他们的用户名。键入 `@` 开始选择一个用户名。 + 要提醒某人关注你的回复,你需要提及他们的名字。键入 `@` 开始选择一个用户名。 - 要使用[标准绘文字(Emoji)](http://www.emoji.codes/),先键入 `:` 用名字匹配,或使用传统表情符 `;)` + 想使用[标准绘文字(Emoji)](http://www.emoji.codes/),只要键入 `:`,然后用名字匹配,或使用传统表情符 `;)` @@ -1349,7 +1440,7 @@ zh_CN: 要让别人知道你喜欢并且感谢他们的帖子,使用**赞**按钮。分享爱! - 如果你觉得某人的帖子有问题,使用**标记**按钮私下让他或者[我们的职员](%{base_url}/about)知道。你也可以**分享**至该帖子的链接,或者标记**书签**以供以后在你的用户页查看。 + 如果你觉得某人的帖子有问题,使用**标记**按钮私下告诉他,或者找[我们的管理人员](%{base_url}/about)。你还可以**分享**至该帖子的链接,或者标记**书签**,这样你之后可以在你的用户页查看。 ## 通知 @@ -1357,29 +1448,29 @@ zh_CN: - 不用担心错过他人的回复 —— 当你不在时,你将会收到邮件提醒。 + 不用担心错过别人的回复 —— 当你不怎么逛的时后,你会收到邮件提醒。 ## 你的设置 - 所有小于**两天**的主题算新主题。 - - 任何你**积极参与**的主题(通过创建、回复或者阅读很长时间)将被自动追踪。 + - 任何你**积极参与**(指你创建、回复或者阅读较长时间)的主题将被自动追踪。 - 你将会在主题名字附近见到蓝色的新主题提示和未读帖子数字指示: + 你将会在主题名字后见到蓝色的新主题提示和未读帖子数字指示: - 你可以通过主题下方的通知控制改变通知状态。 + 你可以通过主题下方的通知控制改变通知设置。 - 你也可以为每个分类设置通知状态,比如你可以要监控一个主题的每一个新主题。 + 你也可以为每个分类设置通知状态,比如你可以监控某分类中的每个新主题。 - 要修改任何设置,见[你的用户设置](%{base_url}/my/preferences)。 + 要修改以上任何设置,见[你的用户设置页面](%{base_url}/my/preferences)。 ## 社群信任 - 因为你的积极参与,你将渐渐获得社群信任,成为一个真正的公民,针对新用户的限制将被移除。当达到了一个足够的[信任等级](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924),你将会得到适当的能力一起帮助管理社群。 + 只要你参与社群,随着时间推移你会慢慢获得社群信任,成为一个真正的公民,那些针对新用户的限制将被移除。当达到了一个足够的[信任等级](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924)时,你将会得到适当的能力一起帮助管理社群。 welcome_user: subject_template: "欢迎来到 %{site_name}!" text_body_template: | @@ -1391,10 +1482,10 @@ zh_CN: 好好享受你在论坛的时光吧! - (如果你在新用户级别需要和[职员](%{base_url}/about)沟通的话,直接回复这个消息。) + (如果你在新用户级别需要和[管理人员](%{base_url}/about)沟通的话,直接回复这个消息。) welcome_invite: subject_template: "欢迎来到 %{site_name}!" - text_body_template: "感谢你接受邀请加入%{site_name} —— 欢迎!\n\n我们为你创建了账号:**%{username}**,同时你已经登录了。你可以在任何时候访问[你的用户设置][prefs]来修改它。\n\n要再次登入,或者:\n\n1. 永远 **使用收到邀请的邮箱地址**登录,。否则我们就无法分辨是不是你本人!\n\n2. 在 %{site_name} 的[用户设置][prefs]页面创建一个密码,然后使用该密码来登入。 \n\n%{new_user_tips}\n\n我们始终相信[讨论应该文明](%{base_url}/guidelines)。\n\n好好享受你在论坛的时光吧!\n\n(如果你在新用户级别需要和[职员](%{base_url}/about)沟通的话,直接回复这个消息。)\n\n[prefs]: %{user_preferences_url}\n" + text_body_template: "感谢你接受邀请加入%{site_name} —— 欢迎!\n\n我们为你创建了账号:**%{username}**,同时你已经登录了。你可以在任何时候访问[你的用户设置][prefs]来修改它。\n\n要再次登入,或者:\n\n1. 永远 **使用收到邀请的邮箱地址**登录,。否则我们就无法分辨是不是你本人!\n\n2. 在 %{site_name} 的[用户设置][prefs]页面创建一个密码,然后使用该密码来登入。 \n\n%{new_user_tips}\n\n我们始终相信[讨论应该文明](%{base_url}/guidelines)。\n\n好好享受你在论坛的时光吧!\n\n(如果你在新用户级别需要和[管理人员](%{base_url}/about)沟通的话,直接回复这个消息。)\n\n[prefs]: %{user_preferences_url}\n" backup_succeeded: subject_template: "备份成功完成" text_body_template: "备份成功。\n\n访问[管理 > 备份](%{base_url}/admin/backups)下载你的新备份文件。" @@ -1444,19 +1535,43 @@ zh_CN: 以上的下载链接将在 48 小时后失效。 csv_export_failed: subject_template: "数据导出失败" - text_body_template: "我们很抱歉,但是你的数据导出请求失败了。请检查日志或联系一位职员。" - email_reject_trust_level: + text_body_template: "我们很抱歉,但是你的数据导出请求失败了。请检查日志或联系一位管理人员。" + email_reject_insufficient_trust_level: subject_template: "[%{site_name}] 电子邮件错误 -- 信任等级不足" text_body_template: | - 我们很抱歉,但是你发送至 %{destination}(名为 %{former_title})的邮件无法发送。 + 我们非常抱歉,你发送至 %{destination}(名为 %{former_title})的邮件出问题了。 - 你的账户没有足够的信任等级向刚邮件地址发布新主题。如果你坚信这是一个错误,联系一个职员。 + 你的账户没有足够的信任等级向该邮件地址发布新主题。如果你坚信这是错误,联系管理人员。 + email_reject_user_not_found: + subject_template: "[%{site_name}] 邮件问题 -- 用户未找到" + text_body_template: | + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 + + 你发送回复的邮件地址是未知的邮件地址。试试从另外一个邮件地址发送,或者联系管理人员。 + email_reject_inactive_user: + subject_template: "[%{site_name}] 电子邮件错误 -- 未激活用户" + text_body_template: | + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 + + 与你账户关联的邮件地址没有激活,请先激活你的账号再发送邮件。 + email_reject_blocked_user: + subject_template: "[%{site_name}] 电子邮件错误 -- 被封禁的用户" + text_body_template: | + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 + + 与你账户关联的邮件地址已经被封禁。 + email_reject_reply_user_not_matching: + subject_template: "[%{site_name}] 电子邮件错误 -- 回复用户不符" + text_body_template: | + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 + + 你发送回复的邮件地址与我们等待的地址不同,所以我们不确定你是不是同一个人。试试从另外一个邮件地址发送,或者联系管理人员。 email_reject_no_account: subject_template: "[%{site_name}] 电子邮件错误 -- 未知账户" text_body_template: | - 我们很抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件无法发送。 + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 - 该邮件没有与已知的账户关联。试试从不同的邮件地址发送或联系一个职员。 + 我们找不到匹配你邮件地址的账号。试试从另外一个邮件地址发送,或者联系管理人员。 email_reject_empty: subject_template: "[%{site_name}] 电子邮件错误 -- 无内容" text_body_template: | @@ -1476,67 +1591,87 @@ zh_CN: text_body_template: | 我们很抱歉,但是您发送至 %{destination}(名为 %{former_title})的邮件无法发送。 - 您的账户没有足够的权限在该分类发布一个新主题。如果您坚信这是一个错误,联系一个职员。 - email_reject_post_error: - subject_template: "[%{site_name}] 邮件问题 -- 发表错误" + 您的账户没有足够的权限在该分类发布一个新主题。如果您坚信这是一个错误,联系一个管理人员。 + email_reject_strangers_not_allowed: + subject_template: "[%{site_name}] 电子邮件错误 -- 无权限" text_body_template: | - 我们很抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件无法发送。 + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 - 一些可能的原因是:复杂的格式、消息超长、消息太短。请再试一次,若还不行,使用网站发表。 - email_reject_post_error_specified: - subject_template: "[%{site_name}] 邮件问题 -- 发表错误" + 你发邮件到的分类只接受已知邮件的合法账户。如果你坚信这是错误,联系管理人员。 + email_reject_invalid_post: + subject_template: "[%{site_name}] 邮件问题 -- 发布时错误" text_body_template: | - 我们很抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件消息无法发送。 + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 - 援引: + 可能的原因是:复杂的格式、消息超长、消息太短。请再试一次,如果还不行,使用网站发表。 + email_reject_invalid_post_specified: + subject_template: "[%{site_name}] 邮件问题 -- 发布时错误" + text_body_template: | + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 + + 原因: %{post_error} 如果你能解决错误,请再试一次。 + email_reject_rate_limit_specified: + subject_template: "[%{site_name}] 电子邮件错误 -- 频率限制" + text_body_template: | + 我们很抱歉,但是您发送至 %{destination}(名为%{former_title})的邮件出问题了。 + + 原因: %{rate_limit_description} + email_reject_invalid_post_action: + subject_template: "[%{site_name}] 电子邮件错误 -- 无发表权限" + text_body_template: | + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 + + 发送的命令无法被识别。请再试一次,如果还有问题,使用网站发表。 email_reject_reply_key: subject_template: "[%{site_name}] 电子邮件错误 -- 未知回复指纹" text_body_template: | - 我们很抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件无法发送。 + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 - 提供的回复 key 是无效或者未知的,所以我们不知道邮件是回复给谁的。联系一个职员。 - email_reject_destination: + 邮件中的回复信令是无效或者未知的,所以我们不知道这封邮件回复给谁了。请联系管理人员。 + email_reject_bad_destination_address: subject_template: "[%{site_name}] 电子邮件错误 -- 未知的回复至地址" text_body_template: | - 我们很抱歉,但是你发送至 %{destination}(名为 %{former_title})的邮件消息无法发送。 + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 - 在论坛中找不到该地址。请确认在你的发送到(而非抄送或密送)中填写的是站点的地址,并且你正在将邮件发送至论坛职员提供的邮件地址。 + 目标邮件地址无法识别。请确保你是向管理人员提供的邮件地址发信。 email_reject_topic_not_found: subject_template: "[%{site_name}] 邮件问题 -- 主题未找到" text_body_template: | - 十分抱歉,无法将你的信息发表到 %{destination} (titled %{former_title}) 。 + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 - 你回复的主题不存在了,可能它已被删除?如果你确定这是个错误,联系职员。 + 你回复的主题已经不存在了 —— 可能已经被深处了?如果你确定这是错误,请联系管理人员。 email_reject_topic_closed: subject_template: "[%{site_name}] 邮件问题 -- 主题已关闭" text_body_template: | 我们很抱歉,但是你发送至 %{destination}(名为 %{former_title})的邮件无法发送。 - 你回复的主题现在已经被关闭并不再接受回复。如果你确定这是个错误,联系职员。 + 你回复的主题现在已经被关闭并不再接受回复。如果你确定这是个错误,联系管理人员。 email_reject_auto_generated: subject_template: "[%{site_name}] 邮件问题 -- 自动生成的回复" text_body_template: | - 我们很抱歉,但是你发送至 %{destination}(名为 %{former_title})的邮件无法发送。 + 我们非常抱歉,但是你发送至 %{destination}(名为%{former_title}) 的邮件出问题了。 - 你的邮件回复被标记为“自动生成的”,我们不接受这种内容。如果你确定这是个错误,联系职员。 + 你的邮件被标记为“自动生成”的,即邮件是由电脑生成而不是人类所写;我们不接受这样的邮件。如果你确信这是错误,请联系管理人员。 email_error_notification: subject_template: "[%{site_name}] 电子邮件错误 -- POP 验证错误" text_body_template: | - 在从 POP 服务器查询邮件时遇到了一个验证错误。 + 不幸的是,从 POP 服务器查询邮件时遇到了验证错误。 请确认你在[站点设置](%{base_url}/admin/site_settings/category/email)中已经正确配置了 POP 验证信息。 + + 如果 POP 邮件账号有图形界面,你可以登录后查看邮箱设置。 too_many_spam_flags: subject_template: "新账号被封禁" text_body_template: | 你好, - 这是一封自 %{site_name} 自动发出的邮件,以告知你的帖子已因被社群多次标记而被自动隐藏。 + 这是%{site_name}自动发出的邮件,以告知你的帖子已因被社群多次标记而被自动隐藏。 - 处于谨慎的考虑,你的新账户被禁止创建新回复或主题。除非一个职员能复核你的账户。 + 处于谨慎的考虑,你的新账户被禁止创建新回复或主题。除非一个管理人员能复核你的账户。 欲查看额外的指导,请查看我们的[社群指引](%{base_url}/guidelines)。 blocked_by_staff: @@ -1544,27 +1679,31 @@ zh_CN: text_body_template: | 你好, - 这是一封自 %{site_name} 自动发出的邮件,以告知你的账户被职员封禁。 + 这是%{site_name}自动发出的邮件。你的账户已经被管理人员封禁。 + + 请知晓在管理人员解封你之前,你不能够再创建新的回复或者主题。 + + 如果你对封禁有异议,请联系我们的[管理人员](%{base_url}/about)。 欲查看额外的指导,请查看我们的[社群指引](%{base_url}/guidelines)。 user_automatically_blocked: subject_template: "因标记而被封禁的新用户 %{username}" text_body_template: | - 这是一封自动发出的邮件。 + 这是自动发出的邮件。 - 新用户 [%{username}](%{base_url}%{user_url}) 已因多位用户标记 %{username} 的帖子而被自动封禁。 + 因多位用户标记%{username}的帖子,新用户[%{username}](%{base_url}%{user_url})已被自动封禁。 - 请[审核这些标记](%{base_url}/admin/flags)。如果 %{username} 被不正确地封禁了编辑功能,点击[该用户的管理页面](%{base_url}%{user_url})上的解封按钮。 + 请[查看这些标记](%{base_url}/admin/flags)。如果%{username}被意外禁用了编辑功能,点击[该用户管理页面](%{base_url}%{user_url})内的解封按钮。 该阈值可以通过站点设置中的 `block_new_user` 更改。 spam_post_blocked: subject_template: "新用户 %{username} 因重复发布链接而被禁止发表相关帖子" text_body_template: | - 这是一封自动发出的邮件。 + 这是自动发出的邮件。 - 新用户 [%{username}](%{base_url}%{user_url}) 已因创建多个链接至 %{domains} 的帖子而被封禁以防止垃圾信息。但是用户仍能够发表不包含到 %{domains} 的帖子。 + 新用户[%{username}](%{base_url}%{user_url})试图创建多个链接至 %{domains} 的帖子,但这些帖子因为反垃圾策略而被阻挡了。用户仍能够发表不包含到 %{domains} 的帖子。 - 请[审核这些用户](%{base_url}%{user_url})。 + 请[审核该用户](%{base_url}%{user_url})。 该阈值可以通过站点设置中的 `newuser_spam_host_threshold` 和 `white_listed_spam_host_domains` 更改。 unblocked: @@ -1572,7 +1711,7 @@ zh_CN: text_body_template: | 你好, - 这是一封自 %{site_name} 自动发出的邮件,以告知你的账户已经在职员审核后被解封。 + 这是%{site_name}自动发出的邮件,以告知你的账户已经在管理人员审核后被解封。 你现在又可以创建新的回复和主题了。 pending_users_reminder: @@ -1586,52 +1725,88 @@ zh_CN: subject_template: "远程图片下载已禁用。" text_body_template: "`download_remote_images_to_local` 设定已被禁用,因为已经达到 ``download_remote_images_threshold` 设定中的磁盘空间限制。" unsubscribe_link: | - 要取消订阅这些邮件,访问你的[用户设置](%{user_preferences_url})。 - - 不想再接受这类主题的通知,[点击这里](%{unsubscribe_url})。 + 不想再接受该主题的通知,[点击这里](%{unsubscribe_url})。要退订这些邮件,修改你的[用户设置](%{user_preferences_url}) + unsubscribe_via_email_link: | + 或者,[点击这儿](mailto:reply@%{hostname}?subject=unsubscribe)发邮件退订。 subject_re: "回复:" subject_pm: "[私信]" user_notifications: previous_discussion: "之前的回复" + reached_limit: + other: "警告:你达到了每日邮件限额(%{count})。之后邮件通知将被禁用。" + in_reply_to: "回复给" unsubscribe: title: "取消订阅" description: "不再对这些邮件感兴趣?没问题!点击下面按钮来立即取消订阅:" - reply_by_email: "通过邮件回复或者在浏览器中访问 %{base_url}%{url} 。" - visit_link_to_respond: "在浏览器中访问 %{base_url}%{url} 回复。" + reply_by_email: "[访问主题](%{base_url}%{url})或者发邮件回复" + reply_by_email_pm: "[访问消息](%{base_url}%{url})或者发邮件回复" + only_reply_by_email: "用邮件回复" + visit_link_to_respond: "访问[Visit Topic](%{base_url}%{url})以回复" + visit_link_to_respond_pm: "访问[Visit Message](%{base_url}%{url})以回复" posted_by: "%{username}发表于%{post_date}" + invited_to_private_message_body: | + %{username} 邀请你至消息交流: + + > **%{topic_title}** + > + > %{topic_excerpt} + + 论坛: + + > %{site_title} -- %{site_description} + invited_to_topic_body: | + %{username} 邀请你参与讨论: + + > **%{topic_title}** + > + > %{topic_excerpt} + + 论坛: + + > %{site_title} -- %{site_description} user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} 邀请你加入消息交流:'%{topic_title}'" - text_body_template: |2 + text_body_template: | + %{header_instructions} - %{username} 邀请你至消息交流: + %{message} - > **%{topic_title}** - > - > %{topic_excerpt} + --- + %{respond_instructions} + user_invited_to_private_message_pm_staged: + subject_template: "[%{site_name}] %{username} 邀请你加入消息交流:'%{topic_title}'" + text_body_template: | + %{header_instructions} - 论坛: + %{message} - > %{site_title} -- %{site_description} - - 请访问 %{base_url}%{url} 来查看该主题。 + --- + %{respond_instructions} user_invited_to_topic: - subject_template: "[%{site_name}] %{username} 邀请你至主题:'%{topic_title}'" - text_body_template: |2 + subject_template: "[%{site_name}] %{username}邀请你参与“%{topic_title}”" + text_body_template: | + %{header_instructions} - %{username} 邀请你参与讨论: + %{message} - > **%{topic_title}** - > - > %{topic_excerpt} - - 论坛: - - > %{site_title} -- %{site_description} - - 请访问 %{base_url}%{url} 来查看该主题。 + --- + %{respond_instructions} user_replied: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_replied_pm: + subject_template: "[%{site_name}] [PM] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1641,6 +1816,19 @@ zh_CN: user_quoted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_linked: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1650,6 +1838,19 @@ zh_CN: user_mentioned: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + + %{message} + + %{context} + + --- + %{respond_instructions} + user_group_mentioned: + subject_template: "[%{site_name}] %{topic_title}" + text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1659,6 +1860,8 @@ zh_CN: user_posted: subject_template: "[%{site_name}] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} @@ -1668,14 +1871,24 @@ zh_CN: user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" text_body_template: | + %{header_instructions} + %{message} %{context} + --- + %{respond_instructions} + user_posted_pm_staged: + subject_template: "%{optional_re}%{topic_title}" + text_body_template: |2 + + %{message} + --- %{respond_instructions} digest: - why: "在你上一次于 %{last_seen_at} 访问后,%{site_link}的简洁摘要。" + why: "在你上一次于 %{last_seen_at}访问后,%{site_link}的新内容摘要。" subject_template: "[%{site_name}] 摘要" new_activity: "在你的主题和帖子里的动态:" top_topics: "热门帖子" @@ -1698,9 +1911,9 @@ zh_CN: set_password: subject_template: "[%{site_name}] 设置密码" text_body_template: | - 有人请求添加你在 [%{site_name}](%{base_url}) 的密码。除此之外,你可以通过已验证邮件地址的在线服务商(Google、Facebook等等)登录。 + 有人请求添加你在 [%{site_name}](%{base_url}) 的密码。除此之外,你可以通过已验证过你邮件地址的在线服务商登录。 - 如果不是你请求添加密码,你可以直接忽略本邮件。 + 如果不是你在请求添加密码,你可以直接忽略本邮件。 点击下面的链接来选择一个新密码: %{base_url}/users/password-reset/%{email_token} @@ -1720,18 +1933,34 @@ zh_CN: 点击下面的链接来为新账户设置密码: %{base_url}/users/password-reset/%{email_token} - authorize_email: + confirm_new_email: subject_template: "[%{site_name}] 确认你的新电子邮箱地址" text_body_template: | - 点击下面的链接来确认你在 %{site_name} 上的新电子邮箱地址: + 点击下面的链接来确认你在%{site_name}上的新电子邮箱地址: %{base_url}/users/authorize-email/%{email_token} + confirm_old_email: + subject_template: "[%{site_name}] 确认你的新电子邮箱地址" + text_body_template: | + 在我们修改你的邮箱地址前,我们需要你确认你拥有当前的邮件账号。在你完成这步之后,我们将确认你的新邮件地址。 + + 点击下面的链接来确认你当前在%{site_name}上的电子邮箱地址: + + %{base_url}/users/authorize-email/%{email_token} + notify_old_email: + subject_template: "[%{site_name}] 你的邮箱地址已经修改成功" + text_body_template: | + 这是%{site_name}自动发出的邮件,以告知你的邮箱地址已经被修改了。如果这是一个错误,请联系站点管理人员。 + + 你的邮箱地址被修改为: + + %{new_email} signup_after_approval: subject_template: "你已经被 %{site_name} 论坛批准加入了!" text_body_template: | 欢迎加入%{site_name}! - 一个职员批准了你在%{site_name}的账户。 + 一个管理人员批准了你在%{site_name}的账户。 点击下面的链接来确认并激活你在 %{site_name} 上的新账号: %{base_url}/users/activate-account/%{email_token} @@ -1744,7 +1973,7 @@ zh_CN: 好好享受你在论坛的时光吧! - (如果你在新用户级别需要和[职员](%{base_url/about)沟通的话,直接回复这个消息。) + (如果你在新用户级别需要和[管理人员](%{base_url/about)沟通的话,直接回复这个消息。) signup: subject_template: "[%{site_name}] 确认你的新账户" text_body_template: | @@ -1755,7 +1984,7 @@ zh_CN: 如果上面的链接无法点击,请拷贝该链接并粘贴到你的浏览器的地址栏里。 page_not_found: - title: "你请求的页面不存在或者是私密的。" + title: "抱歉!这个页面不存在或者是私密的。" popular_topics: "热门" recent_topics: "最近" see_more: "更多" @@ -1781,7 +2010,7 @@ zh_CN: too_large: "抱歉,你试图上传的图片太大了(最大限制为%{max_size_kb}%KB),请裁剪它并重试。" size_not_found: "抱歉,我们无法获取图片大小,请检查你的图片是否已损坏。" avatar: - missing: "抱歉,但是你选用的头像没有存储在服务器上。你能再重新上传一次么?" + missing: "抱歉,我们没法找到与你邮件地址关联的头像。你能再上传一次试试吗?" flag_reason: sockpuppet: "新用户创建了主题,而另外一个新用户以同一个 IP 在该主题回复。查看站点设置的 flag_sockpuppets。" spam_hosts: "新用户试图创建链接到同一个域名的多个帖子。查看站点设置的 newuser_spam_host_threshold。" @@ -1796,6 +2025,7 @@ zh_CN: post_deleted: "主题被作者删除" user_suspended: "用户被封禁" already_read: "用户已经阅读了主题" + exceeded_limit: "超过 max_emails_per_day_per_user" message_blank: "消息为空" message_to_blank: "message.to 为空" text_part_body_blank: "text_part.body 为空" @@ -1813,8 +2043,7 @@ zh_CN: 编辑本主题的第一帖以改变 %{page_name} 页面的内容。 guidelines_topic: title: "FAQ/指引" - body: "\n\n## [这是一个文明讨论的地方](#civilized)\n\n在论坛上请表现得像在公共公园一样得体。我们一群人共享着一个公共社群资源 — 一个通过不断进行讨论以分享我们技能、知识和兴趣的地方。\n\n这些都不是死规矩或者是草率决定,只是一些帮助社群的人们来判断的规定。试用这些指引来保持干净和充满灵感的文明的公开论坛。 \n\n\n\n## [改善讨论](#improve)\n\n帮助我们让这个地方变成一个讨论的好地方。你可以总是一致的做一些帮助改善讨论的事,即使是小事也行。如果你不确定你的帖子有益于讨论,认真想一想你要说什么再发布。\n\n这里讨论的主题对我们很重要,并且我们希望你也觉得这些内容对你很重要。尊重这些讨论的主题,以及讨论他们的人们,特别是当你不同意他们所说的时候。\n\n改善讨论的一种方法是找一找已经发生过的事。请在发帖或创建你自己的主题前,花一些时间浏览这些主题,这样你更有机会遇见和你有共同爱好的人。 \n\n\n\n## [即使你不同意他人时,尊重他人](#agreeable)\n\n你可能想表达你的不同意。这没问题。但是,记住_批评观点,而不是人_。请避免:\n\n* 指名道姓。\n* 人生攻击。\n* 回复帖子无关于帖子的内容。\n* 下意识的反驳。\n\n相反,提供合理的观点改善讨论。 \n\n\n\n## [你的参与有意义](#participate)\n\n我们在这儿的讨论为大家树立了榜样。通过选择参与有意义的讨论,帮助我们将论坛变成一个有意思的地方 — 并且避免那些没有帮助的行为。\n\nDiscourse 提供了让社群共同鉴别最棒(或最差)的贡献的工具:收藏、书签、赞、标记、回复和编辑等等。使用这些工具不仅能改善你自己的体验,也能改善其他人的体验。\n\n让我们创造一个更美好的社群。\n\n\n\n## [如果你发现问题了,标记它](#flag-problems)\n版主有特别的权力;他们对论坛负责。但是你也是。有了你的帮助,版主能成为社群监察者,而不仅是守卫或者警察。\n\n当你见到不合适的行为,不要回复。这种承认变相鼓励了这种不合适的行为,浪费了你的精力,并且浪费了每一个人的时间。_只要标记它。_如果收到了足够的标记,将会有相应的处理,这个处理可能是自动地,也可能由版主介入。\n\n为了维护我们的社群,版主保留了任何情况下删除任何内容和任何用户的权力。版主没有预先审核任何新帖子;版主和站点维护人员对社群里发表的任何言论均不负责任。 \n\n\n\n## [永远保持文明](#be-civil)\n\n粗鲁这样的行为会破坏健康的讨论:\n\n* 文明。不要发表任何理智的人会认为冒犯的、过分的或招致怨恨的言论。\n* 拒绝色情。不要发表任何淫秽或性暗示的东西。\n* 尊重每一个人。不要骚扰或者让别人难过,检视别人,或暴露他们的个人信息。\n* 尊重我们的论坛。不要发表广告或者其他垃圾信息。\n\n这些条款不是法律条文,并且没有准确的定义 — 避免任何做关于他们的_可能擦边_的事。如果你不确定,问问自己的帖子是否能出现在纽约时报的头版头条上。\n\n这是一个公共论坛,并且搜索引擎会索引这些讨论。注意发表的语言、链接和图片,不要在其中包含你的家庭和朋友。 \n\n\n\n## [保持整洁](#keep-tidy)\n\n花一点时间让东西出现在正确的位置,这样我们能花更多的时间在讨论上而非清理格式。所以:\n\n* 不要在错误的分类发表新主题。\n* 不要在多个主题中回复同样的内容。\n* 不要发布没有内容的回复。\n* 不要在中途改变主题。\n* 不要在你的帖子中签名 — 每一贴都附有你的个人信息。\n\n比起发表“+1”或者“同意”,使用赞按钮。比起将帖子带向一个决然不同的方向,使用“回复为关联主题”。\n\n\n\n## [只发表你自己的东西](#stealing)\n\n你不能在没有他人授权的情况下发表任何属于他人的数字资产。你可能不能发表关于窃据他人知识产权(软件、视频、音频和图像)的任何简介、链接或方法,或其他任何违反法律的内容。 \n\n\n\n## [有你参与](#power)\n\n这个站点由[一群友善的职员](/about)、你和社群一起运营。如果你对这里的事情仍有疑问,在[站点反馈](/c/site-feedback)分类新建一个主题并且开始讨论!如果遇到了重要或紧急的事情,并且不能用站务分类的主题或标记解决,通过[职员页面](/about)联系我们。\n\ - \n\n\n## [使用条款](#tos)\n\n是的,法律很无聊,但是我们必须保护我们自己 – 引申开来,你和你的数据 – 用于针对不友好的家伙们。我们有一个[使用条款](/tos)描述你的(以及我们)关于内容、隐私和法律的行为和权力。要使用我们的服务,你必须同意遵守[使用条款](/tos)。\n" + body: "\n\n## [这是一个文明讨论的地方](#civilized)\n\n在论坛上请表现得像在公共公园一样得体。我们一群人共享着一个公共社群资源 — 一个通过不断进行讨论以分享我们技能、知识和兴趣的地方。\n\n这些都不是死规矩或者是草率决定,只是一些帮助社群的人们来判断的规定。试用这些指引来保持干净和充满灵感的文明的公开论坛。 \n\n\n\n## [改善讨论](#improve)\n\n帮助我们让这个地方变成一个讨论的好地方。你可以总是一致的做一些帮助改善讨论的事,即使是小事也行。如果你不确定你的帖子有益于讨论,认真想一想你要说什么再发布。\n\n这里讨论的主题对我们很重要,并且我们希望你也觉得这些内容对你很重要。尊重这些讨论的主题,以及讨论他们的人们,特别是当你不同意他们所说的时候。\n\n改善讨论的一种方法是找一找已经发生过的事。请在发帖或创建你自己的主题前,花一些时间浏览这些主题,这样你更有机会遇见和你有共同爱好的人。 \n\n\n\n## [即使你不同意他人时,尊重他人](#agreeable)\n\n你可能想表达你的不同意。这没问题。但是,记住_批评观点,而不是人_。请避免:\n\n* 指名道姓。\n* 人生攻击。\n* 回复帖子无关于帖子的内容。\n* 下意识的反驳。\n\n相反,提供合理的观点改善讨论。 \n\n\n\n## [你的参与有意义](#participate)\n\n我们在这儿的讨论为大家树立了榜样。通过选择参与有意义的讨论,帮助我们将论坛变成一个有意思的地方 — 并且避免那些没有帮助的行为。\n\nDiscourse 提供了让社群共同鉴别最棒(或最差)的贡献的工具:收藏、书签、赞、标记、回复和编辑等等。使用这些工具不仅能改善你自己的体验,也能改善其他人的体验。\n\n让我们创造一个更美好的社群。\n\n\n\n## [如果你发现问题了,标记它](#flag-problems)\n版主有特别的权力;他们对论坛负责。但是你也是。有了你的帮助,版主能成为社群监察者,而不仅是守卫或者警察。\n\n当你见到不合适的行为,不要回复。这种承认变相鼓励了这种不合适的行为,浪费了你的精力,并且浪费了每一个人的时间。_只要标记它。_如果收到了足够的标记,将会有相应的处理,这个处理可能是自动地,也可能由版主介入。\n\n为了维护我们的社群,版主保留了任何情况下删除任何内容和任何用户的权力。版主没有预先审核任何新帖子;版主和站点维护人员对社群里发表的任何言论均不负责任。 \n\n\n\n## [永远保持文明](#be-civil)\n\n粗鲁这样的行为会破坏健康的讨论:\n\n* 文明。不要发表任何理智的人会认为冒犯的、过分的或招致怨恨的言论。\n* 拒绝色情。不要发表任何淫秽或性暗示的东西。\n* 尊重每一个人。不要骚扰或者让别人难过,检视别人,或暴露他们的个人信息。\n* 尊重我们的论坛。不要发表广告或者其他垃圾信息。\n\n这些条款不是法律条文,并且没有准确的定义 — 避免任何做关于他们的_可能擦边_的事。如果你不确定,问问自己的帖子是否能出现在纽约时报的头版头条上。\n\n这是一个公共论坛,并且搜索引擎会索引这些讨论。注意发表的语言、链接和图片,不要在其中包含你的家庭和朋友。 \n\n\n\n## [保持整洁](#keep-tidy)\n\n花一点时间让东西出现在正确的位置,这样我们能花更多的时间在讨论上而非清理格式。所以:\n\n* 不要在错误的分类发表新主题。\n* 不要在多个主题中回复同样的内容。\n* 不要发布没有内容的回复。\n* 不要在中途改变主题。\n* 不要在你的帖子中签名 — 每一贴都附有你的个人信息。\n\n比起发表“+1”或者“同意”,使用赞按钮。比起将帖子带向一个决然不同的方向,使用“回复为关联主题”。\n\n\n\n## [只发表你自己的东西](#stealing)\n\n你不能在没有他人授权的情况下发表任何属于他人的数字资产。你可能不能发表关于窃据他人知识产权(软件、视频、音频和图像)的任何简介、链接或方法,或其他任何违反法律的内容。 \n\n\n\n## [有你参与](#power)\n\n这个站点由[一群友善的管理人员](/about)、你和社群一起运营。如果你对这里的事情仍有疑问,在[站点反馈](/c/site-feedback)分类新建一个主题并且开始讨论!如果遇到了重要或紧急的事情,并且不能用站务分类的主题或标记解决,通过[管理人员页面](/about)联系我们。\n\n\n\n## [使用条款](#tos)\n\n是的,法律很无聊,但是我们必须保护我们自己 – 引申开来,你和你的数据 – 用于针对不友好的家伙们。我们有一个[使用条款](/tos)描述你的(以及我们)关于内容、隐私和法律的行为和权力。要使用我们的服务,你必须同意遵守[使用条款](/tos)。\n" tos_topic: title: "服务条款" body: | @@ -2015,7 +2244,7 @@ zh_CN: ## [儿童在线隐私保护法案合规](#coppa) - 我们的站点、产品和服务提供给 13 岁以上的人们。如果服务器位于美国,并且你小于 13 岁,根据 COPPA([儿童在线隐私保护法案合规](https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act)),不要使用这个站点。 + 我们的站点、产品和服务提供给 13 岁以上的人们。如果服务器位于美国,并且你小于 13 岁,根据[儿童在线隐私保护法案合规](https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act),不要使用这个站点。 @@ -2037,80 +2266,204 @@ zh_CN: 文档以 CC-BY-SA 发布。最后更新时间为2013年5月31日。 static: - search_help: | -

    小技巧

    -

    -

      -
    • 标题匹配优先 – 不知道搜什么时,搜索标题
    • -
    • 搜索独一无二且不常见的单词可以得到最好的结果
    • -
    • 试试搜索特定的分类、用户或主题
    • -
    -

    -

    选项

    -

    - - - - - - - -
    order:viewsorder:latestorder:likes
    status:openstatus:closedstatus:archivedstatus:norepliesstatus:single_user
    category:foouser:foogroup:foobadge:foo
    in:likesin:postedin:watchingin:trackingin:private
    in:bookmarksin:first
    posts_count:nummin_age:daysmax_age:days
    -

    -

    彩虹 category:公园 status:open order:latest 将搜索在“公园”分类中没有关闭或存档中的名字包含“彩虹”的主题,并按最后一个帖子的日期来排序。

    + search_help: "

    小技巧

    \n

    \n

      \n
    • 标题匹配优先 – 不知道搜什么时,搜索标题
    • \n
    • 搜索独一无二且不常见的词可以找到最好的结果
    • \n
    • 试试搜索特定的分类、用户或主题
    • \n
    \n

    \n

    选项

    \n

    \n\n\n\n<;td>badge:徽章名\n\n\n\n\n
    order:views(按照显示次数排序)order:latest(按照更新时间排序)order:likes(按照赞的次数排序)
    status:open(搜索正常状态的主题)status:closed(搜索已经关闭的主题)status:archived(搜索已经存档的主题)status:noreplies(搜索没有回复的主题)status:single_user(搜索单个用户的主题)
    category:分类名user:用户名<;code>group:群组名
    in:likes(在已经赞的帖子里搜索)in:posted(在发表的帖子里搜索)in:watching(在关注的帖子里搜索)in:tracking(在追踪的帖子里搜索)in:private(在私密的帖子里搜索)
    in:bookmarks(在加书签的帖子里搜索)in:first(在第一帖里搜索)
    posts_count:数字(帖子数量)before:天数或者日期after:天数或者日期
    \n

    \n

    例子

    \n

    \n

      \n
    • 彩虹 category:公园 status:open order:latest 将搜索在“公园”分类中没有关闭或存档中的名字包含“彩虹”的主题,并按最后一个帖子的日期来排序。
    • \n
    • 彩虹 category:\"公园和花园\" in:bookmarks<;/code> 将搜索在“公园和花园”分类中已被你加过书签的且名字包含“彩虹”的主题。
    • \n
    \n

    \n" badges: - long_descriptions: - autobiographer: | - 该徽章授予给填写了用户页面并选择了用户头像的成员。让社群更多地了解你是谁以及你感兴趣的内容能帮助创造一个更好的更团结的社群。 - first_like: | - 该徽章授予给第一次使用 :heart: 按钮赞了帖子的成员。给帖子点赞是一个极好的让社群成员知道他们的帖子有意思、有用、酷炫或者好玩的方法。分享爱! - first_link: |+ - 该徽章授予给第一次在回复中包含了到另一个主题的链接。链接主题在两个主题的右侧显示连接,可以帮助阅读者迅速地找到相关讨论。 - - first_quote: | - 该徽章授予给第一次在回复中包含了到另一个主题的链接。链接主题在两个主题的右侧显示连接,可以帮助阅读者迅速地找到相关讨论。 - first_share: | - 该徽章授予给第一次用分享按钮分享了回复或者主题的链接的成员。分享链接是一个极好的方式向外部世界展示有趣的讨论的方法,并且能推动社群增长。 - read_guidelines: |+ - 该徽章授予给阅读了社群指引的成员。遵守和分享简单的指引能帮助打造一个安全、有趣和可持续的社群。 - - reader: | - 该徽章授予给阅读了一个较长的主题的成员。阅读是最基础的。详细阅读帮助你更好地了解讨论并帮助你编写更好的、更完整的回复。 - editor: | - 该徽章授予给编辑自己帖子的成员。任何时候都不要犹豫编辑你的帖子以改善他们、改正小错误或者增加你忘记的内容。 - first_flag: | - 该徽章授予给标记过帖子的用户。标记对社群的健康很重要。如果你注意到了任何需要版主注意的帖子,请不要犹豫,直接标记 它。你可能也使用了标记对话框向用户发送了消息。 - nice_share: | - 该徽章授予给分享帖子的链接至超过 25 个外部访客的成员。干得好!分享有趣的讨论给朋友是一个帮助社群成长的极好方式。 - welcome: | + editor: + name: 编辑 + description: 首次编辑帖子 + long_description: | + 该徽章授予给第一次编辑自己帖子的你。虽然你不能永远在编辑自己的帖子,但是编辑他们总是一个好办法——你可以改进你的帖子、修正小错误,或者是增补你原来没有写的内容。编辑能让你的帖子质量变得更好! + basic_user: + name: 初级用户 + description: 授予所有常用社群功能 + long_description: | + 该徽章授予给用户等级达到 1 的成员。感谢你在社群里花了一些时间并且阅读了一些帖子,了解了我们的社群。你的新用户限制已经被取消;并且你已经被授予了所有基本的社群权限,必须个人消息、标记、维基编辑和发布多张图片和多个链接的能力。 + member: + name: 成员 + description: 授予邀请、群组消息和更多的赞 + long_description: | + 该徽章授予给达到用户等级 2 的你。感谢你在社群待了几周,真正融入到了社群中。你现在可以在你的用户页或者主题中邀请他人或者创建群组消息了。每天你也可以点更多次赞了。 + regular: + name: 活跃用户 + description: 授予重分类、重命名、跟踪链接、维基功能和更多的赞 + long_description: | + 该徽章授予给达到用户等级 3 的你。感谢你在这几个月持续地参与社群。你现在是我们之中最活跃的读者之一了,你持续的贡献极大地帮助了我们的社群。你现在可以社群待了几周,真正融入到了社群中。你现在可以重新分类或者重命名主题、使用能力强大的垃圾标记功能以及访问隐藏的贵宾分类了。而且每天你可以点更多次赞了。 + leader: + name: 资深 + description: 授予全局编辑、固定、关闭、存档、分割、合并和更多的赞 + long_description: | + 该徽章授予给达到用户等级 4 的你。你被管理人员选作了社群的领导力量,你用你的行动和言辞为社群树立了正面的形象。你现在可以修改所有帖子,使用常见的版主的主题管理功能,比如置顶、关闭、隐藏、存档、分割和合并功能。你每天可以点更多的赞了。 + welcome: + name: 欢迎 + description: 得到一个赞 + long_description: | 该徽章授予给帖子收到了第一个赞的成员。恭喜,有社群成员发现你发表的内容有意思、酷炫或者有用! - anniversary: | - 该徽章授予给在社群超过一年并且这一年中至少发布了一个帖子的成员。谢谢你的关注和对我们社群的贡献! - good_share: | - 该徽章授予给分享帖子的链接至超过 300 个外部访客的成员。做得真棒!你已经把一个有意思的讨论分享给了许多新人,并且帮助了社群成长。 - great_share: | - 该徽章授予给分享帖子的链接至超过 100 个外部访客的成员。哇!你已经把一个有趣的主题分享给了许多新读者,并且帮助了社群成长。 - nice_post: |+ - 该徽章授予给创建了得到 10 个赞的回复的成员。干得好! + autobiographer: + name: 自传作者 + description: 已填写用户资料信息 + long_description: | + 该徽章授予给填写了用户页面并选择了用户头像的你。让社群成员们多了解你一点以及你感兴趣的内容,能帮助我们打造一个更好、更团结的社群。让我们一起努力! + anniversary: + name: 年度纪念日 + description: 一年活跃用户,至少发了一个帖子 + long_description: | + 该徽章授予给在社群注册一年并超至少发布了一个帖子的你。感谢你的持续关注和对我们社群的贡献!我们希望你继续参与我们的社群。 + nice_post: + name: 不错的回复 + description: 回复被赞了 10 次 + long_description: | + 该徽章授予给回复被赞了 10 次的你。你的回复给社群成员们留下了印象,并且你推动了讨论的进程! + good_post: + name: 很好的回复 + description: 回复被赞了 25 次 + long_description: | + 该徽章授予给回复被赞了 25 次的你。你的回复很杰出,这个讨论对每个人都变得更有意义了! + great_post: + name: 精彩的回复 + description: 回复被赞了 50 次 + long_description: | + 该徽章授予给回复被赞了 50 次的你。哇!你的回复很有启发、引经据典、令人冷俊不禁或者十分有内涵,整个社群都喜欢它。 + nice_topic: + name: 不错的主题 + description: 主题被赞了 10 次 + long_description: | + 该徽章授予给主题获得 10 个赞的你。嗨,你开启了一个社群成员觉得有意思的讨论! + good_topic: + name: 很好的主题 + description: 主题被赞了 25 次 + long_description: | + 该徽章授予给主题获得 25 个赞的你。你开启了一个有意义的主题,整个社群都在积极响应,而且大家喜欢你的主题! + great_topic: + name: 精彩的主题 + description: 主题被赞了 50 次 + long_description: | + 该徽章授予给主题获得 50 个赞的你。你开启了一个引人入胜的主题,整个社群都沉浸于讨论之中。 + nice_share: + name: 不错的分享 + description: 分享了一个有 25 个独立访问者的帖子 + long_description: | + 该徽章授予给分享链接给 25 个其他访客的你。感谢你广而告之我们的讨论,和对这个社群的帮助。 + good_share: + name: 很棒的分享 + description: 分享了一个有 300 个独立访问者的帖子 + long_description: | + 该徽章授予给分享链接给 300 个其他访客的你。干得漂亮!你把一个有意思的讨论介绍给了许多新的朋友,并且帮助社群前进了一步。 + great_share: + name: 精彩的分享 + description: 分享了一个有 1000 个独立访问者的帖子 + long_description: |+ + 该徽章授予给分享链接给 1000 个其他访客的你。哇!你把一个有意思的讨论推广给了广大的读者们,并且帮助社群前进了一大步! - nice_topic: | - 该徽章授予给创建了得到 10 个赞的主题的成员。干得好! - good_post: | - 该徽章授予给创建了得到 25 个赞的回复的成员。干得好! - good_topic: | - 该徽章授予给创建了得到 25 个赞的主题的成员。干得好! - great_post: | - 该徽章授予给创建了得到 50 个赞的帖子的成员。哇! - great_topic: | - 该徽章授予给创建了得到 50 个赞的回复的成员。哇! - basic: | - 该徽章授予给用户等级达到 1 的成员。感谢你在社群里花了一些时间并且阅读了一些帖子,了解了我们的社群。你的新用户限制已经被取消,并且你已经被授予了所有基本的社群权限,必须个人消息、标记、维基编辑和发布图片和多个链接的能力。 - member: | - 该徽章授予给用户等级达到 2 的成员。感谢你在社群的这几周时间。你现在已经可以在你的用户页或者主题中发送私人邀请、创建群组消息,以及每天可以赞更多次了。 - regular: | - 该徽章授予给用户等级达到 3 的成员。感谢你在社群的这几月的活跃参与,并且是我们最活跃的读者质疑,也是社群中的可靠贡献者。你现在可以重新分类和重命名主题、访问隐藏的贵宾分类、使用更多强大的防骚扰标记功能,以及每天可以赞更多次了。 - leader: | - 该徽章授予给用户等级达到 4 的成员。你是由职员选择的社群领袖,鉴于你在社群的话语和贡献,你为社群树立了一个正面的例子。你有权限编辑所有的帖子,使用主题管理操作,例如置顶、关闭、不在列表中显示、存档、分割和合并,并且可以每天点赞非常多次。 + first_like: + name: 首个赞 + description: 已赞过了一个帖子 + long_description: | + 该徽章授予给第一次使用 :heart: 按钮赞了帖子的成员。给帖子点赞是一个极好的让社群成员知道他们的帖子有意思、有用、酷炫或者好玩的方法。分享爱! + first_flag: + name: 首个标记 + description: 已标记过了一个帖子 + long_description: | + 该徽章授予给第一次标记帖子的你。标记是帮助我们帮助社群保持健康、合宜的工具。如果你注意到哪个帖子需要版主的注意,不用在乎什么原因,直接标记。如果你注意到别人帖子里的某个问题,你也可用标记功能发送私信给该成员。如果你发现了问题,:flag_black: 标记吧! + promoter: + name: 推广者 + description: 已邀请了 1 个用户 + long_description: | + 该徽章授予给邀请他人加入社群的你。你曾使用了用户页面的邀请按钮或主题底部的邀请按钮。邀请对某个讨论感兴趣的朋友是引介新人的好办法,非常感谢! + campaigner: + name: 活动家 + description: 已邀请了 3 个初级用户 + long_description: | + 该徽章授予给邀请了 3 人加入社群的你,你的朋友在站点上度过了一段时间,已经成为了初级用户。一个活跃的社群需要不断有新鲜血液的参与,这样新观点才能推进讨论进程。 + champion: + name: 外交官 + description: 已邀请了 5 个成员 + long_description: | + 该徽章授予给邀请了 5 人加入社群的你,你的朋友在站点上度过了很长的时间,已经成为了成员。哇!感谢你帮助社群成长,社群因此变得更多元了! + first_share: + name: 首次分享 + description: 已分享了一个帖子 + long_description: | + 该徽章授予给第一次用分享按钮分享了回复或者主题的链接的成员。分享链接是一个极好的方式向外部世界展示有趣的讨论的方法,并且能推动社群增长。 + first_link: + name: 首个链接 + description: 已链接了另一个主题 + long_description: | + 该徽章授予给第一次链接到另一个主题的你。联结主题会在各个主题的右侧显示链接和标题,这可以帮助阅读者迅速地找到相关讨论。多链接一些主题吧! + first_quote: + name: 首次引用 + description: 已引用过一个帖子 + long_description: | + 该徽章授予给第一次在回复中引用帖子的你。在你的回复中引用之前帖子中的相关的段落可以让讨论更有主题和重点。而且这很简单:你只要选中别的帖子中的任何文字,然后点击在旁边的“引用回复”按钮。多引用一些吧! + read_guidelines: + name: 阅读指引 + description: 阅读社群指引 + long_description: | + 该徽章授予给阅读了社群指引的你。遵守和分享简单的指引能让我们打造一个稳定、有趣和可持续的社群。永远记住别人,一个和你有很多共同点的人,就在屏幕的那一侧。友好一些! + reader: + name: 读者 + description: 阅读了有至少 100 个回复的主题中的所有回复 + long_description: | + 该徽章授予给第一次阅读了超过 100 个回复的长主题的你。仔细地阅读对话内容能让你关注到讨论的中心,理解不同的观点,而且能帮助我们打造更有趣的对话情景。你读得越多,对话的效果就会越好。就如我们常说的那般,阅读是最重要的! :slight_smile: + popular_link: + name: 流行链接 + description: 分享的链接被点击了 50 次 + long_description: | + 该徽章授予给分享的链接被点击过 50 次的你。感谢你贴出了有用的链接,这让讨论的情节更形象了! + hot_link: + name: 热门链接 + description: 分享的链接被点击了 300 次 + long_description: | + 该徽章授予给分享的链接被点击过 300 次的你。感谢你贴出了精彩的链接,这推进了讨论的进程,并且装点了讨论! + famous_link: + name: 著名链接 + description: 分享的链接被点击了 1000 次 + long_description: | + 该徽章授予给分享的链接被点击过 1000 次的你。哇!感谢你贴出了推动讨论的重要链接,这让讨论更加具体,更有情节,并且传达了跟多的信息。干的好! + appreciated: + name: 感谢 + description: 有 20 个帖子都被赞了 1 次 + long_description: | + 该徽章授予给 20 个不同的帖子都收到了至少 1 个赞的你。社群感谢你对讨论的贡献! + respected: + name: 尊敬 + description: 有 100 个帖子都被赞了 2 次 + long_description: | + 该徽章授予给 100 个不同的帖子都收到了至少 2 个赞的你。社群越来越尊重你在讨论中的贡献了。 + admired: + name: 敬仰 + description: 有 300 个帖子都被赞了 5 次 + long_description: | + 该徽章授予给 300 个不同的帖子都收到了至少 5 个赞的你。哇!社群敬仰你在讨论中频繁和高质量的贡献。 + out_of_love: + name: 热情 + description: 1 天内赞了 50 次 + long_description: | + 该徽章授予给一天内赞了 50 次的你。别忘记休息一下。赞你喜欢的帖子能鼓励成员不断改进讨论的内容。 + higher_love: + name: "激情\b" + description: 5 天都赞过 50 次 + long_description: | + 该徽章授予给 5 天赞过 50 次的你。感谢你每天都花点时间鼓励讨论的进行! + crazy_in_love: + name: 狂热 + description: 20 天都赞过 50 次 + long_description: | + 该徽章授予给 20 天赞过 50 次的你。哇!你为社群成员们树立了一个令人鼓舞的模范! + thank_you: + name: 感谢你 + description: 有 20 个被赞的帖子,给出过 10 个赞 + long_description: | + 该徽章授予给收到了 20 个赞,且赞过别人 10 次的你。当别人感谢你的帖子时,你也感谢他们的帖子。 + gives_back: + name: 回馈 + description: 有 100 个被赞的帖子,给出过 100 个赞 + long_description: | + 该徽章授予给收到了 100 个赞,且赞过别人 100 次的你。感谢你回馈赞给社群! + empathetic: + name: 感性 + description: 有 500 个被赞的帖子,给出过 1000 个赞 + long_description: | + 该徽章授予给收到了 500 个赞,且赞过别人 1000 次的你。哇!你是一个富有同情心且会换位思考的模范。 :two_hearts: admin_login: success: "邮件已发送" error: "错误!" @@ -2121,3 +2474,10 @@ zh_CN: performance_report: initial_post_raw: 这个主题包括你网站的每日性能报告 initial_topic_title: 网站性能报告 + topic_invite: + user_exists: "抱歉,用户已经被邀请了。你可能只想邀请用户参与主题一次。" + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.zh_TW.yml b/config/locales/server.zh_TW.yml index 188a26cd841..86b2e2e27a2 100644 --- a/config/locales/server.zh_TW.yml +++ b/config/locales/server.zh_TW.yml @@ -10,18 +10,23 @@ zh_TW: short_date_no_year: "D MMM" short_date: "D MMM, YYYY" long_date: "MMMM D, YYYY h:mma" + datetime_formats: &datetime_formats + formats: + short: "%Y-%m-%d" + short_no_year: "%B %-d" + date: + month_names: [null, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月] + <<: *datetime_formats title: "論壇" topics: "討論話題" posts: "文章" loading: "載入中" powered_by_html: 'Powered by Discourse, 請啟用 Javascript 以獲得最佳瀏覽效果' log_in: "登入" - via: "%{username} 自 %{site_name}" - is_reserved: "保留權利" purge_reason: "自動刪除被遺棄、未啟用賬戶" disable_remote_images_download_reason: "磁盤空間不足,圖像下載已被禁用。" anonymous: "匿名" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "限制 %{max} 個字元,你已經輸入了 %{length} 個字元" @@ -37,8 +42,10 @@ zh_TW: exclusion: 被保留 greater_than: 必須大於 %{count} greater_than_or_equal_to: 必須大於或等於 %{count} + has_already_been_used: "已經被使用" inclusion: 不包括在這列表中 invalid: 無效的 + is_invalid: "無效,請再仔細描述" less_than: 必須少於 %{count} less_than_or_equal_to: 必須少於或等於 %{count} not_a_number: 不是數字 @@ -61,6 +68,11 @@ zh_TW: other: '%{count} 個錯誤禁止 %{model} 被儲存' embed: load_from_remote: "載入文章時發生了錯誤" + site_settings: + min_username_length_exists: "你不能設比現有用戶名短的「最小用戶名長度」。" + min_username_length_range: "你不能設定「最小」大於「最大」。" + max_username_length_exists: "您不能設置比現有用戶名短的「最大用戶名長度」。" + max_username_length_range: "你不能設定「最大」小於「最小」。" bulk_invite: file_should_be_csv: "上傳的文件應為 csv 或 txt 格式。" backup: @@ -84,26 +96,6 @@ zh_TW: in_reply_to: "▶ %{username}" replies: other: "%{count} 個回覆" - too_many_mentions: - zero: "抱歉,你無法提及 (@) 其他用戶。" - one: "抱歉,你在一篇文章裡只能提及 (@) 一個用戶。" - other: "抱歉, 你在一篇文章裡只能提及 (@) %{count} 個用戶。" - too_many_mentions_newuser: - zero: "抱歉,新用戶無法提及 (@) 其他用戶。" - one: "抱歉,新用戶在一篇文章裡只能提及 (@) 一個用戶。" - other: "抱歉, 新用戶在一篇文章裡只能提及 (@) %{count} 個用戶。" - too_many_images: - zero: "抱歉, 訪客無法貼圖。" - one: "抱歉, 訪客每次只能張貼一張圖片。" - other: "抱歉, 訪客每次只能張貼 %{count} 張圖片。" - too_many_attachments: - zero: "抱歉,新用戶不可添加附件於文章中。" - one: "抱歉,新用戶在每篇文章中只能添加 1 個附件。" - other: "抱歉,新用戶在每篇文章中只能添加 %{count} 個附件。" - too_many_links: - zero: "抱歉, 訪客無法分享連結。" - one: "抱歉, 訪客每次只能貼一條連結。" - other: "抱歉, 訪客每次只能貼 %{count} 條連結。" spamming_host: "抱歉,你不能張貼該網站之連結。" user_is_suspended: "被停權的用戶無法張貼文章。" topic_not_found: "出現問題。也許這個話題被關閉或刪除。" @@ -126,12 +118,14 @@ zh_TW: rss_description: latest: "最新討論話題" hot: "熱門討論話題" + posts: " 最近文章" too_late_to_edit: "這文章建立很久了,它已經無法被編輯或刪除" excerpt_image: "圖片" groups: errors: can_not_modify_automatic: "你無法修改自動群組" member_already_exist: "'%{username}' 已經是群組成員了。" + invalid_domain: "'%{domain}' 不是有效的域名." default_names: everyone: "所有人" admins: "管理員" @@ -164,9 +158,6 @@ zh_TW: user_profile: bio_raw: "關於我" errors: - messages: - is_invalid: "無效,請嘗試寫得更明確" - has_already_been_used: "已經被使用" models: topic: attributes: @@ -187,6 +178,7 @@ zh_TW: attributes: hex: invalid: "不是一個有效顏色" + <<: *errors user_profile: no_info_me: "
    你的自我簡介中,“關於我” 部分目前還沒有內容,不如來自我介紹一下?
    " no_info_other: "
    %{name} 尚未在他/她自我簡介中的“關於我”部分填寫任何資訊
    " @@ -199,8 +191,6 @@ zh_TW: title: "歡迎來到貴賓室" category: topic_prefix: "對於分類:%{category} 的定義" - replace_paragraph: "[ 將此首段文字替換為描述新分類的簡短說明。說明將會出現在分類選擇區裡,故請盡量少於 200 個字元。在你編輯此處文字或者新增討論話題之前,此分類將不會顯示在分類頁面上。]" - post_template: "%{replace_paragraph}\n\n在下面的空格輸入分類的詳細描述, 可以包括在此分類下討論的規則、內容主題等等。" errors: uncategorized_parent: "未分類不能有一個父分類" self_parent: "一個子分類的上層不能是自己" @@ -216,15 +206,12 @@ zh_TW: title: "新用戶" basic: title: "初級用戶" - regular: + member: title: "成員" - leader: - title: "一般用戶" - elder: - title: "領先用戶" rate_limiter: - slow_down: "你已經執行這個動作太多次,請稍後再試" too_many_requests: "你的瀏覽速度過於頻繁,請等待 %{time_left} 後再試。" + by_type: + create_post: "你的回覆過快。請等待%{time_left}再重試。" hours: other: "%{count} 小時" minutes: @@ -294,6 +281,7 @@ zh_TW: please_continue: "繼續連接至 %{site_name}" error: "修改你的電郵位址時發生錯誤,可能此郵箱已有人使用了。" activation: + action: "點擊此處啟用你的帳戶" already_done: "抱歉,此帳號啟用連結已經失效。可能你的帳號已經啟用了。" please_continue: "你的新帳號已啟用;即將轉到主頁。" continue_button: "繼續連接至 %{site_name}" @@ -315,14 +303,11 @@ zh_TW: description: '此帖內容包含對他人的攻擊、侮辱、仇視語言或違反了我們的社群准則。' long_form: '投訴為不當內容' notify_user: - description: '此帖包含一些我想與該用戶私下直接交流的內容。不能執行標記操作。' + title: '給 @{{username}} 送出一則訊息' email_title: '你的文章在"%{title}"' email_body: "%{link}\n\n%{message}" notify_moderators: title: "其他" - description: '此帖需要版主按照以上未列出的原因處理。' - long_form: '向板主回報問題發文' - email_title: '一篇在 "%{title}" 裡的文章需要板主注意' email_body: "%{link}\n\n%{message}" bookmark: title: '書籤' @@ -347,7 +332,6 @@ zh_TW: long_form: '投訴為不當內容' notify_moderators: title: "其他" - description: '該主題需要版主依據社群准則服務條款(TOS)或其它未列出的原因來給予關注。' long_form: '標記為需版主注意' email_title: '此討論話題 "%{title}" 需要板主注意' email_body: "%{link}\n\n%{message}" @@ -357,6 +341,7 @@ zh_TW: regular: title: "一般討論話題" banner: + title: "討論話題橫幅" message: make: "本主題現在是橫幅主題。它將出現在每頁的頂部,除非用戶將其隱藏。" remove: "本主題已經不再是橫幅主題。它將不在每個頁面的頂部顯示。" @@ -381,6 +366,8 @@ zh_TW: title: "新用戶" xaxis: "天" yaxis: "新用戶數量" + profile_views: + xaxis: "天" topics: title: "討論話題" xaxis: "天" @@ -416,18 +403,23 @@ zh_TW: user_to_user_private_messages: title: "用戶對用戶" xaxis: "天" + yaxis: "訊息數量" system_private_messages: title: "系統" xaxis: "天" + yaxis: "訊息數量" moderator_warning_private_messages: title: "板主警告" xaxis: "天" + yaxis: "訊息數量" notify_moderators_private_messages: title: "板主通知" xaxis: "天" + yaxis: "訊息數量" notify_user_private_messages: title: "用戶通知" xaxis: "天" + yaxis: "訊息數量" top_referrers: title: "最高引用" xaxis: "用戶" @@ -459,6 +451,10 @@ zh_TW: title: "總數" xaxis: "天" yaxis: "API 請求總數" + page_view_logged_in_mobile_reqs: + xaxis: "天" + page_view_anon_mobile_reqs: + xaxis: "天" http_background_reqs: title: "後台" xaxis: "天" @@ -483,6 +479,12 @@ zh_TW: title: "總數" xaxis: "天" yaxis: "請求總數" + time_to_first_response: + xaxis: "天" + topics_with_no_response: + xaxis: "天" + mobile_visits: + xaxis: "天" dashboard: rails_env_warning: "伺服器現在運行 %{env} 模式。" ruby_version_warning: "如果你使用的 Ruby 版本是 2.0.0 ,這個版本有較多的問題,請升級至 p247 或以上的版本" @@ -504,35 +506,6 @@ zh_TW: site_description_missing: "輸入一句話作為網站的簡介,將出現在搜索結果中。在設定中更新 site_description。" consumer_email_warning: "您的網站正以Gmail或其他服務供應商郵件服務發送郵件。Gmail限制每日郵件發送數量. 請考慮使用其他電郵服務商來保證郵件能成功發送,例如 mandrill.com。" notification_email_warning: "通知郵件不是從你域名的一個有效地址發出的;電郵發送將會變得危險和不可靠。請在設定中將 notification_email 設定一個有效的本機電郵地址。" - content_types: - education_new_reply: - title: "新用戶教學:第一個回覆" - description: "在新用戶發表首兩個回覆時, 自動在編輯器上方彈出的說明資訊。" - education_new_topic: - title: "新用戶教學:第一個討論話題" - description: "在新用戶發表首兩個討論話題時,自動在編輯器上方彈出的說明資訊。" - usage_tips: - title: "新用戶指南" - description: "新用戶指引和重要信息" - welcome_user: - title: "歡迎: 新用戶" - welcome_invite: - title: "歡迎: 受邀請用戶" - login_required_welcome_message: - title: "請登入:歡迎訊息" - description: "歡迎資訊只會在已啟用'login required'時向未登入的用戶顯示" - login_required: - title: "請登入:首頁" - description: "當要求登錄時向未授權用戶顯示的文字。" - head: - title: "HTML 標頭" - description: "將在 標籤中插入的 HTML" - top: - title: "頁面頂部" - description: "將在每一個頁面頂端(在頭部之後,在導航或者主題標題前)插入的 HTML。" - bottom: - title: "頁面底部" - description: "將在 標簽前被插入的 HTML。" site_settings: censored_words: "將被自動替換為 ■■■■" delete_old_hidden_posts: "自動刪除被隱藏超過 30 天的帖子。" @@ -540,11 +513,12 @@ zh_TW: allow_user_locale: "允許用戶選擇自己的語言介面" min_post_length: "文章允許的最小文字數" min_first_post_length: "第一篇文章允許的最少文字數" + min_private_message_post_length: "文章允許的最小文字數" max_post_length: "文章允許的最大文字數" min_topic_title_length: "標題允許的最小文字數" max_topic_title_length: "標題允許的最大文字數" + min_private_message_title_length: "標題允許的最小文字數" min_search_term_length: "搜尋條件允許的最小文字數" - uncategorized_description: "\"未分類\"的分類的描述,留空則無描述" allow_duplicate_topic_titles: "允許話題有相同,重複的標題" unique_posts_mins: "使用者再次發表包含相同內容文章的間隔時間" educate_until_posts: "當用戶開始鍵入他們的前幾個 (n) 新帖子時,在編輯器上顯示教育面板視窗。" @@ -557,7 +531,6 @@ zh_TW: download_remote_images_to_local: "下載外部鏈接的圖片到本機;以防圖片損壞。" download_remote_images_threshold: "可用來下載外部圖片到本機最少的空間(百分比)" disabled_image_download_domains: "在此列表的網域名稱的遠端圖片將不會進行下載,用 | 分割多個域名" - ninja_edit_window: "在 (n) 秒內 ,文章的編輯不產生新的文章版本歷史" post_edit_time_limit: "作者可以在發表文章後的 ( n ) 分鐘內編輯或刪除他們的文章,設 0 為永遠" edit_history_visible_to_public: "允許任何人查看編輯過的帖子的舊版本。當禁用時,只有職員才能查看。" delete_removed_posts_after: "帖子被作者刪除,將在 (n) 小時後被自動刪除。如果設置為 0,帖子將被立即刪除。" @@ -613,7 +586,6 @@ zh_TW: suppress_reply_directly_above: "當帖子只有一個回覆時,不顯示回覆到該帖的回覆。" suppress_reply_when_quoting: "當帖子引用回覆時,不顯示可展開的回覆到某帖的標記。" max_reply_history: "擴展回覆到某帖時顯示的最大回覆數量" - experimental_reply_expansion: "當展開回覆到某帖時隱藏直接回覆(實驗性)" topics_per_period_in_top_summary: "預設推薦話題的顯示數量" topics_per_period_in_top_page: "在展開 \"顯示更多\" 推薦話題列表的顯示數量" redirect_users_to_top_page: "將新用戶或長時間未使用的用戶自動重新導向至熱門頁面" @@ -632,6 +604,8 @@ zh_TW: invite_passthrough_hours: "邀請號碼如已被使用,用戶仍可使用多少小時" invite_only: "已經禁止開放註冊,新的使用者必須取得其他用戶,或是管理員的邀請" login_required: "需要登入才能進入網站,不允許匿名操作" + min_username_length: "最少用戶名長度" + max_username_length: "最大用戶名長度" min_password_length: "最小密碼長度" block_common_passwords: "不允許使用 10,000 個最常用的密碼" enable_sso_provider: "在 /session/sso_provider endpoint 必須設定 sso_secret 以實現 Discourse SSO 提供方協定" @@ -669,6 +643,7 @@ zh_TW: max_bookmarks_per_day: "每個用戶每天最多能建立\"書籤\"的數量" max_edits_per_day: "每個用戶每天最大的\"編輯次數\"的數量" max_topics_per_day: "每個用戶每天最多建立\"討論話題\"的數量" + max_private_messages_per_day: "用戶每天能建立訊息的數量上限" max_invites_per_day: "每個用戶每天最多能邀請用戶的數量。" suggested_topics: "討論話題下的推薦話題數量" limit_suggested_to_category: "目前的話題下只顯示同分類的推薦話題" @@ -694,16 +669,9 @@ zh_TW: tl2_requires_likes_received: "一個初級用戶升級到信任等級2所需要獲得的讚賞數。" tl2_requires_likes_given: "初級用戶升級到信任等級2所需要付出的讚賞數。" tl2_requires_topic_reply_count: "一個初級用戶升級到信任等級2所需要回覆的主題數量。" - tl3_requires_days_visited: "在最近 100 天內升至信任等級3所需的訪問網站的天數。(0到100)" - tl3_requires_topics_replied_to: "在最近 100 天內升至信任等級3所需的回覆主題的最少數量。(0或更高)" - tl3_requires_topics_viewed: "在最近 100 天內升至信任等級3所需的創建主題的百分比。(0到100)" - tl3_requires_posts_read: "在最近 100 天內升信任等級3所需的創建帖子的百分比。(0到100)" tl3_requires_topics_viewed_all_time: "用戶升至信任等級3所需查看的最少主題數量。" tl3_requires_posts_read_all_time: "用戶升至信任等級3所需查看的最少帖子數量。" - tl3_requires_max_flagged: "用戶在最近 100 天內升至信任等級3所需的必須沒有超過 x 個帖子被 x 個不同的用戶標記數量,x為數量。(0或更高)" tl3_promotion_min_duration: "信任等級3的用戶可被降級至信任等級2前最少持續天數。" - tl3_requires_likes_given: "升至信任等級3需要在最近 100 天內所給出最少的讚。" - tl3_requires_likes_received: "升至信任等級3需要在最近 100 天內所收到最少的讚。" tl3_links_no_follow: "禁止從信任等級 3 之用戶所發表的連結中刪除 rel=nofollow 標籤" min_trust_to_create_topic: "建立話題最低所需的信任等級" min_trust_to_edit_wiki_post: "編輯被標示為維基的文章所需之最低信任等級。" @@ -761,13 +729,11 @@ zh_TW: automatically_download_gravatars: "當用戶註冊或更改EMail時下載 Gravatars 圖片" digest_topics: "EMail 摘要中顯示的最大話題數量" digest_min_excerpt_length: "EMail 摘要中每篇文章最少顯示的字元數量" - suppress_digest_email_after_days: "不發送摘要郵件給超過 (n) 天閒置的用戶。" disable_digest_emails: "禁用發送摘要郵件給所有用戶。" max_daily_gravatar_crawls: "一天內 Discourse 將自動檢查 Gravatar 自訂個人圖示的次數" public_user_custom_fields: "用戶可設定公開顯示的自定欄位白名單。" staff_user_custom_fields: "用戶可設定只給管理員顯示的自定欄位白名單。" allow_profile_backgrounds: "允許使用者上傳個人檔案背景圖片" - sequential_replies_threshold: "用戶可以在一個主題內多次回覆而不被提醒連續發送多個回覆的通知。" suppress_uncategorized_badge: "不在\"無分類\"的話題列表內顯示徽章。" invites_per_page: "默認在用戶頁顯示的邀請。" autohighlight_all_code: "即使未顯示特定語言,仍為所有預編排程式套用程式碼顏色提示" @@ -809,8 +775,6 @@ zh_TW: category: '分類' topic: '結果' user: '用戶' - sso: - account_not_approved: "帳戶正在等待驗證,完成後你將收到一封電郵提醒" original_poster: "原始作者" most_posts: "大部分文章" most_recent_poster: "當前大部分文章作者" @@ -877,11 +841,6 @@ zh_TW: subject_template: "[%{site_name}] 有可用的新版 Discourse 更新" new_version_mailer_with_notes: subject_template: "[%{site_name}] 可以升級" - flags_reminder: - flags_were_submitted: - other: "這些標記在過去 %{count} 小時內被提交。" - please_review: "請再次確認。" - post_number: "文章" flags_dispositions: disagreed: "感謝你讓我們知道。我們正在調查。" deferred: "感謝你讓我們知道。我們正在調查。" @@ -915,24 +874,8 @@ zh_TW: subject_template: "帳號已被封鎖" user_automatically_blocked: subject_template: "新用戶 %{username} 由於社群的投訴已被封鎖" - text_body_template: | - 這是一則自動產生的訊息。 - - 由於文章受到多位用戶的投訴,新用戶 [%{username}](%{base_url}%{user_url}) 已被自動封鎖。 - - 請[審查那些投訴](%{base_url}/admin/flags)。如果 %{username} 是被錯誤地封鎖,請在[該用戶的管理頁面](%{base_url}%{user_url})中點擊解鎖按鈕。 - - 此門檻可在 `block_new_user` 網站設定中更改。 spam_post_blocked: subject_template: "新用戶 %{username} 由於重複貼連結,文章已被封鎖" - text_body_template: | - 這是一則自動產生的訊息。 - - 新用戶 [%{username}](%{base_url}%{user_url}) 曾嘗試發表多篇內含連結至 %{domains} 的文章。為避免垃圾內容,那些文章已被封鎖。該用戶仍然可以發表不含連結至 %{domains} 的新文章。 - - 請[審查該用戶](%{base_url}%{user_url})。 - - 相關設定可在 `newuser_spam_host_threshold` 和 `white_listed_spam_host_domains` 網站設定中更改。 unblocked: subject_template: "帳號解除封鎖" pending_users_reminder: @@ -944,61 +887,23 @@ zh_TW: subject_pm: "[私訊]" user_notifications: previous_discussion: "之前的回覆" + in_reply_to: "回覆給" unsubscribe: title: "取消訂閱" description: "不再對這些郵件感興趣?沒問題!點擊下面按鈕來立即取消訂閱:" - reply_by_email: "要回應時,請回覆這封郵件,或在瀏覽器裡開啟 %{base_url}%{url} 網址。" - visit_link_to_respond: "要回應時,請在瀏覽器裡開啟 %{base_url}%{url} 網址。" posted_by: "由 %{username} 張貼於 %{post_date}" + user_invited_to_private_message_pm: + subject_template: "[%{site_name}] %{username} 邀請你參與討論 '%{topic_title}'" user_replied: subject_template: "[%{site_name}] %{username} 在 '%{topic_title}' 討論話題回覆了你的文章" - text_body_template: | - %{username} 在 %{site_name} 的 '%{topic_title}' 討論話題中回覆了你的文章: - - --- - %{message} - - --- - 請瀏覽 %{base_url}%{url} 來回覆。 user_quoted: subject_template: "[%{site_name}] %{username} 在 '%{topic_title}' 討論話題引用了你的內容" - text_body_template: | - %{username} 在 %{site_name} 的 '%{topic_title}' 討論話題中引用了你的內容: - - --- - %{message} - - --- - 請瀏覽 %{base_url}%{url} 來回覆。 user_mentioned: subject_template: "[%{site_name}] %{username} 在 '%{topic_title}' 討論話題提及了你" - text_body_template: | - %{username} 在 %{site_name} 的 '%{topic_title}' 討論話題中提及到了你: - - --- - %{message} - - --- - 請瀏覽 %{base_url}%{url} 來回覆。 user_posted: subject_template: "[%{site_name}] %{subject_prefix}%{username} 在 '%{topic_title}' 討論話題發表了文章" - text_body_template: | - %{username} 在 %{site_name} 的 '%{topic_title}' 討論話題中發表了文章: - - --- - %{message} - - --- - 請瀏覽 %{base_url}%{url} 來回覆。 user_posted_pm: subject_template: "[%{site_name}] [PM] %{topic_title}" - text_body_template: | - %{message} - - %{context} - - --- - %{respond_instructions} digest: why: "在你上一次於 %{last_seen_at} 訪問後,在 %{site_link} 上的摘要。" new_activity: "在你的討論話題和文章裡的動態:" @@ -1023,12 +928,6 @@ zh_TW: subject_template: "[%{site_name}] 設定密碼" account_created: subject_template: "[%{site_name}] 你的新帳號" - authorize_email: - subject_template: "[%{site_name}] 確認你的新電子郵箱位址" - text_body_template: | - 點擊下面的連結來確認你在 %{site_name} 上的新電子郵箱位址: - - %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "你已受到 %{site_name} 的認可!" signup: @@ -1040,7 +939,6 @@ zh_TW: 如果上面的連結無法點擊,請拷貝該連結並粘貼到你的流覽器的地址欄裡。 page_not_found: - title: "你請求的頁面在本論壇不存在。可能我們能幫助你找到它,或者類似的其它討論話題:" popular_topics: "熱門" recent_topics: "最近" see_more: "更多" @@ -1060,6 +958,8 @@ zh_TW: spam_hosts: "此新用戶嘗試發表多篇含有指向相同網域之連結的文章。請見網站設定中的 newuser_spam_host_threshold。" email_log: no_user: "無法找到 ID 為 %{user_id} 的使用者" + anonymous_user: "匿名用戶" + suspended_not_pm: "用戶已被停權,不是訊息" seen_recently: "用戶最近活躍" post_not_found: "無法找到 ID 為 %{post_id} 的文章" notification_already_read: "這封通知 EMail 已被讀取" @@ -1093,3 +993,10 @@ zh_TW: error: "錯誤" email_input: "管理者郵件" submit_button: "送出電子郵件" + performance_report: + initial_topic_title: 網站效能報表 + time: + <<: *datetime_formats + activemodel: + errors: + <<: *errors diff --git a/config/nginx.sample.conf b/config/nginx.sample.conf index 712b991e86a..8c2241d92b7 100644 --- a/config/nginx.sample.conf +++ b/config/nginx.sample.conf @@ -80,10 +80,20 @@ server { internal; } + # bypass rails stack with a cheap 204 for favicon.ico requests + location /favicon.ico { + return 204; + access_log off; + log_not_found off; + } + location / { root $public; add_header ETag ""; + # auth_basic on; + # auth_basic_user_file /etc/nginx/htpasswd; + location ~* assets/.*\.(eot|ttf|woff|woff2|ico)$ { expires 1y; add_header Cache-Control public; @@ -128,7 +138,6 @@ server { # # proxy_set_header DOES NOT inherit, by design, we must repeat it, # otherwise headers are not set correctly -# proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -173,7 +182,7 @@ server { # This big block is needed so we can selectively enable # acceleration for backups and avatars # see note about repetition above - location ~ ^/(letter_avatar|user_avatar|highlight-js|stylesheets|favicon/proxied) { + location ~ ^/(letter_avatar/|user_avatar|highlight-js|stylesheets|favicon/proxied) { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -192,6 +201,39 @@ server { break; } + location /letter_avatar_proxy/ { + # Don't send any client headers to the avatars service + proxy_method GET; + proxy_pass_request_headers off; + proxy_pass_request_body off; + + # Don't let cookies interrupt caching, and don't pass them to the + # client + proxy_ignore_headers "Set-Cookie"; + proxy_hide_header "Set-Cookie"; + + proxy_cache one; + proxy_cache_key $uri; + proxy_cache_valid 200 7d; + proxy_cache_valid 404 1m; + proxy_set_header Connection ""; + + proxy_pass https://avatars.discourse.org/; + break; + } + + # we need buffering off for message bus + location /message-bus/ { + proxy_set_header Host $http_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 $thescheme; + proxy_http_version 1.1; + proxy_buffering off; + proxy_pass http://discourse; + break; + } + # this means every file in public is tried first try_files $uri @discourse; } diff --git a/config/puma.rb b/config/puma.rb index 265960d9924..d472c7278f9 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,15 +1,19 @@ -# First, you need to change these below to your situation. -APP_ROOT = '/home/discourse/discourse' -num_workers = ENV["NUM_WEBS"].to_i > 0 ? ENV["NUM_WEBS"].to_i : 4 +if ENV['RAILS_ENV']=='production' -# Second, you can choose how many threads that you are going to run at same time. -workers "#{num_workers}" -threads 8,32 + # First, you need to change these below to your situation. + APP_ROOT = '/home/discourse/discourse' + num_workers = ENV["NUM_WEBS"].to_i > 0 ? ENV["NUM_WEBS"].to_i : 4 -# Unless you know what you are changing, do not change them. -bind "unix://#{APP_ROOT}/tmp/sockets/puma.sock" -stdout_redirect "#{APP_ROOT}/log/puma.log","#{APP_ROOT}/log/puma.err.log" -pidfile "#{APP_ROOT}/tmp/pids/puma.pid" -state_path "#{APP_ROOT}/tmp/pids/puma.state" -daemonize true -preload_app! + # Second, you can choose how many threads that you are going to run at same time. + workers "#{num_workers}" + threads 8,32 + + # Unless you know what you are changing, do not change them. + bind "unix://#{APP_ROOT}/tmp/sockets/puma.sock" + stdout_redirect "#{APP_ROOT}/log/puma.log","#{APP_ROOT}/log/puma.err.log" + pidfile "#{APP_ROOT}/tmp/pids/puma.pid" + state_path "#{APP_ROOT}/tmp/pids/puma.state" + daemonize true + preload_app! + +end diff --git a/config/routes.rb b/config/routes.rb index 187b51d2cd3..48e134e0d59 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,9 +7,9 @@ require_dependency "permalink_constraint" # This used to be User#username_format, but that causes a preload of the User object # and makes Guard not work properly. -USERNAME_ROUTE_FORMAT = /[A-Za-z0-9\_.\-]+/ unless defined? USERNAME_ROUTE_FORMAT +USERNAME_ROUTE_FORMAT = /[\w.\-]+/ unless defined? USERNAME_ROUTE_FORMAT -BACKUP_ROUTE_FORMAT = /[a-zA-Z0-9\-_]*\d{4}(-\d{2}){2}-\d{6}\.(tar\.gz|t?gz)/i unless defined? BACKUP_ROUTE_FORMAT +BACKUP_ROUTE_FORMAT = /[\w.\-]+\.(tar\.gz|tgz)/i unless defined? BACKUP_ROUTE_FORMAT Discourse::Application.routes.draw do @@ -20,7 +20,8 @@ Discourse::Application.routes.draw do mount Sidekiq::Web => "/sidekiq" mount Logster::Web => "/logs" else - mount Sidekiq::Web => "/sidekiq", constraints: AdminConstraint.new + # only allow sidekie in master site + mount Sidekiq::Web => "/sidekiq", constraints: AdminConstraint.new(require_master: true) mount Logster::Web => "/logs", constraints: AdminConstraint.new end @@ -60,18 +61,20 @@ Discourse::Application.routes.draw do resources :groups, constraints: AdminConstraint.new do collection do post "refresh_automatic_groups" => "groups#refresh_automatic_groups" + get 'bulk' + get 'bulk-complete' => 'groups#bulk' + put 'bulk' => 'groups#bulk_perform' end member do - put "members" => "groups#add_members" - delete "members" => "groups#remove_member" + put "owners" => "groups#add_owners" + delete "owners" => "groups#remove_owner" end end get "groups/:type" => "groups#show", constraints: AdminConstraint.new get "groups/:type/:id" => "groups#show", constraints: AdminConstraint.new - get "users/:id.json" => 'users#show' , id: USERNAME_ROUTE_FORMAT, defaults: {format: 'json'} - resources :users, id: USERNAME_ROUTE_FORMAT do + resources :users, id: USERNAME_ROUTE_FORMAT, except: [:show] do collection do get "list/:query" => "users#index" get "ip-info" => "users#ip_info" @@ -106,6 +109,9 @@ Discourse::Application.routes.draw do get "tl3_requirements" put "anonymize" end + get "users/:id.json" => 'users#show', defaults: {format: 'json'} + get 'users/:id/:username' => 'users#show' + get 'users/:id/:username/badges' => 'users#show' post "users/sync_sso" => "users#sync_sso", constraints: AdminConstraint.new @@ -113,13 +119,17 @@ Discourse::Application.routes.draw do resources :impersonate, constraints: AdminConstraint.new - resources :email do + resources :email, constraints: AdminConstraint.new do collection do post "test" - get "all" get "sent" get "skipped" + get "received" + get "rejected" + get "/incoming/:id/raw" => "email#raw_email" + get "/incoming/:id" => "email#incoming" get "preview-digest" => "email#preview_digest" + post "handle_mail" end end @@ -150,10 +160,19 @@ Discourse::Application.routes.draw do post "flags/defer/:id" => "flags#defer" resources :site_customizations, constraints: AdminConstraint.new scope "/customize" do - resources :site_texts, constraints: AdminConstraint.new - resources :site_text_types, constraints: AdminConstraint.new resources :user_fields, constraints: AdminConstraint.new resources :emojis, constraints: AdminConstraint.new + + # They have periods in their URLs often: + get 'site_texts' => 'site_texts#index' + match 'site_texts/(:id)' => 'site_texts#show', :constraints => { :id => /[0-9a-z\_\.\-]+/ }, via: :get + match 'site_texts/(:id)' => 'site_texts#update', :constraints => { :id => /[0-9a-z\_\.\-]+/ }, via: :put + match 'site_texts/(:id)' => 'site_texts#revert', :constraints => { :id => /[0-9a-z\_\.\-]+/ }, via: :delete + + get 'email_templates' => 'email_templates#index' + match 'email_templates/(:id)' => 'email_templates#show', :constraints => { :id => /[0-9a-z\_\.]+/ }, via: :get + match 'email_templates/(:id)' => 'email_templates#update', :constraints => { :id => /[0-9a-z\_\.]+/ }, via: :put + match 'email_templates/(:id)' => 'email_templates#revert', :constraints => { :id => /[0-9a-z\_\.]+/ }, via: :delete end resources :embeddable_hosts, constraints: AdminConstraint.new @@ -204,6 +223,7 @@ Discourse::Application.routes.draw do get "memory_stats"=> "diagnostics#memory_stats", constraints: AdminConstraint.new get "dump_heap"=> "diagnostics#dump_heap", constraints: AdminConstraint.new + get "dump_statement_cache"=> "diagnostics#dump_statement_cache", constraints: AdminConstraint.new end # admin namespace @@ -233,14 +253,15 @@ Discourse::Application.routes.draw do end resources :static - post "login" => "static#enter" - get "login" => "static#show", id: "login" - get "password-reset" => "static#show", id: "password_reset" - get "faq" => "static#show", id: "faq" - get "guidelines" => "static#show", id: "guidelines", as: 'guidelines' - get "tos" => "static#show", id: "tos", as: 'tos' - get "privacy" => "static#show", id: "privacy", as: 'privacy' - get "signup" => "list#latest" + post "login" => "static#enter", constraints: { format: /(json|html)/ } + get "login" => "static#show", id: "login", constraints: { format: /(json|html)/ } + get "password-reset" => "static#show", id: "password_reset", constraints: { format: /(json|html)/ } + get "faq" => "static#show", id: "faq", constraints: { format: /(json|html)/ } + get "guidelines" => "static#show", id: "guidelines", as: 'guidelines', constraints: { format: /(json|html)/ } + get "tos" => "static#show", id: "tos", as: 'tos', constraints: { format: /(json|html)/ } + get "privacy" => "static#show", id: "privacy", as: 'privacy', constraints: { format: /(json|html)/ } + get "signup" => "static#show", id: "signup", constraints: { format: /(json|html)/ } + get "login-preferences" => "static#show", id: "login", constraints: { format: /(json|html)/ } get "users/admin-login" => "users#admin_login" put "users/admin-login" => "users#admin_login" @@ -251,10 +272,11 @@ Discourse::Application.routes.draw do get "users/search/users" => "users#search_users" get "users/account-created/" => "users#account_created" get "users/password-reset/:token" => "users#password_reset" + get "users/confirm-email-token/:token" => "users#confirm_email_token", constraints: { format: 'json' } put "users/password-reset/:token" => "users#password_reset" get "users/activate-account/:token" => "users#activate_account" put "users/activate-account/:token" => "users#perform_account_activation", as: 'perform_activate_account' - get "users/authorize-email/:token" => "users#authorize_email" + get "users/authorize-email/:token" => "users_email#confirm" get "users/hp" => "users#get_honeypot_value" get "my/*path", to: 'users#my_redirect' @@ -263,13 +285,17 @@ Discourse::Application.routes.draw do get "users/:username/private-messages/:filter" => "user_actions#private_messages", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/messages" => "user_actions#private_messages", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/messages/:filter" => "user_actions#private_messages", constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/messages/group/:group_name" => "user_actions#private_messages", constraints: {username: USERNAME_ROUTE_FORMAT, group_name: USERNAME_ROUTE_FORMAT} + + get "users/:username/messages/group/:group_name/archive" => "user_actions#private_messages", constraints: {username: USERNAME_ROUTE_FORMAT, group_name: USERNAME_ROUTE_FORMAT} + get "users/:username.json" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}, defaults: {format: :json} get "users/:username" => "users#show", as: 'user', constraints: {username: USERNAME_ROUTE_FORMAT} put "users/:username" => "users#update", constraints: {username: USERNAME_ROUTE_FORMAT} put "users/:username/emails" => "users#check_emails", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/preferences" => "users#preferences", constraints: {username: USERNAME_ROUTE_FORMAT}, as: :email_preferences - get "users/:username/preferences/email" => "users#preferences", constraints: {username: USERNAME_ROUTE_FORMAT} - put "users/:username/preferences/email" => "users#change_email", constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/preferences/email" => "users_email#index", constraints: {username: USERNAME_ROUTE_FORMAT} + put "users/:username/preferences/email" => "users_email#update", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/preferences/about-me" => "users#preferences", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/preferences/badge_title" => "users#preferences", constraints: {username: USERNAME_ROUTE_FORMAT} put "users/:username/preferences/badge_title" => "users#badge_title", constraints: {username: USERNAME_ROUTE_FORMAT} @@ -281,15 +307,24 @@ Discourse::Application.routes.draw do put "users/:username/preferences/card-badge" => "users#update_card_badge", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/staff-info" => "users#staff_info", constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/summary" => "users#summary", constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/invited" => "users#invited", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/invited_count" => "users#invited_count", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/invited/:filter" => "users#invited", constraints: {username: USERNAME_ROUTE_FORMAT} post "users/action/send_activation_email" => "users#send_activation_email" + get "users/:username/summary" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} + + # user activity RSS feed + get "users/:username/activity/topics.rss" => "list#user_topics_feed", format: :rss, constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/activity.rss" => "posts#user_posts_feed", format: :rss, constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/activity" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/activity/:filter" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/badges" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/notifications" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} - get "users/:username/pending" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/notifications/:filter" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/activity/pending" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} delete "users/:username" => "users#destroy", constraints: {username: USERNAME_ROUTE_FORMAT} # The external_id constraint is to allow periods to be used in the value without becoming part of the format. ie: foo.bar.json get "users/by-external/:external_id" => "users#show", constraints: {external_id: /[^\/]+/} @@ -302,6 +337,9 @@ Discourse::Application.routes.draw do get "letter_avatar/:username/:size/:version.png" => "user_avatars#show_letter", format: false, constraints: { hostname: /[\w\.-]+/, size: /\d+/, username: USERNAME_ROUTE_FORMAT} get "user_avatar/:hostname/:username/:size/:version.png" => "user_avatars#show", format: false, constraints: { hostname: /[\w\.-]+/, size: /\d+/, username: USERNAME_ROUTE_FORMAT } + # in most production settings this is bypassed + get "letter_avatar_proxy/:version/letter/:letter/:color/:size.png" => "user_avatars#show_proxy_letter" + get "highlight-js/:hostname/:version.js" => "highlight_js#show", format: false, constraints: { hostname: /[\w\.-]+/ } get "stylesheets/:name.css" => "stylesheets#show", constraints: { name: /[a-z0-9_]+/ } @@ -310,26 +348,40 @@ Discourse::Application.routes.draw do # used to download original images get "uploads/:site/:sha" => "uploads#show", constraints: { site: /\w+/, sha: /[a-f0-9]{40}/ } - # used to dowwload attachments + # used to download attachments get "uploads/:site/original/:tree:sha" => "uploads#show", constraints: { site: /\w+/, tree: /(\w+\/)+/i, sha: /[a-f0-9]{40}/ } # used to download attachments (old route) get "uploads/:site/:id/:sha" => "uploads#show", constraints: { site: /\w+/, id: /\d+/, sha: /[a-f0-9]{16}/ } - get "posts" => "posts#latest" + get "posts" => "posts#latest", id: "latest_posts" + get "private-posts" => "posts#latest", id: "private_posts" get "posts/by_number/:topic_id/:post_number" => "posts#by_number" get "posts/:id/reply-history" => "posts#reply_history" get "posts/:username/deleted" => "posts#deleted_posts", constraints: {username: USERNAME_ROUTE_FORMAT} get "posts/:username/flagged" => "posts#flagged_posts", constraints: {username: USERNAME_ROUTE_FORMAT} resources :groups do + get "posts.rss" => "groups#posts_feed", format: :rss + get "mentions.rss" => "groups#mentions_feed", format: :rss + get 'members' get 'posts' + get 'topics' + get 'mentions' + get 'messages' get 'counts' - put "members" => "groups#add_members" - delete "members/:username" => "groups#remove_member" + member do + put "members" => "groups#add_members" + delete "members" => "groups#remove_member" + post "notifications" => "groups#set_notifications" + end end + # aliases so old API code works + delete "admin/groups/:id/members" => "groups#remove_member", constraints: AdminConstraint.new + put "admin/groups/:id/members" => "groups#add_members", constraints: AdminConstraint.new + # In case people try the wrong URL get '/group/:id', to: redirect('/groups/%{id}') get '/group/:id/members', to: redirect('/groups/%{id}/members') @@ -345,6 +397,7 @@ Discourse::Application.routes.draw do get "revisions/:revision" => "posts#revisions", constraints: { revision: /\d+/ } put "revisions/:revision/hide" => "posts#hide_revision", constraints: { revision: /\d+/ } put "revisions/:revision/show" => "posts#show_revision", constraints: { revision: /\d+/ } + put "revisions/:revision/revert" => "posts#revert", constraints: { revision: /\d+/ } put "recover" collection do delete "destroy_many" @@ -365,6 +418,7 @@ Discourse::Application.routes.draw do get "excerpt" => "excerpt#show" + resources :post_action_users resources :post_actions do collection do get "users" @@ -387,15 +441,18 @@ Discourse::Application.routes.draw do put "category/:category_id/slug" => "categories#update_slug" get "c/:id/show" => "categories#show" + get "c/:category_slug/find_by_slug" => "categories#find_by_slug" + get "c/:parent_category_slug/:category_slug/find_by_slug" => "categories#find_by_slug" get "c/:category.rss" => "list#category_feed", format: :rss get "c/:parent_category/:category.rss" => "list#category_feed", format: :rss get "c/:category" => "list#category_latest" get "c/:category/none" => "list#category_none_latest" - get "c/:parent_category/:category" => "list#parent_category_category_latest" + get "c/:parent_category/:category/(:id)" => "list#parent_category_category_latest", constraints: { id: /\d+/ } get "c/:category/l/top" => "list#category_top", as: "category_top" get "c/:category/none/l/top" => "list#category_none_top", as: "category_none_top" get "c/:parent_category/:category/l/top" => "list#parent_category_category_top", as: "parent_category_category_top" + get "category_hashtags/check" => "category_hashtags#check" TopTopic.periods.each do |period| get "top/#{period}" => "list#top_#{period}" @@ -426,6 +483,8 @@ Discourse::Application.routes.draw do post "t" => "topics#create" put "t/:id" => "topics#update" delete "t/:id" => "topics#destroy" + put "t/:id/archive-message" => "topics#archive_message" + put "t/:id/move-to-inbox" => "topics#move_to_inbox" put "topics/bulk" put "topics/reset-new" => 'topics#reset_new' post "topics/timings" @@ -437,13 +496,24 @@ Discourse::Application.routes.draw do get "topics/created-by/:username" => "list#topics_by", as: "topics_by", constraints: {username: USERNAME_ROUTE_FORMAT} get "topics/private-messages/:username" => "list#private_messages", as: "topics_private_messages", constraints: {username: USERNAME_ROUTE_FORMAT} get "topics/private-messages-sent/:username" => "list#private_messages_sent", as: "topics_private_messages_sent", constraints: {username: USERNAME_ROUTE_FORMAT} + get "topics/private-messages-archive/:username" => "list#private_messages_archive", as: "topics_private_messages_archive", constraints: {username: USERNAME_ROUTE_FORMAT} get "topics/private-messages-unread/:username" => "list#private_messages_unread", as: "topics_private_messages_unread", constraints: {username: USERNAME_ROUTE_FORMAT} + get "topics/private-messages-group/:username/:group_name.json" => "list#private_messages_group", as: "topics_private_messages_group", constraints: { + username: USERNAME_ROUTE_FORMAT, + group_name: USERNAME_ROUTE_FORMAT + } + + get "topics/private-messages-group/:username/:group_name/archive.json" => "list#private_messages_group_archive", as: "topics_private_messages_group_archive", constraints: { + username: USERNAME_ROUTE_FORMAT, + group_name: USERNAME_ROUTE_FORMAT + } get 'embed/comments' => 'embed#comments' get 'embed/count' => 'embed#count' get 'embed/info' => 'embed#info' get "new-topic" => "list#latest" + get "new-message" => "list#latest" # Topic routes get "t/id_for/:slug" => "topics#id_for_slug" @@ -534,6 +604,7 @@ Discourse::Application.routes.draw do get "favicon/proxied" => "static#favicon", format: false get "robots.txt" => "robots_txt#index" + get "manifest.json" => "manifest_json#index", as: :manifest Discourse.filters.each do |filter| root to: "list##{filter}", constraints: HomePageConstraint.new("#{filter}"), :as => "list_#{filter}" diff --git a/config/site_settings.yml b/config/site_settings.yml index cff228d7d9b..3a4bc825fc2 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -64,6 +64,9 @@ basic: allow_user_locale: client: true default: false + set_locale_from_accept_language_header: + default: false + validator: "AllowUserLocaleEnabledValidator" suggested_topics: client: true default: 5 @@ -164,6 +167,16 @@ basic: topics_per_period_in_top_page: default: 50 min: 1 + top_page_default_timeframe: + default: 'yearly' + type: enum + choices: + - all + - yearly + - quarterly + - monthly + - weekly + - daily category_featured_topics: client: true default: 3 @@ -222,6 +235,15 @@ login: twitter_consumer_secret: default: '' regex: "^[a-zA-Z0-9_+-]+$" + enable_instagram_logins: + client: true + default: false + instagram_consumer_key: + default: '' + regex: "^[a-z0-9]+$" + instagram_consumer_secret: + default: '' + regex: "^[a-z0-9]+$" enable_facebook_logins: client: true default: false @@ -261,6 +283,9 @@ login: type: list forgot_password_strict: false log_out_strict: true + pending_users_reminder_delay: + min: -1 + default: 8 users: min_username_length: @@ -277,7 +302,11 @@ users: default: "admin|moderator|administrator|mod|sys|system|community|info|you|name|username|user|nickname|discourse|discourseorg|discourseforum|support" min_password_length: client: true - default: 8 + default: 10 + min: 1 + min_admin_password_length: + client: true + default: 15 min: 1 block_common_passwords: true enforce_global_nicknames: @@ -312,9 +341,11 @@ users: show_email_on_profile: client: true default: false - email_token_valid_hours: 24 + email_token_valid_hours: + default: 24 + min: 1 email_token_grace_period_hours: 0 - purge_unactivated_users_grace_period_days: 7 + purge_unactivated_users_grace_period_days: 14 public_user_custom_fields: type: list default: '' @@ -332,6 +363,9 @@ users: client: true anonymous_account_duration_minutes: default: 10080 + hide_user_profiles_from_public: + default: false + client: true posting: min_post_length: @@ -362,7 +396,9 @@ posting: max_topic_title_length: client: true default: 255 + max: 255 title_min_entropy: 10 + allow_uppercase_posts: false title_prettify: true title_fancy_entities: true min_private_message_title_length: @@ -372,7 +408,6 @@ posting: client: true default: true refresh: true - uncategorized_description: "Topics that don't need a category, or don't fit into any other existing category." allow_duplicate_topic_titles: false min_title_similar_length: client: true @@ -383,7 +418,7 @@ posting: enable_private_messages: default: true client: true - ninja_edit_window: 300 + editing_grace_period: 300 post_edit_time_limit: 86400 edit_history_visible_to_public: client: true @@ -409,11 +444,9 @@ posting: max_reply_history: default: 1 client: true - experimental_reply_expansion: - default: false - client: true post_undo_action_window_mins: 10 max_mentions_per_post: 10 + max_users_notified_per_group_mention: 100 newuser_max_replies_per_topic: 3 newuser_max_mentions_per_post: 2 title_max_word_length: 30 @@ -474,20 +507,30 @@ email: email_time_window_mins: default: 10 client: true + private_email_time_window_seconds: 20 email_posts_context: 5 digest_min_excerpt_length: 100 digest_topics: 20 - suppress_digest_email_after_days: 365 + delete_digest_email_after_days: 365 + digest_suppress_categories: + type: category_list + default: '' disable_digest_emails: default: false client: true email_custom_headers: 'Auto-Submitted: auto-generated' email_subject: '[%{site_name}] %{optional_pm}%{optional_cat}%{topic_title}' - reply_by_email_enabled: false + reply_by_email_enabled: + default: false + validator: "ReplyByEmailEnabledValidator" reply_by_email_address: default: '' validator: "ReplyByEmailAddressValidator" - pop3_polling_enabled: false + manual_polling_enabled: + default: false + pop3_polling_enabled: + default: false + validator: "POP3PollingEnabledSettingValidator" pop3_polling_ssl: true pop3_polling_period_mins: 5 pop3_polling_host: '' @@ -508,6 +551,17 @@ email: client: true strip_images_from_short_emails: true short_email_length: 2800 + display_name_on_email_from: + default: true + unsubscribe_via_email: + default: true + unsubscribe_via_email_footer: + default: false + delete_email_logs_after_days: + default: 365 + min: 0 + max_emails_per_day_per_user: 100 + enable_staged_users: true files: max_image_size_kb: 3072 @@ -580,9 +634,12 @@ files: client: true shadowed_by_global: true external_system_avatars_url: - default: "https://avatars.discourse.org/letter/{first_letter}/{color}/{size}.png" + default: "/letter_avatar_proxy/v2/letter/{first_letter}/{color}/{size}.png" client: true - regex: '^https?:\/\/.+[^\/]' + regex: '^((https?:)?\/)?\/.+[^\/]' + shadowed_by_global: true + default_opengraph_image_url: '' + allow_all_attachments_for_group_messages: false trust: default_trust_level: @@ -597,6 +654,12 @@ trust: min_trust_to_edit_wiki_post: default: 1 enum: 'TrustLevelSetting' + min_trust_to_allow_self_wiki: + default: 3 + enum: 'TrustLevelSetting' + min_trust_to_send_messages: + default: 1 + enum: 'TrustLevelSetting' tl1_requires_topics_entered: 5 tl1_requires_read_posts: default: 30 @@ -609,10 +672,12 @@ trust: tl2_requires_likes_received: 1 tl2_requires_likes_given: 1 tl2_requires_topic_reply_count: 3 + tl3_time_period: + default: 100 + min: 1 tl3_requires_days_visited: default: 50 min: 0 - max: 100 tl3_requires_topics_replied_to: default: 10 min: 0 @@ -656,6 +721,9 @@ security: cors_origins: default: '' type: list + use_admin_ip_whitelist: + default: false + client: true onebox: enable_flash_video_onebox: false @@ -714,6 +782,14 @@ rate_limits: tl2_additional_likes_per_day_multiplier: 1.5 tl3_additional_likes_per_day_multiplier: 2 tl4_additional_likes_per_day_multiplier: 3 + alert_admins_if_errors_per_minute: + client: true + shadowed_by_global: true + default: 0 + alert_admins_if_errors_per_hour: + client: true + shadowed_by_global: true + default: 0 developer: force_hostname: @@ -758,10 +834,19 @@ developer: verbose_localization: default: false client: true + top_topics_formula_log_views_multiplier: + default: 2 + min: 0 + top_topics_formula_first_post_likes_multiplier: + default: 0.5 + min: 0 + top_topics_formula_least_likes_per_post_multiplier: + default: 3 + min: 0 migrate_to_new_scheme: hidden: true default: false - max_tracked_new_unread: + max_new_topics: default: 500 client: true hidden: true @@ -792,6 +877,9 @@ embedding: embed_blacklist_selector: default: '' hidden: true + embed_classname_whitelist: + default: 'emoji' + hidden: true legal: tos_url: @@ -809,7 +897,7 @@ backups: default: false maximum_backups: client: true - default: 7 + default: 5 shadowed_by_global: true automatic_backups_enabled: default: true @@ -826,6 +914,12 @@ backups: default: '' regex: "^[^A-Z_.]+$" # can't use '.' when using HTTPS shadowed_by_global: true + s3_disable_cleanup: + default: false + backup_time_of_day: + default: '3:30' + regex: "^((0?(0|1|2|3|4|5|6|7|8|9)|(10|11|12|13|14|15|16|17|18|19|20|21|22|23))):\\d\\d$" + backup_with_uploads: true uncategorized: version_checks: @@ -850,12 +944,15 @@ uncategorized: min_search_term_length: client: true default: 3 + + search_tokenize_chinese_japanese_korean: false max_similar_results: 5 minimum_topics_similar: 50 previous_visit_timeout_hours: 1 staff_like_weight: 3 topic_view_duration_hours: 8 + user_profile_view_duration_hours: 8 # Summary mode summary_score_threshold: 15 @@ -912,6 +1009,7 @@ uncategorized: educate_until_posts: 2 sequential_replies_threshold: 2 dominating_topic_minimum_percent: 20 + disable_avatar_education_message: false # Reporting daily_performance_report: false @@ -978,18 +1076,31 @@ uncategorized: default: -1 hidden: true - show_logout_in_header: - default: false + automatically_unpin_topics: + default: true + client: true + + read_time_word_count: + default: 500 client: true user_preferences: default_email_digest_frequency: enum: 'DigestEmailSiteSetting' - default: 7 + default: 10080 + default_include_tl0_in_digests: false default_email_private_messages: true default_email_direct: true default_email_mailing_list_mode: false + disable_mailing_list_mode: + default: false + client: true default_email_always: false + default_email_previous_replies: + enum: 'PreviousRepliesSiteSetting' + default: 2 + default_email_in_reply_to: + default: true default_other_new_topic_duration_minutes: enum: 'NewTopicDurationSiteSetting' @@ -1002,6 +1113,13 @@ user_preferences: default_other_dynamic_favicon: false default_other_disable_jump_reply: false default_other_edit_history_public: false + default_other_like_notification_frequency: + enum: 'LikeNotificationFrequencySiteSetting' + default: 1 + + default_topics_automatic_unpin: + default: true + client: true default_categories_watching: type: category_list diff --git a/db/fixtures/006_badges.rb b/db/fixtures/006_badges.rb index c96c0572ee4..bb2e9fba0f9 100644 --- a/db/fixtures/006_badges.rb +++ b/db/fixtures/006_badges.rb @@ -134,7 +134,8 @@ Badge.seed do |b| b.target_posts = true b.show_posts = false b.query = Badge::Queries::FirstFlag - b.default_badge_grouping_id = BadgeGrouping::Community + b.badge_grouping_id = BadgeGrouping::GettingStarted + b.default_badge_grouping_id = BadgeGrouping::GettingStarted b.trigger = Badge::Trigger::PostAction b.auto_revoke = false b.system = true @@ -228,7 +229,8 @@ Badge.seed do |b| b.badge_type_id = BadgeType::Bronze b.multiple_grant = false b.query = Badge::Queries::Editor - b.default_badge_grouping_id = BadgeGrouping::Community + b.badge_grouping_id = BadgeGrouping::GettingStarted + b.default_badge_grouping_id = BadgeGrouping::GettingStarted b.trigger = Badge::Trigger::PostRevision b.system = true end @@ -285,13 +287,77 @@ end b.target_posts = true b.show_posts = true b.query = Badge::Queries.linking_badge(count) - b.default_badge_grouping_id = BadgeGrouping::Community + b.badge_grouping_id = BadgeGrouping::Posting + b.default_badge_grouping_id = BadgeGrouping::Posting # don't trigger for now, its too expensive b.trigger = Badge::Trigger::None b.system = true end end +[ + [Badge::Appreciated, "Appreciated", BadgeType::Bronze, 1, 20], + [Badge::Respected, "Respected", BadgeType::Silver, 2, 100], + [Badge::Admired, "Admired", BadgeType::Gold, 5, 300], +].each do |spec| + id, name, level, like_count, post_count = spec + Badge.seed do |b| + b.id = id + b.name = name + b.default_name = name + b.default_icon = "fa-heart" + b.badge_type_id = level + b.query = Badge::Queries.liked_posts(post_count, like_count) + b.default_badge_grouping_id = BadgeGrouping::Community + b.trigger = Badge::Trigger::None + b.auto_revoke = false + b.system = true + end +end + + +[ + [Badge::ThankYou, "Thank You", BadgeType::Bronze, 20, 10], + [Badge::GivesBack, "Gives Back", BadgeType::Silver, 100, 100], + [Badge::Empathetic, "Empathetic", BadgeType::Gold, 500, 1000] +].each do |spec| + id, name, level, count, ratio = spec + Badge.seed do |b| + b.id = id + b.default_name = name + b.default_icon = "fa-heart" + b.badge_type_id = level + b.query = Badge::Queries.liked_back(count, ratio) + b.badge_grouping_id = BadgeGrouping::Community + b.default_badge_grouping_id = BadgeGrouping::Community + b.trigger = Badge::Trigger::None + b.auto_revoke = false + b.system = true + end +end + +[ + [Badge::OutOfLove, "Out of Love", BadgeType::Bronze, 1], + [Badge::HigherLove, "Higher Love", BadgeType::Silver, 5], + [Badge::CrazyInLove, "Crazy in Love", BadgeType::Gold, 20], +].each do |spec| + id, name, level, count = spec + Badge.seed do |b| + b.id = id + b.name = name + b.default_name = name + b.default_icon = "fa-heart" + b.badge_type_id = level + b.query = Badge::Queries.like_rate_limit(count) + b.badge_grouping_id = BadgeGrouping::Community + b.default_badge_grouping_id = BadgeGrouping::Community + b.trigger = Badge::Trigger::None + b.auto_revoke = false + b.system = true + end +end + + Badge.where("NOT system AND id < 100").each do |badge| new_id = [Badge.maximum(:id) + 1, 100].max old_id = badge.id diff --git a/db/fixtures/009_users.rb b/db/fixtures/009_users.rb index 7effb73775a..d65c8f2ef73 100644 --- a/db/fixtures/009_users.rb +++ b/db/fixtures/009_users.rb @@ -16,14 +16,54 @@ User.seed do |u| u.active = true u.admin = true u.moderator = true - u.email_direct = false u.approved = true - u.email_private_messages = false u.trust_level = TrustLevel[4] end +UserOption.where(user_id: -1).update_all( + email_private_messages: false, + email_direct: false +) + Group.user_trust_level_change!(-1, TrustLevel[4]) +# 60 minutes after our migration runs we need to exectue this code... +duration = Rails.env.production? ? 60 : 0 +if User.exec_sql("SELECT 1 FROM schema_migration_details + WHERE EXISTS( + SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'users' AND column_name = 'last_redirected_to_top_at' + ) AND + name = 'MoveTrackingOptionsToUserOptions' AND + created_at < (current_timestamp at time zone 'UTC' - interval '#{duration} minutes') + ").to_a.length > 0 + + + User.transaction do + STDERR.puts "Removing superflous user columns!" + %w[ + email_always + mailing_list_mode + email_digests + email_direct + email_private_messages + external_links_in_new_tab + enable_quoting + dynamic_favicon + disable_jump_reply + edit_history_public + automatically_unpin_topics + digest_after_days + auto_track_topics_after_msecs + new_topic_duration_minutes + last_redirected_to_top_at +].each do |column| + User.exec_sql("ALTER TABLE users DROP column IF EXISTS #{column}") + end + + end +end + # User for the smoke tests if ENV["SMOKE"] == "1" smoke_user = User.seed do |u| @@ -33,19 +73,18 @@ if ENV["SMOKE"] == "1" u.username_lower = "smoke_user" u.email = "smoke_user@discourse.org" u.password = "P4ssw0rd" - u.email_direct = false - u.email_digests = false - u.email_private_messages = false u.active = true u.approved = true u.approved_at = Time.now u.trust_level = TrustLevel[3] end.first - EmailToken.seed do |et| - et.id = 1 - et.user_id = smoke_user.id - et.email = smoke_user.email - et.confirmed = true - end + UserOption.where(user_id: smoke_user.id).update_all( + email_direct: false, + email_digests: false, + email_private_messages: false, + ) + + EmailToken.where(user_id: smoke_user.id).update_all(confirmed: true) end + diff --git a/db/fixtures/999_topics.rb b/db/fixtures/999_topics.rb index 0f813877b3c..cfe48615bcc 100644 --- a/db/fixtures/999_topics.rb +++ b/db/fixtures/999_topics.rb @@ -32,11 +32,9 @@ unless Rails.env.test? company_name: "company_short_name" }) - create_static_page_topic('guidelines_topic_id', 'guidelines_topic.title', "guidelines_topic.body", - (SiteText.text_for(:faq) rescue nil), staff, "guidelines") + create_static_page_topic('guidelines_topic_id', 'guidelines_topic.title', "guidelines_topic.body", nil, staff, "guidelines") - create_static_page_topic('privacy_topic_id', 'privacy_topic.title', "privacy_topic.body", - (SiteText.text_for(:privacy_policy) rescue nil), staff, "privacy policy") + create_static_page_topic('privacy_topic_id', 'privacy_topic.title', "privacy_topic.body", nil, staff, "privacy policy") end if seed_welcome_topics diff --git a/db/migrate/20000225050318_add_schema_migration_details.rb b/db/migrate/20000225050318_add_schema_migration_details.rb new file mode 100644 index 00000000000..dbf4959b173 --- /dev/null +++ b/db/migrate/20000225050318_add_schema_migration_details.rb @@ -0,0 +1,30 @@ +class AddSchemaMigrationDetails < ActiveRecord::Migration + def up + # schema_migrations table is way too thin, does not give info about + # duration of migration or the date it happened, this migration together with the + # monkey patch adds a lot of information to the migration table + + create_table :schema_migration_details do |t| + t.string :version, null: false + t.string :name + t.string :hostname + t.string :git_version + t.string :rails_version + t.integer :duration + t.string :direction # this really should be a pg enum type but annoying to wire up for little gain + t.datetime :created_at, null: false + end + + add_index :schema_migration_details, [:version] + + execute("INSERT INTO schema_migration_details(version, created_at) + SELECT version, current_timestamp + FROM schema_migrations + ORDER BY version + ") + end + + def down + drop_table :schema_migration_details + end +end diff --git a/db/migrate/20140120155706_add_lounge_category.rb b/db/migrate/20140120155706_add_lounge_category.rb index 140d0856ed9..b43b8b97e10 100644 --- a/db/migrate/20140120155706_add_lounge_category.rb +++ b/db/migrate/20140120155706_add_lounge_category.rb @@ -1,6 +1,8 @@ class AddLoungeCategory < ActiveRecord::Migration def up - unless Rails.env.test? + return if Rails.env.test? + + I18n.overrides_disabled do result = Category.exec_sql "SELECT 1 FROM site_settings where name = 'lounge_category_id'" if result.count == 0 description = I18n.t('vip_category_description') diff --git a/db/migrate/20140122043508_add_meta_category.rb b/db/migrate/20140122043508_add_meta_category.rb index ae63c48edb1..1e17de6f463 100644 --- a/db/migrate/20140122043508_add_meta_category.rb +++ b/db/migrate/20140122043508_add_meta_category.rb @@ -1,6 +1,8 @@ class AddMetaCategory < ActiveRecord::Migration def up - unless Rails.env.test? + return if Rails.env.test? + + I18n.overrides_disabled do result = Category.exec_sql "SELECT 1 FROM site_settings where name = 'meta_category_id'" if result.count == 0 description = I18n.t('meta_category_description') diff --git a/db/migrate/20140227201005_add_staff_category.rb b/db/migrate/20140227201005_add_staff_category.rb index 74d96405b75..c8b7075b303 100644 --- a/db/migrate/20140227201005_add_staff_category.rb +++ b/db/migrate/20140227201005_add_staff_category.rb @@ -1,6 +1,8 @@ class AddStaffCategory < ActiveRecord::Migration def up - unless Rails.env.test? + return if Rails.env.test? + + I18n.overrides_disabled do result = Category.exec_sql "SELECT 1 FROM site_settings where name = 'staff_category_id'" if result.count == 0 description = I18n.t('staff_category_description') diff --git a/db/migrate/20140929204155_migrate_tos_setting.rb b/db/migrate/20140929204155_migrate_tos_setting.rb index 950d6ac641a..4e313c0373b 100644 --- a/db/migrate/20140929204155_migrate_tos_setting.rb +++ b/db/migrate/20140929204155_migrate_tos_setting.rb @@ -2,7 +2,12 @@ class MigrateTosSetting < ActiveRecord::Migration def up res = execute("SELECT * FROM site_settings WHERE name = 'tos_accept_required' AND value = 't'") if res.present? && res.cmd_tuples > 0 - label = I18n.t("terms_of_service.signup_form_message") + label = nil + + I18n.overrides_disabled do + label = I18n.t("terms_of_service.signup_form_message") + end + res = execute("SELECT value FROM site_texts WHERE text_type = 'tos_signup_form_message'") if res.present? && res.cmd_tuples == 1 label = res[0]['value'] diff --git a/db/migrate/20141014191645_fix_tos_name.rb b/db/migrate/20141014191645_fix_tos_name.rb index ff8ac0aa18e..56059dd95f9 100644 --- a/db/migrate/20141014191645_fix_tos_name.rb +++ b/db/migrate/20141014191645_fix_tos_name.rb @@ -1,6 +1,8 @@ class FixTosName < ActiveRecord::Migration def up - execute ActiveRecord::Base.sql_fragment('UPDATE user_fields SET name = ? WHERE name = ?', I18n.t('terms_of_service.title'), I18n.t("terms_of_service.signup_form_message")) + I18n.overrides_disabled do + execute ActiveRecord::Base.sql_fragment('UPDATE user_fields SET name = ? WHERE name = ?', I18n.t('terms_of_service.title'), I18n.t("terms_of_service.signup_form_message")) + end end end diff --git a/db/migrate/20150728210202_migrate_old_moderator_posts.rb b/db/migrate/20150728210202_migrate_old_moderator_posts.rb index eeeaf7f9000..a741854b0a1 100644 --- a/db/migrate/20150728210202_migrate_old_moderator_posts.rb +++ b/db/migrate/20150728210202_migrate_old_moderator_posts.rb @@ -1,9 +1,11 @@ class MigrateOldModeratorPosts < ActiveRecord::Migration def migrate_key(action_code) - text = I18n.t("topic_statuses.#{action_code.gsub('.', '_')}") + I18n.overrides_disabled do + text = I18n.t("topic_statuses.#{action_code.gsub('.', '_')}") - execute "UPDATE posts SET action_code = '#{action_code}', raw = '', cooked = '', post_type = 3 where post_type = 2 AND raw = #{ActiveRecord::Base.connection.quote(text)}" + execute "UPDATE posts SET action_code = '#{action_code}', raw = '', cooked = '', post_type = 3 where post_type = 2 AND raw = #{ActiveRecord::Base.connection.quote(text)}" + end end def up diff --git a/db/migrate/20150729150523_migrate_auto_close_posts.rb b/db/migrate/20150729150523_migrate_auto_close_posts.rb index 26c2db812c1..d00ec9623ad 100644 --- a/db/migrate/20150729150523_migrate_auto_close_posts.rb +++ b/db/migrate/20150729150523_migrate_auto_close_posts.rb @@ -1,16 +1,18 @@ class MigrateAutoClosePosts < ActiveRecord::Migration def up - strings = [] - %w(days hours lastpost_days lastpost_hours lastpost_minutes).map do |k| - strings << I18n.t("topic_statuses.autoclosed_enabled_#{k}.one") - strings << I18n.t("topic_statuses.autoclosed_enabled_#{k}.other").sub("%{count}", "\\d+") + I18n.overrides_disabled do + strings = [] + %w(days hours lastpost_days lastpost_hours lastpost_minutes).map do |k| + strings << I18n.t("topic_statuses.autoclosed_enabled_#{k}.one") + strings << I18n.t("topic_statuses.autoclosed_enabled_#{k}.other").sub("%{count}", "\\d+") + end + + sql = "UPDATE posts SET action_code = 'autoclosed.enabled', post_type = 3 " + sql << "WHERE post_type = 2 AND (" + sql << strings.map {|s| "raw ~* #{ActiveRecord::Base.connection.quote(s)}" }.join(' OR ') + sql << ")" + + execute sql end - - sql = "UPDATE posts SET action_code = 'autoclosed.enabled', post_type = 3 " - sql << "WHERE post_type = 2 AND (" - sql << strings.map {|s| "raw ~* #{ActiveRecord::Base.connection.quote(s)}" }.join(' OR ') - sql << ")" - - execute sql end end diff --git a/db/migrate/20150914021445_create_user_profile_views.rb b/db/migrate/20150914021445_create_user_profile_views.rb new file mode 100644 index 00000000000..04c085a53bb --- /dev/null +++ b/db/migrate/20150914021445_create_user_profile_views.rb @@ -0,0 +1,15 @@ +class CreateUserProfileViews < ActiveRecord::Migration + def change + create_table :user_profile_views do |t| + t.integer :user_profile_id, null: false + t.datetime :viewed_at, null: false + t.inet :ip_address, null: false + t.integer :user_id + end + + add_index :user_profile_views, :user_profile_id + add_index :user_profile_views, :user_id + add_index :user_profile_views, [:viewed_at, :ip_address, :user_profile_id], where: "user_id IS NULL", unique: true, name: 'unique_profile_view_ip' + add_index :user_profile_views, [:viewed_at, :user_id, :user_profile_id], where: "user_id IS NOT NULL", unique: true, name: 'unique_profile_view_user' + end +end diff --git a/db/migrate/20150914034541_add_views_to_user_profile.rb b/db/migrate/20150914034541_add_views_to_user_profile.rb new file mode 100644 index 00000000000..3a13f6c1366 --- /dev/null +++ b/db/migrate/20150914034541_add_views_to_user_profile.rb @@ -0,0 +1,5 @@ +class AddViewsToUserProfile < ActiveRecord::Migration + def change + add_column :user_profiles, :views, :integer, default: 0, null: false + end +end diff --git a/db/migrate/20150917071017_add_category_id_to_user_histories.rb b/db/migrate/20150917071017_add_category_id_to_user_histories.rb new file mode 100644 index 00000000000..117edef54af --- /dev/null +++ b/db/migrate/20150917071017_add_category_id_to_user_histories.rb @@ -0,0 +1,6 @@ +class AddCategoryIdToUserHistories < ActiveRecord::Migration + def change + add_column :user_histories, :category_id, :integer + add_index :user_histories, :category_id + end +end diff --git a/db/migrate/20150924022040_add_fancy_title_to_topic.rb b/db/migrate/20150924022040_add_fancy_title_to_topic.rb new file mode 100644 index 00000000000..49863f89f5d --- /dev/null +++ b/db/migrate/20150924022040_add_fancy_title_to_topic.rb @@ -0,0 +1,5 @@ +class AddFancyTitleToTopic < ActiveRecord::Migration + def change + add_column :topics, :fancy_title, :string, limit: 400, null: true + end +end diff --git a/db/migrate/20151103233815_add_lower_title_index_on_topics.rb b/db/migrate/20151103233815_add_lower_title_index_on_topics.rb new file mode 100644 index 00000000000..bdd93fd5339 --- /dev/null +++ b/db/migrate/20151103233815_add_lower_title_index_on_topics.rb @@ -0,0 +1,9 @@ +class AddLowerTitleIndexOnTopics < ActiveRecord::Migration + def up + execute "CREATE INDEX index_topics_on_lower_title ON topics (LOWER(title))" + end + + def down + execute "DROP INDEX index_topics_on_lower_title" + end +end diff --git a/db/migrate/20151105181635_add_staged_to_user.rb b/db/migrate/20151105181635_add_staged_to_user.rb new file mode 100644 index 00000000000..16d7984a7a8 --- /dev/null +++ b/db/migrate/20151105181635_add_staged_to_user.rb @@ -0,0 +1,5 @@ +class AddStagedToUser < ActiveRecord::Migration + def change + add_column :users, :staged, :boolean, null: false, default: false + end +end diff --git a/db/migrate/20151107041044_fix_incorrect_topic_creator_after_move.rb b/db/migrate/20151107041044_fix_incorrect_topic_creator_after_move.rb new file mode 100644 index 00000000000..e7ffdf0491a --- /dev/null +++ b/db/migrate/20151107041044_fix_incorrect_topic_creator_after_move.rb @@ -0,0 +1,12 @@ +class FixIncorrectTopicCreatorAfterMove < ActiveRecord::Migration + def up + execute "UPDATE topics SET user_id = p.user_id + FROM posts p + WHERE p.topic_id = topics.id AND + p.post_number = 1 AND + p.user_id <> topics.user_id" + end + + def down + end +end diff --git a/db/migrate/20151107042241_add_owner_to_group_users.rb b/db/migrate/20151107042241_add_owner_to_group_users.rb new file mode 100644 index 00000000000..c834ac13752 --- /dev/null +++ b/db/migrate/20151107042241_add_owner_to_group_users.rb @@ -0,0 +1,5 @@ +class AddOwnerToGroupUsers < ActiveRecord::Migration + def change + add_column :group_users, :owner, :boolean, null: false, default: false + end +end diff --git a/db/migrate/20151109124147_drop_group_managers.rb b/db/migrate/20151109124147_drop_group_managers.rb new file mode 100644 index 00000000000..41e07141c1a --- /dev/null +++ b/db/migrate/20151109124147_drop_group_managers.rb @@ -0,0 +1,15 @@ +class DropGroupManagers < ActiveRecord::Migration + def up + # old data under old structure + execute "UPDATE group_users SET owner = true + WHERE exists (SELECT 1 FROM group_managers m + WHERE m.group_id = group_users.group_id AND + m.user_id = group_users.user_id)" + + drop_table "group_managers" + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20151113205046_create_translation_overrides.rb b/db/migrate/20151113205046_create_translation_overrides.rb new file mode 100644 index 00000000000..48f7bcb3f7c --- /dev/null +++ b/db/migrate/20151113205046_create_translation_overrides.rb @@ -0,0 +1,12 @@ +class CreateTranslationOverrides < ActiveRecord::Migration + def change + create_table :translation_overrides, force: true do |t| + t.string :locale, length: 30, null: false + t.string :translation_key, null: false + t.string :value, null: false + t.timestamps null: false + end + + add_index :translation_overrides, [:locale, :translation_key], unique: true + end +end diff --git a/db/migrate/20151117165756_add_automatically_unpin_topics_to_users.rb b/db/migrate/20151117165756_add_automatically_unpin_topics_to_users.rb new file mode 100644 index 00000000000..e665b427025 --- /dev/null +++ b/db/migrate/20151117165756_add_automatically_unpin_topics_to_users.rb @@ -0,0 +1,5 @@ +class AddAutomaticallyUnpinTopicsToUsers < ActiveRecord::Migration + def change + add_column :users, :automatically_unpin_topics, :boolean, nullabe: false, default: true + end +end diff --git a/db/migrate/20151124172631_add_is_support_to_categories.rb b/db/migrate/20151124172631_add_is_support_to_categories.rb new file mode 100644 index 00000000000..6747153c26e --- /dev/null +++ b/db/migrate/20151124172631_add_is_support_to_categories.rb @@ -0,0 +1,5 @@ +class AddIsSupportToCategories < ActiveRecord::Migration + def change + add_column :categories, :is_support, :boolean, default: false, null: false + end +end diff --git a/db/migrate/20151124192339_rename_ninja_edit.rb b/db/migrate/20151124192339_rename_ninja_edit.rb new file mode 100644 index 00000000000..1b36d4308c3 --- /dev/null +++ b/db/migrate/20151124192339_rename_ninja_edit.rb @@ -0,0 +1,5 @@ +class RenameNinjaEdit < ActiveRecord::Migration + def change + execute "UPDATE site_settings SET name = 'editing_grace_period' WHERE name = 'ninja_edit_window'" + end +end diff --git a/db/migrate/20151125194322_remove_site_text.rb b/db/migrate/20151125194322_remove_site_text.rb new file mode 100644 index 00000000000..9f1b4b6a17b --- /dev/null +++ b/db/migrate/20151125194322_remove_site_text.rb @@ -0,0 +1,21 @@ +class RemoveSiteText < ActiveRecord::Migration + def change + execute "INSERT INTO translation_overrides (locale, translation_key, value, created_at, updated_at) + SELECT '#{I18n.locale}', + CASE + WHEN text_type = 'usage_tips' THEN 'system_messages.usage_tips.text_body_template' + WHEN text_type = 'education_new_topic' THEN 'education.new-topic' + WHEN text_type = 'education_new_reply' THEN 'education.new-reply' + WHEN text_type = 'login_required_welcome_message' THEN 'login_required.welcome_message' + END, + value, + created_at, + updated_at + FROM site_texts + WHERE text_type in ('usage_tips', + 'education_new_topic', + 'education_new_reply', + 'login_required_welcome_message')" + drop_table :site_texts + end +end diff --git a/db/migrate/20151126173356_rename_is_support_to_contains_messages.rb b/db/migrate/20151126173356_rename_is_support_to_contains_messages.rb new file mode 100644 index 00000000000..8d9cf8e4967 --- /dev/null +++ b/db/migrate/20151126173356_rename_is_support_to_contains_messages.rb @@ -0,0 +1,5 @@ +class RenameIsSupportToContainsMessages < ActiveRecord::Migration + def change + rename_column :categories, :is_support, :contains_messages + end +end diff --git a/db/migrate/20151126233623_add_baked_head_and_body_to_site_customizations.rb b/db/migrate/20151126233623_add_baked_head_and_body_to_site_customizations.rb new file mode 100644 index 00000000000..c7f8ed41709 --- /dev/null +++ b/db/migrate/20151126233623_add_baked_head_and_body_to_site_customizations.rb @@ -0,0 +1,6 @@ +class AddBakedHeadAndBodyToSiteCustomizations < ActiveRecord::Migration + def change + add_column :site_customizations, :head_tag_baked, :text + add_column :site_customizations, :body_tag_baked, :text + end +end diff --git a/db/migrate/20151127011837_add_header_and_footer_baked_to_site_customizations.rb b/db/migrate/20151127011837_add_header_and_footer_baked_to_site_customizations.rb new file mode 100644 index 00000000000..7e35898d033 --- /dev/null +++ b/db/migrate/20151127011837_add_header_and_footer_baked_to_site_customizations.rb @@ -0,0 +1,8 @@ +class AddHeaderAndFooterBakedToSiteCustomizations < ActiveRecord::Migration + def change + add_column :site_customizations, :header_baked, :text + add_column :site_customizations, :mobile_header_baked, :text + add_column :site_customizations, :footer_baked, :text + add_column :site_customizations, :mobile_footer_baked, :text + end +end diff --git a/db/migrate/20151201035631_add_group_mentions.rb b/db/migrate/20151201035631_add_group_mentions.rb new file mode 100644 index 00000000000..4e3900387a2 --- /dev/null +++ b/db/migrate/20151201035631_add_group_mentions.rb @@ -0,0 +1,12 @@ +class AddGroupMentions < ActiveRecord::Migration + def change + create_table :group_mentions do |t| + t.integer :post_id + t.integer :group_id + t.timestamps + end + + add_index :group_mentions, [:post_id, :group_id], unique: true + add_index :group_mentions, [:group_id, :post_id], unique: true + end +end diff --git a/db/migrate/20151201161726_add_incoming_email_to_groups.rb b/db/migrate/20151201161726_add_incoming_email_to_groups.rb new file mode 100644 index 00000000000..afea28ba220 --- /dev/null +++ b/db/migrate/20151201161726_add_incoming_email_to_groups.rb @@ -0,0 +1,6 @@ +class AddIncomingEmailToGroups < ActiveRecord::Migration + def change + add_column :groups, :incoming_email, :string, null: true + add_index :groups, :incoming_email, unique: true + end +end diff --git a/db/migrate/20151214165852_add_notification_level_to_group_users.rb b/db/migrate/20151214165852_add_notification_level_to_group_users.rb new file mode 100644 index 00000000000..a1f2a5d8116 --- /dev/null +++ b/db/migrate/20151214165852_add_notification_level_to_group_users.rb @@ -0,0 +1,6 @@ +class AddNotificationLevelToGroupUsers < ActiveRecord::Migration + def change + # defaults to TopicUser.notification_levels[:watching] + add_column :group_users, :notification_level, :integer, default: 3, null: false + end +end diff --git a/db/migrate/20151218232200_add_unique_index_to_category_users.rb b/db/migrate/20151218232200_add_unique_index_to_category_users.rb new file mode 100644 index 00000000000..74cfe3f4f1a --- /dev/null +++ b/db/migrate/20151218232200_add_unique_index_to_category_users.rb @@ -0,0 +1,21 @@ +class AddUniqueIndexToCategoryUsers < ActiveRecord::Migration + def up + execute < 5 were off by one + # + # to correct we are doing this https://meta.discourse.org/t/enums-that-are-used-in-tables-need-to-be-stable/37622 + # + # This migration hunts for date stuff started going wrong and date it started being good and corrects the data + + + # this is a :auto_trust_level_change mislabled as :check_email + # impersonate that was actually delete topic + condition = < 5 AND id >= #{first_wrong_id} AND id <= #{last_wrong_id}") + + execute("INSERT INTO user_histories(action, acting_user_id, details, created_at, updated_at) + VALUES (22, -1, '#{msg}', current_timestamp, current_timestamp)") + end + end + + def down + end +end diff --git a/db/migrate/20160110053003_archive_system_messages_with_no_replies.rb b/db/migrate/20160110053003_archive_system_messages_with_no_replies.rb new file mode 100644 index 00000000000..da9b1d71c31 --- /dev/null +++ b/db/migrate/20160110053003_archive_system_messages_with_no_replies.rb @@ -0,0 +1,24 @@ +class ArchiveSystemMessagesWithNoReplies < ActiveRecord::Migration + def up + # backdate archival of system messages send on behalf of site_contact_user + execute <]+)>', 'im'), '') + , users.email + , array_to_string(regexp_matches(array_to_string(regexp_matches(posts.raw_email, '^to:.+$', 'im'), ''), '[^<\s"''(]+@[^>\s"'')]+'), '') + , topics.title + FROM posts + JOIN topics ON posts.topic_id = topics.id + JOIN users ON posts.user_id = users.id + WHERE posts.user_id IS NOT NULL + AND posts.topic_id IS NOT NULL + AND posts.via_email = 't' + AND posts.raw_email ~* 'Message-Id' + ORDER BY posts.id; + SQL + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20160127105314_change_default_notification_level_on_groups.rb b/db/migrate/20160127105314_change_default_notification_level_on_groups.rb new file mode 100644 index 00000000000..474b200b157 --- /dev/null +++ b/db/migrate/20160127105314_change_default_notification_level_on_groups.rb @@ -0,0 +1,6 @@ +class ChangeDefaultNotificationLevelOnGroups < ActiveRecord::Migration + def change + execute "UPDATE group_users SET notification_level = 2" + change_column :group_users, :notification_level, :integer, null: false, default: 2 + end +end diff --git a/db/migrate/20160127222802_migrate_uncategorized_description_setting.rb b/db/migrate/20160127222802_migrate_uncategorized_description_setting.rb new file mode 100644 index 00000000000..b5439564ba8 --- /dev/null +++ b/db/migrate/20160127222802_migrate_uncategorized_description_setting.rb @@ -0,0 +1,11 @@ +class MigrateUncategorizedDescriptionSetting < ActiveRecord::Migration + def change + execute "INSERT INTO translation_overrides (locale, translation_key, value, created_at, updated_at) + SELECT '#{I18n.locale}', 'category.uncategorized_description', value, created_at, updated_at + FROM site_settings + WHERE name = 'uncategorized_description' + AND value <> 'Topics that don''t need a category, or don''t fit into any other existing category.'" + + execute "DELETE FROM site_settings WHERE name = 'uncategorized_description'" + end +end diff --git a/db/migrate/20160201181320_fix_email_logs.rb b/db/migrate/20160201181320_fix_email_logs.rb new file mode 100644 index 00000000000..402761a8fb6 --- /dev/null +++ b/db/migrate/20160201181320_fix_email_logs.rb @@ -0,0 +1,16 @@ +class FixEmailLogs < ActiveRecord::Migration + def up + execute <<-SQL + UPDATE email_logs + SET user_id = u.id + FROM email_logs el + LEFT JOIN users u ON u.email = el.to_address + WHERE email_logs.id = el.id + AND email_logs.user_id IS NULL + AND NOT email_logs.skipped + SQL + end + + def down + end +end diff --git a/db/migrate/20160206210202_remove_invalid_websites.rb b/db/migrate/20160206210202_remove_invalid_websites.rb new file mode 100644 index 00000000000..d0ae516ef83 --- /dev/null +++ b/db/migrate/20160206210202_remove_invalid_websites.rb @@ -0,0 +1,5 @@ +class RemoveInvalidWebsites < ActiveRecord::Migration + def change + execute "UPDATE user_profiles SET website = NULL WHERE website = 'http://'" + end +end diff --git a/db/migrate/20160215075528_add_unread_pm_index_to_notifications.rb b/db/migrate/20160215075528_add_unread_pm_index_to_notifications.rb new file mode 100644 index 00000000000..382489e2fda --- /dev/null +++ b/db/migrate/20160215075528_add_unread_pm_index_to_notifications.rb @@ -0,0 +1,6 @@ +class AddUnreadPmIndexToNotifications < ActiveRecord::Migration + def change + # create index idxtmp on notifications(user_id, id) where notification_type = 6 AND NOT read + add_index :notifications, [:user_id, :id], unique: true, where: 'notification_type = 6 AND NOT read' + end +end diff --git a/db/migrate/20160224033122_create_instagram_user_infos.rb b/db/migrate/20160224033122_create_instagram_user_infos.rb new file mode 100644 index 00000000000..ef3633f8926 --- /dev/null +++ b/db/migrate/20160224033122_create_instagram_user_infos.rb @@ -0,0 +1,11 @@ +class CreateInstagramUserInfos < ActiveRecord::Migration + def change + create_table :instagram_user_infos do |t| + t.integer :user_id + t.string :screen_name + t.integer :instagram_user_id + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20160225050317_add_user_options.rb b/db/migrate/20160225050317_add_user_options.rb new file mode 100644 index 00000000000..965865197d8 --- /dev/null +++ b/db/migrate/20160225050317_add_user_options.rb @@ -0,0 +1,76 @@ +class AddUserOptions < ActiveRecord::Migration + def up + + create_table :user_options, id: false do |t| + t.integer :user_id, null: false + t.boolean :email_always, null: false, default: false + t.boolean :mailing_list_mode, null: false, default: false + t.boolean :email_digests + t.boolean :email_direct, null: false, default: true + t.boolean :email_private_messages, null: false, default: true + t.boolean :external_links_in_new_tab, null: false, default: false + t.boolean :enable_quoting, null: false, default: true + t.boolean :dynamic_favicon, null: false, default: false + t.boolean :disable_jump_reply, null: false, default: false + t.boolean :edit_history_public, null: false, default: false + t.boolean :automatically_unpin_topics, null: false, default: true + t.integer :digest_after_days + end + + add_index :user_options, [:user_id], unique: true + + execute < 0 + max_likes = max_likes_rows[0]['value'].to_i + end + max_likes ||= 50 + + execute "INSERT INTO given_daily_likes (user_id, likes_given, limit_reached, given_date) + SELECT pa.user_id, + COUNT(*), + CASE WHEN COUNT(*) >= #{max_likes} THEN true + ELSE false + END, + pa.created_at::date + FROM post_actions AS pa + WHERE pa.post_action_type_id = 2 + AND pa.deleted_at IS NULL + GROUP BY pa.user_id, pa.created_at::date" + end + + def down + drop_table :given_daily_likes + end +end diff --git a/db/migrate/20160317201955_add_include_tl0_in_digests_to_user_options.rb b/db/migrate/20160317201955_add_include_tl0_in_digests_to_user_options.rb new file mode 100644 index 00000000000..512f5d6df5b --- /dev/null +++ b/db/migrate/20160317201955_add_include_tl0_in_digests_to_user_options.rb @@ -0,0 +1,5 @@ +class AddIncludeTl0InDigestsToUserOptions < ActiveRecord::Migration + def change + add_column :user_options, :include_tl0_in_digests, :boolean, default: false + end +end diff --git a/db/migrate/20160329101122_remove_wiki_color.rb b/db/migrate/20160329101122_remove_wiki_color.rb new file mode 100644 index 00000000000..4b6007ceae2 --- /dev/null +++ b/db/migrate/20160329101122_remove_wiki_color.rb @@ -0,0 +1,8 @@ +class RemoveWikiColor < ActiveRecord::Migration + def up + execute "DELETE FROM color_scheme_colors WHERE name = 'wiki'" + end + + def down + end +end diff --git a/discourse.sublime-project b/discourse.sublime-project index 20854867ba8..6ec5f18c583 100644 --- a/discourse.sublime-project +++ b/discourse.sublime-project @@ -16,9 +16,7 @@ { "path": "script" }, { "path": "spec" }, { "path": "vendor" }, - { "path": "test", - "folder_exclude_patterns": ["fixtures"] - } + { "path": "test" }, ], "settings": { diff --git a/docs/ADMIN-QUICK-START-GUIDE.md b/docs/ADMIN-QUICK-START-GUIDE.md index 2a0965077e5..5c32d211246 100644 --- a/docs/ADMIN-QUICK-START-GUIDE.md +++ b/docs/ADMIN-QUICK-START-GUIDE.md @@ -73,8 +73,7 @@ Email is required for new account signups and notifications. **Test your email t - You got the test email? Great! **Read that email closely**, it has important email deliverability tips. - You didn't get the test email? This means your users probably aren't getting any signup or notification emails either. - -Email deliverability can be hard. We strongly recommend using dedicated email services like [Mandrill](http://mandrill.com), [MailGun](http://www.mailgun.com/), or [MailJet](https://www.mailjet.com/), which offer generous free plans that work fine for most communities. +- Email deliverability can be hard. Read [**Email Service Configuration**](https://github.com/discourse/discourse/blob/master/docs/INSTALL-email.md). If you'd like to enable *replying* to topics via email, [see this howto](https://meta.discourse.org/t/set-up-reply-via-email-support/14003). diff --git a/docs/DEVELOPER-ADVANCED.md b/docs/DEVELOPER-ADVANCED.md index 150db1a2701..c8e893345a9 100644 --- a/docs/DEVELOPER-ADVANCED.md +++ b/docs/DEVELOPER-ADVANCED.md @@ -9,10 +9,10 @@ Note: If you are developing on a Mac, you will probably want to look at [these i 1. Install and configure PostgreSQL 9.3+. 1. Run `postgres -V` to see if you already have it. 1. Make sure that the server's messages language is English; this is [required](https://github.com/rails/rails/blob/3006c59bc7a50c925f6b744447f1d94533a64241/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L1140) by the ActiveRecord Postgres adapter. -2. Install and configure Redis 2+. +2. Install and configure Redis 2.8.12+. 1. Run `redis-server -v` to see if you already have it. 3. Install ImageMagick -4. Install libxml2, libpq-dev, g++, and make. +4. Install libxml2, libpq-dev, g++, gifsicle, libjpeg-progs and make. 5. Install Ruby 2.1.3 and Bundler. 6. Clone the project and bundle. diff --git a/docs/DEVELOPMENT-OSX-NATIVE.md b/docs/DEVELOPMENT-OSX-NATIVE.md index 1b2536c23bd..4a6a7259a6a 100644 --- a/docs/DEVELOPMENT-OSX-NATIVE.md +++ b/docs/DEVELOPMENT-OSX-NATIVE.md @@ -93,7 +93,7 @@ You should now be able to check out a clone of Discourse. ### SourceTree -Atlassan has a free Git client for OS X called [SourceTree](http://www.sourcetreeapp.com/download/) which can be extremely useful for keeping visual track of what's going on in Git-land. While it's arguably not a full substitute for command-line git (especially if you know the command line well), it's extremely powerful for a GUI version-control client. +Atlassian has a free Git client for OS X called [SourceTree](http://www.sourcetreeapp.com/download/) which can be extremely useful for keeping visual track of what's going on in Git-land. While it's arguably not a full substitute for command-line git (especially if you know the command line well), it's extremely powerful for a GUI version-control client. ## Postgres 9.3 diff --git a/docs/INSTALL-cloud.md b/docs/INSTALL-cloud.md index 5e1e474c5e7..4c0faf053c2 100644 --- a/docs/INSTALL-cloud.md +++ b/docs/INSTALL-cloud.md @@ -1,8 +1,8 @@ -**Set up Discourse in the cloud in under 30 minutes** with zero knowledge of Rails or Linux shell using our [Discourse Docker image][dd]. We recommend [Digital Ocean][do], but these steps will work on any Docker-compatible cloud provider or local server. +**Set up Discourse in the cloud in under 30 minutes** with zero knowledge of Rails or Linux shell using our [Discourse Docker image][dd]. We recommend [DigitalOcean][do], but these steps will work on any Docker-compatible cloud provider or local server. # Create New Cloud Server -[Sign up for Digital Ocean][do], update billing info, then create your new cloud server. +[Sign up for DigitalOcean][do], update billing info, then create your new cloud server. - Enter your domain `discourse.example.com` as the name. @@ -22,7 +22,7 @@ Connect to your server via SSH, or use [Putty][put] on Windows: Replace `192.168.1.1` with the IP address of your server. -You will be asked for permission to connect, type `yes`, then enter the root password from the email Digital Ocean sent you when the server was set up. You may be prompted to change the root password, too. +You will be asked for permission to connect, type `yes`, then enter the root password from the email DigitalOcean sent you when the server was set up. You may be prompted to change the root password, too. @@ -35,17 +35,20 @@ You will be asked for permission to connect, type `yes`, then enter the root pas wget -qO- https://get.docker.com/ | sh -This command installs the latest versions of Docker and Git on your server. Alternately, you can manually install the respective [Docker package for your OS](https://docs.docker.com/installation/). +This command installs the latest versions of Docker and Git on your server. Alternately, you can manually install Git and the [Docker package for your OS](https://docs.docker.com/installation/). # Install Discourse Create a `/var/discourse` folder, clone the [Official Discourse Docker Image][dd] into it, and make a copy of the config file as `app.yml`: + sudo -s mkdir /var/discourse git clone https://github.com/discourse/discourse_docker.git /var/discourse cd /var/discourse cp samples/standalone.yml containers/app.yml +You will need to be root through the rest of the bootstrap process. + # Edit Discourse Configuration Edit the Discourse config file `app.yml`: @@ -58,13 +61,13 @@ We recommend Nano because it's simple; just use your arrow keys to edit. - Set `DISCOURSE_HOSTNAME` to `discourse.example.com`, this means you want your Discourse available at `http://discourse.example.com/`. You'll need to update the DNS A record for this domain with the IP address of your server. -- Place your mail credentials in `DISCOURSE_SMTP_ADDRESS`, `DISCOURSE_SMTP_PORT`, `DISCOURSE_SMTP_USER_NAME`, `DISCOURSE_SMTP_PASSWORD`. Be sure you remove the comment `#` character and space from the front of these lines as necessary. +- Place your [Email Server credentials][mailconfig] in `DISCOURSE_SMTP_ADDRESS`, `DISCOURSE_SMTP_PORT`, `DISCOURSE_SMTP_USER_NAME`, `DISCOURSE_SMTP_PASSWORD`. Be sure you remove the comment `#` character and space from the front of these lines as necessary. - If you are using a 1 GB instance, set `UNICORN_WORKERS` to 2 and `db_shared_buffers` to 128MB so you have more memory room. -After completing your edits, press CtrlO then Enter to save and CtrlX to exit. +Please be careful while editing and double check your work; YAML is _very_ sensitive to incorrect spacing and misplaced characters. After completing your edits, press CtrlO then Enter to save and CtrlX to exit. # Email Is Important @@ -72,9 +75,11 @@ After completing your edits, press CtrlO then Enter @@ -124,8 +129,7 @@ Commands: stop: Stop a running container restart: Restart a container destroy: Stop and remove a container - enter: Use nsenter to enter a container - ssh: Start a bash shell in a running container + enter: Enter a container using docker exec logs: Docker logs for container bootstrap: Bootstrap a container for the config based on a template rebuild: Rebuild a container (destroy old, bootstrap, start new) @@ -142,7 +146,7 @@ Do you want... * Users to log in *only* via your pre-existing website's registration system? [Configure Single-Sign-On](https://meta.discourse.org/t/official-single-sign-on-for-discourse/13045). -- Users to log in via Google? (new Oauth2 authentication) [Configure Google logins](https://meta.discourse.org/t/configuring-google-oauth2-login-for-discourse/15858). +- Users to log in via Google? [Configure Google logins](https://meta.discourse.org/t/configuring-google-oauth2-login-for-discourse/15858). - Users to log in via Facebook? [Configure Facebook logins](https://meta.discourse.org/t/configuring-facebook-login-for-discourse/13394). @@ -153,8 +157,10 @@ Do you want... - Users to post replies via email? [Configure reply via email](https://meta.discourse.org/t/set-up-reply-via-email-support/14003). - Automatic daily backups? [Configure backups](https://meta.discourse.org/t/configure-automatic-backups-for-discourse/14855). + +- Free HTTPS / SSL support? [Configure Let's Encrypt](https://meta.discourse.org/t/setting-up-lets-encrypt-cert-with-discourse-docker/40709) -- HTTPS / SSL support? [Configure SSL](https://meta.discourse.org/t/allowing-ssl-for-your-discourse-docker-setup/13847). +- Paid HTTPS / SSL support? [Configure SSL](https://meta.discourse.org/t/allowing-ssl-for-your-discourse-docker-setup/13847). - Multiple Discourse sites on the same server? [Configure multisite](https://meta.discourse.org/t/multisite-configuration-with-docker/14084). @@ -169,11 +175,8 @@ Do you want... Help us improve this guide! Feel free to ask about it on [meta.discourse.org][meta], or even better, submit a pull request. [dd]: https://github.com/discourse/discourse_docker - [man]: https://mandrillapp.com - [sp]: https://www.sparkpost.com/ [ssh]: https://help.github.com/articles/generating-ssh-keys [meta]: https://meta.discourse.org [do]: https://www.digitalocean.com/?refcode=5fa48ac82415 - [jet]: https://www.mailjet.com/pricing - [gun]: http://www.mailgun.com/ [put]: http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html + [mailconfig]: https://github.com/discourse/discourse/blob/master/docs/INSTALL-email.md diff --git a/docs/INSTALL-email.md b/docs/INSTALL-email.md new file mode 100644 index 00000000000..ee499ad470f --- /dev/null +++ b/docs/INSTALL-email.md @@ -0,0 +1,53 @@ +## Recommended Email Providers for Discourse + +We strongly recommend using a dedicated email service. Email server setup and maintenance is _very_ difficult even for experienced system administrators, and getting any part of the complex required email setup wrong means your email won't be delivered, or worse, delivered erratically. + +The following are template configurations for email service providers who offer generous free plans that work for most communities. + +Use these values when you [edit your Discourse `app.yml` configuration file](https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md#edit-discourse-configuration): + +#### [SparkPost][sp] (100k emails/month) + +```yml +DISCOURSE_SMTP_ADDRESS: smtp.sparkpostmail.com +DISCOURSE_SMTP_PORT: 587 +DISCOURSE_SMTP_USER_NAME: SMTP_Injection +DISCOURSE_SMTP_PASSWORD: [Any API key with Send via SMTP permission] +``` + +If not using **the exact** domain you verified (e.g. you're using a subdomain of it), you must change the default `from` email to match the sending domain. Uncomment (and update with your sending domain) this line in `app.yml`: + +```yml +- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'" +``` + +#### [SendGrid][sg] (12k emails/month) + +```yml +DISCOURSE_SMTP_ADDRESS: smtp.sendgrid.net +DISCOURSE_SMTP_PORT: 587 +DISCOURSE_SMTP_USER_NAME: apikey +DISCOURSE_SMTP_PASSWORD: [SendGrid API Key] +``` +We recommend creating an [API Key][sg2] instead of using your SendGrid username and password. + +#### [Mailgun][gun] (10k emails/month) + + +```yml +DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org +DISCOURSE_SMTP_PORT: 587 +DISCOURSE_SMTP_USER_NAME: [SMTP credentials for your domain under Mailgun domains tab] +DISCOURSE_SMTP_PASSWORD: [SMTP credentials for your domain under Mailgun domains tab] +``` + +#### [Mailjet][jet] (6k emails/month) + +Go to [My Account page](https://www.mailjet.com/account) and click on the ["SMTP and SEND API Settings"](https://www.mailjet.com/account/setup) link. + + + [sp]: https://www.sparkpost.com/ + [jet]: https://www.mailjet.com/pricing + [gun]: http://www.mailgun.com/ + [sg]: https://sendgrid.com/ + [sg2]: https://sendgrid.com/docs/Classroom/Send/How_Emails_Are_Sent/api_keys.html diff --git a/docs/PLUGINS.md b/docs/PLUGINS.md index ee874dc157a..b07268c05cf 100644 --- a/docs/PLUGINS.md +++ b/docs/PLUGINS.md @@ -1,7 +1,7 @@ ## List of Discourse Plugins -If you just want to get some plugins for your Discourse instance, check out [the plugin category](https://meta.discourse.org/category/extensibility/plugin) at meta. This is the most up to date place for plugin discussion and listing. +If you just want to get some plugins for your Discourse instance, check out [the plugin category](https://meta.discourse.org/c/plugin) at meta. This is the most up to date place for plugin discussion and listing. ### Discourse Plugin Tutorials diff --git a/docs/VAGRANT.md b/docs/VAGRANT.md index 4fc103cd464..865eaab8b17 100644 --- a/docs/VAGRANT.md +++ b/docs/VAGRANT.md @@ -87,14 +87,14 @@ bundle exec rake db:migrate Once your VM is up to date, you can start a rails instance using the following command from the /vagrant directory: ``` -bundle exec rails s +bundle exec rails s -b 0.0.0.0 ``` In a few seconds, rails will start serving pages. To access them, open a web browser to [http://localhost:4000](http://localhost:4000) - if it all worked you should see discourse! Congratulations, you are ready to start working! If you want to log in as a user, a shortcut you can use in development mode is to follow this link to log in as `eviltrout`: -http://localhost:4000/session/eviltrout/become +[http://localhost:4000/session/eviltrout/become](http://localhost:4000/session/eviltrout/become) You can now edit files on your local file system, using your favorite text editor or IDE. When you reload your web browser, it should have the latest changes. diff --git a/docs/code-of-conduct.md b/docs/code-of-conduct.md new file mode 100644 index 00000000000..b9d91e61b97 --- /dev/null +++ b/docs/code-of-conduct.md @@ -0,0 +1,50 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of +fostering an open and welcoming community, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating +documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic + addresses, without explicit permission +* Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to +fairly and consistently applying these principles to every aspect of managing +this project. Project maintainers who do not follow or enforce the Code of +Conduct may be permanently removed from the project team. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting a project maintainer at team@discourse.org. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. Maintainers are +obligated to maintain confidentiality with regard to the reporter of an +incident. + + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.3.0, available at +[http://contributor-covenant.org/version/1/3/0/][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/3/0/ diff --git a/lib/active_record/connection_adapters/postgresql_fallback_adapter.rb b/lib/active_record/connection_adapters/postgresql_fallback_adapter.rb new file mode 100644 index 00000000000..857cc28b566 --- /dev/null +++ b/lib/active_record/connection_adapters/postgresql_fallback_adapter.rb @@ -0,0 +1,160 @@ +require 'active_record/connection_adapters/abstract_adapter' +require 'active_record/connection_adapters/postgresql_adapter' +require 'discourse' + +class PostgreSQLFallbackHandler + include Singleton + + def initialize + @master = {} + @running = {} + @mutex = {} + @last_check = {} + + setup! + end + + def verify_master + @mutex[namespace].synchronize do + return if running || recently_checked? + @running[namespace] = true + end + + current_namespace = namespace + Thread.new do + RailsMultisite::ConnectionManagement.with_connection(current_namespace) do + begin + logger.warn "#{log_prefix}: Checking master server..." + connection = ActiveRecord::Base.postgresql_connection(config) + + if connection.active? + connection.disconnect! + ActiveRecord::Base.clear_all_connections! + logger.warn "#{log_prefix}: Master server is active. Reconnecting..." + + if namespace == RailsMultisite::ConnectionManagement::DEFAULT + ActiveRecord::Base.establish_connection(config) + else + RailsMultisite::ConnectionManagement.establish_connection(db: namespace) + end + + Discourse.disable_readonly_mode + self.master = true + end + rescue => e + if e.message.include?("could not connect to server") + logger.warn "#{log_prefix}: Connection to master PostgreSQL server failed with '#{e.message}'" + else + raise e + end + ensure + @mutex[namespace].synchronize do + @last_check[namespace] = Time.zone.now + @running[namespace] = false + end + end + end + end + end + + def master + @master[namespace] + end + + def master=(args) + @master[namespace] = args + end + + def running + @running[namespace] + end + + def setup! + RailsMultisite::ConnectionManagement.all_dbs.each do |db| + @master[db] = true + @running[db] = false + @mutex[db] = Mutex.new + @last_check[db] = nil + end + end + + def verify? + !master && !running && !recently_checked? + end + + private + + def config + ActiveRecord::Base.connection_config + end + + def logger + Rails.logger + end + + def log_prefix + "#{self.class} [#{namespace}]" + end + + def recently_checked? + if @last_check[namespace] + Time.zone.now <= (@last_check[namespace] + 5.seconds) + else + false + end + end + + def namespace + RailsMultisite::ConnectionManagement.current_db + end +end + +module ActiveRecord + module ConnectionHandling + def postgresql_fallback_connection(config) + fallback_handler = ::PostgreSQLFallbackHandler.instance + config = config.symbolize_keys + + if fallback_handler.verify? + connection = postgresql_connection(config.dup.merge({ + host: config[:replica_host], port: config[:replica_port] + })) + + verify_replica(connection) + Discourse.enable_readonly_mode + else + begin + connection = postgresql_connection(config) + rescue PG::ConnectionBad => e + fallback_handler.master = false + raise e + end + end + + connection + end + + private + + def verify_replica(connection) + value = connection.raw_connection.exec("SELECT pg_is_in_recovery()").values[0][0] + raise "Replica database server is not in recovery mode." if value == 'f' + end + end + + module ConnectionAdapters + class PostgreSQLAdapter + set_callback :checkout, :before, :switch_back? + + private + + def fallback_handler + @fallback_handler ||= ::PostgreSQLFallbackHandler.instance + end + + def switch_back? + fallback_handler.verify_master if fallback_handler.verify? + end + end + end +end diff --git a/lib/admin_constraint.rb b/lib/admin_constraint.rb index 2d5df1f5bd4..923e5e806c0 100644 --- a/lib/admin_constraint.rb +++ b/lib/admin_constraint.rb @@ -2,7 +2,12 @@ require_dependency 'current_user' class AdminConstraint + def initialize(options={}) + @require_master = options[:require_master] + end + def matches?(request) + return false if @require_master && RailsMultisite::ConnectionManagement.current_db != "default" provider = Discourse.current_user_provider.new(request.env) provider.current_user && provider.current_user.admin? end diff --git a/lib/age_words.rb b/lib/age_words.rb index 7fa21c5f4e5..92587ec30f4 100644 --- a/lib/age_words.rb +++ b/lib/age_words.rb @@ -1,8 +1,12 @@ module AgeWords def self.age_words(secs) - return "—" if secs.blank? - return FreedomPatches::Rails4.distance_of_time_in_words(Time.now, Time.now + secs) + if secs.blank? + "—" + else + now = Time.now + FreedomPatches::Rails4.distance_of_time_in_words(now, now + secs) + end end end diff --git a/lib/auth.rb b/lib/auth.rb index a218c43f28c..f94ba5cf43c 100644 --- a/lib/auth.rb +++ b/lib/auth.rb @@ -7,3 +7,4 @@ require_dependency 'auth/open_id_authenticator' require_dependency 'auth/github_authenticator' require_dependency 'auth/twitter_authenticator' require_dependency 'auth/google_oauth2_authenticator' +require_dependency 'auth/instagram_authenticator' diff --git a/lib/auth/google_oauth2_authenticator.rb b/lib/auth/google_oauth2_authenticator.rb index 0f40c91f0cb..c51e5a01d0d 100644 --- a/lib/auth/google_oauth2_authenticator.rb +++ b/lib/auth/google_oauth2_authenticator.rb @@ -31,12 +31,15 @@ class Auth::GoogleOAuth2Authenticator < Auth::Authenticator end def register_middleware(omniauth) + # jwt encoding is causing auth to fail in quite a few conditions + # skipping omniauth.provider :google_oauth2, :setup => lambda { |env| strategy = env["omniauth.strategy"] strategy.options[:client_id] = SiteSetting.google_oauth2_client_id strategy.options[:client_secret] = SiteSetting.google_oauth2_client_secret - } + }, + skip_jwt: true end protected diff --git a/lib/auth/instagram_authenticator.rb b/lib/auth/instagram_authenticator.rb new file mode 100644 index 00000000000..ba2dd7f1bb0 --- /dev/null +++ b/lib/auth/instagram_authenticator.rb @@ -0,0 +1,49 @@ +class Auth::InstagramAuthenticator < Auth::Authenticator + + def name + "instagram" + end + + # TODO twitter provides all sorts of extra info, like website/bio etc. + # it may be worth considering pulling some of it in. + def after_authenticate(auth_token) + + result = Auth::Result.new + + data = auth_token[:info] + + result.username = screen_name = data["nickname"] + result.name = name = data["name"].slice!(0) + instagram_user_id = auth_token["uid"] + + result.extra_data = { + instagram_user_id: instagram_user_id, + instagram_screen_name: screen_name + } + + user_info = InstagramUserInfo.find_by(instagram_user_id: instagram_user_id) + + result.user = user_info.try(:user) + + result + end + + def after_create_account(user, auth) + data = auth[:extra_data] + InstagramUserInfo.create( + user_id: user.id, + screen_name: data[:instagram_screen_name], + instagram_user_id: data[:instagram_user_id] + ) + end + + def register_middleware(omniauth) + omniauth.provider :instagram, + :setup => lambda { |env| + strategy = env["omniauth.strategy"] + strategy.options[:client_id] = SiteSetting.instagram_consumer_key + strategy.options[:client_secret] = SiteSetting.instagram_consumer_secret + } + end + +end diff --git a/lib/auth/result.rb b/lib/auth/result.rb index 461c8f7c9f5..3c78b2cf5fb 100644 --- a/lib/auth/result.rb +++ b/lib/auth/result.rb @@ -46,15 +46,18 @@ class Auth::Result } end else - { - email: email, - name: User.suggest_name(name || username || email), - username: UserNameSuggester.suggest(username || name || email), - # this feels a tad wrong - auth_provider: authenticator_name.capitalize, - email_valid: !!email_valid, - omit_username: !!omit_username - } + result = { email: email, + username: UserNameSuggester.suggest(username || name || email), + # this feels a tad wrong + auth_provider: authenticator_name.capitalize, + email_valid: !!email_valid, + omit_username: !!omit_username } + + if SiteSetting.enable_names? + result[:name] = User.suggest_name(name || username || email) + end + + result end end end diff --git a/lib/autospec/manager.rb b/lib/autospec/manager.rb index 45256015d67..9034183bc5b 100644 --- a/lib/autospec/manager.rb +++ b/lib/autospec/manager.rb @@ -148,8 +148,7 @@ class Autospec::Manager puts "@@@@@@@@@@@@ listen_for_changes" if @debug options = { - ignore: /^public|^lib\/autospec/, - relative_paths: true, + ignore: /^lib\/autospec/, } if @opts[:force_polling] @@ -157,11 +156,27 @@ class Autospec::Manager options[:latency] = @opts[:latency] || 3 end - Thread.start do - Listen.to('.', options) do |modified, added, _| - process_change([modified, added].flatten.compact) + path = File.expand_path(File.dirname(__FILE__) + "../../..") + + # to speed up boot we use a thread + ["spec", "lib", "app", "config", "test", "vendor", "plugins"].each do |watch| + + puts "@@@@@@@@@ Listen to #{path}/#{watch} #{options}" if @debug + Thread.new do + begin + Listen.to("#{path}/#{watch}", options) do |modified, added, _| + paths = [modified, added].flatten + paths.compact! + paths.map!{|long| long[(path.length+1)..-1]} + process_change(paths) + end + rescue => e + puts "FAILED to listen on changes to #{path}/#{watch}" + puts e + end end end + end def process_change(files) diff --git a/lib/autospec/rspec_runner.rb b/lib/autospec/rspec_runner.rb index 08677b331b1..cdef09e0b1f 100644 --- a/lib/autospec/rspec_runner.rb +++ b/lib/autospec/rspec_runner.rb @@ -9,17 +9,14 @@ module Autospec # Discourse specific watch(%r{^lib/(.+)\.rb$}) { |m| "spec/components/#{m[1]}_spec.rb" } - # Rails example watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^app/(.+)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } watch(%r{^spec/.+_spec\.rb$}) watch(%r{^spec/support/.+\.rb$}) { "spec" } watch("app/controllers/application_controller.rb") { "spec/controllers" } - # Capybara request specs watch(%r{^app/views/(.+)/.+\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" } - # Fabrication watch(%r{^spec/fabricators/.+_fabricator\.rb$}) { "spec" } RELOADERS = Set.new @@ -27,7 +24,7 @@ module Autospec def reloaders; RELOADERS; end # We need to reload the whole app when changing any of these files - reload("spec/spec_helper.rb") + reload("spec/rails_helper.rb") reload(%r{config/.+\.rb}) reload(%r{app/helpers/.+\.rb}) diff --git a/lib/backup_restore/backup_restore.rb b/lib/backup_restore/backup_restore.rb index e0f02ecb1b3..cde7cfefd4d 100644 --- a/lib/backup_restore/backup_restore.rb +++ b/lib/backup_restore/backup_restore.rb @@ -100,7 +100,7 @@ module BackupRestore DatabaseConfiguration = Struct.new(:host, :port, :username, :password, :database) def self.database_configuration - config = Rails.env.production? ? ActiveRecord::Base.connection_pool.spec.config : Rails.configuration.database_configuration[Rails.env] + config = ActiveRecord::Base.connection_pool.spec.config config = config.with_indifferent_access DatabaseConfiguration.new( diff --git a/lib/backup_restore/backuper.rb b/lib/backup_restore/backuper.rb index 0b3b26656d7..b55d735907e 100644 --- a/lib/backup_restore/backuper.rb +++ b/lib/backup_restore/backuper.rb @@ -258,7 +258,7 @@ module BackupRestore end log "Gzipping archive..." - `gzip #{tar_filename}` + `gzip -5 #{tar_filename}` end def after_create_hook diff --git a/lib/category_badge.rb b/lib/category_badge.rb index 3175372d9ce..196d17691a8 100644 --- a/lib/category_badge.rb +++ b/lib/category_badge.rb @@ -50,7 +50,7 @@ module CategoryBadge case (SiteSetting.category_style || :box).to_sym when :bar then inline_category_stripe(category.color, 'display: inline-block; padding: 1px;', true) when :box then inline_category_stripe(category.color, 'left: 5px; display: block; position: absolute; width: calc(100% - 5px); height: 100%;') - when :bullet then inline_category_stripe(category.color, "display: inline-block; width: #{category.parent_category_id.nil? ? 10 : 5}px; height: 10px;", true) + when :bullet then inline_category_stripe(category.color, "display: inline-block; width: #{category.parent_category_id.nil? ? 10 : 5}px; height: 10px;") end else category_stripe(category.color, 'badge-category-bg') diff --git a/lib/common_passwords/10-char-common-passwords.txt b/lib/common_passwords/10-char-common-passwords.txt new file mode 100644 index 00000000000..e1c2542faf1 --- /dev/null +++ b/lib/common_passwords/10-char-common-passwords.txt @@ -0,0 +1,2344 @@ +0000000000 +000000000000 +0000000000d +0000000000o +000777fffa +0102030405 +010203040506 +0123456789 +01234567890 +012345678910 +0123654789 +0123698745 +014702580369 +0147258369 +0147852369 +0147896325 +0192837465 +01telemike01 +02987654321 +050605rostik +0528325452mr +070793monolit +0987612345 +0987654321 +0987654321a +0987654321q +0995359291 +0cDh0v99uE +0o9i8u7y6t +100894olol +1010101010 +1010810108 +1020304050 +102030405060 +1029384756 +1029384756q +10293847qp +10987654321 +1111111111 +11111111111 +111111111111 +1111111111111 +111111111111111 +11111111111111111111 +1111111111a +1111111111q +1111111111zz +1111122222 +11111aaaaa +1112131415 +111222333000 +111222333444 +111222333444555 +111222333a +111222333q +1122112211 +1122334455 +112233445566 +1123581321 +112358132134 +1133557799 +1212121212 +1212312121 +1213141516 +1213141516171819 +1223334444 +122333444455555 +1223505sayana +123123123123 +123123123123123 +1231231234 +123123123a +123123123q +123123123z +123123qweqwe +123321123321 +123321456654 +123321qweewq +123412341234 +1234509876 +1234512345 +123451234512345 +1234554321 +1234554321a +1234554321q +123456123456 +1234562000 +12345654321 +123456654321 +123456654321a +12345672000 +12345677654321 +1234567812345678 +123456782000 +1234567887654321 +123456789. +123456789* +1234567890- +1234567890 +12345678900 +123456789000 +12345678900987654321 +12345678901 +123456789012 +1234567890123 +12345678901234567890 +1234567890987654321 +1234567890a +1234567890d +1234567890g +1234567890l +1234567890m +1234567890o +1234567890p +1234567890q +1234567890qaz +1234567890qw +1234567890qwe +1234567890qwerty +1234567890qwertyuiop +1234567890s +1234567890v +1234567890w +1234567890z +1234567890zzz +1234567891 +12345678910 +123456789101 +1234567891011 +123456789101112 +12345678912 +123456789123 +123456789123456 +123456789123456789 +1234567892000 +12345678987654321 +1234567899 +123456789987 +1234567899876543 +123456789987654321 +12345678999 +123456789a +123456789A +123456789aa +123456789aaa +123456789abc +123456789as +123456789asd +123456789azat +123456789b +123456789c +123456789d +123456789e +123456789f +123456789g +123456789i +123456789j +123456789k +123456789l +123456789m +123456789n +123456789o +123456789p +123456789q +123456789Q +123456789qaz +123456789qq +123456789qqq +123456789qw +123456789qwe +123456789qwer +123456789qwerty +123456789r +123456789s +123456789t +123456789v +123456789w +123456789x +123456789y +123456789z +123456789Z +123456789zx +123456789zxc +123456789zz +12345678qwe +12345678qwertyu +1234567qwerty +1234567qwertyu +123456qwer +123456qwert +123456qwerty +123456zxcvbn +12345abcde +12345asdfg +12345q12345 +12345qazwsx +12345qwert +12345qwert7 +12345qwerty +12345trewq +12345zxcvb +1234qw1234qw +1234qwerasdf +1234qwerasdfzxcv +1234qwerty +1236547890 +123654789a +1236987005 +12369874123 +123698745a +123ewqasdcxz +123hfjdk147 +123qazwsxedc +123qwe123qwe +123qwe456rty +123qweasdzx +123qweasdzxc +123qwerty123 +123qwerty456 +123qwertyuiop +123sas4758 +125712571257d +12andriy14 +12qw34er56ty +1302alex1994 +1313131313 +131313131313 +1324354657 +1324354657687980 +132Forever +1346798520 +1357908642 +1357913579 +1357924680 +1357997531 +141312190296q +1472583690 +147258369a +147258369q +1478963215 +1488ss1488 +14bestlist +159357159357 +159753159753 +1597532486 +159753258456 +159753456852 +17171717aa +1928374650 +1928374655 +192837465q +193570356033 +193711101994a +1958proman +1986irachka +198719871987 +198919891989 +1994200414 +19952009sa +19960610ilja +19mtpgam19 +1a2a3a4a5a +1a2a3a4a5a6a +1a2b3c4d5e +1a2s3d4f5g +1a2s3d4f5g6h +1pass1page +1q2q3q4q5q +1q2w3e4r5t +1q2w3e4r5t6y +1q3e5t7u9o +1qa2ws3ed4rf +1qa2ws3ed4rf5tg +1qaz1qaz1qaz +1qaz2wsx3ed +1qaz2wsx3edc +1qaz2wsx3edc4rfv +1qazwsxedc +1qazxsw23edc +1qazxsw23edcvfr4 +1qwertyuiop +1rus27540102 +1z2x3c4v5b +20102010ss +20162016up +2143658709 +2222222222 +2222333344445555 +2244668800 +2267137151 +23176djivanfros +2347172123 +23WKoa0FP78dk +2468013579 +2507905048 +2606642yra +26429vadim +277rte87hryloitru +2dumb2live +2pacshakur +3012292113 +30secondstomars +31217221027711 +31321dj51982 +3141592654 +3216732167 +3240500777 +32615948worms +3322607093 +3333333333 +3454051maksim +3478526129 +38gjgeuftd +3f3fphT7oP +3rJs1la7qE +3sYqo15hiL +413276191q +41d8cd98f00b +420842084208555 +4294967296 +42qwerty42 +4444444444 +4465134444 +456456456q +4648246482 +4815162342 +4815162342a +4815162342lf +4815162342lost +4815162342q +4815162342s +4815162342z +4904s677075 +4rdf_king7 +51051051051 +5152535455 +541233432442 +5432112345 +5432167890 +54322q22345 +5544332211 +5555555555 +5566778899 +5647382910 +5858855abc +59382113kevinp +5hsU75kpoT +5t4r3e2w1q +6215mila6215 +6666666666 +671fsa75yt +675675675a +68iypNeg6U +6969696969 +70780070780 +7410258963 +7410852963 +7418529630 +741852963q +742617000027 +7777755102q +7777777777 +777777777777 +787898mich +7894561230 +789456123a +789456123q +7elephants +7jokx7b9DU +7uGd5HIp2J +80070633pc +80361665abc +80633459472qw +80637852730 +80663635606 +80672091913 +80679047880 +8096468644q +80966095182z +80969260620 +80972694711 +80988218126 +80990606390 +87654321vv +87e5nclizry +88002000600 +8888888888 +89015173454 +89023346574 +89032073168 +89055521933 +89057003343 +89063032220m +89128830153 +89132664230 +89172735872 +89181502334 +89211375759 +89231243658s +89600506779 +89614774181 +89876065093rax +89semtsriuty +8PHroWZ622 +8PHroWZ624 +9021090210 +9085084232 +9085603566 +9105425888 +9293709b13 +92k2cizCdP +951753852456 +9638527410 +9731553197 +9874563210 +9876543210 +987654321a +987654321d +987654321g +987654321q +987654321w +987654321z +989244342a +9988776655 +999111999q +9999999999 +99999999999 +999999999999 +99strenght +9Z5ve9rrcZ +a123456789 +A123456789 +a1234567890 +a123456789a +a1a2a3a4a5 +a1b2c3d4e5 +a1s2d3f4g5 +a1s2d3f4g5h6 +a3eilm2s2y +A514527514 +a550777954 +a58Wtjuz4U +a789456123 +a987654321 +aaaaaaaaaa +aaaaaaaaaaa +aaaaaaaaaaaa +ababagalamaga +abc123456789 +abc123abc123 +abcd123456 +abcde12345 +abcdefghij +abcdefghijk +abcdefghijkl +abdullayev +abercrombie +abracadabr +abracadabra +abrakadabra +absolutely +Accessibilit +accountant +accountbloc +accounting +activation +Ad12345678 +admin18533362 +administrato +administrator +adoxreadme +adrenaline +aezakmi123 +afghanistan +afireinside +afrika2002 +agnieszka1 +aionrusian +AjcuiVd289 +ajnjuhfabz +aksjdlasdakj89879 +alabama123 +alejandro1 +aleksandar +aleksander +aleksandra +Aleksandra +aleksandrov +aleksandrova +aleksey1986 +alertemailms +alertpaydoubl +alessandra +alessandro +alexander1 +Alexander1 +alexandra1 +alexandria +alexsander +alinaalina +alisaalisa +alisokskok +alkanaft123 +allahakbar +allahuakbar +alpha135792468 +alphabravo +alphaomega +alteclansing +alternativ +alternativa +alternative +am4h39d8nh +amadeusptfcor +ambassador +amsterdam1 +an83546921an13 +anastasija +anastasiya +Anastasiya +anderlecht +andrewjackie +andrey1234 +andrey1992 +andrey2010 +angelangel +angelochek +angelofwar +animal2000 +anniversary +antananarivu +antichrist +antihero77 +antikiller +antoshenechka +anytimetoday +apocalipsis +apocalypse +apokalipsis +applejuice +applesauce +armageddon +arsenal123 +artemartem +asasasasas +asd123asd123 +asdasdasdasd +asdf123456 +asdfdsasdf +asdfg12345 +asdfgh123456 +asdfghjkl; +asdfghjkl1 +asdfghjkl123 +ashleigh69 +asshole123 +astalavista +astonmartin +astonvilla +astra334566 +auckland2010 +australia1 +automobile +avadakedavra +avrillavigne +awdqseawdssa +awdrgyjilp +awesome123 +awo8rx3wa8t +azerbaijan +azerbaycan +azertyuiop +azsxdcfvgb +azsxdcfvgbhn +azwebitalia +BaBeMaGnEt +badiman28200 +badnaamhere +badreligion +bangladesh +barabashka +barbariska +barbarossa +barcelona1 +bartsimpson +baseball10 +baseball11 +baseball12 +baseball123 +baseball14 +baseball17 +baseball21 +basketball +Basketball +basketball1 +bassmaster +battlefield +battlestar +bbbbbbbbbb +bbbbbbbbbbbb +beautiful1 +belladonna +berezuckiy +bernadette +bestfriend +bestpker09 +bezparolya +BhRh0h2Oof6XbqJEH +biblioteka +bigbrother +billionaire +birmingham +birthday10 +birthday100 +birthday133 +birthday21 +birthday26 +birthday27 +birthday28 +birthday299 +birthday36 +birthday52 +birthday54 +blackadder +blackangel +blackberry +blackdragon +blackhawks +blackheart +blackhorse +blacklabel +blackmagic +blackmetal +blackshadow +blacksheep +blacksonblon +blackstone +blackwhite +bladerunner +blahblahblah +blingbling +blitzkrieg +bltynbabrfwbz +blueberry1 +bluedevils +bluedragon +bluemonkey +bmvm3e46gtr +bobmarley1 +bondarenko +bonneville +boredboi4u +bossyak123 +bot_schokk +boy1cool23 +Boy4u2OwnNYC +bpgjldsgjldthnf +braveheart +breakdance +brotherhood +brucewayne +bruteforce +buccaneers +bujhmbujhm +bulletproof +bullnuts2003 +bullwinkle +burgerking +bushmaster +businessbabe +butterbean +butterfly1 +bvncnbnvvbn +byajhvfnbrf +byyjrtynbq +c123456789 +c43dae874d +c43qpul5RZ +c7e4f8EzqH +cagliostro +calculator +california +California +callofduty +callofduty4 +CallSceSetup +candyeater +candyfinger +cannondale +casablanca +caterpillar +cbvtycbyjrbz +cccccccccc +cegthgegth +cegthgfhjkm +celtic1888 +cfifvfif211 +cfkfvfylhf +cfvfzcxfcnkbdfz +cfvfzkexifz +cfvfzrhfcbdfz +cgfhnfrvjcrdf +cgfhnfrxtvgbjy +cghfdjxybr +cgtkcbyuth +cgtwbfkbcn +challenger +ChangeLangMs +characters +charleston +charlie111 +charlie123 +charliedog +charlotte1 +charmander +cheaphornybastard +cheburashka +checkitout +cheerleader +cheerleaers +cheeseburger +cheesecake +chessmaster +chester123 +chesterfield +chicken123 +chickenwing101 +chinchilla +chocolate1 +chocolate2 +chrisbrown +christiaan +christian1 +christophe +christopher +Christopher +christopher1 +chucknorris +chupakabra +cincinnati +cinderella +cippalippa +civilization +cjcfnmdctv +cjdthitycndj +cjybthbrcjy +ckfltymrfz +clementine +clubpenguin +cnfc35762209 +cnfdhjgjkm +cnfhjghfvty +cnfnbcnbrf +cnhjbntkmcndj +cnjvfnjkju +coccinella +cockgobbler +cocksucker +colchester +collection +combat123654 +comedyclub +comicbookdb +comicbooks +commercial +compatible +compliance +computador +computadora +computer12 +computer123 +confidence +connection +constantin +constantine +constitution +construction +consultant +consulting +contortionist +contrasena +controller +coolbugi2000 +coorslight +copenhagen +corinthians +CORPerfMonSy +cosanostra +cosmopolitan +counterstrike +cranberries +crazyhorse +crepusculo +cristopher +ctdfcnjgjkm +cthnbabrfn +ctrnjhufpf +cumberland +cuntfinger +cuntlicker +cvzefh1gkc +cxfcnkbdfz +cxfcnkbdxbr +cxfcnmttcnm +cyberonline +cyecvevhbr +cyjdsvujljv +cytuehjxrf +CzPS5NYNDWCkSC +daddysgirl +dance4life +dancedance +danildanil +dantheman123 +darjeeling +darkknight +darthvader +dashadasha +daugavpils1 +dazdraperma +dbrnjhjdbx +dbrnjhjdyf +dctvcjcfnm +dctvghbdtn +dddddddddd +december12 +deeppurple +deepthroat +deerhunter +degenerationx +deltaforce +demolition +den1020834880 +denis12345 +denisdenis +department +depechemode +Description +desperados +destination +destruction +deutschland +devastator +DeviceClass +devildriver +devilmaycry +devilmaycry4 +dfcbkmtdyf +dfgdrb5se4 +dfktynbyrf +dhjnvytyjub +dictionary +difference +DigitalProdu +dirtysouth +dirtywhore +disneyland +diunilaobu8* +djljghjdjl +dkflbdjcnjr +dkflbvbhjdbx +dkflbvbhjdyf +dmiller12as +dodgeviper +doggystyle +dogphil3650 +dollarbill +domainlock2005 +domination +domodedovo +donaldduck +donkeykong +dontforget +dragonball +dragonballz +dragonfire +dragonforce +dragonlord +dragonslayer +dreamonline +dreamworks +drumandbass +dtynbkznjh +dunnowho89 +duranduran +dvtcntyfdctulf +e1l2e3n4a5 +e6pz84qfCJ +earthquake +edwardcullen +EFBCAPA201 +Efwe5tgwa5twhgd +eghfdktybt +ejaculation +ekaterina20 +ekx1x3k9BS +electrical +electronic +electronics +elizabeth1 +elsalvador +engineering +enterprise +Enterprise +entertainment +eqeS606898 +ereyes4269 +escaflowne +EulaComplete +evanescence +evangeline +evangelion +everything +excellence +expedition +experience +experienced +eybdthcbntn +F64579820f +fallenangel +falloutboy +fartripper +fatima753357 +fcbarcelona +fcnfkfdbcnf +fdnjhbpfwbz +felicidade +fenerbahce +ferrari360 +ffffffffff +fggjkbyfhbz +fgjkbyfhbz +fgjrfkbgcbc +fgtkmcbyrf +fgtkmcbyxbr +fighting54 +finalfantasy +Findaupair007 +fiorentina +firefighter +firestarter +firstone123 +fishfinger +fitzgerald +fkg7h4f3v6 +fkmnthyfnbdf +fktrcfylh1 +fktrcfylhf +Fktrcfylhf +fktrcfylhjd +fktrcfylhjdbx +fktrcfylhjdf +fktrcfylhjdyf +fktrcfylth +flashlight +flashpoint +flintstone +flvbybcnhfnjh +flvbybcnhfwbz +flyfishing +football10 +football11 +football12 +football123 +football22 +football24 +foreverlove +foreveryoung +forgetmenot +Formatters +forzainter +forzamilan +foundation +frankenstein +frankzappa +frederiksberg +freeaccess +freedom123 +freelancer +freelander +freetraffic +freyfvfnfnf +friendship +friendster +FROINLAVEN +FromVermine +frozenfish +fuckfuckfuck +fuckinglove +fuckingshit +fuck_inside +fuckinside +FUCK_INSIDE +fuckintits +fuckmehard +fuckmylife +fuckoff123 +fuckoff666 +fuckthemall +fucktheworld +fuckthroat +fuckyou123 +fuckyoubitch +fuckyouguys +fufnfrhbcnb +funnybunny +fyfnjkmtdbx +fyfnjkmtdyf +fynfyfyfhbde +g00dPa$$w0rD +galatasara +galatasaray +gamemaster +gangbanged +Gankutsuou1989 +gatekeeper +gblfhfcbyf +gearsofwar +general007 +generation +geniusgenius +GenuineIntel +georgetown +gerasimova +gettysburg +gfhfcjkmrf +gfhfktkjuhfv +gfhfvgfvgfv +gfhjkm1234 +gfhjkm123456 +gfhjkm2011 +gfhjkmgfhjkm +gggggggggg +ghbdtn12345 +ghbdtncerf +ghbdtndctv +ghbdtnghbdtn +ghbdtngjrf +ghbdtnrfrltkf +ghhh47hj764 +ghhh47hj7649 +ghjatccbjyfk +ghjbpdjlcndj +ghjcnbnenrf +ghjcnbnewbz +ghjcnbvtyz +ghjcnhfycndj +ghjcnjabkz +ghjcnjdkfl +ghjcnjgbpltw +ghjcnjgfhjkm +ghjcnjghjcnj +ghjcnjnfr1 +ghjcnjqgfhjkm +ghjcnjrdfibyj +ghjcnjrdfif +ghjgfufylf +ghjnbdjcnjzybt +ghjnbdjufp +ghjrehfnehf +ghjrjgtyrj +ghjuhfvbcn +ghjuhfvvbcn +ghostrecon +ghostrider +ghtdtlvtldtl +ghtpthdfnbd +gianfranco +gilbert2707 +gillingham +girlfriend +gjdtkbntkm +gjhjlfcjqrb +gjikbdctyf +gjkbnjkjubz +gjkyjkeybt +gjkysqgbpltw +gjyjvfhtdf +gjyjvfhtyrj +gjytltkmybr +gladiator5 +godisgreat +godzils4s7 +goldfinger +goldhill25 +Good123654 +goodfellas +goodmorning +googlecheckou +gordolee85 +gossipgirl +grandmaster +grandorgue +grasshopper +greatwhite +greedisgood +greenapple +greenfield +greengrass +greengreen +greenhouse +greenlantern +grimreaper +Groupd2013 +gtasanandreas +gthcgtrnbdf +gthgtylbrekzh +gthtcnhjqrf +gthtrfnbgjkt +gthtrhtcnjr +gtnhj328903 +gtnhjpfdjlcr +guadalajara +guitarhero +gunayka1995 +gundamwing +gunslinger +gunsnroses +gxLMXBeWYm +Gy3Yt2RGLs +H1Y4dUa229 +H2Tmc4g358 +h72sfibbnl +hakunamatata +hallelujah +hammerfall +hammerhead +hammertime +handkerchief +hannover96 +happyhappy +HardwareId +harekrishna +harrypotte +harrypotter +Hd764nW5d7E1vb1 +Hd764nW5d7E1vbv +headhunter +heartagram +heartbreaker +heavymetal +hedimaptfcor +heidelberg +heisenberg +helicopter +hellohello +hellokitty +hellothere +helloworld +hellraiser +hesoyam123 +h_froeschl7 +hhhhhhhhhh +hhhhhhhhhhh +highlander +highschool +hijodeputa +hilaryduff +hjpjxrf23062007 +hocuspocus +hollister1 +hollywood1 +holyspirit +hondacivic +hondas2000 +hondastars +horsepower +housemusic +housewifes +HshFD4n279 +htubcnhfwbz +huangjin1987 +hubbabubba +hubbahubba +hunnybunny +hurricanes +HypnoDanny +iaapptfcor +iamawesome +iampurehaha2 +ibpjahtybz +ibragimova +iddqdiddqd +iddqdidkfa +IdeDeviceP0T +idontknow1 +idspispopd +igeldcheat +ihateniggers +iiiiiiiiii +ilikecheese +ilikepussy +illuminati +iloveboobies +ilovegirls +iloveindia +ilovejesus +ilovemusic +ilovemyfamily +ilovemylife +ilovemyself +ilovepussy +iloveyou11 +iloveyou12 +iloveyou123 +iloveyou143 +iloveyou22 +iloveyoubaby +imagination +imjakie123 +impossible +includecatal +incredible +independent +Infalicall +informatic +information +Information +ingodwetrust +insertions +INSTALLDEVIC +InstallSqlSt +InstallUtil +intelinside +intelligence +interacial +interceptor +intercourse +interfaces +intermilan +internacional +international +intervention +investment +invincible +ipo54tj45uy856 +ironmaiden +iseedeadpeople +isvipebaby +Itachi1995 +itsasecret +ivanivanov +j123456789 +j3qq4h7h2v +jackdaniels +jackhammer +jacksparrow +jacqueline +jamesbond007 +jamesjames +jameslewis +jamiroquai +jasmine123 +jediknight +jedimaster +jeffgordon +jessejames +jesuschris +jesuschrist +jesuscristo +jesusfreak +jesusislord +jesuslives +jesuslovesme +jesussaves +jetbalance +Jhon@ta2011 +jigei743ks +Jimandanne +jjjjjjjjjj +jjjjjjjjjjjj +jkh4545jhk +jlbyjxtcndj +jmhj5464dcx +jNe990pQ23 +jobshop200 +jokerjoker +josephphone7 +juancarlos +juggernaut +juicyfruit +jumpmaster +justforfun +justinbiebe +justinbieber +JwHw6N1742 +jxfhjdfirf +k123456789 +kalashnikov +kalifornia +kaliningrad +kamehameha +kamelia2011 +kanmax1994 +karapetyan +kasablanka +katastrofa +katyakatya +kazakhstan +kbndbytyrj +kbnthfnehf +kbytqrfpkj +kd189nLciH +kensington +keraskeras +keysersoze +kickboxing +kilimanjaro +killer1234 +killkillkill +kingfisher +kirill1995 +kirill1996 +kirill1999 +kirill2002 +kirill2010 +kittykitty +kkkkkkkkkk +klapaucius +KL?benhavn +klubnichka +kmh12025476 +knickerless +knightrider +knucklehead +kobebryant +kolesnikov +kolesnikova +komltptfcor +konovalova +konstantin +kournikova +kozanostra +krasavchik +kravchenko +kriginegor +kristina123 +kristopher +kryptonite +Krzysiek12 +ktjynsq40147 +ktutjyth333 +Kudos4Ever +kurtcobain +kwiatuszek +l0sk2e8S7a +ladyffesta +lalalalala +lamborghini +lamborgini +LarterLarter +lastchance +leadership +leavemealone +Leavemealone +ledzeppelin +leedsunited +left4dead2 +leprechaun +letmein123 +letmeinnow +lfplhfgthvf +lhbjkjubz2957704 +lifeisgood +lighthouse +lightsaber +limon32988 +limpbizkit +lineage123 +linkinpark +lissalissa +littlebear +littlebitch +littlecunt +littlefuck +littlefucker +littlegirl +littlehole +littleminge +littleslut +littlewhore +liverpool1 +Liverpool1 +liverpoolfc +livestrong +lizardsquad +ljcnjtdcrbq +lk9slwGh3x +lkjhgfdsaz +lkjhgfdsazx +llllllllll +lockerroom +LockingServi +lololyo123 +loneranger +lonestar44 +loploprock +losangeles +lost4815162342 +LOST4815162342 +lothlorien +lotrfotr34 +louisvuitton +love777321777 +loveforever +lovehurts1 +loveislife +lovelovelove +loveplanet +lovezp1314 +LP2568cskt +l.qvjdjxrf +lsIA9Dnb9y +luansantana +lucifer666 +luckycharm +luckycharm3 +ludicgirls +lumberjack +luojianhua +lytdybrbdfvgbhf +lytghjgtnhjdcr +Lzhan16889 +m123456789 +m6cJy69u35 +ma123123123 +madagascar +madagaskar +made40media +magical123 +Mailcreated5240 +maintenance +maisuradze +management +manchester +Manchester +manchester1 +manchesterunited +mandarinka +mandragora +mangust6403 +mapet123456 +mapleleafs +marcuseckos +margherita +mariamaria +marinamarina +marinochka +markhegarty +marmeladka +mashamasha +masseffect +massimiliano +master1234 +masterbaiting +masterbate +masterbating +mastercard +masterchief +mastermind +masturbate +masturbation +matchbox20 +matematica +matematika +mathematics +matheus123 +mattylad10 +maurolarastefy +maximilian +maximiliano +maxmotives +mechanical +meditation +metallica1 +metropolis +MeveFalkcakk +michael123 +michaeljackson +michelangelo +mickeymouse +microphone +miguelange +milesdavis +milfhunter +millennium +millerlite +millertime +millionaire +minecraft1 +minecraft123 +minhasenha +minicooper +minnesota_hp +minniemouse +mishaoooyeah +misiaczek1 +mississipp +mississippi +mitsubishi +mmmmmmmmmm +mogwai1976 +momsanaladventure +moneymaker +moneymoney +monkeybutt +monkeynuts +monster123 +monsterkill +montecarlo +montenegro +montgom240 +montgomery +morganstanley +mortalkombat +mostwanted +motdepasse +motherfuck +motherfucker +motherlode +motorcycle +mountaindew +mousemouse +msoracle32re +multimedia +multiplelo +multiplelog +murcielago +musiclover +myjdxtcxks +mypassword +n123456789 +nakedteens +naruto2010 +narutouzumaki +nastya1995 +nastya1996 +nastya1997 +nastya1999 +nastya2010 +nastyanastya +natasha123 +naughtyboy +navigation +nccpl25282 +necromancer +necronomicon +need4speed +needforspeed +ne_e_pod_chehyl +nEMvXyHeqDd5OQxyXYZI +nesterenko +Networkingpe +NetworkingPe +neveragain +nevergiveup +neversaymypassword +neversaynever +neversmile +neverwinter +neworleans +newpassword +newproject2004 +newt7899onrs +newzealand +neznakomka +nhbujyjvtnhbz +nhbybnhjnjkejk +nhecsyfujkjdt +nhfdvfnjkju123 +nhfrnjhbcn +nhfycajhvth +nhfycajhvths +NICK1234-rem936 +Nicrasow212 +nightcrawler +nightmare1 +nightrider +nightshade +nikiforova +nikita1994 +nikita1996 +nikita1997 +nikita1998 +nikita2000 +nikita2002 +nikita2010 +nikita2011 +nikolaevna +ninjamonkey +nintendo64 +nintendods +nissan350z +Nloq_010101 +nnnnnnnnnn +nochnik104 +nokia6230i +nokiadermo +nokianokia +nomeacuerdo +nondriversig +noonehackme +nopassword +nostradamus +nottingham +novosibirsk +nthvbyfnjh +nthvbyfnjh2 +ntktdbpjh1994 +nUADdN9561 +nuttertools +nwctrinity +Oap9UTO293 +oc247ngUcZ +oduvanchik +OlCRackMaster +oldsmobile +olegnaruto +omgkremidia +onetwothree +ontheoutside +ontherocks +oooooooooo +opensesame +operations +ordinateur +orochimaru +P030710P$E4O +p0o9i8u7y6 +p51mustang +p9uJkuf36D +packardbell +painkiller +paintball1 +pandemonium +parabellum +Paraklast1974 +parliament +parolparol +pashademon +passionate +passmaster +passtrader +password00 +password01 +Password01 +password10 +password101 +password11 +password12 +Password12 +password123 +Password123 +password1234 +password13 +password21 +password22 +password23 +password33 +password69 +password88 +password99 +PASSWoRDassword +passwordpassword +passwordstandard +pathfinder +peacemaker +peanutbutter +penetrating +penetration +peppermint +perasperaadastra +percussion +perfectexploiter +perfection +performance +Performing +persephone +peternorth +peterpeter +peugeot406 +pfhfnecnhf +pflhjncndj +pfqwtd27121988 +Phezc419hV +philadelphia +philippines +philosophy +phoenix123 +photography +piggy15708 +pineapple1 +pittsburgh +pjsheridan +playground +playstatio +playstation +playstation2 +playstation3 +plextsofttm +plhfdcndeq +pocahontas +pointblank +pointbreak +poiuytrewq +pokemon123 +polina2005 +polina2008 +polina2009 +polniypizdec0211 +PolniyPizdec0211 +PolniyPizdec1102 +polniypizdec110211 +PolniyPizdec110211 +polopolo09 +ponomarenko +pornografia +pornographic +pornography +pornoporno +porovoz123 +porsche911 +portishead +portsmouth +postov1000 +powerlifting +powerpower +powerrangers +pppppppppp +praetorian +pratap1245 +premiumcash +presidente +prettygirl +primetime21 +princess12 +prisonbreak +ProductId20F +production +professional +programmer +progressive +prokopenko +prometheus +properties +prosperity +protection +providence +psychnaut1 +ptybnxtvgbjy +puertorico +pufunga7782 +pulpfiction +punksnotdead +purplehaze +pussybitch +pussyeater +pussylicker +pussylover +pussypussy +pyfrjvcndf +pyfrjvcndj +q1205199333 +q123123123 +q123456789 +q1234567890 +q1q2q3q4q5 +q1q2q3q4q5q6 +q1w2e3r4t5 +Q1w2e3r4t5 +q1w2e3r4t5y +q1w2e3r4t5y6 +q1w2e3r4t5y6u7 +q1w2e3r4t5y6u7i8 +q1w2e3r4t5y6u7i8o9p0 +q2w3e4r5t6 +q2w3e4r5t6y7 +q80661658441 +qawsedrftg +qawsedrftgyh +qaz123wsx456 +qaz1wsx2edc3 +qaz26101778 +qazwsx1234 +qazwsx12345 +qazwsx123456 +qazwsxedc1 +qazwsxedc12 +qazWSXedc12 +qazwsxedc123 +qazwsxedcrf +qazwsxedcrfv +qazwsxedcrfvtgb +qazwsxqazwsx +qazxswedc123 +qazxswedcvfr +..qlVVcvDeeRo +qpwoeiruty +qq123456789 +qqqqqqqqqq +qrg7t8rhqy +quant4307s +quarantine +queenas8151 +quicksilver +quiksilver +qw12er34ty56 +qwaszxerdfcv +qwaszxqwaszx +Qwe1234567 +qwe123qwe123 +qweasdzxc1 +qweasdzxc12 +qweasdzxc123 +qwerasdfzxcv +qwert12345 +qwert54321 +qwertasdfg +qwertasdfgzxcvb +qwertgfdsa +qwertqwert +qwerttrewq +qwerty123321 +qwerty1234 +qwerty12345 +Qwerty12345 +qwerty123456 +qwerty123456789 +qwerty1992 +qwerty1993 +qwerty2000 +qwerty2010 +qwerty54321 +qwertyasdf +qwertyasdfg +qwertyasdfgh +qwertyqwerty +qwertyu123 +qwertyuiop +QWERTYUIOP +qwertyuiop1 +qwertyuiop10 +qwertyuiop12 +qwertyuiop123 +qwertyuiop12345 +qwertyuiop123456789 +qwertyuiopasdfg +qwertyuiopasdfgh +qwertyuiopasdfghjkl +qwertyytrewq +qwertzuiop +qwqwqwqwqw +r3r3vi3wacc3ss +R3Vi3Wpass +rainbowsix +rainforest +rammstein1 +rangerover +rashley198 +rattlesnake +razorblade +realmadrid +reanimator +redemption +registration +relentless +rendezvous +rerhsybrcs +residentevil +resistance +respublika +retribution +revelation +reviewpass +revolution +reymisterio +reymysterio +rfcgthcrbq +rfgecnfcerf +rfhfrfnbwf +rfhfvtkmrf +rfkbajhybz +rfkbybyuhfl +rfkfiybrjd +rfkmrekznjh +rfnfcnhjaf +rfnfgekmnf +Rfnthbyf1988 +rfnthbyjxrf +rfrfirf123 +rhbcnbyf123 +rhbcnbyjxrf +rhfcyjzhcr +rhfvfnjhcr +richardson +rikitikitavi +riverplate +rjcvtnbxrf +rjhjkmbien +rjirfrgbde +rjkjrjkmxbr +rjycnbnewbz +rjycnfynby +Rjycnfynby +rjyjdfkjdf +rjytwcdtnf +rkfdbfnehf +roadrunner +rockandroll +rockbottom +rockhopper +rockohamster +roflcopter +romanroman +ronaldinho +ronaldinho10 +ronaldo123 +rottweiler +rrrrrrrrrr +rubberduck +ruffryders +runescape1 +runescape123 +s123456789 +s456123789 +sacramento +sagitarius +sagittarius +sailormoon +salamander +salamandra +salmankhan +salocaluimsg +samsung123 +samsungs5230 +sanandreas +sanfrancisco +santaclaus +santaklaus +santamaria +saqartvelo +sasa123321 +sasasasasa +sasha12345 +sashasasha +Sataniv1993 +satisfaction +SaUn24865709 +scandinavian +schoolgirlie +schumacher +scoubidou2 +scoubidou6 +scratchman +scubadiver +sdh686drth +sdicmt7seytn +sebastian1 +seemnemaailm +sektorgaza +selfok2013 +seniseviyor +seo21SAAfd23 +serendipity +serg123111 +sergeevich +sergey2010 +serggalant +sersolution +service321 +sevastopol +sexmachine +sexpistols +sfhj5484fgh +shadow1212 +shakespeare +shamanking +shevchenko +shithappens +showmethemoney +sidewinder +silenthill +silmarillion +silvermoon +silverstar +silverstone +simferopol +simpleplan +skateboard +skateboarding +skateordie +skorpion39 +skylinegtr +skyliner34 +skywalker1 +sleepyhollow +slipknot123 +slipknot66 +slipknot666 +slonopotam +slushslush +sm4llville +smallville +smeshariki +Smokie1994 +snusmumrik +Sojdlg123aljg +solidsnake +something1 +sonnenschein +sonyericsson +Soso123aljg +Soso123bbb +southampton +spam967888 +spartak1922 +spartan117 +SpecialInsta +specialist +specialized +spiderman1 +spiderman2 +spiderman3 +splurgeola +spongebob1 +springfield +sS6z2sw6lU +ssssssssss +stabilmente +stalingrad +stalker123 +stalker2010 +stalker777 +starcraft1 +starcraft2 +stargatesg1 +starscream +starwars12 +starwars123 +statistika +steamforums +stefanescu +stensten12 +stephanie1 +stevesmojo +stickdaddy77 +stinkyfinger +stomatolog +stonehenge +stratocaster +strawberry +streetball +stronghold +studioworks +studmuffin +subhanallah +submission +subscriber +successful +suckmyballs +suckmycock +suckmydick +summer2010 +summertime +sundaypunch +sunderland +sunflower1 +sunglasses +sunshine69 +superduper +superman12 +superman123 +superman69 +SuperManBoy +supermario +supermodel +supernatural +superpower +superpuper +supersonic +supersport +supersuper +supervisor +sutherland +sutvsc5ysaa +svensps820 +svetasveta +sweepstakes +sweetdream +sweetdreams +sweetheart +sweetiepie +sweetpussy +sweetsweet +sylviahans +syncmaster +SyncMaster +syncmaster740n +systemofadown +t123456789 +t34vfrc1991 +t5r4e3w2q1 +table54781 +tadmichaels +tAMwsN3sja +taser334455 +taylormade +tdfyutkbjy +technician +techniques +technology +telecaster +television +TempPassWord +terminator +testing123 +tfjunwptzsjp +thebeatles +thecakeisalie +thegreatone +thesimpsons +thiaguinho +thirteen13 +throatfuck +thugstools +thunder123 +thunderbird +thunderbolt +thundercat +ticketmaster +tigertiger +tigerwoods +tihomirova +timberlake +timberland +timberwolf +tinkerbell +Tojiik85521133 +tokiohotel +TokioHotel +tombraider +tottenham1 +trafficracer +traktorist +transexual +transformer +transformers +transistor +Translator +transporter +travelmate +trustnoone +tttttttttt +tumbleweed +tupacshakur +tylerca310 +ublhjgjybrf +ubnkthrfgen +ubvyfcnbrf +uehby92pac +ufdyfrecjr +ufhhbgjnnth +ujkjdjkjvrf +unbelievable +uncencored +undercover +undergroun +underground +understand +undertaker +underwater +underworld +unforgiven +UninstallSql +uniqueness +universidad +university +userexecute +Usuckballz1 +utyyflmtdyf +uuuuuuuuuu +v123456789 +vaffanculo +valentinka +vanderbilt +vanyarespekt +vbhjndjhtw +vbybcnthcndj +vbyfcnbhbn +vEf6g55frZ +velocidade +venom121293 +verygoodbot +vesy7csae64 +vfhbyfvfhbyf +vfhufhbnrf +vfhvtkflrf +vflfufcrfh +vfntvfnbrf +vfrcbvtyrj +vfrcbvvfrcbv +vfuybnjajy +vfvfgfgf123 +vfvfvskfhfve +vfylfhbyrf +vfylhfujhf +viktorovich +villeneuve +vinogradov +vinogradova +virtuagirl +vitalik123 +vladimirovna +vladislava +vladivostok +volkswagen +volkswagon +volleyball +voxstrange +vp3whbjvp8 +VQsaBLPzLa +Vsavb7rtUI +vSjasnel12 +vtkmybrjdf +vtnhjgjkbnty +vvvvvvvvvv +vyjujltytu +vyjujnjxbt +w123456789w +w1w2w3w4w5 +w2dlWw3v5P +wachtwoord +walkman555 +wallstreet +warhammer40k +washington +waterfalls +watermelon +wazzkaprivet +wcrfxtvgbjy +weaknesspays +webhompass +websolutions +websolutionssu +WebUIValidat +weihnachte +weihnachten +weihnachtsbau +welcome123 +wellington +wenef45313 +werty12345 +westminster +wethepeople +whatthefuck +whatthehell +whitehouse +whitepower +whiterabbit +whosyourdaddy +widescreen +widespread +wildflower +winchester +winnipeg261 +winstonone +wishmaster +witchblade +wolfenstein +wolverines +wonderland +wonderwall +wonderwoman +wrestling1 +writerspace +wsx22wsx22 +wutangclan +wwwooo1234 +wwwwwwwwww +xiaoyuA123 +xpressmusic +xtkjdtrgfer +xxPa33bq.aDNA +xxxp455w0rd5 +xxxxxxxxxx +yanshi1982 +ybrjkftdbx +ybrjkftdyf +yfcnhjtybt +yfcnzyfcnz +yflz13041976 +yfnfif2010 +yfnfitymrf +yjdjrepytwr +yjdjvjcrjdcr +yjdsqgfhjkm +yK66o2kzpZ +yoshimitsu +youngmoney +yourmother +ytdpkjvfti +ytpfdbcbvjcnm +ytpyfrjvrf +ytrhjvfycth +ytrhjvfyn10 +yurkamaliy +z123456789 +z1234567890 +z1x2c3v4b5 +z1x2c3v4b5n6 +z1x2c3v4b5n6m7 +z1z2z3z4z5 +zaq12wsxcde3 +zaq1xsw2cde3 +zaqwsxcderfv +zaqxswcde123 +zaratustra +zcfvfzkexifz +zcfvfzrhfcbdfz +zcxfcnkbdf +zcxfcnkbdfz +zelenograd +zexts364325 +zghjcnjcegth +zjses9evpa +zn87x54mxma +zobrdjlrb1 +zQjphsyf6ctifgu +zsxmr7sztmr +zx123456789 +zxcasdqwe123 +zxcvasdfqwer +zxcvb09876 +zxcvb12345 +Zxcvb12345 +zxcvbasdfg +zxcvbn123456 +zxcvbn3215 +zxcvbnm123 +zxcvbnm123456789 +zxcvbnmmnbvcxz +zxcvbnmzxcvbnm +zxcvbzxcvb +zzzzzzzzzz \ No newline at end of file diff --git a/lib/common_passwords/common_passwords.rb b/lib/common_passwords/common_passwords.rb index 9925b608270..0045cc8a366 100644 --- a/lib/common_passwords/common_passwords.rb +++ b/lib/common_passwords/common_passwords.rb @@ -1,5 +1,7 @@ # CommonPasswords will check a given password against a list of the most commonly used passwords. -# The list comes from https://xato.net/passwords/more-top-worst-passwords/#.UrR1AHmpxs4 +# The list comes from https://github.com/danielmiessler/SecLists/tree/master/Passwords +# specifically the list of 10 million passwords, top 100k, filtered by length +# # The list is stored in Redis at a key that is shared by all sites in a multisite config. # # If the password file is changed, you need to add a migration that deletes the list from redis @@ -9,7 +11,7 @@ class CommonPasswords - PASSWORD_FILE = File.join(Rails.root, 'lib', 'common_passwords', 'long-common-passwords.txt') + PASSWORD_FILE = File.join(Rails.root, 'lib', 'common_passwords', '10-char-common-passwords.txt') LIST_KEY = 'discourse-common-passwords' @mutex = Mutex.new @@ -19,7 +21,6 @@ class CommonPasswords password_list.include?(password) end - private class RedisPasswordList diff --git a/lib/common_passwords/long-common-passwords.txt b/lib/common_passwords/long-common-passwords.txt deleted file mode 100755 index 72e120360cd..00000000000 --- a/lib/common_passwords/long-common-passwords.txt +++ /dev/null @@ -1,2086 +0,0 @@ -password -12345678 -baseball -football -jennifer -superman -trustno1 -michelle -sunshine -123456789 -starwars -computer -corvette -princess -iloveyou -maverick -samantha -steelers -whatever -hardcore -internet -mercedes -bigdaddy -midnight -11111111 -marlboro -victoria -butthead -startrek -liverpoo -danielle -redskins -mountain -shithead -xxxxxxxx -88888888 -nicholas -metallic -qwertyui -dolphins -cocacola -rush2112 -jonathan -scorpion -asdfasdf -godzilla -williams -lifehack -platinum -garfield -69696969 -jordan23 -bullshit -airborne -elephant -explorer -christin -december -benjamin -dickhead -brooklyn -redwings -michigan -87654321 -guinness -einstein -snowball -alexande -passw0rd -lasvegas -slipknot -kimberly -1q2w3e4r -carolina -colorado -creative -bollocks -darkness -asdfghjk -poohbear -nintendo -november -password1 -lacrosse -paradise -maryjane -spitfire -anderson -cherokee -drowssap -marshall -1qaz2wsx -caroline -franklin -snickers -courtney -westside -patricia -semperfi -freeuser -babygirl -champion -softball -security -wildcats -veronica -abcd1234 -wolverin -remember -freepass -pearljam -mistress -peekaboo -budlight -electric -stargate -brittany -swimming -scotland -swordfis -blink182 -virginia -passport -aaaaaaaa -rolltide -bulldogs -liverpool -chevelle -mitchell -spiderma -patriots -cardinal -kawasaki -ncc1701d -airplane -scarface -elizabet -wolfpack -lawrence -american -stingray -simpsons -srinivas -panthers -pussycat -loverboy -tarheels -wolfgang -testtest -michael1 -pakistan -infinity -letmein1 -hercules -billybob -pavilion -changeme -darkside -zeppelin -darkstar -charlie1 -wrangler -qwerty12 -bobafett -business -sterling -babydoll -cheyenne -longhorn -presario -mustang1 -21122112 -q1w2e3r4 -12341234 -devildog -bluebird -metallica -access14 -enterpri -blizzard -asdf1234 -harrison -thailand -1234567890 -cadillac -hellfire -lonewolf -12121212 -fireball -precious -engineer -basketba -valentin -wetpussy -morpheus -hotstuff -fuck_inside -goldberg -wrinkle1 -consumer -serenity -99999999 -bigboobs -chocolat -christia -birthday -stephani -1234qwer -98765432 -77777777 -highland -seminole -airforce -hamilton -buckeyes -abcdefgh -goldfish -deftones -icecream -pleasure -juventus -ncc1701e -51505150 -cavalier -aardvark -babylon5 -savannah -yankees1 -fredfred -concrete -shamrock -atlantis -wordpass -predator -marathon -montreal -kathleen -jessica1 -diamonds -stallion -letmein2 -clitoris -sundance -renegade -hollywoo -hello123 -sweetpea -stocking -campbell -christop -rockstar -geronimo -chandler -lovelove -greenday -987654321 -creampie -trombone -55555555 -mongoose -tottenha -butterfl -clifford -fuckyou2 -infantry -skywalke -raistlin -vanhalen -sherlock -dietcoke -ultimate -superfly -freedom1 -drpepper -lesbians -musicman -warcraft -microsoft -morrison -isabelle -thuglife -stonecol -logitech -florence -1passwor -bluemoon -22222222 -stardust -margaret -66666666 -charlott -waterloo -11223344 -standard -alexandr -hannibal -frontier -welcome1 -spanking -japanese -kristina -deepthroat -bonehead -showtime -squirrel -mustangs -septembe -leonardo -makaveli -vacation -passwor1 -columbia -napoleon -motorola -william1 -matthew1 -robinson -penguins -8j4ye3uz -californ -qwertyuiop -portland -asdfghjkl -overlord -stranger -socrates -spiderman -13131313 -national -intrepid -megadeth -bigballs -chargers -discover -isabella -megapass -grateful -mushroom -cristina -hongkong -basketball -satan666 -kingkong -penelope -thompson -anything -knickers -playtime -lightnin -slapshot -titleist -werewolf -fernando -blackcat -tacobell -kittycat -thunder1 -thankyou -scoobydo -coltrane -lonestar -heather1 -beefcake -zzzzzzzz -personal -anthony1 -fuckface -lowrider -punkrock -dodgeram -dingdong -qqqqqqqq -johnjohn -asshole1 -crusader -syracuse -meridian -turkey50 -keyboard -ilovesex -blackman -richmond -sandiego -cooldude -mariners -caliente -fletcher -porsche9 -kangaroo -springer -goodtime -chelsea1 -freckles -nebraska -webmaster -blueeyes -director -monopoly -blackjac -southern -peterpan -fuckyou1 -a1b2c3d4 -sentinel -richard1 -1234abcd -guardian -candyman -mandingo -munchkin -billyboy -rootbeer -assassin -frederic -giovanni -scarlett -achilles -warriors -plymouth -cameltoe -fuckfuck -sithlord -backdoor -chevrole -lorraine -cosworth -eternity -verbatim -chocolate -deadhead -pineappl -rosemary -porkchop -blackdog -alexander -valhalla -santiago -portugal -1qazxsw2 -stripper -sebastia -hurrican -1x2zkg8w -atlantic -hyperion -44444444 -skittles -hastings -gangbang -sailboat -immortal -maryland -columbus -beautiful -swordfish -ncc1701a -spartans -threesom -dilligaf -pinkfloy -catalina -formula1 -scooter1 -colombia -lancelot -angelica -rockhard -poontang -starship -starbuck -catherin -kentucky -33333333 -12344321 -sapphire -raiders1 -excalibu -imperial -phillips -golfball -front242 -macdaddy -qwer1234 -cowboys1 -dannyboy -martinez -aquarius -pppppppp -clarence -eatpussy -beatrice -phillies -research -gggggggg -doughboy -lollipop -qazwsxed -crazybab -brothers -butthole -rightnow -greatone -gateway1 -wildfire -jackson1 -0.0.0.000 -snuggles -phoenix1 -technics -gesperrt -brucelee -woofwoof -theodore -richards -punisher -username -bunghole -elizabeth -lifetime -masterbate -diamond1 -abnormal -davidson -starfish -penetration -michaela -caligula -railroad -bradford -military -bearbear -patrick1 -christine -swinging -labrador -justdoit -meatball -saturday -defender -piercing -microsof -mechanic -robotech -universe -newpass6 -hellyeah -zaq12wsx -spectrum -jjjjjjjj -oklahoma -mmmmmmmm -blueblue -wolverine -sniffing -keystone -bbbbbbbb -handsome -tttttttt -ssssssss -somethin -melissa1 -marcius2 -godsmack -rangers1 -deeznuts -kingston -yosemite -tommyboy -masterbating -marianne -happyday -manchest -unbelievable -aberdeen -nathalie -intercourse -supersta -bcfields -hardrock -children -commando -sinclair -squerting -jeanette -meathead -gandalf1 -magnolia -kenworth -redalert -homemade -webmaste -insertion -temptress -gretchen -celebrity -ragnarok -trinidad -kingfish -blackhaw -thursday -meatloaf -interacial -streaming -pertinant -pool6123 -animated -gordon24 -fantasies -touching -homepage -ejaculation -whocares -jamesbon -amsterda -february -luckydog -businessbabe -brandon1 -experience -software -thirteen -rasputin -greenbay -pa55word -contortionist -sneakers -sonyfuck -test1234 -roadkill -cheerleaers -madeline -christian -brighton -housewifes -emmanuel -bigmoney -seductive -sexygirl -canadian -gangbanged -crawford -hotpussy -implants -intruder -andyod22 -barcelon -chainsaw -chickens -downtown -magicman -clevelan -designer -budweise -experienced -pitchers -passwords -jeremiah -alliance -halflife -saratoga -positive -transexual -close-up -sunnyday -starfire -pictuers -testing1 -tiberius -lisalisa -golfgolf -flounder -majestic -trailers -mikemike -whitesox -angelina -goodluck -charlton -fingerig -gallaries -lockerroom -treasure -absolutely -homepage- -beerbeer -testerer -fordf150 -pa55w0rd -kamikaze -japanees -masterbaiting -callaway -panasoni -housewife -18436572 -sullivan -terrapin -masturbation -hardcock -freeporn -pornographic -traveler -moneyman -shopping -thumbnils -amateurs -apollo13 -goldwing -doghouse -pounding -truelove -underdog -wrestlin -sherwood -johannes -balloons -happy123 -flamingo -paintbal -llllllll -twilight -christie -bullseye -knickerless -binladen -peterson -thanatos -albatros -getsdown -nwo4life -underwear -dddddddd -deeznutz -enterprise -misfit99 -solution -meredith -barefoot -50spanks -scandinavian -original -shannon1 -techniques -chemical -salvador -manchester -buckshot -thegreat -goldstar -triangle -kristine -snowboar -penetrating -roadking -rockford -chicago1 -ferrari1 -galeries -godfathe -gargoyle -gangster -pussyman -pooppoop -newcastl -mortgage -snoopdog -assholes -property -broadway -butterfly -earthlink -westwood -blackbir -slippery -pianoman -tomorrow -roadrunn -attitude -seahawks -tunafish -cinnamon -northern -23232323 -zerocool -limewire -films+pic+galeries -francois -fuckthis -girfriend -uncencored -chrisbln -netscape -hhhhhhhh -knockers -tazmania -pharmacy -arsenal1 -anaconda -australi -gotohell -bulldog1 -monalisa -whiteout -james007 -bitchass -southpar -lionking -megatron -hawaiian -gymnastic -panther1 -wp2003wp -passwort -friendly -oooooooo -bullfrog -holyshit -jasmine1 -sergeant -babyblue -pass1234 -poseidon -confused -hollywood -insertions -juliette -hayabusa -hawkeyes -geoffrey -chuckles -hounddog -philippe -thunderb -marino13 -handyman -cerberus -gamecock -magician -preacher -chrysler -contains -hedgehog -hoosiers -dutchess -wareagle -ihateyou -sunflowe -senators -terminal -laurence -maradona -america1 -chicken1 -passpass -r2d2c3po -myxworld -missouri -wishbone -infiniti -wonderboy -stanford -smeghead -titanium -charlene -fishing1 -fullmoon -absolute -seinfeld -pingpong -matthews -recovery -babyface -gladiato -paranoid -packers1 -longjohn -clarinet -mortimer -modelsne -vladimir -together -avalanch -55bgates -cccccccc -paradigm -operator -valencia -cocksuck -creature -borussia -browning -heritage -millions -starcraf -spaceman -chester1 -rrrrrrrr -sandwich -magazine -buttfuck -yeahbaby -11235813 -bangbang -charles1 -ffffffff -doberman -overkill -claymore -brewster -electron -eastside -minimoni -wildbill -wildcard -yyyyyyyy -sweetnes -skywalker -alphabet -babybaby -graphics -florida1 -flexible -fuckinside -ursitesux -christma -wwwwwwww -just4fun -rebecca1 -adrienne -19691969 -silverad -rhiannon -10101010 -ashleigh -qwerasdf -presiden -newyork1 -brigitte -buddyboy -heineken -millwall -beautifu -sinister -smashing -teddybea -ticklish -lipstick -reynolds -applepie -digital1 -dinosaur -icehouse -insanity -bluefish -strength -sentnece -temppass -medicine -hahahaha -casanova -fountain -dolphin1 -porsche1 -vampires -highheel -kkkkkkkk -illinois -21212121 -stonecold -testpass -jiggaman -federico -scorpio1 -rt6ytere -madison1 -coolness -christina -coldbeer -brittney -washingt -stephanie -shepherd -tiffany1 -mephisto -dragonba -nygiants -password2 -corleone -kittykat -vikings1 -splinter -pipeline -meowmeow -chestnut -longdong -quant4307s -eastwood -moonligh -illusion -jayhawks -swingers -stefanie -jefferso -michael2 -fastball -scrabble -dirtbike -customer -nemrac58 -bobdylan -hopeless -kcj9wx5n -killbill -volkswag -windmill -iloveyou1 -starligh -soulmate -mcdonald -rochelle -oblivion -valkyrie -concorde -costello -delaware -nocturne -herewego -earnhard -eeeeeeee -mobydick -reddevil -reckless -radiohea -coolcool -classics -choochoo -wireless -bigblock -summer99 -sexysexy -platypus -telephon -12qwaszx -fishhead -paramedi -lonesome -katherin -moonbeam -monster1 -monkeybo -windsurf -31415926 -sebastian -smoothie -snowflak -playstat -playboy1 -roadster -hardware -captain1 -undertak -uuuuuuuu -criminal -1a2b3c4d -thedoors -annabell -catwoman -faithful -farscape -genesis1 -pumpkins -training -islander -jamesbond -19841984 -shitface -maxwell1 -armstron -alejandr -augustus -care1839 -fantasia -freefall -sandrine -qwerqwer -crystal1 -nineinch -broncos1 -winston1 -warrior1 -iiiiiiii -iloveyou2 -straight -specialk -tinkerbe -jellybea -cbr900rr -gabriell -gertrude -glennwei -sausages -vanguard -trinitro -eldorado -whiskers -wildwood -istheman -interest -25802580 -woodland -strawber -amsterdam -catherine -football1 -vancouve -vauxhall -acidburn -myspace1 -buttercu -minemine -bigpoppa -blackout -blowfish -talisman -sundevil -shanghai -spencer1 -slowhand -jonathon -michaels -resident -redbaron -andromed -harddick -5wr2i7h8 -charlotte -fredrick -francesc -ferguson -fairlane -dogpound -pornporn -clippers -daylight -nnnnnnnn -budapest -whistler -whatwhat -wanderer -idontkno -thisisit -robotics -gonzalez -drummer1 -private1 -cornwall -christopher -corvet07 -iverson3 -bluesman -terminat -johnson1 -bastards -fuckoff1 -doomsday -pornking -bookworm -highbury -mischief -ministry -bigbooty -yogibear -september -lkjhgfds -123123123 -carpedie -foxylady -gatorade -valdepen -deadpool -hotmail1 -kordell1 -vvvvvvvv -jackson5 -bergkamp -zanzibar -services -sheridan -checkers -luv2epus -rainbow6 -qwerty123 -commande -nightwin -hotmail0 -enternow -viewsoni -berkeley -woodstoc -starstar -patience -hawaii50 -gorgeous -challeng -callisto -firewall -firefire -passmast -transfer -clarissa -moonshin -jakejake -bluejays -southpark -tomahawk -leedsutd -jermaine -jeepster -josephin -matthias -marriage -antelope -cabernet -cheshire -california -fuckhead -dominion -trucking -nostromo -honolulu -dynamite -mollydog -windows1 -washburn -vincent1 -irishman -bearcats -sylveste -marijuan -reddwarf -12312312 -hardball -goldfing -chambers -fandango -festival -scrapper -cromwell -entrance -klondike -mohammed -insomnia -24682468 -24242424 -billbill -blessing -solitude -pimpdadd -johndeer -babylove -barbados -carpente -fishbone -fireblad -scissors -screamer -obsidian -progress -tottenham -comanche -monsters -veronika -20202020 -blueball -yankees2 -wrestler -sealteam -sidekick -smackdow -sporting -remingto -arkansas -andersen -barcelona -baltimor -fortress -fishfish -firefigh -rsalinas -dontknow -universa -heinrich -enforcer -katherine -waterboy -23skidoo -zildjian -stoppedby -sexybabe -speakers -polopolo -perfect1 -thrasher -lakeside -masamune -cherries -chipmunk -cezer121 -carnival -fearless -funstuff -salasana -pantera1 -qwert123 -creation -nascar24 -estrella -erection -ericsson -internal -1michael -19781978 -25252525 -sheepdog -snowbird -toriamos -tennesse -mazdarx7 -revolver -babycake -hallowee -cannabis -dolemite -dodgers1 -painting -coventry -christmas -cocksucker -hotgirls -eggplant -mustang6 -monkey12 -wapapapa -volleyba -birthday4 -stephen1 -suburban -soccer10 -something -starcraft -soccer12 -plastics -penthous -peterbil -lakewood -reginald -goodgirl -gotyoass -capricor -getmoney -godfather -gilligan -dudedude -pasadena -opendoor -magellan -printing -pressure -killkill -whiteboy -voyager1 -jackjack -success1 -spongebo -phialpha -password9 -tickling -lexingky -redheads -apple123 -backbone -aviation -green123 -carlitos -cartman1 -camaross -favorite6 -ginscoot -sabrina1 -devil666 -doughnut -paintball -rainbow1 -umbrella -abc12345 -complete -deerhunt -darklord -holidays -hetfield -hillbill -hugetits -evolutio -whiplash -wg8e3wjf -istanbul -bluebell -wrestling -superior -suckdick -stephane -playball -marcello -marjorie -rockwell -baritone -gladiator -cricket1 -clemente -exchange -kisskiss -kristian -montecar -mississi -washington -20012001 -bigdick1 -penguin1 -pathfind -testibil -lightning -lighting -republic -anthony7 -goldeney -cameron1 -freefree -screwyou -passthie -postov1000 -puppydog -a1234567 -cleopatr -contract -buffalo1 -bordeaux -sunlight -sprinter -peaches1 -pinetree -theforce -jupiter1 -mckenzie -annmarie -austin31 -78945612 -calimero -chevrolet -favorite -fellatio -f00tball -francine -gateway2 -gamecube -giovanna -scheisse -offshore -macaroni -pringles -trouble1 -coolhand -colonial -darthvad -cygnusx1 -natalie1 -eighteen -elcamino -blueberr -yamahar1 -stafford -snowboard -speedway -playboy2 -toonarmy -mariposa -baberuth -gonzales -chiquita -charisma -capslock -cashmone -gizmodo1 -dragonfl -rachelle -tropical -crescent -nathanie -espresso -kikimora -20002000 -birthday1 -beatles1 -bigdicks -beethove -blacklab -woodwork -survivor -pinnacle -lemonade -lalakers -lebowski -lalalala -mercury1 -rocknrol -riversid -11112222 -alleycat -ambrosia -australia -hattrick -cassandr -charlie123 -fighting -gabriela -outoutout -pussy123 -randolph -coldplay -novifarm -notredam -honeybee -wednesda -waterfal -billabon -zachary1 -01234567 -superstar -stiletto -sigmachi -somerset -smithers -playmate -pinkfloyd -laetitia -revoluti -archange -handball -chewbacc -fullback -dominiqu -mandrake -vagabond -csfbr5yy -deadspin -ncc74656 -houston1 -hurricane -horseman -virginie -idontknow -151nxjmt -bendover -surprise -supernov -phantom1 -playoffs -johngalt -maserati -riffraff -architec -cambridg -foreplay -sanity72 -salesman -dreaming -palmtree -luckyone -treefrog -usmarine -darkange -cyclones -bubba123 -building -eclipse1 -kayleigh -mustang2 -bigtruck -yeahyeah -stickman -skipper1 -singapor -southpaw -slamdunk -therock1 -tiger123 -mccarthy -13576479 -greywolf -candyass -catfight -frankie1 -qazwsxedc -pregnant -death666 -negative -hooligan -everlast -mulligan -motocros -waterman -inspiron -bigblack -zaq1xsw2 -yy5rbfsc -takehana -skydiver -special1 -slimshad -sopranos -patches1 -thething -mash4077 -matchbox -14789632 -amethyst -baseball1 -greenman -goofball -castillo -capitals -favorite2 -forsaken -feelgood -gfxqx686 -dilbert1 -dukeduke -downhill -longhair -lockdown -mamacita -rainyday -pumpkin1 -prospect -rainbows -trinity1 -trooper1 -citation -bukowski -bubbles1 -humphrey -kcchiefs -morticia -montrose -154ugeiu -year2005 -wonderfu -tampabay -slapnuts -spartan1 -sprocket -sometime -stanley1 -thinking -lavalamp -laserjet -jediknig -mazda626 -alexandra -hairball -graduate -cartoons -cashflow -outsider -mallrats -primetime21 -valleywa -abcdefg1 -natedogg -nineball -normandy -nicetits -buddy123 -highlife -earthlin -eatmenow -kirkland -money123 -warhamme -instinct -jackass1 -20spanks -blackjack -085tzzqi -383pdjvl -sparhawk -pavement -johnston -material -melanie1 -redlight -aolsucks -alexalex -b929ezzh -goodyear -griffith -863abgsg -carebear -checkmat -forgetit -rushmore -question -ptfe3xxp -prophecy -aircraft -access99 -cocktail -civilwar -cleveland -claudia1 -dapzu455 -daisydog -eldiablo -kingrich -mudvayne -vipergts -italiano -innocent -yqlgr667 -zxcvbnm1 -suckcock -stephens -380zliki -sexylady -sixtynin -sleeping -sparkles -letsdoit -landmark -marauder -register -basebal1 -azertyui -hawkwind -capetown -flathead -fisherma -flipmode -gabriel1 -dreamcas -dirtydog -dickdick -destiny1 -trumpet1 -aaaaaaa1 -conquest -creepers -constant -cornhole -nirvana1 -elisabet -musician -milamber -isacs155 -1million -1letmein -stonewal -sexsexsex -sonysony -smirnoff -pentagon -paulpaul -lighthou -letmein22 -letmesee -merchant -redstorm -14141414 -allison1 -basement -hartford -hardwood -fatluvr69 -fidelity -feathers -gogators -general1 -dragon69 -dragonball -papillon -optimist -longshot -undertow -copenhag -delldell -culinary -ibilltes -hihje863 -envelope -express1 -mustang5 -wellingt -waterski -infinite -iloveyou! -063dyjuy -survival -stockton -softtail -slimed123 -pizzaman -pathetic -tigercat -jennings -rootedit -riverrat -atreides -happines -chadwick -ffvdj474 -foreskin -gameover -scoobydoo -saxophon -macintos -lollypop -qwertzui -adelaide -acapulco -cybersex -davecole -davedave -nineteen -highlander -kristin1 -knuckles -katarina -montana1 -wingchun -watching -illmatic -bigpenis -blue1234 -xxxxxxx1 -svetlana -368ejhih -playstation -pescator -jo9k2jw2 -jupiter2 -jurassic -marines1 -14725836 -12345679 -alessand -angelika -alpha123 -barefeet -badabing -gsxr1000 -gregory1 -766rglqy -69camaro -calendar -fishcake -giuseppe -gnasher23 -fuzzball -save13tx -russell1 -dripping -dragon12 -dragster -mainland -poophead -porn4life -producer -rapunzel -velocity -vanessa1 -trueblue -vampire1 -navyseal -nightowl -nonenone -nightmar -bulletin -hillside -hzze929b -hellohel -edgewise -embalmer -excalibur -mounta1n -muffdive -vivitron -winfield -wednesday -17171717 -17011701 -tangerin -stewart1 -summer69 -sweetness -surveyor -stirling -ssptx452 -thriller -master12 -anastasi -almighty -argentin -flanders -flyers88 -firehawk -flashman -godspeed -giveitup -funtimes -frenchie -disaster -lovelife -qcmfd454 -undertaker -911turbo -cristian -daughter -notebook -borabora -brisbane -mohammad -bettyboo -blackice -yvtte545 -tailgate -shitshit -sooners1 -smartass -pennywis -thetruth -reindeer -allstate -greatest -caldwell -fussball -geneviev -samadams -dipstick -losangel -loverman -pussy4me -university -troubles -churchil -crazyman -cutiepie -bullwink -bulldawg -horsemen -escalade -minnesot -moonlight -mwq6qlzo -verygood -bellagio -sickness -skeeter1 -phaedrus -thumper1 -tmjxn151 -thematri -letmeinn -jeffjeff -johnmish -11001001 -allnight -amatuers -attorney -happyman -graywolf -474jdvff -551scasi -fishtank -freewill -glendale -frogfrog -gerhardt -scirocco -devilman -pallmall -lunchbox -manhatta -mandarin -pxx3eftp -president -chris123 -daedalus -natasha1 -nancy123 -nevermin -newcastle -edmonton -monterey -violator -wildstar -winter99 -iqzzt580 -19741974 -1q2w3e4r5t -bigbucks -blackcoc -yesterda -skinhead -shadow12 -snapshot -soccer11 -pleasant -pimpdaddy -lionhear -littlema -lincoln1 -laughing -redshift -12locked -arizona1 -alfarome -hawthorn -goodfell -554uzpad -flipflop -garrison -rustydog -sandberg -samsung1 -dreamer1 -detectiv -dominick -paladin1 -papabear -panasonic -nyyankee -pussyeat -princeto -climbing -dad2ownu -daredevi -necklace -huskers1 -hornyman -england1 -motherfucker -ilovegod -201jedlz -wrinkle5 -zoomzoom -09876543 -starlite -peternorth -jeepjeep -joystick -junkmail -jojojojo -rockrock -rasta220 -andyandy -auckland -gooseman -happydog -charlie2 -cardinals -fortune12 -generals -division -ozlq6qwm -macgyver -mallorca -prelude1 -trousers -aerosmit -clueless -delpiero -nounours -buckaroo -honeydew -hooters1 -hugohugo -evangeli \ No newline at end of file diff --git a/lib/common_passwords/short-common-passwords.txt b/lib/common_passwords/short-common-passwords.txt deleted file mode 100644 index d6f602362c8..00000000000 --- a/lib/common_passwords/short-common-passwords.txt +++ /dev/null @@ -1,7914 +0,0 @@ -123456 -1234 -qwerty -12345 -dragon -pussy -letmein -monkey -696969 -abc123 -mustang -michael -shadow -master -111111 -2000 -jordan -harley -1234567 -fuckme -hunter -fuckyou -ranger -buster -thomas -tigger -robert -soccer -fuck -batman -test -pass -killer -hockey -george -charlie -andrew -love -jessica -asshole -6969 -pepper -daniel -access -654321 -joshua -maggie -silver -william -dallas -yankees -123123 -ashley -666666 -hello -amanda -orange -biteme -freedom -sexy -thunder -nicole -ginger -heather -hammer -summer -taylor -fucker -austin -1111 -merlin -matthew -121212 -golfer -cheese -martin -chelsea -patrick -richard -diamond -yellow -bigdog -secret -asdfgh -sparky -cowboy -camaro -anthony -matrix -falcon -bailey -guitar -jackson -purple -scooter -phoenix -aaaaaa -morgan -tigers -porsche -mickey -cookie -nascar -peanut -justin -131313 -money -horny -panties -joseph -snoopy -boomer -iceman -smokey -gateway -dakota -cowboys -eagles -chicken -dick -black -zxcvbn -please -andrea -ferrari -knight -melissa -compaq -coffee -booboo -bitch -johnny -bulldog -xxxxxx -welcome -james -player -ncc1701 -wizard -scooby -charles -junior -bigdick -mike -brandy -tennis -blowjob -banana -monster -spider -lakers -miller -rabbit -enter -brandon -steven -fender -john -yamaha -diablo -chris -boston -tiger -marine -chicago -rangers -gandalf -winter -bigtits -barney -edward -raiders -porn -badboy -blowme -spanky -johnson -chester -london -blue -fishing -000000 -hannah -slayer -rachel -sexsex -redsox -thx1138 -asdf -panther -zxcvbnm -arsenal -oliver -qazwsx -mother -7777777 -jasper -angel -david -winner -crystal -golden -viking -jack -iwantu -shannon -murphy -angels -prince -cameron -girls -madison -wilson -carlos -hooters -willie -captain -maddog -jasmine -butter -booger -angela -golf -lauren -rocket -tiffany -theman -dennis -flower -forever -green -jackie -muffin -turtle -sophie -toyota -jason -sierra -winston -debbie -giants -packers -newyork -jeremy -casper -bubba -112233 -sandra -lovers -united -cooper -driver -tucker -helpme -fucking -pookie -lucky -maxwell -8675309 -bear -suckit -gators -5150 -222222 -fuckoff -jaguar -monica -fred -happy -hotdog -tits -gemini -lover -777777 -canada -nathan -victor -florida -rosebud -doctor -trouble -success -stupid -tomcat -warrior -peaches -apples -fish -magic -buddy -rainbow -gunner -987654 -freddy -alexis -braves -cock -2112 -1212 -xavier -dolphin -testing -bond007 -member -calvin -voodoo -7777 -samson -alex -apollo -fire -tester -walter -beavis -voyager -peter -porno -bonnie -beer -apple -scorpio -skippy -sydney -scott -red123 -power -gordon -travis -beaver -star -jackass -flyers -boobs -232323 -zzzzzz -steve -rebecca -doggie -legend -ou812 -yankee -blazer -bill -runner -birdie -bitches -555555 -parker -topgun -heaven -viper -animal -2222 -bigboy -4444 -arthur -baby -private -donald -phantom -dave -rock -august -sammy -cool -brian -jake -bronco -paul -mark -frank -heka6w2 -copper -billy -cumshot -willow -cunt -little -carter -slut -albert -kitten -super -eagle1 -shelby -america -11111 -jessie -house -free -123321 -chevy -white -broncos -horney -surfer -nissan -999999 -saturn -marvin -shit -action -adidas -qwert -kevin -1313 -walker -police -wolf -sweet -therock -king -online -teresa -cricket -sharon -dexter -racing -penis -gregory -0000 -teens -dreams -hentai -magnum -nothing -donkey -trinity -digital -333333 -stella -cartman -123abc -speedy -buffalo -kitty -pimpin -eagle -kelly -nelson -nirvana -vampire -xxxx -playboy -louise -pumpkin -test123 -girl -sucker -mexico -beatles -fantasy -ford -gibson -celtic -marcus -cherry -cassie -888888 -natasha -sniper -chance -genesis -hotrod -reddog -college -jester -bigcock -smith -carmen -3333 -death -1q2w3e -eclipse -stanley -samuel -drummer -homer -montana -music -aaaa -spencer -jimmy -hello1 -rocky -goober -friday -scotty -abcdef -bubbles -hawaii -fluffy -mine -stephen -horses -thumper -5555 -pussies -pamela -boobies -buddha -vanessa -sandman -naughty -douglas -honda -matt -azerty -6666 -shorty -money1 -beach -loveme -4321 -simple -444444 -badass -destiny -sarah -denise -vikings -lizard -melanie -assman -sabrina -water -good -howard -time -123qwe -xxxxx -october -leather -bastard -young -101010 -extreme -hard -vincent -pussy1 -hotmail -spooky -amateur -alaska -badger -poop -crazy -mozart -video -russell -vagina -norman -eric -cougar -barbara -long -420420 -family -horse -enigma -allison -raider -brazil -blonde -jones -55555 -dude -jeff -school -lovely -jeffrey -booty -molly -leslie -nipples -diesel -rocks -eminem -suzuki -daddy -passion -hummer -ladies -zachary -frankie -elvis -reggie -alpha -suckme -simpson -147147 -pirate -tommy -jupiter -redrum -wanker -stinky -ducati -paris -natalie -bishop -windows -spirit -pantera -monday -patches -brutus -houston -smooth -penguin -marley -forest -cream -212121 -flash -maximus -nipple -bobby -bradley -vision -pokemon -fireman -indian -picard -system -clinton -cobra -enjoy -lucky1 -claire -claudia -boogie -timothy -marines -dirty -admin -pimp -dancer -hardon -fucked -abcdefg -ironman -great -bigred -squirt -justice -francis -hobbes -kermit -mercury -domino -9999 -denver -brooke -rascal -hitman -simon -tony -bbbbbb -friend -naked -sluts -saints -bondage -bigman -zombie -duke -qwerty1 -babes -disney -rooster -brenda -mookie -candy -duncan -olivia -hunting -alicia -8888 -samsung -bubba1 -whore -general -erotic -liberty -arizona -jesus -abcd -newport -skipper -balls -happy1 -galore -christ -weasel -242424 -wombat -digger -classic -poopoo -accord -popcorn -turkey -jenny -amber -bunny -mouse -007007 -titanic -dreamer -everton -friends -carrie -gabriel -psycho -nemesis -burton -pontiac -connor -eatme -lickme -roland -cumming -ireland -lincoln -arnold -goblue -devils -eugene -empire -asdfg -brown -shaggy -froggy -qwer -kodiak -people -phpbb -light -54321 -kramer -chopper -hooker -honey -whynot -lesbian -lisa -baxter -adam -snake -teen -qqqqqq -britney -avalon -sandy -sugar -sublime -stewart -wildcat -raven -123654 -trucks -pervert -raymond -redhead -alyssa -bambam -movie -woody -shaved -snowman -tiger1 -chicks -raptor -1969 -shooter -france -stars -madmax -kristen -sports -jerry -789456 -garcia -lights -ryan -looking -chronic -alison -hahaha -packard -hendrix -perfect -service -spring -spike -katie -252525 -oscar -brother -bigmac -suck -single -cannon -georgia -popeye -tattoo -texas -party -bullet -taurus -sailor -wolves -japan -strike -flowers -chris1 -berlin -sticky -marina -fisher -russia -connie -mature -bass -catch22 -juice -nigger -159753 -women -alpha1 -trooper -hawkeye -head -freaky -dodgers -machine -pyramid -vegeta -katana -moose -tinker -coyote -inside -pepsi -bang -control -morris -james1 -tickle -outlaw -browns -pickle -test1 -michele -antonio -sucks -caesar -prelude -tanner -adrian -bowling -wutang -sunset -robbie -alabama -danger -juan -rusty -pppppp -nick -2001 -ping -madonna -qwe123 -bigone -casino -cheryl -mmmmmm -integra -apache -tweety -simone -none -trevor -transam -dustin -harvey -england -2323 -seattle -ssssss -rose -harry -openup -pandora -pussys -trucker -wallace -indigo -storm -malibu -weed -review -doggy -dilbert -pegasus -joker -catfish -flipper -valerie -herman -fuckit -detroit -kenneth -bruins -stacey -smoke -joey -seven -marino -fetish -xfiles -wonder -stinger -pizza -babe -pretty -stealth -manutd -gracie -gundam -cessna -mnbvcxz -wicked -victory -shelly -awesome -athena -help -holiday -knicks -street -redneck -casey -gizmo -scully -dragon1 -triumph -eddie -shotgun -peewee -ronnie -angel1 -daisy -special -madman -country -impala -lennon -roscoe -omega -miranda -search -smitty -unicorn -tight -rick -ronald -trigger -truck -danny -home -winnie -beauty -castle -tyler -bobcat -buddy1 -sunny -stones -asian -freddie -chuck -butt -loveyou -norton -hotsex -indiana -short -panzer -trumpet -colors -blaster -logan -aaron -elaine -jungle -atlanta -gold -corona -curtis -nikki -polaris -timber -theone -baller -chipper -orlando -island -skyline -dragons -dogs -benson -licker -goldie -kong -pencil -open -hornet -world -linda -barbie -chan -farmer -indians -larry -redman -foobar -travel -bernie -target -141414 -photos -laura -savage -holly -rocky1 -dollar -turbo -design -newton -hottie -moon -202020 -blondes -4128 -lestat -avatar -future -goforit -random -abgrtyu -jjjjjj -cancer -q1w2e3 -smiley -express -virgin -zipper -stone -andy -babylon -dong -powers -dudley -monkey1 -samurai -skeeter -lindsay -joejoe -master1 -aaaaa -tang -alfred -ball -maria -sexual -maxima -sampson -buckeye -kristin -reaper -bassman -nugget -lucifer -nasty -watson -warlock -2121 -philip -always -dodge -chrissy -burger -bird -snatch -missy -pink -gang -maddie -holmes -huskers -piglet -photo -joanne -dodger -paladin -christy -chubby -hamlet -bigfoot -sunday -manson -garden -blondie -spartan -julie -harold -charger -brandi -stormy -sherry -rodney -galaxy -holland -escort -zxcvb -planet -jerome -wesley -blues -song -peace -david1 -1966 -gambit -karen -sidney -ripper -oicu812 -jamie -sister -marie -martha -nylons -nadine -minnie -whiskey -bing -plastic -anal -chang -loser -racecar -insane -mememe -hansolo -chiefs -freak -frog -salmon -yvonne -zxcv -warren -julian -mariah -rommel -1010 -harris -sylvia -massive -cats -sammy1 -mister -stud -rubber -ding -trunks -desire -justme -faster -irish -1999 -bertha -alpine -sammie -tristan -00000 -swinger -shan -pitbull -roberto -ready -april -palmer -ming -shadow1 -audrey -chong -wang -shirley -fuckers -jackoff -bluesky -151515 -bernard -wolfman -soldier -picture -pierre -ling -goddess -manager -nikita -sweety -titans -hang -fang -ficken -niners -bottom -bubble -ibanez -webster -323232 -tornado -lindsey -content -bruce -buck -aragorn -griffin -chen -trojan -newman -wayne -tina -father -pascal -crimson -brooks -hector -penny -anna -google -camera -fatcat -cody -cunts -waters -stimpy -finger -cindy -wheels -viper1 -latin -robin -brendan -hiphop -willy -snapper -funtime -duck -adult -cotton -cookies -kaiser -mulder -westham -latino -jeep -ravens -aurora -drizzt -madness -energy -kinky -314159 -sophia -stefan -slick -rocker -freeman -french -speed -dddddd -hong -henry -hungry -yang -catdog -cheng -ghost -gogogo -randy -curious -mission -january -singer -sherman -shark -techno -lancer -lalala -autumn -chichi -orion -trixie -delta -bobbob -bomber -holden -kang -kiss -1968 -spunky -liquid -mary -beagle -granny -network -bond -kkkkkk -millie -1973 -biggie -beetle -teacher -susan -toronto -anakin -genius -dream -cocks -dang -bush -karate -snakes -bangkok -callie -pacific -daytona -kelsey -foster -felix -sailing -huang -herbert -jacob -blackie -tarzan -strider -lang -gong -sang -tree -shai -sprite -ting -artist -chai -chao -devil -python -ninja -misty -ytrewq -sweetie -456789 -tian -jing -jesus1 -dian -potter -chou -darren -hobbit -violet -yong -shen -phillip -maurice -gloria -nolimit -mylove -biscuit -yahoo -shasta -sex4me -smoker -smile -pebbles -pics -philly -tong -tintin -marlin -cactus -frank1 -tttttt -chun -danni -emerald -showme -pirates -lian -dogg -colleen -xiao -xian -tazman -tanker -patton -toshiba -richie -alberto -gotcha -graham -dillon -rang -emily -keng -jazz -bigguy -yuan -woman -tomtom -marion -greg -chaos -fossil -flight -racerx -tuan -creamy -boss -bobo -window -blade -shuang -sheila -shun -lick -jian -rong -allen -feng -getsome -sally -quality -kennedy -1977 -beng -wwwwww -yoyoyo -zhang -seng -teddy -joanna -andreas -harder -luke -qazxsw -qian -cong -chuan -deng -nang -boeing -keeper -western -1963 -subaru -sheng -teng -jiong -miao -martina -mang -maniac -pussie -tracey -a1b2c3 -clayton -zhou -zhuang -xing -snow -spyder -liang -jiang -memphis -regina -ceng -magic1 -chuang -dark -million -blow -sesame -shao -poison -titty -terry -kuan -kuai -kyle -mian -guan -hamster -guai -ferret -geng -duan -pang -maiden -quan -velvet -nong -neng -nookie -buttons -bian -bingo -biao -zhong -zeng -xiong -zhun -ying -zong -xuan -zang -0.0.000 -suan -shei -shui -sharks -shang -shua -small -peng -pian -piao -liao -meng -miami -reng -guang -cang -change -ruan -diao -luan -lucas -qing -chui -chuo -cuan -nuan -ning -heng -huan -kansas -muscle -monroe -weng -whitney -zhui -zhua -xiang -zheng -zhen -zhei -zhao -zhan -yomama -zhai -zhuo -zuan -tarheel -shou -shuo -tiao -lady -leonard -leng -kuang -jiao -13579 -basket -qiao -qiong -qiang -chuai -nian -niao -niang -huai -bianca -zhuan -zhuai -shuan -shuai -jumper -archie -forget -qwertz -bones -history -milton -2002 -stuff -office -oldman -preston -trains -murray -vertigo -246810 -black1 -swallow -smiles -parrot -luther -user -nicolas -1976 -surfing -pioneer -pete -masters -apple1 -asdasd -auburn -panama -lucy -buffy -brianna -vette -blue22 -shemale -111222 -baggins -groovy -global -turner -181818 -1979 -blades -life -byteme -lobster -collins -dawg -hilton -1970 -1964 -2424 -polo -markus -coco -deedee -mikey -1972 -171717 -1701 -strip -jersey -green1 -capital -sasha -sadie -putter -vader -seven7 -lester -marcel -banshee -grendel -gilbert -dicks -dead -hidden -iloveu -1980 -sound -ledzep -michel -147258 -female -bugger -buffett -bryan -hell -molson -2020 -wookie -sprint -thanks -jericho -102030 -grace -fuckin -mandy -ranger1 -trebor -molly1 -mirage -models -1984 -2468 -stuart -pentium -mario -anime -gator -powder -twister -connect -neptune -bruno -butts -engine -eatshit -woody1 -shogun -pooh -jimbo -roger -annie -bacon -center -russian -sabine -damien -mollie -voyeur -2525 -363636 -camel -chair -germany -giant -qqqq -nudist -bone -sleepy -tequila -megan -fighter -garrett -dominic -obiwan -walnut -1974 -ladybug -cantona -ccbill -satan -rusty1 -dusty -kissme -1967 -zzzz -skater -smut -play -valley -coolio -dagger -boner -bull -horndog -jason1 -blake -rescue -griffey -champs -queen -colt45 -boat -xxxxxxx -xanadu -tacoma -mason -carpet -gggggg -safety -palace -italia -stevie -picturs -picasso -thongs -tempest -ricardo -roberts -asd123 -hairy -foxtrot -gary -nimrod -hotboy -343434 -1111111 -goose -blood -wood -454545 -shaolin -sooners -peanuts -maxine -rogers -andrew1 -filthy -donnie -ohyeah -africa -kenny -keith -monique -jasmin -pickles -assass -fright -potato -darwin -hhhhhh -kingdom -weezer -424242 -pepsi1 -throat -romeo -gerard -looker -puppy -butch -monika -suzanne -sweets -temple -laurie -josh -analsex -nymets -ddddddd -support -stick -today -down -oakland -oooooo -qweasd -chucky -bridge -carrot -dookie -condor -night -butler -hoover -horny1 -sunrise -sinner -jojo -martini -assfuck -ffffff -abigail -esther -janice -jamaica -wright -sims -space -there -timmy -7654321 -77777 -cccccc -gizmodo -roxanne -ralph -tractor -dance -mypass -helena -1975 -blue123 -pissing -thomas1 -redred -rich -attack -cash -drunk -dixie -dublin -bollox -katrina -miles -1971 -22222 -272727 -sexx -bbbb -battle -grizzly -passat -porter -tracy -defiant -bowler -monitor -wisdom -wild -slappy -thor -letsgo -robert1 -feet -rush -brownie -hudson -098765 -playing -melvin -atomic -bart -hawk -goku -glory -llllll -qwaszx -cosmos -bosco -knights -bentley -beast -lewis -assword -frosty -gillian -sara -dumbass -mallard -dddd -deanna -elwood -wally -159357 -angelo -aussie -guest -golfing -doobie -loveit -chloe -elliott -vipers -janine -1965 -blabla -surf -sucking -tardis -serena -shelley -thegame -legion -rebels -fast -gerald -sarah1 -double -onelove -loulou -toto -crash -0007 -soccer1 -jedi -manuel -method -river -chase -ludwig -poopie -derrick -boob -breast -isabel -belly -pikachu -jose -celeste -celtics -frances -frogger -sabbath -budman -willis -jackal -bigger -zzzzz -silvia -sooner -licking -gopher -geheim -primus -pooper -newpass -brasil -husker -element -moomoo -tammy -shitty -smokin -jjjj -anubis -backup -gorilla -painter -traffic -claude -daniela -dale -delta1 -nancy -boys -easy -kissing -kelley -wendy -theresa -amazon -alan -fatass -malcolm -breasts -boots -honda1 -spidey -poker -temp -miguel -147852 -archer -dogdog -tricky -weather -spankme -speaker -amadeus -back -harley1 -falcons -dorothy -kenwood -1978 -shazam -shalom -lickit -jimbob -roller -carson -check -fatman -funny -garbage -loving -magnus -clover -mobile -bell -payton -plumber -texas1 -tool -topper -jenna -rebel -harmony -celica -german -diana -oxford -osiris -orgasm -punkin -tuesday -close -breeze -bossman -billie -latinas -judith -astros -scruffy -donna -qwertyu -davis -hearts -kathy -jammer -java -rhonda -ricky -1122 -flyboy -doodle -city -bootie -kicker -vulcan -iverson -191919 -stoner -321321 -farside -rugby -pussy69 -power1 -bobbie -hershey -hermes -west -birdman -blessed -thumbs -lawyer -melinda -fingers -rrrrrr -coke -nicola -bohica -heart -elvis1 -kids -blacky -stories -snake1 -phoebe -jesse -fisting -scarlet -dildo -pancho -lucky7 -condom -summer1 -student -sword -skiing -sergio -site -sony -thong -cassidy -fffff -fitness -durango -postal -dawn -dylan -kisses -imagine -topdog -asterix -hallo -bridget -eeeeee -mouth -weird -will -sommer -toby -theking -juliet -avenger -goodbye -faith -trance -brad -houses -homers -kingpin -incubus -1961 -blond -zaphod -shiloh -spurs -station -jennie -maynard -mighty -aliens -hank -charly -running -dogman -omega1 -printer -aggies -hope -javier -bitch1 -stone55 -thekid -lizzie -rockets -ashton -camels -formula -forrest -oracle -rain -pussey -abcde -clancy -nellie -mystic -inferno -steve1 -pauline -alice -alfa -grumpy -flames -scream -lonely -puffy -proxy -unreal -cynthia -herbie -engage -yyyyyy -010101 -solomon -pistol -melody -celeb -flying -gggg -scottie -oakley -a12345 -newbie -mmmm -venus -beverly -zorro -work -writer -spread -phil -tobias -links -members -metal -1221 -andre -565656 -funfun -trojans -again -cyber -moneys -zeus -thing -tomato -lion -celine -usa123 -trans -account -aaaaaaa -homerun -kevin1 -blacks -sean -fart -fubar -older -oilers -craig -conrad -church -damian -dean -broken -buster1 -hithere -sticks -pilot -peters -lexmark -jerkoff -anders -cheers -possum -cutter -muppet -stolen -sport -sonic -peter1 -jethro -rockon -asdfghj -pass123 -paper -pornos -bootys -buttman -bonjour -escape -1960 -becky -bears -362436 -tinman -lemons -maxmax -1414 -bbbbb -camelot -chad -chewie -gogo -fusion -saint -nopass -myself -hustler -hunter1 -whitey -beast1 -yesyes -spank -smudge -patriot -lespaul -annette -hammers -finish -sausage -orioles -oscar1 -over -cramps -natural -eating -exotic -iguana -bella -suckers -strong -sheena -start -slave -pearl -topcat -magelan -racer -ramona -crunch -british -button -eileen -steph -456123 -skinny -seeking -chief -filter -first -freaks -sakura -pacman -dalton -newlife -homer1 -klingon -watcher -walleye -tasha -tasty -sinatra -steel -poncho -amber1 -gonzo -grover -carol -candle -firefly -goblin -scotch -diver -usmc -huskies -eleven -kitkat -israel -beckham -bicycle -yourmom -studio -tara -shane -splash -jimmy1 -reality -caitlin -focus -mailman -clark -ddddd -hopper -more -wilbur -illini -lansing -maxx -gothic -carlton -camille -facial -vectra -crazy1 -jane -betty -benny -bennett -leader -barkley -hayden -caught -franky -ffff -floyd -sassy -pppp -prodigy -noodle -vortex -wanking -billy1 -siemens -pedro -groups -carolyn -chevy1 -cccc -fritz -dracula -nurses -loco -madrid -trout -utopia -chrono -cooler -conner -nevada -wibble -werner -summit -marco -marilyn -1225 -babies -capone -fugazi -panda -mama -puppies -triton -9876 -command -nnnnnn -ernest -momoney -iforgot -wolfie -studly -shawn -renee -alien -hamburg -81fukkc -741852 -catman -china -forgot -gagging -scott1 -drew -oregon -qweqwe -train -daniel1 -cutlass -holes -heidi -mothers -music1 -what -walrus -1957 -bigtime -bike -xtreme -simba -ssss -rookie -angie -bathing -fresh -sanchez -rotten -maestro -luis -look -turbo1 -99999 -hhhh -elijah -monty -bender -yoda -shania -shock -phish -thecat -reagan -baddog -asia -randall -abstr -napster -brian1 -bogart -high -hitler -emma -kill -weaver -isaiah -1981 -belinda -beaner -yoyo -super1 -select -slutty -some -toon -raven1 -rayray -123789 -1066 -albion -greens -fashion -santana -paint -powell -credit -darling -mystery -bowser -bottle -hehehe -kelly1 -mojo -1998 -bikini -yyyy -strap -sites -spears -julius -amelia -central -f**k -nyjets -vanilla -twisted -bryant -brent -here -erica -kimber -viagra -veritas -pony -pool -titts -labtec -jenny1 -mayhem -redbull -govols -gremlin -505050 -gmoney -rupert -rovers -lorenzo -trident -deskjet -cuddles -nice -bristol -karina -milano -vh5150 -jarhead -1982 -bigbird -bizkit -sixers -slider -star69 -tommy1 -john316 -meghan -market -grant -carl -flicks -films -madden -cosmo -cthulhu -br0d3r -swedish -spawn -polly -these -todd -reds -anarchy -groove -franco -fuckher -oooo -tyrone -vegas -airbus -cobra1 -clips -delete -duster -kitty1 -mouse1 -monkeys -jazzman -1919 -262626 -stroke -stocks -sting -pippen -jordan1 -females -park -vector -cooter -desert -demon -nike -bubbas -bonkers -english -kahuna -wildman -4121 -sirius -static -terror -teenage -leelee -marissa -rated -hailey -chaser -sanders -salsero -nuts -macross -quantum -rachael -tsunami -daddy1 -cruise -nguyen -nudes -vernon -1959 -striker -sixty -steele -spice -smegma -thumb -mellow -astrid -cancun -cartoon -sabres -samiam -pants -oranges -lust -coleman -denali -nude -noodles -buzz -brest -hooter -warthog -bloody -zappa -lance -jean -jjjjj -harper -calico -freee -rover -door -pooter -closeup -bonsai -evelyn -emily1 -kathryn -iiii -1955 -yzerman -theboss -tolkien -jill -megaman -rasta -bean -hal9000 -goofy -gringo -gofish -gizmo1 -samsam -scuba -onlyme -corrado -clown -clapton -deborah -boris -bulls -vivian -jayhawk -bethany -wwww -sharky -seeker -pillow -thesims -lighter -lkjhgf -barry -guiness -gymnast -casey1 -goalie -doug -lolo -poppy -abby -clemson -clipper -nobody -holly1 -elliot -eeee -miriam -belle -sucked -sex123 -sexy69 -pic\'s -lamont -meat -marc -gretzky -frisco -scratch -orchid -orange1 -quincy -dawson -ne1469 -boxing -hill -korn -161616 -1985 -ziggy -stoney -senior -amature -barber -babyboy -goliath -hack -frodo -scout -scrappy -rosie -qazqaz -tracker -active -craving -cohiba -deep -cyclone -dana -bubba69 -katie1 -mpegs -vsegda -jade -irish1 -better -sexy1 -smelly -lions -jokers -julia -jojojo -ashley1 -groucho -cheetah -champ -firefox -packer -love69 -tyler1 -typhoon -tundra -bobby1 -village -volley -beth -wolf359 -0420 -000007 -swimmer -skydive -smokes -patty -peugeot -pompey -legolas -kristy -redhot -rodman -having -grapes -4runner -carrera -floppy -dollars -ou8122 -quattro -adams -cloud9 -davids -nofear -busty -mmmmm -whisper -vermont -wives -jayjay -philips -phone -topher -tongue -midget -ripken -havefun -canon -five -getting -ghetto -direct -otto -usnavy -conover -cruiser -dalshe -nicole1 -buzzard -hottest -misfit -moore -milfnew -warlord -wassup -bigsexy -zippy -shearer -tights -kungfu -labia -journey -marlene -rider -area51 -batman1 -bananas -636363 -cancel -ggggg -paradox -mack -lynn -queens -adults -aikido -cigars -nova -hoosier -eeyore -moose1 -warez -313131 -mayday -rivers -revenge -banker -baddest -ccccc -fortune -aisan -deadman -iscool -1956 -1pussy -womam -sweden -skidoo -spock -sssss -petra -pepper1 -pinhead -micron -allsop -army -aside -gunnar -666999 -chip -foot -fowler -face -fletch -george1 -sapper -science -sasha1 -lover1 -magick -popopo -public -ultima -derek -cypress -booker -edwards -vulva -vvvv -jabroni -bigbear -yummy -010203 -searay -secret1 -showing -sinbad -sexxxx -soleil -piccolo -leopard -legacy -jensen -justine -memorex -marisa -mathew -redwing -134679 -anfield -gore -catcat -feather -scanner -danzig -daisy1 -hores -erik -exodus -vinnie -iiiiii -zero -1001 -subway -tank -second -snapple -picks -poodle -their -llll -junebug -june -marker -mellon -ronaldo -amanda1 -asdfjkl -beaches -greene -great1 -force -doitnow -ozzy -radio -tyson -daphne -boxster -emerson -kkkk -mnbvcx -moocow -vides -wagner -janet -1717 -blonds -1000 -storys -stereo -4545 -420247 -lesbean -live -justin1 -124578 -animals -balance -hansen -cabbage -dodge1 -dimas -lori -loud -malaka -puss -probes -adriana -coolman -dante -nacked -erotica -kool -mirror -wearing -bigass -zenith -woohoo -womans -tanya -tango -stacy -pisces -laguna -krystal -maxell -flash1 -orgasms -profit -pusyy -pothead -coconut -chuckie -contact -builder -hotshot -horizon -hole -mondeo -wifes -1962 -strange -stumpy -smiths -sparks -slacker -piper -laptop -allmine -bbbbbbb -asscock -grandma -hayley -88888 -cecilia -chacha -sandy1 -santos -doogie -number -qwert40 -crow -darrell -bonita -ib6ub9 -volvo -jacob1 -iiiii -beastie -stoned -sonics -snapon -pepe -lesbain -litle -retard -ripple -austin1 -badgirl -garage -royals -dragoon -dickie -passwor -ocean -poppop -dammit -nokia -bobobo -br549 -emmitt -knock -minime -1954 -3232 -353535 -seamus -solo -sparkle -sluttey -pictere -titten -lback -1024 -goat -ruby -passme -oasis -logan1 -rainman -twins -club -custom -cyclops -nipper -bucket -hhhhh -momsuck -indain -2345 -bimmer -susanne -stunner -stevens -456456 -shell -sheba -tootsie -tiny -reefer -really -1012 -harcore -gollum -545454 -chico -caveman -carole -fishes -gaymen -saleen -doodoo -looney -presto -qqqqq -cigar -bogey -brewer -helloo -dutch -monte -wasser -vietnam -visa -0123 -swords -slapper -peach -jump -marvel -march -redwood -rolling -1005 -ametuer -chiks -cathy -fucing -sadie1 -mamas -race -rambo -unknown -absolut -deacon -dallas1 -kristi -keywest -kirsten -kipper -morning -wings -idiot -1515 -beating -zxczxc -303030 -shaman -sparrow -jeffery -mick -redfish -1492 -angus -barrett -goirish -felicia -forfun -galary -duchess -olivier -lotus -ramses -purdue -crave -brando -enter1 -killme -welder -windsor -wifey -indon -yyyyy -stretch -taylor1 -4417 -picher -pickup -johnboy -jets -jess -maureen -anne -ameteur -hambone -5050 -charley -sally1 -padres -quest -trader -crack -climber -bolitas -bravo -hohoho -model -italian -beanie -beretta -stroker -tabitha -sexyman -jewels -mets -marcos -rhino -bdsm -goodman -grils -games -route66 -devo -dino -outkast -magpie -critter -cupcake -nickel -krista -mimi -murder -videoes -xerxes -slim -slinky -pinky -meister -menace -ripley -retired -balloon -bank -goten -5551212 -donuts -divorce -lord -lost -tttt -comet -deer -damnit -nasty1 -nonono -nina -eeeee -milkman -vvvvvv -isaac -1818 -blueboy -beans -bigbutt -wyatt -tech -poetry -toolman -laurel -juggalo -jetski -gobears -truman -cubbies -nitram -briana -ebony -kings -warner -bilbo -yumyum -zzzzzzz -stylus -321654 -server -secure -silly -squash -starman -steeler -staples -phrases -laser -135790 -allan -barker -athens -cbr600 -fester -gangsta -fucku2 -freeze -game -droopy -objects -passwd -lllll -loaded -louis -losers -vedder -clit -chunky -darkman -damage -buddah -boobed -henti -hillary -webber -winter1 -ingrid -bigmike -beta -zidane -talon -slave1 -pissoff -person -living -lexus -matador -readers -riley -roberta -armani -ashlee -5656 -cards -fmale -ferris -fuking -gaston -fucku -ggggggg -sauron -diggler -pacers -looser -pounded -premier -pulled -town -trisha -cornell -collin -cosmic -deeper -depeche -norway -bright -helmet -kendall -mustard -misty1 -watch -jagger -bertie -berger -word -3x7pxr -silver1 -smoking -sonny -paula -photoes -lesbens -lambert -lindros -lillian -1357 -143143 -asasas -goodboy -898989 -card -gawker -rubble -rrrr -onetime -trapper -twenty -abraham -cinder -company -boricua -bunny1 -boxer -hotred -hockey1 -hooper -edward1 -evan -kris -misery -moscow -milk -bigtit -show -three -lionel -leanne -joshua1 -july -1230 -cedric -fallen -farley -gene -frisky -sanity -script -divine -dharma -lucky13 -tricia -akira -desiree -hunt -hotbox -hootie -heat -howdy -karma -kiteboy -motley -1988 -bert -biggles -wrench -working -wrestle -pheonix -penny1 -thedude -jenn -jonjon -jones1 -mattie -memory -micheal -arrow -azzer -diehard -dotcom -lola -chivas -clouds -deluxe -nuclear -north -boom -boobie -hurley -krishna -momomo -modles -volume -bluedog -wwwwwww -yousuck -pluto -link -joung -marcia -awnyce -gonavy -haha -fabian -girsl -rufus -drive -a123456 -airport -clay -combat -cygnus -cupoi -never -brett -eagles1 -elite -kendra -mommy -1958 -shonuf -piano -thedog -lips -jillian -jenkins -midway -gromit -787878 -66666 -carmex2 -camber -gator1 -ginger1 -fuzzy -seadoo -dorian -lovesex -rancid -uuuuuu -911911 -nature -helen -health -heater -higgins -kirk -mmmmmmm -virtual -ventura -jamie1 -japanes -2727 -2469 -blam -believe -zephyr -stiffy -sweet1 -silent -spectre -tigger1 -tekken -lenny -lakota -jjjjjjj -medical -1369 -golfer1 -gunners -7779311 -515151 -famous -glass -screen -rudy -royal -sanfran -drake -optimus -love1 -mail -maggie1 -pudding -venice -aaron1 -delphi -niceass -bounce -busted -house1 -killer1 -miracle -momo -musashi -jammin -2003 -234567 -submit -silence -sssssss -state -spikes -sleeper -toledo -kume -media -meme -medusa -mantis -remote -reading -reebok -1017 -artemis -hampton -harry1 -cafc91 -fettish -oceans -mango -ppppp -trainer -troy -uuuu -909090 -cross -death1 -news -hokies -eeeeeee -mitch -& -& -spinner -leon -jockey -records -right -hans -gooner -474747 -cheeks -cars -candice -fight -glow -parola -okokok -pablo -magical -major -ramsey -989898 -circle -crusher -cubswin -nnnn -erin -kotaku -milo -mittens -whatsup -vvvvv -iomega -bengals -bermuda -biit -yellow1 -012345 -spike1 -south -sowhat -pitures -peacock -pecker -theend -jimmie -romance -augusta -castro -florian -dolly -lulu -qaz123 -usarmy -twinkle -cloud -cold -hover -hothot -europa -ernie -kenshin -kojak -mikey1 -water1 -196969 -because -wraith -zebra -wwwww -33333 -simon1 -spider1 -snuffy -teddy1 -lesley -maria1 -redline -renault -aloha -antoine -gobucks -freesex -duffman -ooooo -papa -nuggets -longbow -porno1 -county -dalejr -darius -darlene -dell -navy -buffy1 -honey1 -hott -heyhey -europe -everest -3434 -shag -spoon -sonoma -stalker -poochie -terefon -maryann -marty -roman -1007 -142536 -alibaba -bartman -astro -goth -century -cheater -four -ghost1 -oral -civic -cicero -kkkkk -jameson -1a2b3c -1qwerty -skip -shojou -sparky1 -poiuy -torres -lantern -jelly -jeanne -meier -1213 -bayern -basset -gsxr750 -cattle -gilles -dima -obelix -popo -prissy -ramrod -unique -bummer -hotone -dynasty -entry -konyor -missy1 -moses -282828 -yeah -xyz123 -stop -426hemi -404040 -simmons -lazarus -marine1 -manning -12345a -beamer -greece -gustav -7007 -charity -camilla -ccccccc -faggot -foxy -frozen -duckie -dogfood -radical -tuna -claudio -circus -danny1 -novell -nights -bonbon -kashmir -kiki -moondog -monaco -insert -1953 -zxc123 -supreme -3131 -sexxx -selena -softail -poipoi -pong -mars -martin1 -rogue -alone -audia4 -chick -came11 -figaro -geneva -dogboy -dnsadm -dipshit -othello -officer -malone -post -rafael -tripod -choice -chopin -coucou -coach -common -book -hiziad -homerj -eight -earth -mullet -whisky -jacques -store -4242 -speedo -skylar -piggy -pierce -tiger2 -legos -lala -jezebel -judy -joker1 -mazda -barton -baker -727272 -fishman -food -dundee -lumber -radar -ppppppp -tranny -aaliyah -admiral -comics -cleo -delight -homeboy -eternal -kilroy -kellie -khan -violin -wingman -walmart -bigblue -blaze -beemer -beowulf -bigfish -yyyyyyy -woodie -0123456 -tbone -style -syzygy -starter -lemon -linda1 -merlot -mexican -anita -banner -badman -barfly -grease -carla -screw -diane -dogshit -counter -coolguy -demons -demo -nomore -normal -hhhhhhh -hondas -iamgod -enterme -everett -kayla -mybaby -ipswich -200000 -bearcat -zigzag -xander -369369 -skyler -pigeon -peyton -tipper -lilly -asdf123 -asdzxc -banane -barnes -guyver -grand -chinook -otis -tototo -trust -tower -adam12 -corey -chrome -buddie -bombers -bunker -hippie -keegan -misfits -vickie -292929 -woofer -stubby -sheep -secrets -sparta -stang -spud -sporty -pinball -jorge -johanna -maxxxx -gunther -fatima -fffffff -freeway -garion -score -rrrrr -sancho -outback -maggot -puddin -trial -987456 -colton -clyde -brain -brains -hoops -eleanor -dwayne -kirby -mydick -villa -bigcat -becker -shiner -spanish -templar -lamer -juicy -marsha -mike1 -maximum -real -1223 -arrows -andres -alucard -baldwin -baron -avenue -haggis -channel -cheech -safari -ross -dog123 -orion1 -paloma -vegitto -trees -969696 -adonis -colonel -cookie1 -hellos -dwight -eraser -kerstin -motion -moritz -visual -jaybird -1983 -bitter -yvette -zodiac -steven1 -slammer -slick1 -sponge -theater -this -jonny -massage -mann -ring -1211 -amazing -aptiva -bailey1 -guitar1 -chanel -canyon -gagged -fuckme1 -rough -punk -98765 -90210 -clowns -cubs -daniels -deejay -nigga -naruto -boxcar -hotties -electra -kent -widget -india -1986 -2004 -best -bingo1 -***** -stratus -sultan -storm1 -44444 -4200 -season -sexyboy -sigma -smokie -spam -point -pippo -ticket -joel -manman -1022 -anton -almond -bacchus -aztnm -axio -awful -bamboo -hakr -gregor -5678 -caprice -camero1 -fellow -dupont -dianne -paddle -magnet -qwert1 -pyon -tripper -coming -noway -burrito -bozo -hughes -hookem -eddie1 -ellie -entropy -kkkkkkk -jacobs -1945 -1951 -24680 -100000 -taco -subzero -sharp -sexxxy -skolko -shanna -skyhawk -spurs1 -sputnik -piazza -letter -lane -kurt -matilda -1224 -harvard -hannah1 -525252 -4ever -carbon -chef -ghosts -gina -loki -raquel -promise -citadel -highway -evil -monarch -morgan1 -1997 -bella1 -berry -yaya -yolanda -superb -taxman -studman -3636 -sherri -sheriff -poland -pizzas -toilet -latina -lassie -larry1 -joseph1 -meagan -marian -reptile -rico -razor -1013 -barron -hammer1 -gypsy -grande -carroll -camper -chippy -cat123 -call -chimera -fiesta -glock -glenn -domain -dieter -onetwo -odessa -louie -quartz -prowler -prophet -towers -ultra -cocker -dakota1 -cumm -nnnnnnn -natalia -boxers -hugo -heynow -hollow -iceberg -elvira -kate -kitchen -wasabi -impact -beerman -string -sleep -snoopy1 -pocket -legs -maple -mickey1 -manuela -mermaid -micro -redbird -alisha -baura -battery -grass -chevys -caravan -carina -charmed -fraser -frogman -diving -dogger -draven -drifter -oatmeal -paris1 -rachel1 -vegitta -cole -cobras -corsair -dadada -noelle -mylife -nine -bowwow -body -hotrats -modena -wave -iiiiiii -birgit -zone -sutton -susana -shocker -shrimp -sexgod -squall -squeeze -soul -patrice -poiu -players -tigers1 -toejam -tickler -line -julie1 -jimbo1 -juanita -rodeo -robot -1023 -annie1 -bball -guess -happy2 -charter -farm -flasher -falcon1 -fiction -gadget -diaper -dinner -oliver1 -partner -paco -lucille -macman -poopy -popper -postman -ttttttt -ursula -acura -cowboy1 -conan -daewoo -cyrus -nation -nnnnn -nextel -bolton -eureka -extra -kimmie -musica -wage -wert -vintage -itsme -bessie -zippo -311311 -smokey1 -spot -snappy -plasma -thelma -tonight -krusty -just4me -marius -rebel1 -1123 -alfredo -aubrey -audi -chantal -fick -goaway -roses -sales -rusty2 -dirt -dogbone -doofus -ooooooo -mankind -luck -mahler -lllllll -pumper -puck -pulsar -tupac -compass -cougars -niceguy -bob123 -boating -bronze -hopkins -hewlett -houhou -hubert -keller -mingus -venture -verizon -imation -1950 -1948 -1949 -223344 -bigbig -blossom -zack -wowwow -sissy -skinner -spiker -square -snooker -sluggo -player1 -junk -jeannie -jsbach -jumbo -jewel -medic -robins -123456a -1125 -1031 -beacon -astra -gumby -hammond -hassan -757575 -585858 -chillin -fuck1 -sander -lowell -upyours -trek -courage -darryl -nikki1 -nitro -bugs -boytoy -ellen -excite -kirsty -kane -wingnut -icu812 -1master -beatle -blanca -wolfen -sugar1 -tartar -senna -sexman -sick -someone -soprano -pippin -pixies -land -laura1 -laurent -rimmer -road -report -1020 -arturo -around -hamish -halifax -forum -dododo -doit -outside -mandy1 -twist -uuuuu -uranus -ttttt -butcher -bruce1 -helper -hopeful -eduard -dusty1 -kathy1 -muscles -morton -vvvvvvv -vivid -install -1947 -187187 -1941 -1952 -tatiana -susan1 -sinned -sexxy -senator -shadows -playa -toaster -jerry1 -marie1 -mason1 -merlin1 -roger1 -112358 -1121 -andrea1 -bacardi -auto -hardy -789789 -5555555 -flores -fergus -sascha -rrrrrrr -dome -onion -nutter -lololo -qqqqqqq -quick -uuuuuuu -cobain -cindy1 -coors -dani -descent -nimbus -nomad -nanook -norwich -bomb -bombay -broker -hookup -kiwi -winners -jackpot -1776 -beardog -bighead -blast -bird33 -0987 -stress -shot -spooge -pelican -peepee -perry -pointer -titan -jeremy1 -altima -baba -hallie -hate -hardone -5454 -candace -flip -finance -farmboy -salomon -destroy -papers -option -page -loser1 -lopez -r2d2 -chriss -cumcum -ninjas -ninja1 -hung -erika -eduardo -killers -miller1 -intel -jarvis -2626 -bizzare -blue12 -biker -yoyoma -sushi -styles -series -shanti -spanker -steffi -smart -sphinx -please1 -paulie -pistons -tiburon -limited -mdogg -rockies -alexia -arlene -arctic -banger -audio -asimov -grandpa -753951 -4you -chilly -chapman -flyfish -santa -oreo -ohshit -macbeth -madcat -loveya -mallory -rage -quentin -project -ramirez -colnago -citizen -chocha -cobalt -dabears -nevets -helene -huge -edgar -epsilon -easter -kestrel -moron -virgil -1616 -beat -bettina -woowoo -zander -shower -sloppy -reader -romero -redsox1 -ride -1215 -1112 -annika -arcadia -answer -baggio -base -guido -555666 -carmel -cayman -chips -roxy -disco -pass1 -luna -lovebug -macmac -queenie -puffin -trip -airwolf -abbott -aaa111 -cocaine -cisco -cottage -dayton -deadly -datsun -bricks -bumper -kidrock -wizard1 -wind -italy -benoit -bigones -wolfpac -suicide -3030 -sheba1 -sixpack -peace1 -physics -pearson -tigger2 -toad -megan1 -meow -ringo -roll -717171 -686868 -5424 -canuck -footjob -fulham -seagull -orgy -lobo -mancity -truth -trace -derf -boozer -howell -hola -easton -munch -jared -1dragon -biology -bestbuy -bmw325 -bigbob -stream -tazz -3333333 -skate -shutup -shop -polish -pinky1 -tootie -thecrow -leroy -jubilee -jingle -martine -matrix1 -manowar -messiah -mclaren -reilly -rollins -romans -return -rivera -athlon -beach1 -badgers -guitars -harald -gotribe -6996 -7grout -635241 -chase1 -carver -fallout -fiddle -fenris -fortuna -felipe -felix1 -forward -gasman -frost -fucks -sahara -sassy1 -dogbert -divx1 -manila -loretta -priest -quasar -venom -987987 -access1 -decker -daman -data -dentist -crusty -nathan1 -bruno1 -bucks -brodie -kittens -kerouac -mother1 -waldo1 -wedding -1942 -1946 -bigdawg -bigpimp -zaqwsx -414141 -3000gt -434343 -shoes -serpent -starr -smurf -pasword -tommie -lake -john1 -redeye -rebelz -1011 -alatam -asses -asians -bama -banzai -harvest -hair -hanson -575757 -5329 -cascade -chinese -fatty -fender1 -flower2 -funky -sambo -dogcat -dottie -oedipus -osama -macleod -prozac -rampage -punch -presley -concord -cook -cinema -cleaner -ciccio -corinne -clutch -daemon -bruiser -boiler -hjkl -eyes -egghead -expert -ethan -kasper -mordor -wasted -jamess -zouzou -090909 -1002 -switch -stone1 -4040 -sisters -sexo -shawna -smith1 -sperma -sneaky -polska -thewho -krypton -lawson -library -lekker -jules -johann -justus -rockie -romano -aspire -goodie -cheese1 -fenway -fishon -fishin -girls1 -sawyer -dolores -desmond -duane -ramones -rabbits -transit -aaaaa1 -clock -delilah -noel -boyz -bongo -bunnies -brady -buceta -henry1 -heels -eastern -krissy -mopar -vienna -weston -wildone -vodka -jayson -beavis1 -betsy -xxxxxx1 -000001 -0815 -zulu -420000 -sigmar -sprout -stalin -peggy -patch -lagnaf -rolex -redfox -referee -1231 -angus1 -ariana -ballin -attila -hall -greedy -grunt -747474 -cecile -caramel -field -gidget -futbol -frosch -saiyan -schmidt -drums -donner -doggy1 -drum -doudou -pack -pain -nutmeg -quebec -trash -triple -tosser -tuscl -track -comfort -choke -comein -cola -deputy -bremen -borders -bronson -break -hotass -eskimo -eggman -koko -kieran -katrin -komodo -mone -munich -winger -jaeger -ivan -2222222 -bennie -bigben -worm -xxx123 -sunny1 -373737 -slater -slayer1 -snoop -stacie -peachy -thecure -times -little1 -jennaj -marquis -middle -rasta69 -1114 -aries -havana -gratis -calgary -flanker -salope -dirty1 -draco -dogface -umpire -turnip -vbnm -tucson -troll -aileen -codered -damon -nana -neon -nico -neil -boomer1 -bushido -horace -kaitlyn -keepout -karen1 -mindy -mnbv -volcom -wizards -wine -1995 -bite -zach -tarpon -shinobi -phat -patrol -toolbox -julien -johnny1 -joebob -marble -riders -reflex -120676 -1235 -angelus -anthrax -atlas -hawks -grandam -harlem -655321 -cabron -fischer -flyer -flower1 -factory -federal -gambler -frodo1 -funk -sand -sam123 -scania -dingo -papito -olive -palermo -ou8123 -lock -ranch -pride -randy1 -twiggy -travis1 -treetop -addict -admin1 -963852 -aceace -cliff -cirrus -clifton -colin -bobdole -bonner -bogus -bonjovi -bootsy -boater -elway7 -edison -kelvin -kenny1 -montag -moreno -wayne1 -white1 -jazzy -1994 -1991 -2828 -blunt -beau -belmont -worthy -systems -sensei -stan -peeper -pharao -pigpen -teensex -larkin -jimjim -melons -marlon -robocop -1003 -1027 -azsxdc -gordo -hazard -granada -8989 -7894 -ceasar -chelle -candy1 -fergie -fanny -fidelio -giorgio -ruth -sanford -diego -devon -panic -longer -mackie -qawsed -twelve -chloe1 -coral -daddyo -boyboy -booster -bucky -esquire -motor -wilder -waffle -wallet -warning -virus -wealth -jabber -jaguars -javelin -idefix -bigdog1 -blue42 -blanked -blue32 -biteme1 -blaine -yessir -team -stephan -sunfire -tbird -stryker -3ip76k2 -sevens -sheldon -pilgrim -tenchi -titman -leeds -lithium -lander -linkin -landon -mariner -markie -midnite -1129 -123asd -allstar -albany -asdf12 -antonia -aspen -7734 -49ers -carlo -cable -carnage -callum -carlos1 -fitter -flame -gofast -gamma -fucmy69 -dogwood -django -magneto -loose -premium -addison -9999999 -abc1234 -newyear -nichole -bookie -burns -bounty -brown1 -bologna -earl -elway -killjoy -kerry -keenan -kick -mini -mouser -wayer -impreza -irene -2580 -bellaco -blues1 -bedford -blanco -blunts -stinks -teaser -streets -sf49ers -shovel -spikey -sonia -timeout -toffee -lefty -johndoe -mega -manolo -mentor -margie -ratman -ridge -record -rhodes -robin1 -1124 -1210 -1028 -1226 -another -harbor -gramma -646464 -chaos1 -glasgow -frogs -salem -scuba1 -ducks -driven -doggies -dicky -donovan -rams -aikman -corolla -clarke -conway -cumslut -cyborg -dancing -boston1 -bong -houdini -helmut -elvisp -edge -keksa12 -misha -monty1 -wetter -watford -wiseguy -visitor -janelle -1989 -1987 -biatch -beezer -bigguns -bitchy -wyoming -stupid1 -simple1 -spiral -smeller -sperm -plato -tophat -test2 -theatre -thick -toomuch -leigh -jello -jewish -junkie -maxim -maxime -meadow -roofer -124038 -1018 -1269 -1227 -123457 -alberta -aramis -beaker -googoo -goochi -852456 -4711 -catcher -carman -champ1 -chess -geezer -samuel1 -saigon -scooby1 -doors -dick1 -devin -doom -dirk -doris -load -magpies -manfred -raleigh -vader1 -tulips -defense -mygirl -burn -bowtie -bowman -holycow -honeys -minerva -wheeler -witch -jaime -irving -1992 -bimbo -blue11 -birddog -woodman -womble -030303 -stinker -slugger -spotty -smoke1 -things -torpedo -tender -lilith -jimmys -jerk -junior1 -marsh -rice -root -1214 -april1 -allgood -bambi -grinch -767676 -5252 -capecod -finder -flint -goats -gideon -savior -seabee -sandro -schalke -disney1 -duckman -options -pancake -malice -lookin -love123 -lloyd -puppet -prayers -union -tracer -crap -cwoui -hookers -hollie -hewitt -ernesto -edthom -kaylee -kokoko -kokomo -kimball -morales -mooses -monk -walton -weekend -inter -1993 -worker -summers -surgery -shibby -shamus -skibum -sex69 -spliff -slipper -spoons -spanner -slow -temp123 -lakers1 -jomama -julio -rosario -recon -riddle -room -1025 -1101 -barney1 -baylor -gotham -gravity -hancock -616161 -515000 -caca -castor -chilli -fdsa -getout -fuck69 -gators1 -sail -sable -rumble -dork -dickens -duffer -onions -logger -lorena -lookout -magic32 -port -poon -prime -twat -citroen -civicsi -coochie -compaq1 -nancy1 -buzzer -boulder -butkus -bungle -hogtied -honor -hero -hilary -heidi1 -mortal -wendy1 -vibrate -vicky -bledsoe -blink -woof -xxxxx1 -talk -stock -tabatha -sheeba -start1 -peanut1 -tools -tetsuo -torino -tennis1 -termite -ladder -last -lemmein -jughead -melrose -megane -redone -request -angela1 -alive -alissa -gonzo1 -golden1 -656565 -626262 -chains -calvin1 -foolish -fallon -gabber -runaway -salami -dummy -dungeon -dumb -dope -opus -paragon -oxygen -panhead -odyssey -lottie -prince1 -trustme -christa -court -davies -neville -nono -bread -buffet -hound -kajak -mona -moto -mildred -winner1 -vixen -versace -winona -instant -indy -bigal -beech -biggun -blake1 -blue99 -big1 -woods -synergy -336699 -sixty9 -shark1 -skin -simba1 -sharpe -sebring -spunk -springs -sliver -pizza1 -plane -perkins -pookey -lawman -joe123 -jolly -mike123 -romeo1 -reserve -alanis -ariane -antony -band -hand -haley -byebye -camden -chewy -forumwp -franks -fruity -pantie -oldone -lumina -prosper -total -true -ajax -951753 -achtung -compact -color -corn -christi -closer -corndog -dank -nimitz -brandy1 -bowl -breanna -holein1 -east -kenobi -waldo -wing -invis -1996 -benton -bigjohn -beef -beater -benji -bluejay -xyzzy -storage -taichi -stellar -shaker -skirt -seymour -semper -splurge -squeak -pearls -pitch -phyllis -pooky -piss -tomas -titfuck -joemama -johnny5 -married -maxi -rhubarb -ratboy -reload -rooney -redd -1029 -1030 -1220 -anchor -bbking -gryphon -gone -57chevy -494949 -celeron -fishy -fucker1 -roswell -dougie -downer -dicker -diva -domingo -donjuan -nympho -omar -praise -racers -trick -trauma -truck1 -trample -acer -corwin -climax -denmark -cuervo -notnow -nittany -neutron -native -bosco1 -buffa -breaker -hello2 -hydro -estelle -explore -kittys -modem -mooney -weiner -bibi -benfica -yahoo1 -striper -tabasco -supra -383838 -456654 -seneca -serious -shuttle -socks -stanton -thethe -listen -jeter2 -marma -mark1 -metoo -rollin -redleg -redbone -redskin -rocco -1245 -armand -altoids -andrews -barley -away -asswipe -bauhaus -bbbbbb1 -gohome -harrier -golfpro -818181 -6666666 -5000 -5rxypn -calling -checker -calibra -fields -faith1 -fist -fdm7ed -finally -giraffe -glasses -giggles -fringe -gate -georgie -scamper -rrpass1 -duffy -deville -dimples -pacino -ontario -oberon -quest1 -puffer -raining -protect -qwerty7 -trey -tribe -ulysses -tribal -adam25 -compton -collie -davide -norris -namaste -myrtle -bonovox -buckley -bukkake -burning -burner -burly -hun999 -emilie -elmo -enters -enrique -keisha -mohawk -willard -vgirl -whale -vince -jayden -jarrett -1812 -1943 -222333 -bigjim -bigd -zoom -wordup -ziggy1 -yahooo -workout -young1 -written -xmas -zzzzzz1 -surfer1 -strife -tasha1 -skunk -shauna -seth -soft -planes -plum -pimping -thedon -toocool -leeann -laddie -list -lkjh -lara -joke -matty -rene -redrose -1200 -102938 -alexa -antares -ground -goose1 -737373 -789987 -6464 -caster -casper1 -cement -chessie -caddy -chill -child -canucks -feeling -gigi -rugby1 -dshade -dudes -dixie1 -owen -olympia -lucas1 -manga -puff -tribble -ussy -core -clint -colt -debra -dealer -newark -husband -hiking -errors -emmett -emilia -koolaid -knight1 -murphy1 -volcano -idunno -2005 -2233 -block -benito -biguns -zapper -zorro1 -0911 -3006 -sixsix -shopper -siobhan -sextoy -sounds -pokey -peabody -titi -think -toast -lister -lambda -joecool -jonas -joyce -juniper -mercer -max123 -manny -massimo -met2002 -reggae -ricky1 -1236 -1228 -1016 -all4one -arianna -asgard -484848 -5683 -6669 -catnip -chat -figure -galant -frenchy -girlies -gabby -garner -screwy -doubled -divers -dte4uw -done -maker -locks -treble -twinkie -trailer -acid -cooking -cococo -cory -dabomb -daffy -dandfa -cyrano -briggs -boners -helium -horton -hoffman -hellas -emperor -killa -wanda -w4g8at -verona -ilikeit -iforget -1944 -blue1 -blazers -benny1 -0069 -0101 -taffy -susie -swim -stokes -4567 -shodan -spoiled -steffen -pissed -pavlov -place -petunia -terrell -thirty -toni -tito -teenie -lily -lillie -ladyboy -jeeper -joyjoy -mantle -mannn -reeves -123aaa -121314 -1021 -1004 -1120 -allen1 -ambers -amstel -ambrose -alice1 -allegro -alley -hatred -gspot -graves -goodsex -harpoon -878787 -8inches -4wwvte -case -chavez -gatsby -fudge -gerry -generic -gareth -fuckme2 -samm -sage -seadog -satchmo -scxakv -santafe -dipper -dingle -dizzy -madmad -london1 -qbg26i -vaughn -tzpvaw -vamp -comedy -comp -cowgirl -dawgs -delaney -nt5d27 -needles -newness -mykids -bryan1 -bouncer -hihihi -iceman1 -herring -horn -hook -hotlips -dynamo -klaus -kittie -kappa -kahlua -muffy -mizzou -mohamed -musical -wannabe -whatup -weller -willy1 -invest -blanche -bear1 -youknow -zelda -yyyyyy1 -070462 -zurich -storms -tail -strat -427900 -shelter -shells -sexy123 -smile1 -sophie1 -stefano -stayout -phish1 -payday -thebear -telefon -kswbdu -larson -jetta -jerky -melina -metro -retire -respect -1216 -1201 -1204 -1222 -1115 -barry1 -676767 -chandra -flesh -furball -gocubs -fruit -gman -gentle -dunbar -dewalt -diver1 -dhip6a -olemiss -ollie -mangos -pretzel -pusssy -tripleh -valdez -clean -comment -crew -clovis -deaths -dandan -darrel -ninguna -noah -bootsie -bp2002 -bourbon -brennan -bumble -books -hose -heyyou -hemlock -hippo -hornets -hogan -excess -extensa -muffin1 -werdna -info -iron -jack1 -1bitch -bmwbmw -bills -zaq123 -wxcvbn -tahoe -talbot -simona -shakur -sexyone -seviyi -sonja -smart1 -speed1 -pepito -terry1 -terrier -laser1 -lite -lancia -jenjen -jolene -midori -message -matteo -mental -miami1 -ronald1 -reason -rhythm -1218 -1026 -123987 -1015 -1103 -armada -austria -gotmilk -hawkins -gray -camila -camp -charge -camero -flex -getoff -glacier -glotest -froggie -gerbil -rugger -donna1 -deutsch -orchard -oyster -ophelia -pajero -m5wkqf -magenta -vantage -tyvugq -uptown -abacab -aaaaaa1 -advance -chuck1 -delmar -nate -navajo -nope -border -iawgk2 -hrfzlz -dylan1 -enrico -encore -emilio -killian -mutant -mizuno -video1 -viewer -weed420 -whales -jaguar1 -insight -1990 -159159 -1love -bliss -bears1 -binder -bigboss -blitz -xqgann -zeke -zardoz -table -3825 -signal -sentra -side -shiva -sonora -squid -slimjim -placid -photon -placebo -pearl1 -test12 -leinad -legman -jeepers -joeblow -mike23 -redcar -rhinos -rjw7x4 -1102 -112211 -alcohol -gwju3g -7bgiqk -7878 -535353 -4snz9g -cccccc1 -carola -cali -fister -fosters -finland -gizzmo -fuller -royalty -rugrat -sandie -rudolf -dooley -dive -doreen -dodo -drop -oemdlg -out3xf -paddy -opennow -puppy1 -quinn -ramjet -under -uncle -abraxas -corner -creed -cocoa -crown -cows -cn42qj -dancer1 -damned -nudity -nimda2k -buick -bobb -braves1 -brook -henrik -higher -dust -karachi -mortis -monies -wally1 -weapon -view -willie1 -vicki -1test -2929 -xytfu7 -yackwin -100100 -0660 -tahiti -talks -332211 -3535 -sedona -seawolf -shine -spleen -slash -spjfet -spooner -spock1 -penis1 -terri -thierry -toohot -large -limpone -johnnie -masterp -maxdog -ribbit -reed -rita -rockin -redhat -rising -1113 -1331 -allday -aladin -andrey -ariel -anytime -athome -basil -goofy1 -gustavo -ha8fyp -goodday -778899 -charon -chappy -caracas -cardiff -canada1 -cajun -catter -freddy1 -frazier -forme -follow -gavin -garlic -sarge -saskia -sanjose -russ -salsa -loop -locutus -malachi -lolipop -punker -rambo1 -quake -twin -aimee -coolcat -crappy -default -dental -deniro -d9ungl -daddys -napoli -nautica -nermal -brick -bogota -board -branch -breath -buds -hulk -hitachi -evans -ender -export -kikiki -kram -mongo -waqw3p -wizzard -visited -whdbtp -whkzyc -image -1fuck -binky -blind -bigred1 -blubber -benz -becky1 -wooden -xrated -0001 -survey -tammy1 -stuffer -3mpz4r -3000 -3some -selina -sierra1 -shampoo -silk -shyshy -standby -poker1 -plus -thought -theshit -torture -light1 -jjjjj1 -jocelyn -menthol -maximo -margaux -medic1 -release -richter -rhino1 -roach -renate -repair -reveal -1209 -1234321 -amigos -apricot -asdfgh1 -hatter -grimace -7xm5rq -6789 -capcom -cheesy -carrots -camping -fanatic -fool -format -fleming -girlie -glover -gilmore -gardner -safeway -ruthie -dogfart -dondon -diapers -odin -opiate -lollol -love12 -loomis -prague -pugsley -program -r29hqq -touch -airman -darkone -cummer -dempsey -damn -nadia -ndeyl5 -natchez -newone -buddys -homely -husky -iceland -hr3ytm -holla -exeter -kimkim -karine -k2trix -kernel -moonman -miles1 -mufasa -mousey -wilma -wilhelm -whites -2277 -blobby -blair -blinky -bikers -becca -blue23 -xman -wyvern -zxzxzx -zsmj2v -suede -t26gn4 -sugars -sylvie -tantra -swoosh -swiss -4226 -4271 -321123 -shoe -shane1 -shelby1 -spades -spain -smother -soup -pisser -photo1 -pebble -phones -peavey -picnic -terra -thistle -tokyo -therapy -lives -linden -kronos -lilbit -linux -marbles -reno -recall -1208 -1138 -1008 -alchemy -atticus -auditt -ballet -hanna -gubber -7474 -797979 -464646 -543210 -4zqauf -4949 -ch5nmk -carlito -chewey -caleb -cheddar -chachi -fever -fine -forlife -giants1 -gates -getit -gamble -gerhard -galileo -g3ujwg -ganja -rufus1 -scouts -discus -dudeman -olympus -oscars -osprey -madcow -locust -loyola -mammoth -proton -rabbit1 -pwxd5x -purple1 -punkass -uyxnyd -tyson1 -abcabc -colts -contour -clement -dddddd1 -cypher -denied -dagmar -name -noles -butters -buford -hoochie -hotel -hoser -eddy -ellis -motown -mp8o6d -wife -2055 -2211 -beavers -bloke -blade1 -yamato -zooropa -050505 -zw6syj -tango1 -swing -stern -swampy -susanna -tammie -445566 -333666 -sexpot -sickboy -spiffy -skylark -slam -pintail -phreak -places -teller -timtim -tires -thighs -left -latex -llamas -lkjhg -letters -lizzard -marlins -metal1 -manu -righton -1127 -alain -alcat -amigo -attract -azrael -hamper -gotenks -golfgti -gutter -h2slca -harman -grace1 -6chid8 -789654 -canine -casio -cazzo -chamber -cbr900 -cabrio -calypso -feline -fungus -goal -g9zns4 -full -giggle -fuck123 -saffron -dogmeat -dunlop -douche -dresden -pappy -oaktree -lydia -luft4 -puta -prayer -ramada -vcradq -tulip -tracy71 -tycoon -click -chitown -corps -couples -code -danman -dada -density -d9ebk7 -cummins -darth -cute -nash -nixon -norbert -nestle -brenda1 -bonanza -bundy -buddies -hotspur -heavy -horror -hufmqw -electro -erasure -enough -etvww4 -ewyuza -eric1 -kinder -kenken -kismet -klaatu -willi -waiting -igor -x35v8l -yogi -ywvxpz -xngwoj -zippy1 -020202 -**** -sweeney -story -sentry -spence -star12 -solace -sledge -states -snyder -star1 -paxton -pkxe62 -pilot1 -pommes -plants -tical -tictac -toes -lemans -kubrick -jys6wz -jonesy -jjjjjj1 -jigga -joelle -mate -riley1 -rosa -relief -1126 -badboy1 -asthma -auggie -hartley -gumbo -616913 -57np39 -56qhxs -4mnveh -cake -forbes -fqkw5m -fresno -godiva -gecko -gladys -gibson1 -fridge -saxman -rowing -sammys -scotts -scout1 -sasasa -samoht -ducky -driller -p3wqaw -nurse -oneone -openit -portia -rapier -pussy2 -ralphie -tuxedo -ulrike -trenton -come -deltas -mytime -nicky -nickie -noname -noles1 -bucker -bopper -bullock -burnout -bryce -hedges -hitter -ekim -espana -eatme69 -elpaso -eeeeee1 -eatme1 -karaoke -kara -misses -willem -webcam -jasons -jakarta -belair -bigdad -beerme -yoshi -yinyang -zimmer -x24ik3 -0000007 -ztmfcq -stopit -stooges -symow8 -strato -2hot4u -ship -simons -skins -shakes -sex1 -shield -snacks -pipe -pitt -pinto -tonton -lager -lizzy -juju -john123 -josiah -jesse1 -jordon -jingles -martian -mario1 -rochard -redwine -requiem -rats -1117 -1014 -1205 -althea -allie -amor -amiga -alpina -alert -banana1 -bahamut -hart -golfman -7uftyx -5432 -5353 -5151 -4747 -byron -chatham -cherie -foxfire -freaked -gayboy -gggggg1 -glenda -glitter -funny1 -scroll -rudolph -saddle -dingbat -digimon -omicron -parsons -ohio -panda1 -loloxx -lululu -racer1 -queen1 -prick -upnfmc -tyrant -trout1 -9skw5g -aceman -acls2h -aaabbb -aggie -comcast -craft -crissy -cloudy -cq2kph -custer -d6o8pm -darian -crumbs -daisey -dasani -needle -mzepab -myporn -narnia -booger1 -bravo1 -budgie -btnjey -hotel6 -humbug -edwin -ewtosi -kobe -keith1 -muff -muschi -wiggle -whatthe -walking -vette1 -vols -virago -intj3a -ishmael -intern -jachin -199999 -2010 -beck -blender -bengal -your -zaqxsw -xray -zebras -yanks -worlds -tadpole -stripes -3737 -4343 -3728 -4444444 -solar -sonne -smalls -sniffer -sonata -squirts -pitcher -pktmxr -points -texaco -lesbos -lilian -l8v53x -jimbeam -josie -jimi -maya -rocket1 -ringer -1219 -123098 -1233 -althor -arch -armando -basher -balboa -bbbbb1 -banks -harriet -gopack -golfnut -8520 -753159 -8dihc6 -666777 -cheeba -chino -cheeky -camel1 -falling -flubber -gianni -gloves -frisbee -fuzzy1 -sauce -schatz -sandra1 -scrotum -scumbag -sabre -samdog -paige -orwell -lunatic -lonnie -lotion -maine -maddux -qn632o -rapper -tracks -ulrich -abacus -902100 -crispy -corky -crane -chooch -d6wnro -cutie -deal -dabulls -dehpye -njqcw4 -nownow -nigger1 -bustle -buddy2 -boingo -bugman -bosshog -bowie -hybrid -hilltop -hotlegs -honesty -hhhhh1 -eloise -evilone -e5pftu -eded -elefant -kenzie -karl -karin -killah -kleenex -mouses -motors -mutley -w00t88 -iloveit -jarjar -incest -indycar -1664 -222777 -2663 -beelch -benben -yitbos -yyyyy1 -yasmin -zapata -zzzzz1 -stooge -taztaz -system1 -3qvqod -3way -456321 -sizzle -simhrq -shrink -shawnee -someday -sparty -sphere -spark -slammed -sober -persian -peppers -ploppy -pn5jvw -poobear -pianos -plaster -testme -tiff -larissa -lennox -jewell -messier -rockey -1229 -1217 -1478 -1009 -amonra -aragon -albino -azazel -grinder -6uldv8 -83y6pv -8888888 -4tlved -515051 -carsten -changes -ffffff1 -foreman -firedog -ggggg1 -gerber -galway -gohan -giveme -geryfe -sayang -rudeboy -savanna -sandals -devine -dougal -drag0n -dga9la -desktop -only -onlyone -otter -pandas -mafia -lombard -luckys -lovejoy -manders -product -qqh92r -pork -radar1 -punani -ptbdhw -turtles -trs8f7 -tramp -ugejvp -abba -acdc -abcd123 -clever -corina -create -crash1 -colony -crosby -delboy -daniele -davinci -niki -nitrox -bonzai -budd -hotter -heeled -heroes -hooyah -hotgirl -i62gbq -horse1 -hills -hpk2qc -epvjb6 -echo -korean -kristie -mnbvc -mind -mommy1 -munster -wade -wiccan -wanted -jacket -2369 -blondy -bismark -beanbag -bjhgfi -ynot -yess -zlzfrh -wolvie -007bond -****** -tanya1 -sxhq65 -stinky1 -3234412 -3ki42x -seville -shimmer -sheryl -sienna -skillet -seaman -solaris -pastor -pasta -pedros -pfloyd -tobydog -lethal -letme1n -leland -jenifer -mario66 -micky -rocky2 -rewq -ripped -1128 -1207 -1104 -1432 -aprilia -alyson -bagels -basic -baggies -barb -barrage -gomez -guru -guard -72d5tn -606060 -4wcqjn -chance1 -catalog -faust -film -flange -fran -fartman -geil -gbhcf2 -glen -fuaqz4 -gameboy -garnet -rotary -seahawk -russel -saab -seal -devlt4 -ditto -drevil -drinker -deuce -donut -octopus -ottawa -porky -q9umoz -rapture -pump -triplex -ue8fpw -trent -trophy -turbos -agent -aaa340 -consult -creepy -craven -class -ddddd1 -dejavu -cuxldv -nettie -nbvibt -nikon -niko -norwood -nascar1 -nolan -bubba2 -boobear -boogers -buff -bully -editor -eagle2 -dynamic -ella -efyreg -edition -kidney -mogwai -morrow -msnxbi -wars -werder -voodoo1 -wheel -iiiiii1 -159951 -1624 -1911a1 -2244 -bedlam -belkin -bill1 -woodrow -xirt2k -worship -?????? -tanaka -swift -susieq -sundown -sukebe -tales -swifty -2fast4u -senate -sexe -shroom -shaun -seaweed -status -snicker -sorrow -spanky1 -spook -patti -pilots -pinch -peddler -theo -tessie -tiger7 -l2g7k3 -lazy -joan -mantra -mariana -mike69 -marshal -mart -mazda6 -riptide -robots -rental -1107 -1130 -142857 -1134 -armored -alvin -alec -alright -bartok -astral -baboon -bahamas -balls1 -bassoon -hcleeb -granite -golf1 -gomets -8vjzus -7890 -789123 -8uiazp -5757 -50cent -camaro1 -cherry1 -chemist -final -firenze -farrell -ganesh -same -doodles -dinger -okinawa -olympic -nursing -orpheus -ohmygod -paisley -null -lounge -mahalo -qwqwqw -qguvyt -rambler -puzzle -poppy1 -turk182 -trotter -vdlxuc -trish -tugboat -valiant -tracie -uwrl7c -coaster -cmfnpu -decimal -debbie1 -dandy -dede -nissan1 -napalm -boats -branden -britt -bonghit -hester -ibxnsm -hhhhhh1 -holger -durham -erwin -equinox -dvader -kimmy -knulla -mustafa -monsoon -mistral -morgana -monica1 -mojave -month -mrbill -vkaxcs -victor1 -wacker -wendell -vfdhif -wilson1 -wavpzt -verena -jarrod -imback -1914 -1monkey -2500 -2255 -blank -bigshow -zoomer -wtcacq -wobble -xmen -xjznq5 -yhwnqc -zzzxxx -streak -393939 -2fchbg -skilled -shakira -shaft -seaside -sigrid -sinful -silicon -smk7366 -sniper1 -staff -slap -smutty -peepers -plokij -pdiddy -thrust -terran -topaz -today1 -lauren1 -lgnu9d -juneau -methos -medina -merlyn -rogue1 -romulus -1202 -1469 -al9agd -aol123 -altec -apollo1 -arse -baker1 -bbb747 -bach -axeman -astro1 -hawks1 -gstring -hannes -8543852 -868686 -4ng62t -5401 -567890 -5232 -catfood -frame -flow -fire1 -fffff1 -fozzie -fluff -fzappa -furious -round -scarab -satin -ruger -destin -diablo2 -doqvq3 -drywall -offroad -luetdi -qcfmtz -pyf8ah -puddles -privacy -rainer -ralph1 -trivia -trewq -tri5a3 -advent -9898 -agyvorc -clarkie -coach1 -courier -contest -christo -corinna -chowder -concept -cyzkhw -davidb -days -de7mdf -nose -nazgul -booboo1 -broad -bonzo -brenna -boot -butch1 -hgfdsa -elmer -elektra -elodie -kermit1 -knife -kaboom -minute -modern -morten -mocha -monday1 -morgoth -ward -weewee -weenie -walters -vorlon -website -wahoo -insider -jayman -1911 -1dallas -1900 -1ranger -2501 -1qaz -bertram -bignuts -bigbad -beebee -billows -belize -bebe -wvj5np -wu4etd -yamaha1 -zebra1 -yankee1 -0311 -????? -stjabn -tainted -3tmnej -shoot -skooter -skelter -sixteen -smack -spice1 -stacey1 -smithy -perrin -pollux -pixie -paulina -piston -pick -poets -pine -toons -tooth -topspin -kugm7b -legends -juliana -jonboy -judge -midland -meteor -mccabe -matter -mayfair -meeting -merrill -raul -riches -reznor -reboot -reject -robyn -renee1 -roadway -1411 -1478963 -1019 -archery -allman -barks -bagpuss -hazmat -gucci -guns -grammy -greek -7kbe9d -7676 -6bjvpe -5lyedn -5858 -5291 -chas -c7lrwu -candys -chateau -ccccc1 -fear -fihdfv -gocats -gaelic -fwsadn -godboy -gldmeo -fx3tuo -fubar1 -garland -gforce -rxmtkp -rulz -sairam -dunhill -dogggg -detect -details -doll -drinks -ov3ajy -lockout -makayla -loves -prima -pvjegu -qhxbij -raphael -totoro -tusymo -tunnel -valeria -tulane -turtle1 -tracy1 -abbey1 -address -clticic -cooper1 -comets -collect -corbin -derick -cyprus -dante1 -dave1 -neal -nexus6 -nero -nogard -norfolk -brent1 -booyah -bootleg -bulls23 -bulls1 -booper -heretic -icecube -hellno -hounds -hoes -howie -hevnm4 -eighty -epson -eeeee1 -eyphed \ No newline at end of file diff --git a/lib/composer_messages_finder.rb b/lib/composer_messages_finder.rb index e61d0729d84..8dbf1f08b61 100644 --- a/lib/composer_messages_finder.rb +++ b/lib/composer_messages_finder.rb @@ -3,14 +3,15 @@ class ComposerMessagesFinder def initialize(user, details) @user = user @details = details + @topic = Topic.find_by(id: details[:topic_id]) if details[:topic_id] end def find - check_reviving_old_topic || - check_education_message || + check_reviving_old_topic || + check_education_message || check_new_user_many_replies || - check_avatar_notification || - check_sequential_replies || + check_avatar_notification || + check_sequential_replies || check_dominating_topic end @@ -18,10 +19,10 @@ class ComposerMessagesFinder def check_education_message if creating_topic? count = @user.created_topic_count - education_key = :education_new_topic + education_key = 'education.new-topic' else count = @user.post_count - education_key = :education_new_reply + education_key = 'education.new-reply' end if count < SiteSetting.educate_until_posts @@ -29,7 +30,7 @@ class ComposerMessagesFinder return { templateName: 'composer/education', wait_for_typing: true, - body: PrettyText.cook(SiteText.text_for(education_key, education_posts_text: education_posts_text)) + body: PrettyText.cook(I18n.t(education_key, education_posts_text: education_posts_text, site_name: SiteSetting.title)) } end @@ -55,6 +56,12 @@ class ComposerMessagesFinder # We don't notify users who have avatars or who have been notified already. return if @user.uploaded_avatar_id || UserHistory.exists_for_user?(@user, :notified_about_avatar) + # Do not notify user if any of the following is true: + # - "disable avatar education message" is enabled + # - "sso overrides avatar" is enabled + # - "allow uploaded avatars" is disabled + return if SiteSetting.disable_avatar_education_message || SiteSetting.sso_overrides_avatar || !SiteSetting.allow_uploaded_avatars + # If we got this far, log that we've nagged them about the avatar UserHistory.create!(action: UserHistory.actions[:notified_about_avatar], target_user_id: @user.id ) @@ -74,6 +81,9 @@ class ComposerMessagesFinder # And who have posted enough (@user.post_count >= SiteSetting.educate_until_posts) && + # And it's not a message + (@topic.present? && !@topic.private_message?) && + # And who haven't been notified about sequential replies already !UserHistory.exists_for_user?(@user, :notified_about_sequential_replies, topic_id: @details[:topic_id]) @@ -96,7 +106,7 @@ class ComposerMessagesFinder { templateName: 'composer/education', wait_for_typing: true, - extraClass: 'urgent', + extraClass: 'education-message', body: PrettyText.cook(I18n.t('education.sequential_replies')) } end @@ -109,16 +119,14 @@ class ComposerMessagesFinder (@user.post_count >= SiteSetting.educate_until_posts) && !UserHistory.exists_for_user?(@user, :notified_about_dominating_topic, topic_id: @details[:topic_id]) - topic = Topic.find_by(id: @details[:topic_id]) + return if @topic.blank? || + @topic.user_id == @user.id || + @topic.posts_count < SiteSetting.summary_posts_required || + @topic.private_message? - return if topic.blank? || - topic.user_id == @user.id || - topic.posts_count < SiteSetting.summary_posts_required || - topic.archetype == Archetype.private_message + posts_by_user = @user.posts.where(topic_id: @topic.id).count - posts_by_user = @user.posts.where(topic_id: topic.id).count - - ratio = (posts_by_user.to_f / topic.posts_count.to_f) + ratio = (posts_by_user.to_f / @topic.posts_count.to_f) return if ratio < (SiteSetting.dominating_topic_minimum_percent.to_f / 100.0) # Log the topic notification @@ -129,28 +137,23 @@ class ComposerMessagesFinder { templateName: 'composer/education', wait_for_typing: true, - extraClass: 'urgent', + extraClass: 'education-message', body: PrettyText.cook(I18n.t('education.dominating_topic', percent: (ratio * 100).round)) } end def check_reviving_old_topic - return unless @details[:topic_id] - - topic = Topic.find_by(id: @details[:topic_id]) - return unless replying? - - return if topic.nil? || + return if @topic.nil? || SiteSetting.warn_reviving_old_topic_age < 1 || - topic.last_posted_at.nil? || - topic.last_posted_at > SiteSetting.warn_reviving_old_topic_age.days.ago + @topic.last_posted_at.nil? || + @topic.last_posted_at > SiteSetting.warn_reviving_old_topic_age.days.ago { templateName: 'composer/education', wait_for_typing: false, - extraClass: 'urgent', - body: PrettyText.cook(I18n.t('education.reviving_old_topic', days: (Time.zone.now - topic.last_posted_at).round / 1.day)) + extraClass: 'education-message', + body: PrettyText.cook(I18n.t('education.reviving_old_topic', days: (Time.zone.now - @topic.last_posted_at).round / 1.day)) } end diff --git a/lib/cooked_post_processor.rb b/lib/cooked_post_processor.rb index 13d30c2c972..ea82b730a8e 100644 --- a/lib/cooked_post_processor.rb +++ b/lib/cooked_post_processor.rb @@ -2,6 +2,7 @@ # For example, inserting the onebox content, or image sizes/thumbnails. require_dependency 'url_helper' +require_dependency 'pretty_text' class CookedPostProcessor include ActionView::Helpers::NumberHelper @@ -11,7 +12,12 @@ class CookedPostProcessor @opts = opts @post = post @previous_cooked = (@post.cooked || "").dup - @doc = Nokogiri::HTML::fragment(post.cooked) + # NOTE: we re-cook the post here in order to prevent timing issues with edits + # cf. https://meta.discourse.org/t/edit-of-rebaked-post-doesnt-show-in-html-only-in-raw/33815/6 + @cooking_options = post.cooking_options || opts[:cooking_options] || {} + @cooking_options[:topic_id] = post.topic_id + @cooking_options = @cooking_options.symbolize_keys + @doc = Nokogiri::HTML::fragment(post.cook(post.raw, @cooking_options)) @size_cache = {} end @@ -60,7 +66,7 @@ class CookedPostProcessor convert_to_link!(img) end - update_topic_image(images) + update_topic_image end def extract_images @@ -76,6 +82,17 @@ class CookedPostProcessor @doc.css(".quote img") end + def extract_images_for_topic + # all image with a src attribute + @doc.css("img[src]") - + # minus, emojis + @doc.css("img.emoji") - + # minus, image inside oneboxes + oneboxed_images - + # minus, images inside quotes + @doc.css(".quote img") + end + def oneboxed_images @doc.css(".onebox-result img, .onebox img") end @@ -99,13 +116,16 @@ class CookedPostProcessor if w > 0 || h > 0 w = w.to_f h = h.to_f - original_width, original_height = get_size(img["src"]).map {|integer| integer.to_f} + + return unless original_image_size = get_size(img["src"]) + original_width, original_height = original_image_size.map(&:to_f) + if w > 0 ratio = w/original_width - return [w.floor, (original_height*ratio).floor] + [w.floor, (original_height*ratio).floor] else ratio = h/original_height - return [(original_width*ratio).floor, h.floor] + [(original_width*ratio).floor, h.floor] end end end @@ -231,9 +251,9 @@ class CookedPostProcessor span end - def update_topic_image(images) + def update_topic_image if @post.is_first_post? - img = images.first + img = extract_images_for_topic.first @post.topic.update_column(:image_url, img["src"][0...255]) if img["src"].present? end end @@ -245,13 +265,28 @@ class CookedPostProcessor } # apply oneboxes - Oneboxer.apply(@doc) { |url| Oneboxer.onebox(url, args) } + Oneboxer.apply(@doc, topic_id: @post.topic_id) { |url| + Oneboxer.onebox(url, args) + } # make sure we grab dimensions for oneboxed images oneboxed_images.each { |img| limit_size!(img) } + + # respect nofollow admin settings + if !@cooking_options[:omit_nofollow] && SiteSetting.add_rel_nofollow_to_user_content + PrettyText.add_rel_nofollow_to_user_content(@doc) + end end def optimize_urls + # when login is required, attachments can't be on the CDN + if SiteSetting.login_required + @doc.css("a.attachment[href]").each do |a| + href = a["href"].to_s + a["href"] = UrlHelper.schemaless UrlHelper.absolute(href, nil) if UrlHelper.is_local(href) + end + end + %w{href data-download-href}.each do |selector| @doc.css("a[#{selector}]").each do |a| href = a["#{selector}"].to_s @@ -275,7 +310,7 @@ class CookedPostProcessor # make sure no other job is scheduled Jobs.cancel_scheduled_job(:pull_hotlinked_images, post_id: @post.id) # schedule the job - delay = SiteSetting.ninja_edit_window + 1 + delay = SiteSetting.editing_grace_period + 1 Jobs.enqueue_in(delay.seconds.to_i, :pull_hotlinked_images, post_id: @post.id, bypass_bump: bypass_bump) end diff --git a/lib/demon/sidekiq.rb b/lib/demon/sidekiq.rb index 825da9824c6..d8182312de6 100644 --- a/lib/demon/sidekiq.rb +++ b/lib/demon/sidekiq.rb @@ -27,7 +27,7 @@ class Demon::Sidekiq < Demon::Base cli = Sidekiq::CLI.instance cli.parse(["-c", GlobalSetting.sidekiq_workers.to_s]) - load Rails.root + "config/initializers/sidekiq.rb" + load Rails.root + "config/initializers/100-sidekiq.rb" cli.run rescue => e STDERR.puts e.message diff --git a/lib/discourse.rb b/lib/discourse.rb index a087120ee72..8252b5da766 100644 --- a/lib/discourse.rb +++ b/lib/discourse.rb @@ -112,17 +112,22 @@ module Discourse end end + def self.last_read_only + @last_read_only ||= {} + end + def self.recently_readonly? - return false unless @last_read_only - @last_read_only > 15.seconds.ago + read_only = last_read_only[$redis.namespace] + return false unless read_only + read_only > 15.seconds.ago end def self.received_readonly! - @last_read_only = Time.now + last_read_only[$redis.namespace] = Time.zone.now end def self.clear_readonly! - @last_read_only = nil + last_read_only[$redis.namespace] = nil end def self.disabled_plugin_names @@ -272,7 +277,7 @@ module Discourse # Either returns the site_contact_username user or the first admin. def self.site_contact_user user = User.find_by(username_lower: SiteSetting.site_contact_username.downcase) if SiteSetting.site_contact_username.present? - user ||= User.admins.real.order(:id).first + user ||= (system_user || User.admins.real.order(:id).first) end SYSTEM_USER_ID ||= -1 @@ -340,7 +345,7 @@ module Discourse while true begin sleep GlobalSetting.connection_reaper_interval - reap_connections(GlobalSetting.connection_reaper_age) + reap_connections(GlobalSetting.connection_reaper_age, GlobalSetting.connection_reaper_max_age) rescue => e Discourse.handle_exception(e, {message: "Error reaping connections"}) end @@ -348,12 +353,12 @@ module Discourse end end - def self.reap_connections(age) + def self.reap_connections(idle, max_age) pools = [] ObjectSpace.each_object(ActiveRecord::ConnectionAdapters::ConnectionPool){|pool| pools << pool} pools.each do |pool| - pool.drain(age.seconds) + pool.drain(idle.seconds, max_age.seconds) end end diff --git a/lib/discourse_hub.rb b/lib/discourse_hub.rb index 4309647b020..e174cf065a5 100644 --- a/lib/discourse_hub.rb +++ b/lib/discourse_hub.rb @@ -42,7 +42,7 @@ module DiscourseHub def self.hub_base_url if Rails.env.production? - 'http://api.discourse.org/api' + 'https://api.discourse.org/api' else ENV['HUB_BASE_URL'] || 'http://local.hub:3000/api' end diff --git a/lib/discourse_redis.rb b/lib/discourse_redis.rb index b4943fde9e2..8f865d9ac95 100644 --- a/lib/discourse_redis.rb +++ b/lib/discourse_redis.rb @@ -3,6 +3,99 @@ # require_dependency 'cache' class DiscourseRedis + class FallbackHandler + include Singleton + + MASTER_LINK_STATUS = "master_link_status:up".freeze + + def initialize + @master = true + @running = false + @mutex = Mutex.new + @slave_config = DiscourseRedis.slave_config + end + + def verify_master + synchronize do + return if @running && !recently_checked? + @running = true + end + + Thread.new { initiate_fallback_to_master } + end + + def initiate_fallback_to_master + begin + slave_client = ::Redis::Client.new(@slave_config) + + if slave_client.call([:info]).split("\r\n").include?(MASTER_LINK_STATUS) + slave_client.call([:client, [:kill, 'type', 'normal']]) + Discourse.clear_readonly! + Discourse.request_refresh! + @master = true + end + ensure + @running = false + @last_checked = Time.zone.now + slave_client.disconnect + end + end + + def master + synchronize { @master } + end + + def master=(args) + synchronize { @master = args } + end + + def recently_checked? + if @last_checked + Time.zone.now > (@last_checked + 5.seconds) + else + false + end + end + + private + + def synchronize + @mutex.synchronize { yield } + end + end + + class Connector < Redis::Client::Connector + MASTER = 'master'.freeze + SLAVE = 'slave'.freeze + + def initialize(options) + super(options) + @slave_options = DiscourseRedis.slave_config(options) + @fallback_handler = DiscourseRedis::FallbackHandler.instance + end + + def resolve + + return @options unless @slave_options[:host] + + begin + options = @options.dup + options.delete(:connector) + client = ::Redis::Client.new(options) + client.call([:role])[0] + @options + rescue Redis::ConnectionError, Redis::CannotConnectError, RuntimeError => ex + # A consul service name may be deregistered for a redis container setup + raise ex if ex.class == RuntimeError && ex.message != "Name or service not known" + + return @slave_options if !@fallback_handler.master + @fallback_handler.master = false + raise ex + ensure + client.disconnect + end + end + end def self.raw_connection(config = nil) config ||= self.config @@ -13,11 +106,19 @@ class DiscourseRedis GlobalSetting.redis_config end + def self.slave_config(options = config) + options.dup.merge!({ host: options[:slave_host], port: options[:slave_port] }) + end + def initialize(config=nil) @config = config || DiscourseRedis.config @redis = DiscourseRedis.raw_connection(@config) end + def self.fallback_handler + @fallback_handler ||= DiscourseRedis::FallbackHandler.instance + end + def without_namespace # Only use this if you want to store and fetch data that's shared between sites @redis @@ -30,6 +131,8 @@ class DiscourseRedis unless Discourse.recently_readonly? STDERR.puts "WARN: Redis is in a readonly state. Performed a noop" end + + fallback_handler.verify_master if !fallback_handler.master Discourse.received_readonly! else raise ex @@ -49,7 +152,7 @@ class DiscourseRedis [:append, :blpop, :brpop, :brpoplpush, :decr, :decrby, :exists, :expire, :expireat, :get, :getbit, :getrange, :getset, :hdel, :hexists, :hget, :hgetall, :hincrby, :hincrbyfloat, :hkeys, :hlen, :hmget, :hmset, :hset, :hsetnx, :hvals, :incr, :incrby, :incrbyfloat, :lindex, :linsert, :llen, :lpop, :lpush, :lpushx, :lrange, :lrem, :lset, :ltrim, - :mapped_hmset, :mapped_hmget, :mapped_mget, :mapped_mset, :mapped_msetnx, :mget, :move, :mset, + :mapped_hmset, :mapped_hmget, :mapped_mget, :mapped_mset, :mapped_msetnx, :move, :mset, :msetnx, :persist, :pexpire, :pexpireat, :psetex, :pttl, :rename, :renamenx, :rpop, :rpoplpush, :rpush, :rpushx, :sadd, :scard, :sdiff, :set, :setbit, :setex, :setnx, :setrange, :sinter, :sismember, :smembers, :sort, :spop, :srandmember, :srem, :strlen, :sunion, :ttl, :type, :watch, :zadd, :zcard, :zcount, :zincrby, :zrange, :zrangebyscore, :zrank, :zrem, :zremrangebyrank, @@ -60,6 +163,11 @@ class DiscourseRedis end end + def mget(*args) + args.map!{|a| "#{namespace}:#{a}"} + DiscourseRedis.ignore_readonly { @redis.mget(*args) } + end + def del(k) DiscourseRedis.ignore_readonly do k = "#{namespace}:#{k}" diff --git a/lib/disk_space.rb b/lib/disk_space.rb index 18f4d1a9fa6..7a97348430d 100644 --- a/lib/disk_space.rb +++ b/lib/disk_space.rb @@ -57,7 +57,7 @@ class DiskSpace protected def self.free(path) - `df -Pk #{path} | awk 'NR==2 {print $4 * 1024;}'`.to_i + `df -Pk #{path} | awk 'NR==2 {print $4;}'`.to_i * 1024 end def self.used(path) diff --git a/lib/distributed_cache.rb b/lib/distributed_cache.rb index 58974b77ad2..31753320364 100644 --- a/lib/distributed_cache.rb +++ b/lib/distributed_cache.rb @@ -3,6 +3,7 @@ # fill it up require 'weakref' +require 'base64' class DistributedCache @subscribers = [] @@ -31,7 +32,7 @@ class DistributedCache hash = current.hash(message.site_id) case payload["op"] - when "set" then hash[payload["key"]] = payload["marshalled"] ? Marshal.load(payload["value"]) : payload["value"] + when "set" then hash[payload["key"]] = payload["marshalled"] ? Marshal.load(Base64.decode64(payload["value"])) : payload["value"] when "delete" then hash.delete(payload["key"]) when "clear" then hash.clear end @@ -70,8 +71,8 @@ class DistributedCache def self.set(hash, key, value) # special support for set - marshal = Set === value - value = Marshal.dump(value) if marshal + marshal = (Set === value || Hash === value) + value = Base64.encode64(Marshal.dump(value)) if marshal publish(hash, { op: :set, key: key, value: value, marshalled: marshal }) end diff --git a/lib/edit_rate_limiter.rb b/lib/edit_rate_limiter.rb index 3c42a89bfc0..d30c7c66fc7 100644 --- a/lib/edit_rate_limiter.rb +++ b/lib/edit_rate_limiter.rb @@ -1,6 +1,10 @@ require 'rate_limiter' class EditRateLimiter < RateLimiter def initialize(user) - super(user, "edit-post:#{Date.today}", SiteSetting.max_edits_per_day, 1.day.to_i) + super(user, "edit-post", SiteSetting.max_edits_per_day, 1.day.to_i) + end + + def build_key(type) + "#{super(type)}:#{Date.today}" end end diff --git a/lib/email.rb b/lib/email.rb index 1b728aee7ea..f0fbc28e57c 100644 --- a/lib/email.rb +++ b/lib/email.rb @@ -10,13 +10,14 @@ module Email return false unless String === email - parser = Mail::RFC2822Parser.new - parser.root = :addr_spec - result = parser.parse(email) + parsed = Mail::Address.new(email) + # Don't allow for a TLD by itself list (sam@localhost) # The Grammar is: (local_part "@" domain) / local_part ... need to discard latter - result && result.respond_to?(:domain) && result.domain.dot_atom_text.elements.size > 1 + parsed.address == email && parsed.local != parsed.address && parsed.domain && parsed.domain.split(".").length > 1 + rescue Mail::Field::ParseError + false end def self.downcase(email) diff --git a/lib/email/message_builder.rb b/lib/email/message_builder.rb index bacc5f1cf1e..991620e3ad8 100644 --- a/lib/email/message_builder.rb +++ b/lib/email/message_builder.rb @@ -7,7 +7,7 @@ module Email builder = Email::MessageBuilder.new(*builder_args) headers(builder.header_args) if builder.header_args.present? mail(builder.build_args).tap { |message| - if message and h = builder.html_part + if message && h = builder.html_part message.html_part = h end } @@ -28,14 +28,18 @@ module Email }.merge!(@opts) if @template_args[:url].present? + @template_args[:header_instructions] = I18n.t('user_notifications.header_instructions', locale: @opts[:locale]) + if @opts[:include_respond_instructions] == false @template_args[:respond_instructions] = '' else - @template_args[:respond_instructions] = if allow_reply_by_email? - I18n.t('user_notifications.reply_by_email', @template_args) + if @opts[:only_reply_by_email] + string = "user_notifications.only_reply_by_email" else - I18n.t('user_notifications.visit_link_to_respond', @template_args) + string = allow_reply_by_email? ? "user_notifications.reply_by_email" : "user_notifications.visit_link_to_respond" + string << "_pm" if @opts[:private_reply] end + @template_args[:respond_instructions] = I18n.t(string, @template_args) end end end @@ -59,16 +63,37 @@ module Email return unless html_override = @opts[:html_override] if @opts[:add_unsubscribe_link] - if response_instructions = @template_args[:respond_instructions] - respond_instructions = PrettyText.cook(response_instructions).html_safe - html_override.gsub!("%{respond_instructions}", respond_instructions) - end - - unsubscribe_link = PrettyText.cook(I18n.t('unsubscribe_link', template_args)).html_safe + unsubscribe_link = PrettyText.cook(I18n.t('unsubscribe_link', template_args), sanitize: false).html_safe html_override.gsub!("%{unsubscribe_link}", unsubscribe_link) + + if SiteSetting.unsubscribe_via_email_footer && @opts[:add_unsubscribe_via_email_link] + unsubscribe_via_email_link = PrettyText.cook(I18n.t('unsubscribe_via_email_link', hostname: Discourse.current_hostname, locale: @opts[:locale]), sanitize: false).html_safe + html_override.gsub!("%{unsubscribe_via_email_link}", unsubscribe_via_email_link) + else + html_override.gsub!("%{unsubscribe_via_email_link}", "") + end + else + html_override.gsub!("%{unsubscribe_link}", "") + html_override.gsub!("%{unsubscribe_via_email_link}", "") end - styled = Email::Styles.new(html_override) + header_instructions = @template_args[:header_instructions] + if header_instructions.present? + header_instructions = PrettyText.cook(header_instructions, sanitize: false).html_safe + html_override.gsub!("%{header_instructions}", header_instructions) + else + html_override.gsub!("%{header_instructions}", "") + end + + if response_instructions = @template_args[:respond_instructions] + respond_instructions = PrettyText.cook(response_instructions, sanitize: false).html_safe + html_override.gsub!("%{respond_instructions}", respond_instructions) + else + html_override.gsub!("%{respond_instructions}", "") + end + + + styled = Email::Styles.new(html_override, @opts) styled.format_basic if style = @opts[:style] @@ -88,6 +113,9 @@ module Email if @opts[:add_unsubscribe_link] body << "\n" body << I18n.t('unsubscribe_link', template_args) + if SiteSetting.unsubscribe_via_email_footer && @opts[:add_unsubscribe_via_email_link] + body << I18n.t('unsubscribe_via_email_link', hostname: Discourse.current_hostname, locale: @opts[:locale]) + end end body diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb index f8fb71f5bd8..f742733c6c0 100644 --- a/lib/email/receiver.rb +++ b/lib/email/receiver.rb @@ -1,250 +1,355 @@ -require_dependency 'new_post_manager' -require 'email/html_cleaner' -# -# Handles an incoming message -# +require "digest" +require_dependency "new_post_manager" +require_dependency "post_action_creator" +require_dependency "email/html_cleaner" module Email class Receiver - include ActionView::Helpers::NumberHelper - class ProcessingError < StandardError; end - class EmailUnparsableError < ProcessingError; end - class EmptyEmailError < ProcessingError; end - class UserNotFoundError < ProcessingError; end - class UserNotSufficientTrustLevelError < ProcessingError; end - class BadDestinationAddress < ProcessingError; end - class TopicNotFoundError < ProcessingError; end - class TopicClosedError < ProcessingError; end - class AutoGeneratedEmailError < ProcessingError; end - class EmailLogNotFound < ProcessingError; end - class InvalidPost < ProcessingError; end + class ProcessingError < StandardError; end + class EmptyEmailError < ProcessingError; end + class UserNotFoundError < ProcessingError; end + class AutoGeneratedEmailError < ProcessingError; end + class NoBodyDetectedError < ProcessingError; end + class InactiveUserError < ProcessingError; end + class BlockedUserError < ProcessingError; end + class BadDestinationAddress < ProcessingError; end + class StrangersNotAllowedError < ProcessingError; end + class InsufficientTrustLevelError < ProcessingError; end + class ReplyUserNotMatchingError < ProcessingError; end + class TopicNotFoundError < ProcessingError; end + class TopicClosedError < ProcessingError; end + class InvalidPost < ProcessingError; end + class InvalidPostAction < ProcessingError; end - attr_reader :body, :email_log + attr_reader :incoming_email - def initialize(raw, opts=nil) - @raw = raw - @opts = opts || {} + def initialize(mail_string) + raise EmptyEmailError if mail_string.blank? + @raw_email = mail_string + @mail = Mail.new(@raw_email) + @message_id = @mail.message_id.presence || Digest::MD5.hexdigest(mail_string) end - def process - raise EmptyEmailError if @raw.blank? + def process! + @from_email, @from_display_name = parse_from_field + @incoming_email = find_or_create_incoming_email + process_internal + rescue => e + @incoming_email.update_columns(error: e.to_s) + raise + end - message = Mail.new(@raw) - - body = parse_body message - - dest_info = {type: :invalid, obj: nil} - message.to.each do |to_address| - if dest_info[:type] == :invalid - dest_info = check_address to_address - end + def find_or_create_incoming_email + IncomingEmail.find_or_create_by(message_id: @message_id) do |ie| + ie.raw = @raw_email + ie.subject = subject + ie.from_address = @from_email + ie.to_addresses = @mail.to.map(&:downcase).join(";") if @mail.to.present? + ie.cc_addresses = @mail.cc.map(&:downcase).join(";") if @mail.cc.present? end + end - raise BadDestinationAddress if dest_info[:type] == :invalid - raise AutoGeneratedEmailError if message.header.to_s =~ /auto-generated/ || message.header.to_s =~ /auto-replied/ + def process_internal + user = find_or_create_user(@from_email, @from_display_name) - # TODO get to a state where we can remove this - @message = message - @body = body + raise UserNotFoundError if user.nil? - if dest_info[:type] == :category - raise BadDestinationAddress unless SiteSetting.email_in - category = dest_info[:obj] - @category_id = category.id - @allow_strangers = category.email_in_allow_strangers + @incoming_email.update_columns(user_id: user.id) - user_email = @message.from.first - @user = User.find_by_email(user_email) - if @user.blank? && @allow_strangers + body, @elided = select_body + body ||= "" - wrap_body_in_quote user_email - # TODO This is WRONG it should register an account - # and email the user details on how to log in / activate - @user = Discourse.system_user - end + raise AutoGeneratedEmailError if is_auto_generated? + raise NoBodyDetectedError if body.blank? && !@mail.has_attachments? + raise InactiveUserError if !user.active && !user.staged + raise BlockedUserError if user.blocked - raise UserNotFoundError if @user.blank? - raise UserNotSufficientTrustLevelError.new @user unless @allow_strangers || @user.has_trust_level?(TrustLevel[SiteSetting.email_in_min_trust.to_i]) - - create_new_topic + if action = subscription_action_for(body, subject) + message = SubscriptionMailer.send(action, user) + Email::Sender.new(message, :subscription).send + elsif post = find_related_post + create_reply(user: user, + raw: body, + post: post, + topic: post.topic, + skip_validations: user.staged?) else - @email_log = dest_info[:obj] + destination = destinations.first - raise EmailLogNotFound if @email_log.blank? - raise TopicNotFoundError if Topic.find_by_id(@email_log.topic_id).nil? - raise TopicClosedError if Topic.find_by_id(@email_log.topic_id).closed? + raise BadDestinationAddress if destination.blank? - create_reply + case destination[:type] + when :group + group = destination[:obj] + create_topic(user: user, + raw: body, + title: subject, + archetype: Archetype.private_message, + target_group_names: [group.name], + is_group_message: true, + skip_validations: true) + + when :category + category = destination[:obj] + + raise StrangersNotAllowedError if user.staged? && !category.email_in_allow_strangers + raise InsufficientTrustLevelError if !user.has_trust_level?(SiteSetting.email_in_min_trust) + + create_topic(user: user, + raw: body, + title: subject, + category: category.id, + skip_validations: user.staged?) + + when :reply + email_log = destination[:obj] + + raise ReplyUserNotMatchingError if email_log.user_id != user.id + + create_reply(user: user, + raw: body, + post: email_log.post, + topic: email_log.post.topic) + end end - rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError => e - raise EmailUnparsableError.new(e) end - def check_address(address) - category = Category.find_by_email(address) - return {type: :category, obj: category} if category - - regex = Regexp.escape SiteSetting.reply_by_email_address - regex = regex.gsub(Regexp.escape('%{reply_key}'), "(.*)") - regex = Regexp.new regex - match = regex.match address - if match && match[1].present? - reply_key = match[1] - email_log = EmailLog.for(reply_key) - - return {type: :reply, obj: email_log} - end - - {type: :invalid, obj: nil} + def is_auto_generated? + @mail[:precedence].to_s[/list|junk|bulk|auto_reply/i] || + @mail[:from].to_s[/(mailer-?daemon|postmaster|noreply)@/i] || + @mail.header.to_s[/auto[\-_]?(response|submitted|replied|reply|generated|respond)|holidayreply|machinegenerated/i] end - def parse_body(message) - body = select_body message - encoding = body.encoding - raise EmptyEmailError if body.strip.blank? - - body = discourse_email_trimmer body - raise EmptyEmailError if body.strip.blank? - - body = EmailReplyParser.parse_reply body - raise EmptyEmailError if body.strip.blank? - - body.force_encoding(encoding).encode("UTF-8") - end - - def select_body(message) + def select_body + text = nil html = nil - # If the message is multipart, return that part (favor html) - if message.multipart? - html = fix_charset message.html_part - text = fix_charset message.text_part + elided = nil - # prefer plain text - if text - return text - end - elsif message.content_type =~ /text\/html/ - html = fix_charset message - end - - if html - body = HtmlCleaner.new(html).output_html + if @mail.multipart? + text = fix_charset(@mail.text_part) + html = fix_charset(@mail.html_part) + elsif @mail.content_type.to_s["text/html"] + html = fix_charset(@mail) else - body = fix_charset message + text = fix_charset(@mail) end - return body if @opts[:skip_sanity_check] + # prefer text over html + text = trim_discourse_markers(text) if text.present? + text, elided = EmailReplyTrimmer.trim(text, true) if text.present? + return [text, elided] if text.present? - # Certain trigger phrases that means we didn't parse correctly - if body =~ /Content\-Type\:/ || body =~ /multipart\/alternative/ || body =~ /text\/plain/ - raise EmptyEmailError - end - - body + # clean the html if that's all we've got + html = Email::HtmlCleaner.new(html).output_html if html.present? + html = trim_discourse_markers(html) if html.present? + html, elided = EmailReplyTrimmer.trim(html, true) if html.present? + return [html, elided] if html.present? end - # Force encoding to UTF-8 on a Mail::Message or Mail::Part - def fix_charset(object) - return nil if object.nil? + def fix_charset(mail_part) + return nil if mail_part.blank? || mail_part.body.blank? - if object.charset - object.body.decoded.force_encoding(object.charset.gsub(/utf8/i, "UTF-8")).encode("UTF-8").to_s - else - object.body.to_s + string = mail_part.body.decoded rescue nil + + return nil if string.blank? + + # 1) use the charset provided + if mail_part.charset.present? + fixed = try_to_encode(string, mail_part.charset) + return fixed if fixed.present? end - rescue + + # 2) try most used encodings + try_to_encode(string, "UTF-8") || try_to_encode(string, "ISO-8859-1") + end + + def try_to_encode(string, encoding) + encoded = string.encode("UTF-8", encoding) + encoded.present? && encoded.valid_encoding? ? encoded : nil + rescue Encoding::InvalidByteSequenceError, + Encoding::UndefinedConversionError, + Encoding::ConverterNotFoundError nil end - REPLYING_HEADER_LABELS = ['From', 'Sent', 'To', 'Subject', 'Reply To', 'Cc', 'Bcc', 'Date'] - REPLYING_HEADER_REGEX = Regexp.union(REPLYING_HEADER_LABELS.map { |lbl| "#{lbl}:" }) + def previous_replies_regex + @previous_replies_regex ||= /^--[- ]\n\*#{I18n.t("user_notifications.previous_discussion")}\*\n/im + end - def discourse_email_trimmer(body) - lines = body.scrub.lines.to_a - range_end = 0 + def trim_discourse_markers(reply) + reply.split(previous_replies_regex)[0] + end - lines.each_with_index do |l, idx| - break if l =~ /\A\s*\-{3,80}\s*\z/ || - l =~ Regexp.new("\\A\\s*" + I18n.t('user_notifications.previous_discussion') + "\\s*\\Z") || - (l =~ /via #{SiteSetting.title}(.*)\:$/) || - # This one might be controversial but so many reply lines have years, times and end with a colon. - # Let's try it and see how well it works. - (l =~ /\d{4}/ && l =~ /\d:\d\d/ && l =~ /\:$/) || - (l =~ /On \w+ \d+,? \d+,?.*wrote:/) + def parse_from_field + if @mail[:from].errors.blank? + address_field = @mail[:from].address_list.addresses.first + address_field.decoded + from_address = address_field.address + from_display_name = address_field.display_name.try(:to_s) + else + from_address = @mail.from[/<([^>]+)>/, 1] + from_display_name = @mail.from[/^([^<]+)/, 1] + end + [from_address.downcase, from_display_name] + end - # Headers on subsequent lines - break if (0..2).all? { |off| lines[idx+off] =~ REPLYING_HEADER_REGEX } - # Headers on the same line - break if REPLYING_HEADER_LABELS.count { |lbl| l.include? lbl } >= 3 + def subject + @suject ||= @mail.subject.presence || I18n.t("emails.incoming.default_subject", email: @from_email) + end - range_end = idx + def find_or_create_user(email, display_name) + user = nil + + User.transaction do + user = User.find_by_email(email) + + if user.nil? && SiteSetting.enable_staged_users + username = UserNameSuggester.sanitize_username(display_name) if display_name.present? + user = User.create( + email: email, + username: UserNameSuggester.suggest(username.presence || email), + name: display_name.presence || User.suggest_name(email), + staged: true + ) + end end - lines[0..range_end].join.strip + user end - def wrap_body_in_quote(user_email) - @body = "[quote=\"#{user_email}\"] -#{@body} -[/quote]" + def destinations + [ @mail.destinations, + [@mail[:x_forwarded_to]].flatten.compact.map(&:decoded), + [@mail[:delivered_to]].flatten.compact.map(&:decoded), + ].flatten + .select(&:present?) + .uniq + .lazy + .map { |d| check_address(d) } + .drop_while(&:blank?) end - private + def check_address(address) + # only check for a group/category when 'email_in' is enabled + if SiteSetting.email_in + group = Group.find_by_email(address) + return { type: :group, obj: group } if group - def create_reply - create_post_with_attachments(@email_log.user, - raw: @body, - topic_id: @email_log.topic_id, - reply_to_post_number: @email_log.post.post_number) + category = Category.find_by_email(address) + return { type: :category, obj: category } if category + end + + # reply + match = reply_by_email_address_regex.match(address) + if match && match[1].present? + email_log = EmailLog.for(match[1]) + return { type: :reply, obj: email_log } if email_log + end end - def create_new_topic - result = create_post_with_attachments(@user, - raw: @body, - title: @message.subject, - category: @category_id) - - topic_id = result.post.present? ? result.post.topic_id : nil - EmailLog.create( - email_type: "topic_via_incoming_email", - to_address: @message.from.first, # pick from address because we want the user's email - topic_id: topic_id, - user_id: @user.id, - ) - - result + def reply_by_email_address_regex + @reply_by_email_address_regex ||= Regexp.new Regexp.escape(SiteSetting.reply_by_email_address) + .gsub(Regexp.escape("%{reply_key}"), "([[:xdigit:]]{32})") end - def create_post_with_attachments(user, post_opts={}) - options = { - cooking_options: { traditional_markdown_linebreaks: true }, - }.merge(post_opts) + def group_incoming_emails_regex + @group_incoming_emails_regex ||= Regexp.union Group.pluck(:incoming_email).select(&:present?).map { |e| e.split("|") }.flatten.uniq + end - raw = options[:raw] + def category_email_in_regex + @category_email_in_regex ||= Regexp.union Category.pluck(:email_in).select(&:present?).map { |e| e.split("|") }.flatten.uniq + end + def find_related_post + message_ids = [@mail.in_reply_to, Email::Receiver.extract_references(@mail.references)] + message_ids.flatten! + message_ids.select!(&:present?) + message_ids.uniq! + return if message_ids.empty? + + Post.where(id: IncomingEmail.where(message_id: message_ids).select(:post_id)) + .order(created_at: :desc) + .first + end + + def self.extract_references(references) + if Array === references + references + elsif references.present? + references.split(/[\s,]/).map { |r| r.sub(/^$/, "") } + end + end + + def likes + @likes ||= Set.new ["+1", I18n.t('post_action_types.like.title').downcase] + end + + def subscription_action_for(body, subject) + return unless SiteSetting.unsubscribe_via_email + if ([subject, body].compact.map(&:to_s).map(&:downcase) & ['unsubscribe']).any? + :confirm_unsubscribe + end + end + + def post_action_for(body) + if likes.include?(body.strip.downcase) + PostActionType.types[:like] + end + end + + def create_topic(options={}) + create_post_with_attachments(options) + end + + def create_reply(options={}) + raise TopicNotFoundError if options[:topic].nil? || options[:topic].trashed? + raise TopicClosedError if options[:topic].closed? + + if post_action_type = post_action_for(options[:raw]) + create_post_action(options[:user], options[:post], post_action_type) + else + options[:topic_id] = options[:post].try(:topic_id) + options[:reply_to_post_number] = options[:post].try(:post_number) + options[:is_group_message] = options[:topic].private_message? && options[:topic].allowed_groups.exists? + create_post_with_attachments(options) + end + end + + def create_post_action(user, post, type) + PostActionCreator.new(user, post).perform(type) + rescue PostAction::AlreadyActed + # it's cool, don't care + rescue Discourse::InvalidAccess => e + raise InvalidPostAction.new(e) + end + + def create_post_with_attachments(options={}) # deal with attachments - @message.attachments.each do |attachment| + @mail.attachments.each do |attachment| tmp = Tempfile.new("discourse-email-attachment") begin # read attachment File.open(tmp.path, "w+b") { |f| f.write attachment.body.decoded } # create the upload for the user - upload = Upload.create_for(user.id, tmp, attachment.filename, tmp.size) + opts = { is_attachment_for_group_message: options[:is_group_message] } + upload = Upload.create_for(options[:user].id, tmp, attachment.filename, tmp.size, opts) if upload && upload.errors.empty? - # TODO: should use the same code as the client to insert attachments - raw << "\n#{attachment_markdown(upload)}\n" + # try to inline images + if attachment.content_type.start_with?("image/") && options[:raw][/\[image: .+ \d+\]/] + options[:raw].sub!(/\[image: .+ \d+\]/, attachment_markdown(upload)) + else + options[:raw] << "\n\n#{attachment_markdown(upload)}\n\n" + end end ensure - tmp.close! + tmp.try(:close!) rescue nil end end - options[:raw] = raw - - create_post(user, options) + create_post(options) end def attachment_markdown(upload) @@ -255,20 +360,68 @@ module Email end end - def create_post(user, options) - # Mark the reply as incoming via email + def create_post(options={}) options[:via_email] = true - options[:raw_email] = @raw + options[:raw_email] = @raw_email - manager = NewPostManager.new(user, options) - result = manager.perform + # ensure posts aren't created in the future + options[:created_at] = [@mail.date, DateTime.now].min - if result.errors.present? - raise InvalidPost, result.errors.full_messages.join("\n") + # only add elided part in messages + if @elided.present? && options[:topic].try(:private_message?) + options[:raw] << "\n\n" << "
    " << "\n" + options[:raw] << "···" << "\n" + options[:raw] << @elided << "\n" + options[:raw] << "
    " << "\n" end - result + manager = NewPostManager.new(options[:user], options) + result = manager.perform + + raise InvalidPost, result.errors.full_messages.join("\n") if result.errors.any? + + if result.post + @incoming_email.update_columns(topic_id: result.post.topic_id, post_id: result.post.id) + if result.post.topic && result.post.topic.private_message? + add_other_addresses(result.post.topic, options[:user]) + end + end + end + + def add_other_addresses(topic, sender) + %i(to cc bcc).each do |d| + if @mail[d] && @mail[d].address_list && @mail[d].address_list.addresses + @mail[d].address_list.addresses.each do |address_field| + begin + address_field.decoded + email = address_field.address.downcase + display_name = address_field.display_name.try(:to_s) + if should_invite?(email) + user = find_or_create_user(email, display_name) + if user && can_invite?(topic, user) + topic.topic_allowed_users.create!(user_id: user.id) + topic.add_small_action(sender, "invited_user", user.username) + end + end + rescue ActiveRecord::RecordInvalid + # don't care if user already allowed + end + end + end + end + end + + def should_invite?(email) + email !~ reply_by_email_address_regex && + email !~ group_incoming_emails_regex && + email !~ category_email_in_regex + end + + def can_invite?(topic, user) + !topic.topic_allowed_users.where(user_id: user.id).exists? && + !topic.topic_allowed_groups.where("group_id IN (SELECT group_id FROM group_users WHERE user_id = ?)", user.id).exists? end end + end diff --git a/lib/email/renderer.rb b/lib/email/renderer.rb index 4f21cb8bf79..9b209781ff9 100644 --- a/lib/email/renderer.rb +++ b/lib/email/renderer.rb @@ -16,11 +16,11 @@ module Email def html if @message.html_part - style = Email::Styles.new(@message.html_part.body.to_s) + style = Email::Styles.new(@message.html_part.body.to_s, @opts) style.format_basic style.format_html else - style = Email::Styles.new(PrettyText.cook(text)) + style = Email::Styles.new(PrettyText.cook(text), @opts) style.format_basic end diff --git a/lib/email/sender.rb b/lib/email/sender.rb index d1720aedd98..6168b086dfc 100644 --- a/lib/email/sender.rb +++ b/lib/email/sender.rb @@ -23,7 +23,11 @@ module Email def send return if SiteSetting.disable_emails - return skip(I18n.t('email_log.message_blank')) if @message.blank? + + return if ActionMailer::Base::NullMail === @message + return if ActionMailer::Base::NullMail === (@message.message rescue nil) + + return skip(I18n.t('email_log.message_blank')) if @message.blank? return skip(I18n.t('email_log.message_to_blank')) if @message.to.blank? if @message.text_part @@ -59,10 +63,7 @@ module Email @message.text_part.content_type = 'text/plain; charset=UTF-8' # Set up the email log - email_log = EmailLog.new(email_type: @email_type, - to_address: to_address, - user_id: @user.try(:id)) - + email_log = EmailLog.new(email_type: @email_type, to_address: to_address, user_id: @user.try(:id)) host = Email::Sender.host_for(Discourse.base_url) @@ -87,42 +88,40 @@ module Email # http://www.ietf.org/rfc/rfc2919.txt if topic && topic.category && !topic.category.uncategorized? - list_id = "<#{topic.category.name.downcase}.#{host}>" + list_id = "<#{topic.category.name.downcase.gsub(' ', '-')}.#{host}>" # subcategory case if !topic.category.parent_category_id.nil? parent_category_name = Category.find_by(id: topic.category.parent_category_id).name - list_id = "<#{topic.category.name.downcase}.#{parent_category_name.downcase}.#{host}>" + list_id = "<#{topic.category.name.downcase.gsub(' ', '-')}.#{parent_category_name.downcase.gsub(' ', '-')}.#{host}>" end else list_id = "<#{host}>" end - @message.header['List-ID'] = list_id - - @message.header['List-Archive'] = topic.url if topic # http://www.ietf.org/rfc/rfc3834.txt - @message.header['Precedence'] = 'list' + @message.header['Precedence'] = 'list' + @message.header['List-ID'] = list_id + @message.header['List-Archive'] = topic.url if topic end - if reply_key.present? - - if @message.header['Reply-To'] =~ /\<([^\>]+)\>/ - email = Regexp.last_match[1] - @message.header['List-Post'] = "" - end + if reply_key.present? && @message.header['Reply-To'] =~ /\<([^\>]+)\>/ + email = Regexp.last_match[1] + @message.header['List-Post'] = "" end email_log.post_id = post_id if post_id.present? email_log.reply_key = reply_key if reply_key.present? # Remove headers we don't need anymore - @message.header['X-Discourse-Topic-Id'] = nil if topic_id.present? - @message.header['X-Discourse-Post-Id'] = nil if post_id.present? + @message.header['X-Discourse-Topic-Id'] = nil if topic_id.present? + @message.header['X-Discourse-Post-Id'] = nil if post_id.present? @message.header['X-Discourse-Reply-Key'] = nil if reply_key.present? # Suppress images from short emails - if SiteSetting.strip_images_from_short_emails && @message.html_part.body.to_s.bytesize <= SiteSetting.short_email_length && @message.html_part.body =~ /]+>/ + if SiteSetting.strip_images_from_short_emails && + @message.html_part.body.to_s.bytesize <= SiteSetting.short_email_length && + @message.html_part.body =~ /]+>/ style = Email::Styles.new(@message.html_part.body.to_s) @message.html_part.body = style.strip_avatars_and_emojis end @@ -140,8 +139,9 @@ module Email def to_address @to_address ||= begin - to = @message ? @message.to : nil - to.is_a?(Array) ? to.first : to + to = @message.try(:to) + to = to.first if Array === to + to.presence || "no_email_found" end end @@ -166,11 +166,13 @@ module Email end def skip(reason) - EmailLog.create(email_type: @email_type, - to_address: to_address, - user_id: @user.try(:id), - skipped: true, - skipped_reason: reason) + EmailLog.create!( + email_type: @email_type, + to_address: to_address, + user_id: @user.try(:id), + skipped: true, + skipped_reason: "[Sender] #{reason}" + ) end end diff --git a/lib/email/styles.rb b/lib/email/styles.rb index 22f9ffe1e89..a82c8459f30 100644 --- a/lib/email/styles.rb +++ b/lib/email/styles.rb @@ -6,8 +6,9 @@ module Email class Styles @@plugin_callbacks = [] - def initialize(html) + def initialize(html, opts=nil) @html = html + @opts = opts || {} @fragment = Nokogiri::HTML.fragment(@html) end @@ -30,7 +31,6 @@ module Email # images @fragment.css('img').each do |img| - next if img['class'] == 'site-logo' if img['class'] == "emoji" || img['src'] =~ /plugins\/emoji/ @@ -42,7 +42,6 @@ module Email img['width'] = 'auto' img['height'] = 'auto' end - add_styles(img, 'max-width:100%;') if img['style'] !~ /max-width/ end # ensure all urls are absolute @@ -56,9 +55,16 @@ module Email end end + # add max-width to big images + big_images = @fragment.css('img[width="auto"][height="auto"]') - + @fragment.css('aside.onebox img') - + @fragment.css('img.site-logo, img.emoji') + big_images.each do |img| + add_styles(img, 'max-width: 100%;') if img['style'] !~ /max-width/ + end + # attachments @fragment.css('a.attachment').each do |a| - # ensure all urls are absolute if a['href'] =~ /^\/[^\/]/ a['href'] = "#{Discourse.base_url}#{a['href']}" @@ -83,6 +89,7 @@ module Email style('hr', 'background-color: #ddd; height: 1px; border: 1px;') style('.rtl', 'direction: rtl;') style('td.body', 'padding-top:5px;', colspan: "2") + style('.whisper td.body', 'font-style: italic; color: #9c9c9c;') correct_first_body_margin correct_footer_style reset_tables @@ -92,11 +99,15 @@ module Email def onebox_styles # Links to other topics - style('aside.quote', 'border-left: 5px solid #bebebe; background-color: #f1f1f1; padding: 12px 25px 2px 12px; margin-bottom: 10px;') - style('aside.quote blockquote', 'border: 0px; padding: 0; margin: 7px 0') + style('aside.quote', 'border-left: 5px solid #e9e9e9; background-color: #f8f8f8; padding: 12px 25px 2px 12px; margin-bottom: 10px;') + style('aside.quote blockquote', 'border: 0px; padding: 0; margin: 7px 0; background-color: clear;') + style('aside.quote blockquote > p', 'padding: 0;') style('aside.quote div.info-line', 'color: #666; margin: 10px 0') style('aside.quote .avatar', 'margin-right: 5px; width:20px; height:20px') + style('blockquote', 'border-left: 5px solid #e9e9e9; background-color: #f8f8f8; margin: 0;') + style('blockquote > p', 'padding: 1em;') + # Oneboxes style('aside.onebox', "padding: 12px 25px 2px 12px; border-left: 5px solid #bebebe; background: #eee; margin-bottom: 10px;") style('aside.onebox img', "max-height: 80%; max-width: 25%; height: auto; float: left; margin-right: 10px; margin-bottom: 10px") @@ -126,6 +137,7 @@ module Email end def format_html + style('h4', 'color: #222;') style('h3', 'margin: 15px 0 20px 0;') style('hr', 'background-color: #ddd; height: 1px; border: 1px;') style('a', 'text-decoration: none; font-weight: bold; color: #006699;') @@ -146,7 +158,7 @@ module Email # this method is reserved for styles specific to plugin def plugin_styles - @@plugin_callbacks.each { |block| block.call(@fragment) } + @@plugin_callbacks.each { |block| block.call(@fragment, @opts) } end def to_html @@ -196,11 +208,20 @@ module Email end def correct_footer_style + footernum = 0 @fragment.css('.footer').each do |element| element['style'] = "color:#666;" + linknum = 0 element.css('a').each do |inner| - inner['style'] = "color:#666;" + # we want the first footer link to be specially highlighted as IMPORTANT + if footernum == 0 and linknum == 0 + inner['style'] = "background-color: #006699; color:#ffffff; border-top: 4px solid #006699; border-right: 6px solid #006699; border-bottom: 4px solid #006699; border-left: 6px solid #006699; display: inline-block;" + else + inner['style'] = "color:#666;" + end + linknum += 1 end + footernum += 1 end end diff --git a/lib/email_cook.rb b/lib/email_cook.rb index 33693190cbb..48aea344545 100644 --- a/lib/email_cook.rb +++ b/lib/email_cook.rb @@ -1,6 +1,11 @@ # A very simple formatter for imported emails + class EmailCook + def self.url_regexp + /[^\>]*((?:https?:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.])(?:[^\s()<>]+|\([^\s()<>]+\))+(?:\([^\s()<>]+\)|[^`!()\[\]{};:'".,<>?«»\s]))/ + end + def initialize(raw) @raw = raw end @@ -20,6 +25,11 @@ class EmailCook quote_buffer = "" in_quote = false else + + l.scan(EmailCook.url_regexp).each do |m| + url = m[0] + l.gsub!(url, "#{url}") + end result << l << "
    " end end @@ -29,7 +39,6 @@ class EmailCook end result.gsub!(/(
    ){3,10}/, '

    ') - result end diff --git a/lib/email_updater.rb b/lib/email_updater.rb new file mode 100644 index 00000000000..1bda27bb27e --- /dev/null +++ b/lib/email_updater.rb @@ -0,0 +1,117 @@ +require_dependency 'email' +require_dependency 'has_errors' +require_dependency 'email_validator' + +class EmailUpdater + include HasErrors + + attr_reader :user + + def initialize(guardian=nil, user=nil) + @guardian = guardian + @user = user + end + + def self.human_attribute_name(name, options={}) + User.human_attribute_name(name, options) + end + + def authorize_both? + @user.staff? + end + + def change_to(email_input) + @guardian.ensure_can_edit_email!(@user) + + email = Email.downcase(email_input.strip) + EmailValidator.new(attributes: :email).validate_each(self, :email, email) + + if existing_user = User.find_by_email(email) + error_message = 'change_email.error' + error_message << '_staged' if existing_user.staged? + errors.add(:base, I18n.t(error_message)) + end + + if errors.blank? + args = { + old_email: @user.email, + new_email: email, + } + + if authorize_both? + args[:change_state] = EmailChangeRequest.states[:authorizing_old] + email_token = @user.email_tokens.create(email: args[:old_email]) + args[:old_email_token] = email_token + else + args[:change_state] = EmailChangeRequest.states[:authorizing_new] + email_token = @user.email_tokens.create(email: args[:new_email]) + args[:new_email_token] = email_token + end + @user.email_change_requests.create(args) + + if args[:change_state] == EmailChangeRequest.states[:authorizing_new] + send_email(:confirm_new_email, email_token) + elsif args[:change_state] == EmailChangeRequest.states[:authorizing_old] + send_email(:confirm_old_email, email_token) + end + end + end + + def confirm(token) + confirm_result = nil + change_req = nil + + User.transaction do + result = EmailToken.atomic_confirm(token) + if result[:success] + token = result[:email_token] + @user = token.user + + change_req = user.email_change_requests + .where('old_email_token_id = :token_id OR new_email_token_id = :token_id', { token_id: token.id}) + .first + + # Simple state machine + case change_req.try(:change_state) + when EmailChangeRequest.states[:authorizing_old] + new_token = user.email_tokens.create(email: change_req.new_email) + change_req.update_columns(change_state: EmailChangeRequest.states[:authorizing_new], + new_email_token_id: new_token.id) + send_email(:confirm_new_email, new_token) + confirm_result = :authorizing_new + when EmailChangeRequest.states[:authorizing_new] + change_req.update_column(:change_state, EmailChangeRequest.states[:complete]) + user.update_column(:email, token.email) + confirm_result = :complete + end + else + errors.add(:base, I18n.t('change_email.already_done')) + confirm_result = :error + end + end + + if confirm_result == :complete && change_req.old_email_token_id.blank? + notify_old(change_req.old_email, token.email) + end + + confirm_result || :error + end + + protected + + def notify_old(old_email, new_email) + Jobs.enqueue :user_email, + to_address: old_email, + type: :notify_old_email, + user_id: @user.id + end + + def send_email(type, email_token) + Jobs.enqueue :user_email, + to_address: email_token.email, + type: type, + user_id: @user.id, + email_token: email_token.token + end + +end diff --git a/lib/emoji/db.json b/lib/emoji/db.json index 536a025cfc1..a0b396bcf3b 100644 --- a/lib/emoji/db.json +++ b/lib/emoji/db.json @@ -1,8122 +1,4467 @@ -[ - { - "emoji": "😄" - , "description": "smiling face with open mouth and smiling eyes" - , "aliases": [ - "smile" - ] - , "tags": [ - "happy" - , "joy" - , "pleased" - ] - } -, { - "emoji": "😃" - , "description": "smiling face with open mouth" - , "aliases": [ - "smiley" - ] - , "tags": [ - "happy" - , "joy" - , "haha" - ] - } -, { - "emoji": "😀" - , "description": "grinning face" - , "aliases": [ - "grinning" - ] - , "tags": [ - "smile" - , "happy" - ] - } -, { - "emoji": "😊" - , "description": "smiling face with smiling eyes" - , "aliases": [ - "blush" - ] - , "tags": [ - "proud" - ] - } -, { - "emoji": "☺️" - , "description": "white smiling face" - , "aliases": [ - "relaxed" - ] - , "tags": [ - "blush" - , "pleased" - ] - } -, { - "emoji": "😉" - , "description": "winking face" - , "aliases": [ - "wink" - ] - , "tags": [ - "flirt" - ] - } -, { - "emoji": "😍" - , "description": "smiling face with heart-shaped eyes" - , "aliases": [ - "heart_eyes" - ] - , "tags": [ - "love" - , "crush" - ] - } -, { - "emoji": "😘" - , "description": "face throwing a kiss" - , "aliases": [ - "kissing_heart" - ] - , "tags": [ - "flirt" - ] - } -, { - "emoji": "😚" - , "description": "kissing face with closed eyes" - , "aliases": [ - "kissing_closed_eyes" - ] - , "tags": [ - ] - } -, { - "emoji": "😗" - , "description": "kissing face" - , "aliases": [ - "kissing" - ] - , "tags": [ - ] - } -, { - "emoji": "😙" - , "description": "kissing face with smiling eyes" - , "aliases": [ - "kissing_smiling_eyes" - ] - , "tags": [ - ] - } -, { - "emoji": "😜" - , "description": "face with stuck-out tongue and winking eye" - , "aliases": [ - "stuck_out_tongue_winking_eye" - ] - , "tags": [ - "prank" - , "silly" - ] - } -, { - "emoji": "😝" - , "description": "face with stuck-out tongue and tightly-closed eyes" - , "aliases": [ - "stuck_out_tongue_closed_eyes" - ] - , "tags": [ - "prank" - ] - } -, { - "emoji": "😛" - , "description": "face with stuck-out tongue" - , "aliases": [ - "stuck_out_tongue" - ] - , "tags": [ - ] - } -, { - "emoji": "😳" - , "description": "flushed face" - , "aliases": [ - "flushed" - ] - , "tags": [ - ] - } -, { - "emoji": "😁" - , "description": "grinning face with smiling eyes" - , "aliases": [ - "grin" - ] - , "tags": [ - ] - } -, { - "emoji": "😔" - , "description": "pensive face" - , "aliases": [ - "pensive" - ] - , "tags": [ - ] - } -, { - "emoji": "😌" - , "description": "relieved face" - , "aliases": [ - "relieved" - ] - , "tags": [ - "whew" - ] - } -, { - "emoji": "😒" - , "description": "unamused face" - , "aliases": [ - "unamused" - ] - , "tags": [ - "meh" - ] - } -, { - "emoji": "😞" - , "description": "disappointed face" - , "aliases": [ - "disappointed" - ] - , "tags": [ - "sad" - ] - } -, { - "emoji": "😣" - , "description": "persevering face" - , "aliases": [ - "persevere" - ] - , "tags": [ - "struggling" - ] - } -, { - "emoji": "😢" - , "description": "crying face" - , "aliases": [ - "cry" - ] - , "tags": [ - "sad" - , "tear" - ] - } -, { - "emoji": "😂" - , "description": "face with tears of joy" - , "aliases": [ - "joy" - ] - , "tags": [ - "tears" - ] - } -, { - "emoji": "😭" - , "description": "loudly crying face" - , "aliases": [ - "sob" - ] - , "tags": [ - "sad" - , "cry" - , "bawling" - ] - } -, { - "emoji": "😪" - , "description": "sleepy face" - , "aliases": [ - "sleepy" - ] - , "tags": [ - "tired" - ] - } -, { - "emoji": "😥" - , "description": "disappointed but relieved face" - , "aliases": [ - "disappointed_relieved" - ] - , "tags": [ - "phew" - , "sweat" - , "nervous" - ] - } -, { - "emoji": "😰" - , "description": "face with open mouth and cold sweat" - , "aliases": [ - "cold_sweat" - ] - , "tags": [ - "nervous" - ] - } -, { - "emoji": "😅" - , "description": "smiling face with open mouth and cold sweat" - , "aliases": [ - "sweat_smile" - ] - , "tags": [ - "hot" - ] - } -, { - "emoji": "😓" - , "description": "face with cold sweat" - , "aliases": [ - "sweat" - ] - , "tags": [ - ] - } -, { - "emoji": "😩" - , "description": "weary face" - , "aliases": [ - "weary" - ] - , "tags": [ - "tired" - ] - } -, { - "emoji": "😫" - , "description": "tired face" - , "aliases": [ - "tired_face" - ] - , "tags": [ - "upset" - , "whine" - ] - } -, { - "emoji": "😨" - , "description": "fearful face" - , "aliases": [ - "fearful" - ] - , "tags": [ - "scared" - , "shocked" - , "oops" - ] - } -, { - "emoji": "😱" - , "description": "face screaming in fear" - , "aliases": [ - "scream" - ] - , "tags": [ - "horror" - , "shocked" - ] - } -, { - "emoji": "😠" - , "description": "angry face" - , "aliases": [ - "angry" - ] - , "tags": [ - "mad" - , "annoyed" - ] - } -, { - "emoji": "😡" - , "description": "pouting face" - , "aliases": [ - "rage" - ] - , "tags": [ - "angry" - ] - } -, { - "emoji": "😤" - , "description": "face with look of triumph" - , "aliases": [ - "triumph" - ] - , "tags": [ - "smug" - ] - } -, { - "emoji": "😖" - , "description": "confounded face" - , "aliases": [ - "confounded" - ] - , "tags": [ - ] - } -, { - "emoji": "😆" - , "description": "smiling face with open mouth and tightly-closed eyes" - , "aliases": [ - "laughing" - , "satisfied" - ] - , "tags": [ - "happy" - , "haha" - ] - } -, { - "emoji": "😋" - , "description": "face savouring delicious food" - , "aliases": [ - "yum" - ] - , "tags": [ - "tongue" - , "lick" - ] - } -, { - "emoji": "😷" - , "description": "face with medical mask" - , "aliases": [ - "mask" - ] - , "tags": [ - "sick" - , "ill" - ] - } -, { - "emoji": "😎" - , "description": "smiling face with sunglasses" - , "aliases": [ - "sunglasses" - ] - , "tags": [ - "cool" - ] - } -, { - "emoji": "😴" - , "description": "sleeping face" - , "aliases": [ - "sleeping" - ] - , "tags": [ - "zzz" - ] - } -, { - "emoji": "😵" - , "description": "dizzy face" - , "aliases": [ - "dizzy_face" - ] - , "tags": [ - ] - } -, { - "emoji": "😲" - , "description": "astonished face" - , "aliases": [ - "astonished" - ] - , "tags": [ - "amazed" - , "gasp" - ] - } -, { - "emoji": "😟" - , "description": "worried face" - , "aliases": [ - "worried" - ] - , "tags": [ - "nervous" - ] - } -, { - "emoji": "😦" - , "description": "frowning face with open mouth" - , "aliases": [ - "frowning" - ] - , "tags": [ - ] - } -, { - "emoji": "😧" - , "description": "anguished face" - , "aliases": [ - "anguished" - ] - , "tags": [ - "stunned" - ] - } -, { - "emoji": "😈" - , "description": "smiling face with horns" - , "aliases": [ - "smiling_imp" - ] - , "tags": [ - "devil" - , "evil" - , "horns" - ] - } -, { - "emoji": "👿" - , "description": "imp" - , "aliases": [ - "imp" - ] - , "tags": [ - "angry" - , "devil" - , "evil" - , "horns" - ] - } -, { - "emoji": "😮" - , "description": "face with open mouth" - , "aliases": [ - "open_mouth" - ] - , "tags": [ - "surprise" - , "impressed" - , "wow" - ] - } -, { - "emoji": "😬" - , "description": "grimacing face" - , "aliases": [ - "grimacing" - ] - , "tags": [ - ] - } -, { - "emoji": "😐" - , "description": "neutral face" - , "aliases": [ - "neutral_face" - ] - , "tags": [ - "meh" - ] - } -, { - "emoji": "😕" - , "description": "confused face" - , "aliases": [ - "confused" - ] - , "tags": [ - ] - } -, { - "emoji": "😯" - , "description": "hushed face" - , "aliases": [ - "hushed" - ] - , "tags": [ - "silence" - , "speechless" - ] - } -, { - "emoji": "😶" - , "description": "face without mouth" - , "aliases": [ - "no_mouth" - ] - , "tags": [ - "mute" - , "silence" - ] - } -, { - "emoji": "😇" - , "description": "smiling face with halo" - , "aliases": [ - "innocent" - ] - , "tags": [ - "angel" - ] - } -, { - "emoji": "😏" - , "description": "smirking face" - , "aliases": [ - "smirk" - ] - , "tags": [ - "smug" - ] - } -, { - "emoji": "😑" - , "description": "expressionless face" - , "aliases": [ - "expressionless" - ] - , "tags": [ - ] - } -, { - "emoji": "👲" - , "description": "man with gua pi mao" - , "aliases": [ - "man_with_gua_pi_mao" - ] - , "tags": [ - ] - } -, { - "emoji": "👳" - , "description": "man with turban" - , "aliases": [ - "man_with_turban" - ] - , "tags": [ - ] - } -, { - "emoji": "👮" - , "description": "police officer" - , "aliases": [ - "cop" - ] - , "tags": [ - "police" - , "law" - ] - } -, { - "emoji": "👷" - , "description": "construction worker" - , "aliases": [ - "construction_worker" - ] - , "tags": [ - "helmet" - ] - } -, { - "emoji": "💂" - , "description": "guardsman" - , "aliases": [ - "guardsman" - ] - , "tags": [ - ] - } -, { - "emoji": "👶" - , "description": "baby" - , "aliases": [ - "baby" - ] - , "tags": [ - "child" - , "newborn" - ] - } -, { - "emoji": "👦" - , "description": "boy" - , "aliases": [ - "boy" - ] - , "tags": [ - "child" - ] - } -, { - "emoji": "👧" - , "description": "girl" - , "aliases": [ - "girl" - ] - , "tags": [ - "child" - ] - } -, { - "emoji": "👨" - , "description": "man" - , "aliases": [ - "man" - ] - , "tags": [ - "mustache" - , "father" - , "dad" - ] - } -, { - "emoji": "👩" - , "description": "woman" - , "aliases": [ - "woman" - ] - , "tags": [ - "girls" - ] - } -, { - "emoji": "👴" - , "description": "older man" - , "aliases": [ - "older_man" - ] - , "tags": [ - ] - } -, { - "emoji": "👵" - , "description": "older woman" - , "aliases": [ - "older_woman" - ] - , "tags": [ - ] - } -, { - "emoji": "👱" - , "description": "person with blond hair" - , "aliases": [ - "person_with_blond_hair" - ] - , "tags": [ - "boy" - ] - } -, { - "emoji": "👼" - , "description": "baby angel" - , "aliases": [ - "angel" - ] - , "tags": [ - ] - } -, { - "emoji": "👸" - , "description": "princess" - , "aliases": [ - "princess" - ] - , "tags": [ - "blonde" - , "crown" - , "royal" - ] - } -, { - "emoji": "😺" - , "description": "smiling cat face with open mouth" - , "aliases": [ - "smiley_cat" - ] - , "tags": [ - ] - } -, { - "emoji": "😸" - , "description": "grinning cat face with smiling eyes" - , "aliases": [ - "smile_cat" - ] - , "tags": [ - ] - } -, { - "emoji": "😻" - , "description": "smiling cat face with heart-shaped eyes" - , "aliases": [ - "heart_eyes_cat" - ] - , "tags": [ - ] - } -, { - "emoji": "😽" - , "description": "kissing cat face with closed eyes" - , "aliases": [ - "kissing_cat" - ] - , "tags": [ - ] - } -, { - "emoji": "😼" - , "description": "cat face with wry smile" - , "aliases": [ - "smirk_cat" - ] - , "tags": [ - ] - } -, { - "emoji": "🙀" - , "description": "weary cat face" - , "aliases": [ - "scream_cat" - ] - , "tags": [ - "horror" - ] - } -, { - "emoji": "😿" - , "description": "crying cat face" - , "aliases": [ - "crying_cat_face" - ] - , "tags": [ - "sad" - , "tear" - ] - } -, { - "emoji": "😹" - , "description": "cat face with tears of joy" - , "aliases": [ - "joy_cat" - ] - , "tags": [ - ] - } -, { - "emoji": "😾" - , "description": "pouting cat face" - , "aliases": [ - "pouting_cat" - ] - , "tags": [ - ] - } -, { - "emoji": "👹" - , "description": "japanese ogre" - , "aliases": [ - "japanese_ogre" - ] - , "tags": [ - "monster" - ] - } -, { - "emoji": "👺" - , "description": "japanese goblin" - , "aliases": [ - "japanese_goblin" - ] - , "tags": [ - ] - } -, { - "emoji": "🙈" - , "description": "see-no-evil monkey" - , "aliases": [ - "see_no_evil" - ] - , "tags": [ - "monkey" - , "blind" - , "ignore" - ] - } -, { - "emoji": "🙉" - , "description": "hear-no-evil monkey" - , "aliases": [ - "hear_no_evil" - ] - , "tags": [ - "monkey" - , "deaf" - ] - } -, { - "emoji": "🙊" - , "description": "speak-no-evil monkey" - , "aliases": [ - "speak_no_evil" - ] - , "tags": [ - "monkey" - , "mute" - , "hush" - ] - } -, { - "emoji": "💀" - , "description": "skull" - , "aliases": [ - "skull" - ] - , "tags": [ - "dead" - , "danger" - , "poison" - ] - } -, { - "emoji": "👽" - , "description": "extraterrestrial alien" - , "aliases": [ - "alien" - ] - , "tags": [ - "ufo" - ] - } -, { - "emoji": "💩" - , "description": "pile of poo" - , "aliases": [ - "hankey" - , "poop" - , "shit" - ] - , "tags": [ - "crap" - ] - } -, { - "emoji": "🔥" - , "description": "fire" - , "aliases": [ - "fire" - ] - , "tags": [ - "burn" - ] - } -, { - "emoji": "✨" - , "description": "sparkles" - , "aliases": [ - "sparkles" - ] - , "tags": [ - "shiny" - ] - } -, { - "emoji": "🌟" - , "description": "glowing star" - , "aliases": [ - "star2" - ] - , "tags": [ - ] - } -, { - "emoji": "💫" - , "description": "dizzy symbol" - , "aliases": [ - "dizzy" - ] - , "tags": [ - "star" - ] - } -, { - "emoji": "💥" - , "description": "collision symbol" - , "aliases": [ - "boom" - , "collision" - ] - , "tags": [ - "explode" - ] - } -, { - "emoji": "💢" - , "description": "anger symbol" - , "aliases": [ - "anger" - ] - , "tags": [ - "angry" - ] - } -, { - "emoji": "💦" - , "description": "splashing sweat symbol" - , "aliases": [ - "sweat_drops" - ] - , "tags": [ - "water" - , "workout" - ] - } -, { - "emoji": "💧" - , "description": "droplet" - , "aliases": [ - "droplet" - ] - , "tags": [ - "water" - ] - } -, { - "emoji": "💤" - , "description": "sleeping symbol" - , "aliases": [ - "zzz" - ] - , "tags": [ - "sleeping" - ] - } -, { - "emoji": "💨" - , "description": "dash symbol" - , "aliases": [ - "dash" - ] - , "tags": [ - "wind" - , "blow" - , "fast" - ] - } -, { - "emoji": "👂" - , "description": "ear" - , "aliases": [ - "ear" - ] - , "tags": [ - "hear" - , "sound" - , "listen" - ] - } -, { - "emoji": "👀" - , "description": "eyes" - , "aliases": [ - "eyes" - ] - , "tags": [ - "look" - , "see" - , "watch" - ] - } -, { - "emoji": "👃" - , "description": "nose" - , "aliases": [ - "nose" - ] - , "tags": [ - "smell" - ] - } -, { - "emoji": "👅" - , "description": "tongue" - , "aliases": [ - "tongue" - ] - , "tags": [ - "taste" - ] - } -, { - "emoji": "👄" - , "description": "mouth" - , "aliases": [ - "lips" - ] - , "tags": [ - "kiss" - ] - } -, { - "emoji": "👍" - , "description": "thumbs up sign" - , "aliases": [ - "+1" - , "thumbsup" - ] - , "tags": [ - "approve" - , "ok" - ] - } -, { - "emoji": "👎" - , "description": "thumbs down sign" - , "aliases": [ - "-1" - , "thumbsdown" - ] - , "tags": [ - "disapprove" - , "bury" - ] - } -, { - "emoji": "👌" - , "description": "ok hand sign" - , "aliases": [ - "ok_hand" - ] - , "tags": [ - ] - } -, { - "emoji": "👊" - , "description": "fisted hand sign" - , "aliases": [ - "facepunch" - , "punch" - ] - , "tags": [ - "attack" - ] - } -, { - "emoji": "✊" - , "description": "raised fist" - , "aliases": [ - "fist" - ] - , "tags": [ - "power" - ] - } -, { - "emoji": "✌️" - , "description": "victory hand" - , "aliases": [ - "v" - ] - , "tags": [ - "victory" - , "peace" - ] - } -, { - "emoji": "👋" - , "description": "waving hand sign" - , "aliases": [ - "wave" - ] - , "tags": [ - "goodbye" - ] - } -, { - "emoji": "✋" - , "description": "raised hand" - , "aliases": [ - "hand" - , "raised_hand" - ] - , "tags": [ - "highfive" - , "stop" - ] - } -, { - "emoji": "👐" - , "description": "open hands sign" - , "aliases": [ - "open_hands" - ] - , "tags": [ - ] - } -, { - "emoji": "👆" - , "description": "white up pointing backhand index" - , "aliases": [ - "point_up_2" - ] - , "tags": [ - ] - } -, { - "emoji": "👇" - , "description": "white down pointing backhand index" - , "aliases": [ - "point_down" - ] - , "tags": [ - ] - } -, { - "emoji": "👉" - , "description": "white right pointing backhand index" - , "aliases": [ - "point_right" - ] - , "tags": [ - ] - } -, { - "emoji": "👈" - , "description": "white left pointing backhand index" - , "aliases": [ - "point_left" - ] - , "tags": [ - ] - } -, { - "emoji": "🙌" - , "description": "person raising both hands in celebration" - , "aliases": [ - "raised_hands" - ] - , "tags": [ - "hooray" - ] - } -, { - "emoji": "🙏" - , "description": "person with folded hands" - , "aliases": [ - "pray" - ] - , "tags": [ - "please" - , "hope" - , "wish" - ] - } -, { - "emoji": "☝️" - , "description": "white up pointing index" - , "aliases": [ - "point_up" - ] - , "tags": [ - ] - } -, { - "emoji": "👏" - , "description": "clapping hands sign" - , "aliases": [ - "clap" - ] - , "tags": [ - "praise" - , "applause" - ] - } -, { - "emoji": "💪" - , "description": "flexed biceps" - , "aliases": [ - "muscle" - ] - , "tags": [ - "flex" - , "bicep" - , "strong" - , "workout" - ] - } -, { - "emoji": "🚶" - , "description": "pedestrian" - , "aliases": [ - "walking" - ] - , "tags": [ - ] - } -, { - "emoji": "🏃" - , "description": "runner" - , "aliases": [ - "runner" - , "running" - ] - , "tags": [ - "exercise" - , "workout" - , "marathon" - ] - } -, { - "emoji": "💃" - , "description": "dancer" - , "aliases": [ - "dancer" - ] - , "tags": [ - "dress" - ] - } -, { - "emoji": "👫" - , "description": "man and woman holding hands" - , "aliases": [ - "couple" - ] - , "tags": [ - "date" - ] - } -, { - "emoji": "👪" - , "description": "family" - , "aliases": [ - "family" - ] - , "tags": [ - "home" - , "parents" - , "child" - ] - } -, { - "emoji": "👬" - , "description": "two men holding hands" - , "aliases": [ - "two_men_holding_hands" - ] - , "tags": [ - "couple" - , "date" - ] - } -, { - "emoji": "👭" - , "description": "two women holding hands" - , "aliases": [ - "two_women_holding_hands" - ] - , "tags": [ - "couple" - , "date" - ] - } -, { - "emoji": "💏" - , "description": "kiss" - , "aliases": [ - "couplekiss" - ] - , "tags": [ - ] - } -, { - "emoji": "💑" - , "description": "couple with heart" - , "aliases": [ - "couple_with_heart" - ] - , "tags": [ - ] - } -, { - "emoji": "👯" - , "description": "woman with bunny ears" - , "aliases": [ - "dancers" - ] - , "tags": [ - "bunny" - ] - } -, { - "emoji": "🙆" - , "description": "face with ok gesture" - , "aliases": [ - "ok_woman" - ] - , "tags": [ - ] - } -, { - "emoji": "🙅" - , "description": "face with no good gesture" - , "aliases": [ - "no_good" - ] - , "tags": [ - "stop" - , "halt" - ] - } -, { - "emoji": "💁" - , "description": "information desk person" - , "aliases": [ - "information_desk_person" - ] - , "tags": [ - ] - } -, { - "emoji": "🙋" - , "description": "happy person raising one hand" - , "aliases": [ - "raising_hand" - ] - , "tags": [ - ] - } -, { - "emoji": "💆" - , "description": "face massage" - , "aliases": [ - "massage" - ] - , "tags": [ - "spa" - ] - } -, { - "emoji": "💇" - , "description": "haircut" - , "aliases": [ - "haircut" - ] - , "tags": [ - "beauty" - ] - } -, { - "emoji": "💅" - , "description": "nail polish" - , "aliases": [ - "nail_care" - ] - , "tags": [ - "beauty" - , "manicure" - ] - } -, { - "emoji": "👰" - , "description": "bride with veil" - , "aliases": [ - "bride_with_veil" - ] - , "tags": [ - "marriage" - , "wedding" - ] - } -, { - "emoji": "🙎" - , "description": "person with pouting face" - , "aliases": [ - "person_with_pouting_face" - ] - , "tags": [ - ] - } -, { - "emoji": "🙍" - , "description": "person frowning" - , "aliases": [ - "person_frowning" - ] - , "tags": [ - "sad" - ] - } -, { - "emoji": "🙇" - , "description": "person bowing deeply" - , "aliases": [ - "bow" - ] - , "tags": [ - "respect" - , "thanks" - ] - } -, { - "emoji": "🎩" - , "description": "top hat" - , "aliases": [ - "tophat" - ] - , "tags": [ - "hat" - , "classy" - ] - } -, { - "emoji": "👑" - , "description": "crown" - , "aliases": [ - "crown" - ] - , "tags": [ - "king" - , "queen" - , "royal" - ] - } -, { - "emoji": "👒" - , "description": "womans hat" - , "aliases": [ - "womans_hat" - ] - , "tags": [ - ] - } -, { - "emoji": "👟" - , "description": "athletic shoe" - , "aliases": [ - "athletic_shoe" - ] - , "tags": [ - "sneaker" - , "sport" - , "running" - ] - } -, { - "emoji": "👞" - , "description": "mans shoe" - , "aliases": [ - "mans_shoe" - , "shoe" - ] - , "tags": [ - ] - } -, { - "emoji": "👡" - , "description": "womans sandal" - , "aliases": [ - "sandal" - ] - , "tags": [ - "shoe" - ] - } -, { - "emoji": "👠" - , "description": "high-heeled shoe" - , "aliases": [ - "high_heel" - ] - , "tags": [ - "shoe" - ] - } -, { - "emoji": "👢" - , "description": "womans boots" - , "aliases": [ - "boot" - ] - , "tags": [ - ] - } -, { - "emoji": "👕" - , "description": "t-shirt" - , "aliases": [ - "shirt" - , "tshirt" - ] - , "tags": [ - ] - } -, { - "emoji": "👔" - , "description": "necktie" - , "aliases": [ - "necktie" - ] - , "tags": [ - "shirt" - , "formal" - ] - } -, { - "emoji": "👚" - , "description": "womans clothes" - , "aliases": [ - "womans_clothes" - ] - , "tags": [ - ] - } -, { - "emoji": "👗" - , "description": "dress" - , "aliases": [ - "dress" - ] - , "tags": [ - ] - } -, { - "emoji": "🎽" - , "description": "running shirt with sash" - , "aliases": [ - "running_shirt_with_sash" - ] - , "tags": [ - "marathon" - ] - } -, { - "emoji": "👖" - , "description": "jeans" - , "aliases": [ - "jeans" - ] - , "tags": [ - "pants" - ] - } -, { - "emoji": "👘" - , "description": "kimono" - , "aliases": [ - "kimono" - ] - , "tags": [ - ] - } -, { - "emoji": "👙" - , "description": "bikini" - , "aliases": [ - "bikini" - ] - , "tags": [ - "beach" - ] - } -, { - "emoji": "💼" - , "description": "briefcase" - , "aliases": [ - "briefcase" - ] - , "tags": [ - "business" - ] - } -, { - "emoji": "👜" - , "description": "handbag" - , "aliases": [ - "handbag" - ] - , "tags": [ - "bag" - ] - } -, { - "emoji": "👝" - , "description": "pouch" - , "aliases": [ - "pouch" - ] - , "tags": [ - "bag" - ] - } -, { - "emoji": "👛" - , "description": "purse" - , "aliases": [ - "purse" - ] - , "tags": [ - ] - } -, { - "emoji": "👓" - , "description": "eyeglasses" - , "aliases": [ - "eyeglasses" - ] - , "tags": [ - "glasses" - ] - } -, { - "emoji": "🎀" - , "description": "ribbon" - , "aliases": [ - "ribbon" - ] - , "tags": [ - ] - } -, { - "emoji": "🌂" - , "description": "closed umbrella" - , "aliases": [ - "closed_umbrella" - ] - , "tags": [ - "weather" - , "rain" - ] - } -, { - "emoji": "💄" - , "description": "lipstick" - , "aliases": [ - "lipstick" - ] - , "tags": [ - "makeup" - ] - } -, { - "emoji": "💛" - , "description": "yellow heart" - , "aliases": [ - "yellow_heart" - ] - , "tags": [ - ] - } -, { - "emoji": "💙" - , "description": "blue heart" - , "aliases": [ - "blue_heart" - ] - , "tags": [ - ] - } -, { - "emoji": "💜" - , "description": "purple heart" - , "aliases": [ - "purple_heart" - ] - , "tags": [ - ] - } -, { - "emoji": "💚" - , "description": "green heart" - , "aliases": [ - "green_heart" - ] - , "tags": [ - ] - } -, { - "emoji": "❤️" - , "description": "heavy black heart" - , "aliases": [ - "heart" - ] - , "tags": [ - "love" - ] - } -, { - "emoji": "💔" - , "description": "broken heart" - , "aliases": [ - "broken_heart" - ] - , "tags": [ - ] - } -, { - "emoji": "💗" - , "description": "growing heart" - , "aliases": [ - "heartpulse" - ] - , "tags": [ - ] - } -, { - "emoji": "💓" - , "description": "beating heart" - , "aliases": [ - "heartbeat" - ] - , "tags": [ - ] - } -, { - "emoji": "💕" - , "description": "two hearts" - , "aliases": [ - "two_hearts" - ] - , "tags": [ - ] - } -, { - "emoji": "💖" - , "description": "sparkling heart" - , "aliases": [ - "sparkling_heart" - ] - , "tags": [ - ] - } -, { - "emoji": "💞" - , "description": "revolving hearts" - , "aliases": [ - "revolving_hearts" - ] - , "tags": [ - ] - } -, { - "emoji": "💘" - , "description": "heart with arrow" - , "aliases": [ - "cupid" - ] - , "tags": [ - "love" - , "heart" - ] - } -, { - "emoji": "💌" - , "description": "love letter" - , "aliases": [ - "love_letter" - ] - , "tags": [ - "email" - , "envelope" - ] - } -, { - "emoji": "💋" - , "description": "kiss mark" - , "aliases": [ - "kiss" - ] - , "tags": [ - "lipstick" - ] - } -, { - "emoji": "💍" - , "description": "ring" - , "aliases": [ - "ring" - ] - , "tags": [ - "wedding" - , "marriage" - , "engaged" - ] - } -, { - "emoji": "💎" - , "description": "gem stone" - , "aliases": [ - "gem" - ] - , "tags": [ - "diamond" - ] - } -, { - "emoji": "👤" - , "description": "bust in silhouette" - , "aliases": [ - "bust_in_silhouette" - ] - , "tags": [ - "user" - ] - } -, { - "emoji": "👥" - , "description": "busts in silhouette" - , "aliases": [ - "busts_in_silhouette" - ] - , "tags": [ - "users" - , "group" - , "team" - ] - } -, { - "emoji": "💬" - , "description": "speech balloon" - , "aliases": [ - "speech_balloon" - ] - , "tags": [ - "comment" - ] - } -, { - "emoji": "👣" - , "description": "footprints" - , "aliases": [ - "footprints" - ] - , "tags": [ - "feet" - , "tracks" - ] - } -, { - "emoji": "💭" - , "description": "thought balloon" - , "aliases": [ - "thought_balloon" - ] - , "tags": [ - "thinking" - ] - } -, { - "emoji": "🐶" - , "description": "dog face" - , "aliases": [ - "dog" - ] - , "tags": [ - "pet" - ] - } -, { - "emoji": "🐺" - , "description": "wolf face" - , "aliases": [ - "wolf" - ] - , "tags": [ - ] - } -, { - "emoji": "🐱" - , "description": "cat face" - , "aliases": [ - "cat" - ] - , "tags": [ - "pet" - ] - } -, { - "emoji": "🐭" - , "description": "mouse face" - , "aliases": [ - "mouse" - ] - , "tags": [ - ] - } -, { - "emoji": "🐹" - , "description": "hamster face" - , "aliases": [ - "hamster" - ] - , "tags": [ - "pet" - ] - } -, { - "emoji": "🐰" - , "description": "rabbit face" - , "aliases": [ - "rabbit" - ] - , "tags": [ - "bunny" - ] - } -, { - "emoji": "🐸" - , "description": "frog face" - , "aliases": [ - "frog" - ] - , "tags": [ - ] - } -, { - "emoji": "🐯" - , "description": "tiger face" - , "aliases": [ - "tiger" - ] - , "tags": [ - ] - } -, { - "emoji": "🐨" - , "description": "koala" - , "aliases": [ - "koala" - ] - , "tags": [ - ] - } -, { - "emoji": "🐻" - , "description": "bear face" - , "aliases": [ - "bear" - ] - , "tags": [ - ] - } -, { - "emoji": "🐷" - , "description": "pig face" - , "aliases": [ - "pig" - ] - , "tags": [ - ] - } -, { - "emoji": "🐽" - , "description": "pig nose" - , "aliases": [ - "pig_nose" - ] - , "tags": [ - ] - } -, { - "emoji": "🐮" - , "description": "cow face" - , "aliases": [ - "cow" - ] - , "tags": [ - ] - } -, { - "emoji": "🐗" - , "description": "boar" - , "aliases": [ - "boar" - ] - , "tags": [ - ] - } -, { - "emoji": "🐵" - , "description": "monkey face" - , "aliases": [ - "monkey_face" - ] - , "tags": [ - ] - } -, { - "emoji": "🐒" - , "description": "monkey" - , "aliases": [ - "monkey" - ] - , "tags": [ - ] - } -, { - "emoji": "🐴" - , "description": "horse face" - , "aliases": [ - "horse" - ] - , "tags": [ - ] - } -, { - "emoji": "🐑" - , "description": "sheep" - , "aliases": [ - "sheep" - ] - , "tags": [ - ] - } -, { - "emoji": "🐘" - , "description": "elephant" - , "aliases": [ - "elephant" - ] - , "tags": [ - ] - } -, { - "emoji": "🐼" - , "description": "panda face" - , "aliases": [ - "panda_face" - ] - , "tags": [ - ] - } -, { - "emoji": "🐧" - , "description": "penguin" - , "aliases": [ - "penguin" - ] - , "tags": [ - ] - } -, { - "emoji": "🐦" - , "description": "bird" - , "aliases": [ - "bird" - ] - , "tags": [ - ] - } -, { - "emoji": "🐤" - , "description": "baby chick" - , "aliases": [ - "baby_chick" - ] - , "tags": [ - ] - } -, { - "emoji": "🐥" - , "description": "front-facing baby chick" - , "aliases": [ - "hatched_chick" - ] - , "tags": [ - ] - } -, { - "emoji": "🐣" - , "description": "hatching chick" - , "aliases": [ - "hatching_chick" - ] - , "tags": [ - ] - } -, { - "emoji": "🐔" - , "description": "chicken" - , "aliases": [ - "chicken" - ] - , "tags": [ - ] - } -, { - "emoji": "🐍" - , "description": "snake" - , "aliases": [ - "snake" - ] - , "tags": [ - ] - } -, { - "emoji": "🐢" - , "description": "turtle" - , "aliases": [ - "turtle" - ] - , "tags": [ - "slow" - ] - } -, { - "emoji": "🐛" - , "description": "bug" - , "aliases": [ - "bug" - ] - , "tags": [ - ] - } -, { - "emoji": "🐝" - , "description": "honeybee" - , "aliases": [ - "bee" - , "honeybee" - ] - , "tags": [ - ] - } -, { - "emoji": "🐜" - , "description": "ant" - , "aliases": [ - "ant" - ] - , "tags": [ - ] - } -, { - "emoji": "🐞" - , "description": "lady beetle" - , "aliases": [ - "beetle" - ] - , "tags": [ - "bug" - ] - } -, { - "emoji": "🐌" - , "description": "snail" - , "aliases": [ - "snail" - ] - , "tags": [ - "slow" - ] - } -, { - "emoji": "🐙" - , "description": "octopus" - , "aliases": [ - "octopus" - ] - , "tags": [ - ] - } -, { - "emoji": "🐚" - , "description": "spiral shell" - , "aliases": [ - "shell" - ] - , "tags": [ - "sea" - , "beach" - ] - } -, { - "emoji": "🐠" - , "description": "tropical fish" - , "aliases": [ - "tropical_fish" - ] - , "tags": [ - ] - } -, { - "emoji": "🐟" - , "description": "fish" - , "aliases": [ - "fish" - ] - , "tags": [ - ] - } -, { - "emoji": "🐬" - , "description": "dolphin" - , "aliases": [ - "dolphin" - , "flipper" - ] - , "tags": [ - ] - } -, { - "emoji": "🐳" - , "description": "spouting whale" - , "aliases": [ - "whale" - ] - , "tags": [ - "sea" - ] - } -, { - "emoji": "🐋" - , "description": "whale" - , "aliases": [ - "whale2" - ] - , "tags": [ - ] - } -, { - "emoji": "🐄" - , "description": "cow" - , "aliases": [ - "cow2" - ] - , "tags": [ - ] - } -, { - "emoji": "🐏" - , "description": "ram" - , "aliases": [ - "ram" - ] - , "tags": [ - ] - } -, { - "emoji": "🐀" - , "description": "rat" - , "aliases": [ - "rat" - ] - , "tags": [ - ] - } -, { - "emoji": "🐃" - , "description": "water buffalo" - , "aliases": [ - "water_buffalo" - ] - , "tags": [ - ] - } -, { - "emoji": "🐅" - , "description": "tiger" - , "aliases": [ - "tiger2" - ] - , "tags": [ - ] - } -, { - "emoji": "🐇" - , "description": "rabbit" - , "aliases": [ - "rabbit2" - ] - , "tags": [ - ] - } -, { - "emoji": "🐉" - , "description": "dragon" - , "aliases": [ - "dragon" - ] - , "tags": [ - ] - } -, { - "emoji": "🐎" - , "description": "horse" - , "aliases": [ - "racehorse" - ] - , "tags": [ - "speed" - ] - } -, { - "emoji": "🐐" - , "description": "goat" - , "aliases": [ - "goat" - ] - , "tags": [ - ] - } -, { - "emoji": "🐓" - , "description": "rooster" - , "aliases": [ - "rooster" - ] - , "tags": [ - ] - } -, { - "emoji": "🐕" - , "description": "dog" - , "aliases": [ - "dog2" - ] - , "tags": [ - ] - } -, { - "emoji": "🐖" - , "description": "pig" - , "aliases": [ - "pig2" - ] - , "tags": [ - ] - } -, { - "emoji": "🐁" - , "description": "mouse" - , "aliases": [ - "mouse2" - ] - , "tags": [ - ] - } -, { - "emoji": "🐂" - , "description": "ox" - , "aliases": [ - "ox" - ] - , "tags": [ - ] - } -, { - "emoji": "🐲" - , "description": "dragon face" - , "aliases": [ - "dragon_face" - ] - , "tags": [ - ] - } -, { - "emoji": "🐡" - , "description": "blowfish" - , "aliases": [ - "blowfish" - ] - , "tags": [ - ] - } -, { - "emoji": "🐊" - , "description": "crocodile" - , "aliases": [ - "crocodile" - ] - , "tags": [ - ] - } -, { - "emoji": "🐫" - , "description": "bactrian camel" - , "aliases": [ - "camel" - ] - , "tags": [ - ] - } -, { - "emoji": "🐪" - , "description": "dromedary camel" - , "aliases": [ - "dromedary_camel" - ] - , "tags": [ - "desert" - ] - } -, { - "emoji": "🐆" - , "description": "leopard" - , "aliases": [ - "leopard" - ] - , "tags": [ - ] - } -, { - "emoji": "🐈" - , "description": "cat" - , "aliases": [ - "cat2" - ] - , "tags": [ - ] - } -, { - "emoji": "🐩" - , "description": "poodle" - , "aliases": [ - "poodle" - ] - , "tags": [ - "dog" - ] - } -, { - "emoji": "🐾" - , "description": "paw prints" - , "aliases": [ - "feet" - , "paw_prints" - ] - , "tags": [ - ] - } -, { - "emoji": "💐" - , "description": "bouquet" - , "aliases": [ - "bouquet" - ] - , "tags": [ - "flowers" - ] - } -, { - "emoji": "🌸" - , "description": "cherry blossom" - , "aliases": [ - "cherry_blossom" - ] - , "tags": [ - "flower" - , "spring" - ] - } -, { - "emoji": "🌷" - , "description": "tulip" - , "aliases": [ - "tulip" - ] - , "tags": [ - "flower" - ] - } -, { - "emoji": "🍀" - , "description": "four leaf clover" - , "aliases": [ - "four_leaf_clover" - ] - , "tags": [ - "luck" - ] - } -, { - "emoji": "🌹" - , "description": "rose" - , "aliases": [ - "rose" - ] - , "tags": [ - "flower" - ] - } -, { - "emoji": "🌻" - , "description": "sunflower" - , "aliases": [ - "sunflower" - ] - , "tags": [ - ] - } -, { - "emoji": "🌺" - , "description": "hibiscus" - , "aliases": [ - "hibiscus" - ] - , "tags": [ - ] - } -, { - "emoji": "🍁" - , "description": "maple leaf" - , "aliases": [ - "maple_leaf" - ] - , "tags": [ - "canada" - ] - } -, { - "emoji": "🍃" - , "description": "leaf fluttering in wind" - , "aliases": [ - "leaves" - ] - , "tags": [ - "leaf" - ] - } -, { - "emoji": "🍂" - , "description": "fallen leaf" - , "aliases": [ - "fallen_leaf" - ] - , "tags": [ - "autumn" - ] - } -, { - "emoji": "🌿" - , "description": "herb" - , "aliases": [ - "herb" - ] - , "tags": [ - ] - } -, { - "emoji": "🌾" - , "description": "ear of rice" - , "aliases": [ - "ear_of_rice" - ] - , "tags": [ - ] - } -, { - "emoji": "🍄" - , "description": "mushroom" - , "aliases": [ - "mushroom" - ] - , "tags": [ - ] - } -, { - "emoji": "🌵" - , "description": "cactus" - , "aliases": [ - "cactus" - ] - , "tags": [ - ] - } -, { - "emoji": "🌴" - , "description": "palm tree" - , "aliases": [ - "palm_tree" - ] - , "tags": [ - ] - } -, { - "emoji": "🌲" - , "description": "evergreen tree" - , "aliases": [ - "evergreen_tree" - ] - , "tags": [ - "wood" - ] - } -, { - "emoji": "🌳" - , "description": "deciduous tree" - , "aliases": [ - "deciduous_tree" - ] - , "tags": [ - "wood" - ] - } -, { - "emoji": "🌰" - , "description": "chestnut" - , "aliases": [ - "chestnut" - ] - , "tags": [ - ] - } -, { - "emoji": "🌱" - , "description": "seedling" - , "aliases": [ - "seedling" - ] - , "tags": [ - "plant" - ] - } -, { - "emoji": "🌼" - , "description": "blossom" - , "aliases": [ - "blossom" - ] - , "tags": [ - ] - } -, { - "emoji": "🌐" - , "description": "globe with meridians" - , "aliases": [ - "globe_with_meridians" - ] - , "tags": [ - "world" - , "global" - , "international" - ] - } -, { - "emoji": "🌞" - , "description": "sun with face" - , "aliases": [ - "sun_with_face" - ] - , "tags": [ - "summer" - ] - } -, { - "emoji": "🌝" - , "description": "full moon with face" - , "aliases": [ - "full_moon_with_face" - ] - , "tags": [ - ] - } -, { - "emoji": "🌚" - , "description": "new moon with face" - , "aliases": [ - "new_moon_with_face" - ] - , "tags": [ - ] - } -, { - "emoji": "🌑" - , "description": "new moon symbol" - , "aliases": [ - "new_moon" - ] - , "tags": [ - ] - } -, { - "emoji": "🌒" - , "description": "waxing crescent moon symbol" - , "aliases": [ - "waxing_crescent_moon" - ] - , "tags": [ - ] - } -, { - "emoji": "🌓" - , "description": "first quarter moon symbol" - , "aliases": [ - "first_quarter_moon" - ] - , "tags": [ - ] - } -, { - "emoji": "🌔" - , "description": "waxing gibbous moon symbol" - , "aliases": [ - "moon" - , "waxing_gibbous_moon" - ] - , "tags": [ - ] - } -, { - "emoji": "🌕" - , "description": "full moon symbol" - , "aliases": [ - "full_moon" - ] - , "tags": [ - ] - } -, { - "emoji": "🌖" - , "description": "waning gibbous moon symbol" - , "aliases": [ - "waning_gibbous_moon" - ] - , "tags": [ - ] - } -, { - "emoji": "🌗" - , "description": "last quarter moon symbol" - , "aliases": [ - "last_quarter_moon" - ] - , "tags": [ - ] - } -, { - "emoji": "🌘" - , "description": "waning crescent moon symbol" - , "aliases": [ - "waning_crescent_moon" - ] - , "tags": [ - ] - } -, { - "emoji": "🌜" - , "description": "last quarter moon with face" - , "aliases": [ - "last_quarter_moon_with_face" - ] - , "tags": [ - ] - } -, { - "emoji": "🌛" - , "description": "first quarter moon with face" - , "aliases": [ - "first_quarter_moon_with_face" - ] - , "tags": [ - ] - } -, { - "emoji": "🌙" - , "description": "crescent moon" - , "aliases": [ - "crescent_moon" - ] - , "tags": [ - "night" - ] - } -, { - "emoji": "🌍" - , "description": "earth globe europe-africa" - , "aliases": [ - "earth_africa" - ] - , "tags": [ - "globe" - , "world" - , "international" - ] - } -, { - "emoji": "🌎" - , "description": "earth globe americas" - , "aliases": [ - "earth_americas" - ] - , "tags": [ - "globe" - , "world" - , "international" - ] - } -, { - "emoji": "🌏" - , "description": "earth globe asia-australia" - , "aliases": [ - "earth_asia" - ] - , "tags": [ - "globe" - , "world" - , "international" - ] - } -, { - "emoji": "🌋" - , "description": "volcano" - , "aliases": [ - "volcano" - ] - , "tags": [ - ] - } -, { - "emoji": "🌌" - , "description": "milky way" - , "aliases": [ - "milky_way" - ] - , "tags": [ - ] - } -, { - "emoji": "🌠" - , "description": "shooting star" - , "aliases": [ - "stars" - ] - , "tags": [ - ] - } -, { - "emoji": "⭐" - , "description": "white medium star" - , "aliases": [ - "star" - ] - , "tags": [ - ] - } -, { - "emoji": "☀️" - , "description": "black sun with rays" - , "aliases": [ - "sunny" - ] - , "tags": [ - "weather" - ] - } -, { - "emoji": "⛅" - , "description": "sun behind cloud" - , "aliases": [ - "partly_sunny" - ] - , "tags": [ - "weather" - , "cloud" - ] - } -, { - "emoji": "☁️" - , "description": "cloud" - , "aliases": [ - "cloud" - ] - , "tags": [ - ] - } -, { - "emoji": "⚡" - , "description": "high voltage sign" - , "aliases": [ - "zap" - ] - , "tags": [ - "lightning" - , "thunder" - ] - } -, { - "emoji": "☔" - , "description": "umbrella with rain drops" - , "aliases": [ - "umbrella" - ] - , "tags": [ - "rain" - , "weather" - ] - } -, { - "emoji": "❄️" - , "description": "snowflake" - , "aliases": [ - "snowflake" - ] - , "tags": [ - "winter" - , "cold" - , "weather" - ] - } -, { - "emoji": "⛄" - , "description": "snowman without snow" - , "aliases": [ - "snowman" - ] - , "tags": [ - "winter" - , "christmas" - ] - } -, { - "emoji": "🌀" - , "description": "cyclone" - , "aliases": [ - "cyclone" - ] - , "tags": [ - "swirl" - ] - } -, { - "emoji": "🌁" - , "description": "foggy" - , "aliases": [ - "foggy" - ] - , "tags": [ - "karl" - ] - } -, { - "emoji": "🌈" - , "description": "rainbow" - , "aliases": [ - "rainbow" - ] - , "tags": [ - "pride" - ] - } -, { - "emoji": "🌊" - , "description": "water wave" - , "aliases": [ - "ocean" - ] - , "tags": [ - "sea" - ] - } -, { - "emoji": "🎍" - , "description": "pine decoration" - , "aliases": [ - "bamboo" - ] - , "tags": [ - ] - } -, { - "emoji": "💝" - , "description": "heart with ribbon" - , "aliases": [ - "gift_heart" - ] - , "tags": [ - "chocolates" - ] - } -, { - "emoji": "🎎" - , "description": "japanese dolls" - , "aliases": [ - "dolls" - ] - , "tags": [ - ] - } -, { - "emoji": "🎒" - , "description": "school satchel" - , "aliases": [ - "school_satchel" - ] - , "tags": [ - ] - } -, { - "emoji": "🎓" - , "description": "graduation cap" - , "aliases": [ - "mortar_board" - ] - , "tags": [ - "education" - , "college" - , "university" - , "graduation" - ] - } -, { - "emoji": "🎏" - , "description": "carp streamer" - , "aliases": [ - "flags" - ] - , "tags": [ - ] - } -, { - "emoji": "🎆" - , "description": "fireworks" - , "aliases": [ - "fireworks" - ] - , "tags": [ - "festival" - , "celebration" - ] - } -, { - "emoji": "🎇" - , "description": "firework sparkler" - , "aliases": [ - "sparkler" - ] - , "tags": [ - ] - } -, { - "emoji": "🎐" - , "description": "wind chime" - , "aliases": [ - "wind_chime" - ] - , "tags": [ - ] - } -, { - "emoji": "🎑" - , "description": "moon viewing ceremony" - , "aliases": [ - "rice_scene" - ] - , "tags": [ - ] - } -, { - "emoji": "🎃" - , "description": "jack-o-lantern" - , "aliases": [ - "jack_o_lantern" - ] - , "tags": [ - "halloween" - ] - } -, { - "emoji": "👻" - , "description": "ghost" - , "aliases": [ - "ghost" - ] - , "tags": [ - "halloween" - ] - } -, { - "emoji": "🎅" - , "description": "father christmas" - , "aliases": [ - "santa" - ] - , "tags": [ - "christmas" - ] - } -, { - "emoji": "🎄" - , "description": "christmas tree" - , "aliases": [ - "christmas_tree" - ] - , "tags": [ - ] - } -, { - "emoji": "🎁" - , "description": "wrapped present" - , "aliases": [ - "gift" - ] - , "tags": [ - "present" - , "birthday" - , "christmas" - ] - } -, { - "emoji": "🎋" - , "description": "tanabata tree" - , "aliases": [ - "tanabata_tree" - ] - , "tags": [ - ] - } -, { - "emoji": "🎉" - , "description": "party popper" - , "aliases": [ - "tada" - ] - , "tags": [ - "party" - ] - } -, { - "emoji": "🎊" - , "description": "confetti ball" - , "aliases": [ - "confetti_ball" - ] - , "tags": [ - ] - } -, { - "emoji": "🎈" - , "description": "balloon" - , "aliases": [ - "balloon" - ] - , "tags": [ - "party" - , "birthday" - ] - } -, { - "emoji": "🎌" - , "description": "crossed flags" - , "aliases": [ - "crossed_flags" - ] - , "tags": [ - ] - } -, { - "emoji": "🔮" - , "description": "crystal ball" - , "aliases": [ - "crystal_ball" - ] - , "tags": [ - "fortune" - ] - } -, { - "emoji": "🎥" - , "description": "movie camera" - , "aliases": [ - "movie_camera" - ] - , "tags": [ - "film" - , "video" - ] - } -, { - "emoji": "📷" - , "description": "camera" - , "aliases": [ - "camera" - ] - , "tags": [ - "photo" - ] - } -, { - "emoji": "📹" - , "description": "video camera" - , "aliases": [ - "video_camera" - ] - , "tags": [ - ] - } -, { - "emoji": "📼" - , "description": "videocassette" - , "aliases": [ - "vhs" - ] - , "tags": [ - ] - } -, { - "emoji": "💿" - , "description": "optical disc" - , "aliases": [ - "cd" - ] - , "tags": [ - ] - } -, { - "emoji": "📀" - , "description": "dvd" - , "aliases": [ - "dvd" - ] - , "tags": [ - ] - } -, { - "emoji": "💽" - , "description": "minidisc" - , "aliases": [ - "minidisc" - ] - , "tags": [ - ] - } -, { - "emoji": "💾" - , "description": "floppy disk" - , "aliases": [ - "floppy_disk" - ] - , "tags": [ - "save" - ] - } -, { - "emoji": "💻" - , "description": "personal computer" - , "aliases": [ - "computer" - ] - , "tags": [ - "desktop" - , "screen" - ] - } -, { - "emoji": "📱" - , "description": "mobile phone" - , "aliases": [ - "iphone" - ] - , "tags": [ - "smartphone" - , "mobile" - ] - } -, { - "emoji": "☎️" - , "description": "black telephone" - , "aliases": [ - "phone" - , "telephone" - ] - , "tags": [ - ] - } -, { - "emoji": "📞" - , "description": "telephone receiver" - , "aliases": [ - "telephone_receiver" - ] - , "tags": [ - "phone" - , "call" - ] - } -, { - "emoji": "📟" - , "description": "pager" - , "aliases": [ - "pager" - ] - , "tags": [ - ] - } -, { - "emoji": "📠" - , "description": "fax machine" - , "aliases": [ - "fax" - ] - , "tags": [ - ] - } -, { - "emoji": "📡" - , "description": "satellite antenna" - , "aliases": [ - "satellite" - ] - , "tags": [ - "signal" - ] - } -, { - "emoji": "📺" - , "description": "television" - , "aliases": [ - "tv" - ] - , "tags": [ - ] - } -, { - "emoji": "📻" - , "description": "radio" - , "aliases": [ - "radio" - ] - , "tags": [ - "podcast" - ] - } -, { - "emoji": "🔊" - , "description": "speaker with three sound waves" - , "aliases": [ - "loud_sound" - ] - , "tags": [ - "volume" - ] - } -, { - "emoji": "🔉" - , "description": "speaker with one sound wave" - , "aliases": [ - "sound" - ] - , "tags": [ - "volume" - ] - } -, { - "emoji": "🔈" - , "description": "speaker" - , "aliases": [ - "speaker" - ] - , "tags": [ - ] - } -, { - "emoji": "🔇" - , "description": "speaker with cancellation stroke" - , "aliases": [ - "mute" - ] - , "tags": [ - "sound" - , "volume" - ] - } -, { - "emoji": "🔔" - , "description": "bell" - , "aliases": [ - "bell" - ] - , "tags": [ - "sound" - , "notification" - ] - } -, { - "emoji": "🔕" - , "description": "bell with cancellation stroke" - , "aliases": [ - "no_bell" - ] - , "tags": [ - "volume" - , "off" - ] - } -, { - "emoji": "📢" - , "description": "public address loudspeaker" - , "aliases": [ - "loudspeaker" - ] - , "tags": [ - "announcement" - ] - } -, { - "emoji": "📣" - , "description": "cheering megaphone" - , "aliases": [ - "mega" - ] - , "tags": [ - ] - } -, { - "emoji": "⏳" - , "description": "hourglass with flowing sand" - , "aliases": [ - "hourglass_flowing_sand" - ] - , "tags": [ - "time" - ] - } -, { - "emoji": "⌛" - , "description": "hourglass" - , "aliases": [ - "hourglass" - ] - , "tags": [ - "time" - ] - } -, { - "emoji": "⏰" - , "description": "alarm clock" - , "aliases": [ - "alarm_clock" - ] - , "tags": [ - "morning" - ] - } -, { - "emoji": "⌚" - , "description": "watch" - , "aliases": [ - "watch" - ] - , "tags": [ - "time" - ] - } -, { - "emoji": "🔓" - , "description": "open lock" - , "aliases": [ - "unlock" - ] - , "tags": [ - "security" - ] - } -, { - "emoji": "🔒" - , "description": "lock" - , "aliases": [ - "lock" - ] - , "tags": [ - "security" - , "private" - ] - } -, { - "emoji": "🔏" - , "description": "lock with ink pen" - , "aliases": [ - "lock_with_ink_pen" - ] - , "tags": [ - ] - } -, { - "emoji": "🔐" - , "description": "closed lock with key" - , "aliases": [ - "closed_lock_with_key" - ] - , "tags": [ - "security" - ] - } -, { - "emoji": "🔑" - , "description": "key" - , "aliases": [ - "key" - ] - , "tags": [ - "lock" - , "password" - ] - } -, { - "emoji": "🔎" - , "description": "right-pointing magnifying glass" - , "aliases": [ - "mag_right" - ] - , "tags": [ - ] - } -, { - "emoji": "💡" - , "description": "electric light bulb" - , "aliases": [ - "bulb" - ] - , "tags": [ - "idea" - , "light" - ] - } -, { - "emoji": "🔦" - , "description": "electric torch" - , "aliases": [ - "flashlight" - ] - , "tags": [ - ] - } -, { - "emoji": "🔆" - , "description": "high brightness symbol" - , "aliases": [ - "high_brightness" - ] - , "tags": [ - ] - } -, { - "emoji": "🔅" - , "description": "low brightness symbol" - , "aliases": [ - "low_brightness" - ] - , "tags": [ - ] - } -, { - "emoji": "🔌" - , "description": "electric plug" - , "aliases": [ - "electric_plug" - ] - , "tags": [ - ] - } -, { - "emoji": "🔋" - , "description": "battery" - , "aliases": [ - "battery" - ] - , "tags": [ - "power" - ] - } -, { - "emoji": "🔍" - , "description": "left-pointing magnifying glass" - , "aliases": [ - "mag" - ] - , "tags": [ - "search" - , "zoom" - ] - } -, { - "emoji": "🛁" - , "description": "bathtub" - , "aliases": [ - "bathtub" - ] - , "tags": [ - ] - } -, { - "emoji": "🛀" - , "description": "bath" - , "aliases": [ - "bath" - ] - , "tags": [ - "shower" - ] - } -, { - "emoji": "🚿" - , "description": "shower" - , "aliases": [ - "shower" - ] - , "tags": [ - "bath" - ] - } -, { - "emoji": "🚽" - , "description": "toilet" - , "aliases": [ - "toilet" - ] - , "tags": [ - "wc" - ] - } -, { - "emoji": "🔧" - , "description": "wrench" - , "aliases": [ - "wrench" - ] - , "tags": [ - "tool" - ] - } -, { - "emoji": "🔩" - , "description": "nut and bolt" - , "aliases": [ - "nut_and_bolt" - ] - , "tags": [ - ] - } -, { - "emoji": "🔨" - , "description": "hammer" - , "aliases": [ - "hammer" - ] - , "tags": [ - "tool" - ] - } -, { - "emoji": "🚪" - , "description": "door" - , "aliases": [ - "door" - ] - , "tags": [ - ] - } -, { - "emoji": "🚬" - , "description": "smoking symbol" - , "aliases": [ - "smoking" - ] - , "tags": [ - "cigarette" - ] - } -, { - "emoji": "💣" - , "description": "bomb" - , "aliases": [ - "bomb" - ] - , "tags": [ - "boom" - ] - } -, { - "emoji": "🔫" - , "description": "pistol" - , "aliases": [ - "gun" - ] - , "tags": [ - "shoot" - , "weapon" - ] - } -, { - "emoji": "🔪" - , "description": "hocho" - , "aliases": [ - "hocho" - , "knife" - ] - , "tags": [ - "cut" - , "chop" - ] - } -, { - "emoji": "💊" - , "description": "pill" - , "aliases": [ - "pill" - ] - , "tags": [ - "health" - , "medicine" - ] - } -, { - "emoji": "💉" - , "description": "syringe" - , "aliases": [ - "syringe" - ] - , "tags": [ - "health" - , "hospital" - , "needle" - ] - } -, { - "emoji": "💰" - , "description": "money bag" - , "aliases": [ - "moneybag" - ] - , "tags": [ - "dollar" - , "cream" - ] - } -, { - "emoji": "💴" - , "description": "banknote with yen sign" - , "aliases": [ - "yen" - ] - , "tags": [ - ] - } -, { - "emoji": "💵" - , "description": "banknote with dollar sign" - , "aliases": [ - "dollar" - ] - , "tags": [ - "money" - ] - } -, { - "emoji": "💷" - , "description": "banknote with pound sign" - , "aliases": [ - "pound" - ] - , "tags": [ - ] - } -, { - "emoji": "💶" - , "description": "banknote with euro sign" - , "aliases": [ - "euro" - ] - , "tags": [ - ] - } -, { - "emoji": "💳" - , "description": "credit card" - , "aliases": [ - "credit_card" - ] - , "tags": [ - "subscription" - ] - } -, { - "emoji": "💸" - , "description": "money with wings" - , "aliases": [ - "money_with_wings" - ] - , "tags": [ - "dollar" - ] - } -, { - "emoji": "📲" - , "description": "mobile phone with rightwards arrow at left" - , "aliases": [ - "calling" - ] - , "tags": [ - "call" - , "incoming" - ] - } -, { - "emoji": "📧" - , "description": "e-mail symbol" - , "aliases": [ - "e-mail" - ] - , "tags": [ - ] - } -, { - "emoji": "📥" - , "description": "inbox tray" - , "aliases": [ - "inbox_tray" - ] - , "tags": [ - ] - } -, { - "emoji": "📤" - , "description": "outbox tray" - , "aliases": [ - "outbox_tray" - ] - , "tags": [ - ] - } -, { - "emoji": "✉️" - , "description": "envelope" - , "aliases": [ - "email" - , "envelope" - ] - , "tags": [ - "letter" - ] - } -, { - "emoji": "📩" - , "description": "envelope with downwards arrow above" - , "aliases": [ - "envelope_with_arrow" - ] - , "tags": [ - ] - } -, { - "emoji": "📨" - , "description": "incoming envelope" - , "aliases": [ - "incoming_envelope" - ] - , "tags": [ - ] - } -, { - "emoji": "📯" - , "description": "postal horn" - , "aliases": [ - "postal_horn" - ] - , "tags": [ - ] - } -, { - "emoji": "📫" - , "description": "closed mailbox with raised flag" - , "aliases": [ - "mailbox" - ] - , "tags": [ - ] - } -, { - "emoji": "📪" - , "description": "closed mailbox with lowered flag" - , "aliases": [ - "mailbox_closed" - ] - , "tags": [ - ] - } -, { - "emoji": "📬" - , "description": "open mailbox with raised flag" - , "aliases": [ - "mailbox_with_mail" - ] - , "tags": [ - ] - } -, { - "emoji": "📭" - , "description": "open mailbox with lowered flag" - , "aliases": [ - "mailbox_with_no_mail" - ] - , "tags": [ - ] - } -, { - "emoji": "📮" - , "description": "postbox" - , "aliases": [ - "postbox" - ] - , "tags": [ - ] - } -, { - "emoji": "📦" - , "description": "package" - , "aliases": [ - "package" - ] - , "tags": [ - "shipping" - ] - } -, { - "emoji": "📝" - , "description": "memo" - , "aliases": [ - "memo" - , "pencil" - ] - , "tags": [ - "document" - , "note" - ] - } -, { - "emoji": "📄" - , "description": "page facing up" - , "aliases": [ - "page_facing_up" - ] - , "tags": [ - "document" - ] - } -, { - "emoji": "📃" - , "description": "page with curl" - , "aliases": [ - "page_with_curl" - ] - , "tags": [ - ] - } -, { - "emoji": "📑" - , "description": "bookmark tabs" - , "aliases": [ - "bookmark_tabs" - ] - , "tags": [ - ] - } -, { - "emoji": "📊" - , "description": "bar chart" - , "aliases": [ - "bar_chart" - ] - , "tags": [ - "stats" - , "metrics" - ] - } -, { - "emoji": "📈" - , "description": "chart with upwards trend" - , "aliases": [ - "chart_with_upwards_trend" - ] - , "tags": [ - "graph" - , "metrics" - ] - } -, { - "emoji": "📉" - , "description": "chart with downwards trend" - , "aliases": [ - "chart_with_downwards_trend" - ] - , "tags": [ - "graph" - , "metrics" - ] - } -, { - "emoji": "📜" - , "description": "scroll" - , "aliases": [ - "scroll" - ] - , "tags": [ - "document" - ] - } -, { - "emoji": "📋" - , "description": "clipboard" - , "aliases": [ - "clipboard" - ] - , "tags": [ - ] - } -, { - "emoji": "📅" - , "description": "calendar" - , "aliases": [ - "date" - ] - , "tags": [ - "calendar" - , "schedule" - ] - } -, { - "emoji": "📆" - , "description": "tear-off calendar" - , "aliases": [ - "calendar" - ] - , "tags": [ - "schedule" - ] - } -, { - "emoji": "📇" - , "description": "card index" - , "aliases": [ - "card_index" - ] - , "tags": [ - ] - } -, { - "emoji": "📁" - , "description": "file folder" - , "aliases": [ - "file_folder" - ] - , "tags": [ - "directory" - ] - } -, { - "emoji": "📂" - , "description": "open file folder" - , "aliases": [ - "open_file_folder" - ] - , "tags": [ - ] - } -, { - "emoji": "✂️" - , "description": "black scissors" - , "aliases": [ - "scissors" - ] - , "tags": [ - "cut" - ] - } -, { - "emoji": "📌" - , "description": "pushpin" - , "aliases": [ - "pushpin" - ] - , "tags": [ - "location" - ] - } -, { - "emoji": "📎" - , "description": "paperclip" - , "aliases": [ - "paperclip" - ] - , "tags": [ - ] - } -, { - "emoji": "✒️" - , "description": "black nib" - , "aliases": [ - "black_nib" - ] - , "tags": [ - ] - } -, { - "emoji": "✏️" - , "description": "pencil" - , "aliases": [ - "pencil2" - ] - , "tags": [ - ] - } -, { - "emoji": "📏" - , "description": "straight ruler" - , "aliases": [ - "straight_ruler" - ] - , "tags": [ - ] - } -, { - "emoji": "📐" - , "description": "triangular ruler" - , "aliases": [ - "triangular_ruler" - ] - , "tags": [ - ] - } -, { - "emoji": "📕" - , "description": "closed book" - , "aliases": [ - "closed_book" - ] - , "tags": [ - ] - } -, { - "emoji": "📗" - , "description": "green book" - , "aliases": [ - "green_book" - ] - , "tags": [ - ] - } -, { - "emoji": "📘" - , "description": "blue book" - , "aliases": [ - "blue_book" - ] - , "tags": [ - ] - } -, { - "emoji": "📙" - , "description": "orange book" - , "aliases": [ - "orange_book" - ] - , "tags": [ - ] - } -, { - "emoji": "📓" - , "description": "notebook" - , "aliases": [ - "notebook" - ] - , "tags": [ - ] - } -, { - "emoji": "📔" - , "description": "notebook with decorative cover" - , "aliases": [ - "notebook_with_decorative_cover" - ] - , "tags": [ - ] - } -, { - "emoji": "📒" - , "description": "ledger" - , "aliases": [ - "ledger" - ] - , "tags": [ - ] - } -, { - "emoji": "📚" - , "description": "books" - , "aliases": [ - "books" - ] - , "tags": [ - "library" - ] - } -, { - "emoji": "📖" - , "description": "open book" - , "aliases": [ - "book" - , "open_book" - ] - , "tags": [ - ] - } -, { - "emoji": "🔖" - , "description": "bookmark" - , "aliases": [ - "bookmark" - ] - , "tags": [ - ] - } -, { - "emoji": "📛" - , "description": "name badge" - , "aliases": [ - "name_badge" - ] - , "tags": [ - ] - } -, { - "emoji": "🔬" - , "description": "microscope" - , "aliases": [ - "microscope" - ] - , "tags": [ - "science" - , "laboratory" - , "investigate" - ] - } -, { - "emoji": "🔭" - , "description": "telescope" - , "aliases": [ - "telescope" - ] - , "tags": [ - ] - } -, { - "emoji": "📰" - , "description": "newspaper" - , "aliases": [ - "newspaper" - ] - , "tags": [ - "press" - ] - } -, { - "emoji": "🎨" - , "description": "artist palette" - , "aliases": [ - "art" - ] - , "tags": [ - "design" - , "paint" - ] - } -, { - "emoji": "🎬" - , "description": "clapper board" - , "aliases": [ - "clapper" - ] - , "tags": [ - "film" - ] - } -, { - "emoji": "🎤" - , "description": "microphone" - , "aliases": [ - "microphone" - ] - , "tags": [ - "sing" - ] - } -, { - "emoji": "🎧" - , "description": "headphone" - , "aliases": [ - "headphones" - ] - , "tags": [ - "music" - , "earphones" - ] - } -, { - "emoji": "🎼" - , "description": "musical score" - , "aliases": [ - "musical_score" - ] - , "tags": [ - ] - } -, { - "emoji": "🎵" - , "description": "musical note" - , "aliases": [ - "musical_note" - ] - , "tags": [ - ] - } -, { - "emoji": "🎶" - , "description": "multiple musical notes" - , "aliases": [ - "notes" - ] - , "tags": [ - "music" - ] - } -, { - "emoji": "🎹" - , "description": "musical keyboard" - , "aliases": [ - "musical_keyboard" - ] - , "tags": [ - "piano" - ] - } -, { - "emoji": "🎻" - , "description": "violin" - , "aliases": [ - "violin" - ] - , "tags": [ - ] - } -, { - "emoji": "🎺" - , "description": "trumpet" - , "aliases": [ - "trumpet" - ] - , "tags": [ - ] - } -, { - "emoji": "🎷" - , "description": "saxophone" - , "aliases": [ - "saxophone" - ] - , "tags": [ - ] - } -, { - "emoji": "🎸" - , "description": "guitar" - , "aliases": [ - "guitar" - ] - , "tags": [ - "rock" - ] - } -, { - "emoji": "👾" - , "description": "alien monster" - , "aliases": [ - "space_invader" - ] - , "tags": [ - "game" - , "retro" - ] - } -, { - "emoji": "🎮" - , "description": "video game" - , "aliases": [ - "video_game" - ] - , "tags": [ - "play" - , "controller" - , "console" - ] - } -, { - "emoji": "🃏" - , "description": "playing card black joker" - , "aliases": [ - "black_joker" - ] - , "tags": [ - ] - } -, { - "emoji": "🎴" - , "description": "flower playing cards" - , "aliases": [ - "flower_playing_cards" - ] - , "tags": [ - ] - } -, { - "emoji": "🀄" - , "description": "mahjong tile red dragon" - , "aliases": [ - "mahjong" - ] - , "tags": [ - ] - } -, { - "emoji": "🎲" - , "description": "game die" - , "aliases": [ - "game_die" - ] - , "tags": [ - "dice" - , "gambling" - ] - } -, { - "emoji": "🎯" - , "description": "direct hit" - , "aliases": [ - "dart" - ] - , "tags": [ - "target" - ] - } -, { - "emoji": "🏈" - , "description": "american football" - , "aliases": [ - "football" - ] - , "tags": [ - "sports" - ] - } -, { - "emoji": "🏀" - , "description": "basketball and hoop" - , "aliases": [ - "basketball" - ] - , "tags": [ - "sports" - ] - } -, { - "emoji": "⚽" - , "description": "soccer ball" - , "aliases": [ - "soccer" - ] - , "tags": [ - "sports" - ] - } -, { - "emoji": "⚾️" - , "description": "baseball" - , "aliases": [ - "baseball" - ] - , "tags": [ - "sports" - ] - } -, { - "emoji": "🎾" - , "description": "tennis racquet and ball" - , "aliases": [ - "tennis" - ] - , "tags": [ - "sports" - ] - } -, { - "emoji": "🎱" - , "description": "billiards" - , "aliases": [ - "8ball" - ] - , "tags": [ - "pool" - , "billiards" - ] - } -, { - "emoji": "🏉" - , "description": "rugby football" - , "aliases": [ - "rugby_football" - ] - , "tags": [ - ] - } -, { - "emoji": "🎳" - , "description": "bowling" - , "aliases": [ - "bowling" - ] - , "tags": [ - ] - } -, { - "emoji": "⛳" - , "description": "flag in hole" - , "aliases": [ - "golf" - ] - , "tags": [ - ] - } -, { - "emoji": "🚵" - , "description": "mountain bicyclist" - , "aliases": [ - "mountain_bicyclist" - ] - , "tags": [ - ] - } -, { - "emoji": "🚴" - , "description": "bicyclist" - , "aliases": [ - "bicyclist" - ] - , "tags": [ - ] - } -, { - "emoji": "🏁" - , "description": "chequered flag" - , "aliases": [ - "checkered_flag" - ] - , "tags": [ - "milestone" - , "finish" - ] - } -, { - "emoji": "🏇" - , "description": "horse racing" - , "aliases": [ - "horse_racing" - ] - , "tags": [ - ] - } -, { - "emoji": "🏆" - , "description": "trophy" - , "aliases": [ - "trophy" - ] - , "tags": [ - "award" - , "contest" - , "winner" - ] - } -, { - "emoji": "🎿" - , "description": "ski and ski boot" - , "aliases": [ - "ski" - ] - , "tags": [ - ] - } -, { - "emoji": "🏂" - , "description": "snowboarder" - , "aliases": [ - "snowboarder" - ] - , "tags": [ - ] - } -, { - "emoji": "🏊" - , "description": "swimmer" - , "aliases": [ - "swimmer" - ] - , "tags": [ - ] - } -, { - "emoji": "🏄" - , "description": "surfer" - , "aliases": [ - "surfer" - ] - , "tags": [ - ] - } -, { - "emoji": "🎣" - , "description": "fishing pole and fish" - , "aliases": [ - "fishing_pole_and_fish" - ] - , "tags": [ - ] - } -, { - "emoji": "☕" - , "description": "hot beverage" - , "aliases": [ - "coffee" - ] - , "tags": [ - "cafe" - , "espresso" - ] - } -, { - "emoji": "🍵" - , "description": "teacup without handle" - , "aliases": [ - "tea" - ] - , "tags": [ - "green" - , "breakfast" - ] - } -, { - "emoji": "🍶" - , "description": "sake bottle and cup" - , "aliases": [ - "sake" - ] - , "tags": [ - ] - } -, { - "emoji": "🍼" - , "description": "baby bottle" - , "aliases": [ - "baby_bottle" - ] - , "tags": [ - "milk" - ] - } -, { - "emoji": "🍺" - , "description": "beer mug" - , "aliases": [ - "beer" - ] - , "tags": [ - "drink" - ] - } -, { - "emoji": "🍻" - , "description": "clinking beer mugs" - , "aliases": [ - "beers" - ] - , "tags": [ - "drinks" - ] - } -, { - "emoji": "🍸" - , "description": "cocktail glass" - , "aliases": [ - "cocktail" - ] - , "tags": [ - "drink" - ] - } -, { - "emoji": "🍹" - , "description": "tropical drink" - , "aliases": [ - "tropical_drink" - ] - , "tags": [ - "summer" - , "vacation" - ] - } -, { - "emoji": "🍷" - , "description": "wine glass" - , "aliases": [ - "wine_glass" - ] - , "tags": [ - ] - } -, { - "emoji": "🍴" - , "description": "fork and knife" - , "aliases": [ - "fork_and_knife" - ] - , "tags": [ - "cutlery" - ] - } -, { - "emoji": "🍕" - , "description": "slice of pizza" - , "aliases": [ - "pizza" - ] - , "tags": [ - ] - } -, { - "emoji": "🍔" - , "description": "hamburger" - , "aliases": [ - "hamburger" - ] - , "tags": [ - "burger" - ] - } -, { - "emoji": "🍟" - , "description": "french fries" - , "aliases": [ - "fries" - ] - , "tags": [ - ] - } -, { - "emoji": "🍗" - , "description": "poultry leg" - , "aliases": [ - "poultry_leg" - ] - , "tags": [ - "meat" - , "chicken" - ] - } -, { - "emoji": "🍖" - , "description": "meat on bone" - , "aliases": [ - "meat_on_bone" - ] - , "tags": [ - ] - } -, { - "emoji": "🍝" - , "description": "spaghetti" - , "aliases": [ - "spaghetti" - ] - , "tags": [ - "pasta" - ] - } -, { - "emoji": "🍛" - , "description": "curry and rice" - , "aliases": [ - "curry" - ] - , "tags": [ - ] - } -, { - "emoji": "🍤" - , "description": "fried shrimp" - , "aliases": [ - "fried_shrimp" - ] - , "tags": [ - "tempura" - ] - } -, { - "emoji": "🍱" - , "description": "bento box" - , "aliases": [ - "bento" - ] - , "tags": [ - ] - } -, { - "emoji": "🍣" - , "description": "sushi" - , "aliases": [ - "sushi" - ] - , "tags": [ - ] - } -, { - "emoji": "🍥" - , "description": "fish cake with swirl design" - , "aliases": [ - "fish_cake" - ] - , "tags": [ - ] - } -, { - "emoji": "🍙" - , "description": "rice ball" - , "aliases": [ - "rice_ball" - ] - , "tags": [ - ] - } -, { - "emoji": "🍘" - , "description": "rice cracker" - , "aliases": [ - "rice_cracker" - ] - , "tags": [ - ] - } -, { - "emoji": "🍚" - , "description": "cooked rice" - , "aliases": [ - "rice" - ] - , "tags": [ - ] - } -, { - "emoji": "🍜" - , "description": "steaming bowl" - , "aliases": [ - "ramen" - ] - , "tags": [ - "noodle" - ] - } -, { - "emoji": "🍲" - , "description": "pot of food" - , "aliases": [ - "stew" - ] - , "tags": [ - ] - } -, { - "emoji": "🍢" - , "description": "oden" - , "aliases": [ - "oden" - ] - , "tags": [ - ] - } -, { - "emoji": "🍡" - , "description": "dango" - , "aliases": [ - "dango" - ] - , "tags": [ - ] - } -, { - "emoji": "🍳" - , "description": "cooking" - , "aliases": [ - "egg" - ] - , "tags": [ - "breakfast" - ] - } -, { - "emoji": "🍞" - , "description": "bread" - , "aliases": [ - "bread" - ] - , "tags": [ - "toast" - ] - } -, { - "emoji": "🍩" - , "description": "doughnut" - , "aliases": [ - "doughnut" - ] - , "tags": [ - ] - } -, { - "emoji": "🍮" - , "description": "custard" - , "aliases": [ - "custard" - ] - , "tags": [ - ] - } -, { - "emoji": "🍦" - , "description": "soft ice cream" - , "aliases": [ - "icecream" - ] - , "tags": [ - ] - } -, { - "emoji": "🍨" - , "description": "ice cream" - , "aliases": [ - "ice_cream" - ] - , "tags": [ - ] - } -, { - "emoji": "🍧" - , "description": "shaved ice" - , "aliases": [ - "shaved_ice" - ] - , "tags": [ - ] - } -, { - "emoji": "🎂" - , "description": "birthday cake" - , "aliases": [ - "birthday" - ] - , "tags": [ - "party" - ] - } -, { - "emoji": "🍰" - , "description": "shortcake" - , "aliases": [ - "cake" - ] - , "tags": [ - "dessert" - ] - } -, { - "emoji": "🍪" - , "description": "cookie" - , "aliases": [ - "cookie" - ] - , "tags": [ - ] - } -, { - "emoji": "🍫" - , "description": "chocolate bar" - , "aliases": [ - "chocolate_bar" - ] - , "tags": [ - ] - } -, { - "emoji": "🍬" - , "description": "candy" - , "aliases": [ - "candy" - ] - , "tags": [ - "sweet" - ] - } -, { - "emoji": "🍭" - , "description": "lollipop" - , "aliases": [ - "lollipop" - ] - , "tags": [ - ] - } -, { - "emoji": "🍯" - , "description": "honey pot" - , "aliases": [ - "honey_pot" - ] - , "tags": [ - ] - } -, { - "emoji": "🍎" - , "description": "red apple" - , "aliases": [ - "apple" - ] - , "tags": [ - ] - } -, { - "emoji": "🍏" - , "description": "green apple" - , "aliases": [ - "green_apple" - ] - , "tags": [ - "fruit" - ] - } -, { - "emoji": "🍊" - , "description": "tangerine" - , "aliases": [ - "tangerine" - ] - , "tags": [ - ] - } -, { - "emoji": "🍋" - , "description": "lemon" - , "aliases": [ - "lemon" - ] - , "tags": [ - ] - } -, { - "emoji": "🍒" - , "description": "cherries" - , "aliases": [ - "cherries" - ] - , "tags": [ - "fruit" - ] - } -, { - "emoji": "🍇" - , "description": "grapes" - , "aliases": [ - "grapes" - ] - , "tags": [ - ] - } -, { - "emoji": "🍉" - , "description": "watermelon" - , "aliases": [ - "watermelon" - ] - , "tags": [ - ] - } -, { - "emoji": "🍓" - , "description": "strawberry" - , "aliases": [ - "strawberry" - ] - , "tags": [ - "fruit" - ] - } -, { - "emoji": "🍑" - , "description": "peach" - , "aliases": [ - "peach" - ] - , "tags": [ - ] - } -, { - "emoji": "🍈" - , "description": "melon" - , "aliases": [ - "melon" - ] - , "tags": [ - ] - } -, { - "emoji": "🍌" - , "description": "banana" - , "aliases": [ - "banana" - ] - , "tags": [ - "fruit" - ] - } -, { - "emoji": "🍐" - , "description": "pear" - , "aliases": [ - "pear" - ] - , "tags": [ - ] - } -, { - "emoji": "🍍" - , "description": "pineapple" - , "aliases": [ - "pineapple" - ] - , "tags": [ - ] - } -, { - "emoji": "🍠" - , "description": "roasted sweet potato" - , "aliases": [ - "sweet_potato" - ] - , "tags": [ - ] - } -, { - "emoji": "🍆" - , "description": "aubergine" - , "aliases": [ - "eggplant" - ] - , "tags": [ - "aubergine" - ] - } -, { - "emoji": "🍅" - , "description": "tomato" - , "aliases": [ - "tomato" - ] - , "tags": [ - ] - } -, { - "emoji": "🌽" - , "description": "ear of maize" - , "aliases": [ - "corn" - ] - , "tags": [ - ] - } -, { - "emoji": "🏠" - , "description": "house building" - , "aliases": [ - "house" - ] - , "tags": [ - ] - } -, { - "emoji": "🏡" - , "description": "house with garden" - , "aliases": [ - "house_with_garden" - ] - , "tags": [ - ] - } -, { - "emoji": "🏫" - , "description": "school" - , "aliases": [ - "school" - ] - , "tags": [ - ] - } -, { - "emoji": "🏢" - , "description": "office building" - , "aliases": [ - "office" - ] - , "tags": [ - ] - } -, { - "emoji": "🏣" - , "description": "japanese post office" - , "aliases": [ - "post_office" - ] - , "tags": [ - ] - } -, { - "emoji": "🏥" - , "description": "hospital" - , "aliases": [ - "hospital" - ] - , "tags": [ - ] - } -, { - "emoji": "🏦" - , "description": "bank" - , "aliases": [ - "bank" - ] - , "tags": [ - ] - } -, { - "emoji": "🏪" - , "description": "convenience store" - , "aliases": [ - "convenience_store" - ] - , "tags": [ - ] - } -, { - "emoji": "🏩" - , "description": "love hotel" - , "aliases": [ - "love_hotel" - ] - , "tags": [ - ] - } -, { - "emoji": "🏨" - , "description": "hotel" - , "aliases": [ - "hotel" - ] - , "tags": [ - ] - } -, { - "emoji": "💒" - , "description": "wedding" - , "aliases": [ - "wedding" - ] - , "tags": [ - "marriage" - ] - } -, { - "emoji": "⛪" - , "description": "church" - , "aliases": [ - "church" - ] - , "tags": [ - ] - } -, { - "emoji": "🏬" - , "description": "department store" - , "aliases": [ - "department_store" - ] - , "tags": [ - ] - } -, { - "emoji": "🏤" - , "description": "european post office" - , "aliases": [ - "european_post_office" - ] - , "tags": [ - ] - } -, { - "emoji": "🌇" - , "description": "sunset over buildings" - , "aliases": [ +{ + "emojis": [ + { + "code": "1f4af", + "name": "100" + }, + { + "code": "1f522", + "name": "1234" + }, + { + "code": "1f3b1", + "name": "8ball" + }, + { + "code": "1f170", + "name": "a" + }, + { + "code": "1f18e", + "name": "ab" + }, + { + "code": "1f524", + "name": "abc" + }, + { + "code": "1f521", + "name": "abcd" + }, + { + "code": "1f251", + "name": "accept" + }, + { + "code": "1f6a1", + "name": "aerial_tramway" + }, + { + "code": "2708", + "name": "airplane" + }, + { + "code": "1f6ec", + "name": "airplane_arriving" + }, + { + "code": "1f6eb", + "name": "airplane_departure" + }, + { + "code": "1f6e9", + "name": "airplane_small" + }, + { + "code": "23f0", + "name": "alarm_clock" + }, + { + "code": "2697", + "name": "alembic" + }, + { + "code": "1f47d", + "name": "alien" + }, + { + "code": "1f691", + "name": "ambulance" + }, + { + "code": "1f3fa", + "name": "amphora" + }, + { + "code": "2693", + "name": "anchor" + }, + { + "code": "1f47c", + "name": "angel" + }, + { + "code": "1f4a2", + "name": "anger" + }, + { + "code": "1f5ef", + "name": "anger_right" + }, + { + "code": "1f620", + "name": "angry" + }, + { + "code": "1f627", + "name": "anguished" + }, + { + "code": "1f41c", + "name": "ant" + }, + { + "code": "1f34e", + "name": "apple" + }, + { + "code": "2652", + "name": "aquarius" + }, + { + "code": "2648", + "name": "aries" + }, + { + "code": "25c0", + "name": "arrow_backward" + }, + { + "code": "23ec", + "name": "arrow_double_down" + }, + { + "code": "23eb", + "name": "arrow_double_up" + }, + { + "code": "2b07", + "name": "arrow_down" + }, + { + "code": "1f53d", + "name": "arrow_down_small" + }, + { + "code": "25b6", + "name": "arrow_forward" + }, + { + "code": "2935", + "name": "arrow_heading_down" + }, + { + "code": "2934", + "name": "arrow_heading_up" + }, + { + "code": "2b05", + "name": "arrow_left" + }, + { + "code": "2199", + "name": "arrow_lower_left" + }, + { + "code": "2198", + "name": "arrow_lower_right" + }, + { + "code": "27a1", + "name": "arrow_right" + }, + { + "code": "21aa", + "name": "arrow_right_hook" + }, + { + "code": "2b06", + "name": "arrow_up" + }, + { + "code": "2195", + "name": "arrow_up_down" + }, + { + "code": "1f53c", + "name": "arrow_up_small" + }, + { + "code": "2196", + "name": "arrow_upper_left" + }, + { + "code": "2197", + "name": "arrow_upper_right" + }, + { + "code": "1f503", + "name": "arrows_clockwise" + }, + { + "code": "1f504", + "name": "arrows_counterclockwise" + }, + { + "code": "1f3a8", + "name": "art" + }, + { + "code": "1f69b", + "name": "articulated_lorry" + }, + { + "code": "1f632", + "name": "astonished" + }, + { + "code": "1f45f", + "name": "athletic_shoe" + }, + { + "code": "1f3e7", + "name": "atm" + }, + { + "code": "269b", + "name": "atom" + }, + { + "code": "1f171", + "name": "b" + }, + { + "code": "1f476", + "name": "baby" + }, + { + "code": "1f37c", + "name": "baby_bottle" + }, + { + "code": "1f424", + "name": "baby_chick" + }, + { + "code": "1f6bc", + "name": "baby_symbol" + }, + { + "code": "1f519", + "name": "back" + }, + { + "code": "1f3f8", + "name": "badminton" + }, + { + "code": "1f6c4", + "name": "baggage_claim" + }, + { + "code": "1f388", + "name": "balloon" + }, + { + "code": "1f5f3", + "name": "ballot_box" + }, + { + "code": "2611", + "name": "ballot_box_with_check" + }, + { + "code": "1f38d", + "name": "bamboo" + }, + { + "code": "1f34c", + "name": "banana" + }, + { + "code": "203c", + "name": "bangbang" + }, + { + "code": "1f3e6", + "name": "bank" + }, + { + "code": "1f4ca", + "name": "bar_chart" + }, + { + "code": "1f488", + "name": "barber" + }, + { + "code": "26be", + "name": "baseball" + }, + { + "code": "1f3c0", + "name": "basketball" + }, + { + "code": "26f9", + "name": "basketball_player" + }, + { + "code": "1f6c0", + "name": "bath" + }, + { + "code": "1f6c1", + "name": "bathtub" + }, + { + "code": "1f50b", + "name": "battery" + }, + { + "code": "1f3d6", + "name": "beach" + }, + { + "code": "26f1", + "name": "beach_umbrella" + }, + { + "code": "1f43b", + "name": "bear" + }, + { + "code": "1f6cf", + "name": "bed" + }, + { + "code": "1f41d", + "name": "bee" + }, + { + "code": "1f37a", + "name": "beer" + }, + { + "code": "1f37b", + "name": "beers" + }, + { + "code": "1f41e", + "name": "beetle" + }, + { + "code": "1f530", + "name": "beginner" + }, + { + "code": "1f514", + "name": "bell" + }, + { + "code": "1f6ce", + "name": "bellhop" + }, + { + "code": "1f371", + "name": "bento" + }, + { + "code": "1f6b4", + "name": "bicyclist" + }, + { + "code": "1f6b2", + "name": "bike" + }, + { + "code": "1f459", + "name": "bikini" + }, + { + "code": "2623", + "name": "biohazard" + }, + { + "code": "1f426", + "name": "bird" + }, + { + "code": "1f382", + "name": "birthday" + }, + { + "code": "26ab", + "name": "black_circle" + }, + { + "code": "1f0cf", + "name": "black_joker" + }, + { + "code": "2b1b", + "name": "black_large_square" + }, + { + "code": "25fe", + "name": "black_medium_small_square" + }, + { + "code": "25fc", + "name": "black_medium_square" + }, + { + "code": "2712", + "name": "black_nib" + }, + { + "code": "25aa", + "name": "black_small_square" + }, + { + "code": "1f532", + "name": "black_square_button" + }, + { + "code": "1f33c", + "name": "blossom" + }, + { + "code": "1f421", + "name": "blowfish" + }, + { + "code": "1f4d8", + "name": "blue_book" + }, + { + "code": "1f699", + "name": "blue_car" + }, + { + "code": "1f499", + "name": "blue_heart" + }, + { + "code": "1f60a", + "name": "blush" + }, + { + "code": "1f417", + "name": "boar" + }, + { + "code": "1f4a3", + "name": "bomb" + }, + { + "code": "1f4d6", + "name": "book" + }, + { + "code": "1f516", + "name": "bookmark" + }, + { + "code": "1f4d1", + "name": "bookmark_tabs" + }, + { + "code": "1f4da", + "name": "books" + }, + { + "code": "1f4a5", + "name": "boom" + }, + { + "code": "1f462", + "name": "boot" + }, + { + "code": "1f490", + "name": "bouquet" + }, + { + "code": "1f647", + "name": "bow" + }, + { + "code": "1f3f9", + "name": "bow_and_arrow" + }, + { + "code": "1f3b3", + "name": "bowling" + }, + { + "code": "1f466", + "name": "boy" + }, + { + "code": "1f35e", + "name": "bread" + }, + { + "code": "1f470", + "name": "bride_with_veil" + }, + { + "code": "1f309", + "name": "bridge_at_night" + }, + { + "code": "1f4bc", + "name": "briefcase" + }, + { + "code": "1f494", + "name": "broken_heart" + }, + { + "code": "1f41b", + "name": "bug" + }, + { + "code": "1f4a1", + "name": "bulb" + }, + { + "code": "1f685", + "name": "bullettrain_front" + }, + { + "code": "1f684", + "name": "bullettrain_side" + }, + { + "code": "1f32f", + "name": "burrito" + }, + { + "code": "1f68c", + "name": "bus" + }, + { + "code": "1f68f", + "name": "busstop" + }, + { + "code": "1f464", + "name": "bust_in_silhouette" + }, + { + "code": "1f465", + "name": "busts_in_silhouette" + }, + { + "code": "1f335", + "name": "cactus" + }, + { + "code": "1f370", + "name": "cake" + }, + { + "code": "1f4c6", + "name": "calendar" + }, + { + "code": "1f5d3", + "name": "calendar_spiral" + }, + { + "code": "1f4f2", + "name": "calling" + }, + { + "code": "1f42b", + "name": "camel" + }, + { + "code": "1f4f7", + "name": "camera" + }, + { + "code": "1f4f8", + "name": "camera_with_flash" + }, + { + "code": "1f3d5", + "name": "camping" + }, + { + "code": "264b", + "name": "cancer" + }, + { + "code": "1f56f", + "name": "candle" + }, + { + "code": "1f36c", + "name": "candy" + }, + { + "code": "1f520", + "name": "capital_abcd" + }, + { + "code": "2651", + "name": "capricorn" + }, + { + "code": "1f5c3", + "name": "card_box" + }, + { + "code": "1f4c7", + "name": "card_index" + }, + { + "code": "1f3a0", + "name": "carousel_horse" + }, + { + "code": "1f431", + "name": "cat" + }, + { + "code": "1f408", + "name": "cat2" + }, + { + "code": "1f4bf", + "name": "cd" + }, + { + "code": "26d3", + "name": "chains" + }, + { + "code": "1f37e", + "name": "champagne" + }, + { + "code": "1f4b9", + "name": "chart" + }, + { + "code": "1f4c9", + "name": "chart_with_downwards_trend" + }, + { + "code": "1f4c8", + "name": "chart_with_upwards_trend" + }, + { + "code": "1f3c1", + "name": "checkered_flag" + }, + { + "code": "1f9c0", + "name": "cheese" + }, + { + "code": "1f352", + "name": "cherries" + }, + { + "code": "1f338", + "name": "cherry_blossom" + }, + { + "code": "1f330", + "name": "chestnut" + }, + { + "code": "1f414", + "name": "chicken" + }, + { + "code": "1f6b8", + "name": "children_crossing" + }, + { + "code": "1f43f", + "name": "chipmunk" + }, + { + "code": "1f36b", + "name": "chocolate_bar" + }, + { + "code": "1f384", + "name": "christmas_tree" + }, + { + "code": "26ea", + "name": "church" + }, + { + "code": "1f3a6", + "name": "cinema" + }, + { + "code": "1f3aa", + "name": "circus_tent" + }, + { + "code": "1f306", + "name": "city_dusk" + }, + { + "code": "1f307", + "name": "city_sunset" + }, + { + "code": "1f3d9", + "name": "cityscape" + }, + { + "code": "1f191", + "name": "cl" + }, + { + "code": "1f44f", + "name": "clap" + }, + { + "code": "1f3ac", + "name": "clapper" + }, + { + "code": "1f3db", + "name": "classical_building" + }, + { + "code": "1f4cb", + "name": "clipboard" + }, + { + "code": "1f570", + "name": "clock" + }, + { + "code": "1f550", + "name": "clock1" + }, + { + "code": "1f559", + "name": "clock10" + }, + { + "code": "1f565", + "name": "clock1030" + }, + { + "code": "1f55a", + "name": "clock11" + }, + { + "code": "1f566", + "name": "clock1130" + }, + { + "code": "1f55b", + "name": "clock12" + }, + { + "code": "1f567", + "name": "clock1230" + }, + { + "code": "1f55c", + "name": "clock130" + }, + { + "code": "1f551", + "name": "clock2" + }, + { + "code": "1f55d", + "name": "clock230" + }, + { + "code": "1f552", + "name": "clock3" + }, + { + "code": "1f55e", + "name": "clock330" + }, + { + "code": "1f553", + "name": "clock4" + }, + { + "code": "1f55f", + "name": "clock430" + }, + { + "code": "1f554", + "name": "clock5" + }, + { + "code": "1f560", + "name": "clock530" + }, + { + "code": "1f555", + "name": "clock6" + }, + { + "code": "1f561", + "name": "clock630" + }, + { + "code": "1f556", + "name": "clock7" + }, + { + "code": "1f562", + "name": "clock730" + }, + { + "code": "1f557", + "name": "clock8" + }, + { + "code": "1f563", + "name": "clock830" + }, + { + "code": "1f558", + "name": "clock9" + }, + { + "code": "1f564", + "name": "clock930" + }, + { + "code": "1f4d5", + "name": "closed_book" + }, + { + "code": "1f510", + "name": "closed_lock_with_key" + }, + { + "code": "1f302", + "name": "closed_umbrella" + }, + { + "code": "2601", + "name": "cloud" + }, + { + "code": "1f329", + "name": "cloud_lightning" + }, + { + "code": "1f327", + "name": "cloud_rain" + }, + { + "code": "1f328", + "name": "cloud_snow" + }, + { + "code": "1f32a", + "name": "cloud_tornado" + }, + { + "code": "2663", + "name": "clubs" + }, + { + "code": "1f378", + "name": "cocktail" + }, + { + "code": "2615", + "name": "coffee" + }, + { + "code": "26b0", + "name": "coffin" + }, + { + "code": "1f630", + "name": "cold_sweat" + }, + { + "code": "2604", + "name": "comet" + }, + { + "code": "1f5dc", + "name": "compression" + }, + { + "code": "1f4bb", + "name": "computer" + }, + { + "code": "1f38a", + "name": "confetti_ball" + }, + { + "code": "1f616", + "name": "confounded" + }, + { + "code": "1f615", + "name": "confused" + }, + { + "code": "3297", + "name": "congratulations" + }, + { + "code": "1f6a7", + "name": "construction" + }, + { + "code": "1f3d7", + "name": "construction_site" + }, + { + "code": "1f477", + "name": "construction_worker" + }, + { + "code": "1f39b", + "name": "control_knobs" + }, + { + "code": "1f3ea", + "name": "convenience_store" + }, + { + "code": "1f36a", + "name": "cookie" + }, + { + "code": "1f192", + "name": "cool" + }, + { + "code": "1f46e", + "name": "cop" + }, + { + "code": "00a9", + "name": "copyright" + }, + { + "code": "1f33d", + "name": "corn" + }, + { + "code": "1f6cb", + "name": "couch" + }, + { + "code": "1f46b", + "name": "couple" + }, + { + "code": "1f491", + "name": "couple_with_heart" + }, + { + "code": "1f48f", + "name": "couplekiss" + }, + { + "code": "1f42e", + "name": "cow" + }, + { + "code": "1f404", + "name": "cow2" + }, + { + "code": "1f980", + "name": "crab" + }, + { + "code": "1f58d", + "name": "crayon" + }, + { + "code": "1f4b3", + "name": "credit_card" + }, + { + "code": "1f319", + "name": "crescent_moon" + }, + { + "code": "1f3cf", + "name": "cricket" + }, + { + "code": "1f40a", + "name": "crocodile" + }, + { + "code": "271d", + "name": "cross" + }, + { + "code": "1f38c", + "name": "crossed_flags" + }, + { + "code": "2694", + "name": "crossed_swords" + }, + { + "code": "1f451", + "name": "crown" + }, + { + "code": "1f6f3", + "name": "cruise_ship" + }, + { + "code": "1f622", + "name": "cry" + }, + { + "code": "1f63f", + "name": "crying_cat_face" + }, + { + "code": "1f52e", + "name": "crystal_ball" + }, + { + "code": "1f498", + "name": "cupid" + }, + { + "code": "27b0", + "name": "curly_loop" + }, + { + "code": "1f4b1", + "name": "currency_exchange" + }, + { + "code": "1f35b", + "name": "curry" + }, + { + "code": "1f36e", + "name": "custard" + }, + { + "code": "1f6c3", + "name": "customs" + }, + { + "code": "1f300", + "name": "cyclone" + }, + { + "code": "1f5e1", + "name": "dagger" + }, + { + "code": "1f483", + "name": "dancer" + }, + { + "code": "1f46f", + "name": "dancers" + }, + { + "code": "1f361", + "name": "dango" + }, + { + "code": "1f576", + "name": "dark_sunglasses" + }, + { + "code": "1f3af", + "name": "dart" + }, + { + "code": "1f4a8", + "name": "dash" + }, + { + "code": "1f4c5", + "name": "date" + }, + { + "code": "1f333", + "name": "deciduous_tree" + }, + { + "code": "1f3ec", + "name": "department_store" + }, + { + "code": "1f3dc", + "name": "desert" + }, + { + "code": "1f5a5", + "name": "desktop" + }, + { + "code": "1f4a0", + "name": "diamond_shape_with_a_dot_inside" + }, + { + "code": "2666", + "name": "diamonds" + }, + { + "code": "1f61e", + "name": "disappointed" + }, + { + "code": "1f625", + "name": "disappointed_relieved" + }, + { + "code": "1f5c2", + "name": "dividers" + }, + { + "code": "1f4ab", + "name": "dizzy" + }, + { + "code": "1f635", + "name": "dizzy_face" + }, + { + "code": "1f6af", + "name": "do_not_litter" + }, + { + "code": "1f436", + "name": "dog" + }, + { + "code": "1f415", + "name": "dog2" + }, + { + "code": "1f4b5", + "name": "dollar" + }, + { + "code": "1f38e", + "name": "dolls" + }, + { + "code": "1f42c", + "name": "dolphin" + }, + { + "code": "1f6aa", + "name": "door" + }, + { + "code": "1f369", + "name": "doughnut" + }, + { + "code": "1f54a", + "name": "dove" + }, + { + "code": "1f409", + "name": "dragon" + }, + { + "code": "1f432", + "name": "dragon_face" + }, + { + "code": "1f457", + "name": "dress" + }, + { + "code": "1f42a", + "name": "dromedary_camel" + }, + { + "code": "1f4a7", + "name": "droplet" + }, + { + "code": "1f4c0", + "name": "dvd" + }, + { + "code": "1f4e7", + "name": "e-mail" + }, + { + "code": "1f442", + "name": "ear" + }, + { + "code": "1f33e", + "name": "ear_of_rice" + }, + { + "code": "1f30d", + "name": "earth_africa" + }, + { + "code": "1f30e", + "name": "earth_americas" + }, + { + "code": "1f30f", + "name": "earth_asia" + }, + { + "code": "1f373", + "name": "egg" + }, + { + "code": "1f346", + "name": "eggplant" + }, + { + "code": "0038-20e3", + "name": "eight" + }, + { + "code": "2734", + "name": "eight_pointed_black_star" + }, + { + "code": "2733", + "name": "eight_spoked_asterisk" + }, + { + "code": "1f50c", + "name": "electric_plug" + }, + { + "code": "1f418", + "name": "elephant" + }, + { + "code": "1f51a", + "name": "end" + }, + { + "code": "2709", + "name": "envelope" + }, + { + "code": "1f4e9", + "name": "envelope_with_arrow" + }, + { + "code": "1f4b6", + "name": "euro" + }, + { + "code": "1f3f0", + "name": "european_castle" + }, + { + "code": "1f3e4", + "name": "european_post_office" + }, + { + "code": "1f332", + "name": "evergreen_tree" + }, + { + "code": "2757", + "name": "exclamation" + }, + { + "code": "1f611", + "name": "expressionless" + }, + { + "code": "1f441", + "name": "eye" + }, + { + "code": "1f453", + "name": "eyeglasses" + }, + { + "code": "1f440", + "name": "eyes" + }, + { + "code": "1f3ed", + "name": "factory" + }, + { + "code": "1f342", + "name": "fallen_leaf" + }, + { + "code": "1f46a", + "name": "family" + }, + { + "code": "23e9", + "name": "fast_forward" + }, + { + "code": "1f4e0", + "name": "fax" + }, + { + "code": "1f628", + "name": "fearful" + }, + { + "code": "1f43e", + "name": "feet" + }, + { + "code": "1f3a1", + "name": "ferris_wheel" + }, + { + "code": "26f4", + "name": "ferry" + }, + { + "code": "1f3d1", + "name": "field_hockey" + }, + { + "code": "1f5c4", + "name": "file_cabinet" + }, + { + "code": "1f4c1", + "name": "file_folder" + }, + { + "code": "1f39e", + "name": "film_frames" + }, + { + "code": "1f525", + "name": "fire" + }, + { + "code": "1f692", + "name": "fire_engine" + }, + { + "code": "1f386", + "name": "fireworks" + }, + { + "code": "1f313", + "name": "first_quarter_moon" + }, + { + "code": "1f31b", + "name": "first_quarter_moon_with_face" + }, + { + "code": "1f41f", + "name": "fish" + }, + { + "code": "1f365", + "name": "fish_cake" + }, + { + "code": "1f3a3", + "name": "fishing_pole_and_fish" + }, + { + "code": "270a", + "name": "fist" + }, + { + "code": "0035-20e3", + "name": "five" + }, + { + "code": "1f3f4", + "name": "flag_black" + }, + { + "code": "1f1e8-1f1f3", + "name": "flag_cn" + }, + { + "code": "1f1e9-1f1ea", + "name": "flag_de" + }, + { + "code": "1f1ea-1f1f8", + "name": "flag_es" + }, + { + "code": "1f1eb-1f1f7", + "name": "flag_fr" + }, + { + "code": "1f1ec-1f1e7", + "name": "flag_gb" + }, + { + "code": "1f1ee-1f1f9", + "name": "flag_it" + }, + { + "code": "1f1ef-1f1f5", + "name": "flag_jp" + }, + { + "code": "1f1f0-1f1f7", + "name": "flag_kr" + }, + { + "code": "1f1f7-1f1fa", + "name": "flag_ru" + }, + { + "code": "1f1fa-1f1f8", + "name": "flag_us" + }, + { + "code": "1f3f3", + "name": "flag_white" + }, + { + "code": "1f38f", + "name": "flags" + }, + { + "code": "1f526", + "name": "flashlight" + }, + { + "code": "269c", + "name": "fleur-de-lis" + }, + { + "code": "1f4be", + "name": "floppy_disk" + }, + { + "code": "1f3b4", + "name": "flower_playing_cards" + }, + { + "code": "1f633", + "name": "flushed" + }, + { + "code": "1f32b", + "name": "fog" + }, + { + "code": "1f301", + "name": "foggy" + }, + { + "code": "1f3c8", + "name": "football" + }, + { + "code": "1f463", + "name": "footprints" + }, + { + "code": "1f374", + "name": "fork_and_knife" + }, + { + "code": "1f37d", + "name": "fork_knife_plate" + }, + { + "code": "26f2", + "name": "fountain" + }, + { + "code": "0034-20e3", + "name": "four" + }, + { + "code": "1f340", + "name": "four_leaf_clover" + }, + { + "code": "1f5bc", + "name": "frame_photo" + }, + { + "code": "1f193", + "name": "free" + }, + { + "code": "1f364", + "name": "fried_shrimp" + }, + { + "code": "1f35f", + "name": "fries" + }, + { + "code": "1f438", + "name": "frog" + }, + { + "code": "1f626", + "name": "frowning" + }, + { + "code": "2639", + "name": "frowning2" + }, + { + "code": "26fd", + "name": "fuelpump" + }, + { + "code": "1f315", + "name": "full_moon" + }, + { + "code": "1f31d", + "name": "full_moon_with_face" + }, + { + "code": "1f3b2", + "name": "game_die" + }, + { + "code": "2699", + "name": "gear" + }, + { + "code": "1f48e", + "name": "gem" + }, + { + "code": "264a", + "name": "gemini" + }, + { + "code": "1f47b", + "name": "ghost" + }, + { + "code": "1f381", + "name": "gift" + }, + { + "code": "1f49d", + "name": "gift_heart" + }, + { + "code": "1f467", + "name": "girl" + }, + { + "code": "1f310", + "name": "globe_with_meridians" + }, + { + "code": "1f410", + "name": "goat" + }, + { + "code": "26f3", + "name": "golf" + }, + { + "code": "1f3cc", + "name": "golfer" + }, + { + "code": "1f347", + "name": "grapes" + }, + { + "code": "1f34f", + "name": "green_apple" + }, + { + "code": "1f4d7", + "name": "green_book" + }, + { + "code": "1f49a", + "name": "green_heart" + }, + { + "code": "2755", + "name": "grey_exclamation" + }, + { + "code": "2754", + "name": "grey_question" + }, + { + "code": "1f62c", + "name": "grimacing" + }, + { + "code": "1f601", + "name": "grin" + }, + { + "code": "1f600", + "name": "grinning" + }, + { + "code": "1f482", + "name": "guardsman" + }, + { + "code": "1f3b8", + "name": "guitar" + }, + { + "code": "1f52b", + "name": "gun" + }, + { + "code": "1f487", + "name": "haircut" + }, + { + "code": "1f354", + "name": "hamburger" + }, + { + "code": "1f528", + "name": "hammer" + }, + { + "code": "2692", + "name": "hammer_pick" + }, + { + "code": "1f439", + "name": "hamster" + }, + { + "code": "1f590", + "name": "hand_splayed" + }, + { + "code": "1f45c", + "name": "handbag" + }, + { + "code": "0023-20e3", + "name": "hash" + }, + { + "code": "1f425", + "name": "hatched_chick" + }, + { + "code": "1f423", + "name": "hatching_chick" + }, + { + "code": "1f915", + "name": "head_bandage" + }, + { + "code": "1f3a7", + "name": "headphones" + }, + { + "code": "1f649", + "name": "hear_no_evil" + }, + { + "code": "2764", + "name": "heart" + }, + { + "code": "1f49f", + "name": "heart_decoration" + }, + { + "code": "2763", + "name": "heart_exclamation" + }, + { + "code": "1f60d", + "name": "heart_eyes" + }, + { + "code": "1f63b", + "name": "heart_eyes_cat" + }, + { + "code": "1f493", + "name": "heartbeat" + }, + { + "code": "1f497", + "name": "heartpulse" + }, + { + "code": "2665", + "name": "hearts" + }, + { + "code": "2714", + "name": "heavy_check_mark" + }, + { + "code": "2797", + "name": "heavy_division_sign" + }, + { + "code": "1f4b2", + "name": "heavy_dollar_sign" + }, + { + "code": "2796", + "name": "heavy_minus_sign" + }, + { + "code": "2716", + "name": "heavy_multiplication_x" + }, + { + "code": "2795", + "name": "heavy_plus_sign" + }, + { + "code": "1f681", + "name": "helicopter" + }, + { + "code": "26d1", + "name": "helmet_with_cross" + }, + { + "code": "1f33f", + "name": "herb" + }, + { + "code": "1f33a", + "name": "hibiscus" + }, + { + "code": "1f506", + "name": "high_brightness" + }, + { + "code": "1f460", + "name": "high_heel" + }, + { + "code": "1f3d2", + "name": "hockey" + }, + { + "code": "1f573", + "name": "hole" + }, + { + "code": "1f3d8", + "name": "homes" + }, + { + "code": "1f36f", + "name": "honey_pot" + }, + { + "code": "1f434", + "name": "horse" + }, + { + "code": "1f3c7", + "name": "horse_racing" + }, + { + "code": "1f3e5", + "name": "hospital" + }, + { + "code": "1f336", + "name": "hot_pepper" + }, + { + "code": "1f32d", + "name": "hotdog" + }, + { + "code": "1f3e8", + "name": "hotel" + }, + { + "code": "2668", + "name": "hotsprings" + }, + { + "code": "231b", + "name": "hourglass" + }, + { + "code": "23f3", + "name": "hourglass_flowing_sand" + }, + { + "code": "1f3e0", + "name": "house" + }, + { + "code": "1f3da", + "name": "house_abandoned" + }, + { + "code": "1f3e1", + "name": "house_with_garden" + }, + { + "code": "1f917", + "name": "hugging" + }, + { + "code": "1f62f", + "name": "hushed" + }, + { + "code": "1f368", + "name": "ice_cream" + }, + { + "code": "26f8", + "name": "ice_skate" + }, + { + "code": "1f366", + "name": "icecream" + }, + { + "code": "1f194", + "name": "id" + }, + { + "code": "1f250", + "name": "ideograph_advantage" + }, + { + "code": "1f47f", + "name": "imp" + }, + { + "code": "1f4e5", + "name": "inbox_tray" + }, + { + "code": "1f4e8", + "name": "incoming_envelope" + }, + { + "code": "1f481", + "name": "information_desk_person" + }, + { + "code": "2139", + "name": "information_source" + }, + { + "code": "1f607", + "name": "innocent" + }, + { + "code": "2049", + "name": "interrobang" + }, + { + "code": "1f4f1", + "name": "iphone" + }, + { + "code": "1f3dd", + "name": "island" + }, + { + "code": "1f3ee", + "name": "izakaya_lantern" + }, + { + "code": "1f383", + "name": "jack_o_lantern" + }, + { + "code": "1f5fe", + "name": "japan" + }, + { + "code": "1f3ef", + "name": "japanese_castle" + }, + { + "code": "1f47a", + "name": "japanese_goblin" + }, + { + "code": "1f479", + "name": "japanese_ogre" + }, + { + "code": "1f456", + "name": "jeans" + }, + { + "code": "1f602", + "name": "joy" + }, + { + "code": "1f639", + "name": "joy_cat" + }, + { + "code": "1f579", + "name": "joystick" + }, + { + "code": "1f54b", + "name": "kaaba" + }, + { + "code": "1f511", + "name": "key" + }, + { + "code": "1f5dd", + "name": "key2" + }, + { + "code": "2328", + "name": "keyboard" + }, + { + "code": "1f458", + "name": "kimono" + }, + { + "code": "1f48b", + "name": "kiss" + }, + { + "code": "1f617", + "name": "kissing" + }, + { + "code": "1f63d", + "name": "kissing_cat" + }, + { + "code": "1f61a", + "name": "kissing_closed_eyes" + }, + { + "code": "1f618", + "name": "kissing_heart" + }, + { + "code": "1f619", + "name": "kissing_smiling_eyes" + }, + { + "code": "1f52a", + "name": "knife" + }, + { + "code": "1f428", + "name": "koala" + }, + { + "code": "1f201", + "name": "koko" + }, + { + "code": "1f3f7", + "name": "label" + }, + { + "code": "1f535", + "name": "large_blue_circle" + }, + { + "code": "1f537", + "name": "large_blue_diamond" + }, + { + "code": "1f536", + "name": "large_orange_diamond" + }, + { + "code": "1f317", + "name": "last_quarter_moon" + }, + { + "code": "1f31c", + "name": "last_quarter_moon_with_face" + }, + { + "code": "1f606", + "name": "laughing" + }, + { + "code": "1f343", + "name": "leaves" + }, + { + "code": "1f4d2", + "name": "ledger" + }, + { + "code": "1f6c5", + "name": "left_luggage" + }, + { + "code": "2194", + "name": "left_right_arrow" + }, + { + "code": "21a9", + "name": "leftwards_arrow_with_hook" + }, + { + "code": "1f34b", + "name": "lemon" + }, + { + "code": "264c", + "name": "leo" + }, + { + "code": "1f406", + "name": "leopard" + }, + { + "code": "1f39a", + "name": "level_slider" + }, + { + "code": "1f574", + "name": "levitate" + }, + { + "code": "264e", + "name": "libra" + }, + { + "code": "1f3cb", + "name": "lifter" + }, + { + "code": "1f688", + "name": "light_rail" + }, + { + "code": "1f517", + "name": "link" + }, + { + "code": "1f981", + "name": "lion_face" + }, + { + "code": "1f444", + "name": "lips" + }, + { + "code": "1f484", + "name": "lipstick" + }, + { + "code": "1f512", + "name": "lock" + }, + { + "code": "1f50f", + "name": "lock_with_ink_pen" + }, + { + "code": "1f36d", + "name": "lollipop" + }, + { + "code": "27bf", + "name": "loop" + }, + { + "code": "1f50a", + "name": "loud_sound" + }, + { + "code": "1f4e2", + "name": "loudspeaker" + }, + { + "code": "1f3e9", + "name": "love_hotel" + }, + { + "code": "1f48c", + "name": "love_letter" + }, + { + "code": "1f505", + "name": "low_brightness" + }, + { + "code": "24c2", + "name": "m" + }, + { + "code": "1f50d", + "name": "mag" + }, + { + "code": "1f50e", + "name": "mag_right" + }, + { + "code": "1f004", + "name": "mahjong" + }, + { + "code": "1f4eb", + "name": "mailbox" + }, + { + "code": "1f4ea", + "name": "mailbox_closed" + }, + { + "code": "1f4ec", + "name": "mailbox_with_mail" + }, + { + "code": "1f4ed", + "name": "mailbox_with_no_mail" + }, + { + "code": "1f468", + "name": "man" + }, + { + "code": "1f472", + "name": "man_with_gua_pi_mao" + }, + { + "code": "1f473", + "name": "man_with_turban" + }, + { + "code": "1f45e", + "name": "mans_shoe" + }, + { + "code": "1f5fa", + "name": "map" + }, + { + "code": "1f341", + "name": "maple_leaf" + }, + { + "code": "1f637", + "name": "mask" + }, + { + "code": "1f486", + "name": "massage" + }, + { + "code": "1f356", + "name": "meat_on_bone" + }, + { + "code": "1f3c5", + "name": "medal" + }, + { + "code": "1f4e3", + "name": "mega" + }, + { + "code": "1f348", + "name": "melon" + }, + { + "code": "1f54e", + "name": "menorah" + }, + { + "code": "1f6b9", + "name": "mens" + }, + { + "code": "1f918", + "name": "metal" + }, + { + "code": "1f687", + "name": "metro" + }, + { + "code": "1f3a4", + "name": "microphone" + }, + { + "code": "1f399", + "name": "microphone2" + }, + { + "code": "1f52c", + "name": "microscope" + }, + { + "code": "1f595", + "name": "middle_finger" + }, + { + "code": "1f396", + "name": "military_medal" + }, + { + "code": "1f30c", + "name": "milky_way" + }, + { + "code": "1f690", + "name": "minibus" + }, + { + "code": "1f4bd", + "name": "minidisc" + }, + { + "code": "1f4f4", + "name": "mobile_phone_off" + }, + { + "code": "1f911", + "name": "money_mouth" + }, + { + "code": "1f4b8", + "name": "money_with_wings" + }, + { + "code": "1f4b0", + "name": "moneybag" + }, + { + "code": "1f412", + "name": "monkey" + }, + { + "code": "1f435", + "name": "monkey_face" + }, + { + "code": "1f69d", + "name": "monorail" + }, + { + "code": "1f393", + "name": "mortar_board" + }, + { + "code": "1f54c", + "name": "mosque" + }, + { + "code": "1f6e5", + "name": "motorboat" + }, + { + "code": "1f3cd", + "name": "motorcycle" + }, + { + "code": "1f6e3", + "name": "motorway" + }, + { + "code": "1f5fb", + "name": "mount_fuji" + }, + { + "code": "26f0", + "name": "mountain" + }, + { + "code": "1f6b5", + "name": "mountain_bicyclist" + }, + { + "code": "1f6a0", + "name": "mountain_cableway" + }, + { + "code": "1f69e", + "name": "mountain_railway" + }, + { + "code": "1f3d4", + "name": "mountain_snow" + }, + { + "code": "1f42d", + "name": "mouse" + }, + { + "code": "1f401", + "name": "mouse2" + }, + { + "code": "1f5b1", + "name": "mouse_three_button" + }, + { + "code": "1f3a5", + "name": "movie_camera" + }, + { + "code": "1f5ff", + "name": "moyai" + }, + { + "code": "1f4aa", + "name": "muscle" + }, + { + "code": "1f344", + "name": "mushroom" + }, + { + "code": "1f3b9", + "name": "musical_keyboard" + }, + { + "code": "1f3b5", + "name": "musical_note" + }, + { + "code": "1f3bc", + "name": "musical_score" + }, + { + "code": "1f507", + "name": "mute" + }, + { + "code": "1f485", + "name": "nail_care" + }, + { + "code": "1f4db", + "name": "name_badge" + }, + { + "code": "1f454", + "name": "necktie" + }, + { + "code": "274e", + "name": "negative_squared_cross_mark" + }, + { + "code": "1f913", + "name": "nerd" + }, + { + "code": "1f610", + "name": "neutral_face" + }, + { + "code": "1f195", + "name": "new" + }, + { + "code": "1f311", + "name": "new_moon" + }, + { + "code": "1f31a", + "name": "new_moon_with_face" + }, + { + "code": "1f4f0", + "name": "newspaper" + }, + { + "code": "1f5de", + "name": "newspaper2" + }, + { + "code": "1f196", + "name": "ng" + }, + { + "code": "1f303", + "name": "night_with_stars" + }, + { + "code": "0039-20e3", + "name": "nine" + }, + { + "code": "1f515", + "name": "no_bell" + }, + { + "code": "1f6b3", + "name": "no_bicycles" + }, + { + "code": "26d4", + "name": "no_entry" + }, + { + "code": "1f6ab", + "name": "no_entry_sign" + }, + { + "code": "1f645", + "name": "no_good" + }, + { + "code": "1f4f5", + "name": "no_mobile_phones" + }, + { + "code": "1f636", + "name": "no_mouth" + }, + { + "code": "1f6b7", + "name": "no_pedestrians" + }, + { + "code": "1f6ad", + "name": "no_smoking" + }, + { + "code": "1f6b1", + "name": "non-potable_water" + }, + { + "code": "1f443", + "name": "nose" + }, + { + "code": "1f4d3", + "name": "notebook" + }, + { + "code": "1f4d4", + "name": "notebook_with_decorative_cover" + }, + { + "code": "1f5d2", + "name": "notepad_spiral" + }, + { + "code": "1f3b6", + "name": "notes" + }, + { + "code": "1f529", + "name": "nut_and_bolt" + }, + { + "code": "2b55", + "name": "o" + }, + { + "code": "1f17e", + "name": "o2" + }, + { + "code": "1f30a", + "name": "ocean" + }, + { + "code": "1f419", + "name": "octopus" + }, + { + "code": "1f362", + "name": "oden" + }, + { + "code": "1f3e2", + "name": "office" + }, + { + "code": "1f6e2", + "name": "oil" + }, + { + "code": "1f197", + "name": "ok" + }, + { + "code": "1f44c", + "name": "ok_hand" + }, + { + "code": "1f646", + "name": "ok_woman" + }, + { + "code": "1f474", + "name": "older_man" + }, + { + "code": "1f475", + "name": "older_woman" + }, + { + "code": "1f549", + "name": "om_symbol" + }, + { + "code": "1f51b", + "name": "on" + }, + { + "code": "1f698", + "name": "oncoming_automobile" + }, + { + "code": "1f68d", + "name": "oncoming_bus" + }, + { + "code": "1f694", + "name": "oncoming_police_car" + }, + { + "code": "1f696", + "name": "oncoming_taxi" + }, + { + "code": "0031-20e3", + "name": "one" + }, + { + "code": "1f4c2", + "name": "open_file_folder" + }, + { + "code": "1f450", + "name": "open_hands" + }, + { + "code": "1f62e", + "name": "open_mouth" + }, + { + "code": "26ce", + "name": "ophiuchus" + }, + { + "code": "1f4d9", + "name": "orange_book" + }, + { + "code": "2626", + "name": "orthodox_cross" + }, + { + "code": "1f4e4", + "name": "outbox_tray" + }, + { + "code": "1f402", + "name": "ox" + }, + { + "code": "1f4e6", + "name": "package" + }, + { + "code": "1f4c4", + "name": "page_facing_up" + }, + { + "code": "1f4c3", + "name": "page_with_curl" + }, + { + "code": "1f4df", + "name": "pager" + }, + { + "code": "1f58c", + "name": "paintbrush" + }, + { + "code": "1f334", + "name": "palm_tree" + }, + { + "code": "1f43c", + "name": "panda_face" + }, + { + "code": "1f4ce", + "name": "paperclip" + }, + { + "code": "1f587", + "name": "paperclips" + }, + { + "code": "1f3de", + "name": "park" + }, + { + "code": "1f17f", + "name": "parking" + }, + { + "code": "303d", + "name": "part_alternation_mark" + }, + { + "code": "26c5", + "name": "partly_sunny" + }, + { + "code": "1f6c2", + "name": "passport_control" + }, + { + "code": "23f8", + "name": "pause_button" + }, + { + "code": "262e", + "name": "peace" + }, + { + "code": "1f351", + "name": "peach" + }, + { + "code": "1f350", + "name": "pear" + }, + { + "code": "1f58a", + "name": "pen_ballpoint" + }, + { + "code": "1f58b", + "name": "pen_fountain" + }, + { + "code": "1f4dd", + "name": "pencil" + }, + { + "code": "270f", + "name": "pencil2" + }, + { + "code": "1f427", + "name": "penguin" + }, + { + "code": "1f614", + "name": "pensive" + }, + { + "code": "1f3ad", + "name": "performing_arts" + }, + { + "code": "1f623", + "name": "persevere" + }, + { + "code": "1f64d", + "name": "person_frowning" + }, + { + "code": "1f471", + "name": "person_with_blond_hair" + }, + { + "code": "1f64e", + "name": "person_with_pouting_face" + }, + { + "code": "26cf", + "name": "pick" + }, + { + "code": "1f437", + "name": "pig" + }, + { + "code": "1f416", + "name": "pig2" + }, + { + "code": "1f43d", + "name": "pig_nose" + }, + { + "code": "1f48a", + "name": "pill" + }, + { + "code": "1f34d", + "name": "pineapple" + }, + { + "code": "1f3d3", + "name": "ping_pong" + }, + { + "code": "2653", + "name": "pisces" + }, + { + "code": "1f355", + "name": "pizza" + }, + { + "code": "1f6d0", + "name": "place_of_worship" + }, + { + "code": "23ef", + "name": "play_pause" + }, + { + "code": "1f447", + "name": "point_down" + }, + { + "code": "1f448", + "name": "point_left" + }, + { + "code": "1f449", + "name": "point_right" + }, + { + "code": "261d", + "name": "point_up" + }, + { + "code": "1f446", + "name": "point_up_2" + }, + { + "code": "1f693", + "name": "police_car" + }, + { + "code": "1f429", + "name": "poodle" + }, + { + "code": "1f4a9", + "name": "poop" + }, + { + "code": "1f37f", + "name": "popcorn" + }, + { + "code": "1f3e3", + "name": "post_office" + }, + { + "code": "1f4ef", + "name": "postal_horn" + }, + { + "code": "1f4ee", + "name": "postbox" + }, + { + "code": "1f6b0", + "name": "potable_water" + }, + { + "code": "1f45d", + "name": "pouch" + }, + { + "code": "1f357", + "name": "poultry_leg" + }, + { + "code": "1f4b7", + "name": "pound" + }, + { + "code": "1f63e", + "name": "pouting_cat" + }, + { + "code": "1f64f", + "name": "pray" + }, + { + "code": "1f4ff", + "name": "prayer_beads" + }, + { + "code": "1f478", + "name": "princess" + }, + { + "code": "1f5a8", + "name": "printer" + }, + { + "code": "1f4fd", + "name": "projector" + }, + { + "code": "1f44a", + "name": "punch" + }, + { + "code": "1f49c", + "name": "purple_heart" + }, + { + "code": "1f45b", + "name": "purse" + }, + { + "code": "1f4cc", + "name": "pushpin" + }, + { + "code": "1f6ae", + "name": "put_litter_in_its_place" + }, + { + "code": "2753", + "name": "question" + }, + { + "code": "1f430", + "name": "rabbit" + }, + { + "code": "1f407", + "name": "rabbit2" + }, + { + "code": "1f3ce", + "name": "race_car" + }, + { + "code": "1f40e", + "name": "racehorse" + }, + { + "code": "1f4fb", + "name": "radio" + }, + { + "code": "1f518", + "name": "radio_button" + }, + { + "code": "2622", + "name": "radioactive" + }, + { + "code": "1f621", + "name": "rage" + }, + { + "code": "1f683", + "name": "railway_car" + }, + { + "code": "1f6e4", + "name": "railway_track" + }, + { + "code": "1f308", + "name": "rainbow" + }, + { + "code": "270b", + "name": "raised_hand" + }, + { + "code": "1f64c", + "name": "raised_hands" + }, + { + "code": "1f64b", + "name": "raising_hand" + }, + { + "code": "1f40f", + "name": "ram" + }, + { + "code": "1f35c", + "name": "ramen" + }, + { + "code": "1f400", + "name": "rat" + }, + { + "code": "23fa", + "name": "record_button" + }, + { + "code": "267b", + "name": "recycle" + }, + { + "code": "1f697", + "name": "red_car" + }, + { + "code": "1f534", + "name": "red_circle" + }, + { + "code": "00ae", + "name": "registered" + }, + { + "code": "263a", + "name": "relaxed" + }, + { + "code": "1f60c", + "name": "relieved" + }, + { + "code": "1f397", + "name": "reminder_ribbon" + }, + { + "code": "1f501", + "name": "repeat" + }, + { + "code": "1f502", + "name": "repeat_one" + }, + { + "code": "1f6bb", + "name": "restroom" + }, + { + "code": "1f49e", + "name": "revolving_hearts" + }, + { + "code": "23ea", + "name": "rewind" + }, + { + "code": "1f380", + "name": "ribbon" + }, + { + "code": "1f35a", + "name": "rice" + }, + { + "code": "1f359", + "name": "rice_ball" + }, + { + "code": "1f358", + "name": "rice_cracker" + }, + { + "code": "1f391", + "name": "rice_scene" + }, + { + "code": "1f48d", + "name": "ring" + }, + { + "code": "1f916", + "name": "robot" + }, + { + "code": "1f680", + "name": "rocket" + }, + { + "code": "1f3a2", + "name": "roller_coaster" + }, + { + "code": "1f644", + "name": "rolling_eyes" + }, + { + "code": "1f413", + "name": "rooster" + }, + { + "code": "1f339", + "name": "rose" + }, + { + "code": "1f3f5", + "name": "rosette" + }, + { + "code": "1f6a8", + "name": "rotating_light" + }, + { + "code": "1f4cd", + "name": "round_pushpin" + }, + { + "code": "1f6a3", + "name": "rowboat" + }, + { + "code": "1f3c9", + "name": "rugby_football" + }, + { + "code": "1f3c3", + "name": "runner" + }, + { + "code": "1f3bd", + "name": "running_shirt_with_sash" + }, + { + "code": "1f202", + "name": "sa" + }, + { + "code": "2650", + "name": "sagittarius" + }, + { + "code": "26f5", + "name": "sailboat" + }, + { + "code": "1f376", + "name": "sake" + }, + { + "code": "1f461", + "name": "sandal" + }, + { + "code": "1f385", + "name": "santa" + }, + { + "code": "1f4e1", + "name": "satellite" + }, + { + "code": "1f6f0", + "name": "satellite_orbital" + }, + { + "code": "1f3b7", + "name": "saxophone" + }, + { + "code": "2696", + "name": "scales" + }, + { + "code": "1f3eb", + "name": "school" + }, + { + "code": "1f392", + "name": "school_satchel" + }, + { + "code": "2702", + "name": "scissors" + }, + { + "code": "1f982", + "name": "scorpion" + }, + { + "code": "264f", + "name": "scorpius" + }, + { + "code": "1f631", + "name": "scream" + }, + { + "code": "1f640", + "name": "scream_cat" + }, + { + "code": "1f4dc", + "name": "scroll" + }, + { + "code": "1f4ba", + "name": "seat" + }, + { + "code": "3299", + "name": "secret" + }, + { + "code": "1f648", + "name": "see_no_evil" + }, + { + "code": "1f331", + "name": "seedling" + }, + { + "code": "0037-20e3", + "name": "seven" + }, + { + "code": "2618", + "name": "shamrock" + }, + { + "code": "1f367", + "name": "shaved_ice" + }, + { + "code": "1f411", + "name": "sheep" + }, + { + "code": "1f41a", + "name": "shell" + }, + { + "code": "1f6e1", + "name": "shield" + }, + { + "code": "26e9", + "name": "shinto_shrine" + }, + { + "code": "1f6a2", + "name": "ship" + }, + { + "code": "1f455", + "name": "shirt" + }, + { + "code": "1f6cd", + "name": "shopping_bags" + }, + { + "code": "1f6bf", + "name": "shower" + }, + { + "code": "1f4f6", + "name": "signal_strength" + }, + { + "code": "0036-20e3", + "name": "six" + }, + { + "code": "1f52f", + "name": "six_pointed_star" + }, + { + "code": "1f3bf", + "name": "ski" + }, + { + "code": "26f7", + "name": "skier" + }, + { + "code": "1f480", + "name": "skull" + }, + { + "code": "2620", + "name": "skull_crossbones" + }, + { + "code": "1f634", + "name": "sleeping" + }, + { + "code": "1f6cc", + "name": "sleeping_accommodation" + }, + { + "code": "1f62a", + "name": "sleepy" + }, + { + "code": "1f641", + "name": "slight_frown" + }, + { + "code": "1f642", + "name": "slight_smile" + }, + { + "code": "1f3b0", + "name": "slot_machine" + }, + { + "code": "1f539", + "name": "small_blue_diamond" + }, + { + "code": "1f538", + "name": "small_orange_diamond" + }, + { + "code": "1f53a", + "name": "small_red_triangle" + }, + { + "code": "1f53b", + "name": "small_red_triangle_down" + }, + { + "code": "1f604", + "name": "smile" + }, + { + "code": "1f638", + "name": "smile_cat" + }, + { + "code": "1f603", + "name": "smiley" + }, + { + "code": "1f63a", + "name": "smiley_cat" + }, + { + "code": "1f608", + "name": "smiling_imp" + }, + { + "code": "1f60f", + "name": "smirk" + }, + { + "code": "1f63c", + "name": "smirk_cat" + }, + { + "code": "1f6ac", + "name": "smoking" + }, + { + "code": "1f40c", + "name": "snail" + }, + { + "code": "1f40d", + "name": "snake" + }, + { + "code": "1f3c2", + "name": "snowboarder" + }, + { + "code": "2744", + "name": "snowflake" + }, + { + "code": "26c4", + "name": "snowman" + }, + { + "code": "2603", + "name": "snowman2" + }, + { + "code": "1f62d", + "name": "sob" + }, + { + "code": "26bd", + "name": "soccer" + }, + { + "code": "1f51c", + "name": "soon" + }, + { + "code": "1f198", + "name": "sos" + }, + { + "code": "1f509", + "name": "sound" + }, + { + "code": "1f47e", + "name": "space_invader" + }, + { + "code": "2660", + "name": "spades" + }, + { + "code": "1f35d", + "name": "spaghetti" + }, + { + "code": "2747", + "name": "sparkle" + }, + { + "code": "1f387", + "name": "sparkler" + }, + { + "code": "2728", + "name": "sparkles" + }, + { + "code": "1f496", + "name": "sparkling_heart" + }, + { + "code": "1f64a", + "name": "speak_no_evil" + }, + { + "code": "1f508", + "name": "speaker" + }, + { + "code": "1f5e3", + "name": "speaking_head" + }, + { + "code": "1f4ac", + "name": "speech_balloon" + }, + { + "code": "1f6a4", + "name": "speedboat" + }, + { + "code": "1f577", + "name": "spider" + }, + { + "code": "1f578", + "name": "spider_web" + }, + { + "code": "1f575", + "name": "spy" + }, + { + "code": "1f3df", + "name": "stadium" + }, + { + "code": "2b50", + "name": "star" + }, + { + "code": "1f31f", + "name": "star2" + }, + { + "code": "262a", + "name": "star_and_crescent" + }, + { + "code": "2721", + "name": "star_of_david" + }, + { + "code": "1f320", + "name": "stars" + }, + { + "code": "1f689", + "name": "station" + }, + { + "code": "1f5fd", + "name": "statue_of_liberty" + }, + { + "code": "1f682", + "name": "steam_locomotive" + }, + { + "code": "1f372", + "name": "stew" + }, + { + "code": "23f9", + "name": "stop_button" + }, + { + "code": "23f1", + "name": "stopwatch" + }, + { + "code": "1f4cf", + "name": "straight_ruler" + }, + { + "code": "1f353", + "name": "strawberry" + }, + { + "code": "1f61b", + "name": "stuck_out_tongue" + }, + { + "code": "1f61d", + "name": "stuck_out_tongue_closed_eyes" + }, + { + "code": "1f61c", + "name": "stuck_out_tongue_winking_eye" + }, + { + "code": "1f31e", + "name": "sun_with_face" + }, + { + "code": "1f33b", + "name": "sunflower" + }, + { + "code": "1f60e", + "name": "sunglasses" + }, + { + "code": "2600", + "name": "sunny" + }, + { + "code": "1f305", + "name": "sunrise" + }, + { + "code": "1f304", + "name": "sunrise_over_mountains" + }, + { + "code": "1f3c4", + "name": "surfer" + }, + { + "code": "1f363", + "name": "sushi" + }, + { + "code": "1f69f", + "name": "suspension_railway" + }, + { + "code": "1f613", + "name": "sweat" + }, + { + "code": "1f4a6", + "name": "sweat_drops" + }, + { + "code": "1f605", + "name": "sweat_smile" + }, + { + "code": "1f360", + "name": "sweet_potato" + }, + { + "code": "1f3ca", + "name": "swimmer" + }, + { + "code": "1f523", + "name": "symbols" + }, + { + "code": "1f54d", + "name": "synagogue" + }, + { + "code": "1f489", + "name": "syringe" + }, + { + "code": "1f32e", + "name": "taco" + }, + { + "code": "1f389", + "name": "tada" + }, + { + "code": "1f38b", + "name": "tanabata_tree" + }, + { + "code": "1f34a", + "name": "tangerine" + }, + { + "code": "2649", + "name": "taurus" + }, + { + "code": "1f695", + "name": "taxi" + }, + { + "code": "1f375", + "name": "tea" + }, + { + "code": "260e", + "name": "telephone" + }, + { + "code": "1f4de", + "name": "telephone_receiver" + }, + { + "code": "1f52d", + "name": "telescope" + }, + { + "code": "1f51f", + "name": "ten" + }, + { + "code": "1f3be", + "name": "tennis" + }, + { + "code": "26fa", + "name": "tent" + }, + { + "code": "1f321", + "name": "thermometer" + }, + { + "code": "1f912", + "name": "thermometer_face" + }, + { + "code": "1f914", + "name": "thinking" + }, + { + "code": "1f4ad", + "name": "thought_balloon" + }, + { + "code": "0033-20e3", + "name": "three" + }, + { + "code": "1f44e", + "name": "thumbsdown" + }, + { + "code": "1f44d", + "name": "thumbsup" + }, + { + "code": "26c8", + "name": "thunder_cloud_rain" + }, + { + "code": "1f3ab", + "name": "ticket" + }, + { + "code": "1f39f", + "name": "tickets" + }, + { + "code": "1f42f", + "name": "tiger" + }, + { + "code": "1f405", + "name": "tiger2" + }, + { + "code": "23f2", + "name": "timer" + }, + { + "code": "1f62b", + "name": "tired_face" + }, + { + "code": "2122", + "name": "tm" + }, + { + "code": "1f6bd", + "name": "toilet" + }, + { + "code": "1f5fc", + "name": "tokyo_tower" + }, + { + "code": "1f345", + "name": "tomato" + }, + { + "code": "1f445", + "name": "tongue" + }, + { + "code": "1f6e0", + "name": "tools" + }, + { + "code": "1f51d", + "name": "top" + }, + { + "code": "1f3a9", + "name": "tophat" + }, + { + "code": "23ed", + "name": "track_next" + }, + { + "code": "23ee", + "name": "track_previous" + }, + { + "code": "1f5b2", + "name": "trackball" + }, + { + "code": "1f69c", + "name": "tractor" + }, + { + "code": "1f6a5", + "name": "traffic_light" + }, + { + "code": "1f68b", + "name": "train" + }, + { + "code": "1f686", + "name": "train2" + }, + { + "code": "1f68a", + "name": "tram" + }, + { + "code": "1f6a9", + "name": "triangular_flag_on_post" + }, + { + "code": "1f4d0", + "name": "triangular_ruler" + }, + { + "code": "1f531", + "name": "trident" + }, + { + "code": "1f624", + "name": "triumph" + }, + { + "code": "1f68e", + "name": "trolleybus" + }, + { + "code": "1f3c6", + "name": "trophy" + }, + { + "code": "1f379", + "name": "tropical_drink" + }, + { + "code": "1f420", + "name": "tropical_fish" + }, + { + "code": "1f69a", + "name": "truck" + }, + { + "code": "1f3ba", + "name": "trumpet" + }, + { + "code": "1f337", + "name": "tulip" + }, + { + "code": "1f983", + "name": "turkey" + }, + { + "code": "1f422", + "name": "turtle" + }, + { + "code": "1f4fa", + "name": "tv" + }, + { + "code": "1f500", + "name": "twisted_rightwards_arrows" + }, + { + "code": "0032-20e3", + "name": "two" + }, + { + "code": "1f495", + "name": "two_hearts" + }, + { + "code": "1f46c", + "name": "two_men_holding_hands" + }, + { + "code": "1f46d", + "name": "two_women_holding_hands" + }, + { + "code": "1f239", + "name": "u5272" + }, + { + "code": "1f234", + "name": "u5408" + }, + { + "code": "1f23a", + "name": "u55b6" + }, + { + "code": "1f22f", + "name": "u6307" + }, + { + "code": "1f237", + "name": "u6708" + }, + { + "code": "1f236", + "name": "u6709" + }, + { + "code": "1f235", + "name": "u6e80" + }, + { + "code": "1f21a", + "name": "u7121" + }, + { + "code": "1f238", + "name": "u7533" + }, + { + "code": "1f232", + "name": "u7981" + }, + { + "code": "1f233", + "name": "u7a7a" + }, + { + "code": "2614", + "name": "umbrella" + }, + { + "code": "2602", + "name": "umbrella2" + }, + { + "code": "1f612", + "name": "unamused" + }, + { + "code": "1f51e", + "name": "underage" + }, + { + "code": "1f984", + "name": "unicorn" + }, + { + "code": "1f513", + "name": "unlock" + }, + { + "code": "1f199", + "name": "up" + }, + { + "code": "1f643", + "name": "upside_down" + }, + { + "code": "26b1", + "name": "urn" + }, + { + "code": "270c", + "name": "v" + }, + { + "code": "1f6a6", + "name": "vertical_traffic_light" + }, + { + "code": "1f4fc", + "name": "vhs" + }, + { + "code": "1f4f3", + "name": "vibration_mode" + }, + { + "code": "1f4f9", + "name": "video_camera" + }, + { + "code": "1f3ae", + "name": "video_game" + }, + { + "code": "1f3bb", + "name": "violin" + }, + { + "code": "264d", + "name": "virgo" + }, + { + "code": "1f30b", + "name": "volcano" + }, + { + "code": "1f3d0", + "name": "volleyball" + }, + { + "code": "1f19a", + "name": "vs" + }, + { + "code": "1f596", + "name": "vulcan" + }, + { + "code": "1f6b6", + "name": "walking" + }, + { + "code": "1f318", + "name": "waning_crescent_moon" + }, + { + "code": "1f316", + "name": "waning_gibbous_moon" + }, + { + "code": "26a0", + "name": "warning" + }, + { + "code": "1f5d1", + "name": "wastebasket" + }, + { + "code": "231a", + "name": "watch" + }, + { + "code": "1f403", + "name": "water_buffalo" + }, + { + "code": "1f349", + "name": "watermelon" + }, + { + "code": "1f44b", + "name": "wave" + }, + { + "code": "3030", + "name": "wavy_dash" + }, + { + "code": "1f312", + "name": "waxing_crescent_moon" + }, + { + "code": "1f314", + "name": "waxing_gibbous_moon" + }, + { + "code": "1f6be", + "name": "wc" + }, + { + "code": "1f629", + "name": "weary" + }, + { + "code": "1f492", + "name": "wedding" + }, + { + "code": "1f433", + "name": "whale" + }, + { + "code": "1f40b", + "name": "whale2" + }, + { + "code": "2638", + "name": "wheel_of_dharma" + }, + { + "code": "267f", + "name": "wheelchair" + }, + { + "code": "2705", + "name": "white_check_mark" + }, + { + "code": "26aa", + "name": "white_circle" + }, + { + "code": "1f4ae", + "name": "white_flower" + }, + { + "code": "2b1c", + "name": "white_large_square" + }, + { + "code": "25fd", + "name": "white_medium_small_square" + }, + { + "code": "25fb", + "name": "white_medium_square" + }, + { + "code": "25ab", + "name": "white_small_square" + }, + { + "code": "1f533", + "name": "white_square_button" + }, + { + "code": "1f325", + "name": "white_sun_cloud" + }, + { + "code": "1f326", + "name": "white_sun_rain_cloud" + }, + { + "code": "1f324", + "name": "white_sun_small_cloud" + }, + { + "code": "1f32c", + "name": "wind_blowing_face" + }, + { + "code": "1f390", + "name": "wind_chime" + }, + { + "code": "1f377", + "name": "wine_glass" + }, + { + "code": "1f609", + "name": "wink" + }, + { + "code": "1f43a", + "name": "wolf" + }, + { + "code": "1f469", + "name": "woman" + }, + { + "code": "1f45a", + "name": "womans_clothes" + }, + { + "code": "1f452", + "name": "womans_hat" + }, + { + "code": "1f6ba", + "name": "womens" + }, + { + "code": "1f61f", + "name": "worried" + }, + { + "code": "1f527", + "name": "wrench" + }, + { + "code": "270d", + "name": "writing_hand" + }, + { + "code": "274c", + "name": "x" + }, + { + "code": "1f49b", + "name": "yellow_heart" + }, + { + "code": "1f4b4", + "name": "yen" + }, + { + "code": "262f", + "name": "yin_yang" + }, + { + "code": "1f60b", + "name": "yum" + }, + { + "code": "26a1", + "name": "zap" + }, + { + "code": "0030-20e3", + "name": "zero" + }, + { + "code": "1f910", + "name": "zipper_mouth" + }, + { + "code": "1f4a4", + "name": "zzz" + } + ], + "aliases": { + "airplane_small": [ + "small_airplane" + ], + "anger_right": [ + "right_anger_bubble" + ], + "atom": [ + "atom_symbol" + ], + "ballot_box": [ + "ballot_box_with_ballot" + ], + "basketball_player": [ + "person_with_ball" + ], + "beach": [ + "beach_with_umbrella" + ], + "beach_umbrella": [ + "umbrella_on_ground" + ], + "bellhop": [ + "bellhop_bell" + ], + "biohazard": [ + "biohazard_sign" + ], + "bow_and_arrow": [ + "archery" + ], + "calendar_spiral": [ + "spiral_calendar_pad" + ], + "card_box": [ + "card_file_box" + ], + "champagne": [ + "bottle_with_popping_cork" + ], + "cheese": [ + "cheese_wedge" + ], + "city_sunset": [ "city_sunrise" - ] - , "tags": [ - ] - } -, { - "emoji": "🌆" - , "description": "cityscape at dusk" - , "aliases": [ - "city_sunset" - ] - , "tags": [ - ] - } -, { - "emoji": "🏯" - , "description": "japanese castle" - , "aliases": [ - "japanese_castle" - ] - , "tags": [ - ] - } -, { - "emoji": "🏰" - , "description": "european castle" - , "aliases": [ - "european_castle" - ] - , "tags": [ - ] - } -, { - "emoji": "⛺" - , "description": "tent" - , "aliases": [ - "tent" - ] - , "tags": [ - "camping" - ] - } -, { - "emoji": "🏭" - , "description": "factory" - , "aliases": [ - "factory" - ] - , "tags": [ - ] - } -, { - "emoji": "🗼" - , "description": "tokyo tower" - , "aliases": [ - "tokyo_tower" - ] - , "tags": [ - ] - } -, { - "emoji": "🗾" - , "description": "silhouette of japan" - , "aliases": [ - "japan" - ] - , "tags": [ - ] - } -, { - "emoji": "🗻" - , "description": "mount fuji" - , "aliases": [ - "mount_fuji" - ] - , "tags": [ - ] - } -, { - "emoji": "🌄" - , "description": "sunrise over mountains" - , "aliases": [ - "sunrise_over_mountains" - ] - , "tags": [ - ] - } -, { - "emoji": "🌅" - , "description": "sunrise" - , "aliases": [ - "sunrise" - ] - , "tags": [ - ] - } -, { - "emoji": "🌃" - , "description": "night with stars" - , "aliases": [ - "night_with_stars" - ] - , "tags": [ - ] - } -, { - "emoji": "🗽" - , "description": "statue of liberty" - , "aliases": [ - "statue_of_liberty" - ] - , "tags": [ - ] - } -, { - "emoji": "🌉" - , "description": "bridge at night" - , "aliases": [ - "bridge_at_night" - ] - , "tags": [ - ] - } -, { - "emoji": "🎠" - , "description": "carousel horse" - , "aliases": [ - "carousel_horse" - ] - , "tags": [ - ] - } -, { - "emoji": "🎡" - , "description": "ferris wheel" - , "aliases": [ - "ferris_wheel" - ] - , "tags": [ - ] - } -, { - "emoji": "⛲" - , "description": "fountain" - , "aliases": [ - "fountain" - ] - , "tags": [ - ] - } -, { - "emoji": "🎢" - , "description": "roller coaster" - , "aliases": [ - "roller_coaster" - ] - , "tags": [ - ] - } -, { - "emoji": "🚢" - , "description": "ship" - , "aliases": [ - "ship" - ] - , "tags": [ - ] - } -, { - "emoji": "⛵" - , "description": "sailboat" - , "aliases": [ - "boat" - , "sailboat" - ] - , "tags": [ - ] - } -, { - "emoji": "🚤" - , "description": "speedboat" - , "aliases": [ - "speedboat" - ] - , "tags": [ - "ship" - ] - } -, { - "emoji": "🚣" - , "description": "rowboat" - , "aliases": [ - "rowboat" - ] - , "tags": [ - ] - } -, { - "emoji": "⚓" - , "description": "anchor" - , "aliases": [ - "anchor" - ] - , "tags": [ - "ship" - ] - } -, { - "emoji": "🚀" - , "description": "rocket" - , "aliases": [ - "rocket" - ] - , "tags": [ - "ship" - , "launch" - ] - } -, { - "emoji": "✈️" - , "description": "airplane" - , "aliases": [ - "airplane" - ] - , "tags": [ - "flight" - ] - } -, { - "emoji": "💺" - , "description": "seat" - , "aliases": [ - "seat" - ] - , "tags": [ - ] - } -, { - "emoji": "🚁" - , "description": "helicopter" - , "aliases": [ - "helicopter" - ] - , "tags": [ - ] - } -, { - "emoji": "🚂" - , "description": "steam locomotive" - , "aliases": [ - "steam_locomotive" - ] - , "tags": [ - "train" - ] - } -, { - "emoji": "🚊" - , "description": "tram" - , "aliases": [ - "tram" - ] - , "tags": [ - ] - } -, { - "emoji": "🚉" - , "description": "station" - , "aliases": [ - "station" - ] - , "tags": [ - ] - } -, { - "emoji": "🚞" - , "description": "mountain railway" - , "aliases": [ - "mountain_railway" - ] - , "tags": [ - ] - } -, { - "emoji": "🚆" - , "description": "train" - , "aliases": [ - "train2" - ] - , "tags": [ - ] - } -, { - "emoji": "🚄" - , "description": "high-speed train" - , "aliases": [ - "bullettrain_side" - ] - , "tags": [ - "train" - ] - } -, { - "emoji": "🚅" - , "description": "high-speed train with bullet nose" - , "aliases": [ - "bullettrain_front" - ] - , "tags": [ - "train" - ] - } -, { - "emoji": "🚈" - , "description": "light rail" - , "aliases": [ - "light_rail" - ] - , "tags": [ - ] - } -, { - "emoji": "🚇" - , "description": "metro" - , "aliases": [ - "metro" - ] - , "tags": [ - ] - } -, { - "emoji": "🚝" - , "description": "monorail" - , "aliases": [ - "monorail" - ] - , "tags": [ - ] - } -, { - "emoji": "🚋" - , "description": "tram car" - , "aliases": [ - "train" - ] - , "tags": [ - ] - } -, { - "emoji": "🚃" - , "description": "railway car" - , "aliases": [ - "railway_car" - ] - , "tags": [ - ] - } -, { - "emoji": "🚎" - , "description": "trolleybus" - , "aliases": [ - "trolleybus" - ] - , "tags": [ - ] - } -, { - "emoji": "🚌" - , "description": "bus" - , "aliases": [ - "bus" - ] - , "tags": [ - ] - } -, { - "emoji": "🚍" - , "description": "oncoming bus" - , "aliases": [ - "oncoming_bus" - ] - , "tags": [ - ] - } -, { - "emoji": "🚙" - , "description": "recreational vehicle" - , "aliases": [ - "blue_car" - ] - , "tags": [ - ] - } -, { - "emoji": "🚘" - , "description": "oncoming automobile" - , "aliases": [ - "oncoming_automobile" - ] - , "tags": [ - ] - } -, { - "emoji": "🚗" - , "description": "automobile" - , "aliases": [ - "car" - , "red_car" - ] - , "tags": [ - ] - } -, { - "emoji": "🚕" - , "description": "taxi" - , "aliases": [ - "taxi" - ] - , "tags": [ - ] - } -, { - "emoji": "🚖" - , "description": "oncoming taxi" - , "aliases": [ - "oncoming_taxi" - ] - , "tags": [ - ] - } -, { - "emoji": "🚛" - , "description": "articulated lorry" - , "aliases": [ - "articulated_lorry" - ] - , "tags": [ - ] - } -, { - "emoji": "🚚" - , "description": "delivery truck" - , "aliases": [ - "truck" - ] - , "tags": [ - ] - } -, { - "emoji": "🚨" - , "description": "police cars revolving light" - , "aliases": [ - "rotating_light" - ] - , "tags": [ - "911" - , "emergency" - ] - } -, { - "emoji": "🚓" - , "description": "police car" - , "aliases": [ - "police_car" - ] - , "tags": [ - ] - } -, { - "emoji": "🚔" - , "description": "oncoming police car" - , "aliases": [ - "oncoming_police_car" - ] - , "tags": [ - ] - } -, { - "emoji": "🚒" - , "description": "fire engine" - , "aliases": [ - "fire_engine" - ] - , "tags": [ - ] - } -, { - "emoji": "🚑" - , "description": "ambulance" - , "aliases": [ - "ambulance" - ] - , "tags": [ - ] - } -, { - "emoji": "🚐" - , "description": "minibus" - , "aliases": [ - "minibus" - ] - , "tags": [ - ] - } -, { - "emoji": "🚲" - , "description": "bicycle" - , "aliases": [ - "bike" - ] - , "tags": [ - "bicycle" - ] - } -, { - "emoji": "🚡" - , "description": "aerial tramway" - , "aliases": [ - "aerial_tramway" - ] - , "tags": [ - ] - } -, { - "emoji": "🚟" - , "description": "suspension railway" - , "aliases": [ - "suspension_railway" - ] - , "tags": [ - ] - } -, { - "emoji": "🚠" - , "description": "mountain cableway" - , "aliases": [ - "mountain_cableway" - ] - , "tags": [ - ] - } -, { - "emoji": "🚜" - , "description": "tractor" - , "aliases": [ - "tractor" - ] - , "tags": [ - ] - } -, { - "emoji": "💈" - , "description": "barber pole" - , "aliases": [ - "barber" - ] - , "tags": [ - ] - } -, { - "emoji": "🚏" - , "description": "bus stop" - , "aliases": [ - "busstop" - ] - , "tags": [ - ] - } -, { - "emoji": "🎫" - , "description": "ticket" - , "aliases": [ - "ticket" - ] - , "tags": [ - ] - } -, { - "emoji": "🚦" - , "description": "vertical traffic light" - , "aliases": [ - "vertical_traffic_light" - ] - , "tags": [ - "semaphore" - ] - } -, { - "emoji": "🚥" - , "description": "horizontal traffic light" - , "aliases": [ - "traffic_light" - ] - , "tags": [ - ] - } -, { - "emoji": "⚠️" - , "description": "warning sign" - , "aliases": [ - "warning" - ] - , "tags": [ - "wip" - ] - } -, { - "emoji": "🚧" - , "description": "construction sign" - , "aliases": [ - "construction" - ] - , "tags": [ - "wip" - ] - } -, { - "emoji": "🔰" - , "description": "japanese symbol for beginner" - , "aliases": [ - "beginner" - ] - , "tags": [ - ] - } -, { - "emoji": "⛽" - , "description": "fuel pump" - , "aliases": [ - "fuelpump" - ] - , "tags": [ - ] - } -, { - "emoji": "🏮" - , "description": "izakaya lantern" - , "aliases": [ - "izakaya_lantern" - , "lantern" - ] - , "tags": [ - ] - } -, { - "emoji": "🎰" - , "description": "slot machine" - , "aliases": [ - "slot_machine" - ] - , "tags": [ - ] - } -, { - "emoji": "♨️" - , "description": "hot springs" - , "aliases": [ - "hotsprings" - ] - , "tags": [ - ] - } -, { - "emoji": "🗿" - , "description": "moyai" - , "aliases": [ - "moyai" - ] - , "tags": [ - "stone" - ] - } -, { - "emoji": "🎪" - , "description": "circus tent" - , "aliases": [ - "circus_tent" - ] - , "tags": [ - ] - } -, { - "emoji": "🎭" - , "description": "performing arts" - , "aliases": [ - "performing_arts" - ] - , "tags": [ - "theater" - , "drama" - ] - } -, { - "emoji": "📍" - , "description": "round pushpin" - , "aliases": [ - "round_pushpin" - ] - , "tags": [ - "location" - ] - } -, { - "emoji": "🚩" - , "description": "triangular flag on post" - , "aliases": [ - "triangular_flag_on_post" - ] - , "tags": [ - ] - } -, { - "emoji": "🇯🇵" - , "description": "regional indicator symbol letter j + regional indicator symbol letter p" - , "aliases": [ - "jp" - ] - , "tags": [ - "japan" - ] - } -, { - "emoji": "🇰🇷" - , "description": "regional indicator symbol letter k + regional indicator symbol letter r" - , "aliases": [ - "kr" - ] - , "tags": [ - "korea" - ] - } -, { - "emoji": "🇩🇪" - , "description": "regional indicator symbol letter d + regional indicator symbol letter e" - , "aliases": [ - "de" - ] - , "tags": [ - "flag" - , "germany" - ] - } -, { - "emoji": "🇨🇳" - , "description": "regional indicator symbol letter c + regional indicator symbol letter n" - , "aliases": [ + ], + "clock": [ + "mantlepiece_clock" + ], + "cloud_lightning": [ + "cloud_with_lightning" + ], + "cloud_rain": [ + "cloud_with_rain" + ], + "cloud_snow": [ + "cloud_with_snow" + ], + "cloud_tornado": [ + "cloud_with_tornado" + ], + "construction_site": [ + "building_construction" + ], + "couch": [ + "couch_and_lamp" + ], + "crayon": [ + "lower_left_crayon" + ], + "cricket": [ + "cricket_bat_ball" + ], + "cross": [ + "latin_cross" + ], + "cruise_ship": [ + "passenger_ship" + ], + "dagger": [ + "dagger_knife" + ], + "desktop": [ + "desktop_computer" + ], + "dividers": [ + "card_index_dividers" + ], + "dove": [ + "dove_of_peace" + ], + "e-mail": [ + "email" + ], + "feet": [ + "paw_prints" + ], + "fire": [ + "flame" + ], + "flag_black": [ + "waving_black_flag" + ], + "flag_cn": [ "cn" - ] - , "tags": [ - "china" - ] - } -, { - "emoji": "🇺🇸" - , "description": "regional indicator symbol letter u + regional indicator symbol letter s" - , "aliases": [ - "us" - ] - , "tags": [ - "flag" - , "united" - , "america" - ] - } -, { - "emoji": "🇫🇷" - , "description": "regional indicator symbol letter f + regional indicator symbol letter r" - , "aliases": [ - "fr" - ] - , "tags": [ - "france" - , "french" - ] - } -, { - "emoji": "🇪🇸" - , "description": "regional indicator symbol letter e + regional indicator symbol letter s" - , "aliases": [ + ], + "flag_de": [ + "de" + ], + "flag_es": [ "es" - ] - , "tags": [ - "spain" - ] - } -, { - "emoji": "🇮🇹" - , "description": "regional indicator symbol letter i + regional indicator symbol letter t" - , "aliases": [ - "it" - ] - , "tags": [ - "italy" - ] - } -, { - "emoji": "🇷🇺" - , "description": "regional indicator symbol letter r + regional indicator symbol letter u" - , "aliases": [ - "ru" - ] - , "tags": [ - "russia" - ] - } -, { - "emoji": "🇬🇧" - , "description": "regional indicator symbol letter g + regional indicator symbol letter b" - , "aliases": [ + ], + "flag_fr": [ + "fr" + ], + "flag_gb": [ "gb" - , "uk" - ] - , "tags": [ - "flag" - , "british" - ] - } -, { - "emoji": "1️⃣" - , "description": "digit one + combining enclosing keycap" - , "aliases": [ - "one" - ] - , "tags": [ - ] - } -, { - "emoji": "2️⃣" - , "description": "digit two + combining enclosing keycap" - , "aliases": [ - "two" - ] - , "tags": [ - ] - } -, { - "emoji": "3️⃣" - , "description": "digit three + combining enclosing keycap" - , "aliases": [ - "three" - ] - , "tags": [ - ] - } -, { - "emoji": "4️⃣" - , "description": "digit four + combining enclosing keycap" - , "aliases": [ - "four" - ] - , "tags": [ - ] - } -, { - "emoji": "5️⃣" - , "description": "digit five + combining enclosing keycap" - , "aliases": [ - "five" - ] - , "tags": [ - ] - } -, { - "emoji": "6️⃣" - , "description": "digit six + combining enclosing keycap" - , "aliases": [ - "six" - ] - , "tags": [ - ] - } -, { - "emoji": "7️⃣" - , "description": "digit seven + combining enclosing keycap" - , "aliases": [ - "seven" - ] - , "tags": [ - ] - } -, { - "emoji": "8️⃣" - , "description": "digit eight + combining enclosing keycap" - , "aliases": [ - "eight" - ] - , "tags": [ - ] - } -, { - "emoji": "9️⃣" - , "description": "digit nine + combining enclosing keycap" - , "aliases": [ - "nine" - ] - , "tags": [ - ] - } -, { - "emoji": "0️⃣" - , "description": "digit zero + combining enclosing keycap" - , "aliases": [ - "zero" - ] - , "tags": [ - ] - } -, { - "emoji": "🔟" - , "description": "keycap ten" - , "aliases": [ - "keycap_ten" - ] - , "tags": [ - ] - } -, { - "emoji": "🔢" - , "description": "input symbol for numbers" - , "aliases": [ - "1234" - ] - , "tags": [ - "numbers" - ] - } -, { - "emoji": "#️⃣" - , "description": "number sign + combining enclosing keycap" - , "aliases": [ - "hash" - ] - , "tags": [ - "number" - ] - } -, { - "emoji": "🔣" - , "description": "input symbol for symbols" - , "aliases": [ - "symbols" - ] - , "tags": [ - ] - } -, { - "emoji": "⬆️" - , "description": "upwards black arrow" - , "aliases": [ - "arrow_up" - ] - , "tags": [ - ] - } -, { - "emoji": "⬇️" - , "description": "downwards black arrow" - , "aliases": [ - "arrow_down" - ] - , "tags": [ - ] - } -, { - "emoji": "⬅️" - , "description": "leftwards black arrow" - , "aliases": [ - "arrow_left" - ] - , "tags": [ - ] - } -, { - "emoji": "➡️" - , "description": "black rightwards arrow" - , "aliases": [ - "arrow_right" - ] - , "tags": [ - ] - } -, { - "emoji": "🔠" - , "description": "input symbol for latin capital letters" - , "aliases": [ - "capital_abcd" - ] - , "tags": [ - "letters" - ] - } -, { - "emoji": "🔡" - , "description": "input symbol for latin small letters" - , "aliases": [ - "abcd" - ] - , "tags": [ - ] - } -, { - "emoji": "🔤" - , "description": "input symbol for latin letters" - , "aliases": [ - "abc" - ] - , "tags": [ - "alphabet" - ] - } -, { - "emoji": "↗️" - , "description": "north east arrow" - , "aliases": [ - "arrow_upper_right" - ] - , "tags": [ - ] - } -, { - "emoji": "↖️" - , "description": "north west arrow" - , "aliases": [ - "arrow_upper_left" - ] - , "tags": [ - ] - } -, { - "emoji": "↘️" - , "description": "south east arrow" - , "aliases": [ - "arrow_lower_right" - ] - , "tags": [ - ] - } -, { - "emoji": "↙️" - , "description": "south west arrow" - , "aliases": [ - "arrow_lower_left" - ] - , "tags": [ - ] - } -, { - "emoji": "↔️" - , "description": "left right arrow" - , "aliases": [ - "left_right_arrow" - ] - , "tags": [ - ] - } -, { - "emoji": "↕️" - , "description": "up down arrow" - , "aliases": [ - "arrow_up_down" - ] - , "tags": [ - ] - } -, { - "emoji": "🔄" - , "description": "anticlockwise downwards and upwards open circle arrows" - , "aliases": [ - "arrows_counterclockwise" - ] - , "tags": [ - "sync" - ] - } -, { - "emoji": "◀️" - , "description": "black left-pointing triangle" - , "aliases": [ - "arrow_backward" - ] - , "tags": [ - ] - } -, { - "emoji": "▶️" - , "description": "black right-pointing triangle" - , "aliases": [ - "arrow_forward" - ] - , "tags": [ - ] - } -, { - "emoji": "🔼" - , "description": "up-pointing small red triangle" - , "aliases": [ - "arrow_up_small" - ] - , "tags": [ - ] - } -, { - "emoji": "🔽" - , "description": "down-pointing small red triangle" - , "aliases": [ - "arrow_down_small" - ] - , "tags": [ - ] - } -, { - "emoji": "↩️" - , "description": "leftwards arrow with hook" - , "aliases": [ - "leftwards_arrow_with_hook" - ] - , "tags": [ - "return" - ] - } -, { - "emoji": "↪️" - , "description": "rightwards arrow with hook" - , "aliases": [ - "arrow_right_hook" - ] - , "tags": [ - ] - } -, { - "emoji": "ℹ️" - , "description": "information source" - , "aliases": [ - "information_source" - ] - , "tags": [ - ] - } -, { - "emoji": "⏪" - , "description": "black left-pointing double triangle" - , "aliases": [ - "rewind" - ] - , "tags": [ - ] - } -, { - "emoji": "⏩" - , "description": "black right-pointing double triangle" - , "aliases": [ - "fast_forward" - ] - , "tags": [ - ] - } -, { - "emoji": "⏫" - , "description": "black up-pointing double triangle" - , "aliases": [ - "arrow_double_up" - ] - , "tags": [ - ] - } -, { - "emoji": "⏬" - , "description": "black down-pointing double triangle" - , "aliases": [ - "arrow_double_down" - ] - , "tags": [ - ] - } -, { - "emoji": "⤵️" - , "description": "arrow pointing rightwards then curving downwards" - , "aliases": [ - "arrow_heading_down" - ] - , "tags": [ - ] - } -, { - "emoji": "⤴️" - , "description": "arrow pointing rightwards then curving upwards" - , "aliases": [ - "arrow_heading_up" - ] - , "tags": [ - ] - } -, { - "emoji": "🆗" - , "description": "squared ok" - , "aliases": [ - "ok" - ] - , "tags": [ - "yes" - ] - } -, { - "emoji": "🔀" - , "description": "twisted rightwards arrows" - , "aliases": [ - "twisted_rightwards_arrows" - ] - , "tags": [ - "shuffle" - ] - } -, { - "emoji": "🔁" - , "description": "clockwise rightwards and leftwards open circle arrows" - , "aliases": [ - "repeat" - ] - , "tags": [ - "loop" - ] - } -, { - "emoji": "🔂" - , "description": "clockwise rightwards and leftwards open circle arrows with circled one overlay" - , "aliases": [ - "repeat_one" - ] - , "tags": [ - ] - } -, { - "emoji": "🆕" - , "description": "squared new" - , "aliases": [ - "new" - ] - , "tags": [ - "fresh" - ] - } -, { - "emoji": "🆙" - , "description": "squared up with exclamation mark" - , "aliases": [ - "up" - ] - , "tags": [ - ] - } -, { - "emoji": "🆒" - , "description": "squared cool" - , "aliases": [ - "cool" - ] - , "tags": [ - ] - } -, { - "emoji": "🆓" - , "description": "squared free" - , "aliases": [ - "free" - ] - , "tags": [ - ] - } -, { - "emoji": "🆖" - , "description": "squared ng" - , "aliases": [ - "ng" - ] - , "tags": [ - ] - } -, { - "emoji": "📶" - , "description": "antenna with bars" - , "aliases": [ - "signal_strength" - ] - , "tags": [ - "wifi" - ] - } -, { - "emoji": "🎦" - , "description": "cinema" - , "aliases": [ - "cinema" - ] - , "tags": [ - "film" - , "movie" - ] - } -, { - "emoji": "🈁" - , "description": "squared katakana koko" - , "aliases": [ - "koko" - ] - , "tags": [ - ] - } -, { - "emoji": "🈯" - , "description": "squared cjk unified ideograph-6307" - , "aliases": [ - "u6307" - ] - , "tags": [ - ] - } -, { - "emoji": "🈳" - , "description": "squared cjk unified ideograph-7a7a" - , "aliases": [ - "u7a7a" - ] - , "tags": [ - ] - } -, { - "emoji": "🈵" - , "description": "squared cjk unified ideograph-6e80" - , "aliases": [ - "u6e80" - ] - , "tags": [ - ] - } -, { - "emoji": "🈴" - , "description": "squared cjk unified ideograph-5408" - , "aliases": [ - "u5408" - ] - , "tags": [ - ] - } -, { - "emoji": "🈲" - , "description": "squared cjk unified ideograph-7981" - , "aliases": [ - "u7981" - ] - , "tags": [ - ] - } -, { - "emoji": "🉐" - , "description": "circled ideograph advantage" - , "aliases": [ - "ideograph_advantage" - ] - , "tags": [ - ] - } -, { - "emoji": "🈹" - , "description": "squared cjk unified ideograph-5272" - , "aliases": [ - "u5272" - ] - , "tags": [ - ] - } -, { - "emoji": "🈺" - , "description": "squared cjk unified ideograph-55b6" - , "aliases": [ - "u55b6" - ] - , "tags": [ - ] - } -, { - "emoji": "🈶" - , "description": "squared cjk unified ideograph-6709" - , "aliases": [ - "u6709" - ] - , "tags": [ - ] - } -, { - "emoji": "🈚" - , "description": "squared cjk unified ideograph-7121" - , "aliases": [ - "u7121" - ] - , "tags": [ - ] - } -, { - "emoji": "🚻" - , "description": "restroom" - , "aliases": [ - "restroom" - ] - , "tags": [ - "toilet" - ] - } -, { - "emoji": "🚹" - , "description": "mens symbol" - , "aliases": [ - "mens" - ] - , "tags": [ - ] - } -, { - "emoji": "🚺" - , "description": "womens symbol" - , "aliases": [ - "womens" - ] - , "tags": [ - ] - } -, { - "emoji": "🚼" - , "description": "baby symbol" - , "aliases": [ - "baby_symbol" - ] - , "tags": [ - ] - } -, { - "emoji": "🚾" - , "description": "water closet" - , "aliases": [ - "wc" - ] - , "tags": [ - "toilet" - , "restroom" - ] - } -, { - "emoji": "🚰" - , "description": "potable water symbol" - , "aliases": [ - "potable_water" - ] - , "tags": [ - ] - } -, { - "emoji": "🚮" - , "description": "put litter in its place symbol" - , "aliases": [ - "put_litter_in_its_place" - ] - , "tags": [ - ] - } -, { - "emoji": "🅿️" - , "description": "negative squared latin capital letter p" - , "aliases": [ - "parking" - ] - , "tags": [ - ] - } -, { - "emoji": "♿" - , "description": "wheelchair symbol" - , "aliases": [ - "wheelchair" - ] - , "tags": [ - "accessibility" - ] - } -, { - "emoji": "🚭" - , "description": "no smoking symbol" - , "aliases": [ - "no_smoking" - ] - , "tags": [ - ] - } -, { - "emoji": "🈷️" - , "description": "squared cjk unified ideograph-6708" - , "aliases": [ - "u6708" - ] - , "tags": [ - ] - } -, { - "emoji": "🈸" - , "description": "squared cjk unified ideograph-7533" - , "aliases": [ - "u7533" - ] - , "tags": [ - ] - } -, { - "emoji": "🈂️" - , "description": "squared katakana sa" - , "aliases": [ - "sa" - ] - , "tags": [ - ] - } -, { - "emoji": "Ⓜ️" - , "description": "circled latin capital letter m" - , "aliases": [ - "m" - ] - , "tags": [ - ] - } -, { - "emoji": "🛂" - , "description": "passport control" - , "aliases": [ - "passport_control" - ] - , "tags": [ - ] - } -, { - "emoji": "🛄" - , "description": "baggage claim" - , "aliases": [ - "baggage_claim" - ] - , "tags": [ - "airport" - ] - } -, { - "emoji": "🛅" - , "description": "left luggage" - , "aliases": [ - "left_luggage" - ] - , "tags": [ - ] - } -, { - "emoji": "🛃" - , "description": "customs" - , "aliases": [ - "customs" - ] - , "tags": [ - ] - } -, { - "emoji": "🉑" - , "description": "circled ideograph accept" - , "aliases": [ - "accept" - ] - , "tags": [ - ] - } -, { - "emoji": "㊙️" - , "description": "circled ideograph secret" - , "aliases": [ - "secret" - ] - , "tags": [ - ] - } -, { - "emoji": "㊗️" - , "description": "circled ideograph congratulation" - , "aliases": [ - "congratulations" - ] - , "tags": [ - ] - } -, { - "emoji": "🆑" - , "description": "squared cl" - , "aliases": [ - "cl" - ] - , "tags": [ - ] - } -, { - "emoji": "🆘" - , "description": "squared sos" - , "aliases": [ - "sos" - ] - , "tags": [ - "help" - , "emergency" - ] - } -, { - "emoji": "🆔" - , "description": "squared id" - , "aliases": [ - "id" - ] - , "tags": [ - ] - } -, { - "emoji": "🚫" - , "description": "no entry sign" - , "aliases": [ - "no_entry_sign" - ] - , "tags": [ - "block" - , "forbidden" - ] - } -, { - "emoji": "🔞" - , "description": "no one under eighteen symbol" - , "aliases": [ - "underage" - ] - , "tags": [ - ] - } -, { - "emoji": "📵" - , "description": "no mobile phones" - , "aliases": [ - "no_mobile_phones" - ] - , "tags": [ - ] - } -, { - "emoji": "🚯" - , "description": "do not litter symbol" - , "aliases": [ - "do_not_litter" - ] - , "tags": [ - ] - } -, { - "emoji": "🚱" - , "description": "non-potable water symbol" - , "aliases": [ - "non-potable_water" - ] - , "tags": [ - ] - } -, { - "emoji": "🚳" - , "description": "no bicycles" - , "aliases": [ - "no_bicycles" - ] - , "tags": [ - ] - } -, { - "emoji": "🚷" - , "description": "no pedestrians" - , "aliases": [ - "no_pedestrians" - ] - , "tags": [ - ] - } -, { - "emoji": "🚸" - , "description": "children crossing" - , "aliases": [ - "children_crossing" - ] - , "tags": [ - ] - } -, { - "emoji": "⛔" - , "description": "no entry" - , "aliases": [ - "no_entry" - ] - , "tags": [ - "limit" - ] - } -, { - "emoji": "✳️" - , "description": "eight spoked asterisk" - , "aliases": [ - "eight_spoked_asterisk" - ] - , "tags": [ - ] - } -, { - "emoji": "❇️" - , "description": "sparkle" - , "aliases": [ - "sparkle" - ] - , "tags": [ - ] - } -, { - "emoji": "❎" - , "description": "negative squared cross mark" - , "aliases": [ - "negative_squared_cross_mark" - ] - , "tags": [ - ] - } -, { - "emoji": "✅" - , "description": "white heavy check mark" - , "aliases": [ - "white_check_mark" - ] - , "tags": [ - ] - } -, { - "emoji": "✴️" - , "description": "eight pointed black star" - , "aliases": [ - "eight_pointed_black_star" - ] - , "tags": [ - ] - } -, { - "emoji": "💟" - , "description": "heart decoration" - , "aliases": [ - "heart_decoration" - ] - , "tags": [ - ] - } -, { - "emoji": "🆚" - , "description": "squared vs" - , "aliases": [ - "vs" - ] - , "tags": [ - ] - } -, { - "emoji": "📳" - , "description": "vibration mode" - , "aliases": [ - "vibration_mode" - ] - , "tags": [ - ] - } -, { - "emoji": "📴" - , "description": "mobile phone off" - , "aliases": [ - "mobile_phone_off" - ] - , "tags": [ - "mute" - , "off" - ] - } -, { - "emoji": "🅰️" - , "description": "negative squared latin capital letter a" - , "aliases": [ - "a" - ] - , "tags": [ - ] - } -, { - "emoji": "🅱️" - , "description": "negative squared latin capital letter b" - , "aliases": [ - "b" - ] - , "tags": [ - ] - } -, { - "emoji": "🆎" - , "description": "negative squared ab" - , "aliases": [ - "ab" - ] - , "tags": [ - ] - } -, { - "emoji": "🅾️" - , "description": "negative squared latin capital letter o" - , "aliases": [ - "o2" - ] - , "tags": [ - ] - } -, { - "emoji": "💠" - , "description": "diamond shape with a dot inside" - , "aliases": [ - "diamond_shape_with_a_dot_inside" - ] - , "tags": [ - ] - } -, { - "emoji": "➿" - , "description": "double curly loop" - , "aliases": [ - "loop" - ] - , "tags": [ - ] - } -, { - "emoji": "♻️" - , "description": "black universal recycling symbol" - , "aliases": [ - "recycle" - ] - , "tags": [ - "environment" - , "green" - ] - } -, { - "emoji": "♈" - , "description": "aries" - , "aliases": [ - "aries" - ] - , "tags": [ - ] - } -, { - "emoji": "♉" - , "description": "taurus" - , "aliases": [ - "taurus" - ] - , "tags": [ - ] - } -, { - "emoji": "♊" - , "description": "gemini" - , "aliases": [ - "gemini" - ] - , "tags": [ - ] - } -, { - "emoji": "♋" - , "description": "cancer" - , "aliases": [ - "cancer" - ] - , "tags": [ - ] - } -, { - "emoji": "♌" - , "description": "leo" - , "aliases": [ - "leo" - ] - , "tags": [ - ] - } -, { - "emoji": "♍" - , "description": "virgo" - , "aliases": [ - "virgo" - ] - , "tags": [ - ] - } -, { - "emoji": "♎" - , "description": "libra" - , "aliases": [ - "libra" - ] - , "tags": [ - ] - } -, { - "emoji": "♏" - , "description": "scorpius" - , "aliases": [ - "scorpius" - ] - , "tags": [ - ] - } -, { - "emoji": "♐" - , "description": "sagittarius" - , "aliases": [ - "sagittarius" - ] - , "tags": [ - ] - } -, { - "emoji": "♑" - , "description": "capricorn" - , "aliases": [ - "capricorn" - ] - , "tags": [ - ] - } -, { - "emoji": "♒" - , "description": "aquarius" - , "aliases": [ - "aquarius" - ] - , "tags": [ - ] - } -, { - "emoji": "♓" - , "description": "pisces" - , "aliases": [ - "pisces" - ] - , "tags": [ - ] - } -, { - "emoji": "⛎" - , "description": "ophiuchus" - , "aliases": [ - "ophiuchus" - ] - , "tags": [ - ] - } -, { - "emoji": "🔯" - , "description": "six pointed star with middle dot" - , "aliases": [ - "six_pointed_star" - ] - , "tags": [ - ] - } -, { - "emoji": "🏧" - , "description": "automated teller machine" - , "aliases": [ - "atm" - ] - , "tags": [ - ] - } -, { - "emoji": "💹" - , "description": "chart with upwards trend and yen sign" - , "aliases": [ - "chart" - ] - , "tags": [ - ] - } -, { - "emoji": "💲" - , "description": "heavy dollar sign" - , "aliases": [ - "heavy_dollar_sign" - ] - , "tags": [ - ] - } -, { - "emoji": "💱" - , "description": "currency exchange" - , "aliases": [ - "currency_exchange" - ] - , "tags": [ - ] - } -, { - "emoji": "©️" - , "description": "copyright sign" - , "aliases": [ - "copyright" - ] - , "tags": [ - ] - } -, { - "emoji": "®️" - , "description": "registered sign" - , "aliases": [ - "registered" - ] - , "tags": [ - ] - } -, { - "emoji": "™️" - , "description": "trade mark sign" - , "aliases": [ - "tm" - ] - , "tags": [ - "trademark" - ] - } -, { - "emoji": "❌" - , "description": "cross mark" - , "aliases": [ - "x" - ] - , "tags": [ - ] - } -, { - "emoji": "‼️" - , "description": "double exclamation mark" - , "aliases": [ - "bangbang" - ] - , "tags": [ - ] - } -, { - "emoji": "⁉️" - , "description": "exclamation question mark" - , "aliases": [ - "interrobang" - ] - , "tags": [ - ] - } -, { - "emoji": "❗" - , "description": "heavy exclamation mark symbol" - , "aliases": [ - "exclamation" - , "heavy_exclamation_mark" - ] - , "tags": [ - "bang" - ] - } -, { - "emoji": "❓" - , "description": "black question mark ornament" - , "aliases": [ - "question" - ] - , "tags": [ - "confused" - ] - } -, { - "emoji": "❕" - , "description": "white exclamation mark ornament" - , "aliases": [ - "grey_exclamation" - ] - , "tags": [ - ] - } -, { - "emoji": "❔" - , "description": "white question mark ornament" - , "aliases": [ - "grey_question" - ] - , "tags": [ - ] - } -, { - "emoji": "⭕" - , "description": "heavy large circle" - , "aliases": [ - "o" - ] - , "tags": [ - ] - } -, { - "emoji": "🔝" - , "description": "top with upwards arrow above" - , "aliases": [ - "top" - ] - , "tags": [ - ] - } -, { - "emoji": "🔚" - , "description": "end with leftwards arrow above" - , "aliases": [ - "end" - ] - , "tags": [ - ] - } -, { - "emoji": "🔙" - , "description": "back with leftwards arrow above" - , "aliases": [ - "back" - ] - , "tags": [ - ] - } -, { - "emoji": "🔛" - , "description": "on with exclamation mark with left right arrow above" - , "aliases": [ - "on" - ] - , "tags": [ - ] - } -, { - "emoji": "🔜" - , "description": "soon with rightwards arrow above" - , "aliases": [ - "soon" - ] - , "tags": [ - ] - } -, { - "emoji": "🔃" - , "description": "clockwise downwards and upwards open circle arrows" - , "aliases": [ - "arrows_clockwise" - ] - , "tags": [ - ] - } -, { - "emoji": "🕛" - , "description": "clock face twelve oclock" - , "aliases": [ - "clock12" - ] - , "tags": [ - ] - } -, { - "emoji": "🕧" - , "description": "clock face twelve-thirty" - , "aliases": [ - "clock1230" - ] - , "tags": [ - ] - } -, { - "emoji": "🕐" - , "description": "clock face one oclock" - , "aliases": [ - "clock1" - ] - , "tags": [ - ] - } -, { - "emoji": "🕜" - , "description": "clock face one-thirty" - , "aliases": [ - "clock130" - ] - , "tags": [ - ] - } -, { - "emoji": "🕑" - , "description": "clock face two oclock" - , "aliases": [ - "clock2" - ] - , "tags": [ - ] - } -, { - "emoji": "🕝" - , "description": "clock face two-thirty" - , "aliases": [ - "clock230" - ] - , "tags": [ - ] - } -, { - "emoji": "🕒" - , "description": "clock face three oclock" - , "aliases": [ - "clock3" - ] - , "tags": [ - ] - } -, { - "emoji": "🕞" - , "description": "clock face three-thirty" - , "aliases": [ - "clock330" - ] - , "tags": [ - ] - } -, { - "emoji": "🕓" - , "description": "clock face four oclock" - , "aliases": [ - "clock4" - ] - , "tags": [ - ] - } -, { - "emoji": "🕟" - , "description": "clock face four-thirty" - , "aliases": [ - "clock430" - ] - , "tags": [ - ] - } -, { - "emoji": "🕔" - , "description": "clock face five oclock" - , "aliases": [ - "clock5" - ] - , "tags": [ - ] - } -, { - "emoji": "🕠" - , "description": "clock face five-thirty" - , "aliases": [ - "clock530" - ] - , "tags": [ - ] - } -, { - "emoji": "🕕" - , "description": "clock face six oclock" - , "aliases": [ - "clock6" - ] - , "tags": [ - ] - } -, { - "emoji": "🕖" - , "description": "clock face seven oclock" - , "aliases": [ - "clock7" - ] - , "tags": [ - ] - } -, { - "emoji": "🕗" - , "description": "clock face eight oclock" - , "aliases": [ - "clock8" - ] - , "tags": [ - ] - } -, { - "emoji": "🕘" - , "description": "clock face nine oclock" - , "aliases": [ - "clock9" - ] - , "tags": [ - ] - } -, { - "emoji": "🕙" - , "description": "clock face ten oclock" - , "aliases": [ - "clock10" - ] - , "tags": [ - ] - } -, { - "emoji": "🕚" - , "description": "clock face eleven oclock" - , "aliases": [ - "clock11" - ] - , "tags": [ - ] - } -, { - "emoji": "🕡" - , "description": "clock face six-thirty" - , "aliases": [ - "clock630" - ] - , "tags": [ - ] - } -, { - "emoji": "🕢" - , "description": "clock face seven-thirty" - , "aliases": [ - "clock730" - ] - , "tags": [ - ] - } -, { - "emoji": "🕣" - , "description": "clock face eight-thirty" - , "aliases": [ - "clock830" - ] - , "tags": [ - ] - } -, { - "emoji": "🕤" - , "description": "clock face nine-thirty" - , "aliases": [ - "clock930" - ] - , "tags": [ - ] - } -, { - "emoji": "🕥" - , "description": "clock face ten-thirty" - , "aliases": [ - "clock1030" - ] - , "tags": [ - ] - } -, { - "emoji": "🕦" - , "description": "clock face eleven-thirty" - , "aliases": [ - "clock1130" - ] - , "tags": [ - ] - } -, { - "emoji": "✖️" - , "description": "heavy multiplication x" - , "aliases": [ - "heavy_multiplication_x" - ] - , "tags": [ - ] - } -, { - "emoji": "➕" - , "description": "heavy plus sign" - , "aliases": [ - "heavy_plus_sign" - ] - , "tags": [ - ] - } -, { - "emoji": "➖" - , "description": "heavy minus sign" - , "aliases": [ - "heavy_minus_sign" - ] - , "tags": [ - ] - } -, { - "emoji": "➗" - , "description": "heavy division sign" - , "aliases": [ - "heavy_division_sign" - ] - , "tags": [ - ] - } -, { - "emoji": "♠️" - , "description": "black spade suit" - , "aliases": [ - "spades" - ] - , "tags": [ - ] - } -, { - "emoji": "♥️" - , "description": "black heart suit" - , "aliases": [ - "hearts" - ] - , "tags": [ - ] - } -, { - "emoji": "♣️" - , "description": "black club suit" - , "aliases": [ - "clubs" - ] - , "tags": [ - ] - } -, { - "emoji": "♦️" - , "description": "black diamond suit" - , "aliases": [ - "diamonds" - ] - , "tags": [ - ] - } -, { - "emoji": "💮" - , "description": "white flower" - , "aliases": [ - "white_flower" - ] - , "tags": [ - ] - } -, { - "emoji": "💯" - , "description": "hundred points symbol" - , "aliases": [ - "100" - ] - , "tags": [ - "score" - , "perfect" - ] - } -, { - "emoji": "✔️" - , "description": "heavy check mark" - , "aliases": [ - "heavy_check_mark" - ] - , "tags": [ - ] - } -, { - "emoji": "☑️" - , "description": "ballot box with check" - , "aliases": [ - "ballot_box_with_check" - ] - , "tags": [ - ] - } -, { - "emoji": "🔘" - , "description": "radio button" - , "aliases": [ - "radio_button" - ] - , "tags": [ - ] - } -, { - "emoji": "🔗" - , "description": "link symbol" - , "aliases": [ - "link" - ] - , "tags": [ - ] - } -, { - "emoji": "➰" - , "description": "curly loop" - , "aliases": [ - "curly_loop" - ] - , "tags": [ - ] - } -, { - "emoji": "〰️" - , "description": "wavy dash" - , "aliases": [ - "wavy_dash" - ] - , "tags": [ - ] - } -, { - "emoji": "〽️" - , "description": "part alternation mark" - , "aliases": [ - "part_alternation_mark" - ] - , "tags": [ - ] - } -, { - "emoji": "🔱" - , "description": "trident emblem" - , "aliases": [ - "trident" - ] - , "tags": [ - ] - } -, { - "emoji": "◼️" - , "description": "black medium square" - , "aliases": [ - "black_medium_square" - ] - , "tags": [ - ] - } -, { - "emoji": "◻️" - , "description": "white medium square" - , "aliases": [ - "white_medium_square" - ] - , "tags": [ - ] - } -, { - "emoji": "◾" - , "description": "black medium small square" - , "aliases": [ - "black_medium_small_square" - ] - , "tags": [ - ] - } -, { - "emoji": "◽" - , "description": "white medium small square" - , "aliases": [ - "white_medium_small_square" - ] - , "tags": [ - ] - } -, { - "emoji": "▪️" - , "description": "black small square" - , "aliases": [ - "black_small_square" - ] - , "tags": [ - ] - } -, { - "emoji": "▫️" - , "description": "white small square" - , "aliases": [ - "white_small_square" - ] - , "tags": [ - ] - } -, { - "emoji": "🔺" - , "description": "up-pointing red triangle" - , "aliases": [ - "small_red_triangle" - ] - , "tags": [ - ] - } -, { - "emoji": "🔲" - , "description": "black square button" - , "aliases": [ - "black_square_button" - ] - , "tags": [ - ] - } -, { - "emoji": "🔳" - , "description": "white square button" - , "aliases": [ - "white_square_button" - ] - , "tags": [ - ] - } -, { - "emoji": "⚫" - , "description": "medium black circle" - , "aliases": [ - "black_circle" - ] - , "tags": [ - ] - } -, { - "emoji": "⚪" - , "description": "medium white circle" - , "aliases": [ - "white_circle" - ] - , "tags": [ - ] - } -, { - "emoji": "🔴" - , "description": "large red circle" - , "aliases": [ - "red_circle" - ] - , "tags": [ - ] - } -, { - "emoji": "🔵" - , "description": "large blue circle" - , "aliases": [ - "large_blue_circle" - ] - , "tags": [ - ] - } -, { - "emoji": "🔻" - , "description": "down-pointing red triangle" - , "aliases": [ - "small_red_triangle_down" - ] - , "tags": [ - ] - } -, { - "emoji": "⬜" - , "description": "white large square" - , "aliases": [ - "white_large_square" - ] - , "tags": [ - ] - } -, { - "emoji": "⬛" - , "description": "black large square" - , "aliases": [ - "black_large_square" - ] - , "tags": [ - ] - } -, { - "emoji": "🔶" - , "description": "large orange diamond" - , "aliases": [ - "large_orange_diamond" - ] - , "tags": [ - ] - } -, { - "emoji": "🔷" - , "description": "large blue diamond" - , "aliases": [ - "large_blue_diamond" - ] - , "tags": [ - ] - } -, { - "emoji": "🔸" - , "description": "small orange diamond" - , "aliases": [ - "small_orange_diamond" - ] - , "tags": [ - ] - } -, { - "emoji": "🔹" - , "description": "small blue diamond" - , "aliases": [ - "small_blue_diamond" - ] - , "tags": [ - ] - } -] + ], + "flag_it": [ + "it" + ], + "flag_jp": [ + "jp" + ], + "flag_kr": [ + "kr" + ], + "flag_ru": [ + "ru" + ], + "flag_us": [ + "us" + ], + "flag_white": [ + "waving_white_flag" + ], + "fork_knife_plate": [ + "fork_and_knife_with_plate" + ], + "frame_photo": [ + "frame_with_picture" + ], + "frowning2": [ + "white_frowning_face" + ], + "hammer_pick": [ + "hammer_and_pick" + ], + "hand_splayed": [ + "raised_hand_with_fingers_splayed" + ], + "head_bandage": [ + "face_with_head_bandage" + ], + "heart_exclamation": [ + "heavy_heart_exclamation_mark_ornament" + ], + "helmet_with_cross": [ + "helmet_with_white_cross" + ], + "homes": [ + "house_buildings" + ], + "hotdog": [ + "hot_dog" + ], + "house_abandoned": [ + "derelict_house_building" + ], + "hugging": [ + "hugging_face" + ], + "island": [ + "desert_island" + ], + "key2": [ + "old_key" + ], + "laughing": [ + "satisfied" + ], + "levitate": [ + "man_in_business_suit_levitating" + ], + "lifter": [ + "weight_lifter" + ], + "lion_face": [ + "lion" + ], + "map": [ + "world_map" + ], + "medal": [ + "sports_medal" + ], + "metal": [ + "sign_of_the_horns" + ], + "microphone2": [ + "studio_microphone" + ], + "middle_finger": [ + "reversed_hand_with_middle_finger_extended" + ], + "money_mouth": [ + "money_mouth_face" + ], + "motorcycle": [ + "racing_motorcycle" + ], + "mountain_snow": [ + "snow_capped_mountain" + ], + "mouse_three_button": [ + "three_button_mouse" + ], + "nerd": [ + "nerd_face" + ], + "newspaper2": [ + "rolled_up_newspaper" + ], + "notepad_spiral": [ + "spiral_note_pad" + ], + "oil": [ + "oil_drum" + ], + "older_woman": [ + "grandma" + ], + "paintbrush": [ + "lower_left_paintbrush" + ], + "paperclips": [ + "linked_paperclips" + ], + "park": [ + "national_park" + ], + "pause_button": [ + "double_vertical_bar" + ], + "peace": [ + "peace_symbol" + ], + "pen_ballpoint": [ + "lower_left_ballpoint_pen" + ], + "pen_fountain": [ + "lower_left_fountain_pen" + ], + "ping_pong": [ + "table_tennis" + ], + "place_of_worship": [ + "worship_symbol" + ], + "poop": [ + "shit", + "hankey", + "poo" + ], + "projector": [ + "film_projector" + ], + "race_car": [ + "racing_car" + ], + "radioactive": [ + "radioactive_sign" + ], + "railway_track": [ + "railroad_track" + ], + "robot": [ + "robot_face" + ], + "rolling_eyes": [ + "face_with_rolling_eyes" + ], + "skull": [ + "skeleton" + ], + "skull_crossbones": [ + "skull_and_crossbones" + ], + "slight_frown": [ + "slightly_frowning_face" + ], + "slight_smile": [ + "slightly_smiling_face" + ], + "speaking_head": [ + "speaking_head_in_silhouette" + ], + "spy": [ + "sleuth_or_spy" + ], + "thermometer_face": [ + "face_with_thermometer" + ], + "thinking": [ + "thinking_face" + ], + "thumbsdown": [ + "-1" + ], + "thumbsup": [ + "+1" + ], + "thunder_cloud_rain": [ + "thunder_cloud_and_rain" + ], + "tickets": [ + "admission_tickets" + ], + "timer": [ + "timer_clock" + ], + "tools": [ + "hammer_and_wrench" + ], + "track_next": [ + "next_track" + ], + "track_previous": [ + "previous_track" + ], + "unicorn": [ + "unicorn_face" + ], + "upside_down": [ + "upside_down_face" + ], + "urn": [ + "funeral_urn" + ], + "vulcan": [ + "raised_hand_with_part_between_middle_and_ring_fingers" + ], + "white_sun_cloud": [ + "white_sun_behind_cloud" + ], + "white_sun_rain_cloud": [ + "white_sun_behind_cloud_with_rain" + ], + "white_sun_small_cloud": [ + "white_sun_with_small_cloud" + ], + "zipper_mouth": [ + "zipper_mouth_face" + ] + } +} diff --git a/lib/enum.rb b/lib/enum.rb index bbdc3fe82d8..7db1845dc4d 100644 --- a/lib/enum.rb +++ b/lib/enum.rb @@ -1,19 +1,28 @@ class Enum < Hash # Public: Initialize an enum. # - # members - the array of enum members. May contain a hash of options: - # :start - the number of first enum member. Defaults to 1. + # members - Array of enum members or Hash of enum members. + # Array of enum members may also contain a hash of options: + # :start - the number of first enum member. Defaults to 1. # # Examples # - # FRUITS = Enum.new(:apple, :orange, :kiwi) + # FRUITS = Enum.new(:apple, :orange, :kiwi) # array + # FRUITS = Enum.new(:apple, :orange, :kiwi, start: 0) # array + # FRUITS = Enum.new(apple: 1, orange: 2, kiwi: 3) # hash + def initialize(*members) super({}) - options = members.extract_options! - start = options.fetch(:start) { 1 } - - update Hash[members.zip(start..members.count + start)] + if members[0].is_a?(Hash) + # hash + update Hash[members[0]] + else + # array + options = members.extract_options! + start = options.fetch(:start) { 1 } + update Hash[members.zip(start..members.count + start)] + end end # Public: Access the number/value of member. diff --git a/lib/es6_module_transpiler/tilt/es6_module_transpiler_template.rb b/lib/es6_module_transpiler/tilt/es6_module_transpiler_template.rb index 30f575f4235..f827746ea7d 100644 --- a/lib/es6_module_transpiler/tilt/es6_module_transpiler_template.rb +++ b/lib/es6_module_transpiler/tilt/es6_module_transpiler_template.rb @@ -29,7 +29,7 @@ module Tilt end def self.create_new_context - ctx = V8::Context.new(timeout: 5000) + ctx = V8::Context.new(timeout: 10000) ctx.eval("var self = this; #{File.read(Babel::Transpiler.script_path)}") ctx.eval("module = {}; exports = {};"); ctx.load("#{Rails.root}/lib/es6_module_transpiler/support/es6-module-transpiler.js") @@ -74,6 +74,34 @@ module Tilt rval end + def whitelisted?(path) + + @@whitelisted ||= Set.new( + ["discourse/models/nav-item", + "discourse/models/user-action", + "discourse/routes/discourse", + "discourse/models/category", + "discourse/models/trust-level", + "discourse/models/site", + "discourse/models/user", + "discourse/models/session", + "discourse/models/model", + "discourse/models/topic", + "discourse/models/post", + "discourse/views/grouped"] + ) + + @@whitelisted.include?(path) || path =~ /discourse\/mixins/ + end + + def babel_transpile(source) + klass = self.class + klass.protect do + klass.v8['console'] = Console.new("BABEL: babel-eval: ") + @output = klass.v8.eval(babel_source(source)) + end + end + def evaluate(scope, locals, &block) return @output if @output @@ -86,7 +114,7 @@ module Tilt # For backwards compatibility with plugins, for now export the Global format too. # We should eventually have an upgrade system for plugins to use ES6 or some other # resolve based API. - if ENV['DISCOURSE_NO_CONSTANTS'].nil? && + if whitelisted?(scope.logical_path) && scope.logical_path =~ /(discourse|admin)\/(controllers|components|views|routes|mixins|models)\/(.*)/ type = Regexp.last_match[2] @@ -119,11 +147,15 @@ module Tilt @output end + def babel_source(source) + js_source = ::JSON.generate(source, quirks_mode: true) + "babel.transform(#{js_source}, {ast: false, whitelist: ['es6.constants', 'es6.properties.shorthand', 'es6.arrowFunctions', 'es6.blockScoping', 'es6.destructuring', 'es6.spread', 'es6.parameters', 'es6.templateLiterals', 'es6.regex.unicode', 'es7.decorators', 'es6.classes']})['code']" + end + private def generate_source(scope) - js_source = ::JSON.generate(data, quirks_mode: true) - js_source = "babel.transform(#{js_source}, {ast: false, whitelist: ['es6.constants', 'es6.properties.shorthand', 'es6.arrowFunctions', 'es6.blockScoping', 'es6.destructuring', 'es6.spread', 'es6.parameters', 'es6.templateLiterals', 'es6.regex.unicode', 'es7.decorators']})['code']" + js_source = babel_source(data) "new module.exports.Compiler(#{js_source}, '#{module_name(scope.root_path, scope.logical_path)}', #{compiler_options}).#{compiler_method}()" end diff --git a/lib/excerpt_parser.rb b/lib/excerpt_parser.rb index 95e9cf1de7f..acfa88b88c2 100644 --- a/lib/excerpt_parser.rb +++ b/lib/excerpt_parser.rb @@ -13,7 +13,8 @@ class ExcerptParser < Nokogiri::XML::SAX::Document @text_entities = options[:text_entities] == true @markdown_images = options[:markdown_images] == true @keep_newlines = options[:keep_newlines] == true - @keep_emojis = options[:keep_emojis] == true + @keep_emoji_images = options[:keep_emoji_images] == true + @keep_emoji_codes = options[:keep_emoji_codes] == true @start_excerpt = false end @@ -48,11 +49,14 @@ class ExcerptParser < Nokogiri::XML::SAX::Document def start_element(name, attributes=[]) case name when "img" - attributes = Hash[*attributes.flatten] - if @keep_emojis && attributes["class"] == 'emoji' - return include_tag(name, attributes) + if attributes["class"] == 'emoji' + if @keep_emoji_images + return include_tag(name, attributes) + elsif @keep_emoji_codes + return characters(attributes["alt"]) + end end # If include_images is set, include the image in markdown diff --git a/lib/file_helper.rb b/lib/file_helper.rb index 30f9895a71c..ecf966a5fdd 100644 --- a/lib/file_helper.rb +++ b/lib/file_helper.rb @@ -6,7 +6,7 @@ class FileHelper filename =~ images_regexp end - def self.download(url, max_file_size, tmp_file_name, follow_redirect=false) + def self.download(url, max_file_size, tmp_file_name, follow_redirect=false, read_timeout=5) raise Discourse::InvalidParameters.new(:url) unless url =~ /^https?:\/\// uri = parse_url(url) @@ -14,7 +14,7 @@ class FileHelper tmp = Tempfile.new([tmp_file_name, extension]) File.open(tmp.path, "wb") do |f| - downloaded = uri.open("rb", read_timeout: 5, redirect: follow_redirect, allow_redirections: :all) + downloaded = uri.open("rb", read_timeout: read_timeout, redirect: follow_redirect, allow_redirections: :all) while f.size <= max_file_size && data = downloaded.read(512.kilobytes) f.write(data) end @@ -28,7 +28,7 @@ class FileHelper private def self.images - @@images ||= Set.new ["jpg", "jpeg", "png", "gif", "tif", "tiff", "bmp", "svg", "webp"] + @@images ||= Set.new ["jpg", "jpeg", "png", "gif", "tif", "tiff", "bmp", "svg", "webp", "ico"] end def self.images_regexp diff --git a/lib/file_store/base_store.rb b/lib/file_store/base_store.rb index 7e984a65288..275e78dff73 100644 --- a/lib/file_store/base_store.rb +++ b/lib/file_store/base_store.rb @@ -71,8 +71,12 @@ module FileStore def purge_tombstone(grace_period) end + def get_depth_for(id) + [0, Math.log(id / 1_000.0, 16).ceil].max + end + def get_path_for(type, id, sha, extension) - depth = [0, Math.log(id / 1_000.0, 16).ceil].max + depth = get_depth_for(id) tree = File.join(*sha[0, depth].split(""), "") "#{type}/#{depth + 1}X/#{tree}#{sha}#{extension}" end diff --git a/lib/freedom_patches/arel_patch.rb b/lib/freedom_patches/arel_patch.rb deleted file mode 100644 index 4c0ae309b19..00000000000 --- a/lib/freedom_patches/arel_patch.rb +++ /dev/null @@ -1,6 +0,0 @@ -# https://github.com/rails/arel/pull/206 -class Arel::Table - def hash - @name.hash - end -end diff --git a/lib/freedom_patches/i18n_fallbacks.rb b/lib/freedom_patches/i18n_fallbacks.rb deleted file mode 100644 index b8aa691835b..00000000000 --- a/lib/freedom_patches/i18n_fallbacks.rb +++ /dev/null @@ -1,17 +0,0 @@ -module I18n - module Backend - module Fallbacks - def exists?(locale, key) - I18n.fallbacks[locale].each do |fallback| - begin - return true if super(fallback, key) - rescue I18n::InvalidLocale - # we do nothing when the locale is invalid, as this is a fallback anyways. - end - end - - false - end - end - end -end diff --git a/lib/freedom_patches/pool_drainer.rb b/lib/freedom_patches/pool_drainer.rb index ff58a288d4e..6ded19de97d 100644 --- a/lib/freedom_patches/pool_drainer.rb +++ b/lib/freedom_patches/pool_drainer.rb @@ -2,11 +2,12 @@ if Rails.version >= "4.2.0" class ActiveRecord::ConnectionAdapters::AbstractAdapter module LastUseExtension - attr_reader :last_use + attr_reader :last_use, :first_use def initialize(connection, logger = nil, pool = nil) super @last_use = false + @first_use = Time.now end def lease @@ -26,11 +27,11 @@ end class ActiveRecord::ConnectionAdapters::ConnectionPool # drain all idle connections # if idle_time is specified only connections idle for N seconds will be drained - def drain(idle_time=nil) + def drain(idle_time=nil, max_age=nil) synchronize do @available.clear @connections.delete_if do |conn| - try_drain?(conn, idle_time) + try_drain?(conn, idle_time, max_age) end @connections.each do |conn| @@ -42,9 +43,9 @@ class ActiveRecord::ConnectionAdapters::ConnectionPool private - def try_drain?(conn, idle_time) + def try_drain?(conn, idle_time, max_age) if !conn.in_use? - if !idle_time || conn.last_use < idle_time.seconds.ago + if !idle_time || conn.last_use < idle_time.seconds.ago || (max_age && conn.first_use < max_age.seconds.ago) conn.disconnect! return true end diff --git a/lib/freedom_patches/redis.rb b/lib/freedom_patches/redis.rb new file mode 100644 index 00000000000..8bab1e7141d --- /dev/null +++ b/lib/freedom_patches/redis.rb @@ -0,0 +1,14 @@ +# https://github.com/redis/redis-rb/pull/591 +class Redis + class Client + alias_method :old_initialize, :initialize + + def initialize(options = {}) + old_initialize(options) + + if options.include?(:connector) && options[:connector].is_a?(Class) + @connector = options[:connector].new(@options) + end + end + end +end diff --git a/lib/freedom_patches/schema_migration_details.rb b/lib/freedom_patches/schema_migration_details.rb new file mode 100644 index 00000000000..bbae956c11a --- /dev/null +++ b/lib/freedom_patches/schema_migration_details.rb @@ -0,0 +1,54 @@ +module FreedomPatches + module SchemaMigrationDetails + def exec_migration(conn, direction) + rval = nil + + time = Benchmark.measure do + rval=super + end + + sql = < 0 + def search(query, opts=nil) + locale = opts[:locale] || config.locale + + load_locale(locale) unless @loaded_locales.include?(locale) + opts ||= {} + + target = opts[:backend] || backend + results = opts[:overridden] ? {} : target.search(config.locale, query) + + regexp = /#{query}/i + (overrides_by_locale(locale) || {}).each do |k, v| + results.delete(k) + results[k] = v if (k =~ regexp || v =~ regexp) + end + results + end + + def ensure_loaded!(locale) + @loaded_locales ||= [] + load_locale(locale) unless @loaded_locales.include?(locale) + end + + # In some environments such as migrations we don't want to use overrides. + # Use this to disable them over a block of ruby code + def overrides_disabled + @overrides_enabled = false + yield + ensure + @overrides_enabled = true + end + + def translate_no_override(*args) + return translate_no_cache(*args) if args.length > 1 && args[1].present? + + options = args.last.is_a?(Hash) ? args.pop.dup : {} + key = args.shift + locale = options[:locale] || config.locale + @cache ||= LruRedux::ThreadSafeCache.new(LRU_CACHE_SIZE) - k = "#{key}#{config.locale}#{config.backend.object_id}" + k = "#{key}#{locale}#{config.backend.object_id}" @cache.getset(k) do - translate_no_cache(key).freeze + translate_no_cache(key, options).freeze end end + def overrides_by_locale(locale) + return unless @overrides_enabled + + site = RailsMultisite::ConnectionManagement.current_db + + by_site = @overrides_by_site[site] + + if by_site.nil? || !by_site.has_key?(locale) + by_site = @overrides_by_site[site] = {} + + # Load overrides + translations_overrides = TranslationOverride.where(locale: locale).pluck(:translation_key, :value) + + if translations_overrides.empty? + by_site[locale] = {} + else + translations_overrides.each do |tuple| + by_locale = by_site[locale] ||= {} + by_locale[tuple[0]] = tuple[1] + end + end + end + + by_site[locale] + end + + def client_overrides_json(locale) + client_json = (overrides_by_locale(locale) || {}).select {|k, _| k.starts_with?('js.') || k.starts_with?('admin_js.')} + MultiJson.dump(client_json) + end + + def translate(*args) + options = args.last.is_a?(Hash) ? args.pop.dup : {} + key = args.shift + locale = options[:locale] || config.locale + + load_locale(locale) unless @loaded_locales.include?(locale) + + if @overrides_enabled + by_locale = overrides_by_locale(locale) + if by_locale + if options.present? + options[:overrides] = by_locale + + # I18n likes to use throw... + catch(:exception) do + return backend.translate(locale, key, options) + end + else + if result = by_locale[key] + return result + end + end + + end + end + translate_no_override(key, options) + end + alias_method :t, :translate + + def exists?(key, locale=nil) + locale ||= config.locale + load_locale(locale) unless @loaded_locales.include?(locale) + exists_no_cache?(key, locale) + end + end end diff --git a/lib/global_path.rb b/lib/global_path.rb index 20f09f18bd4..c2d9a2a4da2 100644 --- a/lib/global_path.rb +++ b/lib/global_path.rb @@ -6,4 +6,13 @@ module GlobalPath def cdn_path(p) "#{GlobalSetting.cdn_url}#{path(p)}" end + + def cdn_relative_path(path) + if (cdn_url = GlobalSetting.cdn_url).present? + URI.parse(cdn_url).path + path + else + path + end + end + end diff --git a/lib/guardian.rb b/lib/guardian.rb index 6cc1e9e3fb1..576d477b130 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -22,6 +22,7 @@ class Guardian def staff?; false; end def moderator?; false; end def approved?; false; end + def staged?; false; end def secure_category_ids; []; end def topic_create_allowed_category_ids; []; end def has_trust_level?(level); false; end @@ -212,7 +213,7 @@ class Guardian def can_invite_to?(object, group_ids=nil) return false if ! authenticated? - return false unless ( SiteSetting.enable_local_logins && (!SiteSetting.must_approve_users? || is_staff?) ) + return false unless (!SiteSetting.must_approve_users? || is_staff?) return true if is_admin? return false if (SiteSetting.max_invites_per_day.to_i == 0 && !is_staff?) return false if ! can_see?(object) @@ -250,13 +251,15 @@ class Guardian # Can't send message to yourself is_not_me?(target) && # Have to be a basic level at least - @user.has_trust_level?(TrustLevel[1]) && + @user.has_trust_level?(SiteSetting.min_trust_to_send_messages) && # PMs are enabled (SiteSetting.enable_private_messages || @user.username == SiteSetting.site_contact_username || @user == Discourse.system_user) && # Can't send PMs to suspended users - (is_staff? || target.is_a?(Group) || !target.suspended?) + (is_staff? || target.is_a?(Group) || !target.suspended?) && + # Blocked users can only send PM to staff + (!@user.blocked? || target.staff?) end def can_see_emails? diff --git a/lib/guardian/category_guardian.rb b/lib/guardian/category_guardian.rb index 63bbd5be797..b711c12d03e 100644 --- a/lib/guardian/category_guardian.rb +++ b/lib/guardian/category_guardian.rb @@ -45,7 +45,10 @@ module CategoryGuardian end def can_see_category?(category) - not(category.read_restricted) || secure_category_ids.include?(category.id) + is_admin? || + !category.read_restricted || + (@user.staged? && category.email_in.present? && category.email_in_allow_strangers) || + secure_category_ids.include?(category.id) end def secure_category_ids @@ -54,8 +57,11 @@ module CategoryGuardian # all allowed category ids def allowed_category_ids - unrestricted = Category.where(read_restricted: false).pluck(:id) - unrestricted.concat(secure_category_ids) + @allowed_category_ids ||= + begin + unrestricted = Category.where(read_restricted: false).pluck(:id) + unrestricted.concat(secure_category_ids) + end end def topic_create_allowed_category_ids diff --git a/lib/guardian/group_guardian.rb b/lib/guardian/group_guardian.rb index 308d95b2be0..8cc3ffa3899 100644 --- a/lib/guardian/group_guardian.rb +++ b/lib/guardian/group_guardian.rb @@ -5,7 +5,11 @@ module GroupGuardian # Automatic groups are not represented in the GROUP_USERS # table and thus do not allow membership changes. def can_edit_group?(group) - (group.managers.include?(user) || is_admin?) && !group.automatic + (is_admin? || group.users.where('group_users.owner').include?(user)) && !group.automatic + end + + def can_see_group_messages?(group) + is_admin? || group.users.include?(user) end end diff --git a/lib/guardian/post_guardian.rb b/lib/guardian/post_guardian.rb index d668803ab56..9c07db3380d 100644 --- a/lib/guardian/post_guardian.rb +++ b/lib/guardian/post_guardian.rb @@ -30,7 +30,7 @@ module PostGuardian not(action_key == :like && is_my_own?(post)) && # new users can't notify_user because they are not allowed to send private messages - not(action_key == :notify_user && !@user.has_trust_level?(TrustLevel[1])) && + not(action_key == :notify_user && !@user.has_trust_level?(SiteSetting.min_trust_to_send_messages)) && # can't send private messages if they're disabled globally not(action_key == :notify_user && !SiteSetting.enable_private_messages) && @@ -73,7 +73,7 @@ module PostGuardian # Creating Method def can_create_post?(parent) - !SpamRule::AutoBlock.block?(@user) && ( + (!SpamRule::AutoBlock.block?(@user) || (!!parent.try(:private_message?) && parent.allowed_users.include?(@user))) && ( !parent || !parent.category || Category.post_create_allowed(self).where(:id => parent.category.id).count == 1 @@ -157,7 +157,7 @@ module PostGuardian return false unless post if !post.hidden - return true if post.wiki || SiteSetting.edit_history_visible_to_public || post.user.try(:edit_history_public) + return true if post.wiki || SiteSetting.edit_history_visible_to_public || (post.user && post.user.user_option.edit_history_public) end authenticated? && @@ -173,8 +173,16 @@ module PostGuardian is_admin? end - def can_wiki? - is_staff? || @user.has_trust_level?(TrustLevel[4]) + def can_wiki?(post) + return false unless authenticated? + return true if is_staff? || @user.has_trust_level?(TrustLevel[4]) + + if @user.has_trust_level?(SiteSetting.min_trust_to_allow_self_wiki) && is_my_own?(post) + return false if post.hidden? + return !post.edit_time_limit_expired? + end + + false end def can_change_post_type? diff --git a/lib/guardian/topic_guardian.rb b/lib/guardian/topic_guardian.rb index cb5cc6d7239..655273b7cdb 100644 --- a/lib/guardian/topic_guardian.rb +++ b/lib/guardian/topic_guardian.rb @@ -30,7 +30,10 @@ module TopicGuardian return false if Discourse.static_doc_topic_ids.include?(topic.id) && !is_admin? return false unless can_see?(topic) return true if is_staff? - return true if (!topic.private_message? && user.has_trust_level?(TrustLevel[3]) && can_create_post?(topic)) + # TL4 users can edit archived topics, but can not edit private messages + return true if (topic.archived && !topic.private_message? && user.has_trust_level?(TrustLevel[4]) && can_create_post?(topic)) + # TL3 users can not edit archived topics and private messages + return true if (!topic.archived && !topic.private_message? && user.has_trust_level?(TrustLevel[3]) && can_create_post?(topic)) return false if topic.archived is_my_own?(topic) && !topic.edit_time_limit_expired? diff --git a/lib/highlight_js/assets/highlight.js b/lib/highlight_js/assets/highlight.js index e2a581c1c05..ac1a7541755 100644 --- a/lib/highlight_js/assets/highlight.js +++ b/lib/highlight_js/assets/highlight.js @@ -1 +1,2 @@ -!function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/no-?highlight|plain|text/.test(e)}function i(e){var n,t,r,i=e.className+" ";for(i+=e.parentNode?e.parentNode.className:"",i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(t=i[n].replace(/^lang(uage)?-/,""),w(t)||a(t))return t}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function u(e){f+=""}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,f="",l=[];e.length||r.length;){var g=i();if(f+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){l.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);l.reverse().forEach(o)}else"start"==g[0].event?l.push(g[0].node):l.pop(),c(g.splice(0,1)[0])}return f+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\b\w+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var f=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=f.length?t(f.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){for(var t=0;t";return i+=e+'">',i+n+o}function d(){if(!L.k)return n(y);var e="",t=0;L.lR.lastIndex=0;for(var r=L.lR.exec(y);r;){e+=n(y.substr(t,r.index-t));var a=g(L,r);a?(B+=a[1],e+=p(a[0],n(r[0]))):e+=n(r[0]),t=L.lR.lastIndex,r=L.lR.exec(y)}return e+n(y.substr(t))}function h(){if(L.sL&&!E[L.sL])return n(y);var e=L.sL?f(L.sL,y,!0,M[L.sL]):l(y);return L.r>0&&(B+=e.r),"continuous"==L.subLanguageMode&&(M[L.sL]=e.top),p(e.language,e.value,!1,!0)}function b(){return void 0!==L.sL?h():d()}function v(e,t){var r=e.cN?p(e.cN,"",!0):"";e.rB?(k+=r,y=""):e.eB?(k+=n(t)+r,y=""):(k+=r,y=t),L=Object.create(e,{parent:{value:L}})}function m(e,t){if(y+=e,void 0===t)return k+=b(),0;var r=o(t,L);if(r)return k+=b(),v(r,t),r.rB?0:t.length;var a=u(L,t);if(a){var i=L;i.rE||i.eE||(y+=t),k+=b();do L.cN&&(k+=""),B+=L.r,L=L.parent;while(L!=a.parent);return i.eE&&(k+=n(t)),y="",a.starts&&v(a.starts,""),i.rE?0:t.length}if(c(t,L))throw new Error('Illegal lexeme "'+t+'" for mode "'+(L.cN||"")+'"');return y+=t,t.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,L=i||N,M={},k="";for(R=L;R!=N;R=R.parent)R.cN&&(k=p(R.cN,"",!0)+k);var y="",B=0;try{for(var C,j,I=0;;){if(L.t.lastIndex=I,C=L.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),R=L;R.parent;R=R.parent)R.cN&&(k+="");return{r:B,value:k,language:e,top:L}}catch(S){if(-1!=S.message.indexOf("Illegal"))return{r:0,value:n(t)};throw S}}function l(e,t){t=t||x.languages||Object.keys(E);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(w(n)){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return x.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,x.tabReplace)})),x.useBR&&(e=e.replace(/\n/g,"
    ")),e}function p(e,n,t){var r=n?R[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n=i(e);if(!a(n)){var t;x.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?f(n,r,!0):l(r),s=u(t);if(s.length){var d=document.createElementNS("http://www.w3.org/1999/xhtml","div");d.innerHTML=o.value,o.value=c(s,u(d),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=p(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function h(e){x=o(x,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,d)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=E[n]=t(e);r.aliases&&r.aliases.forEach(function(e){R[e]=n})}function N(){return Object.keys(E)}function w(e){return E[e]||E[R[e]]}var x={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},E={},R={};return e.highlight=f,e.highlightAuto=l,e.fixMarkup=g,e.highlightBlock=d,e.configure=h,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="\\b(0[xX][a-fA-F0-9]+|(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e}); \ No newline at end of file +/*! highlight.js v9.2.0 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/^(no-?highlight|plain|text)$/i.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/i.exec(i))return w(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(w(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function u(e){f+=""}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,f="",l=[];e.length||r.length;){var g=i();if(f+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){l.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);l.reverse().forEach(o)}else"start"==g[0].event?l.push(g[0].node):l.pop(),c(g.splice(0,1)[0])}return f+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var f=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=f.length?t(f.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){for(var t=0;t";return i+=e+'">',i+n+o}function h(){if(!k.k)return n(M);var e="",t=0;k.lR.lastIndex=0;for(var r=k.lR.exec(M);r;){e+=n(M.substr(t,r.index-t));var a=g(k,r);a?(B+=a[1],e+=p(a[0],n(r[0]))):e+=n(r[0]),t=k.lR.lastIndex,r=k.lR.exec(M)}return e+n(M.substr(t))}function d(){var e="string"==typeof k.sL;if(e&&!R[k.sL])return n(M);var t=e?f(k.sL,M,!0,y[k.sL]):l(M,k.sL.length?k.sL:void 0);return k.r>0&&(B+=t.r),e&&(y[k.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=void 0!==k.sL?d():h(),M=""}function v(e,n){L+=e.cN?p(e.cN,"",!0):"",k=Object.create(e,{parent:{value:k}})}function m(e,n){if(M+=e,void 0===n)return b(),0;var t=o(n,k);if(t)return t.skip?M+=n:(t.eB&&(M+=n),b(),t.rB||t.eB||(M=n)),v(t,n),t.rB?0:n.length;var r=u(k,n);if(r){var a=k;a.skip?M+=n:(a.rE||a.eE||(M+=n),b(),a.eE&&(M=n));do k.cN&&(L+=""),k.skip||(B+=k.r),k=k.parent;while(k!=r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,k))throw new Error('Illegal lexeme "'+n+'" for mode "'+(k.cN||"")+'"');return M+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var x,k=i||N,y={},L="";for(x=k;x!=N;x=x.parent)x.cN&&(L=p(x.cN,"",!0)+L);var M="",B=0;try{for(var C,j,I=0;;){if(k.t.lastIndex=I,C=k.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),x=k;x.parent;x=x.parent)x.cN&&(L+="");return{r:B,value:L,language:e,top:k}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function l(e,t){t=t||E.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(w(n)){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\n/g,"
    ")),e}function p(e,n,t){var r=n?x[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function h(e){var n=i(e);if(!a(n)){var t;E.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?f(n,r,!0):l(r),s=u(t);if(s.length){var h=document.createElementNS("http://www.w3.org/1999/xhtml","div");h.innerHTML=o.value,o.value=c(s,u(h),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=p(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,h)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){x[e]=n})}function N(){return Object.keys(R)}function w(e){return e=(e||"").toLowerCase(),R[e]||R[x[e]]}var E={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},x={};return e.highlight=f,e.highlightAuto=l,e.fixMarkup=g,e.highlightBlock=h,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/1c.js b/lib/highlight_js/assets/lang/1c.js index a6f1f57e2c1..2e5eb6db935 100644 --- a/lib/highlight_js/assets/lang/1c.js +++ b/lib/highlight_js/assets/lang/1c.js @@ -1 +1 @@ -hljs.registerLanguage("1c",function(c){var e="[a-zA-Zа-яА-Я][a-zA-Z0-9_а-яА-Я]*",r="возврат дата для если и или иначе иначеесли исключение конецесли конецпопытки конецпроцедуры конецфункции конеццикла константа не перейти перем перечисление по пока попытка прервать продолжить процедура строка тогда фс функция цикл число экспорт",t="ansitooem oemtoansi ввестивидсубконто ввестидату ввестизначение ввестиперечисление ввестипериод ввестиплансчетов ввестистроку ввестичисло вопрос восстановитьзначение врег выбранныйплансчетов вызватьисключение датагод датамесяц датачисло добавитьмесяц завершитьработусистемы заголовоксистемы записьжурналарегистрации запуститьприложение зафиксироватьтранзакцию значениевстроку значениевстрокувнутр значениевфайл значениеизстроки значениеизстрокивнутр значениеизфайла имякомпьютера имяпользователя каталогвременныхфайлов каталогиб каталогпользователя каталогпрограммы кодсимв командасистемы конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лев лог лог10 макс максимальноеколичествосубконто мин монопольныйрежим названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найти найтипомеченныенаудаление найтиссылки началопериодаби началостандартногоинтервала начатьтранзакцию начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода нрег обработкаожидания окр описаниеошибки основнойжурналрасчетов основнойплансчетов основнойязык открытьформу открытьформумодально отменитьтранзакцию очиститьокносообщений периодстр полноеимяпользователя получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта прав праводоступа предупреждение префиксавтонумерации пустаястрока пустоезначение рабочаядаттьпустоезначение рабочаядата разделительстраниц разделительстрок разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо сигнал симв символтабуляции создатьобъект сокрл сокрлп сокрп сообщить состояние сохранитьзначение сред статусвозврата стрдлина стрзаменить стрколичествострок стрполучитьстроку стрчисловхождений сформироватьпозициюдокумента счетпокоду текущаядата текущеевремя типзначения типзначениястр удалитьобъекты установитьтана установитьтапо фиксшаблон формат цел шаблон",i={cN:"dquote",b:'""'},n={cN:"string",b:'"',e:'"|$',c:[i]},a={cN:"string",b:"\\|",e:'"|$',c:[i]};return{cI:!0,l:e,k:{keyword:r,built_in:t},c:[c.CLCM,c.NM,n,a,{cN:"function",b:"(процедура|функция)",e:"$",l:e,k:"процедура функция",c:[c.inherit(c.TM,{b:e}),{cN:"tail",eW:!0,c:[{cN:"params",b:"\\(",e:"\\)",l:e,k:"знач",c:[n,a]},{cN:"export",b:"экспорт",eW:!0,l:e,k:"экспорт",c:[c.CLCM]}]},c.CLCM]},{cN:"preprocessor",b:"#",e:"$"},{cN:"date",b:"'\\d{2}\\.\\d{2}\\.(\\d{2}|\\d{4})'"}]}}); \ No newline at end of file +hljs.registerLanguage("1c",function(c){var e="[a-zA-Zа-яА-Я][a-zA-Z0-9_а-яА-Я]*",n="возврат дата для если и или иначе иначеесли исключение конецесли конецпопытки конецпроцедуры конецфункции конеццикла константа не перейти перем перечисление по пока попытка прервать продолжить процедура строка тогда фс функция цикл число экспорт",b="ansitooem oemtoansi ввестивидсубконто ввестидату ввестизначение ввестиперечисление ввестипериод ввестиплансчетов ввестистроку ввестичисло вопрос восстановитьзначение врег выбранныйплансчетов вызватьисключение датагод датамесяц датачисло добавитьмесяц завершитьработусистемы заголовоксистемы записьжурналарегистрации запуститьприложение зафиксироватьтранзакцию значениевстроку значениевстрокувнутр значениевфайл значениеизстроки значениеизстрокивнутр значениеизфайла имякомпьютера имяпользователя каталогвременныхфайлов каталогиб каталогпользователя каталогпрограммы кодсимв командасистемы конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лев лог лог10 макс максимальноеколичествосубконто мин монопольныйрежим названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найти найтипомеченныенаудаление найтиссылки началопериодаби началостандартногоинтервала начатьтранзакцию начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода нрег обработкаожидания окр описаниеошибки основнойжурналрасчетов основнойплансчетов основнойязык открытьформу открытьформумодально отменитьтранзакцию очиститьокносообщений периодстр полноеимяпользователя получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта прав праводоступа предупреждение префиксавтонумерации пустаястрока пустоезначение рабочаядаттьпустоезначение рабочаядата разделительстраниц разделительстрок разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо сигнал симв символтабуляции создатьобъект сокрл сокрлп сокрп сообщить состояние сохранитьзначение сред статусвозврата стрдлина стрзаменить стрколичествострок стрполучитьстроку стрчисловхождений сформироватьпозициюдокумента счетпокоду текущаядата текущеевремя типзначения типзначениястр удалитьобъекты установитьтана установитьтапо фиксшаблон формат цел шаблон",i={b:'""'},r={cN:"string",b:'"',e:'"|$',c:[i]},t={cN:"string",b:"\\|",e:'"|$',c:[i]};return{cI:!0,l:e,k:{keyword:n,built_in:b},c:[c.CLCM,c.NM,r,t,{cN:"function",b:"(процедура|функция)",e:"$",l:e,k:"процедура функция",c:[{b:"экспорт",eW:!0,l:e,k:"экспорт",c:[c.CLCM]},{cN:"params",b:"\\(",e:"\\)",l:e,k:"знач",c:[r,t]},c.CLCM,c.inherit(c.TM,{b:e})]},{cN:"meta",b:"#",e:"$"},{cN:"number",b:"'\\d{2}\\.\\d{2}\\.(\\d{2}|\\d{4})'"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/accesslog.js b/lib/highlight_js/assets/lang/accesslog.js new file mode 100644 index 00000000000..02ee5f15ba7 --- /dev/null +++ b/lib/highlight_js/assets/lang/accesslog.js @@ -0,0 +1 @@ +hljs.registerLanguage("accesslog",function(T){return{c:[{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+\\b",r:0},{cN:"string",b:'"(GET|POST|HEAD|PUT|DELETE|CONNECT|OPTIONS|PATCH|TRACE)',e:'"',k:"GET POST HEAD PUT DELETE CONNECT OPTIONS PATCH TRACE",i:"\\n",r:10},{cN:"string",b:/\[/,e:/\]/,i:"\\n"},{cN:"string",b:'"',e:'"',i:"\\n"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/actionscript.js b/lib/highlight_js/assets/lang/actionscript.js index eab42f9699a..40e2a305b43 100644 --- a/lib/highlight_js/assets/lang/actionscript.js +++ b/lib/highlight_js/assets/lang/actionscript.js @@ -1 +1 @@ -hljs.registerLanguage("actionscript",function(e){var a="[a-zA-Z_$][a-zA-Z0-9_$]*",c="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)",t={cN:"rest_arg",b:"[.]{3}",e:a,r:10};return{aliases:["as"],k:{keyword:"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with",literal:"true false null undefined"},c:[e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{cN:"package",bK:"package",e:"{",c:[e.TM]},{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.TM]},{cN:"preprocessor",bK:"import include",e:";"},{cN:"function",bK:"function",e:"[{;]",eE:!0,i:"\\S",c:[e.TM,{cN:"params",b:"\\(",e:"\\)",c:[e.ASM,e.QSM,e.CLCM,e.CBCM,t]},{cN:"type",b:":",e:c,r:10}]}]}}); \ No newline at end of file +hljs.registerLanguage("actionscript",function(e){var a="[a-zA-Z_$][a-zA-Z0-9_$]*",t="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)",c={cN:"rest_arg",b:"[.]{3}",e:a,r:10};return{aliases:["as"],k:{keyword:"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with",literal:"true false null undefined"},c:[e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{cN:"class",bK:"package",e:"{",c:[e.TM]},{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.TM]},{cN:"meta",bK:"import include",e:";",k:{"meta-keyword":"import include"}},{cN:"function",bK:"function",e:"[{;]",eE:!0,i:"\\S",c:[e.TM,{cN:"params",b:"\\(",e:"\\)",c:[e.ASM,e.QSM,e.CLCM,e.CBCM,c]},{b:":\\s*"+t}]},e.METHOD_GUARD],i:/#/}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/apache.js b/lib/highlight_js/assets/lang/apache.js index 24877edf3b3..9de481dd370 100644 --- a/lib/highlight_js/assets/lang/apache.js +++ b/lib/highlight_js/assets/lang/apache.js @@ -1 +1 @@ -hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"tag",b:""},{cN:"keyword",b:/\w+/,r:0,k:{common:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}}); \ No newline at end of file +hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/applescript.js b/lib/highlight_js/assets/lang/applescript.js index 28a5f9860cf..be3489866ce 100644 --- a/lib/highlight_js/assets/lang/applescript.js +++ b/lib/highlight_js/assets/lang/applescript.js @@ -1 +1 @@ -hljs.registerLanguage("applescript",function(e){var t=e.inherit(e.QSM,{i:""}),r={cN:"params",b:"\\(",e:"\\)",c:["self",e.CNM,t]},o=e.C("--","$"),n=e.C("\\(\\*","\\*\\)",{c:["self",o]}),a=[o,n,e.HCM];return{aliases:["osascript"],k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without",constant:"AppleScript false linefeed return pi quote result space tab true",type:"alias application boolean class constant date file integer list number real record string text",command:"activate beep count delay launch log offset read round run say summarize write",property:"character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[t,e.CNM,{cN:"type",b:"\\bPOSIX file\\b"},{cN:"command",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"constant",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference))\\b"},{cN:"property",b:"\\b(POSIX path|(date|time) string|quoted form)\\b"},{cN:"function_start",bK:"on",i:"[${=;\\n]",c:[e.UTM,r]}].concat(a),i:"//|->|=>"}}); \ No newline at end of file +hljs.registerLanguage("applescript",function(e){var t=e.inherit(e.QSM,{i:""}),r={cN:"params",b:"\\(",e:"\\)",c:["self",e.CNM,t]},i=e.C("--","$"),o=e.C("\\(\\*","\\*\\)",{c:["self",i]}),n=[i,o,e.HCM];return{aliases:["osascript"],k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without",literal:"AppleScript false linefeed return pi quote result space tab true",built_in:"alias application boolean class constant date file integer list number real record string text activate beep count delay launch log offset read round run say summarize write character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[t,e.CNM,{cN:"built_in",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"literal",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference)|POSIX file|POSIX path|(date|time) string|quoted form)\\b"},{bK:"on",i:"[${=;\\n]",c:[e.UTM,r]}].concat(n),i:"//|->|=>|\\[\\["}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/arduino.js b/lib/highlight_js/assets/lang/arduino.js new file mode 100644 index 00000000000..29f63a22f2e --- /dev/null +++ b/lib/highlight_js/assets/lang/arduino.js @@ -0,0 +1 @@ +hljs.registerLanguage("arduino",function(e){var t={cN:"string",v:[e.inherit(e.QSM,{b:'((u8?|U)|L)?"'}),{b:'(u8?|U)?R"',e:'"',c:[e.BE]},{b:"'\\\\?.",e:"'",i:"."}]},r={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef"},c:[{b:/\\\n/,r:0},{bK:"include",e:"$",k:{"meta-keyword":"include"},c:[e.inherit(t,{cN:"meta-string"}),{cN:"meta-string",b:"<",e:">",i:"\\n"}]},t,e.CLCM,e.CBCM]};return{k:{keyword:"boolean byte word string String array int float private char export virtual operator sizeof uint8_t uint16_t uint32_t uint64_t int8_t int16_t int32_t int64_t dynamic_cast typedef const_cast const struct static_cast union namespace unsigned long volatile static protected bool template mutable public friend auto void enum extern using class asm typeid short reinterpret_cast double register explicit signed typename this inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong",built_in:"setup loop while catch for if do goto try switch case else default break continue return KeyboardController MouseController SoftwareSerial EthernetServer EthernetClient LiquidCrystal RobotControl GSMVoiceCall EthernetUDP EsploraTFT HttpClient RobotMotor WiFiClient GSMScanner FileSystem Scheduler GSMServer YunClient YunServer IPAddress GSMClient GSMModem Keyboard Ethernet Console GSMBand Esplora Stepper Process WiFiUDP GSM_SMS Mailbox USBHost Firmata PImage Client Server GSMPIN FileIO Bridge Serial EEPROM Stream Mouse Audio Servo File Task GPRS WiFi Wire TFT GSM SPI SD runShellCommandAsynchronously analogWriteResolution retrieveCallingNumber printFirmwareVersion analogReadResolution sendDigitalPortPair noListenOnLocalhost readJoystickButton setFirmwareVersion readJoystickSwitch scrollDisplayRight getVoiceCallStatus scrollDisplayLeft writeMicroseconds delayMicroseconds beginTransmission getSignalStrength runAsynchronously getAsynchronously listenOnLocalhost getCurrentCarrier readAccelerometer messageAvailable sendDigitalPorts lineFollowConfig countryNameWrite runShellCommand readStringUntil rewindDirectory readTemperature setClockDivider readLightSensor endTransmission analogReference detachInterrupt countryNameRead attachInterrupt encryptionType readBytesUntil robotNameWrite readMicrophone robotNameRead cityNameWrite userNameWrite readJoystickY readJoystickX mouseReleased openNextFile scanNetworks noInterrupts digitalWrite beginSpeaker mousePressed isActionDone mouseDragged displayLogos noAutoscroll addParameter remoteNumber getModifiers keyboardRead userNameRead waitContinue processInput parseCommand printVersion readNetworks writeMessage blinkVersion cityNameRead readMessage setDataMode parsePacket isListening setBitOrder beginPacket isDirectory motorsWrite drawCompass digitalRead clearScreen serialEvent rightToLeft setTextSize leftToRight requestFrom keyReleased compassRead analogWrite interrupts WiFiServer disconnect playMelody parseFloat autoscroll getPINUsed setPINUsed setTimeout sendAnalog readSlider analogRead beginWrite createChar motorsStop keyPressed tempoWrite readButton subnetMask debugPrint macAddress writeGreen randomSeed attachGPRS readString sendString remotePort releaseAll mouseMoved background getXChange getYChange answerCall getResult voiceCall endPacket constrain getSocket writeJSON getButton available connected findUntil readBytes exitValue readGreen writeBlue startLoop IPAddress isPressed sendSysex pauseMode gatewayIP setCursor getOemKey tuneWrite noDisplay loadImage switchPIN onRequest onReceive changePIN playFile noBuffer parseInt overflow checkPIN knobRead beginTFT bitClear updateIR bitWrite position writeRGB highByte writeRed setSpeed readBlue noStroke remoteIP transfer shutdown hangCall beginSMS endWrite attached maintain noCursor checkReg checkPUK shiftOut isValid shiftIn pulseIn connect println localIP pinMode getIMEI display noBlink process getBand running beginSD drawBMP lowByte setBand release bitRead prepare pointTo readRed setMode noFill remove listen stroke detach attach noTone exists buffer height bitSet circle config cursor random IRread setDNS endSMS getKey micros millis begin print write ready flush width isPIN blink clear press mkdir rmdir close point yield image BSSID click delay read text move peek beep rect line open seek fill size turn stop home find step tone sqrt RSSI SSID end bit tan cos sin pow map abs max min get run put",literal:"DIGITAL_MESSAGE FIRMATA_STRING ANALOG_MESSAGE REPORT_DIGITAL REPORT_ANALOG INPUT_PULLUP SET_PIN_MODE INTERNAL2V56 SYSTEM_RESET LED_BUILTIN INTERNAL1V1 SYSEX_START INTERNAL EXTERNAL DEFAULT OUTPUT INPUT HIGH LOW"},c:[r,e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/armasm.js b/lib/highlight_js/assets/lang/armasm.js new file mode 100644 index 00000000000..f019f56c400 --- /dev/null +++ b/lib/highlight_js/assets/lang/armasm.js @@ -0,0 +1 @@ +hljs.registerLanguage("armasm",function(s){return{cI:!0,aliases:["arm"],l:"\\.?"+s.IR,k:{meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @"},c:[{cN:"keyword",b:"\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?",e:"\\s"},s.C("[;@]","$",{r:0}),s.CBCM,s.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"title",b:"\\|",e:"\\|",i:"\\n",r:0},{cN:"number",v:[{b:"[#$=]?0x[0-9a-f]+"},{b:"[#$=]?0b[01]+"},{b:"[#$=]\\d+"},{b:"\\b\\d+"}],r:0},{cN:"symbol",v:[{b:"^[a-z_\\.\\$][a-z0-9_\\.\\$]+"},{b:"^\\s*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{b:"[=#]\\w+"}],r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/asciidoc.js b/lib/highlight_js/assets/lang/asciidoc.js index 8212bea519c..88081dc84fb 100644 --- a/lib/highlight_js/assets/lang/asciidoc.js +++ b/lib/highlight_js/assets/lang/asciidoc.js @@ -1 +1 @@ -hljs.registerLanguage("asciidoc",function(e){return{aliases:["adoc"],c:[e.C("^/{4,}\\n","\\n/{4,}$",{r:10}),e.C("^//","$",{r:0}),{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"header",b:"^(={1,5}) .+?( \\1)?$",r:10},{cN:"header",b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$",r:10},{cN:"attribute",b:"^:.+?:",e:"\\s",eE:!0,r:10},{cN:"attribute",b:"^\\[.+?\\]$",r:0},{cN:"blockquote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"label",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"smartquote",v:[{b:"``.+?''"},{b:"`.+?'"}]},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{cN:"horizontal_rule",b:"^'{3,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:!0,c:[{b:"(link|image:?):",r:0},{cN:"link_url",b:"\\w",e:"[^\\[]+",r:0},{cN:"link_label",b:"\\[",e:"\\]",eB:!0,eE:!0,r:0}],r:10}]}}); \ No newline at end of file +hljs.registerLanguage("asciidoc",function(e){return{aliases:["adoc"],c:[e.C("^/{4,}\\n","\\n/{4,}$",{r:10}),e.C("^//","$",{r:0}),{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"section",r:10,v:[{b:"^(={1,5}) .+?( \\1)?$"},{b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{cN:"meta",b:"^:.+?:",e:"\\s",eE:!0,r:10},{cN:"meta",b:"^\\[.+?\\]$",r:0},{cN:"quote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"symbol",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"string",v:[{b:"``.+?''"},{b:"`.+?'"}]},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{b:"^'{3,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:!0,c:[{b:"(link|image:?):",r:0},{cN:"link",b:"\\w",e:"[^\\[]+",r:0},{cN:"string",b:"\\[",e:"\\]",eB:!0,eE:!0,r:0}],r:10}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/aspectj.js b/lib/highlight_js/assets/lang/aspectj.js index 570faf4bcbd..0609f5fb9ba 100644 --- a/lib/highlight_js/assets/lang/aspectj.js +++ b/lib/highlight_js/assets/lang/aspectj.js @@ -1 +1 @@ -hljs.registerLanguage("aspectj",function(e){var t="false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance",i="get set args call";return{k:t,i:/<\//,c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",r:0,c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}]},e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"aspect",bK:"aspect",e:/[{;=]/,eE:!0,i:/[:;"\[\]]/,c:[{bK:"extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton"},e.UTM,{b:/\([^\)]*/,e:/[)]+/,k:t+" "+i,eE:!1}]},{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,r:0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"pointcut after before around throwing returning",e:/[)]/,eE:!1,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",rB:!0,c:[e.UTM]}]},{b:/[:]/,rB:!0,e:/[{;]/,r:0,eE:!1,k:t,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",k:t+" "+i},e.QSM]},{bK:"new throw",r:0},{cN:"function",b:/\w+ +\w+(\.)?\w+\s*\([^\)]*\)\s*((throws)[\w\s,]+)?[\{;]/,rB:!0,e:/[{;=]/,k:t,eE:!0,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,r:0,k:t,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},e.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}}); \ No newline at end of file +hljs.registerLanguage("aspectj",function(e){var t="false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance",i="get set args call";return{k:t,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"aspect",e:/[{;=]/,eE:!0,i:/[:;"\[\]]/,c:[{bK:"extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton"},e.UTM,{b:/\([^\)]*/,e:/[)]+/,k:t+" "+i,eE:!1}]},{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,r:0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"pointcut after before around throwing returning",e:/[)]/,eE:!1,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",rB:!0,c:[e.UTM]}]},{b:/[:]/,rB:!0,e:/[{;]/,r:0,eE:!1,k:t,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",k:t+" "+i},e.QSM]},{bK:"new throw",r:0},{cN:"function",b:/\w+ +\w+(\.)?\w+\s*\([^\)]*\)\s*((throws)[\w\s,]+)?[\{;]/,rB:!0,e:/[{;=]/,k:t,eE:!0,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,r:0,k:t,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},e.CNM,{cN:"meta",b:"@[A-Za-z]+"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/autohotkey.js b/lib/highlight_js/assets/lang/autohotkey.js index 9cecca81663..6d198ee2dae 100644 --- a/lib/highlight_js/assets/lang/autohotkey.js +++ b/lib/highlight_js/assets/lang/autohotkey.js @@ -1 +1 @@ -hljs.registerLanguage("autohotkey",function(e){var r={cN:"escape",b:"`[\\s\\S]"},c=e.C(";","$",{r:0}),n=[{cN:"built_in",b:"A_[a-zA-Z0-9]+"},{cN:"built_in",bK:"ComSpec Clipboard ClipboardAll ErrorLevel"}];return{cI:!0,k:{keyword:"Break Continue Else Gosub If Loop Return While",literal:"A true false NOT AND OR"},c:n.concat([r,e.inherit(e.QSM,{c:[r]}),c,{cN:"number",b:e.NR,r:0},{cN:"var_expand",b:"%",e:"%",i:"\\n",c:[r]},{cN:"label",c:[r],v:[{b:'^[^\\n";]+::(?!=)'},{b:'^[^\\n";]+:(?!=)',r:0}]},{b:",\\s*,",r:10}])}}); \ No newline at end of file +hljs.registerLanguage("autohotkey",function(e){var r={b:/`[\s\S]/};return{cI:!0,k:{keyword:"Break Continue Else Gosub If Loop Return While",literal:"A|0 true false NOT AND OR",built_in:"ComSpec Clipboard ClipboardAll ErrorLevel"},c:[{cN:"built_in",b:"A_[a-zA-Z0-9]+"},r,e.inherit(e.QSM,{c:[r]}),e.C(";","$",{r:0}),{cN:"number",b:e.NR,r:0},{cN:"variable",b:"%",e:"%",i:"\\n",c:[r]},{cN:"symbol",c:[r],v:[{b:'^[^\\n";]+::(?!=)'},{b:'^[^\\n";]+:(?!=)',r:0}]},{b:",\\s*,"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/autoit.js b/lib/highlight_js/assets/lang/autoit.js new file mode 100644 index 00000000000..f92fa905a6e --- /dev/null +++ b/lib/highlight_js/assets/lang/autoit.js @@ -0,0 +1,2 @@ +hljs.registerLanguage("autoit",function(e){var t="ByRef Case Const ContinueCase ContinueLoop Default Dim Do Else ElseIf EndFunc EndIf EndSelect EndSwitch EndWith Enum Exit ExitLoop For Func Global If In Local Next ReDim Return Select Static Step Switch Then To Until Volatile WEnd While With",r="True False And Null Not Or",i="Abs ACos AdlibRegister AdlibUnRegister Asc AscW ASin Assign ATan AutoItSetOption AutoItWinGetTitle AutoItWinSetTitle Beep Binary BinaryLen BinaryMid BinaryToString BitAND BitNOT BitOR BitRotate BitShift BitXOR BlockInput Break Call CDTray Ceiling Chr ChrW ClipGet ClipPut ConsoleRead ConsoleWrite ConsoleWriteError ControlClick ControlCommand ControlDisable ControlEnable ControlFocus ControlGetFocus ControlGetHandle ControlGetPos ControlGetText ControlHide ControlListView ControlMove ControlSend ControlSetText ControlShow ControlTreeView Cos Dec DirCopy DirCreate DirGetSize DirMove DirRemove DllCall DllCallAddress DllCallbackFree DllCallbackGetPtr DllCallbackRegister DllClose DllOpen DllStructCreate DllStructGetData DllStructGetPtr DllStructGetSize DllStructSetData DriveGetDrive DriveGetFileSystem DriveGetLabel DriveGetSerial DriveGetType DriveMapAdd DriveMapDel DriveMapGet DriveSetLabel DriveSpaceFree DriveSpaceTotal DriveStatus EnvGet EnvSet EnvUpdate Eval Execute Exp FileChangeDir FileClose FileCopy FileCreateNTFSLink FileCreateShortcut FileDelete FileExists FileFindFirstFile FileFindNextFile FileFlush FileGetAttrib FileGetEncoding FileGetLongName FileGetPos FileGetShortcut FileGetShortName FileGetSize FileGetTime FileGetVersion FileInstall FileMove FileOpen FileOpenDialog FileRead FileReadLine FileReadToArray FileRecycle FileRecycleEmpty FileSaveDialog FileSelectFolder FileSetAttrib FileSetEnd FileSetPos FileSetTime FileWrite FileWriteLine Floor FtpSetProxy FuncName GUICreate GUICtrlCreateAvi GUICtrlCreateButton GUICtrlCreateCheckbox GUICtrlCreateCombo GUICtrlCreateContextMenu GUICtrlCreateDate GUICtrlCreateDummy GUICtrlCreateEdit GUICtrlCreateGraphic GUICtrlCreateGroup GUICtrlCreateIcon GUICtrlCreateInput GUICtrlCreateLabel GUICtrlCreateList GUICtrlCreateListView GUICtrlCreateListViewItem GUICtrlCreateMenu GUICtrlCreateMenuItem GUICtrlCreateMonthCal GUICtrlCreateObj GUICtrlCreatePic GUICtrlCreateProgress GUICtrlCreateRadio GUICtrlCreateSlider GUICtrlCreateTab GUICtrlCreateTabItem GUICtrlCreateTreeView GUICtrlCreateTreeViewItem GUICtrlCreateUpdown GUICtrlDelete GUICtrlGetHandle GUICtrlGetState GUICtrlRead GUICtrlRecvMsg GUICtrlRegisterListViewSort GUICtrlSendMsg GUICtrlSendToDummy GUICtrlSetBkColor GUICtrlSetColor GUICtrlSetCursor GUICtrlSetData GUICtrlSetDefBkColor GUICtrlSetDefColor GUICtrlSetFont GUICtrlSetGraphic GUICtrlSetImage GUICtrlSetLimit GUICtrlSetOnEvent GUICtrlSetPos GUICtrlSetResizing GUICtrlSetState GUICtrlSetStyle GUICtrlSetTip GUIDelete GUIGetCursorInfo GUIGetMsg GUIGetStyle GUIRegisterMsg GUISetAccelerators GUISetBkColor GUISetCoord GUISetCursor GUISetFont GUISetHelp GUISetIcon GUISetOnEvent GUISetState GUISetStyle GUIStartGroup GUISwitch Hex HotKeySet HttpSetProxy HttpSetUserAgent HWnd InetClose InetGet InetGetInfo InetGetSize InetRead IniDelete IniRead IniReadSection IniReadSectionNames IniRenameSection IniWrite IniWriteSection InputBox Int IsAdmin IsArray IsBinary IsBool IsDeclared IsDllStruct IsFloat IsFunc IsHWnd IsInt IsKeyword IsNumber IsObj IsPtr IsString Log MemGetStats Mod MouseClick MouseClickDrag MouseDown MouseGetCursor MouseGetPos MouseMove MouseUp MouseWheel MsgBox Number ObjCreate ObjCreateInterface ObjEvent ObjGet ObjName OnAutoItExitRegister OnAutoItExitUnRegister Opt Ping PixelChecksum PixelGetColor PixelSearch ProcessClose ProcessExists ProcessGetStats ProcessList ProcessSetPriority ProcessWait ProcessWaitClose ProgressOff ProgressOn ProgressSet Ptr Random RegDelete RegEnumKey RegEnumVal RegRead RegWrite Round Run RunAs RunAsWait RunWait Send SendKeepActive SetError SetExtended ShellExecute ShellExecuteWait Shutdown Sin Sleep SoundPlay SoundSetWaveVolume SplashImageOn SplashOff SplashTextOn Sqrt SRandom StatusbarGetText StderrRead StdinWrite StdioClose StdoutRead String StringAddCR StringCompare StringFormat StringFromASCIIArray StringInStr StringIsAlNum StringIsAlpha StringIsASCII StringIsDigit StringIsFloat StringIsInt StringIsLower StringIsSpace StringIsUpper StringIsXDigit StringLeft StringLen StringLower StringMid StringRegExp StringRegExpReplace StringReplace StringReverse StringRight StringSplit StringStripCR StringStripWS StringToASCIIArray StringToBinary StringTrimLeft StringTrimRight StringUpper Tan TCPAccept TCPCloseSocket TCPConnect TCPListen TCPNameToIP TCPRecv TCPSend TCPShutdown TCPStartup TimerDiff TimerInit ToolTip TrayCreateItem TrayCreateMenu TrayGetMsg TrayItemDelete TrayItemGetHandle TrayItemGetState TrayItemGetText TrayItemSetOnEvent TrayItemSetState TrayItemSetText TraySetClick TraySetIcon TraySetOnEvent TraySetPauseIcon TraySetState TraySetToolTip TrayTip UBound UDPBind UDPCloseSocket UDPOpen UDPRecv UDPSend UDPShutdown UDPStartup VarGetType WinActivate WinActive WinClose WinExists WinFlash WinGetCaretPos WinGetClassList WinGetClientSize WinGetHandle WinGetPos WinGetProcess WinGetState WinGetText WinGetTitle WinKill WinList WinMenuSelectItem WinMinimizeAll WinMinimizeAllUndo WinMove WinSetOnTop WinSetState WinSetTitle WinSetTrans WinWait WinWaitActive WinWaitClose WinWaitNotActive Array1DToHistogram ArrayAdd ArrayBinarySearch ArrayColDelete ArrayColInsert ArrayCombinations ArrayConcatenate ArrayDelete ArrayDisplay ArrayExtract ArrayFindAll ArrayInsert ArrayMax ArrayMaxIndex ArrayMin ArrayMinIndex ArrayPermute ArrayPop ArrayPush ArrayReverse ArraySearch ArrayShuffle ArraySort ArraySwap ArrayToClip ArrayToString ArrayTranspose ArrayTrim ArrayUnique Assert ChooseColor ChooseFont ClipBoard_ChangeChain ClipBoard_Close ClipBoard_CountFormats ClipBoard_Empty ClipBoard_EnumFormats ClipBoard_FormatStr ClipBoard_GetData ClipBoard_GetDataEx ClipBoard_GetFormatName ClipBoard_GetOpenWindow ClipBoard_GetOwner ClipBoard_GetPriorityFormat ClipBoard_GetSequenceNumber ClipBoard_GetViewer ClipBoard_IsFormatAvailable ClipBoard_Open ClipBoard_RegisterFormat ClipBoard_SetData ClipBoard_SetDataEx ClipBoard_SetViewer ClipPutFile ColorConvertHSLtoRGB ColorConvertRGBtoHSL ColorGetBlue ColorGetCOLORREF ColorGetGreen ColorGetRed ColorGetRGB ColorSetCOLORREF ColorSetRGB Crypt_DecryptData Crypt_DecryptFile Crypt_DeriveKey Crypt_DestroyKey Crypt_EncryptData Crypt_EncryptFile Crypt_GenRandom Crypt_HashData Crypt_HashFile Crypt_Shutdown Crypt_Startup DateAdd DateDayOfWeek DateDaysInMonth DateDiff DateIsLeapYear DateIsValid DateTimeFormat DateTimeSplit DateToDayOfWeek DateToDayOfWeekISO DateToDayValue DateToMonth Date_Time_CompareFileTime Date_Time_DOSDateTimeToArray Date_Time_DOSDateTimeToFileTime Date_Time_DOSDateTimeToStr Date_Time_DOSDateToArray Date_Time_DOSDateToStr Date_Time_DOSTimeToArray Date_Time_DOSTimeToStr Date_Time_EncodeFileTime Date_Time_EncodeSystemTime Date_Time_FileTimeToArray Date_Time_FileTimeToDOSDateTime Date_Time_FileTimeToLocalFileTime Date_Time_FileTimeToStr Date_Time_FileTimeToSystemTime Date_Time_GetFileTime Date_Time_GetLocalTime Date_Time_GetSystemTime Date_Time_GetSystemTimeAdjustment Date_Time_GetSystemTimeAsFileTime Date_Time_GetSystemTimes Date_Time_GetTickCount Date_Time_GetTimeZoneInformation Date_Time_LocalFileTimeToFileTime Date_Time_SetFileTime Date_Time_SetLocalTime Date_Time_SetSystemTime Date_Time_SetSystemTimeAdjustment Date_Time_SetTimeZoneInformation Date_Time_SystemTimeToArray Date_Time_SystemTimeToDateStr Date_Time_SystemTimeToDateTimeStr Date_Time_SystemTimeToFileTime Date_Time_SystemTimeToTimeStr Date_Time_SystemTimeToTzSpecificLocalTime Date_Time_TzSpecificLocalTimeToSystemTime DayValueToDate DebugBugReportEnv DebugCOMError DebugOut DebugReport DebugReportEx DebugReportVar DebugSetup Degree EventLog__Backup EventLog__Clear EventLog__Close EventLog__Count EventLog__DeregisterSource EventLog__Full EventLog__Notify EventLog__Oldest EventLog__Open EventLog__OpenBackup EventLog__Read EventLog__RegisterSource EventLog__Report Excel_BookAttach Excel_BookClose Excel_BookList Excel_BookNew Excel_BookOpen Excel_BookOpenText Excel_BookSave Excel_BookSaveAs Excel_Close Excel_ColumnToLetter Excel_ColumnToNumber Excel_ConvertFormula Excel_Export Excel_FilterGet Excel_FilterSet Excel_Open Excel_PictureAdd Excel_Print Excel_RangeCopyPaste Excel_RangeDelete Excel_RangeFind Excel_RangeInsert Excel_RangeLinkAddRemove Excel_RangeRead Excel_RangeReplace Excel_RangeSort Excel_RangeValidate Excel_RangeWrite Excel_SheetAdd Excel_SheetCopyMove Excel_SheetDelete Excel_SheetList FileCountLines FileCreate FileListToArray FileListToArrayRec FilePrint FileReadToArray FileWriteFromArray FileWriteLog FileWriteToLine FTP_Close FTP_Command FTP_Connect FTP_DecodeInternetStatus FTP_DirCreate FTP_DirDelete FTP_DirGetCurrent FTP_DirPutContents FTP_DirSetCurrent FTP_FileClose FTP_FileDelete FTP_FileGet FTP_FileGetSize FTP_FileOpen FTP_FilePut FTP_FileRead FTP_FileRename FTP_FileTimeLoHiToStr FTP_FindFileClose FTP_FindFileFirst FTP_FindFileNext FTP_GetLastResponseInfo FTP_ListToArray FTP_ListToArray2D FTP_ListToArrayEx FTP_Open FTP_ProgressDownload FTP_ProgressUpload FTP_SetStatusCallback GDIPlus_ArrowCapCreate GDIPlus_ArrowCapDispose GDIPlus_ArrowCapGetFillState GDIPlus_ArrowCapGetHeight GDIPlus_ArrowCapGetMiddleInset GDIPlus_ArrowCapGetWidth GDIPlus_ArrowCapSetFillState GDIPlus_ArrowCapSetHeight GDIPlus_ArrowCapSetMiddleInset GDIPlus_ArrowCapSetWidth GDIPlus_BitmapApplyEffect GDIPlus_BitmapApplyEffectEx GDIPlus_BitmapCloneArea GDIPlus_BitmapConvertFormat GDIPlus_BitmapCreateApplyEffect GDIPlus_BitmapCreateApplyEffectEx GDIPlus_BitmapCreateDIBFromBitmap GDIPlus_BitmapCreateFromFile GDIPlus_BitmapCreateFromGraphics GDIPlus_BitmapCreateFromHBITMAP GDIPlus_BitmapCreateFromHICON GDIPlus_BitmapCreateFromHICON32 GDIPlus_BitmapCreateFromMemory GDIPlus_BitmapCreateFromResource GDIPlus_BitmapCreateFromScan0 GDIPlus_BitmapCreateFromStream GDIPlus_BitmapCreateHBITMAPFromBitmap GDIPlus_BitmapDispose GDIPlus_BitmapGetHistogram GDIPlus_BitmapGetHistogramEx GDIPlus_BitmapGetHistogramSize GDIPlus_BitmapGetPixel GDIPlus_BitmapLockBits GDIPlus_BitmapSetPixel GDIPlus_BitmapUnlockBits GDIPlus_BrushClone GDIPlus_BrushCreateSolid GDIPlus_BrushDispose GDIPlus_BrushGetSolidColor GDIPlus_BrushGetType GDIPlus_BrushSetSolidColor GDIPlus_ColorMatrixCreate GDIPlus_ColorMatrixCreateGrayScale GDIPlus_ColorMatrixCreateNegative GDIPlus_ColorMatrixCreateSaturation GDIPlus_ColorMatrixCreateScale GDIPlus_ColorMatrixCreateTranslate GDIPlus_CustomLineCapClone GDIPlus_CustomLineCapCreate GDIPlus_CustomLineCapDispose GDIPlus_CustomLineCapGetStrokeCaps GDIPlus_CustomLineCapSetStrokeCaps GDIPlus_Decoders GDIPlus_DecodersGetCount GDIPlus_DecodersGetSize GDIPlus_DrawImageFX GDIPlus_DrawImageFXEx GDIPlus_DrawImagePoints GDIPlus_EffectCreate GDIPlus_EffectCreateBlur GDIPlus_EffectCreateBrightnessContrast GDIPlus_EffectCreateColorBalance GDIPlus_EffectCreateColorCurve GDIPlus_EffectCreateColorLUT GDIPlus_EffectCreateColorMatrix GDIPlus_EffectCreateHueSaturationLightness GDIPlus_EffectCreateLevels GDIPlus_EffectCreateRedEyeCorrection GDIPlus_EffectCreateSharpen GDIPlus_EffectCreateTint GDIPlus_EffectDispose GDIPlus_EffectGetParameters GDIPlus_EffectSetParameters GDIPlus_Encoders GDIPlus_EncodersGetCLSID GDIPlus_EncodersGetCount GDIPlus_EncodersGetParamList GDIPlus_EncodersGetParamListSize GDIPlus_EncodersGetSize GDIPlus_FontCreate GDIPlus_FontDispose GDIPlus_FontFamilyCreate GDIPlus_FontFamilyCreateFromCollection GDIPlus_FontFamilyDispose GDIPlus_FontFamilyGetCellAscent GDIPlus_FontFamilyGetCellDescent GDIPlus_FontFamilyGetEmHeight GDIPlus_FontFamilyGetLineSpacing GDIPlus_FontGetHeight GDIPlus_FontPrivateAddFont GDIPlus_FontPrivateAddMemoryFont GDIPlus_FontPrivateCollectionDispose GDIPlus_FontPrivateCreateCollection GDIPlus_GraphicsClear GDIPlus_GraphicsCreateFromHDC GDIPlus_GraphicsCreateFromHWND GDIPlus_GraphicsDispose GDIPlus_GraphicsDrawArc GDIPlus_GraphicsDrawBezier GDIPlus_GraphicsDrawClosedCurve GDIPlus_GraphicsDrawClosedCurve2 GDIPlus_GraphicsDrawCurve GDIPlus_GraphicsDrawCurve2 GDIPlus_GraphicsDrawEllipse GDIPlus_GraphicsDrawImage GDIPlus_GraphicsDrawImagePointsRect GDIPlus_GraphicsDrawImageRect GDIPlus_GraphicsDrawImageRectRect GDIPlus_GraphicsDrawLine GDIPlus_GraphicsDrawPath GDIPlus_GraphicsDrawPie GDIPlus_GraphicsDrawPolygon GDIPlus_GraphicsDrawRect GDIPlus_GraphicsDrawString GDIPlus_GraphicsDrawStringEx GDIPlus_GraphicsFillClosedCurve GDIPlus_GraphicsFillClosedCurve2 GDIPlus_GraphicsFillEllipse GDIPlus_GraphicsFillPath GDIPlus_GraphicsFillPie GDIPlus_GraphicsFillPolygon GDIPlus_GraphicsFillRect GDIPlus_GraphicsFillRegion GDIPlus_GraphicsGetCompositingMode GDIPlus_GraphicsGetCompositingQuality GDIPlus_GraphicsGetDC GDIPlus_GraphicsGetInterpolationMode GDIPlus_GraphicsGetSmoothingMode GDIPlus_GraphicsGetTransform GDIPlus_GraphicsMeasureCharacterRanges GDIPlus_GraphicsMeasureString GDIPlus_GraphicsReleaseDC GDIPlus_GraphicsResetClip GDIPlus_GraphicsResetTransform GDIPlus_GraphicsRestore GDIPlus_GraphicsRotateTransform GDIPlus_GraphicsSave GDIPlus_GraphicsScaleTransform GDIPlus_GraphicsSetClipPath GDIPlus_GraphicsSetClipRect GDIPlus_GraphicsSetClipRegion GDIPlus_GraphicsSetCompositingMode GDIPlus_GraphicsSetCompositingQuality GDIPlus_GraphicsSetInterpolationMode GDIPlus_GraphicsSetPixelOffsetMode GDIPlus_GraphicsSetSmoothingMode GDIPlus_GraphicsSetTextRenderingHint GDIPlus_GraphicsSetTransform GDIPlus_GraphicsTransformPoints GDIPlus_GraphicsTranslateTransform GDIPlus_HatchBrushCreate GDIPlus_HICONCreateFromBitmap GDIPlus_ImageAttributesCreate GDIPlus_ImageAttributesDispose GDIPlus_ImageAttributesSetColorKeys GDIPlus_ImageAttributesSetColorMatrix GDIPlus_ImageDispose GDIPlus_ImageGetDimension GDIPlus_ImageGetFlags GDIPlus_ImageGetGraphicsContext GDIPlus_ImageGetHeight GDIPlus_ImageGetHorizontalResolution GDIPlus_ImageGetPixelFormat GDIPlus_ImageGetRawFormat GDIPlus_ImageGetThumbnail GDIPlus_ImageGetType GDIPlus_ImageGetVerticalResolution GDIPlus_ImageGetWidth GDIPlus_ImageLoadFromFile GDIPlus_ImageLoadFromStream GDIPlus_ImageResize GDIPlus_ImageRotateFlip GDIPlus_ImageSaveToFile GDIPlus_ImageSaveToFileEx GDIPlus_ImageSaveToStream GDIPlus_ImageScale GDIPlus_LineBrushCreate GDIPlus_LineBrushCreateFromRect GDIPlus_LineBrushCreateFromRectWithAngle GDIPlus_LineBrushGetColors GDIPlus_LineBrushGetRect GDIPlus_LineBrushMultiplyTransform GDIPlus_LineBrushResetTransform GDIPlus_LineBrushSetBlend GDIPlus_LineBrushSetColors GDIPlus_LineBrushSetGammaCorrection GDIPlus_LineBrushSetLinearBlend GDIPlus_LineBrushSetPresetBlend GDIPlus_LineBrushSetSigmaBlend GDIPlus_LineBrushSetTransform GDIPlus_MatrixClone GDIPlus_MatrixCreate GDIPlus_MatrixDispose GDIPlus_MatrixGetElements GDIPlus_MatrixInvert GDIPlus_MatrixMultiply GDIPlus_MatrixRotate GDIPlus_MatrixScale GDIPlus_MatrixSetElements GDIPlus_MatrixShear GDIPlus_MatrixTransformPoints GDIPlus_MatrixTranslate GDIPlus_PaletteInitialize GDIPlus_ParamAdd GDIPlus_ParamInit GDIPlus_ParamSize GDIPlus_PathAddArc GDIPlus_PathAddBezier GDIPlus_PathAddClosedCurve GDIPlus_PathAddClosedCurve2 GDIPlus_PathAddCurve GDIPlus_PathAddCurve2 GDIPlus_PathAddCurve3 GDIPlus_PathAddEllipse GDIPlus_PathAddLine GDIPlus_PathAddLine2 GDIPlus_PathAddPath GDIPlus_PathAddPie GDIPlus_PathAddPolygon GDIPlus_PathAddRectangle GDIPlus_PathAddString GDIPlus_PathBrushCreate GDIPlus_PathBrushCreateFromPath GDIPlus_PathBrushGetCenterPoint GDIPlus_PathBrushGetFocusScales GDIPlus_PathBrushGetPointCount GDIPlus_PathBrushGetRect GDIPlus_PathBrushGetWrapMode GDIPlus_PathBrushMultiplyTransform GDIPlus_PathBrushResetTransform GDIPlus_PathBrushSetBlend GDIPlus_PathBrushSetCenterColor GDIPlus_PathBrushSetCenterPoint GDIPlus_PathBrushSetFocusScales GDIPlus_PathBrushSetGammaCorrection GDIPlus_PathBrushSetLinearBlend GDIPlus_PathBrushSetPresetBlend GDIPlus_PathBrushSetSigmaBlend GDIPlus_PathBrushSetSurroundColor GDIPlus_PathBrushSetSurroundColorsWithCount GDIPlus_PathBrushSetTransform GDIPlus_PathBrushSetWrapMode GDIPlus_PathClone GDIPlus_PathCloseFigure GDIPlus_PathCreate GDIPlus_PathCreate2 GDIPlus_PathDispose GDIPlus_PathFlatten GDIPlus_PathGetData GDIPlus_PathGetFillMode GDIPlus_PathGetLastPoint GDIPlus_PathGetPointCount GDIPlus_PathGetPoints GDIPlus_PathGetWorldBounds GDIPlus_PathIsOutlineVisiblePoint GDIPlus_PathIsVisiblePoint GDIPlus_PathIterCreate GDIPlus_PathIterDispose GDIPlus_PathIterGetSubpathCount GDIPlus_PathIterNextMarkerPath GDIPlus_PathIterNextSubpathPath GDIPlus_PathIterRewind GDIPlus_PathReset GDIPlus_PathReverse GDIPlus_PathSetFillMode GDIPlus_PathSetMarker GDIPlus_PathStartFigure GDIPlus_PathTransform GDIPlus_PathWarp GDIPlus_PathWiden GDIPlus_PathWindingModeOutline GDIPlus_PenCreate GDIPlus_PenCreate2 GDIPlus_PenDispose GDIPlus_PenGetAlignment GDIPlus_PenGetColor GDIPlus_PenGetCustomEndCap GDIPlus_PenGetDashCap GDIPlus_PenGetDashStyle GDIPlus_PenGetEndCap GDIPlus_PenGetMiterLimit GDIPlus_PenGetWidth GDIPlus_PenSetAlignment GDIPlus_PenSetColor GDIPlus_PenSetCustomEndCap GDIPlus_PenSetDashCap GDIPlus_PenSetDashStyle GDIPlus_PenSetEndCap GDIPlus_PenSetLineCap GDIPlus_PenSetLineJoin GDIPlus_PenSetMiterLimit GDIPlus_PenSetStartCap GDIPlus_PenSetWidth GDIPlus_RectFCreate GDIPlus_RegionClone GDIPlus_RegionCombinePath GDIPlus_RegionCombineRect GDIPlus_RegionCombineRegion GDIPlus_RegionCreate GDIPlus_RegionCreateFromPath GDIPlus_RegionCreateFromRect GDIPlus_RegionDispose GDIPlus_RegionGetBounds GDIPlus_RegionGetHRgn GDIPlus_RegionTransform GDIPlus_RegionTranslate GDIPlus_Shutdown GDIPlus_Startup GDIPlus_StringFormatCreate GDIPlus_StringFormatDispose GDIPlus_StringFormatGetMeasurableCharacterRangeCount GDIPlus_StringFormatSetAlign GDIPlus_StringFormatSetLineAlign GDIPlus_StringFormatSetMeasurableCharacterRanges GDIPlus_TextureCreate GDIPlus_TextureCreate2 GDIPlus_TextureCreateIA GetIP GUICtrlAVI_Close GUICtrlAVI_Create GUICtrlAVI_Destroy GUICtrlAVI_IsPlaying GUICtrlAVI_Open GUICtrlAVI_OpenEx GUICtrlAVI_Play GUICtrlAVI_Seek GUICtrlAVI_Show GUICtrlAVI_Stop GUICtrlButton_Click GUICtrlButton_Create GUICtrlButton_Destroy GUICtrlButton_Enable GUICtrlButton_GetCheck GUICtrlButton_GetFocus GUICtrlButton_GetIdealSize GUICtrlButton_GetImage GUICtrlButton_GetImageList GUICtrlButton_GetNote GUICtrlButton_GetNoteLength GUICtrlButton_GetSplitInfo GUICtrlButton_GetState GUICtrlButton_GetText GUICtrlButton_GetTextMargin GUICtrlButton_SetCheck GUICtrlButton_SetDontClick GUICtrlButton_SetFocus GUICtrlButton_SetImage GUICtrlButton_SetImageList GUICtrlButton_SetNote GUICtrlButton_SetShield GUICtrlButton_SetSize GUICtrlButton_SetSplitInfo GUICtrlButton_SetState GUICtrlButton_SetStyle GUICtrlButton_SetText GUICtrlButton_SetTextMargin GUICtrlButton_Show GUICtrlComboBoxEx_AddDir GUICtrlComboBoxEx_AddString GUICtrlComboBoxEx_BeginUpdate GUICtrlComboBoxEx_Create GUICtrlComboBoxEx_CreateSolidBitMap GUICtrlComboBoxEx_DeleteString GUICtrlComboBoxEx_Destroy GUICtrlComboBoxEx_EndUpdate GUICtrlComboBoxEx_FindStringExact GUICtrlComboBoxEx_GetComboBoxInfo GUICtrlComboBoxEx_GetComboControl GUICtrlComboBoxEx_GetCount GUICtrlComboBoxEx_GetCurSel GUICtrlComboBoxEx_GetDroppedControlRect GUICtrlComboBoxEx_GetDroppedControlRectEx GUICtrlComboBoxEx_GetDroppedState GUICtrlComboBoxEx_GetDroppedWidth GUICtrlComboBoxEx_GetEditControl GUICtrlComboBoxEx_GetEditSel GUICtrlComboBoxEx_GetEditText GUICtrlComboBoxEx_GetExtendedStyle GUICtrlComboBoxEx_GetExtendedUI GUICtrlComboBoxEx_GetImageList GUICtrlComboBoxEx_GetItem GUICtrlComboBoxEx_GetItemEx GUICtrlComboBoxEx_GetItemHeight GUICtrlComboBoxEx_GetItemImage GUICtrlComboBoxEx_GetItemIndent GUICtrlComboBoxEx_GetItemOverlayImage GUICtrlComboBoxEx_GetItemParam GUICtrlComboBoxEx_GetItemSelectedImage GUICtrlComboBoxEx_GetItemText GUICtrlComboBoxEx_GetItemTextLen GUICtrlComboBoxEx_GetList GUICtrlComboBoxEx_GetListArray GUICtrlComboBoxEx_GetLocale GUICtrlComboBoxEx_GetLocaleCountry GUICtrlComboBoxEx_GetLocaleLang GUICtrlComboBoxEx_GetLocalePrimLang GUICtrlComboBoxEx_GetLocaleSubLang GUICtrlComboBoxEx_GetMinVisible GUICtrlComboBoxEx_GetTopIndex GUICtrlComboBoxEx_GetUnicode GUICtrlComboBoxEx_InitStorage GUICtrlComboBoxEx_InsertString GUICtrlComboBoxEx_LimitText GUICtrlComboBoxEx_ReplaceEditSel GUICtrlComboBoxEx_ResetContent GUICtrlComboBoxEx_SetCurSel GUICtrlComboBoxEx_SetDroppedWidth GUICtrlComboBoxEx_SetEditSel GUICtrlComboBoxEx_SetEditText GUICtrlComboBoxEx_SetExtendedStyle GUICtrlComboBoxEx_SetExtendedUI GUICtrlComboBoxEx_SetImageList GUICtrlComboBoxEx_SetItem GUICtrlComboBoxEx_SetItemEx GUICtrlComboBoxEx_SetItemHeight GUICtrlComboBoxEx_SetItemImage GUICtrlComboBoxEx_SetItemIndent GUICtrlComboBoxEx_SetItemOverlayImage GUICtrlComboBoxEx_SetItemParam GUICtrlComboBoxEx_SetItemSelectedImage GUICtrlComboBoxEx_SetMinVisible GUICtrlComboBoxEx_SetTopIndex GUICtrlComboBoxEx_SetUnicode GUICtrlComboBoxEx_ShowDropDown GUICtrlComboBox_AddDir GUICtrlComboBox_AddString GUICtrlComboBox_AutoComplete GUICtrlComboBox_BeginUpdate GUICtrlComboBox_Create GUICtrlComboBox_DeleteString GUICtrlComboBox_Destroy GUICtrlComboBox_EndUpdate GUICtrlComboBox_FindString GUICtrlComboBox_FindStringExact GUICtrlComboBox_GetComboBoxInfo GUICtrlComboBox_GetCount GUICtrlComboBox_GetCueBanner GUICtrlComboBox_GetCurSel GUICtrlComboBox_GetDroppedControlRect GUICtrlComboBox_GetDroppedControlRectEx GUICtrlComboBox_GetDroppedState GUICtrlComboBox_GetDroppedWidth GUICtrlComboBox_GetEditSel GUICtrlComboBox_GetEditText GUICtrlComboBox_GetExtendedUI GUICtrlComboBox_GetHorizontalExtent GUICtrlComboBox_GetItemHeight GUICtrlComboBox_GetLBText GUICtrlComboBox_GetLBTextLen GUICtrlComboBox_GetList GUICtrlComboBox_GetListArray GUICtrlComboBox_GetLocale GUICtrlComboBox_GetLocaleCountry GUICtrlComboBox_GetLocaleLang GUICtrlComboBox_GetLocalePrimLang GUICtrlComboBox_GetLocaleSubLang GUICtrlComboBox_GetMinVisible GUICtrlComboBox_GetTopIndex GUICtrlComboBox_InitStorage GUICtrlComboBox_InsertString GUICtrlComboBox_LimitText GUICtrlComboBox_ReplaceEditSel GUICtrlComboBox_ResetContent GUICtrlComboBox_SelectString GUICtrlComboBox_SetCueBanner GUICtrlComboBox_SetCurSel GUICtrlComboBox_SetDroppedWidth GUICtrlComboBox_SetEditSel GUICtrlComboBox_SetEditText GUICtrlComboBox_SetExtendedUI GUICtrlComboBox_SetHorizontalExtent GUICtrlComboBox_SetItemHeight GUICtrlComboBox_SetMinVisible GUICtrlComboBox_SetTopIndex GUICtrlComboBox_ShowDropDown GUICtrlDTP_Create GUICtrlDTP_Destroy GUICtrlDTP_GetMCColor GUICtrlDTP_GetMCFont GUICtrlDTP_GetMonthCal GUICtrlDTP_GetRange GUICtrlDTP_GetRangeEx GUICtrlDTP_GetSystemTime GUICtrlDTP_GetSystemTimeEx GUICtrlDTP_SetFormat GUICtrlDTP_SetMCColor GUICtrlDTP_SetMCFont GUICtrlDTP_SetRange GUICtrlDTP_SetRangeEx GUICtrlDTP_SetSystemTime GUICtrlDTP_SetSystemTimeEx GUICtrlEdit_AppendText GUICtrlEdit_BeginUpdate GUICtrlEdit_CanUndo GUICtrlEdit_CharFromPos GUICtrlEdit_Create GUICtrlEdit_Destroy GUICtrlEdit_EmptyUndoBuffer GUICtrlEdit_EndUpdate GUICtrlEdit_Find GUICtrlEdit_FmtLines GUICtrlEdit_GetCueBanner GUICtrlEdit_GetFirstVisibleLine GUICtrlEdit_GetLimitText GUICtrlEdit_GetLine GUICtrlEdit_GetLineCount GUICtrlEdit_GetMargins GUICtrlEdit_GetModify GUICtrlEdit_GetPasswordChar GUICtrlEdit_GetRECT GUICtrlEdit_GetRECTEx GUICtrlEdit_GetSel GUICtrlEdit_GetText GUICtrlEdit_GetTextLen GUICtrlEdit_HideBalloonTip GUICtrlEdit_InsertText GUICtrlEdit_LineFromChar GUICtrlEdit_LineIndex GUICtrlEdit_LineLength GUICtrlEdit_LineScroll GUICtrlEdit_PosFromChar GUICtrlEdit_ReplaceSel GUICtrlEdit_Scroll GUICtrlEdit_SetCueBanner GUICtrlEdit_SetLimitText GUICtrlEdit_SetMargins GUICtrlEdit_SetModify GUICtrlEdit_SetPasswordChar GUICtrlEdit_SetReadOnly GUICtrlEdit_SetRECT GUICtrlEdit_SetRECTEx GUICtrlEdit_SetRECTNP GUICtrlEdit_SetRectNPEx GUICtrlEdit_SetSel GUICtrlEdit_SetTabStops GUICtrlEdit_SetText GUICtrlEdit_ShowBalloonTip GUICtrlEdit_Undo GUICtrlHeader_AddItem GUICtrlHeader_ClearFilter GUICtrlHeader_ClearFilterAll GUICtrlHeader_Create GUICtrlHeader_CreateDragImage GUICtrlHeader_DeleteItem GUICtrlHeader_Destroy GUICtrlHeader_EditFilter GUICtrlHeader_GetBitmapMargin GUICtrlHeader_GetImageList GUICtrlHeader_GetItem GUICtrlHeader_GetItemAlign GUICtrlHeader_GetItemBitmap GUICtrlHeader_GetItemCount GUICtrlHeader_GetItemDisplay GUICtrlHeader_GetItemFlags GUICtrlHeader_GetItemFormat GUICtrlHeader_GetItemImage GUICtrlHeader_GetItemOrder GUICtrlHeader_GetItemParam GUICtrlHeader_GetItemRect GUICtrlHeader_GetItemRectEx GUICtrlHeader_GetItemText GUICtrlHeader_GetItemWidth GUICtrlHeader_GetOrderArray GUICtrlHeader_GetUnicodeFormat GUICtrlHeader_HitTest GUICtrlHeader_InsertItem GUICtrlHeader_Layout GUICtrlHeader_OrderToIndex GUICtrlHeader_SetBitmapMargin GUICtrlHeader_SetFilterChangeTimeout GUICtrlHeader_SetHotDivider GUICtrlHeader_SetImageList GUICtrlHeader_SetItem GUICtrlHeader_SetItemAlign GUICtrlHeader_SetItemBitmap GUICtrlHeader_SetItemDisplay GUICtrlHeader_SetItemFlags GUICtrlHeader_SetItemFormat GUICtrlHeader_SetItemImage GUICtrlHeader_SetItemOrder GUICtrlHeader_SetItemParam GUICtrlHeader_SetItemText GUICtrlHeader_SetItemWidth GUICtrlHeader_SetOrderArray GUICtrlHeader_SetUnicodeFormat GUICtrlIpAddress_ClearAddress GUICtrlIpAddress_Create GUICtrlIpAddress_Destroy GUICtrlIpAddress_Get GUICtrlIpAddress_GetArray GUICtrlIpAddress_GetEx GUICtrlIpAddress_IsBlank GUICtrlIpAddress_Set GUICtrlIpAddress_SetArray GUICtrlIpAddress_SetEx GUICtrlIpAddress_SetFocus GUICtrlIpAddress_SetFont GUICtrlIpAddress_SetRange GUICtrlIpAddress_ShowHide GUICtrlListBox_AddFile GUICtrlListBox_AddString GUICtrlListBox_BeginUpdate GUICtrlListBox_ClickItem GUICtrlListBox_Create GUICtrlListBox_DeleteString GUICtrlListBox_Destroy GUICtrlListBox_Dir GUICtrlListBox_EndUpdate GUICtrlListBox_FindInText GUICtrlListBox_FindString GUICtrlListBox_GetAnchorIndex GUICtrlListBox_GetCaretIndex GUICtrlListBox_GetCount GUICtrlListBox_GetCurSel GUICtrlListBox_GetHorizontalExtent GUICtrlListBox_GetItemData GUICtrlListBox_GetItemHeight GUICtrlListBox_GetItemRect GUICtrlListBox_GetItemRectEx GUICtrlListBox_GetListBoxInfo GUICtrlListBox_GetLocale GUICtrlListBox_GetLocaleCountry GUICtrlListBox_GetLocaleLang GUICtrlListBox_GetLocalePrimLang GUICtrlListBox_GetLocaleSubLang GUICtrlListBox_GetSel GUICtrlListBox_GetSelCount GUICtrlListBox_GetSelItems GUICtrlListBox_GetSelItemsText GUICtrlListBox_GetText GUICtrlListBox_GetTextLen GUICtrlListBox_GetTopIndex GUICtrlListBox_InitStorage GUICtrlListBox_InsertString GUICtrlListBox_ItemFromPoint GUICtrlListBox_ReplaceString GUICtrlListBox_ResetContent GUICtrlListBox_SelectString GUICtrlListBox_SelItemRange GUICtrlListBox_SelItemRangeEx GUICtrlListBox_SetAnchorIndex GUICtrlListBox_SetCaretIndex GUICtrlListBox_SetColumnWidth GUICtrlListBox_SetCurSel GUICtrlListBox_SetHorizontalExtent GUICtrlListBox_SetItemData GUICtrlListBox_SetItemHeight GUICtrlListBox_SetLocale GUICtrlListBox_SetSel GUICtrlListBox_SetTabStops GUICtrlListBox_SetTopIndex GUICtrlListBox_Sort GUICtrlListBox_SwapString GUICtrlListBox_UpdateHScroll GUICtrlListView_AddArray GUICtrlListView_AddColumn GUICtrlListView_AddItem GUICtrlListView_AddSubItem GUICtrlListView_ApproximateViewHeight GUICtrlListView_ApproximateViewRect GUICtrlListView_ApproximateViewWidth GUICtrlListView_Arrange GUICtrlListView_BeginUpdate GUICtrlListView_CancelEditLabel GUICtrlListView_ClickItem GUICtrlListView_CopyItems GUICtrlListView_Create GUICtrlListView_CreateDragImage GUICtrlListView_CreateSolidBitMap GUICtrlListView_DeleteAllItems GUICtrlListView_DeleteColumn GUICtrlListView_DeleteItem GUICtrlListView_DeleteItemsSelected GUICtrlListView_Destroy GUICtrlListView_DrawDragImage GUICtrlListView_EditLabel GUICtrlListView_EnableGroupView GUICtrlListView_EndUpdate GUICtrlListView_EnsureVisible GUICtrlListView_FindInText GUICtrlListView_FindItem GUICtrlListView_FindNearest GUICtrlListView_FindParam GUICtrlListView_FindText GUICtrlListView_GetBkColor GUICtrlListView_GetBkImage GUICtrlListView_GetCallbackMask GUICtrlListView_GetColumn GUICtrlListView_GetColumnCount GUICtrlListView_GetColumnOrder GUICtrlListView_GetColumnOrderArray GUICtrlListView_GetColumnWidth GUICtrlListView_GetCounterPage GUICtrlListView_GetEditControl GUICtrlListView_GetExtendedListViewStyle GUICtrlListView_GetFocusedGroup GUICtrlListView_GetGroupCount GUICtrlListView_GetGroupInfo GUICtrlListView_GetGroupInfoByIndex GUICtrlListView_GetGroupRect GUICtrlListView_GetGroupViewEnabled GUICtrlListView_GetHeader GUICtrlListView_GetHotCursor GUICtrlListView_GetHotItem GUICtrlListView_GetHoverTime GUICtrlListView_GetImageList GUICtrlListView_GetISearchString GUICtrlListView_GetItem GUICtrlListView_GetItemChecked GUICtrlListView_GetItemCount GUICtrlListView_GetItemCut GUICtrlListView_GetItemDropHilited GUICtrlListView_GetItemEx GUICtrlListView_GetItemFocused GUICtrlListView_GetItemGroupID GUICtrlListView_GetItemImage GUICtrlListView_GetItemIndent GUICtrlListView_GetItemParam GUICtrlListView_GetItemPosition GUICtrlListView_GetItemPositionX GUICtrlListView_GetItemPositionY GUICtrlListView_GetItemRect GUICtrlListView_GetItemRectEx GUICtrlListView_GetItemSelected GUICtrlListView_GetItemSpacing GUICtrlListView_GetItemSpacingX GUICtrlListView_GetItemSpacingY GUICtrlListView_GetItemState GUICtrlListView_GetItemStateImage GUICtrlListView_GetItemText GUICtrlListView_GetItemTextArray GUICtrlListView_GetItemTextString GUICtrlListView_GetNextItem GUICtrlListView_GetNumberOfWorkAreas GUICtrlListView_GetOrigin GUICtrlListView_GetOriginX GUICtrlListView_GetOriginY GUICtrlListView_GetOutlineColor GUICtrlListView_GetSelectedColumn GUICtrlListView_GetSelectedCount GUICtrlListView_GetSelectedIndices GUICtrlListView_GetSelectionMark GUICtrlListView_GetStringWidth GUICtrlListView_GetSubItemRect GUICtrlListView_GetTextBkColor GUICtrlListView_GetTextColor GUICtrlListView_GetToolTips GUICtrlListView_GetTopIndex GUICtrlListView_GetUnicodeFormat GUICtrlListView_GetView GUICtrlListView_GetViewDetails GUICtrlListView_GetViewLarge GUICtrlListView_GetViewList GUICtrlListView_GetViewRect GUICtrlListView_GetViewSmall GUICtrlListView_GetViewTile GUICtrlListView_HideColumn GUICtrlListView_HitTest GUICtrlListView_InsertColumn GUICtrlListView_InsertGroup GUICtrlListView_InsertItem GUICtrlListView_JustifyColumn GUICtrlListView_MapIDToIndex GUICtrlListView_MapIndexToID GUICtrlListView_RedrawItems GUICtrlListView_RegisterSortCallBack GUICtrlListView_RemoveAllGroups GUICtrlListView_RemoveGroup GUICtrlListView_Scroll GUICtrlListView_SetBkColor GUICtrlListView_SetBkImage GUICtrlListView_SetCallBackMask GUICtrlListView_SetColumn GUICtrlListView_SetColumnOrder GUICtrlListView_SetColumnOrderArray GUICtrlListView_SetColumnWidth GUICtrlListView_SetExtendedListViewStyle GUICtrlListView_SetGroupInfo GUICtrlListView_SetHotItem GUICtrlListView_SetHoverTime GUICtrlListView_SetIconSpacing GUICtrlListView_SetImageList GUICtrlListView_SetItem GUICtrlListView_SetItemChecked GUICtrlListView_SetItemCount GUICtrlListView_SetItemCut GUICtrlListView_SetItemDropHilited GUICtrlListView_SetItemEx GUICtrlListView_SetItemFocused GUICtrlListView_SetItemGroupID GUICtrlListView_SetItemImage GUICtrlListView_SetItemIndent GUICtrlListView_SetItemParam GUICtrlListView_SetItemPosition GUICtrlListView_SetItemPosition32 GUICtrlListView_SetItemSelected GUICtrlListView_SetItemState GUICtrlListView_SetItemStateImage GUICtrlListView_SetItemText GUICtrlListView_SetOutlineColor GUICtrlListView_SetSelectedColumn GUICtrlListView_SetSelectionMark GUICtrlListView_SetTextBkColor GUICtrlListView_SetTextColor GUICtrlListView_SetToolTips GUICtrlListView_SetUnicodeFormat GUICtrlListView_SetView GUICtrlListView_SetWorkAreas GUICtrlListView_SimpleSort GUICtrlListView_SortItems GUICtrlListView_SubItemHitTest GUICtrlListView_UnRegisterSortCallBack GUICtrlMenu_AddMenuItem GUICtrlMenu_AppendMenu GUICtrlMenu_CalculatePopupWindowPosition GUICtrlMenu_CheckMenuItem GUICtrlMenu_CheckRadioItem GUICtrlMenu_CreateMenu GUICtrlMenu_CreatePopup GUICtrlMenu_DeleteMenu GUICtrlMenu_DestroyMenu GUICtrlMenu_DrawMenuBar GUICtrlMenu_EnableMenuItem GUICtrlMenu_FindItem GUICtrlMenu_FindParent GUICtrlMenu_GetItemBmp GUICtrlMenu_GetItemBmpChecked GUICtrlMenu_GetItemBmpUnchecked GUICtrlMenu_GetItemChecked GUICtrlMenu_GetItemCount GUICtrlMenu_GetItemData GUICtrlMenu_GetItemDefault GUICtrlMenu_GetItemDisabled GUICtrlMenu_GetItemEnabled GUICtrlMenu_GetItemGrayed GUICtrlMenu_GetItemHighlighted GUICtrlMenu_GetItemID GUICtrlMenu_GetItemInfo GUICtrlMenu_GetItemRect GUICtrlMenu_GetItemRectEx GUICtrlMenu_GetItemState GUICtrlMenu_GetItemStateEx GUICtrlMenu_GetItemSubMenu GUICtrlMenu_GetItemText GUICtrlMenu_GetItemType GUICtrlMenu_GetMenu GUICtrlMenu_GetMenuBackground GUICtrlMenu_GetMenuBarInfo GUICtrlMenu_GetMenuContextHelpID GUICtrlMenu_GetMenuData GUICtrlMenu_GetMenuDefaultItem GUICtrlMenu_GetMenuHeight GUICtrlMenu_GetMenuInfo GUICtrlMenu_GetMenuStyle GUICtrlMenu_GetSystemMenu GUICtrlMenu_InsertMenuItem GUICtrlMenu_InsertMenuItemEx GUICtrlMenu_IsMenu GUICtrlMenu_LoadMenu GUICtrlMenu_MapAccelerator GUICtrlMenu_MenuItemFromPoint GUICtrlMenu_RemoveMenu GUICtrlMenu_SetItemBitmaps GUICtrlMenu_SetItemBmp GUICtrlMenu_SetItemBmpChecked GUICtrlMenu_SetItemBmpUnchecked GUICtrlMenu_SetItemChecked GUICtrlMenu_SetItemData GUICtrlMenu_SetItemDefault GUICtrlMenu_SetItemDisabled GUICtrlMenu_SetItemEnabled GUICtrlMenu_SetItemGrayed GUICtrlMenu_SetItemHighlighted GUICtrlMenu_SetItemID GUICtrlMenu_SetItemInfo GUICtrlMenu_SetItemState GUICtrlMenu_SetItemSubMenu GUICtrlMenu_SetItemText GUICtrlMenu_SetItemType GUICtrlMenu_SetMenu GUICtrlMenu_SetMenuBackground GUICtrlMenu_SetMenuContextHelpID GUICtrlMenu_SetMenuData GUICtrlMenu_SetMenuDefaultItem GUICtrlMenu_SetMenuHeight GUICtrlMenu_SetMenuInfo GUICtrlMenu_SetMenuStyle GUICtrlMenu_TrackPopupMenu GUICtrlMonthCal_Create GUICtrlMonthCal_Destroy GUICtrlMonthCal_GetCalendarBorder GUICtrlMonthCal_GetCalendarCount GUICtrlMonthCal_GetColor GUICtrlMonthCal_GetColorArray GUICtrlMonthCal_GetCurSel GUICtrlMonthCal_GetCurSelStr GUICtrlMonthCal_GetFirstDOW GUICtrlMonthCal_GetFirstDOWStr GUICtrlMonthCal_GetMaxSelCount GUICtrlMonthCal_GetMaxTodayWidth GUICtrlMonthCal_GetMinReqHeight GUICtrlMonthCal_GetMinReqRect GUICtrlMonthCal_GetMinReqRectArray GUICtrlMonthCal_GetMinReqWidth GUICtrlMonthCal_GetMonthDelta GUICtrlMonthCal_GetMonthRange GUICtrlMonthCal_GetMonthRangeMax GUICtrlMonthCal_GetMonthRangeMaxStr GUICtrlMonthCal_GetMonthRangeMin GUICtrlMonthCal_GetMonthRangeMinStr GUICtrlMonthCal_GetMonthRangeSpan GUICtrlMonthCal_GetRange GUICtrlMonthCal_GetRangeMax GUICtrlMonthCal_GetRangeMaxStr GUICtrlMonthCal_GetRangeMin GUICtrlMonthCal_GetRangeMinStr GUICtrlMonthCal_GetSelRange GUICtrlMonthCal_GetSelRangeMax GUICtrlMonthCal_GetSelRangeMaxStr GUICtrlMonthCal_GetSelRangeMin GUICtrlMonthCal_GetSelRangeMinStr GUICtrlMonthCal_GetToday GUICtrlMonthCal_GetTodayStr GUICtrlMonthCal_GetUnicodeFormat GUICtrlMonthCal_HitTest GUICtrlMonthCal_SetCalendarBorder GUICtrlMonthCal_SetColor GUICtrlMonthCal_SetCurSel GUICtrlMonthCal_SetDayState GUICtrlMonthCal_SetFirstDOW GUICtrlMonthCal_SetMaxSelCount GUICtrlMonthCal_SetMonthDelta GUICtrlMonthCal_SetRange GUICtrlMonthCal_SetSelRange GUICtrlMonthCal_SetToday GUICtrlMonthCal_SetUnicodeFormat GUICtrlRebar_AddBand GUICtrlRebar_AddToolBarBand GUICtrlRebar_BeginDrag GUICtrlRebar_Create GUICtrlRebar_DeleteBand GUICtrlRebar_Destroy GUICtrlRebar_DragMove GUICtrlRebar_EndDrag GUICtrlRebar_GetBandBackColor GUICtrlRebar_GetBandBorders GUICtrlRebar_GetBandBordersEx GUICtrlRebar_GetBandChildHandle GUICtrlRebar_GetBandChildSize GUICtrlRebar_GetBandCount GUICtrlRebar_GetBandForeColor GUICtrlRebar_GetBandHeaderSize GUICtrlRebar_GetBandID GUICtrlRebar_GetBandIdealSize GUICtrlRebar_GetBandLength GUICtrlRebar_GetBandLParam GUICtrlRebar_GetBandMargins GUICtrlRebar_GetBandMarginsEx GUICtrlRebar_GetBandRect GUICtrlRebar_GetBandRectEx GUICtrlRebar_GetBandStyle GUICtrlRebar_GetBandStyleBreak GUICtrlRebar_GetBandStyleChildEdge GUICtrlRebar_GetBandStyleFixedBMP GUICtrlRebar_GetBandStyleFixedSize GUICtrlRebar_GetBandStyleGripperAlways GUICtrlRebar_GetBandStyleHidden GUICtrlRebar_GetBandStyleHideTitle GUICtrlRebar_GetBandStyleNoGripper GUICtrlRebar_GetBandStyleTopAlign GUICtrlRebar_GetBandStyleUseChevron GUICtrlRebar_GetBandStyleVariableHeight GUICtrlRebar_GetBandText GUICtrlRebar_GetBarHeight GUICtrlRebar_GetBarInfo GUICtrlRebar_GetBKColor GUICtrlRebar_GetColorScheme GUICtrlRebar_GetRowCount GUICtrlRebar_GetRowHeight GUICtrlRebar_GetTextColor GUICtrlRebar_GetToolTips GUICtrlRebar_GetUnicodeFormat GUICtrlRebar_HitTest GUICtrlRebar_IDToIndex GUICtrlRebar_MaximizeBand GUICtrlRebar_MinimizeBand GUICtrlRebar_MoveBand GUICtrlRebar_SetBandBackColor GUICtrlRebar_SetBandForeColor GUICtrlRebar_SetBandHeaderSize GUICtrlRebar_SetBandID GUICtrlRebar_SetBandIdealSize GUICtrlRebar_SetBandLength GUICtrlRebar_SetBandLParam GUICtrlRebar_SetBandStyle GUICtrlRebar_SetBandStyleBreak GUICtrlRebar_SetBandStyleChildEdge GUICtrlRebar_SetBandStyleFixedBMP GUICtrlRebar_SetBandStyleFixedSize GUICtrlRebar_SetBandStyleGripperAlways GUICtrlRebar_SetBandStyleHidden GUICtrlRebar_SetBandStyleHideTitle GUICtrlRebar_SetBandStyleNoGripper GUICtrlRebar_SetBandStyleTopAlign GUICtrlRebar_SetBandStyleUseChevron GUICtrlRebar_SetBandStyleVariableHeight GUICtrlRebar_SetBandText GUICtrlRebar_SetBarInfo GUICtrlRebar_SetBKColor GUICtrlRebar_SetColorScheme GUICtrlRebar_SetTextColor GUICtrlRebar_SetToolTips GUICtrlRebar_SetUnicodeFormat GUICtrlRebar_ShowBand GUICtrlRichEdit_AppendText GUICtrlRichEdit_AutoDetectURL GUICtrlRichEdit_CanPaste GUICtrlRichEdit_CanPasteSpecial GUICtrlRichEdit_CanRedo GUICtrlRichEdit_CanUndo GUICtrlRichEdit_ChangeFontSize GUICtrlRichEdit_Copy GUICtrlRichEdit_Create GUICtrlRichEdit_Cut GUICtrlRichEdit_Deselect GUICtrlRichEdit_Destroy GUICtrlRichEdit_EmptyUndoBuffer GUICtrlRichEdit_FindText GUICtrlRichEdit_FindTextInRange GUICtrlRichEdit_GetBkColor GUICtrlRichEdit_GetCharAttributes GUICtrlRichEdit_GetCharBkColor GUICtrlRichEdit_GetCharColor GUICtrlRichEdit_GetCharPosFromXY GUICtrlRichEdit_GetCharPosOfNextWord GUICtrlRichEdit_GetCharPosOfPreviousWord GUICtrlRichEdit_GetCharWordBreakInfo GUICtrlRichEdit_GetFirstCharPosOnLine GUICtrlRichEdit_GetFont GUICtrlRichEdit_GetLineCount GUICtrlRichEdit_GetLineLength GUICtrlRichEdit_GetLineNumberFromCharPos GUICtrlRichEdit_GetNextRedo GUICtrlRichEdit_GetNextUndo GUICtrlRichEdit_GetNumberOfFirstVisibleLine GUICtrlRichEdit_GetParaAlignment GUICtrlRichEdit_GetParaAttributes GUICtrlRichEdit_GetParaBorder GUICtrlRichEdit_GetParaIndents GUICtrlRichEdit_GetParaNumbering GUICtrlRichEdit_GetParaShading GUICtrlRichEdit_GetParaSpacing GUICtrlRichEdit_GetParaTabStops GUICtrlRichEdit_GetPasswordChar GUICtrlRichEdit_GetRECT GUICtrlRichEdit_GetScrollPos GUICtrlRichEdit_GetSel GUICtrlRichEdit_GetSelAA GUICtrlRichEdit_GetSelText GUICtrlRichEdit_GetSpaceUnit GUICtrlRichEdit_GetText GUICtrlRichEdit_GetTextInLine GUICtrlRichEdit_GetTextInRange GUICtrlRichEdit_GetTextLength GUICtrlRichEdit_GetVersion GUICtrlRichEdit_GetXYFromCharPos GUICtrlRichEdit_GetZoom GUICtrlRichEdit_GotoCharPos GUICtrlRichEdit_HideSelection GUICtrlRichEdit_InsertText GUICtrlRichEdit_IsModified GUICtrlRichEdit_IsTextSelected GUICtrlRichEdit_Paste GUICtrlRichEdit_PasteSpecial GUICtrlRichEdit_PauseRedraw GUICtrlRichEdit_Redo GUICtrlRichEdit_ReplaceText GUICtrlRichEdit_ResumeRedraw GUICtrlRichEdit_ScrollLineOrPage GUICtrlRichEdit_ScrollLines GUICtrlRichEdit_ScrollToCaret GUICtrlRichEdit_SetBkColor GUICtrlRichEdit_SetCharAttributes GUICtrlRichEdit_SetCharBkColor GUICtrlRichEdit_SetCharColor GUICtrlRichEdit_SetEventMask GUICtrlRichEdit_SetFont GUICtrlRichEdit_SetLimitOnText GUICtrlRichEdit_SetModified GUICtrlRichEdit_SetParaAlignment GUICtrlRichEdit_SetParaAttributes GUICtrlRichEdit_SetParaBorder GUICtrlRichEdit_SetParaIndents GUICtrlRichEdit_SetParaNumbering GUICtrlRichEdit_SetParaShading GUICtrlRichEdit_SetParaSpacing GUICtrlRichEdit_SetParaTabStops GUICtrlRichEdit_SetPasswordChar GUICtrlRichEdit_SetReadOnly GUICtrlRichEdit_SetRECT GUICtrlRichEdit_SetScrollPos GUICtrlRichEdit_SetSel GUICtrlRichEdit_SetSpaceUnit GUICtrlRichEdit_SetTabStops GUICtrlRichEdit_SetText GUICtrlRichEdit_SetUndoLimit GUICtrlRichEdit_SetZoom GUICtrlRichEdit_StreamFromFile GUICtrlRichEdit_StreamFromVar GUICtrlRichEdit_StreamToFile GUICtrlRichEdit_StreamToVar GUICtrlRichEdit_Undo GUICtrlSlider_ClearSel GUICtrlSlider_ClearTics GUICtrlSlider_Create GUICtrlSlider_Destroy GUICtrlSlider_GetBuddy GUICtrlSlider_GetChannelRect GUICtrlSlider_GetChannelRectEx GUICtrlSlider_GetLineSize GUICtrlSlider_GetLogicalTics GUICtrlSlider_GetNumTics GUICtrlSlider_GetPageSize GUICtrlSlider_GetPos GUICtrlSlider_GetRange GUICtrlSlider_GetRangeMax GUICtrlSlider_GetRangeMin GUICtrlSlider_GetSel GUICtrlSlider_GetSelEnd GUICtrlSlider_GetSelStart GUICtrlSlider_GetThumbLength GUICtrlSlider_GetThumbRect GUICtrlSlider_GetThumbRectEx GUICtrlSlider_GetTic GUICtrlSlider_GetTicPos GUICtrlSlider_GetToolTips GUICtrlSlider_GetUnicodeFormat GUICtrlSlider_SetBuddy GUICtrlSlider_SetLineSize GUICtrlSlider_SetPageSize GUICtrlSlider_SetPos GUICtrlSlider_SetRange GUICtrlSlider_SetRangeMax GUICtrlSlider_SetRangeMin GUICtrlSlider_SetSel GUICtrlSlider_SetSelEnd GUICtrlSlider_SetSelStart GUICtrlSlider_SetThumbLength GUICtrlSlider_SetTic GUICtrlSlider_SetTicFreq GUICtrlSlider_SetTipSide GUICtrlSlider_SetToolTips GUICtrlSlider_SetUnicodeFormat GUICtrlStatusBar_Create GUICtrlStatusBar_Destroy GUICtrlStatusBar_EmbedControl GUICtrlStatusBar_GetBorders GUICtrlStatusBar_GetBordersHorz GUICtrlStatusBar_GetBordersRect GUICtrlStatusBar_GetBordersVert GUICtrlStatusBar_GetCount GUICtrlStatusBar_GetHeight GUICtrlStatusBar_GetIcon GUICtrlStatusBar_GetParts GUICtrlStatusBar_GetRect GUICtrlStatusBar_GetRectEx GUICtrlStatusBar_GetText GUICtrlStatusBar_GetTextFlags GUICtrlStatusBar_GetTextLength GUICtrlStatusBar_GetTextLengthEx GUICtrlStatusBar_GetTipText GUICtrlStatusBar_GetUnicodeFormat GUICtrlStatusBar_GetWidth GUICtrlStatusBar_IsSimple GUICtrlStatusBar_Resize GUICtrlStatusBar_SetBkColor GUICtrlStatusBar_SetIcon GUICtrlStatusBar_SetMinHeight GUICtrlStatusBar_SetParts GUICtrlStatusBar_SetSimple GUICtrlStatusBar_SetText GUICtrlStatusBar_SetTipText GUICtrlStatusBar_SetUnicodeFormat GUICtrlStatusBar_ShowHide GUICtrlTab_ActivateTab GUICtrlTab_ClickTab GUICtrlTab_Create GUICtrlTab_DeleteAllItems GUICtrlTab_DeleteItem GUICtrlTab_DeselectAll GUICtrlTab_Destroy GUICtrlTab_FindTab GUICtrlTab_GetCurFocus GUICtrlTab_GetCurSel GUICtrlTab_GetDisplayRect GUICtrlTab_GetDisplayRectEx GUICtrlTab_GetExtendedStyle GUICtrlTab_GetImageList GUICtrlTab_GetItem GUICtrlTab_GetItemCount GUICtrlTab_GetItemImage GUICtrlTab_GetItemParam GUICtrlTab_GetItemRect GUICtrlTab_GetItemRectEx GUICtrlTab_GetItemState GUICtrlTab_GetItemText GUICtrlTab_GetRowCount GUICtrlTab_GetToolTips GUICtrlTab_GetUnicodeFormat GUICtrlTab_HighlightItem GUICtrlTab_HitTest GUICtrlTab_InsertItem GUICtrlTab_RemoveImage GUICtrlTab_SetCurFocus GUICtrlTab_SetCurSel GUICtrlTab_SetExtendedStyle GUICtrlTab_SetImageList GUICtrlTab_SetItem GUICtrlTab_SetItemImage GUICtrlTab_SetItemParam GUICtrlTab_SetItemSize GUICtrlTab_SetItemState GUICtrlTab_SetItemText GUICtrlTab_SetMinTabWidth GUICtrlTab_SetPadding GUICtrlTab_SetToolTips GUICtrlTab_SetUnicodeFormat GUICtrlToolbar_AddBitmap GUICtrlToolbar_AddButton GUICtrlToolbar_AddButtonSep GUICtrlToolbar_AddString GUICtrlToolbar_ButtonCount GUICtrlToolbar_CheckButton GUICtrlToolbar_ClickAccel GUICtrlToolbar_ClickButton GUICtrlToolbar_ClickIndex GUICtrlToolbar_CommandToIndex GUICtrlToolbar_Create GUICtrlToolbar_Customize GUICtrlToolbar_DeleteButton GUICtrlToolbar_Destroy GUICtrlToolbar_EnableButton GUICtrlToolbar_FindToolbar GUICtrlToolbar_GetAnchorHighlight GUICtrlToolbar_GetBitmapFlags GUICtrlToolbar_GetButtonBitmap GUICtrlToolbar_GetButtonInfo GUICtrlToolbar_GetButtonInfoEx GUICtrlToolbar_GetButtonParam GUICtrlToolbar_GetButtonRect GUICtrlToolbar_GetButtonRectEx GUICtrlToolbar_GetButtonSize GUICtrlToolbar_GetButtonState GUICtrlToolbar_GetButtonStyle GUICtrlToolbar_GetButtonText GUICtrlToolbar_GetColorScheme GUICtrlToolbar_GetDisabledImageList GUICtrlToolbar_GetExtendedStyle GUICtrlToolbar_GetHotImageList GUICtrlToolbar_GetHotItem GUICtrlToolbar_GetImageList GUICtrlToolbar_GetInsertMark GUICtrlToolbar_GetInsertMarkColor GUICtrlToolbar_GetMaxSize GUICtrlToolbar_GetMetrics GUICtrlToolbar_GetPadding GUICtrlToolbar_GetRows GUICtrlToolbar_GetString GUICtrlToolbar_GetStyle GUICtrlToolbar_GetStyleAltDrag GUICtrlToolbar_GetStyleCustomErase GUICtrlToolbar_GetStyleFlat GUICtrlToolbar_GetStyleList GUICtrlToolbar_GetStyleRegisterDrop GUICtrlToolbar_GetStyleToolTips GUICtrlToolbar_GetStyleTransparent GUICtrlToolbar_GetStyleWrapable GUICtrlToolbar_GetTextRows GUICtrlToolbar_GetToolTips GUICtrlToolbar_GetUnicodeFormat GUICtrlToolbar_HideButton GUICtrlToolbar_HighlightButton GUICtrlToolbar_HitTest GUICtrlToolbar_IndexToCommand GUICtrlToolbar_InsertButton GUICtrlToolbar_InsertMarkHitTest GUICtrlToolbar_IsButtonChecked GUICtrlToolbar_IsButtonEnabled GUICtrlToolbar_IsButtonHidden GUICtrlToolbar_IsButtonHighlighted GUICtrlToolbar_IsButtonIndeterminate GUICtrlToolbar_IsButtonPressed GUICtrlToolbar_LoadBitmap GUICtrlToolbar_LoadImages GUICtrlToolbar_MapAccelerator GUICtrlToolbar_MoveButton GUICtrlToolbar_PressButton GUICtrlToolbar_SetAnchorHighlight GUICtrlToolbar_SetBitmapSize GUICtrlToolbar_SetButtonBitMap GUICtrlToolbar_SetButtonInfo GUICtrlToolbar_SetButtonInfoEx GUICtrlToolbar_SetButtonParam GUICtrlToolbar_SetButtonSize GUICtrlToolbar_SetButtonState GUICtrlToolbar_SetButtonStyle GUICtrlToolbar_SetButtonText GUICtrlToolbar_SetButtonWidth GUICtrlToolbar_SetCmdID GUICtrlToolbar_SetColorScheme GUICtrlToolbar_SetDisabledImageList GUICtrlToolbar_SetDrawTextFlags GUICtrlToolbar_SetExtendedStyle GUICtrlToolbar_SetHotImageList GUICtrlToolbar_SetHotItem GUICtrlToolbar_SetImageList GUICtrlToolbar_SetIndent GUICtrlToolbar_SetIndeterminate GUICtrlToolbar_SetInsertMark GUICtrlToolbar_SetInsertMarkColor GUICtrlToolbar_SetMaxTextRows GUICtrlToolbar_SetMetrics GUICtrlToolbar_SetPadding GUICtrlToolbar_SetParent GUICtrlToolbar_SetRows GUICtrlToolbar_SetStyle GUICtrlToolbar_SetStyleAltDrag GUICtrlToolbar_SetStyleCustomErase GUICtrlToolbar_SetStyleFlat GUICtrlToolbar_SetStyleList GUICtrlToolbar_SetStyleRegisterDrop GUICtrlToolbar_SetStyleToolTips GUICtrlToolbar_SetStyleTransparent GUICtrlToolbar_SetStyleWrapable GUICtrlToolbar_SetToolTips GUICtrlToolbar_SetUnicodeFormat GUICtrlToolbar_SetWindowTheme GUICtrlTreeView_Add GUICtrlTreeView_AddChild GUICtrlTreeView_AddChildFirst GUICtrlTreeView_AddFirst GUICtrlTreeView_BeginUpdate GUICtrlTreeView_ClickItem GUICtrlTreeView_Create GUICtrlTreeView_CreateDragImage GUICtrlTreeView_CreateSolidBitMap GUICtrlTreeView_Delete GUICtrlTreeView_DeleteAll GUICtrlTreeView_DeleteChildren GUICtrlTreeView_Destroy GUICtrlTreeView_DisplayRect GUICtrlTreeView_DisplayRectEx GUICtrlTreeView_EditText GUICtrlTreeView_EndEdit GUICtrlTreeView_EndUpdate GUICtrlTreeView_EnsureVisible GUICtrlTreeView_Expand GUICtrlTreeView_ExpandedOnce GUICtrlTreeView_FindItem GUICtrlTreeView_FindItemEx GUICtrlTreeView_GetBkColor GUICtrlTreeView_GetBold GUICtrlTreeView_GetChecked GUICtrlTreeView_GetChildCount GUICtrlTreeView_GetChildren GUICtrlTreeView_GetCount GUICtrlTreeView_GetCut GUICtrlTreeView_GetDropTarget GUICtrlTreeView_GetEditControl GUICtrlTreeView_GetExpanded GUICtrlTreeView_GetFirstChild GUICtrlTreeView_GetFirstItem GUICtrlTreeView_GetFirstVisible GUICtrlTreeView_GetFocused GUICtrlTreeView_GetHeight GUICtrlTreeView_GetImageIndex GUICtrlTreeView_GetImageListIconHandle GUICtrlTreeView_GetIndent GUICtrlTreeView_GetInsertMarkColor GUICtrlTreeView_GetISearchString GUICtrlTreeView_GetItemByIndex GUICtrlTreeView_GetItemHandle GUICtrlTreeView_GetItemParam GUICtrlTreeView_GetLastChild GUICtrlTreeView_GetLineColor GUICtrlTreeView_GetNext GUICtrlTreeView_GetNextChild GUICtrlTreeView_GetNextSibling GUICtrlTreeView_GetNextVisible GUICtrlTreeView_GetNormalImageList GUICtrlTreeView_GetParentHandle GUICtrlTreeView_GetParentParam GUICtrlTreeView_GetPrev GUICtrlTreeView_GetPrevChild GUICtrlTreeView_GetPrevSibling GUICtrlTreeView_GetPrevVisible GUICtrlTreeView_GetScrollTime GUICtrlTreeView_GetSelected GUICtrlTreeView_GetSelectedImageIndex GUICtrlTreeView_GetSelection GUICtrlTreeView_GetSiblingCount GUICtrlTreeView_GetState GUICtrlTreeView_GetStateImageIndex GUICtrlTreeView_GetStateImageList GUICtrlTreeView_GetText GUICtrlTreeView_GetTextColor GUICtrlTreeView_GetToolTips GUICtrlTreeView_GetTree GUICtrlTreeView_GetUnicodeFormat GUICtrlTreeView_GetVisible GUICtrlTreeView_GetVisibleCount GUICtrlTreeView_HitTest GUICtrlTreeView_HitTestEx GUICtrlTreeView_HitTestItem GUICtrlTreeView_Index GUICtrlTreeView_InsertItem GUICtrlTreeView_IsFirstItem GUICtrlTreeView_IsParent GUICtrlTreeView_Level GUICtrlTreeView_SelectItem GUICtrlTreeView_SelectItemByIndex GUICtrlTreeView_SetBkColor GUICtrlTreeView_SetBold GUICtrlTreeView_SetChecked GUICtrlTreeView_SetCheckedByIndex GUICtrlTreeView_SetChildren GUICtrlTreeView_SetCut GUICtrlTreeView_SetDropTarget GUICtrlTreeView_SetFocused GUICtrlTreeView_SetHeight GUICtrlTreeView_SetIcon GUICtrlTreeView_SetImageIndex GUICtrlTreeView_SetIndent GUICtrlTreeView_SetInsertMark GUICtrlTreeView_SetInsertMarkColor GUICtrlTreeView_SetItemHeight GUICtrlTreeView_SetItemParam GUICtrlTreeView_SetLineColor GUICtrlTreeView_SetNormalImageList GUICtrlTreeView_SetScrollTime GUICtrlTreeView_SetSelected GUICtrlTreeView_SetSelectedImageIndex GUICtrlTreeView_SetState GUICtrlTreeView_SetStateImageIndex GUICtrlTreeView_SetStateImageList GUICtrlTreeView_SetText GUICtrlTreeView_SetTextColor GUICtrlTreeView_SetToolTips GUICtrlTreeView_SetUnicodeFormat GUICtrlTreeView_Sort GUIImageList_Add GUIImageList_AddBitmap GUIImageList_AddIcon GUIImageList_AddMasked GUIImageList_BeginDrag GUIImageList_Copy GUIImageList_Create GUIImageList_Destroy GUIImageList_DestroyIcon GUIImageList_DragEnter GUIImageList_DragLeave GUIImageList_DragMove GUIImageList_Draw GUIImageList_DrawEx GUIImageList_Duplicate GUIImageList_EndDrag GUIImageList_GetBkColor GUIImageList_GetIcon GUIImageList_GetIconHeight GUIImageList_GetIconSize GUIImageList_GetIconSizeEx GUIImageList_GetIconWidth GUIImageList_GetImageCount GUIImageList_GetImageInfoEx GUIImageList_Remove GUIImageList_ReplaceIcon GUIImageList_SetBkColor GUIImageList_SetIconSize GUIImageList_SetImageCount GUIImageList_Swap GUIScrollBars_EnableScrollBar GUIScrollBars_GetScrollBarInfoEx GUIScrollBars_GetScrollBarRect GUIScrollBars_GetScrollBarRGState GUIScrollBars_GetScrollBarXYLineButton GUIScrollBars_GetScrollBarXYThumbBottom GUIScrollBars_GetScrollBarXYThumbTop GUIScrollBars_GetScrollInfo GUIScrollBars_GetScrollInfoEx GUIScrollBars_GetScrollInfoMax GUIScrollBars_GetScrollInfoMin GUIScrollBars_GetScrollInfoPage GUIScrollBars_GetScrollInfoPos GUIScrollBars_GetScrollInfoTrackPos GUIScrollBars_GetScrollPos GUIScrollBars_GetScrollRange GUIScrollBars_Init GUIScrollBars_ScrollWindow GUIScrollBars_SetScrollInfo GUIScrollBars_SetScrollInfoMax GUIScrollBars_SetScrollInfoMin GUIScrollBars_SetScrollInfoPage GUIScrollBars_SetScrollInfoPos GUIScrollBars_SetScrollRange GUIScrollBars_ShowScrollBar GUIToolTip_Activate GUIToolTip_AddTool GUIToolTip_AdjustRect GUIToolTip_BitsToTTF GUIToolTip_Create GUIToolTip_Deactivate GUIToolTip_DelTool GUIToolTip_Destroy GUIToolTip_EnumTools GUIToolTip_GetBubbleHeight GUIToolTip_GetBubbleSize GUIToolTip_GetBubbleWidth GUIToolTip_GetCurrentTool GUIToolTip_GetDelayTime GUIToolTip_GetMargin GUIToolTip_GetMarginEx GUIToolTip_GetMaxTipWidth GUIToolTip_GetText GUIToolTip_GetTipBkColor GUIToolTip_GetTipTextColor GUIToolTip_GetTitleBitMap GUIToolTip_GetTitleText GUIToolTip_GetToolCount GUIToolTip_GetToolInfo GUIToolTip_HitTest GUIToolTip_NewToolRect GUIToolTip_Pop GUIToolTip_PopUp GUIToolTip_SetDelayTime GUIToolTip_SetMargin GUIToolTip_SetMaxTipWidth GUIToolTip_SetTipBkColor GUIToolTip_SetTipTextColor GUIToolTip_SetTitle GUIToolTip_SetToolInfo GUIToolTip_SetWindowTheme GUIToolTip_ToolExists GUIToolTip_ToolToArray GUIToolTip_TrackActivate GUIToolTip_TrackPosition GUIToolTip_Update GUIToolTip_UpdateTipText HexToString IEAction IEAttach IEBodyReadHTML IEBodyReadText IEBodyWriteHTML IECreate IECreateEmbedded IEDocGetObj IEDocInsertHTML IEDocInsertText IEDocReadHTML IEDocWriteHTML IEErrorNotify IEFormElementCheckBoxSelect IEFormElementGetCollection IEFormElementGetObjByName IEFormElementGetValue IEFormElementOptionSelect IEFormElementRadioSelect IEFormElementSetValue IEFormGetCollection IEFormGetObjByName IEFormImageClick IEFormReset IEFormSubmit IEFrameGetCollection IEFrameGetObjByName IEGetObjById IEGetObjByName IEHeadInsertEventScript IEImgClick IEImgGetCollection IEIsFrameSet IELinkClickByIndex IELinkClickByText IELinkGetCollection IELoadWait IELoadWaitTimeout IENavigate IEPropertyGet IEPropertySet IEQuit IETableGetCollection IETableWriteToArray IETagNameAllGetCollection IETagNameGetCollection IE_Example IE_Introduction IE_VersionInfo INetExplorerCapable INetGetSource INetMail INetSmtpMail IsPressed MathCheckDiv Max MemGlobalAlloc MemGlobalFree MemGlobalLock MemGlobalSize MemGlobalUnlock MemMoveMemory MemVirtualAlloc MemVirtualAllocEx MemVirtualFree MemVirtualFreeEx Min MouseTrap NamedPipes_CallNamedPipe NamedPipes_ConnectNamedPipe NamedPipes_CreateNamedPipe NamedPipes_CreatePipe NamedPipes_DisconnectNamedPipe NamedPipes_GetNamedPipeHandleState NamedPipes_GetNamedPipeInfo NamedPipes_PeekNamedPipe NamedPipes_SetNamedPipeHandleState NamedPipes_TransactNamedPipe NamedPipes_WaitNamedPipe Net_Share_ConnectionEnum Net_Share_FileClose Net_Share_FileEnum Net_Share_FileGetInfo Net_Share_PermStr Net_Share_ResourceStr Net_Share_SessionDel Net_Share_SessionEnum Net_Share_SessionGetInfo Net_Share_ShareAdd Net_Share_ShareCheck Net_Share_ShareDel Net_Share_ShareEnum Net_Share_ShareGetInfo Net_Share_ShareSetInfo Net_Share_StatisticsGetSvr Net_Share_StatisticsGetWrk Now NowCalc NowCalcDate NowDate NowTime PathFull PathGetRelative PathMake PathSplit ProcessGetName ProcessGetPriority Radian ReplaceStringInFile RunDos ScreenCapture_Capture ScreenCapture_CaptureWnd ScreenCapture_SaveImage ScreenCapture_SetBMPFormat ScreenCapture_SetJPGQuality ScreenCapture_SetTIFColorDepth ScreenCapture_SetTIFCompression Security__AdjustTokenPrivileges Security__CreateProcessWithToken Security__DuplicateTokenEx Security__GetAccountSid Security__GetLengthSid Security__GetTokenInformation Security__ImpersonateSelf Security__IsValidSid Security__LookupAccountName Security__LookupAccountSid Security__LookupPrivilegeValue Security__OpenProcessToken Security__OpenThreadToken Security__OpenThreadTokenEx Security__SetPrivilege Security__SetTokenInformation Security__SidToStringSid Security__SidTypeStr Security__StringSidToSid SendMessage SendMessageA SetDate SetTime Singleton SoundClose SoundLength SoundOpen SoundPause SoundPlay SoundPos SoundResume SoundSeek SoundStatus SoundStop SQLite_Changes SQLite_Close SQLite_Display2DResult SQLite_Encode SQLite_ErrCode SQLite_ErrMsg SQLite_Escape SQLite_Exec SQLite_FastEncode SQLite_FastEscape SQLite_FetchData SQLite_FetchNames SQLite_GetTable SQLite_GetTable2d SQLite_LastInsertRowID SQLite_LibVersion SQLite_Open SQLite_Query SQLite_QueryFinalize SQLite_QueryReset SQLite_QuerySingleRow SQLite_SafeMode SQLite_SetTimeout SQLite_Shutdown SQLite_SQLiteExe SQLite_Startup SQLite_TotalChanges StringBetween StringExplode StringInsert StringProper StringRepeat StringTitleCase StringToHex TCPIpToName TempFile TicksToTime Timer_Diff Timer_GetIdleTime Timer_GetTimerID Timer_Init Timer_KillAllTimers Timer_KillTimer Timer_SetTimer TimeToTicks VersionCompare viClose viExecCommand viFindGpib viGpibBusReset viGTL viInteractiveControl viOpen viSetAttribute viSetTimeout WeekNumberISO WinAPI_AbortPath WinAPI_ActivateKeyboardLayout WinAPI_AddClipboardFormatListener WinAPI_AddFontMemResourceEx WinAPI_AddFontResourceEx WinAPI_AddIconOverlay WinAPI_AddIconTransparency WinAPI_AddMRUString WinAPI_AdjustBitmap WinAPI_AdjustTokenPrivileges WinAPI_AdjustWindowRectEx WinAPI_AlphaBlend WinAPI_AngleArc WinAPI_AnimateWindow WinAPI_Arc WinAPI_ArcTo WinAPI_ArrayToStruct WinAPI_AssignProcessToJobObject WinAPI_AssocGetPerceivedType WinAPI_AssocQueryString WinAPI_AttachConsole WinAPI_AttachThreadInput WinAPI_BackupRead WinAPI_BackupReadAbort WinAPI_BackupSeek WinAPI_BackupWrite WinAPI_BackupWriteAbort WinAPI_Beep WinAPI_BeginBufferedPaint WinAPI_BeginDeferWindowPos WinAPI_BeginPaint WinAPI_BeginPath WinAPI_BeginUpdateResource WinAPI_BitBlt WinAPI_BringWindowToTop WinAPI_BroadcastSystemMessage WinAPI_BrowseForFolderDlg WinAPI_BufferedPaintClear WinAPI_BufferedPaintInit WinAPI_BufferedPaintSetAlpha WinAPI_BufferedPaintUnInit WinAPI_CallNextHookEx WinAPI_CallWindowProc WinAPI_CallWindowProcW WinAPI_CascadeWindows WinAPI_ChangeWindowMessageFilterEx WinAPI_CharToOem WinAPI_ChildWindowFromPointEx WinAPI_ClientToScreen WinAPI_ClipCursor WinAPI_CloseDesktop WinAPI_CloseEnhMetaFile WinAPI_CloseFigure WinAPI_CloseHandle WinAPI_CloseThemeData WinAPI_CloseWindow WinAPI_CloseWindowStation WinAPI_CLSIDFromProgID WinAPI_CoInitialize WinAPI_ColorAdjustLuma WinAPI_ColorHLSToRGB WinAPI_ColorRGBToHLS WinAPI_CombineRgn WinAPI_CombineTransform WinAPI_CommandLineToArgv WinAPI_CommDlgExtendedError WinAPI_CommDlgExtendedErrorEx WinAPI_CompareString WinAPI_CompressBitmapBits WinAPI_CompressBuffer WinAPI_ComputeCrc32 WinAPI_ConfirmCredentials WinAPI_CopyBitmap WinAPI_CopyCursor WinAPI_CopyEnhMetaFile WinAPI_CopyFileEx WinAPI_CopyIcon WinAPI_CopyImage WinAPI_CopyRect WinAPI_CopyStruct WinAPI_CoTaskMemAlloc WinAPI_CoTaskMemFree WinAPI_CoTaskMemRealloc WinAPI_CoUninitialize WinAPI_Create32BitHBITMAP WinAPI_Create32BitHICON WinAPI_CreateANDBitmap WinAPI_CreateBitmap WinAPI_CreateBitmapIndirect WinAPI_CreateBrushIndirect WinAPI_CreateBuffer WinAPI_CreateBufferFromStruct WinAPI_CreateCaret WinAPI_CreateColorAdjustment WinAPI_CreateCompatibleBitmap WinAPI_CreateCompatibleBitmapEx WinAPI_CreateCompatibleDC WinAPI_CreateDesktop WinAPI_CreateDIB WinAPI_CreateDIBColorTable WinAPI_CreateDIBitmap WinAPI_CreateDIBSection WinAPI_CreateDirectory WinAPI_CreateDirectoryEx WinAPI_CreateEllipticRgn WinAPI_CreateEmptyIcon WinAPI_CreateEnhMetaFile WinAPI_CreateEvent WinAPI_CreateFile WinAPI_CreateFileEx WinAPI_CreateFileMapping WinAPI_CreateFont WinAPI_CreateFontEx WinAPI_CreateFontIndirect WinAPI_CreateGUID WinAPI_CreateHardLink WinAPI_CreateIcon WinAPI_CreateIconFromResourceEx WinAPI_CreateIconIndirect WinAPI_CreateJobObject WinAPI_CreateMargins WinAPI_CreateMRUList WinAPI_CreateMutex WinAPI_CreateNullRgn WinAPI_CreateNumberFormatInfo WinAPI_CreateObjectID WinAPI_CreatePen WinAPI_CreatePoint WinAPI_CreatePolygonRgn WinAPI_CreateProcess WinAPI_CreateProcessWithToken WinAPI_CreateRect WinAPI_CreateRectEx WinAPI_CreateRectRgn WinAPI_CreateRectRgnIndirect WinAPI_CreateRoundRectRgn WinAPI_CreateSemaphore WinAPI_CreateSize WinAPI_CreateSolidBitmap WinAPI_CreateSolidBrush WinAPI_CreateStreamOnHGlobal WinAPI_CreateString WinAPI_CreateSymbolicLink WinAPI_CreateTransform WinAPI_CreateWindowEx WinAPI_CreateWindowStation WinAPI_DecompressBuffer WinAPI_DecryptFile WinAPI_DeferWindowPos WinAPI_DefineDosDevice WinAPI_DefRawInputProc WinAPI_DefSubclassProc WinAPI_DefWindowProc WinAPI_DefWindowProcW WinAPI_DeleteDC WinAPI_DeleteEnhMetaFile WinAPI_DeleteFile WinAPI_DeleteObject WinAPI_DeleteObjectID WinAPI_DeleteVolumeMountPoint WinAPI_DeregisterShellHookWindow WinAPI_DestroyCaret WinAPI_DestroyCursor WinAPI_DestroyIcon WinAPI_DestroyWindow WinAPI_DeviceIoControl WinAPI_DisplayStruct WinAPI_DllGetVersion WinAPI_DllInstall WinAPI_DllUninstall WinAPI_DPtoLP WinAPI_DragAcceptFiles WinAPI_DragFinish WinAPI_DragQueryFileEx WinAPI_DragQueryPoint WinAPI_DrawAnimatedRects WinAPI_DrawBitmap WinAPI_DrawEdge WinAPI_DrawFocusRect WinAPI_DrawFrameControl WinAPI_DrawIcon WinAPI_DrawIconEx WinAPI_DrawLine WinAPI_DrawShadowText WinAPI_DrawText WinAPI_DrawThemeBackground WinAPI_DrawThemeEdge WinAPI_DrawThemeIcon WinAPI_DrawThemeParentBackground WinAPI_DrawThemeText WinAPI_DrawThemeTextEx WinAPI_DuplicateEncryptionInfoFile WinAPI_DuplicateHandle WinAPI_DuplicateTokenEx WinAPI_DwmDefWindowProc WinAPI_DwmEnableBlurBehindWindow WinAPI_DwmEnableComposition WinAPI_DwmExtendFrameIntoClientArea WinAPI_DwmGetColorizationColor WinAPI_DwmGetColorizationParameters WinAPI_DwmGetWindowAttribute WinAPI_DwmInvalidateIconicBitmaps WinAPI_DwmIsCompositionEnabled WinAPI_DwmQueryThumbnailSourceSize WinAPI_DwmRegisterThumbnail WinAPI_DwmSetColorizationParameters WinAPI_DwmSetIconicLivePreviewBitmap WinAPI_DwmSetIconicThumbnail WinAPI_DwmSetWindowAttribute WinAPI_DwmUnregisterThumbnail WinAPI_DwmUpdateThumbnailProperties WinAPI_DWordToFloat WinAPI_DWordToInt WinAPI_EjectMedia WinAPI_Ellipse WinAPI_EmptyWorkingSet WinAPI_EnableWindow WinAPI_EncryptFile WinAPI_EncryptionDisable WinAPI_EndBufferedPaint WinAPI_EndDeferWindowPos WinAPI_EndPaint WinAPI_EndPath WinAPI_EndUpdateResource WinAPI_EnumChildProcess WinAPI_EnumChildWindows WinAPI_EnumDesktops WinAPI_EnumDesktopWindows WinAPI_EnumDeviceDrivers WinAPI_EnumDisplayDevices WinAPI_EnumDisplayMonitors WinAPI_EnumDisplaySettings WinAPI_EnumDllProc WinAPI_EnumFiles WinAPI_EnumFileStreams WinAPI_EnumFontFamilies WinAPI_EnumHardLinks WinAPI_EnumMRUList WinAPI_EnumPageFiles WinAPI_EnumProcessHandles WinAPI_EnumProcessModules WinAPI_EnumProcessThreads WinAPI_EnumProcessWindows WinAPI_EnumRawInputDevices WinAPI_EnumResourceLanguages WinAPI_EnumResourceNames WinAPI_EnumResourceTypes WinAPI_EnumSystemGeoID WinAPI_EnumSystemLocales WinAPI_EnumUILanguages WinAPI_EnumWindows WinAPI_EnumWindowsPopup WinAPI_EnumWindowStations WinAPI_EnumWindowsTop WinAPI_EqualMemory WinAPI_EqualRect WinAPI_EqualRgn WinAPI_ExcludeClipRect WinAPI_ExpandEnvironmentStrings WinAPI_ExtCreatePen WinAPI_ExtCreateRegion WinAPI_ExtFloodFill WinAPI_ExtractIcon WinAPI_ExtractIconEx WinAPI_ExtSelectClipRgn WinAPI_FatalAppExit WinAPI_FatalExit WinAPI_FileEncryptionStatus WinAPI_FileExists WinAPI_FileIconInit WinAPI_FileInUse WinAPI_FillMemory WinAPI_FillPath WinAPI_FillRect WinAPI_FillRgn WinAPI_FindClose WinAPI_FindCloseChangeNotification WinAPI_FindExecutable WinAPI_FindFirstChangeNotification WinAPI_FindFirstFile WinAPI_FindFirstFileName WinAPI_FindFirstStream WinAPI_FindNextChangeNotification WinAPI_FindNextFile WinAPI_FindNextFileName WinAPI_FindNextStream WinAPI_FindResource WinAPI_FindResourceEx WinAPI_FindTextDlg WinAPI_FindWindow WinAPI_FlashWindow WinAPI_FlashWindowEx WinAPI_FlattenPath WinAPI_FloatToDWord WinAPI_FloatToInt WinAPI_FlushFileBuffers WinAPI_FlushFRBuffer WinAPI_FlushViewOfFile WinAPI_FormatDriveDlg WinAPI_FormatMessage WinAPI_FrameRect WinAPI_FrameRgn WinAPI_FreeLibrary WinAPI_FreeMemory WinAPI_FreeMRUList WinAPI_FreeResource WinAPI_GdiComment WinAPI_GetActiveWindow WinAPI_GetAllUsersProfileDirectory WinAPI_GetAncestor WinAPI_GetApplicationRestartSettings WinAPI_GetArcDirection WinAPI_GetAsyncKeyState WinAPI_GetBinaryType WinAPI_GetBitmapBits WinAPI_GetBitmapDimension WinAPI_GetBitmapDimensionEx WinAPI_GetBkColor WinAPI_GetBkMode WinAPI_GetBoundsRect WinAPI_GetBrushOrg WinAPI_GetBufferedPaintBits WinAPI_GetBufferedPaintDC WinAPI_GetBufferedPaintTargetDC WinAPI_GetBufferedPaintTargetRect WinAPI_GetBValue WinAPI_GetCaretBlinkTime WinAPI_GetCaretPos WinAPI_GetCDType WinAPI_GetClassInfoEx WinAPI_GetClassLongEx WinAPI_GetClassName WinAPI_GetClientHeight WinAPI_GetClientRect WinAPI_GetClientWidth WinAPI_GetClipboardSequenceNumber WinAPI_GetClipBox WinAPI_GetClipCursor WinAPI_GetClipRgn WinAPI_GetColorAdjustment WinAPI_GetCompressedFileSize WinAPI_GetCompression WinAPI_GetConnectedDlg WinAPI_GetCurrentDirectory WinAPI_GetCurrentHwProfile WinAPI_GetCurrentObject WinAPI_GetCurrentPosition WinAPI_GetCurrentProcess WinAPI_GetCurrentProcessExplicitAppUserModelID WinAPI_GetCurrentProcessID WinAPI_GetCurrentThemeName WinAPI_GetCurrentThread WinAPI_GetCurrentThreadId WinAPI_GetCursor WinAPI_GetCursorInfo WinAPI_GetDateFormat WinAPI_GetDC WinAPI_GetDCEx WinAPI_GetDefaultPrinter WinAPI_GetDefaultUserProfileDirectory WinAPI_GetDesktopWindow WinAPI_GetDeviceCaps WinAPI_GetDeviceDriverBaseName WinAPI_GetDeviceDriverFileName WinAPI_GetDeviceGammaRamp WinAPI_GetDIBColorTable WinAPI_GetDIBits WinAPI_GetDiskFreeSpaceEx WinAPI_GetDlgCtrlID WinAPI_GetDlgItem WinAPI_GetDllDirectory WinAPI_GetDriveBusType WinAPI_GetDriveGeometryEx WinAPI_GetDriveNumber WinAPI_GetDriveType WinAPI_GetDurationFormat WinAPI_GetEffectiveClientRect WinAPI_GetEnhMetaFile WinAPI_GetEnhMetaFileBits WinAPI_GetEnhMetaFileDescription WinAPI_GetEnhMetaFileDimension WinAPI_GetEnhMetaFileHeader WinAPI_GetErrorMessage WinAPI_GetErrorMode WinAPI_GetExitCodeProcess WinAPI_GetExtended WinAPI_GetFileAttributes WinAPI_GetFileID WinAPI_GetFileInformationByHandle WinAPI_GetFileInformationByHandleEx WinAPI_GetFilePointerEx WinAPI_GetFileSizeEx WinAPI_GetFileSizeOnDisk WinAPI_GetFileTitle WinAPI_GetFileType WinAPI_GetFileVersionInfo WinAPI_GetFinalPathNameByHandle WinAPI_GetFinalPathNameByHandleEx WinAPI_GetFocus WinAPI_GetFontMemoryResourceInfo WinAPI_GetFontName WinAPI_GetFontResourceInfo WinAPI_GetForegroundWindow WinAPI_GetFRBuffer WinAPI_GetFullPathName WinAPI_GetGeoInfo WinAPI_GetGlyphOutline WinAPI_GetGraphicsMode WinAPI_GetGuiResources WinAPI_GetGUIThreadInfo WinAPI_GetGValue WinAPI_GetHandleInformation WinAPI_GetHGlobalFromStream WinAPI_GetIconDimension WinAPI_GetIconInfo WinAPI_GetIconInfoEx WinAPI_GetIdleTime WinAPI_GetKeyboardLayout WinAPI_GetKeyboardLayoutList WinAPI_GetKeyboardState WinAPI_GetKeyboardType WinAPI_GetKeyNameText WinAPI_GetKeyState WinAPI_GetLastActivePopup WinAPI_GetLastError WinAPI_GetLastErrorMessage WinAPI_GetLayeredWindowAttributes WinAPI_GetLocaleInfo WinAPI_GetLogicalDrives WinAPI_GetMapMode WinAPI_GetMemorySize WinAPI_GetMessageExtraInfo WinAPI_GetModuleFileNameEx WinAPI_GetModuleHandle WinAPI_GetModuleHandleEx WinAPI_GetModuleInformation WinAPI_GetMonitorInfo WinAPI_GetMousePos WinAPI_GetMousePosX WinAPI_GetMousePosY WinAPI_GetMUILanguage WinAPI_GetNumberFormat WinAPI_GetObject WinAPI_GetObjectID WinAPI_GetObjectInfoByHandle WinAPI_GetObjectNameByHandle WinAPI_GetObjectType WinAPI_GetOpenFileName WinAPI_GetOutlineTextMetrics WinAPI_GetOverlappedResult WinAPI_GetParent WinAPI_GetParentProcess WinAPI_GetPerformanceInfo WinAPI_GetPEType WinAPI_GetPhysicallyInstalledSystemMemory WinAPI_GetPixel WinAPI_GetPolyFillMode WinAPI_GetPosFromRect WinAPI_GetPriorityClass WinAPI_GetProcAddress WinAPI_GetProcessAffinityMask WinAPI_GetProcessCommandLine WinAPI_GetProcessFileName WinAPI_GetProcessHandleCount WinAPI_GetProcessID WinAPI_GetProcessIoCounters WinAPI_GetProcessMemoryInfo WinAPI_GetProcessName WinAPI_GetProcessShutdownParameters WinAPI_GetProcessTimes WinAPI_GetProcessUser WinAPI_GetProcessWindowStation WinAPI_GetProcessWorkingDirectory WinAPI_GetProfilesDirectory WinAPI_GetPwrCapabilities WinAPI_GetRawInputBuffer WinAPI_GetRawInputBufferLength WinAPI_GetRawInputData WinAPI_GetRawInputDeviceInfo WinAPI_GetRegionData WinAPI_GetRegisteredRawInputDevices WinAPI_GetRegKeyNameByHandle WinAPI_GetRgnBox WinAPI_GetROP2 WinAPI_GetRValue WinAPI_GetSaveFileName WinAPI_GetShellWindow WinAPI_GetStartupInfo WinAPI_GetStdHandle WinAPI_GetStockObject WinAPI_GetStretchBltMode WinAPI_GetString WinAPI_GetSysColor WinAPI_GetSysColorBrush WinAPI_GetSystemDefaultLangID WinAPI_GetSystemDefaultLCID WinAPI_GetSystemDefaultUILanguage WinAPI_GetSystemDEPPolicy WinAPI_GetSystemInfo WinAPI_GetSystemMetrics WinAPI_GetSystemPowerStatus WinAPI_GetSystemTimes WinAPI_GetSystemWow64Directory WinAPI_GetTabbedTextExtent WinAPI_GetTempFileName WinAPI_GetTextAlign WinAPI_GetTextCharacterExtra WinAPI_GetTextColor WinAPI_GetTextExtentPoint32 WinAPI_GetTextFace WinAPI_GetTextMetrics WinAPI_GetThemeAppProperties WinAPI_GetThemeBackgroundContentRect WinAPI_GetThemeBackgroundExtent WinAPI_GetThemeBackgroundRegion WinAPI_GetThemeBitmap WinAPI_GetThemeBool WinAPI_GetThemeColor WinAPI_GetThemeDocumentationProperty WinAPI_GetThemeEnumValue WinAPI_GetThemeFilename WinAPI_GetThemeFont WinAPI_GetThemeInt WinAPI_GetThemeMargins WinAPI_GetThemeMetric WinAPI_GetThemePartSize WinAPI_GetThemePosition WinAPI_GetThemePropertyOrigin WinAPI_GetThemeRect WinAPI_GetThemeString WinAPI_GetThemeSysBool WinAPI_GetThemeSysColor WinAPI_GetThemeSysColorBrush WinAPI_GetThemeSysFont WinAPI_GetThemeSysInt WinAPI_GetThemeSysSize WinAPI_GetThemeSysString WinAPI_GetThemeTextExtent WinAPI_GetThemeTextMetrics WinAPI_GetThemeTransitionDuration WinAPI_GetThreadDesktop WinAPI_GetThreadErrorMode WinAPI_GetThreadLocale WinAPI_GetThreadUILanguage WinAPI_GetTickCount WinAPI_GetTickCount64 WinAPI_GetTimeFormat WinAPI_GetTopWindow WinAPI_GetUDFColorMode WinAPI_GetUpdateRect WinAPI_GetUpdateRgn WinAPI_GetUserDefaultLangID WinAPI_GetUserDefaultLCID WinAPI_GetUserDefaultUILanguage WinAPI_GetUserGeoID WinAPI_GetUserObjectInformation WinAPI_GetVersion WinAPI_GetVersionEx WinAPI_GetVolumeInformation WinAPI_GetVolumeInformationByHandle WinAPI_GetVolumeNameForVolumeMountPoint WinAPI_GetWindow WinAPI_GetWindowDC WinAPI_GetWindowDisplayAffinity WinAPI_GetWindowExt WinAPI_GetWindowFileName WinAPI_GetWindowHeight WinAPI_GetWindowInfo WinAPI_GetWindowLong WinAPI_GetWindowOrg WinAPI_GetWindowPlacement WinAPI_GetWindowRect WinAPI_GetWindowRgn WinAPI_GetWindowRgnBox WinAPI_GetWindowSubclass WinAPI_GetWindowText WinAPI_GetWindowTheme WinAPI_GetWindowThreadProcessId WinAPI_GetWindowWidth WinAPI_GetWorkArea WinAPI_GetWorldTransform WinAPI_GetXYFromPoint WinAPI_GlobalMemoryStatus WinAPI_GradientFill WinAPI_GUIDFromString WinAPI_GUIDFromStringEx WinAPI_HashData WinAPI_HashString WinAPI_HiByte WinAPI_HideCaret WinAPI_HiDWord WinAPI_HiWord WinAPI_InflateRect WinAPI_InitMUILanguage WinAPI_InProcess WinAPI_IntersectClipRect WinAPI_IntersectRect WinAPI_IntToDWord WinAPI_IntToFloat WinAPI_InvalidateRect WinAPI_InvalidateRgn WinAPI_InvertANDBitmap WinAPI_InvertColor WinAPI_InvertRect WinAPI_InvertRgn WinAPI_IOCTL WinAPI_IsAlphaBitmap WinAPI_IsBadCodePtr WinAPI_IsBadReadPtr WinAPI_IsBadStringPtr WinAPI_IsBadWritePtr WinAPI_IsChild WinAPI_IsClassName WinAPI_IsDoorOpen WinAPI_IsElevated WinAPI_IsHungAppWindow WinAPI_IsIconic WinAPI_IsInternetConnected WinAPI_IsLoadKBLayout WinAPI_IsMemory WinAPI_IsNameInExpression WinAPI_IsNetworkAlive WinAPI_IsPathShared WinAPI_IsProcessInJob WinAPI_IsProcessorFeaturePresent WinAPI_IsRectEmpty WinAPI_IsThemeActive WinAPI_IsThemeBackgroundPartiallyTransparent WinAPI_IsThemePartDefined WinAPI_IsValidLocale WinAPI_IsWindow WinAPI_IsWindowEnabled WinAPI_IsWindowUnicode WinAPI_IsWindowVisible WinAPI_IsWow64Process WinAPI_IsWritable WinAPI_IsZoomed WinAPI_Keybd_Event WinAPI_KillTimer WinAPI_LineDDA WinAPI_LineTo WinAPI_LoadBitmap WinAPI_LoadCursor WinAPI_LoadCursorFromFile WinAPI_LoadIcon WinAPI_LoadIconMetric WinAPI_LoadIconWithScaleDown WinAPI_LoadImage WinAPI_LoadIndirectString WinAPI_LoadKeyboardLayout WinAPI_LoadLibrary WinAPI_LoadLibraryEx WinAPI_LoadMedia WinAPI_LoadResource WinAPI_LoadShell32Icon WinAPI_LoadString WinAPI_LoadStringEx WinAPI_LoByte WinAPI_LocalFree WinAPI_LockDevice WinAPI_LockFile WinAPI_LockResource WinAPI_LockWindowUpdate WinAPI_LockWorkStation WinAPI_LoDWord WinAPI_LongMid WinAPI_LookupIconIdFromDirectoryEx WinAPI_LoWord WinAPI_LPtoDP WinAPI_MAKELANGID WinAPI_MAKELCID WinAPI_MakeLong WinAPI_MakeQWord WinAPI_MakeWord WinAPI_MapViewOfFile WinAPI_MapVirtualKey WinAPI_MaskBlt WinAPI_MessageBeep WinAPI_MessageBoxCheck WinAPI_MessageBoxIndirect WinAPI_MirrorIcon WinAPI_ModifyWorldTransform WinAPI_MonitorFromPoint WinAPI_MonitorFromRect WinAPI_MonitorFromWindow WinAPI_Mouse_Event WinAPI_MoveFileEx WinAPI_MoveMemory WinAPI_MoveTo WinAPI_MoveToEx WinAPI_MoveWindow WinAPI_MsgBox WinAPI_MulDiv WinAPI_MultiByteToWideChar WinAPI_MultiByteToWideCharEx WinAPI_NtStatusToDosError WinAPI_OemToChar WinAPI_OffsetClipRgn WinAPI_OffsetPoints WinAPI_OffsetRect WinAPI_OffsetRgn WinAPI_OffsetWindowOrg WinAPI_OpenDesktop WinAPI_OpenFileById WinAPI_OpenFileDlg WinAPI_OpenFileMapping WinAPI_OpenIcon WinAPI_OpenInputDesktop WinAPI_OpenJobObject WinAPI_OpenMutex WinAPI_OpenProcess WinAPI_OpenProcessToken WinAPI_OpenSemaphore WinAPI_OpenThemeData WinAPI_OpenWindowStation WinAPI_PageSetupDlg WinAPI_PaintDesktop WinAPI_PaintRgn WinAPI_ParseURL WinAPI_ParseUserName WinAPI_PatBlt WinAPI_PathAddBackslash WinAPI_PathAddExtension WinAPI_PathAppend WinAPI_PathBuildRoot WinAPI_PathCanonicalize WinAPI_PathCommonPrefix WinAPI_PathCompactPath WinAPI_PathCompactPathEx WinAPI_PathCreateFromUrl WinAPI_PathFindExtension WinAPI_PathFindFileName WinAPI_PathFindNextComponent WinAPI_PathFindOnPath WinAPI_PathGetArgs WinAPI_PathGetCharType WinAPI_PathGetDriveNumber WinAPI_PathIsContentType WinAPI_PathIsDirectory WinAPI_PathIsDirectoryEmpty WinAPI_PathIsExe WinAPI_PathIsFileSpec WinAPI_PathIsLFNFileSpec WinAPI_PathIsRelative WinAPI_PathIsRoot WinAPI_PathIsSameRoot WinAPI_PathIsSystemFolder WinAPI_PathIsUNC WinAPI_PathIsUNCServer WinAPI_PathIsUNCServerShare WinAPI_PathMakeSystemFolder WinAPI_PathMatchSpec WinAPI_PathParseIconLocation WinAPI_PathRelativePathTo WinAPI_PathRemoveArgs WinAPI_PathRemoveBackslash WinAPI_PathRemoveExtension WinAPI_PathRemoveFileSpec WinAPI_PathRenameExtension WinAPI_PathSearchAndQualify WinAPI_PathSkipRoot WinAPI_PathStripPath WinAPI_PathStripToRoot WinAPI_PathToRegion WinAPI_PathUndecorate WinAPI_PathUnExpandEnvStrings WinAPI_PathUnmakeSystemFolder WinAPI_PathUnquoteSpaces WinAPI_PathYetAnotherMakeUniqueName WinAPI_PickIconDlg WinAPI_PlayEnhMetaFile WinAPI_PlaySound WinAPI_PlgBlt WinAPI_PointFromRect WinAPI_PolyBezier WinAPI_PolyBezierTo WinAPI_PolyDraw WinAPI_Polygon WinAPI_PostMessage WinAPI_PrimaryLangId WinAPI_PrintDlg WinAPI_PrintDlgEx WinAPI_PrintWindow WinAPI_ProgIDFromCLSID WinAPI_PtInRect WinAPI_PtInRectEx WinAPI_PtInRegion WinAPI_PtVisible WinAPI_QueryDosDevice WinAPI_QueryInformationJobObject WinAPI_QueryPerformanceCounter WinAPI_QueryPerformanceFrequency WinAPI_RadialGradientFill WinAPI_ReadDirectoryChanges WinAPI_ReadFile WinAPI_ReadProcessMemory WinAPI_Rectangle WinAPI_RectInRegion WinAPI_RectIsEmpty WinAPI_RectVisible WinAPI_RedrawWindow WinAPI_RegCloseKey WinAPI_RegConnectRegistry WinAPI_RegCopyTree WinAPI_RegCopyTreeEx WinAPI_RegCreateKey WinAPI_RegDeleteEmptyKey WinAPI_RegDeleteKey WinAPI_RegDeleteKeyValue WinAPI_RegDeleteTree WinAPI_RegDeleteTreeEx WinAPI_RegDeleteValue WinAPI_RegDisableReflectionKey WinAPI_RegDuplicateHKey WinAPI_RegEnableReflectionKey WinAPI_RegEnumKey WinAPI_RegEnumValue WinAPI_RegFlushKey WinAPI_RegisterApplicationRestart WinAPI_RegisterClass WinAPI_RegisterClassEx WinAPI_RegisterHotKey WinAPI_RegisterPowerSettingNotification WinAPI_RegisterRawInputDevices WinAPI_RegisterShellHookWindow WinAPI_RegisterWindowMessage WinAPI_RegLoadMUIString WinAPI_RegNotifyChangeKeyValue WinAPI_RegOpenKey WinAPI_RegQueryInfoKey WinAPI_RegQueryLastWriteTime WinAPI_RegQueryMultipleValues WinAPI_RegQueryReflectionKey WinAPI_RegQueryValue WinAPI_RegRestoreKey WinAPI_RegSaveKey WinAPI_RegSetValue WinAPI_ReleaseCapture WinAPI_ReleaseDC WinAPI_ReleaseMutex WinAPI_ReleaseSemaphore WinAPI_ReleaseStream WinAPI_RemoveClipboardFormatListener WinAPI_RemoveDirectory WinAPI_RemoveFontMemResourceEx WinAPI_RemoveFontResourceEx WinAPI_RemoveWindowSubclass WinAPI_ReOpenFile WinAPI_ReplaceFile WinAPI_ReplaceTextDlg WinAPI_ResetEvent WinAPI_RestartDlg WinAPI_RestoreDC WinAPI_RGB WinAPI_RotatePoints WinAPI_RoundRect WinAPI_SaveDC WinAPI_SaveFileDlg WinAPI_SaveHBITMAPToFile WinAPI_SaveHICONToFile WinAPI_ScaleWindowExt WinAPI_ScreenToClient WinAPI_SearchPath WinAPI_SelectClipPath WinAPI_SelectClipRgn WinAPI_SelectObject WinAPI_SendMessageTimeout WinAPI_SetActiveWindow WinAPI_SetArcDirection WinAPI_SetBitmapBits WinAPI_SetBitmapDimensionEx WinAPI_SetBkColor WinAPI_SetBkMode WinAPI_SetBoundsRect WinAPI_SetBrushOrg WinAPI_SetCapture WinAPI_SetCaretBlinkTime WinAPI_SetCaretPos WinAPI_SetClassLongEx WinAPI_SetColorAdjustment WinAPI_SetCompression WinAPI_SetCurrentDirectory WinAPI_SetCurrentProcessExplicitAppUserModelID WinAPI_SetCursor WinAPI_SetDCBrushColor WinAPI_SetDCPenColor WinAPI_SetDefaultPrinter WinAPI_SetDeviceGammaRamp WinAPI_SetDIBColorTable WinAPI_SetDIBits WinAPI_SetDIBitsToDevice WinAPI_SetDllDirectory WinAPI_SetEndOfFile WinAPI_SetEnhMetaFileBits WinAPI_SetErrorMode WinAPI_SetEvent WinAPI_SetFileAttributes WinAPI_SetFileInformationByHandleEx WinAPI_SetFilePointer WinAPI_SetFilePointerEx WinAPI_SetFileShortName WinAPI_SetFileValidData WinAPI_SetFocus WinAPI_SetFont WinAPI_SetForegroundWindow WinAPI_SetFRBuffer WinAPI_SetGraphicsMode WinAPI_SetHandleInformation WinAPI_SetInformationJobObject WinAPI_SetKeyboardLayout WinAPI_SetKeyboardState WinAPI_SetLastError WinAPI_SetLayeredWindowAttributes WinAPI_SetLocaleInfo WinAPI_SetMapMode WinAPI_SetMessageExtraInfo WinAPI_SetParent WinAPI_SetPixel WinAPI_SetPolyFillMode WinAPI_SetPriorityClass WinAPI_SetProcessAffinityMask WinAPI_SetProcessShutdownParameters WinAPI_SetProcessWindowStation WinAPI_SetRectRgn WinAPI_SetROP2 WinAPI_SetSearchPathMode WinAPI_SetStretchBltMode WinAPI_SetSysColors WinAPI_SetSystemCursor WinAPI_SetTextAlign WinAPI_SetTextCharacterExtra WinAPI_SetTextColor WinAPI_SetTextJustification WinAPI_SetThemeAppProperties WinAPI_SetThreadDesktop WinAPI_SetThreadErrorMode WinAPI_SetThreadExecutionState WinAPI_SetThreadLocale WinAPI_SetThreadUILanguage WinAPI_SetTimer WinAPI_SetUDFColorMode WinAPI_SetUserGeoID WinAPI_SetUserObjectInformation WinAPI_SetVolumeMountPoint WinAPI_SetWindowDisplayAffinity WinAPI_SetWindowExt WinAPI_SetWindowLong WinAPI_SetWindowOrg WinAPI_SetWindowPlacement WinAPI_SetWindowPos WinAPI_SetWindowRgn WinAPI_SetWindowsHookEx WinAPI_SetWindowSubclass WinAPI_SetWindowText WinAPI_SetWindowTheme WinAPI_SetWinEventHook WinAPI_SetWorldTransform WinAPI_SfcIsFileProtected WinAPI_SfcIsKeyProtected WinAPI_ShellAboutDlg WinAPI_ShellAddToRecentDocs WinAPI_ShellChangeNotify WinAPI_ShellChangeNotifyDeregister WinAPI_ShellChangeNotifyRegister WinAPI_ShellCreateDirectory WinAPI_ShellEmptyRecycleBin WinAPI_ShellExecute WinAPI_ShellExecuteEx WinAPI_ShellExtractAssociatedIcon WinAPI_ShellExtractIcon WinAPI_ShellFileOperation WinAPI_ShellFlushSFCache WinAPI_ShellGetFileInfo WinAPI_ShellGetIconOverlayIndex WinAPI_ShellGetImageList WinAPI_ShellGetKnownFolderIDList WinAPI_ShellGetKnownFolderPath WinAPI_ShellGetLocalizedName WinAPI_ShellGetPathFromIDList WinAPI_ShellGetSetFolderCustomSettings WinAPI_ShellGetSettings WinAPI_ShellGetSpecialFolderLocation WinAPI_ShellGetSpecialFolderPath WinAPI_ShellGetStockIconInfo WinAPI_ShellILCreateFromPath WinAPI_ShellNotifyIcon WinAPI_ShellNotifyIconGetRect WinAPI_ShellObjectProperties WinAPI_ShellOpenFolderAndSelectItems WinAPI_ShellOpenWithDlg WinAPI_ShellQueryRecycleBin WinAPI_ShellQueryUserNotificationState WinAPI_ShellRemoveLocalizedName WinAPI_ShellRestricted WinAPI_ShellSetKnownFolderPath WinAPI_ShellSetLocalizedName WinAPI_ShellSetSettings WinAPI_ShellStartNetConnectionDlg WinAPI_ShellUpdateImage WinAPI_ShellUserAuthenticationDlg WinAPI_ShellUserAuthenticationDlgEx WinAPI_ShortToWord WinAPI_ShowCaret WinAPI_ShowCursor WinAPI_ShowError WinAPI_ShowLastError WinAPI_ShowMsg WinAPI_ShowOwnedPopups WinAPI_ShowWindow WinAPI_ShutdownBlockReasonCreate WinAPI_ShutdownBlockReasonDestroy WinAPI_ShutdownBlockReasonQuery WinAPI_SizeOfResource WinAPI_StretchBlt WinAPI_StretchDIBits WinAPI_StrFormatByteSize WinAPI_StrFormatByteSizeEx WinAPI_StrFormatKBSize WinAPI_StrFromTimeInterval WinAPI_StringFromGUID WinAPI_StringLenA WinAPI_StringLenW WinAPI_StrLen WinAPI_StrokeAndFillPath WinAPI_StrokePath WinAPI_StructToArray WinAPI_SubLangId WinAPI_SubtractRect WinAPI_SwapDWord WinAPI_SwapQWord WinAPI_SwapWord WinAPI_SwitchColor WinAPI_SwitchDesktop WinAPI_SwitchToThisWindow WinAPI_SystemParametersInfo WinAPI_TabbedTextOut WinAPI_TerminateJobObject WinAPI_TerminateProcess WinAPI_TextOut WinAPI_TileWindows WinAPI_TrackMouseEvent WinAPI_TransparentBlt WinAPI_TwipsPerPixelX WinAPI_TwipsPerPixelY WinAPI_UnhookWindowsHookEx WinAPI_UnhookWinEvent WinAPI_UnionRect WinAPI_UnionStruct WinAPI_UniqueHardwareID WinAPI_UnloadKeyboardLayout WinAPI_UnlockFile WinAPI_UnmapViewOfFile WinAPI_UnregisterApplicationRestart WinAPI_UnregisterClass WinAPI_UnregisterHotKey WinAPI_UnregisterPowerSettingNotification WinAPI_UpdateLayeredWindow WinAPI_UpdateLayeredWindowEx WinAPI_UpdateLayeredWindowIndirect WinAPI_UpdateResource WinAPI_UpdateWindow WinAPI_UrlApplyScheme WinAPI_UrlCanonicalize WinAPI_UrlCombine WinAPI_UrlCompare WinAPI_UrlCreateFromPath WinAPI_UrlFixup WinAPI_UrlGetPart WinAPI_UrlHash WinAPI_UrlIs WinAPI_UserHandleGrantAccess WinAPI_ValidateRect WinAPI_ValidateRgn WinAPI_VerQueryRoot WinAPI_VerQueryValue WinAPI_VerQueryValueEx WinAPI_WaitForInputIdle WinAPI_WaitForMultipleObjects WinAPI_WaitForSingleObject WinAPI_WideCharToMultiByte WinAPI_WidenPath WinAPI_WindowFromDC WinAPI_WindowFromPoint WinAPI_WordToShort WinAPI_Wow64EnableWow64FsRedirection WinAPI_WriteConsole WinAPI_WriteFile WinAPI_WriteProcessMemory WinAPI_ZeroMemory WinNet_AddConnection WinNet_AddConnection2 WinNet_AddConnection3 WinNet_CancelConnection WinNet_CancelConnection2 WinNet_CloseEnum WinNet_ConnectionDialog WinNet_ConnectionDialog1 WinNet_DisconnectDialog WinNet_DisconnectDialog1 WinNet_EnumResource WinNet_GetConnection WinNet_GetConnectionPerformance WinNet_GetLastError WinNet_GetNetworkInformation WinNet_GetProviderName WinNet_GetResourceInformation WinNet_GetResourceParent WinNet_GetUniversalName WinNet_GetUser WinNet_OpenEnum WinNet_RestoreConnection WinNet_UseConnection Word_Create Word_DocAdd Word_DocAttach Word_DocClose Word_DocExport Word_DocFind Word_DocFindReplace Word_DocGet Word_DocLinkAdd Word_DocLinkGet Word_DocOpen Word_DocPictureAdd Word_DocPrint Word_DocRangeSet Word_DocSave Word_DocSaveAs Word_DocTableRead Word_DocTableWrite Word_Quit",I={ +v:[e.C(";","$",{r:0}),e.C("#cs","#ce"),e.C("#comments-start","#comments-end")]},n={b:"\\$[A-z0-9_]+"},l={cN:"string",v:[{b:/"/,e:/"/,c:[{b:/""/,r:0}]},{b:/'/,e:/'/,c:[{b:/''/,r:0}]}]},o={v:[e.BNM,e.CNM]},a={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"include include-once NoTrayIcon OnAutoItStartRegister RequireAdmin pragma Au3Stripper_Ignore_Funcs Au3Stripper_Ignore_Variables Au3Stripper_Off Au3Stripper_On Au3Stripper_Parameters AutoIt3Wrapper_Add_Constants AutoIt3Wrapper_Au3Check_Parameters AutoIt3Wrapper_Au3Check_Stop_OnWarning AutoIt3Wrapper_Aut2Exe AutoIt3Wrapper_AutoIt3 AutoIt3Wrapper_AutoIt3Dir AutoIt3Wrapper_Change2CUI AutoIt3Wrapper_Compile_Both AutoIt3Wrapper_Compression AutoIt3Wrapper_EndIf AutoIt3Wrapper_Icon AutoIt3Wrapper_If_Compile AutoIt3Wrapper_If_Run AutoIt3Wrapper_Jump_To_First_Error AutoIt3Wrapper_OutFile AutoIt3Wrapper_OutFile_Type AutoIt3Wrapper_OutFile_X64 AutoIt3Wrapper_PlugIn_Funcs AutoIt3Wrapper_Res_Comment Autoit3Wrapper_Res_Compatibility AutoIt3Wrapper_Res_Description AutoIt3Wrapper_Res_Field AutoIt3Wrapper_Res_File_Add AutoIt3Wrapper_Res_FileVersion AutoIt3Wrapper_Res_FileVersion_AutoIncrement AutoIt3Wrapper_Res_Icon_Add AutoIt3Wrapper_Res_Language AutoIt3Wrapper_Res_LegalCopyright AutoIt3Wrapper_Res_ProductVersion AutoIt3Wrapper_Res_requestedExecutionLevel AutoIt3Wrapper_Res_SaveSource AutoIt3Wrapper_Run_After AutoIt3Wrapper_Run_Au3Check AutoIt3Wrapper_Run_Au3Stripper AutoIt3Wrapper_Run_Before AutoIt3Wrapper_Run_Debug_Mode AutoIt3Wrapper_Run_SciTE_Minimized AutoIt3Wrapper_Run_SciTE_OutputPane_Minimized AutoIt3Wrapper_Run_Tidy AutoIt3Wrapper_ShowProgress AutoIt3Wrapper_Testing AutoIt3Wrapper_Tidy_Stop_OnError AutoIt3Wrapper_UPX_Parameters AutoIt3Wrapper_UseUPX AutoIt3Wrapper_UseX64 AutoIt3Wrapper_Version AutoIt3Wrapper_Versioning AutoIt3Wrapper_Versioning_Parameters Tidy_Off Tidy_On Tidy_Parameters EndRegion Region"},c:[{b:/\\\n/,r:0},{bK:"include",k:{"meta-keyword":"include"},e:"$",c:[l,{cN:"meta-string",v:[{b:"<",e:">"},{b:/"/,e:/"/,c:[{b:/""/,r:0}]},{b:/'/,e:/'/,c:[{b:/''/,r:0}]}]}]},l,I]},_={cN:"symbol",b:"@[A-z0-9_]+"},G={cN:"function",bK:"Func",e:"$",i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:[n,l,o]}]};return{cI:!0,i:/\/\*/,k:{keyword:t,built_in:i,literal:r},c:[I,n,l,o,a,_,G]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/avrasm.js b/lib/highlight_js/assets/lang/avrasm.js index c3ff1ee24e9..d741bd0e294 100644 --- a/lib/highlight_js/assets/lang/avrasm.js +++ b/lib/highlight_js/assets/lang/avrasm.js @@ -1 +1 @@ -hljs.registerLanguage("avrasm",function(r){return{cI:!0,l:"\\.?"+r.IR,k:{keyword:"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf",preprocessor:".byte .cseg .db .def .device .dseg .dw .endmacro .equ .eseg .exit .include .list .listmac .macro .nolist .org .set"},c:[r.CBCM,r.C(";","$",{r:0}),r.CNM,r.BNM,{cN:"number",b:"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},r.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"label",b:"^[A-Za-z0-9_.$]+:"},{cN:"preprocessor",b:"#",e:"$"},{cN:"localvars",b:"@[0-9]+"}]}}); \ No newline at end of file +hljs.registerLanguage("avrasm",function(r){return{cI:!0,l:"\\.?"+r.IR,k:{keyword:"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf",meta:".byte .cseg .db .def .device .dseg .dw .endmacro .equ .eseg .exit .include .list .listmac .macro .nolist .org .set"},c:[r.CBCM,r.C(";","$",{r:0}),r.CNM,r.BNM,{cN:"number",b:"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},r.QSM,{cN:"string",b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"},{cN:"symbol",b:"^[A-Za-z0-9_.$]+:"},{cN:"meta",b:"#",e:"$"},{cN:"subst",b:"@[0-9]+"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/axapta.js b/lib/highlight_js/assets/lang/axapta.js index 4574e0628f9..016d5a28971 100644 --- a/lib/highlight_js/assets/lang/axapta.js +++ b/lib/highlight_js/assets/lang/axapta.js @@ -1 +1 @@ -hljs.registerLanguage("axapta",function(e){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"class",bK:"class interface",e:"{",eE:!0,i:":",c:[{bK:"extends implements"},e.UTM]}]}}); \ No newline at end of file +hljs.registerLanguage("axapta",function(e){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM,{cN:"meta",b:"#",e:"$"},{cN:"class",bK:"class interface",e:"{",eE:!0,i:":",c:[{bK:"extends implements"},e.UTM]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/bash.js b/lib/highlight_js/assets/lang/bash.js index dc42cd4d25e..7d4af5a1755 100644 --- a/lib/highlight_js/assets/lang/bash.js +++ b/lib/highlight_js/assets/lang/bash.js @@ -1 +1 @@ -hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,e.NM,s,a,t]}}); \ No newline at end of file +hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/basic.js b/lib/highlight_js/assets/lang/basic.js new file mode 100644 index 00000000000..7aca8079b1b --- /dev/null +++ b/lib/highlight_js/assets/lang/basic.js @@ -0,0 +1 @@ +hljs.registerLanguage("basic",function(E){return{cI:!0,i:"^.",l:"[a-zA-Z][a-zA-Z0-9_$%!#]*",k:{keyword:"ABS ASC AND ATN AUTO|0 BEEP BLOAD|10 BSAVE|10 CALL CALLS CDBL CHAIN CHDIR CHR$|10 CINT CIRCLE CLEAR CLOSE CLS COLOR COM COMMON CONT COS CSNG CSRLIN CVD CVI CVS DATA DATE$ DEFDBL DEFINT DEFSNG DEFSTR DEF|0 SEG USR DELETE DIM DRAW EDIT END ENVIRON ENVIRON$ EOF EQV ERASE ERDEV ERDEV$ ERL ERR ERROR EXP FIELD FILES FIX FOR|0 FRE GET GOSUB|10 GOTO HEX$ IF|0 THEN ELSE|0 INKEY$ INP INPUT INPUT# INPUT$ INSTR IMP INT IOCTL IOCTL$ KEY ON OFF LIST KILL LEFT$ LEN LET LINE LLIST LOAD LOC LOCATE LOF LOG LPRINT USING LSET MERGE MID$ MKDIR MKD$ MKI$ MKS$ MOD NAME NEW NEXT NOISE NOT OCT$ ON OR PEN PLAY STRIG OPEN OPTION BASE OUT PAINT PALETTE PCOPY PEEK PMAP POINT POKE POS PRINT PRINT] PSET PRESET PUT RANDOMIZE READ REM RENUM RESET|0 RESTORE RESUME RETURN|0 RIGHT$ RMDIR RND RSET RUN SAVE SCREEN SGN SHELL SIN SOUND SPACE$ SPC SQR STEP STICK STOP STR$ STRING$ SWAP SYSTEM TAB TAN TIME$ TIMER TROFF TRON TO USR VAL VARPTR VARPTR$ VIEW WAIT WHILE WEND WIDTH WINDOW WRITE XOR"},c:[E.QSM,E.C("REM","$",{r:10}),E.C("'","$",{r:0}),{cN:"symbol",b:"^[0-9]+ ",r:10},{cN:"number",b:"\\b([0-9]+[0-9edED.]*[#!]?)",r:0},{cN:"number",b:"(&[hH][0-9a-fA-F]{1,4})"},{cN:"number",b:"(&[oO][0-7]{1,6})"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/cal.js b/lib/highlight_js/assets/lang/cal.js index 409b3fe92d8..c67fd244cea 100644 --- a/lib/highlight_js/assets/lang/cal.js +++ b/lib/highlight_js/assets/lang/cal.js @@ -1 +1 @@ -hljs.registerLanguage("cal",function(e){var r="div mod in and or not xor asserterror begin case do downto else end exit for if of repeat then to until while with var",t="false true",a=[e.CLCM,e.C(/\{/,/\}/,{r:0}),e.C(/\(\*/,/\*\)/,{r:10})],c={cN:"string",b:/'/,e:/'/,c:[{b:/''/}]},o={cN:"string",b:/(#\d+)+/},n={cN:"date",b:"\\b\\d+(\\.\\d+)?(DT|D|T)",r:0},i={cN:"variable",b:'"',e:'"'},d={cN:"function",bK:"procedure",e:/[:;]/,k:"procedure|10",c:[e.TM,{cN:"params",b:/\(/,e:/\)/,k:r,c:[c,o]}].concat(a)},b={cN:"class",b:"OBJECT (Table|Form|Report|Dataport|Codeunit|XMLport|MenuSuite|Page|Query) (\\d+) ([^\\r\\n]+)",rB:!0,c:[e.TM,d]};return{cI:!0,k:{keyword:r,literal:t},c:[c,o,n,i,e.NM,b,d]}}); \ No newline at end of file +hljs.registerLanguage("cal",function(e){var r="div mod in and or not xor asserterror begin case do downto else end exit for if of repeat then to until while with var",t="false true",c=[e.CLCM,e.C(/\{/,/\}/,{r:0}),e.C(/\(\*/,/\*\)/,{r:10})],n={cN:"string",b:/'/,e:/'/,c:[{b:/''/}]},o={cN:"string",b:/(#\d+)+/},a={cN:"number",b:"\\b\\d+(\\.\\d+)?(DT|D|T)",r:0},i={cN:"string",b:'"',e:'"'},d={cN:"function",bK:"procedure",e:/[:;]/,k:"procedure|10",c:[e.TM,{cN:"params",b:/\(/,e:/\)/,k:r,c:[n,o]}].concat(c)},s={cN:"class",b:"OBJECT (Table|Form|Report|Dataport|Codeunit|XMLport|MenuSuite|Page|Query) (\\d+) ([^\\r\\n]+)",rB:!0,c:[e.TM,d]};return{cI:!0,k:{keyword:r,literal:t},i:/\/\*/,c:[n,o,a,i,e.NM,s,d]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/capnproto.js b/lib/highlight_js/assets/lang/capnproto.js index a4240ccf4e8..3728f16f0f8 100644 --- a/lib/highlight_js/assets/lang/capnproto.js +++ b/lib/highlight_js/assets/lang/capnproto.js @@ -1 +1 @@ -hljs.registerLanguage("capnproto",function(t){return{aliases:["capnp"],k:{keyword:"struct enum interface union group import using const annotation extends in of on as with from fixed",built_in:"Void Bool Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Float32 Float64 Text Data AnyPointer AnyStruct Capability List",literal:"true false"},c:[t.QSM,t.NM,t.HCM,{cN:"shebang",b:/@0x[\w\d]{16};/,i:/\n/},{cN:"number",b:/@\d+\b/},{cN:"class",bK:"struct enum",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]},{cN:"class",bK:"interface",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]}]}}); \ No newline at end of file +hljs.registerLanguage("capnproto",function(t){return{aliases:["capnp"],k:{keyword:"struct enum interface union group import using const annotation extends in of on as with from fixed",built_in:"Void Bool Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Float32 Float64 Text Data AnyPointer AnyStruct Capability List",literal:"true false"},c:[t.QSM,t.NM,t.HCM,{cN:"meta",b:/@0x[\w\d]{16};/,i:/\n/},{cN:"symbol",b:/@\d+\b/},{cN:"class",bK:"struct enum",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]},{cN:"class",bK:"interface",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/ceylon.js b/lib/highlight_js/assets/lang/ceylon.js new file mode 100644 index 00000000000..951e03677ba --- /dev/null +++ b/lib/highlight_js/assets/lang/ceylon.js @@ -0,0 +1 @@ +hljs.registerLanguage("ceylon",function(e){var a="assembly module package import alias class interface object given value assign void function new of extends satisfies abstracts in out return break continue throw assert dynamic if else switch case for while try catch finally then let this outer super is exists nonempty",t="shared abstract formal default actual variable late native deprecatedfinal sealed annotation suppressWarnings small",s="doc by license see throws tagged",n={cN:"subst",eB:!0,eE:!0,b:/``/,e:/``/,k:a,r:10},r=[{cN:"string",b:'"""',e:'"""',r:10},{cN:"string",b:'"',e:'"',c:[n]},{cN:"string",b:"'",e:"'"},{cN:"number",b:"#[0-9a-fA-F_]+|\\$[01_]+|[0-9_]+(?:\\.[0-9_](?:[eE][+-]?\\d+)?)?[kMGTPmunpf]?",r:0}];return n.c=r,{k:{keyword:a+" "+t,meta:s},i:"\\$[^01]|#[^0-9a-fA-F]",c:[e.CLCM,e.C("/\\*","\\*/",{c:["self"]}),{cN:"meta",b:'@[a-z]\\w*(?:\\:"[^"]*")?'}].concat(r)}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/clojure-repl.js b/lib/highlight_js/assets/lang/clojure-repl.js index 0d7541d0124..3951cf9ad85 100644 --- a/lib/highlight_js/assets/lang/clojure-repl.js +++ b/lib/highlight_js/assets/lang/clojure-repl.js @@ -1 +1 @@ -hljs.registerLanguage("clojure-repl",function(e){return{c:[{cN:"prompt",b:/^([\w.-]+|\s*#_)=>/,starts:{e:/$/,sL:"clojure",subLanguageMode:"continuous"}}]}}); \ No newline at end of file +hljs.registerLanguage("clojure-repl",function(e){return{c:[{cN:"meta",b:/^([\w.-]+|\s*#_)=>/,starts:{e:/$/,sL:"clojure"}}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/clojure.js b/lib/highlight_js/assets/lang/clojure.js index 1c6926e81e7..61aafe085dd 100644 --- a/lib/highlight_js/assets/lang/clojure.js +++ b/lib/highlight_js/assets/lang/clojure.js @@ -1 +1 @@ -hljs.registerLanguage("clojure",function(e){var t={built_in:"def cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},i=e.inherit(e.QSM,{i:null}),c=e.C(";","$",{r:0}),d={cN:"literal",b:/\b(true|false|nil)\b/},l={cN:"collection",b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p=e.C("\\^\\{","\\}"),u={cN:"attribute",b:"[:]"+n},f={cN:"list",b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"keyword",b:n,starts:h},b=[f,i,m,p,c,u,l,s,d,o];return f.c=[e.C("comment",""),y,h],h.c=b,l.c=b,{aliases:["clj"],i:/\S/,c:[f,i,m,p,c,u,l,s,d]}}); \ No newline at end of file +hljs.registerLanguage("clojure",function(e){var t={"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},i=e.inherit(e.QSM,{i:null}),c=e.C(";","$",{r:0}),d={cN:"literal",b:/\b(true|false|nil)\b/},l={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p=e.C("\\^\\{","\\}"),u={cN:"symbol",b:"[:]"+n},f={b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"name",b:n,starts:h},b=[f,i,m,p,c,u,l,s,d,o];return f.c=[e.C("comment",""),y,h],h.c=b,l.c=b,{aliases:["clj"],i:/\S/,c:[f,i,m,p,c,u,l,s,d]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/cmake.js b/lib/highlight_js/assets/lang/cmake.js index e2605bef3db..0295f8a79a3 100644 --- a/lib/highlight_js/assets/lang/cmake.js +++ b/lib/highlight_js/assets/lang/cmake.js @@ -1 +1 @@ -hljs.registerLanguage("cmake",function(e){return{aliases:["cmake.in"],cI:!0,k:{keyword:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or",operator:"equal less greater strless strgreater strequal matches"},c:[{cN:"envvar",b:"\\${",e:"}"},e.HCM,e.QSM,e.NM]}}); \ No newline at end of file +hljs.registerLanguage("cmake",function(e){return{aliases:["cmake.in"],cI:!0,k:{keyword:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or equal less greater strless strgreater strequal matches"},c:[{cN:"variable",b:"\\${",e:"}"},e.HCM,e.QSM,e.NM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/coffeescript.js b/lib/highlight_js/assets/lang/coffeescript.js index 2b0f0173bad..f3299c5b7b5 100644 --- a/lib/highlight_js/assets/lang/coffeescript.js +++ b/lib/highlight_js/assets/lang/coffeescript.js @@ -1 +1 @@ -hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",t={cN:"subst",b:/#\{/,e:/}/,k:c},r=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,t]},{b:/"/,e:/"/,c:[e.BE,t]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[t,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+n},{b:"`",e:"`",eB:!0,eE:!0,sL:"javascript"}];t.c=r;var i=e.inherit(e.TM,{b:n}),s="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(r)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:r.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+s,e:"[-=]>",rB:!0,c:[i,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:s,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{cN:"attribute",b:n+":",e:":",rB:!0,rE:!0,r:0}])}}); \ No newline at end of file +hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:c},s=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+n},{b:"`",e:"`",eB:!0,eE:!0,sL:"javascript"}];r.c=s;var i=e.inherit(e.TM,{b:n}),t="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(s)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:s.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+t,e:"[-=]>",rB:!0,c:[i,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:t,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{b:n+":",e:":",rB:!0,rE:!0,r:0}])}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/cos.js b/lib/highlight_js/assets/lang/cos.js new file mode 100644 index 00000000000..12ffd590bb9 --- /dev/null +++ b/lib/highlight_js/assets/lang/cos.js @@ -0,0 +1 @@ +hljs.registerLanguage("cos",function(e){var t={cN:"string",v:[{b:'"',e:'"',c:[{b:'""',r:0}]}]},r={cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)",r:0},s={keyword:["property","parameter","class","classmethod","clientmethod","extends","as","break","catch","close","continue","do","d","else","elseif","for","goto","halt","hang","h","if","job","j","kill","k","lock","l","merge","new","open","quit","q","read","r","return","set","s","tcommit","throw","trollback","try","tstart","use","view","while","write","w","xecute","x","zkill","znspace","zn","ztrap","zwrite","zw","zzdump","zzwrite","print","zbreak","zinsert","zload","zprint","zremove","zsave","zzprint","mv","mvcall","mvcrt","mvdim","mvprint","zquit","zsync","ascii"].join(" ")};return{cI:!0,aliases:["cos","cls"],k:s,c:[r,t,e.CLCM,e.CBCM,{cN:"comment",b:/;/,e:"$",r:0},{cN:"built_in",b:/(?:\$\$?|\.\.)\^?[a-zA-Z]+/},{cN:"built_in",b:/\$\$\$[a-zA-Z]+/},{cN:"built_in",b:/%[a-z]+(?:\.[a-z]+)*/},{cN:"symbol",b:/\^%?[a-zA-Z][\w]*/},{cN:"keyword",b:/##class|##super|#define|#dim/},{b:/&sql\(/,e:/\)/,eB:!0,eE:!0,sL:"sql"},{b:/&(js|jscript|javascript)/,eB:!0,eE:!0,sL:"javascript"},{b:/&html<\s*\s*>/,sL:"xml"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/cpp.js b/lib/highlight_js/assets/lang/cpp.js index c10e19991e7..4ef82476d83 100644 --- a/lib/highlight_js/assets/lang/cpp.js +++ b/lib/highlight_js/assets/lang/cpp.js @@ -1 +1 @@ -hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"[a-z\\d_]*_t"},r={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf"};return{aliases:["c","cc","h","c++","h++","hpp"],k:r,i:""]',k:"include",i:"\\n"},t.CLCM]},{b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:r,c:["self",e]},{b:t.IR+"::",k:r},{bK:"new throw return else",r:0},{cN:"function",b:"("+t.IR+"\\s+)+"+t.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:t.IR+"\\s*\\(",rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[t.CBCM]},t.CLCM,t.CBCM]}]}}); \ No newline at end of file +hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[t.inherit(t.QSM,{b:'((u8?|U)|L)?"'}),{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},i={cN:"number",v:[{b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},{b:t.CNR}],r:0},s={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef"},c:[{b:/\\\n/,r:0},{bK:"include",e:"$",k:{"meta-keyword":"include"},c:[t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:"<",e:">",i:"\\n"}]},r,t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"};return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"",k:c,c:["self",e]},{b:t.IR+"::",k:c},{bK:"new throw return else",r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,i]},t.CLCM,t.CBCM,s]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/crmsh.js b/lib/highlight_js/assets/lang/crmsh.js new file mode 100644 index 00000000000..902468b8950 --- /dev/null +++ b/lib/highlight_js/assets/lang/crmsh.js @@ -0,0 +1 @@ +hljs.registerLanguage("crmsh",function(t){var e="primitive rsc_template",r="group clone ms master location colocation order fencing_topology rsc_ticket acl_target acl_group user role tag xml",s="property rsc_defaults op_defaults",a="params meta operations op rule attributes utilization",i="read write deny defined not_defined in_range date spec in ref reference attribute type xpath version and or lt gt tag lte gte eq ne \\",o="number string",n="Master Started Slave Stopped start promote demote stop monitor true false";return{aliases:["crm","pcmk"],cI:!0,k:{keyword:a+" "+i+" "+o,literal:n},c:[t.HCM,{bK:"node",starts:{e:"\\s*([\\w_-]+:)?",starts:{cN:"title",e:"\\s*[\\$\\w_][\\w_-]*"}}},{bK:e,starts:{cN:"title",e:"\\s*[\\$\\w_][\\w_-]*",starts:{e:"\\s*@?[\\w_][\\w_\\.:-]*"}}},{b:"\\b("+r.split(" ").join("|")+")\\s+",k:r,starts:{cN:"title",e:"[\\$\\w_][\\w_-]*"}},{bK:s,starts:{cN:"title",e:"\\s*([\\w_-]+:)?"}},t.QSM,{cN:"meta",b:"(ocf|systemd|service|lsb):[\\w_:-]+",r:0},{cN:"number",b:"\\b\\d+(\\.\\d+)?(ms|s|h|m)?",r:0},{cN:"literal",b:"[-]?(infinity|inf)",r:0},{cN:"attr",b:/([A-Za-z\$_\#][\w_-]+)=/,r:0},{cN:"tag",b:"",r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/crystal.js b/lib/highlight_js/assets/lang/crystal.js new file mode 100644 index 00000000000..5c6e207afcc --- /dev/null +++ b/lib/highlight_js/assets/lang/crystal.js @@ -0,0 +1 @@ +hljs.registerLanguage("crystal",function(e){function r(e,r){var b=[{b:e,e:r}];return b[0].c=b,b}var b="(_[uif](8|16|32|64))?",c="[a-zA-Z_]\\w*[!?=]?",n="!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",s="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\][=?]?",i={keyword:"abstract alias as asm begin break case class def do else elsif end ensure enum extend for fun if ifdef include instance_sizeof is_a? lib macro module next of out pointerof private protected rescue responds_to? return require self sizeof struct super then type typeof union unless until when while with yield __DIR__ __FILE__ __LINE__",literal:"false nil true"},t={cN:"subst",b:"#{",e:"}",k:i},a={cN:"template-variable",v:[{b:"\\{\\{",e:"\\}\\}"},{b:"\\{%",e:"%\\}"}],k:i,r:10},l={cN:"string",c:[e.BE,t],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%w?\\(",e:"\\)",c:r("\\(","\\)")},{b:"%w?\\[",e:"\\]",c:r("\\[","\\]")},{b:"%w?{",e:"}",c:r("{","}")},{b:"%w?<",e:">",c:r("<",">")},{b:"%w?/",e:"/"},{b:"%w?%",e:"%"},{b:"%w?-",e:"-"},{b:"%w?\\|",e:"\\|"}],r:0},u={b:"("+n+")\\s*",c:[{cN:"regexp",c:[e.BE,t],v:[{b:"/",e:"/[a-z]*"},{b:"%r\\(",e:"\\)",c:r("\\(","\\)")},{b:"%r\\[",e:"\\]",c:r("\\[","\\]")},{b:"%r{",e:"}",c:r("{","}")},{b:"%r<",e:">",c:r("<",">")},{b:"%r/",e:"/"},{b:"%r%",e:"%"},{b:"%r-",e:"-"},{b:"%r\\|",e:"\\|"}]}],r:0},o={cN:"regexp",c:[e.BE,t],v:[{b:"%r\\(",e:"\\)",c:r("\\(","\\)")},{b:"%r\\[",e:"\\]",c:r("\\[","\\]")},{b:"%r{",e:"}",c:r("{","}")},{b:"%r<",e:">",c:r("<",">")},{b:"%r/",e:"/"},{b:"%r%",e:"%"},{b:"%r-",e:"-"},{b:"%r\\|",e:"\\|"}],r:0},_={cN:"meta",b:"@\\[",e:"\\]",r:5},f=[a,l,u,o,_,e.HCM,{cN:"class",bK:"class module struct",e:"$|;",i:/=/,c:[e.HCM,e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<"}]},{cN:"class",bK:"lib enum union",e:"$|;",i:/=/,c:[e.HCM,e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"})],r:10},{cN:"function",bK:"def",e:/\B\b/,c:[e.inherit(e.TM,{b:s,endsParent:!0})]},{cN:"function",bK:"fun macro",e:/\B\b/,c:[e.inherit(e.TM,{b:s,endsParent:!0})],r:5},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[l,{b:s}],r:0},{cN:"number",v:[{b:"\\b0b([01_]*[01])"+b},{b:"\\b0o([0-7_]*[0-7])"+b},{b:"\\b0x([A-Fa-f0-9_]*[A-Fa-f0-9])"+b},{b:"\\b(([0-9][0-9_]*[0-9]|[0-9])(\\.[0-9_]*[0-9])?([eE][+-]?[0-9_]*[0-9])?)"+b}],r:0}];return t.c=f,_.c=f,a.c=f.slice(1),{aliases:["cr"],l:c,k:i,c:f}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/cs.js b/lib/highlight_js/assets/lang/cs.js index c6e09c6d60a..055f4496d7f 100644 --- a/lib/highlight_js/assets/lang/cs.js +++ b/lib/highlight_js/assets/lang/cs.js @@ -1 +1 @@ -hljs.registerLanguage("cs",function(e){var r="abstract as base bool break byte case catch char checked const continue decimal dynamic default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long null when object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async protected public private internal ascending descending from get group into join let orderby partial select set value var where yield",t=e.IR+"(<"+e.IR+">)?";return{aliases:["csharp"],k:r,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"xmlDocTag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},e.ASM,e.QSM,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[{cN:"title",b:"[a-zA-Z](\\.?\\w)*",r:0},e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}}); \ No newline at end of file +hljs.registerLanguage("cs",function(e){var t="abstract as base bool break byte case catch char checked const continue decimal dynamic default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long null when object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async protected public private internal ascending descending from get group into join let orderby partial select set value var where yield",r=e.IR+"(<"+e.IR+">)?";return{aliases:["csharp"],k:t,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},e.ASM,e.QSM,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+r+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/csp.js b/lib/highlight_js/assets/lang/csp.js new file mode 100644 index 00000000000..e9d12e05e8a --- /dev/null +++ b/lib/highlight_js/assets/lang/csp.js @@ -0,0 +1 @@ +hljs.registerLanguage("csp",function(r){return{cI:!1,l:"[a-zA-Z][a-zA-Z0-9_-]*",k:{keyword:"base-uri child-src connect-src default-src font-src form-action frame-ancestors frame-src img-src media-src object-src plugin-types report-uri sandbox script-src style-src"},c:[{cN:"string",b:"'",e:"'"},{cN:"attribute",b:"^Content",e:":",eE:!0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/css.js b/lib/highlight_js/assets/lang/css.js index eba92b40dc3..f02d2b87341 100644 --- a/lib/highlight_js/assets/lang/css.js +++ b/lib/highlight_js/assets/lang/css.js @@ -1 +1 @@ -hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",a={cN:"function",b:c+"\\(",rB:!0,eE:!0,e:"\\("},r={cN:"rule",b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{cN:"value",eW:!0,eE:!0,c:[a,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]};return{cI:!0,i:/[=\/|']/,c:[e.CBCM,r,{cN:"id",b:/\#[A-Za-z0-9_-]+/},{cN:"class",b:/\.[A-Za-z0-9_-]+/,r:0},{cN:"attr_selector",b:/\[/,e:/\]/,i:"$"},{cN:"pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"']+/},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[a,e.ASM,e.QSM,e.CSSNM]}]},{cN:"tag",b:c,r:0},{cN:"rules",b:"{",e:"}",i:/\S/,r:0,c:[e.CBCM,r]}]}}); \ No newline at end of file +hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/d.js b/lib/highlight_js/assets/lang/d.js index 12386f84418..9e34711e0ec 100644 --- a/lib/highlight_js/assets/lang/d.js +++ b/lib/highlight_js/assets/lang/d.js @@ -1 +1 @@ -hljs.registerLanguage("d",function(e){var r={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},t="(0|[1-9][\\d_]*)",a="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",i="0[bB][01_]+",n="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",c="0[xX]"+n,_="([eE][+-]?"+a+")",d="("+a+"(\\.\\d*|"+_+")|\\d+\\."+a+a+"|\\."+t+_+"?)",o="(0[xX]("+n+"\\."+n+"|\\.?"+n+")[pP][+-]?"+a+")",s="("+t+"|"+i+"|"+c+")",l="("+o+"|"+d+")",u="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",b={cN:"number",b:"\\b"+s+"(L|u|U|Lu|LU|uL|UL)?",r:0},f={cN:"number",b:"\\b("+l+"([fF]|L|i|[fF]i|Li)?|"+s+"(i|[fF]i|Li))",r:0},g={cN:"string",b:"'("+u+"|.)",e:"'",i:"."},h={b:u,r:0},p={cN:"string",b:'"',c:[h],e:'"[cwd]?'},w={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5},N={cN:"string",b:"`",e:"`[cwd]?"},A={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10},F={cN:"string",b:'q"\\{',e:'\\}"'},m={cN:"shebang",b:"^#!",e:"$",r:5},y={cN:"preprocessor",b:"#(line)",e:"$",r:5},L={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"},v=e.C("\\/\\+","\\+\\/",{c:["self"],r:10});return{l:e.UIR,k:r,c:[e.CLCM,e.CBCM,v,A,p,w,N,F,f,b,g,m,y,L]}}); \ No newline at end of file +hljs.registerLanguage("d",function(e){var t={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},r="(0|[1-9][\\d_]*)",a="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",i="0[bB][01_]+",n="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",_="0[xX]"+n,c="([eE][+-]?"+a+")",d="("+a+"(\\.\\d*|"+c+")|\\d+\\."+a+a+"|\\."+r+c+"?)",o="(0[xX]("+n+"\\."+n+"|\\.?"+n+")[pP][+-]?"+a+")",s="("+r+"|"+i+"|"+_+")",l="("+o+"|"+d+")",u="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",b={cN:"number",b:"\\b"+s+"(L|u|U|Lu|LU|uL|UL)?",r:0},f={cN:"number",b:"\\b("+l+"([fF]|L|i|[fF]i|Li)?|"+s+"(i|[fF]i|Li))",r:0},g={cN:"string",b:"'("+u+"|.)",e:"'",i:"."},h={b:u,r:0},p={cN:"string",b:'"',c:[h],e:'"[cwd]?'},m={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5},w={cN:"string",b:"`",e:"`[cwd]?"},N={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10},A={cN:"string",b:'q"\\{',e:'\\}"'},F={cN:"meta",b:"^#!",e:"$",r:5},y={cN:"meta",b:"#(line)",e:"$",r:5},L={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"},v=e.C("\\/\\+","\\+\\/",{c:["self"],r:10});return{l:e.UIR,k:t,c:[e.CLCM,e.CBCM,v,N,p,m,w,A,f,b,g,F,y,L]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/dart.js b/lib/highlight_js/assets/lang/dart.js index 5e6d1472b66..8b70ab96a83 100644 --- a/lib/highlight_js/assets/lang/dart.js +++ b/lib/highlight_js/assets/lang/dart.js @@ -1 +1 @@ -hljs.registerLanguage("dart",function(e){var t={cN:"subst",b:"\\$\\{",e:"}",k:"true false null this is new super"},r={cN:"string",v:[{b:"r'''",e:"'''"},{b:'r"""',e:'"""'},{b:"r'",e:"'",i:"\\n"},{b:'r"',e:'"',i:"\\n"},{b:"'''",e:"'''",c:[e.BE,t]},{b:'"""',e:'"""',c:[e.BE,t]},{b:"'",e:"'",i:"\\n",c:[e.BE,t]},{b:'"',e:'"',i:"\\n",c:[e.BE,t]}]};t.c=[e.CNM,r];var n={keyword:"assert break case catch class const continue default do else enum extends false final finally for if in is new null rethrow return super switch this throw true try var void while with",literal:"abstract as dynamic export external factory get implements import library operator part set static typedef",built_in:"print Comparable DateTime Duration Function Iterable Iterator List Map Match Null Object Pattern RegExp Set Stopwatch String StringBuffer StringSink Symbol Type Uri bool double int num document window querySelector querySelectorAll Element ElementList"};return{k:n,c:[r,{cN:"dartdoc",b:"/\\*\\*",e:"\\*/",sL:"markdown",subLanguageMode:"continuous"},{cN:"dartdoc",b:"///",e:"$",sL:"markdown",subLanguageMode:"continuous"},e.CLCM,e.CBCM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.UTM]},e.CNM,{cN:"annotation",b:"@[A-Za-z]+"},{b:"=>"}]}}); \ No newline at end of file +hljs.registerLanguage("dart",function(e){var t={cN:"subst",b:"\\$\\{",e:"}",k:"true false null this is new super"},r={cN:"string",v:[{b:"r'''",e:"'''"},{b:'r"""',e:'"""'},{b:"r'",e:"'",i:"\\n"},{b:'r"',e:'"',i:"\\n"},{b:"'''",e:"'''",c:[e.BE,t]},{b:'"""',e:'"""',c:[e.BE,t]},{b:"'",e:"'",i:"\\n",c:[e.BE,t]},{b:'"',e:'"',i:"\\n",c:[e.BE,t]}]};t.c=[e.CNM,r];var n={keyword:"assert async await break case catch class const continue default do else enum extends false final finally for if in is new null rethrow return super switch sync this throw true try var void while with yield abstract as dynamic export external factory get implements import library operator part set static typedef",built_in:"print Comparable DateTime Duration Function Iterable Iterator List Map Match Null Object Pattern RegExp Set Stopwatch String StringBuffer StringSink Symbol Type Uri bool double int num document window querySelector querySelectorAll Element ElementList"};return{k:n,c:[r,e.C("/\\*\\*","\\*/",{sL:"markdown"}),e.C("///","$",{sL:"markdown"}),e.CLCM,e.CBCM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.UTM]},e.CNM,{cN:"meta",b:"@[A-Za-z]+"},{b:"=>"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/delphi.js b/lib/highlight_js/assets/lang/delphi.js index 709910af615..92cc8622ecc 100644 --- a/lib/highlight_js/assets/lang/delphi.js +++ b/lib/highlight_js/assets/lang/delphi.js @@ -1 +1 @@ -hljs.registerLanguage("delphi",function(e){var r="exports register file shl array record property for mod while set ally label uses raise not stored class safecall var interface or private static exit index inherited to else stdcall override shr asm far resourcestring finalization packed virtual out and protected library do xorwrite goto near function end div overload object unit begin string on inline repeat until destructor write message program with read initialization except default nil if case cdecl in downto threadvar of try pascal const external constructor type public then implementation finally published procedure",t=[e.CLCM,e.C(/\{/,/\}/,{r:0}),e.C(/\(\*/,/\*\)/,{r:10})],i={cN:"string",b:/'/,e:/'/,c:[{b:/''/}]},c={cN:"string",b:/(#\d+)+/},o={b:e.IR+"\\s*=\\s*class\\s*\\(",rB:!0,c:[e.TM]},n={cN:"function",bK:"function constructor destructor procedure",e:/[:;]/,k:"function constructor|10 destructor|10 procedure|10",c:[e.TM,{cN:"params",b:/\(/,e:/\)/,k:r,c:[i,c]}].concat(t)};return{cI:!0,k:r,i:/"|\$[G-Zg-z]|\/\*|<\/|\|/,c:[i,c,e.NM,o,n].concat(t)}}); \ No newline at end of file +hljs.registerLanguage("delphi",function(e){var r="exports register file shl array record property for mod while set ally label uses raise not stored class safecall var interface or private static exit index inherited to else stdcall override shr asm far resourcestring finalization packed virtual out and protected library do xorwrite goto near function end div overload object unit begin string on inline repeat until destructor write message program with read initialization except default nil if case cdecl in downto threadvar of try pascal const external constructor type public then implementation finally published procedure",t=[e.CLCM,e.C(/\{/,/\}/,{r:0}),e.C(/\(\*/,/\*\)/,{r:10})],a={cN:"string",b:/'/,e:/'/,c:[{b:/''/}]},i={cN:"string",b:/(#\d+)+/},c={b:e.IR+"\\s*=\\s*class\\s*\\(",rB:!0,c:[e.TM]},o={cN:"function",bK:"function constructor destructor procedure",e:/[:;]/,k:"function constructor|10 destructor|10 procedure|10",c:[e.TM,{cN:"params",b:/\(/,e:/\)/,k:r,c:[a,i]}].concat(t)};return{aliases:["dpr","dfm","pas","pascal","freepascal","lazarus","lpr","lfm"],cI:!0,k:r,i:/"|\$[G-Zg-z]|\/\*|<\/|\|/,c:[a,i,e.NM,c,o].concat(t)}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/diff.js b/lib/highlight_js/assets/lang/diff.js index bbc14301e4e..96890439f5d 100644 --- a/lib/highlight_js/assets/lang/diff.js +++ b/lib/highlight_js/assets/lang/diff.js @@ -1 +1 @@ -hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"chunk",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}}); \ No newline at end of file +hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/django.js b/lib/highlight_js/assets/lang/django.js index 86f738f16ed..b41e5b93f1b 100644 --- a/lib/highlight_js/assets/lang/django.js +++ b/lib/highlight_js/assets/lang/django.js @@ -1 +1 @@ -hljs.registerLanguage("django",function(e){var t={cN:"filter",b:/\|[A-Za-z]+:?/,k:"truncatewords removetags linebreaksbr yesno get_digit timesince random striptags filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort dictsortreversed default_if_none pluralize lower join center default truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize localtime utc timezone",c:[{cN:"argument",b:/"/,e:/"/},{cN:"argument",b:/'/,e:/'/}]};return{aliases:["jinja"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[e.C(/\{%\s*comment\s*%}/,/\{%\s*endcomment\s*%}/),e.C(/\{#/,/#}/),{cN:"template_tag",b:/\{%/,e:/%}/,k:"comment endcomment load templatetag ifchanged endifchanged if endif firstof for endfor in ifnotequal endifnotequal widthratio extends include spaceless endspaceless regroup by as ifequal endifequal ssi now with cycle url filter endfilter debug block endblock else autoescape endautoescape csrf_token empty elif endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix plural get_current_language language get_available_languages get_current_language_bidi get_language_info get_language_info_list localize endlocalize localtime endlocaltime timezone endtimezone get_current_timezone verbatim",c:[t]},{cN:"variable",b:/\{\{/,e:/}}/,c:[t]}]}}); \ No newline at end of file +hljs.registerLanguage("django",function(e){var t={b:/\|[A-Za-z]+:?/,k:{name:"truncatewords removetags linebreaksbr yesno get_digit timesince random striptags filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort dictsortreversed default_if_none pluralize lower join center default truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize localtime utc timezone"},c:[e.QSM,e.ASM]};return{aliases:["jinja"],cI:!0,sL:"xml",c:[e.C(/\{%\s*comment\s*%}/,/\{%\s*endcomment\s*%}/),e.C(/\{#/,/#}/),{cN:"template-tag",b:/\{%/,e:/%}/,c:[{cN:"name",b:/\w+/,k:{name:"comment endcomment load templatetag ifchanged endifchanged if endif firstof for endfor ifnotequal endifnotequal widthratio extends include spaceless endspaceless regroup ifequal endifequal ssi now with cycle url filter endfilter debug block endblock else autoescape endautoescape csrf_token empty elif endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix plural get_current_language language get_available_languages get_current_language_bidi get_language_info get_language_info_list localize endlocalize localtime endlocaltime timezone endtimezone get_current_timezone verbatim"},starts:{eW:!0,k:"in by as",c:[t],r:0}}]},{cN:"template-variable",b:/\{\{/,e:/}}/,c:[t]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/dns.js b/lib/highlight_js/assets/lang/dns.js new file mode 100644 index 00000000000..bbc4e72d0d5 --- /dev/null +++ b/lib/highlight_js/assets/lang/dns.js @@ -0,0 +1 @@ +hljs.registerLanguage("dns",function(d){return{aliases:["bind","zone"],k:{keyword:"IN A AAAA AFSDB APL CAA CDNSKEY CDS CERT CNAME DHCID DLV DNAME DNSKEY DS HIP IPSECKEY KEY KX LOC MX NAPTR NS NSEC NSEC3 NSEC3PARAM PTR RRSIG RP SIG SOA SRV SSHFP TA TKEY TLSA TSIG TXT"},c:[d.C(";","$"),{cN:"meta",b:/^\$(TTL|GENERATE|INCLUDE|ORIGIN)\b/},{cN:"number",b:"((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))\\b"},{cN:"number",b:"((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\b"},d.inherit(d.NM,{b:/\b\d+[dhwm]?/})]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/dockerfile.js b/lib/highlight_js/assets/lang/dockerfile.js index e505c660639..692932fda72 100644 --- a/lib/highlight_js/assets/lang/dockerfile.js +++ b/lib/highlight_js/assets/lang/dockerfile.js @@ -1 +1 @@ -hljs.registerLanguage("dockerfile",function(n){return{aliases:["docker"],cI:!0,k:{built_ins:"from maintainer cmd expose add copy entrypoint volume user workdir onbuild run env"},c:[n.HCM,{k:{built_in:"run cmd entrypoint volume add copy workdir onbuild"},b:/^ *(onbuild +)?(run|cmd|entrypoint|volume|add|copy|workdir) +/,starts:{e:/[^\\]\n/,sL:"bash",subLanguageMode:"continuous"}},{k:{built_in:"from maintainer expose env user onbuild"},b:/^ *(onbuild +)?(from|maintainer|expose|env|user|onbuild) +/,e:/[^\\]\n/,c:[n.ASM,n.QSM,n.NM,n.HCM]}]}}); \ No newline at end of file +hljs.registerLanguage("dockerfile",function(e){return{aliases:["docker"],cI:!0,k:"from maintainer cmd expose add copy entrypoint volume user workdir onbuild run env label",c:[e.HCM,{k:"run cmd entrypoint volume add copy workdir onbuild label",b:/^ *(onbuild +)?(run|cmd|entrypoint|volume|add|copy|workdir|label) +/,starts:{e:/[^\\]\n/,sL:"bash"}},{k:"from maintainer expose env user onbuild",b:/^ *(onbuild +)?(from|maintainer|expose|env|user|onbuild) +/,e:/[^\\]\n/,c:[e.ASM,e.QSM,e.NM,e.HCM]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/dos.js b/lib/highlight_js/assets/lang/dos.js index 4002382b7a7..4d71bf5f6ad 100644 --- a/lib/highlight_js/assets/lang/dos.js +++ b/lib/highlight_js/assets/lang/dos.js @@ -1 +1 @@ -hljs.registerLanguage("dos",function(e){var r=e.C(/@?rem\b/,/$/,{r:10}),t={cN:"label",b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",r:0};return{aliases:["bat","cmd"],cI:!0,k:{flow:"if else goto for in do call exit not exist errorlevel defined",operator:"equ neq lss leq gtr geq",keyword:"shift cd dir echo setlocal endlocal set pause copy",stream:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux",winutils:"ping net ipconfig taskkill xcopy ren del",built_in:"append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color comp compact convert date dir diskcomp diskcopy doskey erase fs find findstr format ftype graftabl help keyb label md mkdir mode more move path pause print popd pushd promt rd recover rem rename replace restore rmdir shiftsort start subst time title tree type ver verify vol"},c:[{cN:"envvar",b:/%%[^ ]|%[^ ]+?%|![^ ]+?!/},{cN:"function",b:t.b,e:"goto:eof",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),r]},{cN:"number",b:"\\b\\d+",r:0},r]}}); \ No newline at end of file +hljs.registerLanguage("dos",function(e){var r=e.C(/@?rem\b/,/$/,{r:10}),t={cN:"symbol",b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",r:0};return{aliases:["bat","cmd"],cI:!0,i:/\/\*/,k:{keyword:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",built_in:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux shift cd dir echo setlocal endlocal set pause copy append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color comp compact convert date dir diskcomp diskcopy doskey erase fs find findstr format ftype graftabl help keyb label md mkdir mode more move path pause print popd pushd promt rd recover rem rename replace restore rmdir shiftsort start subst time title tree type ver verify vol ping net ipconfig taskkill xcopy ren del"},c:[{cN:"variable",b:/%%[^ ]|%[^ ]+?%|![^ ]+?!/},{cN:"function",b:t.b,e:"goto:eof",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),r]},{cN:"number",b:"\\b\\d+",r:0},r]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/dts.js b/lib/highlight_js/assets/lang/dts.js new file mode 100644 index 00000000000..1cdb447f03d --- /dev/null +++ b/lib/highlight_js/assets/lang/dts.js @@ -0,0 +1 @@ +hljs.registerLanguage("dts",function(e){var a={cN:"string",v:[e.inherit(e.QSM,{b:'((u8?|U)|L)?"'}),{b:'(u8?|U)?R"',e:'"',c:[e.BE]},{b:"'\\\\?.",e:"'",i:"."}]},c={cN:"number",v:[{b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},{b:e.CNR}],r:0},b={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef ifdef ifndef"},c:[{b:/\\\n/,r:0},{bK:"include",e:"$",k:{"meta-keyword":"include"},c:[e.inherit(a,{cN:"meta-string"}),{cN:"meta-string",b:"<",e:">",i:"\\n"}]},a,e.CLCM,e.CBCM]},i={cN:"variable",b:"\\&[a-z\\d_]*\\b"},r={cN:"meta-keyword",b:"/[a-z][a-z\\d-]*/"},d={cN:"symbol",b:"^\\s*[a-zA-Z_][a-zA-Z\\d_]*:"},n={cN:"params",b:"<",e:">",c:[c,i]},s={cN:"class",b:/[a-zA-Z_][a-zA-Z\d_@]*\s{/,e:/[{;=]/,rB:!0,eE:!0},t={cN:"class",b:"/\\s*{",e:"};",r:10,c:[i,r,d,s,n,e.CLCM,e.CBCM,c,a]};return{k:"",c:[t,i,r,d,s,n,e.CLCM,e.CBCM,c,a,b,{b:e.IR+"::",k:""}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/dust.js b/lib/highlight_js/assets/lang/dust.js index a5503261a73..e7d5b0ca05d 100644 --- a/lib/highlight_js/assets/lang/dust.js +++ b/lib/highlight_js/assets/lang/dust.js @@ -1 +1 @@ -hljs.registerLanguage("dust",function(e){var a="if eq ne lt lte gt gte select default math sep";return{aliases:["dst"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[{cN:"expression",b:"{",e:"}",r:0,c:[{cN:"begin-block",b:"#[a-zA-Z- .]+",k:a},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z- .]+",k:a},{cN:"variable",b:"[a-zA-Z-.]+",k:a,r:0}]}]}}); \ No newline at end of file +hljs.registerLanguage("dust",function(e){var t="if eq ne lt lte gt gte select default math sep";return{aliases:["dst"],cI:!0,sL:"xml",c:[{cN:"template-tag",b:/\{[#\/]/,e:/\}/,i:/;/,c:[{cN:"name",b:/[a-zA-Z\.-]+/,starts:{eW:!0,r:0,c:[e.QSM]}}]},{cN:"template-variable",b:/\{/,e:/\}/,i:/;/,k:t}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/elixir.js b/lib/highlight_js/assets/lang/elixir.js index 4e8f54cab3b..c12c8a41232 100644 --- a/lib/highlight_js/assets/lang/elixir.js +++ b/lib/highlight_js/assets/lang/elixir.js @@ -1 +1 @@ -hljs.registerLanguage("elixir",function(e){var n="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?",r="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",b="and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote",c={cN:"subst",b:"#\\{",e:"}",l:n,k:b},a={cN:"string",c:[e.BE,c],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},i={cN:"function",bK:"def defp defmacro",e:/\B\b/,c:[e.inherit(e.TM,{b:n,endsParent:!0})]},s=e.inherit(i,{cN:"class",bK:"defmodule defrecord",e:/\bdo\b|$|;/}),l=[a,e.HCM,s,i,{cN:"constant",b:"(\\b[A-Z_]\\w*(.)?)+",r:0},{cN:"symbol",b:":",c:[a,{b:r}],r:0},{cN:"symbol",b:n+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"->"},{b:"("+e.RSR+")\\s*",c:[e.HCM,{cN:"regexp",i:"\\n",c:[e.BE,c],v:[{b:"/",e:"/[a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];return c.c=l,{l:n,k:b,c:l}}); \ No newline at end of file +hljs.registerLanguage("elixir",function(e){var r="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?",n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",b="and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote",c={cN:"subst",b:"#\\{",e:"}",l:r,k:b},a={cN:"string",c:[e.BE,c],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},i={cN:"function",bK:"def defp defmacro",e:/\B\b/,c:[e.inherit(e.TM,{b:r,endsParent:!0})]},s=e.inherit(i,{cN:"class",bK:"defmodule defrecord",e:/\bdo\b|$|;/}),l=[a,e.HCM,s,i,{cN:"symbol",b:":",c:[a,{b:n}],r:0},{cN:"symbol",b:r+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"->"},{b:"("+e.RSR+")\\s*",c:[e.HCM,{cN:"regexp",i:"\\n",c:[e.BE,c],v:[{b:"/",e:"/[a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];return c.c=l,{l:r,k:b,c:l}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/elm.js b/lib/highlight_js/assets/lang/elm.js new file mode 100644 index 00000000000..c1b9e208a48 --- /dev/null +++ b/lib/highlight_js/assets/lang/elm.js @@ -0,0 +1 @@ +hljs.registerLanguage("elm",function(e){var i={v:[e.C("--","$"),e.C("{-","-}",{c:["self"]})]},r={cN:"type",b:"\\b[A-Z][\\w']*",r:0},t={b:"\\(",e:"\\)",i:'"',c:[{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},i]},n={b:"{",e:"}",c:t.c};return{k:"let in if then else case of where module import exposing type alias as infix infixl infixr port",c:[{bK:"module",e:"where",k:"module where",c:[t,i],i:"\\W\\.|;"},{b:"import",e:"$",k:"import as exposing",c:[t,i],i:"\\W\\.|;"},{b:"type",e:"$",k:"type alias",c:[r,t,n,i]},{bK:"infix infixl infixr",e:"$",c:[e.CNM,i]},{b:"port",e:"$",k:"port",c:[i]},e.QSM,e.CNM,r,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),i,{b:"->|<-"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/erb.js b/lib/highlight_js/assets/lang/erb.js index 26ff7c3be19..a77c7a27340 100644 --- a/lib/highlight_js/assets/lang/erb.js +++ b/lib/highlight_js/assets/lang/erb.js @@ -1 +1 @@ -hljs.registerLanguage("erb",function(e){return{sL:"xml",subLanguageMode:"continuous",c:[e.C("<%#","%>"),{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0}]}}); \ No newline at end of file +hljs.registerLanguage("erb",function(e){return{sL:"xml",c:[e.C("<%#","%>"),{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/erlang-repl.js b/lib/highlight_js/assets/lang/erlang-repl.js index ca148f619a2..4799733c40e 100644 --- a/lib/highlight_js/assets/lang/erlang-repl.js +++ b/lib/highlight_js/assets/lang/erlang-repl.js @@ -1 +1 @@ -hljs.registerLanguage("erlang-repl",function(r){return{k:{special_functions:"spawn spawn_link self",reserved:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"prompt",b:"^[0-9]+> ",r:10},r.C("%","$"),{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},r.ASM,r.QSM,{cN:"constant",b:"\\?(::)?([A-Z]\\w*(::)?)+"},{cN:"arrow",b:"->"},{cN:"ok",b:"ok"},{cN:"exclamation_mark",b:"!"},{cN:"function_or_atom",b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{cN:"variable",b:"[A-Z][a-zA-Z0-9_']*",r:0}]}}); \ No newline at end of file +hljs.registerLanguage("erlang-repl",function(e){return{k:{built_in:"spawn spawn_link self",keyword:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"meta",b:"^[0-9]+> ",r:10},e.C("%","$"),{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},e.ASM,e.QSM,{b:"\\?(::)?([A-Z]\\w*(::)?)+"},{b:"->"},{b:"ok"},{b:"!"},{b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{b:"[A-Z][a-zA-Z0-9_']*",r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/erlang.js b/lib/highlight_js/assets/lang/erlang.js index 3894bdbd3e2..38ced08c9ac 100644 --- a/lib/highlight_js/assets/lang/erlang.js +++ b/lib/highlight_js/assets/lang/erlang.js @@ -1 +1 @@ -hljs.registerLanguage("erlang",function(e){var r="[a-z'][a-zA-Z0-9_']*",c="("+r+":"+r+"|"+r+")",a={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor",literal:"false true"},n=e.C("%","$"),i={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},b={b:"fun\\s+"+r+"/\\d+"},d={b:c+"\\(",e:"\\)",rB:!0,r:0,c:[{cN:"function_name",b:c,r:0},{b:"\\(",e:"\\)",eW:!0,rE:!0,r:0}]},o={cN:"tuple",b:"{",e:"}",r:0},t={cN:"variable",b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0},l={cN:"variable",b:"[A-Z][a-zA-Z0-9_]*",r:0},f={b:"#"+e.UIR,r:0,rB:!0,c:[{cN:"record_name",b:"#"+e.UIR,r:0},{b:"{",e:"}",r:0}]},s={bK:"fun receive if try case",e:"end",k:a};s.c=[n,b,e.inherit(e.ASM,{cN:""}),s,d,e.QSM,i,o,t,l,f];var u=[n,b,s,d,e.QSM,i,o,t,l,f];d.c[1].c=u,o.c=u,f.c[1].c=u;var v={cN:"params",b:"\\(",e:"\\)",c:u};return{aliases:["erl"],k:a,i:"(",rB:!0,i:"\\(|#|//|/\\*|\\\\|:|;",c:[v,e.inherit(e.TM,{b:r})],starts:{e:";|\\.",k:a,c:u}},n,{cN:"pp",b:"^-",e:"\\.",r:0,eE:!0,rB:!0,l:"-"+e.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec",c:[v]},i,e.QSM,f,t,l,o,{b:/\.$/}]}}); \ No newline at end of file +hljs.registerLanguage("erlang",function(e){var r="[a-z'][a-zA-Z0-9_']*",c="("+r+":"+r+"|"+r+")",b={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor",literal:"false true"},i=e.C("%","$"),n={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},a={b:"fun\\s+"+r+"/\\d+"},d={b:c+"\\(",e:"\\)",rB:!0,r:0,c:[{b:c,r:0},{b:"\\(",e:"\\)",eW:!0,rE:!0,r:0}]},o={b:"{",e:"}",r:0},t={b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0},f={b:"[A-Z][a-zA-Z0-9_]*",r:0},l={b:"#"+e.UIR,r:0,rB:!0,c:[{b:"#"+e.UIR,r:0},{b:"{",e:"}",r:0}]},s={bK:"fun receive if try case",e:"end",k:b};s.c=[i,a,e.inherit(e.ASM,{cN:""}),s,d,e.QSM,n,o,t,f,l];var u=[i,a,s,d,e.QSM,n,o,t,f,l];d.c[1].c=u,o.c=u,l.c[1].c=u;var h={cN:"params",b:"\\(",e:"\\)",c:u};return{aliases:["erl"],k:b,i:"(",rB:!0,i:"\\(|#|//|/\\*|\\\\|:|;",c:[h,e.inherit(e.TM,{b:r})],starts:{e:";|\\.",k:b,c:u}},i,{b:"^-",e:"\\.",r:0,eE:!0,rB:!0,l:"-"+e.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec",c:[h]},n,e.QSM,l,t,f,o,{b:/\.$/}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/fix.js b/lib/highlight_js/assets/lang/fix.js index 042d23b15d1..f07d5bbd78d 100644 --- a/lib/highlight_js/assets/lang/fix.js +++ b/lib/highlight_js/assets/lang/fix.js @@ -1 +1 @@ -hljs.registerLanguage("fix",function(u){return{c:[{b:/[^\u2401\u0001]+/,e:/[\u2401\u0001]/,eE:!0,rB:!0,rE:!1,c:[{b:/([^\u2401\u0001=]+)/,e:/=([^\u2401\u0001=]+)/,rE:!0,rB:!1,cN:"attribute"},{b:/=/,e:/([\u2401\u0001])/,eE:!0,eB:!0,cN:"string"}]}],cI:!0}}); \ No newline at end of file +hljs.registerLanguage("fix",function(u){return{c:[{b:/[^\u2401\u0001]+/,e:/[\u2401\u0001]/,eE:!0,rB:!0,rE:!1,c:[{b:/([^\u2401\u0001=]+)/,e:/=([^\u2401\u0001=]+)/,rE:!0,rB:!1,cN:"attr"},{b:/=/,e:/([\u2401\u0001])/,eE:!0,eB:!0,cN:"string"}]}],cI:!0}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/fortran.js b/lib/highlight_js/assets/lang/fortran.js index 430f466dc53..1bea831365f 100644 --- a/lib/highlight_js/assets/lang/fortran.js +++ b/lib/highlight_js/assets/lang/fortran.js @@ -1 +1 @@ -hljs.registerLanguage("fortran",function(e){var t={cN:"params",b:"\\(",e:"\\)"},n={constant:".False. .True.",type:"integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data",keyword:"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure",built_in:"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image"};return{cI:!0,aliases:["f90","f95"],k:n,c:[e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{cN:"string",r:0}),{cN:"function",bK:"subroutine function program",i:"[${=\\n]",c:[e.UTM,t]},e.C("!","$",{r:0}),{cN:"number",b:"(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?",r:0}]}}); \ No newline at end of file +hljs.registerLanguage("fortran",function(e){var t={cN:"params",b:"\\(",e:"\\)"},n={literal:".False. .True.",keyword:"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data",built_in:"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image"};return{cI:!0,aliases:["f90","f95"],k:n,i:/\/\*/,c:[e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{cN:"string",r:0}),{cN:"function",bK:"subroutine function program",i:"[${=\\n]",c:[e.UTM,t]},e.C("!","$",{r:0}),{cN:"number",b:"(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?",r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/fsharp.js b/lib/highlight_js/assets/lang/fsharp.js index 43238bce5bc..2cafa53d846 100644 --- a/lib/highlight_js/assets/lang/fsharp.js +++ b/lib/highlight_js/assets/lang/fsharp.js @@ -1 +1 @@ -hljs.registerLanguage("fsharp",function(e){var t={b:"<",e:">",c:[e.inherit(e.TM,{b:/'[a-zA-Z0-9_]+/})]};return{aliases:["fs"],k:"yield! return! let! do!abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield",c:[{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},e.C("\\(\\*","\\*\\)"),{cN:"class",bK:"type",e:"\\(|=|$",eE:!0,c:[e.UTM,t]},{cN:"annotation",b:"\\[<",e:">\\]",r:10},{cN:"attribute",b:"\\B('[A-Za-z])\\b",c:[e.BE]},e.CLCM,e.inherit(e.QSM,{i:null}),e.CNM]}}); \ No newline at end of file +hljs.registerLanguage("fsharp",function(e){var t={b:"<",e:">",c:[e.inherit(e.TM,{b:/'[a-zA-Z0-9_]+/})]};return{aliases:["fs"],k:"abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield",i:/\/\*/,c:[{cN:"keyword",b:/\b(yield|return|let|do)!/},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},e.C("\\(\\*","\\*\\)"),{cN:"class",bK:"type",e:"\\(|=|$",eE:!0,c:[e.UTM,t]},{cN:"meta",b:"\\[<",e:">\\]",r:10},{cN:"symbol",b:"\\B('[A-Za-z])\\b",c:[e.BE]},e.CLCM,e.inherit(e.QSM,{i:null}),e.CNM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/gams.js b/lib/highlight_js/assets/lang/gams.js new file mode 100644 index 00000000000..65638faaf29 --- /dev/null +++ b/lib/highlight_js/assets/lang/gams.js @@ -0,0 +1 @@ +hljs.registerLanguage("gams",function(e){var s="abort acronym acronyms alias all and assign binary card diag display else1 eps eq equation equations file files for1 free ge gt if inf integer le loop lt maximizing minimizing model models na ne negative no not option options or ord parameter parameters positive prod putpage puttl repeat sameas scalar scalars semicont semiint set1 sets smax smin solve sos1 sos2 sum system table then until using variable variables while1 xor yes";return{aliases:["gms"],cI:!0,k:s,c:[{bK:"sets parameters variables equations",e:";",c:[{b:"/",e:"/",c:[e.NM]}]},{cN:"string",b:"\\*{3}",e:"\\*{3}"},e.NM,{cN:"number",b:"\\$[a-zA-Z0-9]+"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/gauss.js b/lib/highlight_js/assets/lang/gauss.js new file mode 100644 index 00000000000..3a46d0d0993 --- /dev/null +++ b/lib/highlight_js/assets/lang/gauss.js @@ -0,0 +1 @@ +hljs.registerLanguage("gauss",function(e){var t={keyword:"and bool break|0 call callexe checkinterrupt clear clearg closeall cls comlog compile continue create debug declare delete disable dlibrary|10 dllcall do|0 dos ed edit else|0 elseif enable end endfor|10 endif|10 endp|10 endo|10 errorlog|10 errorlogat expr external fn for|0 format goto gosub|0 graph if|0 keyword let lib library line load loadarray loadexe loadf|10 loadk|10 loadm|10 loadp loads loadx local locate loopnextindex lprint lpwidth lshow matrix msym ndpclex new not open or output outwidth plot plotsym pop prcsn print printdos proc|10 push retp|10 return|0 rndcon rndmod rndmult rndseed run save saveall screen scroll setarray show sparse stop string struct system trace trap|10 threadfor|10 threadendfor|10 threadbegin|10 threadjoin|10 threadstat|10 threadend|10 until use while winprint",built_in:"abs acf aconcat aeye amax amean AmericanBinomCall AmericanBinomCall_Greeks AmericanBinomCall_ImpVol AmericanBinomPut AmericanBinomPut_Greeks AmericanBinomPut_ImpVol AmericanBSCall AmericanBSCall_Greeks AmericanBSCall_ImpVol AmericanBSPut AmericanBSPut_Greeks AmericanBSPut_ImpVol amin amult annotationGetDefaults annotationSetBkd annotationSetFont annotationSetLineColor annotationSetLineStyle annotationSetLineThickness annualTradingDays arccos arcsin areshape arrayalloc arrayindex arrayinit arraytomat asciiload asclabel astd astds asum atan atan2 atranspose axmargin balance band bandchol bandcholsol bandltsol bandrv bandsolpd bar base10 begwind besselj bessely beta box boxcox cdfBeta cdfBetaInv cdfBinomial cdfBinomialInv cdfBvn cdfBvn2 cdfBvn2e cdfCauchy cdfCauchyInv cdfChic cdfChii cdfChinc cdfChincInv cdfExp cdfExpInv cdfFc cdfFnc cdfFncInv cdfGam cdfGenPareto cdfHyperGeo cdfLaplace cdfLaplaceInv cdfLogistic cdfLogisticInv cdfmControlCreate cdfMvn cdfMvn2e cdfMvnce cdfMvne cdfMvt2e cdfMvtce cdfMvte cdfN cdfN2 cdfNc cdfNegBinomial cdfNegBinomialInv cdfNi cdfPoisson cdfPoissonInv cdfRayleigh cdfRayleighInv cdfTc cdfTci cdfTnc cdfTvn cdfWeibull cdfWeibullInv cdir ceil ChangeDir chdir chiBarSquare chol choldn cholsol cholup chrs close code cols colsf combinate combinated complex con cond conj cons ConScore contour conv convertsatostr convertstrtosa corrm corrms corrvc corrx corrxs cos cosh counts countwts crossprd crout croutp csrcol csrlin csvReadM csvReadSA cumprodc cumsumc curve cvtos datacreate datacreatecomplex datalist dataload dataloop dataopen datasave date datestr datestring datestrymd dayinyr dayofweek dbAddDatabase|10 dbClose|10 dbCommit|10 dbCreateQuery|10 dbExecQuery|10 dbGetConnectOptions|10 dbGetDatabaseName|10 dbGetDriverName|10 dbGetDrivers|10 dbGetHostName|10 dbGetLastErrorNum|10 dbGetLastErrorText|10 dbGetNumericalPrecPolicy|10 dbGetPassword|10 dbGetPort|10 dbGetTableHeaders|10 dbGetTables|10 dbGetUserName|10 dbHasFeature|10 dbIsDriverAvailable|10 dbIsOpen|10 dbIsOpenError|10 dbOpen|10 dbQueryBindValue|10 dbQueryClear|10 dbQueryCols|10 dbQueryExecPrepared|10 dbQueryFetchAllM|10 dbQueryFetchAllSA|10 dbQueryFetchOneM|10 dbQueryFetchOneSA|10 dbQueryFinish|10 dbQueryGetBoundValue|10 dbQueryGetBoundValues|10 dbQueryGetField|10 dbQueryGetLastErrorNum|10 dbQueryGetLastErrorText|10 dbQueryGetLastInsertID|10 dbQueryGetLastQuery|10 dbQueryGetPosition|10 dbQueryIsActive|10 dbQueryIsForwardOnly|10 dbQueryIsNull|10 dbQueryIsSelect|10 dbQueryIsValid|10 dbQueryPrepare|10 dbQueryRows|10 dbQuerySeek|10 dbQuerySeekFirst|10 dbQuerySeekLast|10 dbQuerySeekNext|10 dbQuerySeekPrevious|10 dbQuerySetForwardOnly|10 dbRemoveDatabase|10 dbRollback|10 dbSetConnectOptions|10 dbSetDatabaseName|10 dbSetHostName|10 dbSetNumericalPrecPolicy|10 dbSetPort|10 dbSetUserName|10 dbTransaction|10 DeleteFile delif delrows denseToSp denseToSpRE denToZero design det detl dfft dffti diag diagrv digamma doswin DOSWinCloseall DOSWinOpen dotfeq dotfeqmt dotfge dotfgemt dotfgt dotfgtmt dotfle dotflemt dotflt dotfltmt dotfne dotfnemt draw drop dsCreate dstat dstatmt dstatmtControlCreate dtdate dtday dttime dttodtv dttostr dttoutc dtvnormal dtvtodt dtvtoutc dummy dummybr dummydn eig eigh eighv eigv elapsedTradingDays endwind envget eof eqSolve eqSolvemt eqSolvemtControlCreate eqSolvemtOutCreate eqSolveset erf erfc erfccplx erfcplx error etdays ethsec etstr EuropeanBinomCall EuropeanBinomCall_Greeks EuropeanBinomCall_ImpVol EuropeanBinomPut EuropeanBinomPut_Greeks EuropeanBinomPut_ImpVol EuropeanBSCall EuropeanBSCall_Greeks EuropeanBSCall_ImpVol EuropeanBSPut EuropeanBSPut_Greeks EuropeanBSPut_ImpVol exctsmpl exec execbg exp extern eye fcheckerr fclearerr feq feqmt fflush fft ffti fftm fftmi fftn fge fgemt fgets fgetsa fgetsat fgetst fgt fgtmt fileinfo filesa fle flemt floor flt fltmt fmod fne fnemt fonts fopen formatcv formatnv fputs fputst fseek fstrerror ftell ftocv ftos ftostrC gamma gammacplx gammaii gausset gdaAppend gdaCreate gdaDStat gdaDStatMat gdaGetIndex gdaGetName gdaGetNames gdaGetOrders gdaGetType gdaGetTypes gdaGetVarInfo gdaIsCplx gdaLoad gdaPack gdaRead gdaReadByIndex gdaReadSome gdaReadSparse gdaReadStruct gdaReportVarInfo gdaSave gdaUpdate gdaUpdateAndPack gdaVars gdaWrite gdaWrite32 gdaWriteSome getarray getdims getf getGAUSShome getmatrix getmatrix4D getname getnamef getNextTradingDay getNextWeekDay getnr getorders getpath getPreviousTradingDay getPreviousWeekDay getRow getscalar3D getscalar4D getTrRow getwind glm gradcplx gradMT gradMTm gradMTT gradMTTm gradp graphprt graphset hasimag header headermt hess hessMT hessMTg hessMTgw hessMTm hessMTmw hessMTT hessMTTg hessMTTgw hessMTTm hessMTw hessp hist histf histp hsec imag indcv indexcat indices indices2 indicesf indicesfn indnv indsav indx integrate1d integrateControlCreate intgrat2 intgrat3 inthp1 inthp2 inthp3 inthp4 inthpControlCreate intquad1 intquad2 intquad3 intrleav intrleavsa intrsect intsimp inv invpd invswp iscplx iscplxf isden isinfnanmiss ismiss key keyav keyw lag lag1 lagn lapEighb lapEighi lapEighvb lapEighvi lapgEig lapgEigh lapgEighv lapgEigv lapgSchur lapgSvdcst lapgSvds lapgSvdst lapSvdcusv lapSvds lapSvdusv ldlp ldlsol linSolve listwise ln lncdfbvn lncdfbvn2 lncdfmvn lncdfn lncdfn2 lncdfnc lnfact lngammacplx lnpdfmvn lnpdfmvt lnpdfn lnpdft loadd loadstruct loadwind loess loessmt loessmtControlCreate log loglog logx logy lower lowmat lowmat1 ltrisol lu lusol machEpsilon make makevars makewind margin matalloc matinit mattoarray maxbytes maxc maxindc maxv maxvec mbesselei mbesselei0 mbesselei1 mbesseli mbesseli0 mbesseli1 meanc median mergeby mergevar minc minindc minv miss missex missrv moment momentd movingave movingaveExpwgt movingaveWgt nextindex nextn nextnevn nextwind ntos null null1 numCombinations ols olsmt olsmtControlCreate olsqr olsqr2 olsqrmt ones optn optnevn orth outtyp pacf packedToSp packr parse pause pdfCauchy pdfChi pdfExp pdfGenPareto pdfHyperGeo pdfLaplace pdfLogistic pdfn pdfPoisson pdfRayleigh pdfWeibull pi pinv pinvmt plotAddArrow plotAddBar plotAddBox plotAddHist plotAddHistF plotAddHistP plotAddPolar plotAddScatter plotAddShape plotAddTextbox plotAddTS plotAddXY plotArea plotBar plotBox plotClearLayout plotContour plotCustomLayout plotGetDefaults plotHist plotHistF plotHistP plotLayout plotLogLog plotLogX plotLogY plotOpenWindow plotPolar plotSave plotScatter plotSetAxesPen plotSetBar plotSetBarFill plotSetBarStacked plotSetBkdColor plotSetFill plotSetGrid plotSetLegend plotSetLineColor plotSetLineStyle plotSetLineSymbol plotSetLineThickness plotSetNewWindow plotSetTitle plotSetWhichYAxis plotSetXAxisShow plotSetXLabel plotSetXRange plotSetXTicInterval plotSetXTicLabel plotSetYAxisShow plotSetYLabel plotSetYRange plotSetZAxisShow plotSetZLabel plotSurface plotTS plotXY polar polychar polyeval polygamma polyint polymake polymat polymroot polymult polyroot pqgwin previousindex princomp printfm printfmt prodc psi putarray putf putvals pvCreate pvGetIndex pvGetParNames pvGetParVector pvLength pvList pvPack pvPacki pvPackm pvPackmi pvPacks pvPacksi pvPacksm pvPacksmi pvPutParVector pvTest pvUnpack QNewton QNewtonmt QNewtonmtControlCreate QNewtonmtOutCreate QNewtonSet QProg QProgmt QProgmtInCreate qqr qqre qqrep qr qre qrep qrsol qrtsol qtyr qtyre qtyrep quantile quantiled qyr qyre qyrep qz rank rankindx readr real reclassify reclassifyCuts recode recserar recsercp recserrc rerun rescale reshape rets rev rfft rffti rfftip rfftn rfftnp rfftp rndBernoulli rndBeta rndBinomial rndCauchy rndChiSquare rndCon rndCreateState rndExp rndGamma rndGeo rndGumbel rndHyperGeo rndi rndKMbeta rndKMgam rndKMi rndKMn rndKMnb rndKMp rndKMu rndKMvm rndLaplace rndLCbeta rndLCgam rndLCi rndLCn rndLCnb rndLCp rndLCu rndLCvm rndLogNorm rndMTu rndMVn rndMVt rndn rndnb rndNegBinomial rndp rndPoisson rndRayleigh rndStateSkip rndu rndvm rndWeibull rndWishart rotater round rows rowsf rref sampleData satostrC saved saveStruct savewind scale scale3d scalerr scalinfnanmiss scalmiss schtoc schur searchsourcepath seekr select selif seqa seqm setdif setdifsa setvars setvwrmode setwind shell shiftr sin singleindex sinh sleep solpd sortc sortcc sortd sorthc sorthcc sortind sortindc sortmc sortr sortrc spBiconjGradSol spChol spConjGradSol spCreate spDenseSubmat spDiagRvMat spEigv spEye spLDL spline spLU spNumNZE spOnes spreadSheetReadM spreadSheetReadSA spreadSheetWrite spScale spSubmat spToDense spTrTDense spTScalar spZeros sqpSolve sqpSolveMT sqpSolveMTControlCreate sqpSolveMTlagrangeCreate sqpSolveMToutCreate sqpSolveSet sqrt statements stdc stdsc stocv stof strcombine strindx strlen strput strrindx strsect strsplit strsplitPad strtodt strtof strtofcplx strtriml strtrimr strtrunc strtruncl strtruncpad strtruncr submat subscat substute subvec sumc sumr surface svd svd1 svd2 svdcusv svds svdusv sysstate tab tan tanh tempname threadBegin threadEnd threadEndFor threadFor threadJoin threadStat time timedt timestr timeutc title tkf2eps tkf2ps tocart todaydt toeplitz token topolar trapchk trigamma trimr trunc type typecv typef union unionsa uniqindx uniqindxsa unique uniquesa upmat upmat1 upper utctodt utctodtv utrisol vals varCovMS varCovXS varget vargetl varmall varmares varput varputl vartypef vcm vcms vcx vcxs vec vech vecr vector vget view viewxyz vlist vnamecv volume vput vread vtypecv wait waitc walkindex where window writer xlabel xlsGetSheetCount xlsGetSheetSize xlsGetSheetTypes xlsMakeRange xlsReadM xlsReadSA xlsWrite xlsWriteM xlsWriteSA xpnd xtics xy xyz ylabel ytics zeros zeta zlabel ztics",literal:"DB_AFTER_LAST_ROW DB_ALL_TABLES DB_BATCH_OPERATIONS DB_BEFORE_FIRST_ROW DB_BLOB DB_EVENT_NOTIFICATIONS DB_FINISH_QUERY DB_HIGH_PRECISION DB_LAST_INSERT_ID DB_LOW_PRECISION_DOUBLE DB_LOW_PRECISION_INT32 DB_LOW_PRECISION_INT64 DB_LOW_PRECISION_NUMBERS DB_MULTIPLE_RESULT_SETS DB_NAMED_PLACEHOLDERS DB_POSITIONAL_PLACEHOLDERS DB_PREPARED_QUERIES DB_QUERY_SIZE DB_SIMPLE_LOCKING DB_SYSTEM_TABLES DB_TABLES DB_TRANSACTIONS DB_UNICODE DB_VIEWS"},a={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"define definecs|10 undef ifdef ifndef iflight ifdllcall ifmac ifos2win ifunix else endif lineson linesoff srcfile srcline"},c:[{b:/\\\n/,r:0},{bK:"include",e:"$",k:{"meta-keyword":"include"},c:[{cN:"meta-string",b:'"',e:'"',i:"\\n"}]},e.CLCM,e.CBCM]},r=e.UIR+"\\s*\\(?",o=[{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.CNM,e.CLCM,e.CBCM]}];return{aliases:["gss"],cI:!0,k:t,i:"(\\{[%#]|[%#]\\})",c:[e.CNM,e.CLCM,e.CBCM,e.C("@","@"),a,{cN:"string",b:'"',e:'"',c:[e.BE]},{cN:"function",bK:"proc keyword",e:";",eE:!0,k:t,c:[{b:r,rB:!0,c:[e.UTM],r:0},e.CNM,e.CLCM,e.CBCM,a].concat(o)},{cN:"function",bK:"fn",e:";",eE:!0,k:t,c:[{b:r+e.IR+"\\)?\\s*\\=\\s*",rB:!0,c:[e.UTM],r:0},e.CNM,e.CLCM,e.CBCM].concat(o)},{cN:"function",b:"\\bexternal (proc|keyword|fn)\\s+",e:";",eE:!0,k:t,c:[{b:r,rB:!0,c:[e.UTM],r:0},e.CLCM,e.CBCM]},{cN:"function",b:"\\bexternal (matrix|string|array|sparse matrix|struct "+e.IR+")\\s+",e:";",eE:!0,k:t,c:[e.CLCM,e.CBCM]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/gcode.js b/lib/highlight_js/assets/lang/gcode.js index 00607061b65..898c3832ecc 100644 --- a/lib/highlight_js/assets/lang/gcode.js +++ b/lib/highlight_js/assets/lang/gcode.js @@ -1 +1 @@ -hljs.registerLanguage("gcode",function(e){var N="[A-Z_][A-Z0-9_.]*",i="\\%",c={literal:"",built_in:"",keyword:"IF DO WHILE ENDWHILE CALL ENDIF SUB ENDSUB GOTO REPEAT ENDREPEAT EQ LT GT NE GE LE OR XOR"},r={cN:"preprocessor",b:"([O])([0-9]+)"},l=[e.CLCM,e.CBCM,e.C(/\(/,/\)/),e.inherit(e.CNM,{b:"([-+]?([0-9]*\\.?[0-9]+\\.?))|"+e.CNR}),e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"keyword",b:"([G])([0-9]+\\.?[0-9]?)"},{cN:"title",b:"([M])([0-9]+\\.?[0-9]?)"},{cN:"title",b:"(VC|VS|#)",e:"(\\d+)"},{cN:"title",b:"(VZOFX|VZOFY|VZOFZ)"},{cN:"built_in",b:"(ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN)(\\[)",e:"([-+]?([0-9]*\\.?[0-9]+\\.?))(\\])"},{cN:"label",v:[{b:"N",e:"\\d+",i:"\\W"}]}];return{aliases:["nc"],cI:!0,l:N,k:c,c:[{cN:"preprocessor",b:i},r].concat(l)}}); \ No newline at end of file +hljs.registerLanguage("gcode",function(N){var e="[A-Z_][A-Z0-9_.]*",c="\\%",E="IF DO WHILE ENDWHILE CALL ENDIF SUB ENDSUB GOTO REPEAT ENDREPEAT EQ LT GT NE GE LE OR XOR",i={cN:"meta",b:"([O])([0-9]+)"},n=[N.CLCM,N.CBCM,N.C(/\(/,/\)/),N.inherit(N.CNM,{b:"([-+]?([0-9]*\\.?[0-9]+\\.?))|"+N.CNR}),N.inherit(N.ASM,{i:null}),N.inherit(N.QSM,{i:null}),{cN:"name",b:"([G])([0-9]+\\.?[0-9]?)"},{cN:"name",b:"([M])([0-9]+\\.?[0-9]?)"},{cN:"attr",b:"(VC|VS|#)",e:"(\\d+)"},{cN:"attr",b:"(VZOFX|VZOFY|VZOFZ)"},{cN:"built_in",b:"(ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN)(\\[)",e:"([-+]?([0-9]*\\.?[0-9]+\\.?))(\\])"},{cN:"symbol",v:[{b:"N",e:"\\d+",i:"\\W"}]}];return{aliases:["nc"],cI:!0,l:e,k:E,c:[{cN:"meta",b:c},i].concat(n)}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/gherkin.js b/lib/highlight_js/assets/lang/gherkin.js index 2df5db806ae..10cc38b26d4 100644 --- a/lib/highlight_js/assets/lang/gherkin.js +++ b/lib/highlight_js/assets/lang/gherkin.js @@ -1 +1 @@ -hljs.registerLanguage("gherkin",function(e){return{aliases:["feature"],k:"Feature Background Ability Business Need Scenario Scenarios Scenario Outline Scenario Template Examples Given And Then But When",c:[{cN:"keyword",b:"\\*"},e.C("@[^@\r\n ]+","$"),{cN:"string",b:"\\|",e:"\\$"},{cN:"variable",b:"<",e:">"},e.HCM,{cN:"string",b:'"""',e:'"""'},e.QSM]}}); \ No newline at end of file +hljs.registerLanguage("gherkin",function(e){return{aliases:["feature"],k:"Feature Background Ability Business Need Scenario Scenarios Scenario Outline Scenario Template Examples Given And Then But When",c:[{cN:"symbol",b:"\\*",r:0},{cN:"meta",b:"@[^@\\s]+"},{b:"\\|",e:"\\|\\w*$",c:[{cN:"string",b:"[^|]+"}]},{cN:"variable",b:"<",e:">"},e.HCM,{cN:"string",b:'"""',e:'"""'},e.QSM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/glsl.js b/lib/highlight_js/assets/lang/glsl.js index b7c40588927..7095358259b 100644 --- a/lib/highlight_js/assets/lang/glsl.js +++ b/lib/highlight_js/assets/lang/glsl.js @@ -1 +1 @@ -hljs.registerLanguage("glsl",function(e){return{k:{keyword:"atomic_uint attribute bool break bvec2 bvec3 bvec4 case centroid coherent const continue default discard dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 do double dvec2 dvec3 dvec4 else flat float for highp if iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBuffer iimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray in inout int invariant isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 layout lowp mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 mediump noperspective out patch precision readonly restrict return sample sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow smooth struct subroutine switch uimage1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint uniform usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D usamplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 varying vec2 vec3 vec4 void volatile while writeonly",built_in:"gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffsetgl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_PerVertex gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicCounter atomicCounterDecrement atomicCounterIncrement barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow gl_TextureMatrix gl_TextureMatrixInverse",literal:"true false"},i:'"',c:[e.CLCM,e.CBCM,e.CNM,{cN:"preprocessor",b:"#",e:"$"}]}}); \ No newline at end of file +hljs.registerLanguage("glsl",function(e){return{k:{keyword:"break continue discard do else for if return whileattribute binding buffer ccw centroid centroid varying coherent column_major const cw depth_any depth_greater depth_less depth_unchanged early_fragment_tests equal_spacing flat fractional_even_spacing fractional_odd_spacing highp in index inout invariant invocations isolines layout line_strip lines lines_adjacency local_size_x local_size_y local_size_z location lowp max_vertices mediump noperspective offset origin_upper_left out packed patch pixel_center_integer point_mode points precise precision quads r11f_g11f_b10f r16 r16_snorm r16f r16i r16ui r32f r32i r32ui r8 r8_snorm r8i r8ui readonly restrict rg16 rg16_snorm rg16f rg16i rg16ui rg32f rg32i rg32ui rg8 rg8_snorm rg8i rg8ui rgb10_a2 rgb10_a2ui rgba16 rgba16_snorm rgba16f rgba16i rgba16ui rgba32f rgba32i rgba32ui rgba8 rgba8_snorm rgba8i rgba8ui row_major sample shared smooth std140 std430 stream triangle_strip triangles triangles_adjacency uniform varying vertices volatile writeonly",type:"atomic_uint bool bvec2 bvec3 bvec4 dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 double dvec2 dvec3 dvec4 float iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBufferiimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray int isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow image1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D samplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 vec2 vec3 vec4 void",built_in:"gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxComputeAtomicCounterBuffers gl_MaxComputeAtomicCounters gl_MaxComputeImageUniforms gl_MaxComputeTextureImageUnits gl_MaxComputeUniformComponents gl_MaxComputeWorkGroupCount gl_MaxComputeWorkGroupSize gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentInputVectors gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexOutputVectors gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffset gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_GlobalInvocationID gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_LocalInvocationID gl_LocalInvocationIndex gl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_NumSamples gl_NumWorkGroups gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrix gl_TextureMatrixInverse gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_WorkGroupID gl_WorkGroupSize gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicAdd atomicAnd atomicCompSwap atomicCounter atomicCounterDecrement atomicCounterIncrement atomicExchange atomicMax atomicMin atomicOr atomicXor barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual groupMemoryBarrier imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageSize imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier memoryBarrierAtomicCounter memoryBarrierBuffer memoryBarrierImage memoryBarrierShared min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLevels textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow",literal:"true false"},i:'"',c:[e.CLCM,e.CBCM,e.CNM,{cN:"meta",b:"#",e:"$"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/go.js b/lib/highlight_js/assets/lang/go.js index 96c94475399..269feec6687 100644 --- a/lib/highlight_js/assets/lang/go.js +++ b/lib/highlight_js/assets/lang/go.js @@ -1 +1 @@ -hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer",constant:"true false iota nil",typename:"bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"",e:",\\s+",rB:!0,eW:!0,c:[{cN:"symbol",b:":\\w+"},s.ASM,s.QSM,{b:"\\w+",r:0}]}]},{b:"\\(\\s*",e:"\\s*\\)",eE:!0,c:[{b:"\\w+\\s*=",e:"\\s+",rB:!0,eW:!0,c:[{cN:"attribute",b:"\\w+",r:0},s.ASM,s.QSM,{b:"\\w+",r:0}]}]}]},{cN:"bullet",b:"^\\s*[=~]\\s*",r:0},{b:"#{",starts:{e:"}",sL:"ruby"}}]}}); \ No newline at end of file +hljs.registerLanguage("haml",function(s){return{cI:!0,c:[{cN:"meta",b:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",r:10},s.C("^\\s*(!=#|=#|-#|/).*$",!1,{r:0}),{b:"^\\s*(-|=|!=)(?!#)",starts:{e:"\\n",sL:"ruby"}},{cN:"tag",b:"^\\s*%",c:[{cN:"selector-tag",b:"\\w+"},{cN:"selector-id",b:"#[\\w-]+"},{cN:"selector-class",b:"\\.[\\w-]+"},{b:"{\\s*",e:"\\s*}",c:[{b:":\\w+\\s*=>",e:",\\s+",rB:!0,eW:!0,c:[{cN:"attr",b:":\\w+"},s.ASM,s.QSM,{b:"\\w+",r:0}]}]},{b:"\\(\\s*",e:"\\s*\\)",eE:!0,c:[{b:"\\w+\\s*=",e:"\\s+",rB:!0,eW:!0,c:[{cN:"attr",b:"\\w+",r:0},s.ASM,s.QSM,{b:"\\w+",r:0}]}]}]},{b:"^\\s*[=~]\\s*"},{b:"#{",starts:{e:"}",sL:"ruby"}}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/handlebars.js b/lib/highlight_js/assets/lang/handlebars.js index ca5655c621f..a3c1c859c18 100644 --- a/lib/highlight_js/assets/lang/handlebars.js +++ b/lib/highlight_js/assets/lang/handlebars.js @@ -1 +1 @@ -hljs.registerLanguage("handlebars",function(e){var a="each in with if else unless bindattr action collection debugger log outlet template unbound view yield";return{aliases:["hbs","html.hbs","html.handlebars"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[{cN:"expression",b:"{{",e:"}}",c:[{cN:"begin-block",b:"#[a-zA-Z- .]+",k:a},{cN:"string",b:'"',e:'"'},{cN:"end-block",b:"\\/[a-zA-Z- .]+",k:a},{cN:"variable",b:"[a-zA-Z-.]+",k:a}]}]}}); \ No newline at end of file +hljs.registerLanguage("handlebars",function(e){var a={"builtin-name":"each in with if else unless bindattr action collection debugger log outlet template unbound view yield"};return{aliases:["hbs","html.hbs","html.handlebars"],cI:!0,sL:"xml",c:[e.C("{{!(--)?","(--)?}}"),{cN:"template-tag",b:/\{\{[#\/]/,e:/\}\}/,c:[{cN:"name",b:/[a-zA-Z\.-]+/,k:a,starts:{eW:!0,r:0,c:[e.QSM]}}]},{cN:"template-variable",b:/\{\{/,e:/\}\}/,k:a}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/haskell.js b/lib/highlight_js/assets/lang/haskell.js index 42f0ba1dd03..334d56325df 100644 --- a/lib/highlight_js/assets/lang/haskell.js +++ b/lib/highlight_js/assets/lang/haskell.js @@ -1 +1 @@ -hljs.registerLanguage("haskell",function(e){var c=[e.C("--","$"),e.C("{-","-}",{c:["self"]})],a={cN:"pragma",b:"{-#",e:"#-}"},i={cN:"preprocessor",b:"^#",e:"$"},n={cN:"type",b:"\\b[A-Z][\\w']*",r:0},t={cN:"container",b:"\\(",e:"\\)",i:'"',c:[a,i,{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TM,{b:"[_a-z][\\w']*"})].concat(c)},l={cN:"container",b:"{",e:"}",c:t.c};return{aliases:["hs"],k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",c:[{cN:"module",b:"\\bmodule\\b",e:"where",k:"module where",c:[t].concat(c),i:"\\W\\.|;"},{cN:"import",b:"\\bimport\\b",e:"$",k:"import|0 qualified as hiding",c:[t].concat(c),i:"\\W\\.|;"},{cN:"class",b:"^(\\s*)?(class|instance)\\b",e:"where",k:"class family instance where",c:[n,t].concat(c)},{cN:"typedef",b:"\\b(data|(new)?type)\\b",e:"$",k:"data family type newtype deriving",c:[a,n,t,l].concat(c)},{cN:"default",bK:"default",e:"$",c:[n,t].concat(c)},{cN:"infix",bK:"infix infixl infixr",e:"$",c:[e.CNM].concat(c)},{cN:"foreign",b:"\\bforeign\\b",e:"$",k:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",c:[n,e.QSM].concat(c)},{cN:"shebang",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},a,i,e.QSM,e.CNM,n,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),{b:"->|<-"}].concat(c)}}); \ No newline at end of file +hljs.registerLanguage("haskell",function(e){var i={v:[e.C("--","$"),e.C("{-","-}",{c:["self"]})]},a={cN:"meta",b:"{-#",e:"#-}"},l={cN:"meta",b:"^#",e:"$"},c={cN:"type",b:"\\b[A-Z][\\w']*",r:0},n={b:"\\(",e:"\\)",i:'"',c:[a,l,{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TM,{b:"[_a-z][\\w']*"}),i]},s={b:"{",e:"}",c:n.c};return{aliases:["hs"],k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",c:[{bK:"module",e:"where",k:"module where",c:[n,i],i:"\\W\\.|;"},{b:"\\bimport\\b",e:"$",k:"import qualified as hiding",c:[n,i],i:"\\W\\.|;"},{cN:"class",b:"^(\\s*)?(class|instance)\\b",e:"where",k:"class family instance where",c:[c,n,i]},{cN:"class",b:"\\b(data|(new)?type)\\b",e:"$",k:"data family type newtype deriving",c:[a,c,n,s,i]},{bK:"default",e:"$",c:[c,n,i]},{bK:"infix infixl infixr",e:"$",c:[e.CNM,i]},{b:"\\bforeign\\b",e:"$",k:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",c:[c,e.QSM,i]},{cN:"meta",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},a,l,e.QSM,e.CNM,c,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),i,{b:"->|<-"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/haxe.js b/lib/highlight_js/assets/lang/haxe.js index 4d2a775d108..3408828b72c 100644 --- a/lib/highlight_js/assets/lang/haxe.js +++ b/lib/highlight_js/assets/lang/haxe.js @@ -1 +1 @@ -hljs.registerLanguage("haxe",function(e){var r="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)";return{aliases:["hx"],k:{keyword:"break callback case cast catch class continue default do dynamic else enum extends extern for function here if implements import in inline interface never new override package private public return static super switch this throw trace try typedef untyped using var while",literal:"true false null"},c:[e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.TM]},{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end error"},{cN:"function",bK:"function",e:"[{;]",eE:!0,i:"\\S",c:[e.TM,{cN:"params",b:"\\(",e:"\\)",c:[e.ASM,e.QSM,e.CLCM,e.CBCM]},{cN:"type",b:":",e:r,r:10}]}]}}); \ No newline at end of file +hljs.registerLanguage("haxe",function(e){var a="([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)";return{aliases:["hx"],k:{keyword:"break callback case cast catch class continue default do dynamic else enum extends extern for function here if implements import in inline interface never new override package private public return static super switch this throw trace try typedef untyped using var while",literal:"true false null"},c:[e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.TM]},{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elseif end error"}},{cN:"function",bK:"function",e:"[{;]",eE:!0,i:"\\S",c:[e.TM,{cN:"params",b:"\\(",e:"\\)",c:[e.ASM,e.QSM,e.CLCM,e.CBCM]},{b:":\\s*"+a}]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/hsp.js b/lib/highlight_js/assets/lang/hsp.js new file mode 100644 index 00000000000..8cdbc7ce1d9 --- /dev/null +++ b/lib/highlight_js/assets/lang/hsp.js @@ -0,0 +1 @@ +hljs.registerLanguage("hsp",function(e){return{cI:!0,k:"goto gosub return break repeat loop continue wait await dim sdim foreach dimtype dup dupptr end stop newmod delmod mref run exgoto on mcall assert logmes newlab resume yield onexit onerror onkey onclick oncmd exist delete mkdir chdir dirlist bload bsave bcopy memfile if else poke wpoke lpoke getstr chdpm memexpand memcpy memset notesel noteadd notedel noteload notesave randomize noteunsel noteget split strrep setease button chgdisp exec dialog mmload mmplay mmstop mci pset pget syscolor mes print title pos circle cls font sysfont objsize picload color palcolor palette redraw width gsel gcopy gzoom gmode bmpsave hsvcolor getkey listbox chkbox combox input mesbox buffer screen bgscr mouse objsel groll line clrobj boxf objprm objmode stick grect grotate gsquare gradf objimage objskip objenable celload celdiv celput newcom querycom delcom cnvstow comres axobj winobj sendmsg comevent comevarg sarrayconv callfunc cnvwtos comevdisp libptr system hspstat hspver stat cnt err strsize looplev sublev iparam wparam lparam refstr refdval int rnd strlen length length2 length3 length4 vartype gettime peek wpeek lpeek varptr varuse noteinfo instr abs limit getease str strmid strf getpath strtrim sin cos tan atan sqrt double absf expf logf limitf powf geteasef mousex mousey mousew hwnd hinstance hdc ginfo objinfo dirinfo sysinfo thismod __hspver__ __hsp30__ __date__ __time__ __line__ __file__ _debug __hspdef__ and or xor not screen_normal screen_palette screen_hide screen_fixedsize screen_tool screen_frame gmode_gdi gmode_mem gmode_rgb0 gmode_alpha gmode_rgb0alpha gmode_add gmode_sub gmode_pixela ginfo_mx ginfo_my ginfo_act ginfo_sel ginfo_wx1 ginfo_wy1 ginfo_wx2 ginfo_wy2 ginfo_vx ginfo_vy ginfo_sizex ginfo_sizey ginfo_winx ginfo_winy ginfo_mesx ginfo_mesy ginfo_r ginfo_g ginfo_b ginfo_paluse ginfo_dispx ginfo_dispy ginfo_cx ginfo_cy ginfo_intid ginfo_newid ginfo_sx ginfo_sy objinfo_mode objinfo_bmscr objinfo_hwnd notemax notesize dir_cur dir_exe dir_win dir_sys dir_cmdline dir_desktop dir_mydoc dir_tv font_normal font_bold font_italic font_underline font_strikeout font_antialias objmode_normal objmode_guifont objmode_usefont gsquare_grad msgothic msmincho do until while wend for next _break _continue switch case default swbreak swend ddim ldim alloc m_pi rad2deg deg2rad ease_linear ease_quad_in ease_quad_out ease_quad_inout ease_cubic_in ease_cubic_out ease_cubic_inout ease_quartic_in ease_quartic_out ease_quartic_inout ease_bounce_in ease_bounce_out ease_bounce_inout ease_shake_in ease_shake_out ease_shake_inout ease_loop",c:[e.CLCM,e.CBCM,e.QSM,e.ASM,{cN:"string",b:'{"',e:'"}',c:[e.BE]},e.C(";","$",{r:0}),{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"addion cfunc cmd cmpopt comfunc const defcfunc deffunc define else endif enum epack func global if ifdef ifndef include modcfunc modfunc modinit modterm module pack packopt regcmd runtime undef usecom uselib"},c:[e.inherit(e.QSM,{cN:"meta-string"}),e.NM,e.CNM,e.CLCM,e.CBCM]},{cN:"symbol",b:"^\\*(\\w+|@)"},e.NM,e.CNM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/htmlbars.js b/lib/highlight_js/assets/lang/htmlbars.js new file mode 100644 index 00000000000..cb955b25758 --- /dev/null +++ b/lib/highlight_js/assets/lang/htmlbars.js @@ -0,0 +1 @@ +hljs.registerLanguage("htmlbars",function(e){var a="action collection component concat debugger each each-in else get hash if input link-to loc log mut outlet partial query-params render textarea unbound unless with yield view",t={i:/\}\}/,b:/[a-zA-Z0-9_]+=/,rB:!0,r:0,c:[{cN:"attr",b:/[a-zA-Z0-9_]+/}]},i=({i:/\}\}/,b:/\)/,e:/\)/,c:[{b:/[a-zA-Z\.\-]+/,k:{built_in:a},starts:{eW:!0,r:0,c:[e.QSM]}}]},{eW:!0,r:0,k:{keyword:"as",built_in:a},c:[e.QSM,t,e.NM]});return{aliases:["hbs","html.hbs","html.handlebars"],cI:!0,sL:"xml",c:[e.C("{{!(--)?","(--)?}}"),{cN:"template-tag",b:/\{\{[#\/]/,e:/\}\}/,c:[{cN:"name",b:/[a-zA-Z\.\-]+/,k:{"builtin-name":a},starts:i}]},{cN:"template-variable",b:/\{\{[a-zA-Z][a-zA-Z\-]+/,e:/\}\}/,k:{keyword:"as",built_in:a},c:[e.QSM]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/http.js b/lib/highlight_js/assets/lang/http.js index ad06182a841..9f017165abd 100644 --- a/lib/highlight_js/assets/lang/http.js +++ b/lib/highlight_js/assets/lang/http.js @@ -1 +1 @@ -hljs.registerLanguage("http",function(t){return{aliases:["https"],i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:!0}}]}}); \ No newline at end of file +hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/inform7.js b/lib/highlight_js/assets/lang/inform7.js new file mode 100644 index 00000000000..bb827d4e27f --- /dev/null +++ b/lib/highlight_js/assets/lang/inform7.js @@ -0,0 +1 @@ +hljs.registerLanguage("inform7",function(e){var r="\\[",o="\\]";return{aliases:["i7"],cI:!0,k:{keyword:"thing room person man woman animal container supporter backdrop door scenery open closed locked inside gender is are say understand kind of rule"},c:[{cN:"string",b:'"',e:'"',r:0,c:[{cN:"subst",b:r,e:o}]},{cN:"section",b:/^(Volume|Book|Part|Chapter|Section|Table)\b/,e:"$"},{b:/^(Check|Carry out|Report|Instead of|To|Rule|When|Before|After)\b/,e:":",c:[{b:"\\(This",e:"\\)"}]},{cN:"comment",b:r,e:o,c:["self"]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/ini.js b/lib/highlight_js/assets/lang/ini.js index 6618500ecdd..28e99fb8a26 100644 --- a/lib/highlight_js/assets/lang/ini.js +++ b/lib/highlight_js/assets/lang/ini.js @@ -1 +1 @@ -hljs.registerLanguage("ini",function(e){return{cI:!0,i:/\S/,c:[e.C(";","$"),{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:!0,k:"on off true false yes no",c:[e.QSM,e.NM],r:0}]}]}}); \ No newline at end of file +hljs.registerLanguage("ini",function(e){var b={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_-]+/},{b:/=/,eW:!0,r:0,c:[{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},b,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/irpf90.js b/lib/highlight_js/assets/lang/irpf90.js new file mode 100644 index 00000000000..c6efe978191 --- /dev/null +++ b/lib/highlight_js/assets/lang/irpf90.js @@ -0,0 +1 @@ +hljs.registerLanguage("irpf90",function(e){var t={cN:"params",b:"\\(",e:"\\)"},n={literal:".False. .True.",keyword:"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data begin_provider &begin_provider end_provider begin_shell end_shell begin_template end_template subst assert touch soft_touch provide no_dep free irp_if irp_else irp_endif irp_write irp_read",built_in:"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image IRP_ALIGN irp_here"};return{cI:!0,k:n,i:/\/\*/,c:[e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{cN:"string",r:0}),{cN:"function",bK:"subroutine function program",i:"[${=\\n]",c:[e.UTM,t]},e.C("!","$",{r:0}),e.C("begin_doc","end_doc",{r:10}),{cN:"number",b:"(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?",r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/java.js b/lib/highlight_js/assets/lang/java.js index c58ebcc78bd..f6c25e1e664 100644 --- a/lib/highlight_js/assets/lang/java.js +++ b/lib/highlight_js/assets/lang/java.js @@ -1 +1 @@ -hljs.registerLanguage("java",function(e){var a=e.UIR+"(<"+e.UIR+">)?",t="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",c="(\\b(0b[01_]+)|\\b0[xX][a-fA-F0-9_]+|(\\b[\\d_]+(\\.[\\d_]*)?|\\.[\\d_]+)([eE][-+]?\\d+)?)[lLfF]?",r={cN:"number",b:c,r:0};return{aliases:["jsp"],k:t,i:/<\//,c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",r:0,c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}]},e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return",r:0},{cN:"function",b:"("+a+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},r,{cN:"annotation",b:"@[A-Za-z]+"}]}}); \ No newline at end of file +hljs.registerLanguage("java",function(e){var a=e.UIR+"(<"+e.UIR+"(\\s*,\\s*"+e.UIR+")*>)?",t="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",r="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:r,r:0};return{aliases:["jsp"],k:t,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+a+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/javascript.js b/lib/highlight_js/assets/lang/javascript.js index ed9320fb7e3..0fda499007e 100644 --- a/lib/highlight_js/assets/lang/javascript.js +++ b/lib/highlight_js/assets/lang/javascript.js @@ -1 +1 @@ -hljs.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"pi",r:10,v:[{b:/^\s*('|")use strict('|")/},{b:/^\s*('|")use asm('|")/}]},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",b:"\\b(0[xXbBoO][a-fA-F0-9]+|(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/\s*[);\]]/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{bK:"import",e:"[;$]",k:"import from as",c:[e.ASM,e.QSM]},{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]}]}}); \ No newline at end of file +hljs.registerLanguage("javascript",function(e){return{aliases:["js","jsx"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b://,sL:"xml",c:[{b:/<\w+\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:["self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM]}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/json.js b/lib/highlight_js/assets/lang/json.js index 38f9c0010a9..ffcb329c511 100644 --- a/lib/highlight_js/assets/lang/json.js +++ b/lib/highlight_js/assets/lang/json.js @@ -1 +1 @@ -hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],l={cN:"value",e:",",eW:!0,eE:!0,c:i,k:t},c={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:l}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(l,{cN:null})],i:"\\S"};return i.splice(i.length,0,c,n),{c:i,k:t,i:"\\S"}}); \ No newline at end of file +hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/julia.js b/lib/highlight_js/assets/lang/julia.js index 1aa4c111cb4..1d3e28b3a31 100644 --- a/lib/highlight_js/assets/lang/julia.js +++ b/lib/highlight_js/assets/lang/julia.js @@ -1 +1 @@ -hljs.registerLanguage("julia",function(r){var e={keyword:"in abstract baremodule begin bitstype break catch ccall const continue do else elseif end export finally for function global if immutable import importall let local macro module quote return try type typealias using while",literal:"true false ANY ARGS CPU_CORES C_NULL DL_LOAD_PATH DevNull ENDIAN_BOM ENV I|0 Inf Inf16 Inf32 InsertionSort JULIA_HOME LOAD_PATH MS_ASYNC MS_INVALIDATE MS_SYNC MergeSort NaN NaN16 NaN32 OS_NAME QuickSort RTLD_DEEPBIND RTLD_FIRST RTLD_GLOBAL RTLD_LAZY RTLD_LOCAL RTLD_NODELETE RTLD_NOLOAD RTLD_NOW RoundDown RoundFromZero RoundNearest RoundToZero RoundUp STDERR STDIN STDOUT VERSION WORD_SIZE catalan cglobal e eu eulergamma golden im nothing pi γ π φ",built_in:"ASCIIString AbstractArray AbstractRNG AbstractSparseArray Any ArgumentError Array Associative Base64Pipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError Box CFILE Cchar Cdouble Cfloat Char CharString Cint Clong Clonglong ClusterManager Cmd Coff_t Colon Complex Complex128 Complex32 Complex64 Condition Cptrdiff_t Cshort Csize_t Cssize_t Cuchar Cuint Culong Culonglong Cushort Cwchar_t DArray DataType DenseArray Diagonal Dict DimensionMismatch DirectIndexString Display DivideError DomainError EOFError EachLine Enumerate ErrorException Exception Expr Factorization FileMonitor FileOffset Filter Float16 Float32 Float64 FloatRange FloatingPoint Function GetfieldNode GotoNode Hermitian IO IOBuffer IOStream IPv4 IPv6 InexactError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException IntrinsicFunction KeyError LabelNode LambdaStaticData LineNumberNode LoadError LocalProcess MIME MathConst MemoryError MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode Nothing Number ObjectIdDict OrdinalRange OverflowError ParseError PollingFileWatcher ProcessExitedException ProcessGroup Ptr QuoteNode Range Range1 Ranges Rational RawFD Real Regex RegexMatch RemoteRef RepString RevString RopeString RoundingMode Set SharedArray Signed SparseMatrixCSC StackOverflowError Stat StatStruct StepRange String SubArray SubString SymTridiagonal Symbol SymbolNode Symmetric SystemError Task TextDisplay Timer TmStruct TopNode Triangular Tridiagonal Type TypeConstructor TypeError TypeName TypeVar UTF16String UTF32String UTF8String UdpSocket Uint Uint128 Uint16 Uint32 Uint64 Uint8 UndefRefError UndefVarError UniformScaling UnionType UnitRange Unsigned Vararg VersionNumber WString WeakKeyDict WeakRef Woodbury Zip"},t="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",o={l:t,k:e},n={cN:"type-annotation",b:/::/},a={cN:"subtype",b:/<:/},i={cN:"number",b:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,r:0},l={cN:"char",b:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},c={cN:"subst",b:/\$\(/,e:/\)/,k:e},u={cN:"variable",b:"\\$"+t},d={cN:"string",c:[r.BE,c,u],v:[{b:/\w*"/,e:/"\w*/},{b:/\w*"""/,e:/"""\w*/}]},g={cN:"string",c:[r.BE,c,u],b:"`",e:"`"},s={cN:"macrocall",b:"@"+t},S={cN:"comment",v:[{b:"#=",e:"=#",r:10},{b:"#",e:"$"}]};return o.c=[i,l,n,a,d,g,s,S,r.HCM],c.c=o.c,o}); \ No newline at end of file +hljs.registerLanguage("julia",function(e){var r={keyword:"in abstract baremodule begin bitstype break catch ccall const continue do else elseif end export finally for function global if immutable import importall let local macro module quote return try type typealias using while",literal:"true false ARGS CPU_CORES C_NULL DL_LOAD_PATH DevNull ENDIAN_BOM ENV I|0 Inf Inf16 Inf32 InsertionSort JULIA_HOME LOAD_PATH MS_ASYNC MS_INVALIDATE MS_SYNC MergeSort NaN NaN16 NaN32 OS_NAME QuickSort RTLD_DEEPBIND RTLD_FIRST RTLD_GLOBAL RTLD_LAZY RTLD_LOCAL RTLD_NODELETE RTLD_NOLOAD RTLD_NOW RoundDown RoundFromZero RoundNearest RoundToZero RoundUp STDERR STDIN STDOUT VERSION WORD_SIZE catalan cglobal e|0 eu|0 eulergamma golden im nothing pi γ π φ Inf64 NaN64 RoundNearestTiesAway RoundNearestTiesUp ",built_in:"ANY ASCIIString AbstractArray AbstractRNG AbstractSparseArray Any ArgumentError Array Associative Base64Pipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError Box CFILE Cchar Cdouble Cfloat Char CharString Cint Clong Clonglong ClusterManager Cmd Coff_t Colon Complex Complex128 Complex32 Complex64 Condition Cptrdiff_t Cshort Csize_t Cssize_t Cuchar Cuint Culong Culonglong Cushort Cwchar_t DArray DataType DenseArray Diagonal Dict DimensionMismatch DirectIndexString Display DivideError DomainError EOFError EachLine Enumerate ErrorException Exception Expr Factorization FileMonitor FileOffset Filter Float16 Float32 Float64 FloatRange FloatingPoint Function GetfieldNode GotoNode Hermitian IO IOBuffer IOStream IPv4 IPv6 InexactError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException IntrinsicFunction KeyError LabelNode LambdaStaticData LineNumberNode LoadError LocalProcess MIME MathConst MemoryError MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode Nothing Number ObjectIdDict OrdinalRange OverflowError ParseError PollingFileWatcher ProcessExitedException ProcessGroup Ptr QuoteNode Range Range1 Ranges Rational RawFD Real Regex RegexMatch RemoteRef RepString RevString RopeString RoundingMode Set SharedArray Signed SparseMatrixCSC StackOverflowError Stat StatStruct StepRange String SubArray SubString SymTridiagonal Symbol SymbolNode Symmetric SystemError Task TextDisplay Timer TmStruct TopNode Triangular Tridiagonal Type TypeConstructor TypeError TypeName TypeVar UTF16String UTF32String UTF8String UdpSocket Uint Uint128 Uint16 Uint32 Uint64 Uint8 UndefRefError UndefVarError UniformScaling UnionType UnitRange Unsigned Vararg VersionNumber WString WeakKeyDict WeakRef Woodbury Zip AbstractChannel AbstractFloat AbstractString AssertionError Base64DecodePipe Base64EncodePipe BufferStream CapturedException CartesianIndex CartesianRange Channel Cintmax_t CompositeException Cstring Cuintmax_t Cwstring Date DateTime Dims Enum GenSym GlobalRef HTML InitError InvalidStateException Irrational LinSpace LowerTriangular NullException Nullable OutOfMemoryError Pair PartialQuickSort Pipe RandomDevice ReadOnlyMemoryError ReentrantLock Ref RemoteException SegmentationFault SerializationState SimpleVector TCPSocket Text Tuple UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UnicodeError Union UpperTriangular Val Void WorkerConfig AbstractMatrix AbstractSparseMatrix AbstractSparseVector AbstractVecOrMat AbstractVector DenseMatrix DenseVecOrMat DenseVector Matrix SharedMatrix SharedVector StridedArray StridedMatrix StridedVecOrMat StridedVector VecOrMat Vector "},t="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",a={l:t,k:r,i:/<\//},n={cN:"type",b:/::/},o={cN:"type",b:/<:/},i={cN:"number",b:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,r:0},l={cN:"string",b:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},c={cN:"subst",b:/\$\(/,e:/\)/,k:r},s={cN:"variable",b:"\\$"+t},d={cN:"string",c:[e.BE,c,s],v:[{b:/\w*"""/,e:/"""\w*/,r:10},{b:/\w*"/,e:/"\w*/}]},S={cN:"string",c:[e.BE,c,s],b:"`",e:"`"},u={cN:"meta",b:"@"+t},g={cN:"comment",v:[{b:"#=",e:"=#",r:10},{b:"#",e:"$"}]};return a.c=[i,l,n,o,d,S,u,g,e.HCM],c.c=a.c,a}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/kotlin.js b/lib/highlight_js/assets/lang/kotlin.js index 237d7270c1c..b3b9b3670b6 100644 --- a/lib/highlight_js/assets/lang/kotlin.js +++ b/lib/highlight_js/assets/lang/kotlin.js @@ -1 +1 @@ -hljs.registerLanguage("kotlin",function(e){var a="val var get set class trait object public open private protected final enum if else do while for when break continue throw try catch finally import package is as in return fun override default companion reified inline volatile transient native";return{k:{typename:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null",keyword:a},c:[e.CLCM,{cN:"javadoc",b:"/\\*\\*",e:"\\*//*",r:0,c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}]},e.CBCM,{cN:"type",b://,rB:!0,eE:!1,r:0},{cN:"function",bK:"fun",e:"[(]|$",rB:!0,eE:!0,k:a,i:/fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,r:5,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"type",b://,k:"reified",r:0},{cN:"params",b:/\(/,e:/\)/,k:a,r:0,i:/\([^\(,\s:]+,/,c:[{cN:"typename",b:/:\s*/,e:/\s*[=\)]/,eB:!0,rE:!0,r:0}]},e.CLCM,e.CBCM]},{cN:"class",bK:"class trait",e:/[:\{(]|$/,eE:!0,i:"extends implements",c:[e.UTM,{cN:"type",b://,eB:!0,eE:!0,r:0},{cN:"typename",b:/[,:]\s*/,e:/[<\(,]|$/,eB:!0,rE:!0}]},{cN:"variable",bK:"var val",e:/\s*[=:$]/,eE:!0},e.QSM,{cN:"shebang",b:"^#!/usr/bin/env",e:"$",i:"\n"},e.CNM]}}); \ No newline at end of file +hljs.registerLanguage("kotlin",function(e){var t="val var get set class trait object open private protected public final enum if else do while for when break continue throw try catch finally import package is as in return fun override default companion reified inline volatile transient native Byte Short Char Int Long Boolean Float Double Void Unit Nothing";return{k:{keyword:t,literal:"true false null"},c:[e.C("/\\*\\*","\\*/",{r:0,c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,{cN:"function",bK:"fun",e:"[(]|$",rB:!0,eE:!0,k:t,i:/fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,r:5,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"type",b://,k:"reified",r:0},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,i:/\([^\(,\s:]+,/,c:[{cN:"type",b:/:\s*/,e:/\s*[=\)]/,eB:!0,rE:!0,r:0}]},e.CLCM,e.CBCM]},{cN:"class",bK:"class trait",e:/[:\{(]|$/,eE:!0,i:"extends implements",c:[e.UTM,{cN:"type",b://,eB:!0,eE:!0,r:0},{cN:"type",b:/[,:]\s*/,e:/[<\(,]|$/,eB:!0,rE:!0}]},e.QSM,{cN:"meta",b:"^#!/usr/bin/env",e:"$",i:"\n"},e.CNM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/lasso.js b/lib/highlight_js/assets/lang/lasso.js index 24e01c7ed5a..3bb34cb8222 100644 --- a/lib/highlight_js/assets/lang/lasso.js +++ b/lib/highlight_js/assets/lang/lasso.js @@ -1 +1 @@ -hljs.registerLanguage("lasso",function(e){var r="[a-zA-Z_][a-zA-Z0-9_.]*",a="<\\?(lasso(script)?|=)",t="\\]|\\?>",s={literal:"true false none minimal full all void and or not bw nbw ew new cn ncn lt lte gt gte eq neq rx nrx ft",built_in:"array date decimal duration integer map pair string tag xml null boolean bytes keyword list locale queue set stack staticarray local var variable global data self inherited",keyword:"error_code error_msg error_pop error_push error_reset cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require returnhome skip split_thread sum take thread to trait type where with yield yieldhome"},n=e.C("",{r:0}),o={cN:"preprocessor",b:"\\[noprocess\\]",starts:{cN:"markup",e:"\\[/noprocess\\]",rE:!0,c:[n]}},i={cN:"preprocessor",b:"\\[/noprocess|"+a},l={cN:"variable",b:"'"+r+"'"},c=[e.CLCM,{cN:"javadoc",b:"/\\*\\*!",e:"\\*/",c:[e.PWM]},e.CBCM,e.inherit(e.CNM,{b:e.CNR+"|(-?infinity|nan)\\b"}),e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{cN:"variable",v:[{b:"[#$]"+r},{b:"#",e:"\\d+",i:"\\W"}]},{cN:"tag",b:"::\\s*",e:r,i:"\\W"},{cN:"attribute",v:[{b:"-"+e.UIR,r:0},{b:"(\\.\\.\\.)"}]},{cN:"subst",v:[{b:"->\\s*",c:[l]},{b:":=|/(?!\\w)=?|[-+*%=<>&|!?\\\\]+",r:0}]},{cN:"built_in",b:"\\.\\.?\\s*",r:0,c:[l]},{cN:"class",bK:"define",rE:!0,e:"\\(|=>",c:[e.inherit(e.TM,{b:e.UIR+"(=(?!>))?"})]}];return{aliases:["ls","lassoscript"],cI:!0,l:r+"|&[lg]t;",k:s,c:[{cN:"preprocessor",b:t,r:0,starts:{cN:"markup",e:"\\[|"+a,rE:!0,r:0,c:[n]}},o,i,{cN:"preprocessor",b:"\\[no_square_brackets",starts:{e:"\\[/no_square_brackets\\]",l:r+"|&[lg]t;",k:s,c:[{cN:"preprocessor",b:t,r:0,starts:{cN:"markup",e:"\\[noprocess\\]|"+a,rE:!0,c:[n]}},o,i].concat(c)}},{cN:"preprocessor",b:"\\[",r:0},{cN:"shebang",b:"^#!.+lasso9\\b",r:10}].concat(c)}}); \ No newline at end of file +hljs.registerLanguage("lasso",function(e){var r="[a-zA-Z_][a-zA-Z0-9_.]*",t="<\\?(lasso(script)?|=)",a="\\]|\\?>",n={literal:"true false none minimal full all void bw nbw ew new cn ncn lt lte gt gte eq neq rx nrx ft",built_in:"array date decimal duration integer map pair string tag xml null boolean bytes keyword list locale queue set stack staticarray local var variable global data self inherited currentcapture givenblock",keyword:"error_code error_msg error_pop error_push error_reset cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require returnhome skip split_thread sum take thread to trait type where with yield yieldhome and or not"},s=e.C("",{r:0}),i={cN:"meta",b:"\\[noprocess\\]",starts:{e:"\\[/noprocess\\]",rE:!0,c:[s]}},l={cN:"meta",b:"\\[/noprocess|"+t},o={cN:"symbol",b:"'"+r+"'"},c=[e.C("/\\*\\*!","\\*/"),e.CLCM,e.CBCM,e.inherit(e.CNM,{b:e.CNR+"|(infinity|nan)\\b"}),e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{v:[{b:"[#$]"+r},{b:"#",e:"\\d+",i:"\\W"}]},{cN:"type",b:"::\\s*",e:r,i:"\\W"},{cN:"attr",v:[{b:"-(?!infinity)"+e.UIR,r:0},{b:"(\\.\\.\\.)"}]},{b:/(->|\.\.?)\s*/,r:0,c:[o]},{cN:"class",bK:"define",rE:!0,e:"\\(|=>",c:[e.inherit(e.TM,{b:e.UIR+"(=(?!>))?"})]}];return{aliases:["ls","lassoscript"],cI:!0,l:r+"|&[lg]t;",k:n,c:[{cN:"meta",b:a,r:0,starts:{e:"\\[|"+t,rE:!0,r:0,c:[s]}},i,l,{cN:"meta",b:"\\[no_square_brackets",starts:{e:"\\[/no_square_brackets\\]",l:r+"|&[lg]t;",k:n,c:[{cN:"meta",b:a,r:0,starts:{e:"\\[noprocess\\]|"+t,rE:!0,c:[s]}},i,l].concat(c)}},{cN:"meta",b:"\\[",r:0},{cN:"meta",b:"^#!.+lasso9\\b",r:10}].concat(c)}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/less.js b/lib/highlight_js/assets/lang/less.js index 61f038720f7..d56097136ce 100644 --- a/lib/highlight_js/assets/lang/less.js +++ b/lib/highlight_js/assets/lang/less.js @@ -1 +1 @@ -hljs.registerLanguage("less",function(e){var r="[\\w-]+",t="("+r+"|@{"+r+"})",a=[],c=[],n=function(e){return{cN:"string",b:"~?"+e+".*?"+e}},i=function(e,r,t){return{cN:e,b:r,r:t}},s=function(r,t,a){return e.inherit({cN:r,b:t+"\\(",e:"\\(",rB:!0,eE:!0,r:0},a)},b={b:"\\(",e:"\\)",c:c,r:0};c.push(e.CLCM,e.CBCM,n("'"),n('"'),e.CSSNM,i("hexcolor","#[0-9A-Fa-f]+\\b"),s("function","(url|data-uri)",{starts:{cN:"string",e:"[\\)\\n]",eE:!0}}),s("function",r),b,i("variable","@@?"+r,10),i("variable","@{"+r+"}"),i("built_in","~?`[^`]*?`"),{cN:"attribute",b:r+"\\s*:",e:":",rB:!0,eE:!0});var o=c.concat({b:"{",e:"}",c:a}),u={bK:"when",eW:!0,c:[{bK:"and not"}].concat(c)},C={cN:"attribute",b:t,e:":",eE:!0,c:[e.CLCM,e.CBCM],i:/\S/,starts:{e:"[;}]",rE:!0,c:c,i:"[<=$]"}},l={cN:"at_rule",b:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{e:"[;{}]",rE:!0,c:c,r:0}},d={cN:"variable",v:[{b:"@"+r+"\\s*:",r:15},{b:"@"+r}],starts:{e:"[;}]",rE:!0,c:o}},p={v:[{b:"[\\.#:&\\[]",e:"[;{}]"},{b:t+"[^;]*{",e:"{"}],rB:!0,rE:!0,i:"[<='$\"]",c:[e.CLCM,e.CBCM,u,i("keyword","all\\b"),i("variable","@{"+r+"}"),i("tag",t+"%?",0),i("id","#"+t),i("class","\\."+t,0),i("keyword","&",0),s("pseudo",":not"),s("keyword",":extend"),i("pseudo","::?"+t),{cN:"attr_selector",b:"\\[",e:"\\]"},{b:"\\(",e:"\\)",c:o},{b:"!important"}]};return a.push(e.CLCM,e.CBCM,l,d,p,C),{cI:!0,i:"[=>'/<($\"]",c:a}}); \ No newline at end of file +hljs.registerLanguage("less",function(e){var r="[\\w-]+",t="("+r+"|@{"+r+"})",a=[],c=[],s=function(e){return{cN:"string",b:"~?"+e+".*?"+e}},b=function(e,r,t){return{cN:e,b:r,r:t}},i={b:"\\(",e:"\\)",c:c,r:0};c.push(e.CLCM,e.CBCM,s("'"),s('"'),e.CSSNM,{b:"(url|data-uri)\\(",starts:{cN:"string",e:"[\\)\\n]",eE:!0}},b("number","#[0-9A-Fa-f]+\\b"),i,b("variable","@@?"+r,10),b("variable","@{"+r+"}"),b("built_in","~?`[^`]*?`"),{cN:"attribute",b:r+"\\s*:",e:":",rB:!0,eE:!0},{cN:"meta",b:"!important"});var n=c.concat({b:"{",e:"}",c:a}),o={bK:"when",eW:!0,c:[{bK:"and not"}].concat(c)},u={cN:"attribute",b:t,e:":",eE:!0,c:[e.CLCM,e.CBCM],i:/\S/,starts:{e:"[;}]",rE:!0,c:c,i:"[<=$]"}},C={cN:"keyword",b:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{e:"[;{}]",rE:!0,c:c,r:0}},l={cN:"variable",v:[{b:"@"+r+"\\s*:",r:15},{b:"@"+r}],starts:{e:"[;}]",rE:!0,c:n}},p={v:[{b:"[\\.#:&\\[]",e:"[;{}]"},{b:t+"[^;]*{",e:"{"}],rB:!0,rE:!0,i:"[<='$\"]",c:[e.CLCM,e.CBCM,o,b("keyword","all\\b"),b("variable","@{"+r+"}"),b("selector-tag",t+"%?",0),b("selector-id","#"+t),b("selector-class","\\."+t,0),b("selector-tag","&",0),{cN:"selector-attr",b:"\\[",e:"\\]"},{b:"\\(",e:"\\)",c:n},{b:"!important"}]};return a.push(e.CLCM,e.CBCM,C,l,p,u),{cI:!0,i:"[=>'/<($\"]",c:a}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/lisp.js b/lib/highlight_js/assets/lang/lisp.js index 0338f37ca13..b2747ab3d7f 100644 --- a/lib/highlight_js/assets/lang/lisp.js +++ b/lib/highlight_js/assets/lang/lisp.js @@ -1 +1 @@ -hljs.registerLanguage("lisp",function(b){var e="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*",c="\\|[^]*?\\|",r="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\+|\\-)?\\d+)?",a={cN:"shebang",b:"^#!",e:"$"},i={cN:"literal",b:"\\b(t{1}|nil)\\b"},l={cN:"number",v:[{b:r,r:0},{b:"#(b|B)[0-1]+(/[0-1]+)?"},{b:"#(o|O)[0-7]+(/[0-7]+)?"},{b:"#(x|X)[0-9a-fA-F]+(/[0-9a-fA-F]+)?"},{b:"#(c|C)\\("+r+" +"+r,e:"\\)"}]},t=b.inherit(b.QSM,{i:null}),d=b.C(";","$",{r:0}),n={cN:"variable",b:"\\*",e:"\\*"},u={cN:"keyword",b:"[:&]"+e},N={b:e,r:0},o={b:c},s={b:"\\(",e:"\\)",c:["self",i,t,l,N]},v={cN:"quoted",c:[l,t,n,u,s,N],v:[{b:"['`]\\(",e:"\\)"},{b:"\\(quote ",e:"\\)",k:"quote"},{b:"'"+c}]},f={cN:"quoted",v:[{b:"'"+e},{b:"#'"+e+"(::"+e+")*"}]},g={cN:"list",b:"\\(\\s*",e:"\\)"},q={eW:!0,r:0};return g.c=[{cN:"keyword",v:[{b:e},{b:c}]},q],q.c=[v,f,g,i,l,t,d,n,u,o,N],{i:/\S/,c:[l,a,i,t,d,v,f,g,N]}}); \ No newline at end of file +hljs.registerLanguage("lisp",function(b){var e="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*",c="\\|[^]*?\\|",r="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\+|\\-)?\\d+)?",a={cN:"meta",b:"^#!",e:"$"},l={cN:"literal",b:"\\b(t{1}|nil)\\b"},n={cN:"number",v:[{b:r,r:0},{b:"#(b|B)[0-1]+(/[0-1]+)?"},{b:"#(o|O)[0-7]+(/[0-7]+)?"},{b:"#(x|X)[0-9a-fA-F]+(/[0-9a-fA-F]+)?"},{b:"#(c|C)\\("+r+" +"+r,e:"\\)"}]},i=b.inherit(b.QSM,{i:null}),t=b.C(";","$",{r:0}),s={b:"\\*",e:"\\*"},u={cN:"symbol",b:"[:&]"+e},d={b:e,r:0},f={b:c},m={b:"\\(",e:"\\)",c:["self",l,i,n,d]},o={c:[n,i,s,u,m,d],v:[{b:"['`]\\(",e:"\\)"},{b:"\\(quote ",e:"\\)",k:{name:"quote"}},{b:"'"+c}]},v={v:[{b:"'"+e},{b:"#'"+e+"(::"+e+")*"}]},N={b:"\\(\\s*",e:"\\)"},A={eW:!0,r:0};return N.c=[{cN:"name",v:[{b:e},{b:c}]},A],A.c=[o,v,N,l,n,i,t,s,u,f,d],{i:/\S/,c:[n,a,l,i,t,o,v,N,d]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/livecodeserver.js b/lib/highlight_js/assets/lang/livecodeserver.js index b2d10f2fd0f..21ac65c22f6 100644 --- a/lib/highlight_js/assets/lang/livecodeserver.js +++ b/lib/highlight_js/assets/lang/livecodeserver.js @@ -1 +1 @@ -hljs.registerLanguage("livecodeserver",function(e){var r={cN:"variable",b:"\\b[gtps][A-Z]+[A-Za-z0-9_\\-]*\\b|\\$_[A-Z]+",r:0},t=[e.CBCM,e.HCM,e.C("--","$"),e.C("[^:]//","$")],a=e.inherit(e.TM,{v:[{b:"\\b_*rig[A-Z]+[A-Za-z0-9_\\-]*"},{b:"\\b_[a-z0-9\\-]+"}]}),o=e.inherit(e.TM,{b:"\\b([A-Za-z0-9_\\-]+)\\b"});return{cI:!1,k:{keyword:"$_COOKIE $_FILES $_GET $_GET_BINARY $_GET_RAW $_POST $_POST_BINARY $_POST_RAW $_SESSION $_SERVER codepoint codepoints segment segments codeunit codeunits sentence sentences trueWord trueWords paragraph after byte bytes english the until http forever descending using line real8 with seventh for stdout finally element word words fourth before black ninth sixth characters chars stderr uInt1 uInt1s uInt2 uInt2s stdin string lines relative rel any fifth items from middle mid at else of catch then third it file milliseconds seconds second secs sec int1 int1s int4 int4s internet int2 int2s normal text item last long detailed effective uInt4 uInt4s repeat end repeat URL in try into switch to words https token binfile each tenth as ticks tick system real4 by dateItems without char character ascending eighth whole dateTime numeric short first ftp integer abbreviated abbr abbrev private case while if",constant:"SIX TEN FORMFEED NINE ZERO NONE SPACE FOUR FALSE COLON CRLF PI COMMA ENDOFFILE EOF EIGHT FIVE QUOTE EMPTY ONE TRUE RETURN CR LINEFEED RIGHT BACKSLASH NULL SEVEN TAB THREE TWO six ten formfeed nine zero none space four false colon crlf pi comma endoffile eof eight five quote empty one true return cr linefeed right backslash null seven tab three two RIVERSION RISTATE FILE_READ_MODE FILE_WRITE_MODE FILE_WRITE_MODE DIR_WRITE_MODE FILE_READ_UMASK FILE_WRITE_UMASK DIR_READ_UMASK DIR_WRITE_UMASK",operator:"div mod wrap and or bitAnd bitNot bitOr bitXor among not in a an within contains ends with begins the keys of keys",built_in:"put abs acos aliasReference annuity arrayDecode arrayEncode asin atan atan2 average avg avgDev base64Decode base64Encode baseConvert binaryDecode binaryEncode byteOffset byteToNum cachedURL cachedURLs charToNum cipherNames codepointOffset codepointProperty codepointToNum codeunitOffset commandNames compound compress constantNames cos date dateFormat decompress directories diskSpace DNSServers exp exp1 exp2 exp10 extents files flushEvents folders format functionNames geometricMean global globals hasMemory harmonicMean hostAddress hostAddressToName hostName hostNameToAddress isNumber ISOToMac itemOffset keys len length libURLErrorData libUrlFormData libURLftpCommand libURLLastHTTPHeaders libURLLastRHHeaders libUrlMultipartFormAddPart libUrlMultipartFormData libURLVersion lineOffset ln ln1 localNames log log2 log10 longFilePath lower macToISO matchChunk matchText matrixMultiply max md5Digest median merge millisec millisecs millisecond milliseconds min monthNames nativeCharToNum normalizeText num number numToByte numToChar numToCodepoint numToNativeChar offset open openfiles openProcesses openProcessIDs openSockets paragraphOffset paramCount param params peerAddress pendingMessages platform popStdDev populationStandardDeviation populationVariance popVariance processID random randomBytes replaceText result revCreateXMLTree revCreateXMLTreeFromFile revCurrentRecord revCurrentRecordIsFirst revCurrentRecordIsLast revDatabaseColumnCount revDatabaseColumnIsNull revDatabaseColumnLengths revDatabaseColumnNames revDatabaseColumnNamed revDatabaseColumnNumbered revDatabaseColumnTypes revDatabaseConnectResult revDatabaseCursors revDatabaseID revDatabaseTableNames revDatabaseType revDataFromQuery revdb_closeCursor revdb_columnbynumber revdb_columncount revdb_columnisnull revdb_columnlengths revdb_columnnames revdb_columntypes revdb_commit revdb_connect revdb_connections revdb_connectionerr revdb_currentrecord revdb_cursorconnection revdb_cursorerr revdb_cursors revdb_dbtype revdb_disconnect revdb_execute revdb_iseof revdb_isbof revdb_movefirst revdb_movelast revdb_movenext revdb_moveprev revdb_query revdb_querylist revdb_recordcount revdb_rollback revdb_tablenames revGetDatabaseDriverPath revNumberOfRecords revOpenDatabase revOpenDatabases revQueryDatabase revQueryDatabaseBlob revQueryResult revQueryIsAtStart revQueryIsAtEnd revUnixFromMacPath revXMLAttribute revXMLAttributes revXMLAttributeValues revXMLChildContents revXMLChildNames revXMLCreateTreeFromFileWithNamespaces revXMLCreateTreeWithNamespaces revXMLDataFromXPathQuery revXMLEvaluateXPath revXMLFirstChild revXMLMatchingNode revXMLNextSibling revXMLNodeContents revXMLNumberOfChildren revXMLParent revXMLPreviousSibling revXMLRootNode revXMLRPC_CreateRequest revXMLRPC_Documents revXMLRPC_Error revXMLRPC_GetHost revXMLRPC_GetMethod revXMLRPC_GetParam revXMLText revXMLRPC_Execute revXMLRPC_GetParamCount revXMLRPC_GetParamNode revXMLRPC_GetParamType revXMLRPC_GetPath revXMLRPC_GetPort revXMLRPC_GetProtocol revXMLRPC_GetRequest revXMLRPC_GetResponse revXMLRPC_GetSocket revXMLTree revXMLTrees revXMLValidateDTD revZipDescribeItem revZipEnumerateItems revZipOpenArchives round sampVariance sec secs seconds sentenceOffset sha1Digest shell shortFilePath sin specialFolderPath sqrt standardDeviation statRound stdDev sum sysError systemVersion tan tempName textDecode textEncode tick ticks time to tokenOffset toLower toUpper transpose truewordOffset trunc uniDecode uniEncode upper URLDecode URLEncode URLStatus uuid value variableNames variance version waitDepth weekdayNames wordOffset xsltApplyStylesheet xsltApplyStylesheetFromFile xsltLoadStylesheet xsltLoadStylesheetFromFile add breakpoint cancel clear local variable file word line folder directory URL close socket process combine constant convert create new alias folder directory decrypt delete variable word line folder directory URL dispatch divide do encrypt filter get include intersect kill libURLDownloadToFile libURLFollowHttpRedirects libURLftpUpload libURLftpUploadFile libURLresetAll libUrlSetAuthCallback libURLSetCustomHTTPHeaders libUrlSetExpect100 libURLSetFTPListCommand libURLSetFTPMode libURLSetFTPStopTime libURLSetStatusCallback load multiply socket prepare process post seek rel relative read from process rename replace require resetAll resolve revAddXMLNode revAppendXML revCloseCursor revCloseDatabase revCommitDatabase revCopyFile revCopyFolder revCopyXMLNode revDeleteFolder revDeleteXMLNode revDeleteAllXMLTrees revDeleteXMLTree revExecuteSQL revGoURL revInsertXMLNode revMoveFolder revMoveToFirstRecord revMoveToLastRecord revMoveToNextRecord revMoveToPreviousRecord revMoveToRecord revMoveXMLNode revPutIntoXMLNode revRollBackDatabase revSetDatabaseDriverPath revSetXMLAttribute revXMLRPC_AddParam revXMLRPC_DeleteAllDocuments revXMLAddDTD revXMLRPC_Free revXMLRPC_FreeAll revXMLRPC_DeleteDocument revXMLRPC_DeleteParam revXMLRPC_SetHost revXMLRPC_SetMethod revXMLRPC_SetPort revXMLRPC_SetProtocol revXMLRPC_SetSocket revZipAddItemWithData revZipAddItemWithFile revZipAddUncompressedItemWithData revZipAddUncompressedItemWithFile revZipCancel revZipCloseArchive revZipDeleteItem revZipExtractItemToFile revZipExtractItemToVariable revZipSetProgressCallback revZipRenameItem revZipReplaceItemWithData revZipReplaceItemWithFile revZipOpenArchive send set sort split start stop subtract union unload wait write"},c:[r,{cN:"keyword",b:"\\bend\\sif\\b"},{cN:"function",bK:"function",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"function",bK:"end",e:"$",c:[o,a]},{cN:"command",bK:"command on",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"command",bK:"end",e:"$",c:[o,a]},{cN:"preprocessor",b:"<\\?rev|<\\?lc|<\\?livecode",r:10},{cN:"preprocessor",b:"<\\?"},{cN:"preprocessor",b:"\\?>"},e.ASM,e.QSM,e.BNM,e.CNM,a].concat(t),i:";$|^\\[|^="}}); \ No newline at end of file +hljs.registerLanguage("livecodeserver",function(e){var r={b:"\\b[gtps][A-Z]+[A-Za-z0-9_\\-]*\\b|\\$_[A-Z]+",r:0},t=[e.CBCM,e.HCM,e.C("--","$"),e.C("[^:]//","$")],a=e.inherit(e.TM,{v:[{b:"\\b_*rig[A-Z]+[A-Za-z0-9_\\-]*"},{b:"\\b_[a-z0-9\\-]+"}]}),o=e.inherit(e.TM,{b:"\\b([A-Za-z0-9_\\-]+)\\b"});return{cI:!1,k:{keyword:"$_COOKIE $_FILES $_GET $_GET_BINARY $_GET_RAW $_POST $_POST_BINARY $_POST_RAW $_SESSION $_SERVER codepoint codepoints segment segments codeunit codeunits sentence sentences trueWord trueWords paragraph after byte bytes english the until http forever descending using line real8 with seventh for stdout finally element word words fourth before black ninth sixth characters chars stderr uInt1 uInt1s uInt2 uInt2s stdin string lines relative rel any fifth items from middle mid at else of catch then third it file milliseconds seconds second secs sec int1 int1s int4 int4s internet int2 int2s normal text item last long detailed effective uInt4 uInt4s repeat end repeat URL in try into switch to words https token binfile each tenth as ticks tick system real4 by dateItems without char character ascending eighth whole dateTime numeric short first ftp integer abbreviated abbr abbrev private case while if div mod wrap and or bitAnd bitNot bitOr bitXor among not in a an within contains ends with begins the keys of keys",literal:"SIX TEN FORMFEED NINE ZERO NONE SPACE FOUR FALSE COLON CRLF PI COMMA ENDOFFILE EOF EIGHT FIVE QUOTE EMPTY ONE TRUE RETURN CR LINEFEED RIGHT BACKSLASH NULL SEVEN TAB THREE TWO six ten formfeed nine zero none space four false colon crlf pi comma endoffile eof eight five quote empty one true return cr linefeed right backslash null seven tab three two RIVERSION RISTATE FILE_READ_MODE FILE_WRITE_MODE FILE_WRITE_MODE DIR_WRITE_MODE FILE_READ_UMASK FILE_WRITE_UMASK DIR_READ_UMASK DIR_WRITE_UMASK",built_in:"put abs acos aliasReference annuity arrayDecode arrayEncode asin atan atan2 average avg avgDev base64Decode base64Encode baseConvert binaryDecode binaryEncode byteOffset byteToNum cachedURL cachedURLs charToNum cipherNames codepointOffset codepointProperty codepointToNum codeunitOffset commandNames compound compress constantNames cos date dateFormat decompress directories diskSpace DNSServers exp exp1 exp2 exp10 extents files flushEvents folders format functionNames geometricMean global globals hasMemory harmonicMean hostAddress hostAddressToName hostName hostNameToAddress isNumber ISOToMac itemOffset keys len length libURLErrorData libUrlFormData libURLftpCommand libURLLastHTTPHeaders libURLLastRHHeaders libUrlMultipartFormAddPart libUrlMultipartFormData libURLVersion lineOffset ln ln1 localNames log log2 log10 longFilePath lower macToISO matchChunk matchText matrixMultiply max md5Digest median merge millisec millisecs millisecond milliseconds min monthNames nativeCharToNum normalizeText num number numToByte numToChar numToCodepoint numToNativeChar offset open openfiles openProcesses openProcessIDs openSockets paragraphOffset paramCount param params peerAddress pendingMessages platform popStdDev populationStandardDeviation populationVariance popVariance processID random randomBytes replaceText result revCreateXMLTree revCreateXMLTreeFromFile revCurrentRecord revCurrentRecordIsFirst revCurrentRecordIsLast revDatabaseColumnCount revDatabaseColumnIsNull revDatabaseColumnLengths revDatabaseColumnNames revDatabaseColumnNamed revDatabaseColumnNumbered revDatabaseColumnTypes revDatabaseConnectResult revDatabaseCursors revDatabaseID revDatabaseTableNames revDatabaseType revDataFromQuery revdb_closeCursor revdb_columnbynumber revdb_columncount revdb_columnisnull revdb_columnlengths revdb_columnnames revdb_columntypes revdb_commit revdb_connect revdb_connections revdb_connectionerr revdb_currentrecord revdb_cursorconnection revdb_cursorerr revdb_cursors revdb_dbtype revdb_disconnect revdb_execute revdb_iseof revdb_isbof revdb_movefirst revdb_movelast revdb_movenext revdb_moveprev revdb_query revdb_querylist revdb_recordcount revdb_rollback revdb_tablenames revGetDatabaseDriverPath revNumberOfRecords revOpenDatabase revOpenDatabases revQueryDatabase revQueryDatabaseBlob revQueryResult revQueryIsAtStart revQueryIsAtEnd revUnixFromMacPath revXMLAttribute revXMLAttributes revXMLAttributeValues revXMLChildContents revXMLChildNames revXMLCreateTreeFromFileWithNamespaces revXMLCreateTreeWithNamespaces revXMLDataFromXPathQuery revXMLEvaluateXPath revXMLFirstChild revXMLMatchingNode revXMLNextSibling revXMLNodeContents revXMLNumberOfChildren revXMLParent revXMLPreviousSibling revXMLRootNode revXMLRPC_CreateRequest revXMLRPC_Documents revXMLRPC_Error revXMLRPC_GetHost revXMLRPC_GetMethod revXMLRPC_GetParam revXMLText revXMLRPC_Execute revXMLRPC_GetParamCount revXMLRPC_GetParamNode revXMLRPC_GetParamType revXMLRPC_GetPath revXMLRPC_GetPort revXMLRPC_GetProtocol revXMLRPC_GetRequest revXMLRPC_GetResponse revXMLRPC_GetSocket revXMLTree revXMLTrees revXMLValidateDTD revZipDescribeItem revZipEnumerateItems revZipOpenArchives round sampVariance sec secs seconds sentenceOffset sha1Digest shell shortFilePath sin specialFolderPath sqrt standardDeviation statRound stdDev sum sysError systemVersion tan tempName textDecode textEncode tick ticks time to tokenOffset toLower toUpper transpose truewordOffset trunc uniDecode uniEncode upper URLDecode URLEncode URLStatus uuid value variableNames variance version waitDepth weekdayNames wordOffset xsltApplyStylesheet xsltApplyStylesheetFromFile xsltLoadStylesheet xsltLoadStylesheetFromFile add breakpoint cancel clear local variable file word line folder directory URL close socket process combine constant convert create new alias folder directory decrypt delete variable word line folder directory URL dispatch divide do encrypt filter get include intersect kill libURLDownloadToFile libURLFollowHttpRedirects libURLftpUpload libURLftpUploadFile libURLresetAll libUrlSetAuthCallback libURLSetCustomHTTPHeaders libUrlSetExpect100 libURLSetFTPListCommand libURLSetFTPMode libURLSetFTPStopTime libURLSetStatusCallback load multiply socket prepare process post seek rel relative read from process rename replace require resetAll resolve revAddXMLNode revAppendXML revCloseCursor revCloseDatabase revCommitDatabase revCopyFile revCopyFolder revCopyXMLNode revDeleteFolder revDeleteXMLNode revDeleteAllXMLTrees revDeleteXMLTree revExecuteSQL revGoURL revInsertXMLNode revMoveFolder revMoveToFirstRecord revMoveToLastRecord revMoveToNextRecord revMoveToPreviousRecord revMoveToRecord revMoveXMLNode revPutIntoXMLNode revRollBackDatabase revSetDatabaseDriverPath revSetXMLAttribute revXMLRPC_AddParam revXMLRPC_DeleteAllDocuments revXMLAddDTD revXMLRPC_Free revXMLRPC_FreeAll revXMLRPC_DeleteDocument revXMLRPC_DeleteParam revXMLRPC_SetHost revXMLRPC_SetMethod revXMLRPC_SetPort revXMLRPC_SetProtocol revXMLRPC_SetSocket revZipAddItemWithData revZipAddItemWithFile revZipAddUncompressedItemWithData revZipAddUncompressedItemWithFile revZipCancel revZipCloseArchive revZipDeleteItem revZipExtractItemToFile revZipExtractItemToVariable revZipSetProgressCallback revZipRenameItem revZipReplaceItemWithData revZipReplaceItemWithFile revZipOpenArchive send set sort split start stop subtract union unload wait write"},c:[r,{cN:"keyword",b:"\\bend\\sif\\b"},{cN:"function",bK:"function",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"function",b:"\\bend\\s+",e:"$",k:"end",c:[o,a]},{bK:"command on",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"meta",v:[{b:"<\\?(rev|lc|livecode)",r:10},{b:"<\\?"},{b:"\\?>"}]},e.ASM,e.QSM,e.BNM,e.CNM,a].concat(t),i:";$|^\\[|^="}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/livescript.js b/lib/highlight_js/assets/lang/livescript.js index 72340804fb6..b3227f89e64 100644 --- a/lib/highlight_js/assets/lang/livescript.js +++ b/lib/highlight_js/assets/lang/livescript.js @@ -1 +1 @@ -hljs.registerLanguage("livescript",function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger case default function var with then unless until loop of by when and or is isnt not it that otherwise from to til fallthrough super case default function var void const let enum export import native __hasProp __extends __slice __bind __indexOf",literal:"true false null undefined yes no on off it that void",built_in:"npm require console print module global window document"},s="[A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*",i=e.inherit(e.TM,{b:s}),n={cN:"subst",b:/#\{/,e:/}/,k:t},r={cN:"subst",b:/#[A-Za-z$_]/,e:/(?:\-[0-9A-Za-z$_]|[0-9A-Za-z$_])*/,k:t},c=[e.BNM,{cN:"number",b:"(\\b0[xX][a-fA-F0-9_]+)|(\\b\\d(\\d|_\\d)*(\\.(\\d(\\d|_\\d)*)?)?(_*[eE]([-+]\\d(_\\d|\\d)*)?)?[_a-z]*)",r:0,starts:{e:"(\\s*/)?",r:0}},{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,n,r]},{b:/"/,e:/"/,c:[e.BE,n,r]},{b:/\\/,e:/(\s|$)/,eE:!0}]},{cN:"pi",v:[{b:"//",e:"//[gim]*",c:[n,e.HCM]},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+s},{b:"``",e:"``",eB:!0,eE:!0,sL:"javascript"}];n.c=c;var a={cN:"params",b:"\\(",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(c)}]};return{aliases:["ls"],k:t,i:/\/\*/,c:c.concat([e.C("\\/\\*","\\*\\/"),e.HCM,{cN:"function",c:[i,a],rB:!0,v:[{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B\\->\\*?",e:"\\->\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?!?(\\(.*\\))?\\s*\\B[-~]{1,2}>\\*?",e:"[-~]{1,2}>\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B!?[-~]{1,2}>\\*?",e:"!?[-~]{1,2}>\\*?"}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{cN:"attribute",b:s+":",e:":",rB:!0,rE:!0,r:0}])}}); \ No newline at end of file +hljs.registerLanguage("livescript",function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger case default function var with then unless until loop of by when and or is isnt not it that otherwise from to til fallthrough super case default function var void const let enum export import native __hasProp __extends __slice __bind __indexOf",literal:"true false null undefined yes no on off it that void",built_in:"npm require console print module global window document"},s="[A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*",n=e.inherit(e.TM,{b:s}),i={cN:"subst",b:/#\{/,e:/}/,k:t},r={cN:"subst",b:/#[A-Za-z$_]/,e:/(?:\-[0-9A-Za-z$_]|[0-9A-Za-z$_])*/,k:t},c=[e.BNM,{cN:"number",b:"(\\b0[xX][a-fA-F0-9_]+)|(\\b\\d(\\d|_\\d)*(\\.(\\d(\\d|_\\d)*)?)?(_*[eE]([-+]\\d(_\\d|\\d)*)?)?[_a-z]*)",r:0,starts:{e:"(\\s*/)?",r:0}},{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,i,r]},{b:/"/,e:/"/,c:[e.BE,i,r]},{b:/\\/,e:/(\s|$)/,eE:!0}]},{cN:"regexp",v:[{b:"//",e:"//[gim]*",c:[i,e.HCM]},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+s},{b:"``",e:"``",eB:!0,eE:!0,sL:"javascript"}];i.c=c;var a={cN:"params",b:"\\(",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(c)}]};return{aliases:["ls"],k:t,i:/\/\*/,c:c.concat([e.C("\\/\\*","\\*\\/"),e.HCM,{cN:"function",c:[n,a],rB:!0,v:[{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B\\->\\*?",e:"\\->\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?!?(\\(.*\\))?\\s*\\B[-~]{1,2}>\\*?",e:"[-~]{1,2}>\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B!?[-~]{1,2}>\\*?",e:"!?[-~]{1,2}>\\*?"}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[n]},n]},{b:s+":",e:":",rB:!0,rE:!0,r:0}])}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/makefile.js b/lib/highlight_js/assets/lang/makefile.js index 8575486c0cb..a6060420ea5 100644 --- a/lib/highlight_js/assets/lang/makefile.js +++ b/lib/highlight_js/assets/lang/makefile.js @@ -1 +1 @@ -hljs.registerLanguage("makefile",function(e){var a={cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]};return{aliases:["mk","mak"],c:[e.HCM,{b:/^\w+\s*\W*=/,rB:!0,r:0,starts:{cN:"constant",e:/\s*\W*=/,eE:!0,starts:{e:/$/,r:0,c:[a]}}},{cN:"title",b:/^[\w]+:\s*$/},{cN:"phony",b:/^\.PHONY:/,e:/$/,k:".PHONY",l:/[\.\w]+/},{b:/^\t+/,e:/$/,r:0,c:[e.QSM,a]}]}}); \ No newline at end of file +hljs.registerLanguage("makefile",function(e){var a={cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]};return{aliases:["mk","mak"],c:[e.HCM,{b:/^\w+\s*\W*=/,rB:!0,r:0,starts:{e:/\s*\W*=/,eE:!0,starts:{e:/$/,r:0,c:[a]}}},{cN:"section",b:/^[\w]+:\s*$/},{cN:"meta",b:/^\.PHONY:/,e:/$/,k:{"meta-keyword":".PHONY"},l:/[\.\w]+/},{b:/^\t+/,e:/$/,r:0,c:[e.QSM,a]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/markdown.js b/lib/highlight_js/assets/lang/markdown.js index 765a55c0306..54d98310807 100644 --- a/lib/highlight_js/assets/lang/markdown.js +++ b/lib/highlight_js/assets/lang/markdown.js @@ -1 +1 @@ -hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"header",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{cN:"horizontal_rule",b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"link_label",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link_url",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"link_reference",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:"^\\[.+\\]:",rB:!0,c:[{cN:"link_reference",b:"\\[",e:"\\]:",eB:!0,eE:!0,starts:{cN:"link_url",e:"$"}}]}]}}); \ No newline at end of file +hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:"^\\[.+\\]:",rB:!0,c:[{cN:"symbol",b:"\\[",e:"\\]:",eB:!0,eE:!0,starts:{cN:"link",e:"$"}}]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/mathematica.js b/lib/highlight_js/assets/lang/mathematica.js index 4e3e612aa5a..d5f6b2ec04c 100644 --- a/lib/highlight_js/assets/lang/mathematica.js +++ b/lib/highlight_js/assets/lang/mathematica.js @@ -1,2 +1,2 @@ hljs.registerLanguage("mathematica",function(e){return{aliases:["mma"],l:"(\\$|\\b)"+e.IR+"\\b",k:"AbelianGroup Abort AbortKernels AbortProtect Above Abs Absolute AbsoluteCorrelation AbsoluteCorrelationFunction AbsoluteCurrentValue AbsoluteDashing AbsoluteFileName AbsoluteOptions AbsolutePointSize AbsoluteThickness AbsoluteTime AbsoluteTiming AccountingForm Accumulate Accuracy AccuracyGoal ActionDelay ActionMenu ActionMenuBox ActionMenuBoxOptions Active ActiveItem ActiveStyle AcyclicGraphQ AddOnHelpPath AddTo AdjacencyGraph AdjacencyList AdjacencyMatrix AdjustmentBox AdjustmentBoxOptions AdjustTimeSeriesForecast AffineTransform After AiryAi AiryAiPrime AiryAiZero AiryBi AiryBiPrime AiryBiZero AlgebraicIntegerQ AlgebraicNumber AlgebraicNumberDenominator AlgebraicNumberNorm AlgebraicNumberPolynomial AlgebraicNumberTrace AlgebraicRules AlgebraicRulesData Algebraics AlgebraicUnitQ Alignment AlignmentMarker AlignmentPoint All AllowedDimensions AllowGroupClose AllowInlineCells AllowKernelInitialization AllowReverseGroupClose AllowScriptLevelChange AlphaChannel AlternatingGroup AlternativeHypothesis Alternatives AmbientLight Analytic AnchoredSearch And AndersonDarlingTest AngerJ AngleBracket AngularGauge Animate AnimationCycleOffset AnimationCycleRepetitions AnimationDirection AnimationDisplayTime AnimationRate AnimationRepetitions AnimationRunning Animator AnimatorBox AnimatorBoxOptions AnimatorElements Annotation Annuity AnnuityDue Antialiasing Antisymmetric Apart ApartSquareFree Appearance AppearanceElements AppellF1 Append AppendTo Apply ArcCos ArcCosh ArcCot ArcCoth ArcCsc ArcCsch ArcSec ArcSech ArcSin ArcSinDistribution ArcSinh ArcTan ArcTanh Arg ArgMax ArgMin ArgumentCountQ ARIMAProcess ArithmeticGeometricMean ARMAProcess ARProcess Array ArrayComponents ArrayDepth ArrayFlatten ArrayPad ArrayPlot ArrayQ ArrayReshape ArrayRules Arrays Arrow Arrow3DBox ArrowBox Arrowheads AspectRatio AspectRatioFixed Assert Assuming Assumptions AstronomicalData Asynchronous AsynchronousTaskObject AsynchronousTasks AtomQ Attributes AugmentedSymmetricPolynomial AutoAction AutoDelete AutoEvaluateEvents AutoGeneratedPackage AutoIndent AutoIndentSpacings AutoItalicWords AutoloadPath AutoMatch Automatic AutomaticImageSize AutoMultiplicationSymbol AutoNumberFormatting AutoOpenNotebooks AutoOpenPalettes AutorunSequencing AutoScaling AutoScroll AutoSpacing AutoStyleOptions AutoStyleWords Axes AxesEdge AxesLabel AxesOrigin AxesStyle Axis BabyMonsterGroupB Back Background BackgroundTasksSettings Backslash Backsubstitution Backward Band BandpassFilter BandstopFilter BarabasiAlbertGraphDistribution BarChart BarChart3D BarLegend BarlowProschanImportance BarnesG BarOrigin BarSpacing BartlettHannWindow BartlettWindow BaseForm Baseline BaselinePosition BaseStyle BatesDistribution BattleLemarieWavelet Because BeckmannDistribution Beep Before Begin BeginDialogPacket BeginFrontEndInteractionPacket BeginPackage BellB BellY Below BenfordDistribution BeniniDistribution BenktanderGibratDistribution BenktanderWeibullDistribution BernoulliB BernoulliDistribution BernoulliGraphDistribution BernoulliProcess BernsteinBasis BesselFilterModel BesselI BesselJ BesselJZero BesselK BesselY BesselYZero Beta BetaBinomialDistribution BetaDistribution BetaNegativeBinomialDistribution BetaPrimeDistribution BetaRegularized BetweennessCentrality BezierCurve BezierCurve3DBox BezierCurve3DBoxOptions BezierCurveBox BezierCurveBoxOptions BezierFunction BilateralFilter Binarize BinaryFormat BinaryImageQ BinaryRead BinaryReadList BinaryWrite BinCounts BinLists Binomial BinomialDistribution BinomialProcess BinormalDistribution BiorthogonalSplineWavelet BipartiteGraphQ BirnbaumImportance BirnbaumSaundersDistribution BitAnd BitClear BitGet BitLength BitNot BitOr BitSet BitShiftLeft BitShiftRight BitXor Black BlackmanHarrisWindow BlackmanNuttallWindow BlackmanWindow Blank BlankForm BlankNullSequence BlankSequence Blend Block BlockRandom BlomqvistBeta BlomqvistBetaTest Blue Blur BodePlot BohmanWindow Bold Bookmarks Boole BooleanConsecutiveFunction BooleanConvert BooleanCountingFunction BooleanFunction BooleanGraph BooleanMaxterms BooleanMinimize BooleanMinterms Booleans BooleanTable BooleanVariables BorderDimensions BorelTannerDistribution Bottom BottomHatTransform BoundaryStyle Bounds Box BoxBaselineShift BoxData BoxDimensions Boxed Boxes BoxForm BoxFormFormatTypes BoxFrame BoxID BoxMargins BoxMatrix BoxRatios BoxRotation BoxRotationPoint BoxStyle BoxWhiskerChart Bra BracketingBar BraKet BrayCurtisDistance BreadthFirstScan Break Brown BrownForsytheTest BrownianBridgeProcess BrowserCategory BSplineBasis BSplineCurve BSplineCurve3DBox BSplineCurveBox BSplineCurveBoxOptions BSplineFunction BSplineSurface BSplineSurface3DBox BubbleChart BubbleChart3D BubbleScale BubbleSizes BulletGauge BusinessDayQ ButterflyGraph ButterworthFilterModel Button ButtonBar ButtonBox ButtonBoxOptions ButtonCell ButtonContents ButtonData ButtonEvaluator ButtonExpandable ButtonFrame ButtonFunction ButtonMargins ButtonMinHeight ButtonNote ButtonNotebook ButtonSource ButtonStyle ButtonStyleMenuListing Byte ByteCount ByteOrdering C CachedValue CacheGraphics CalendarData CalendarType CallPacket CanberraDistance Cancel CancelButton CandlestickChart Cap CapForm CapitalDifferentialD CardinalBSplineBasis CarmichaelLambda Cases Cashflow Casoratian Catalan CatalanNumber Catch CauchyDistribution CauchyWindow CayleyGraph CDF CDFDeploy CDFInformation CDFWavelet Ceiling Cell CellAutoOverwrite CellBaseline CellBoundingBox CellBracketOptions CellChangeTimes CellContents CellContext CellDingbat CellDynamicExpression CellEditDuplicate CellElementsBoundingBox CellElementSpacings CellEpilog CellEvaluationDuplicate CellEvaluationFunction CellEventActions CellFrame CellFrameColor CellFrameLabelMargins CellFrameLabels CellFrameMargins CellGroup CellGroupData CellGrouping CellGroupingRules CellHorizontalScrolling CellID CellLabel CellLabelAutoDelete CellLabelMargins CellLabelPositioning CellMargins CellObject CellOpen CellPrint CellProlog Cells CellSize CellStyle CellTags CellularAutomaton CensoredDistribution Censoring Center CenterDot CentralMoment CentralMomentGeneratingFunction CForm ChampernowneNumber ChanVeseBinarize Character CharacterEncoding CharacterEncodingsPath CharacteristicFunction CharacteristicPolynomial CharacterRange Characters ChartBaseStyle ChartElementData ChartElementDataFunction ChartElementFunction ChartElements ChartLabels ChartLayout ChartLegends ChartStyle Chebyshev1FilterModel Chebyshev2FilterModel ChebyshevDistance ChebyshevT ChebyshevU Check CheckAbort CheckAll Checkbox CheckboxBar CheckboxBox CheckboxBoxOptions ChemicalData ChessboardDistance ChiDistribution ChineseRemainder ChiSquareDistribution ChoiceButtons ChoiceDialog CholeskyDecomposition Chop Circle CircleBox CircleDot CircleMinus CirclePlus CircleTimes CirculantGraph CityData Clear ClearAll ClearAttributes ClearSystemCache ClebschGordan ClickPane Clip ClipboardNotebook ClipFill ClippingStyle ClipPlanes ClipRange Clock ClockGauge ClockwiseContourIntegral Close Closed CloseKernels ClosenessCentrality Closing ClosingAutoSave ClosingEvent ClusteringComponents CMYKColor Coarse Coefficient CoefficientArrays CoefficientDomain CoefficientList CoefficientRules CoifletWavelet Collect Colon ColonForm ColorCombine ColorConvert ColorData ColorDataFunction ColorFunction ColorFunctionScaling Colorize ColorNegate ColorOutput ColorProfileData ColorQuantize ColorReplace ColorRules ColorSelectorSettings ColorSeparate ColorSetter ColorSetterBox ColorSetterBoxOptions ColorSlider ColorSpace Column ColumnAlignments ColumnBackgrounds ColumnForm ColumnLines ColumnsEqual ColumnSpacings ColumnWidths CommonDefaultFormatTypes Commonest CommonestFilter CommonUnits CommunityBoundaryStyle CommunityGraphPlot CommunityLabels CommunityRegionStyle CompatibleUnitQ CompilationOptions CompilationTarget Compile Compiled CompiledFunction Complement CompleteGraph CompleteGraphQ CompleteKaryTree CompletionsListPacket Complex Complexes ComplexExpand ComplexInfinity ComplexityFunction ComponentMeasurements ComponentwiseContextMenu Compose ComposeList ComposeSeries Composition CompoundExpression CompoundPoissonDistribution CompoundPoissonProcess CompoundRenewalProcess Compress CompressedData Condition ConditionalExpression Conditioned Cone ConeBox ConfidenceLevel ConfidenceRange ConfidenceTransform ConfigurationPath Congruent Conjugate ConjugateTranspose Conjunction Connect ConnectedComponents ConnectedGraphQ ConnesWindow ConoverTest ConsoleMessage ConsoleMessagePacket ConsolePrint Constant ConstantArray Constants ConstrainedMax ConstrainedMin ContentPadding ContentsBoundingBox ContentSelectable ContentSize Context ContextMenu Contexts ContextToFilename ContextToFileName Continuation Continue ContinuedFraction ContinuedFractionK ContinuousAction ContinuousMarkovProcess ContinuousTimeModelQ ContinuousWaveletData ContinuousWaveletTransform ContourDetect ContourGraphics ContourIntegral ContourLabels ContourLines ContourPlot ContourPlot3D Contours ContourShading ContourSmoothing ContourStyle ContraharmonicMean Control ControlActive ControlAlignment ControllabilityGramian ControllabilityMatrix ControllableDecomposition ControllableModelQ ControllerDuration ControllerInformation ControllerInformationData ControllerLinking ControllerManipulate ControllerMethod ControllerPath ControllerState ControlPlacement ControlsRendering ControlType Convergents ConversionOptions ConversionRules ConvertToBitmapPacket ConvertToPostScript ConvertToPostScriptPacket Convolve ConwayGroupCo1 ConwayGroupCo2 ConwayGroupCo3 CoordinateChartData CoordinatesToolOptions CoordinateTransform CoordinateTransformData CoprimeQ Coproduct CopulaDistribution Copyable CopyDirectory CopyFile CopyTag CopyToClipboard CornerFilter CornerNeighbors Correlation CorrelationDistance CorrelationFunction CorrelationTest Cos Cosh CoshIntegral CosineDistance CosineWindow CosIntegral Cot Coth Count CounterAssignments CounterBox CounterBoxOptions CounterClockwiseContourIntegral CounterEvaluator CounterFunction CounterIncrements CounterStyle CounterStyleMenuListing CountRoots CountryData Covariance CovarianceEstimatorFunction CovarianceFunction CoxianDistribution CoxIngersollRossProcess CoxModel CoxModelFit CramerVonMisesTest CreateArchive CreateDialog CreateDirectory CreateDocument CreateIntermediateDirectories CreatePalette CreatePalettePacket CreateScheduledTask CreateTemporary CreateWindow CriticalityFailureImportance CriticalitySuccessImportance CriticalSection Cross CrossingDetect CrossMatrix Csc Csch CubeRoot Cubics Cuboid CuboidBox Cumulant CumulantGeneratingFunction Cup CupCap Curl CurlyDoubleQuote CurlyQuote CurrentImage CurrentlySpeakingPacket CurrentValue CurvatureFlowFilter CurveClosed Cyan CycleGraph CycleIndexPolynomial Cycles CyclicGroup Cyclotomic Cylinder CylinderBox CylindricalDecomposition D DagumDistribution DamerauLevenshteinDistance DampingFactor Darker Dashed Dashing DataCompression DataDistribution DataRange DataReversed Date DateDelimiters DateDifference DateFunction DateList DateListLogPlot DateListPlot DatePattern DatePlus DateRange DateString DateTicksFormat DaubechiesWavelet DavisDistribution DawsonF DayCount DayCountConvention DayMatchQ DayName DayPlus DayRange DayRound DeBruijnGraph Debug DebugTag Decimal DeclareKnownSymbols DeclarePackage Decompose Decrement DedekindEta Default DefaultAxesStyle DefaultBaseStyle DefaultBoxStyle DefaultButton DefaultColor DefaultControlPlacement DefaultDuplicateCellStyle DefaultDuration DefaultElement DefaultFaceGridsStyle DefaultFieldHintStyle DefaultFont DefaultFontProperties DefaultFormatType DefaultFormatTypeForStyle DefaultFrameStyle DefaultFrameTicksStyle DefaultGridLinesStyle DefaultInlineFormatType DefaultInputFormatType DefaultLabelStyle DefaultMenuStyle DefaultNaturalLanguage DefaultNewCellStyle DefaultNewInlineCellStyle DefaultNotebook DefaultOptions DefaultOutputFormatType DefaultStyle DefaultStyleDefinitions DefaultTextFormatType DefaultTextInlineFormatType DefaultTicksStyle DefaultTooltipStyle DefaultValues Defer DefineExternal DefineInputStreamMethod DefineOutputStreamMethod Definition Degree DegreeCentrality DegreeGraphDistribution DegreeLexicographic DegreeReverseLexicographic Deinitialization Del Deletable Delete DeleteBorderComponents DeleteCases DeleteContents DeleteDirectory DeleteDuplicates DeleteFile DeleteSmallComponents DeleteWithContents DeletionWarning Delimiter DelimiterFlashTime DelimiterMatching Delimiters Denominator DensityGraphics DensityHistogram DensityPlot DependentVariables Deploy Deployed Depth DepthFirstScan Derivative DerivativeFilter DescriptorStateSpace DesignMatrix Det DGaussianWavelet DiacriticalPositioning Diagonal DiagonalMatrix Dialog DialogIndent DialogInput DialogLevel DialogNotebook DialogProlog DialogReturn DialogSymbols Diamond DiamondMatrix DiceDissimilarity DictionaryLookup DifferenceDelta DifferenceOrder DifferenceRoot DifferenceRootReduce Differences DifferentialD DifferentialRoot DifferentialRootReduce DifferentiatorFilter DigitBlock DigitBlockMinimum DigitCharacter DigitCount DigitQ DihedralGroup Dilation Dimensions DiracComb DiracDelta DirectedEdge DirectedEdges DirectedGraph DirectedGraphQ DirectedInfinity Direction Directive Directory DirectoryName DirectoryQ DirectoryStack DirichletCharacter DirichletConvolve DirichletDistribution DirichletL DirichletTransform DirichletWindow DisableConsolePrintPacket DiscreteChirpZTransform DiscreteConvolve DiscreteDelta DiscreteHadamardTransform DiscreteIndicator DiscreteLQEstimatorGains DiscreteLQRegulatorGains DiscreteLyapunovSolve DiscreteMarkovProcess DiscretePlot DiscretePlot3D DiscreteRatio DiscreteRiccatiSolve DiscreteShift DiscreteTimeModelQ DiscreteUniformDistribution DiscreteVariables DiscreteWaveletData DiscreteWaveletPacketTransform DiscreteWaveletTransform Discriminant Disjunction Disk DiskBox DiskMatrix Dispatch DispersionEstimatorFunction Display DisplayAllSteps DisplayEndPacket DisplayFlushImagePacket DisplayForm DisplayFunction DisplayPacket DisplayRules DisplaySetSizePacket DisplayString DisplayTemporary DisplayWith DisplayWithRef DisplayWithVariable DistanceFunction DistanceTransform Distribute Distributed DistributedContexts DistributeDefinitions DistributionChart DistributionDomain DistributionFitTest DistributionParameterAssumptions DistributionParameterQ Dithering Div Divergence Divide DivideBy Dividers Divisible Divisors DivisorSigma DivisorSum DMSList DMSString Do DockedCells DocumentNotebook DominantColors DOSTextFormat Dot DotDashed DotEqual Dotted DoubleBracketingBar DoubleContourIntegral DoubleDownArrow DoubleLeftArrow DoubleLeftRightArrow DoubleLeftTee DoubleLongLeftArrow DoubleLongLeftRightArrow DoubleLongRightArrow DoubleRightArrow DoubleRightTee DoubleUpArrow DoubleUpDownArrow DoubleVerticalBar DoublyInfinite Down DownArrow DownArrowBar DownArrowUpArrow DownLeftRightVector DownLeftTeeVector DownLeftVector DownLeftVectorBar DownRightTeeVector DownRightVector DownRightVectorBar Downsample DownTee DownTeeArrow DownValues DragAndDrop DrawEdges DrawFrontFaces DrawHighlighted Drop DSolve Dt DualLinearProgramming DualSystemsModel DumpGet DumpSave DuplicateFreeQ Dynamic DynamicBox DynamicBoxOptions DynamicEvaluationTimeout DynamicLocation DynamicModule DynamicModuleBox DynamicModuleBoxOptions DynamicModuleParent DynamicModuleValues DynamicName DynamicNamespace DynamicReference DynamicSetting DynamicUpdating DynamicWrapper DynamicWrapperBox DynamicWrapperBoxOptions E EccentricityCentrality EdgeAdd EdgeBetweennessCentrality EdgeCapacity EdgeCapForm EdgeColor EdgeConnectivity EdgeCost EdgeCount EdgeCoverQ EdgeDashing EdgeDelete EdgeDetect EdgeForm EdgeIndex EdgeJoinForm EdgeLabeling EdgeLabels EdgeLabelStyle EdgeList EdgeOpacity EdgeQ EdgeRenderingFunction EdgeRules EdgeShapeFunction EdgeStyle EdgeThickness EdgeWeight Editable EditButtonSettings EditCellTagsSettings EditDistance EffectiveInterest Eigensystem Eigenvalues EigenvectorCentrality Eigenvectors Element ElementData Eliminate EliminationOrder EllipticE EllipticExp EllipticExpPrime EllipticF EllipticFilterModel EllipticK EllipticLog EllipticNomeQ EllipticPi EllipticReducedHalfPeriods EllipticTheta EllipticThetaPrime EmitSound EmphasizeSyntaxErrors EmpiricalDistribution Empty EmptyGraphQ EnableConsolePrintPacket Enabled Encode End EndAdd EndDialogPacket EndFrontEndInteractionPacket EndOfFile EndOfLine EndOfString EndPackage EngineeringForm Enter EnterExpressionPacket EnterTextPacket Entropy EntropyFilter Environment Epilog Equal EqualColumns EqualRows EqualTilde EquatedTo Equilibrium EquirippleFilterKernel Equivalent Erf Erfc Erfi ErlangB ErlangC ErlangDistribution Erosion ErrorBox ErrorBoxOptions ErrorNorm ErrorPacket ErrorsDialogSettings EstimatedDistribution EstimatedProcess EstimatorGains EstimatorRegulator EuclideanDistance EulerE EulerGamma EulerianGraphQ EulerPhi Evaluatable Evaluate Evaluated EvaluatePacket EvaluationCell EvaluationCompletionAction EvaluationElements EvaluationMode EvaluationMonitor EvaluationNotebook EvaluationObject EvaluationOrder Evaluator EvaluatorNames EvenQ EventData EventEvaluator EventHandler EventHandlerTag EventLabels ExactBlackmanWindow ExactNumberQ ExactRootIsolation ExampleData Except ExcludedForms ExcludePods Exclusions ExclusionsStyle Exists Exit ExitDialog Exp Expand ExpandAll ExpandDenominator ExpandFileName ExpandNumerator Expectation ExpectationE ExpectedValue ExpGammaDistribution ExpIntegralE ExpIntegralEi Exponent ExponentFunction ExponentialDistribution ExponentialFamily ExponentialGeneratingFunction ExponentialMovingAverage ExponentialPowerDistribution ExponentPosition ExponentStep Export ExportAutoReplacements ExportPacket ExportString Expression ExpressionCell ExpressionPacket ExpToTrig ExtendedGCD Extension ExtentElementFunction ExtentMarkers ExtentSize ExternalCall ExternalDataCharacterEncoding Extract ExtractArchive ExtremeValueDistribution FaceForm FaceGrids FaceGridsStyle Factor FactorComplete Factorial Factorial2 FactorialMoment FactorialMomentGeneratingFunction FactorialPower FactorInteger FactorList FactorSquareFree FactorSquareFreeList FactorTerms FactorTermsList Fail FailureDistribution False FARIMAProcess FEDisableConsolePrintPacket FeedbackSector FeedbackSectorStyle FeedbackType FEEnableConsolePrintPacket Fibonacci FieldHint FieldHintStyle FieldMasked FieldSize File FileBaseName FileByteCount FileDate FileExistsQ FileExtension FileFormat FileHash FileInformation FileName FileNameDepth FileNameDialogSettings FileNameDrop FileNameJoin FileNames FileNameSetter FileNameSplit FileNameTake FilePrint FileType FilledCurve FilledCurveBox Filling FillingStyle FillingTransform FilterRules FinancialBond FinancialData FinancialDerivative FinancialIndicator Find FindArgMax FindArgMin FindClique FindClusters FindCurvePath FindDistributionParameters FindDivisions FindEdgeCover FindEdgeCut FindEulerianCycle FindFaces FindFile FindFit FindGeneratingFunction FindGeoLocation FindGeometricTransform FindGraphCommunities FindGraphIsomorphism FindGraphPartition FindHamiltonianCycle FindIndependentEdgeSet FindIndependentVertexSet FindInstance FindIntegerNullVector FindKClan FindKClique FindKClub FindKPlex FindLibrary FindLinearRecurrence FindList FindMaximum FindMaximumFlow FindMaxValue FindMinimum FindMinimumCostFlow FindMinimumCut FindMinValue FindPermutation FindPostmanTour FindProcessParameters FindRoot FindSequenceFunction FindSettings FindShortestPath FindShortestTour FindThreshold FindVertexCover FindVertexCut Fine FinishDynamic FiniteAbelianGroupCount FiniteGroupCount FiniteGroupData First FirstPassageTimeDistribution FischerGroupFi22 FischerGroupFi23 FischerGroupFi24Prime FisherHypergeometricDistribution FisherRatioTest FisherZDistribution Fit FitAll FittedModel FixedPoint FixedPointList FlashSelection Flat Flatten FlattenAt FlatTopWindow FlipView Floor FlushPrintOutputPacket Fold FoldList Font FontColor FontFamily FontForm FontName FontOpacity FontPostScriptName FontProperties FontReencoding FontSize FontSlant FontSubstitutions FontTracking FontVariations FontWeight For ForAll Format FormatRules FormatType FormatTypeAutoConvert FormatValues FormBox FormBoxOptions FortranForm Forward ForwardBackward Fourier FourierCoefficient FourierCosCoefficient FourierCosSeries FourierCosTransform FourierDCT FourierDCTFilter FourierDCTMatrix FourierDST FourierDSTMatrix FourierMatrix FourierParameters FourierSequenceTransform FourierSeries FourierSinCoefficient FourierSinSeries FourierSinTransform FourierTransform FourierTrigSeries FractionalBrownianMotionProcess FractionalPart FractionBox FractionBoxOptions FractionLine Frame FrameBox FrameBoxOptions Framed FrameInset FrameLabel Frameless FrameMargins FrameStyle FrameTicks FrameTicksStyle FRatioDistribution FrechetDistribution FreeQ FrequencySamplingFilterKernel FresnelC FresnelS Friday FrobeniusNumber FrobeniusSolve FromCharacterCode FromCoefficientRules FromContinuedFraction FromDate FromDigits FromDMS Front FrontEndDynamicExpression FrontEndEventActions FrontEndExecute FrontEndObject FrontEndResource FrontEndResourceString FrontEndStackSize FrontEndToken FrontEndTokenExecute FrontEndValueCache FrontEndVersion FrontFaceColor FrontFaceOpacity Full FullAxes FullDefinition FullForm FullGraphics FullOptions FullSimplify Function FunctionExpand FunctionInterpolation FunctionSpace FussellVeselyImportance GaborFilter GaborMatrix GaborWavelet GainMargins GainPhaseMargins Gamma GammaDistribution GammaRegularized GapPenalty Gather GatherBy GaugeFaceElementFunction GaugeFaceStyle GaugeFrameElementFunction GaugeFrameSize GaugeFrameStyle GaugeLabels GaugeMarkers GaugeStyle GaussianFilter GaussianIntegers GaussianMatrix GaussianWindow GCD GegenbauerC General GeneralizedLinearModelFit GenerateConditions GeneratedCell GeneratedParameters GeneratingFunction Generic GenericCylindricalDecomposition GenomeData GenomeLookup GeodesicClosing GeodesicDilation GeodesicErosion GeodesicOpening GeoDestination GeodesyData GeoDirection GeoDistance GeoGridPosition GeometricBrownianMotionProcess GeometricDistribution GeometricMean GeometricMeanFilter GeometricTransformation GeometricTransformation3DBox GeometricTransformation3DBoxOptions GeometricTransformationBox GeometricTransformationBoxOptions GeoPosition GeoPositionENU GeoPositionXYZ GeoProjectionData GestureHandler GestureHandlerTag Get GetBoundingBoxSizePacket GetContext GetEnvironment GetFileName GetFrontEndOptionsDataPacket GetLinebreakInformationPacket GetMenusPacket GetPageBreakInformationPacket Glaisher GlobalClusteringCoefficient GlobalPreferences GlobalSession Glow GoldenRatio GompertzMakehamDistribution GoodmanKruskalGamma GoodmanKruskalGammaTest Goto Grad Gradient GradientFilter GradientOrientationFilter Graph GraphAssortativity GraphCenter GraphComplement GraphData GraphDensity GraphDiameter GraphDifference GraphDisjointUnion GraphDistance GraphDistanceMatrix GraphElementData GraphEmbedding GraphHighlight GraphHighlightStyle GraphHub Graphics Graphics3D Graphics3DBox Graphics3DBoxOptions GraphicsArray GraphicsBaseline GraphicsBox GraphicsBoxOptions GraphicsColor GraphicsColumn GraphicsComplex GraphicsComplex3DBox GraphicsComplex3DBoxOptions GraphicsComplexBox GraphicsComplexBoxOptions GraphicsContents GraphicsData GraphicsGrid GraphicsGridBox GraphicsGroup GraphicsGroup3DBox GraphicsGroup3DBoxOptions GraphicsGroupBox GraphicsGroupBoxOptions GraphicsGrouping GraphicsHighlightColor GraphicsRow GraphicsSpacing GraphicsStyle GraphIntersection GraphLayout GraphLinkEfficiency GraphPeriphery GraphPlot GraphPlot3D GraphPower GraphPropertyDistribution GraphQ GraphRadius GraphReciprocity GraphRoot GraphStyle GraphUnion Gray GrayLevel GreatCircleDistance Greater GreaterEqual GreaterEqualLess GreaterFullEqual GreaterGreater GreaterLess GreaterSlantEqual GreaterTilde Green Grid GridBaseline GridBox GridBoxAlignment GridBoxBackground GridBoxDividers GridBoxFrame GridBoxItemSize GridBoxItemStyle GridBoxOptions GridBoxSpacings GridCreationSettings GridDefaultElement GridElementStyleOptions GridFrame GridFrameMargins GridGraph GridLines GridLinesStyle GroebnerBasis GroupActionBase GroupCentralizer GroupElementFromWord GroupElementPosition GroupElementQ GroupElements GroupElementToWord GroupGenerators GroupMultiplicationTable GroupOrbits GroupOrder GroupPageBreakWithin GroupSetwiseStabilizer GroupStabilizer GroupStabilizerChain Gudermannian GumbelDistribution HaarWavelet HadamardMatrix HalfNormalDistribution HamiltonianGraphQ HammingDistance HammingWindow HankelH1 HankelH2 HankelMatrix HannPoissonWindow HannWindow HaradaNortonGroupHN HararyGraph HarmonicMean HarmonicMeanFilter HarmonicNumber Hash HashTable Haversine HazardFunction Head HeadCompose Heads HeavisideLambda HeavisidePi HeavisideTheta HeldGroupHe HeldPart HelpBrowserLookup HelpBrowserNotebook HelpBrowserSettings HermiteDecomposition HermiteH HermitianMatrixQ HessenbergDecomposition Hessian HexadecimalCharacter Hexahedron HexahedronBox HexahedronBoxOptions HiddenSurface HighlightGraph HighlightImage HighpassFilter HigmanSimsGroupHS HilbertFilter HilbertMatrix Histogram Histogram3D HistogramDistribution HistogramList HistogramTransform HistogramTransformInterpolation HitMissTransform HITSCentrality HodgeDual HoeffdingD HoeffdingDTest Hold HoldAll HoldAllComplete HoldComplete HoldFirst HoldForm HoldPattern HoldRest HolidayCalendar HomeDirectory HomePage Horizontal HorizontalForm HorizontalGauge HorizontalScrollPosition HornerForm HotellingTSquareDistribution HoytDistribution HTMLSave Hue HumpDownHump HumpEqual HurwitzLerchPhi HurwitzZeta HyperbolicDistribution HypercubeGraph HyperexponentialDistribution Hyperfactorial Hypergeometric0F1 Hypergeometric0F1Regularized Hypergeometric1F1 Hypergeometric1F1Regularized Hypergeometric2F1 Hypergeometric2F1Regularized HypergeometricDistribution HypergeometricPFQ HypergeometricPFQRegularized HypergeometricU Hyperlink HyperlinkCreationSettings Hyphenation HyphenationOptions HypoexponentialDistribution HypothesisTestData I Identity IdentityMatrix If IgnoreCase Im Image Image3D Image3DSlices ImageAccumulate ImageAdd ImageAdjust ImageAlign ImageApply ImageAspectRatio ImageAssemble ImageCache ImageCacheValid ImageCapture ImageChannels ImageClip ImageColorSpace ImageCompose ImageConvolve ImageCooccurrence ImageCorners ImageCorrelate ImageCorrespondingPoints ImageCrop ImageData ImageDataPacket ImageDeconvolve ImageDemosaic ImageDifference ImageDimensions ImageDistance ImageEffect ImageFeatureTrack ImageFileApply ImageFileFilter ImageFileScan ImageFilter ImageForestingComponents ImageForwardTransformation ImageHistogram ImageKeypoints ImageLevels ImageLines ImageMargins ImageMarkers ImageMeasurements ImageMultiply ImageOffset ImagePad ImagePadding ImagePartition ImagePeriodogram ImagePerspectiveTransformation ImageQ ImageRangeCache ImageReflect ImageRegion ImageResize ImageResolution ImageRotate ImageRotated ImageScaled ImageScan ImageSize ImageSizeAction ImageSizeCache ImageSizeMultipliers ImageSizeRaw ImageSubtract ImageTake ImageTransformation ImageTrim ImageType ImageValue ImageValuePositions Implies Import ImportAutoReplacements ImportString ImprovementImportance In IncidenceGraph IncidenceList IncidenceMatrix IncludeConstantBasis IncludeFileExtension IncludePods IncludeSingularTerm Increment Indent IndentingNewlineSpacings IndentMaxFraction IndependenceTest IndependentEdgeSetQ IndependentUnit IndependentVertexSetQ Indeterminate IndexCreationOptions Indexed IndexGraph IndexTag Inequality InexactNumberQ InexactNumbers Infinity Infix Information Inherited InheritScope Initialization InitializationCell InitializationCellEvaluation InitializationCellWarning InlineCounterAssignments InlineCounterIncrements InlineRules Inner Inpaint Input InputAliases InputAssumptions InputAutoReplacements InputField InputFieldBox InputFieldBoxOptions InputForm InputGrouping InputNamePacket InputNotebook InputPacket InputSettings InputStream InputString InputStringPacket InputToBoxFormPacket Insert InsertionPointObject InsertResults Inset Inset3DBox Inset3DBoxOptions InsetBox InsetBoxOptions Install InstallService InString Integer IntegerDigits IntegerExponent IntegerLength IntegerPart IntegerPartitions IntegerQ Integers IntegerString Integral Integrate Interactive InteractiveTradingChart Interlaced Interleaving InternallyBalancedDecomposition InterpolatingFunction InterpolatingPolynomial Interpolation InterpolationOrder InterpolationPoints InterpolationPrecision Interpretation InterpretationBox InterpretationBoxOptions InterpretationFunction InterpretTemplate InterquartileRange Interrupt InterruptSettings Intersection Interval IntervalIntersection IntervalMemberQ IntervalUnion Inverse InverseBetaRegularized InverseCDF InverseChiSquareDistribution InverseContinuousWaveletTransform InverseDistanceTransform InverseEllipticNomeQ InverseErf InverseErfc InverseFourier InverseFourierCosTransform InverseFourierSequenceTransform InverseFourierSinTransform InverseFourierTransform InverseFunction InverseFunctions InverseGammaDistribution InverseGammaRegularized InverseGaussianDistribution InverseGudermannian InverseHaversine InverseJacobiCD InverseJacobiCN InverseJacobiCS InverseJacobiDC InverseJacobiDN InverseJacobiDS InverseJacobiNC InverseJacobiND InverseJacobiNS InverseJacobiSC InverseJacobiSD InverseJacobiSN InverseLaplaceTransform InversePermutation InverseRadon InverseSeries InverseSurvivalFunction InverseWaveletTransform InverseWeierstrassP InverseZTransform Invisible InvisibleApplication InvisibleTimes IrreduciblePolynomialQ IsolatingInterval IsomorphicGraphQ IsotopeData Italic Item ItemBox ItemBoxOptions ItemSize ItemStyle ItoProcess JaccardDissimilarity JacobiAmplitude Jacobian JacobiCD JacobiCN JacobiCS JacobiDC JacobiDN JacobiDS JacobiNC JacobiND JacobiNS JacobiP JacobiSC JacobiSD JacobiSN JacobiSymbol JacobiZeta JankoGroupJ1 JankoGroupJ2 JankoGroupJ3 JankoGroupJ4 JarqueBeraALMTest JohnsonDistribution Join Joined JoinedCurve JoinedCurveBox JoinForm JordanDecomposition JordanModelDecomposition K KagiChart KaiserBesselWindow KaiserWindow KalmanEstimator KalmanFilter KarhunenLoeveDecomposition KaryTree KatzCentrality KCoreComponents KDistribution KelvinBei KelvinBer KelvinKei KelvinKer KendallTau KendallTauTest KernelExecute KernelMixtureDistribution KernelObject Kernels Ket Khinchin KirchhoffGraph KirchhoffMatrix KleinInvariantJ KnightTourGraph KnotData KnownUnitQ KolmogorovSmirnovTest KroneckerDelta KroneckerModelDecomposition KroneckerProduct KroneckerSymbol KuiperTest KumaraswamyDistribution Kurtosis KuwaharaFilter Label Labeled LabeledSlider LabelingFunction LabelStyle LaguerreL LambdaComponents LambertW LanczosWindow LandauDistribution Language LanguageCategory LaplaceDistribution LaplaceTransform Laplacian LaplacianFilter LaplacianGaussianFilter Large Larger Last Latitude LatitudeLongitude LatticeData LatticeReduce Launch LaunchKernels LayeredGraphPlot LayerSizeFunction LayoutInformation LCM LeafCount LeapYearQ LeastSquares LeastSquaresFilterKernel Left LeftArrow LeftArrowBar LeftArrowRightArrow LeftDownTeeVector LeftDownVector LeftDownVectorBar LeftRightArrow LeftRightVector LeftTee LeftTeeArrow LeftTeeVector LeftTriangle LeftTriangleBar LeftTriangleEqual LeftUpDownVector LeftUpTeeVector LeftUpVector LeftUpVectorBar LeftVector LeftVectorBar LegendAppearance Legended LegendFunction LegendLabel LegendLayout LegendMargins LegendMarkers LegendMarkerSize LegendreP LegendreQ LegendreType Length LengthWhile LerchPhi Less LessEqual LessEqualGreater LessFullEqual LessGreater LessLess LessSlantEqual LessTilde LetterCharacter LetterQ Level LeveneTest LeviCivitaTensor LevyDistribution Lexicographic LibraryFunction LibraryFunctionError LibraryFunctionInformation LibraryFunctionLoad LibraryFunctionUnload LibraryLoad LibraryUnload LicenseID LiftingFilterData LiftingWaveletTransform LightBlue LightBrown LightCyan Lighter LightGray LightGreen Lighting LightingAngle LightMagenta LightOrange LightPink LightPurple LightRed LightSources LightYellow Likelihood Limit LimitsPositioning LimitsPositioningTokens LindleyDistribution Line Line3DBox LinearFilter LinearFractionalTransform LinearModelFit LinearOffsetFunction LinearProgramming LinearRecurrence LinearSolve LinearSolveFunction LineBox LineBreak LinebreakAdjustments LineBreakChart LineBreakWithin LineColor LineForm LineGraph LineIndent LineIndentMaxFraction LineIntegralConvolutionPlot LineIntegralConvolutionScale LineLegend LineOpacity LineSpacing LineWrapParts LinkActivate LinkClose LinkConnect LinkConnectedQ LinkCreate LinkError LinkFlush LinkFunction LinkHost LinkInterrupt LinkLaunch LinkMode LinkObject LinkOpen LinkOptions LinkPatterns LinkProtocol LinkRead LinkReadHeld LinkReadyQ Links LinkWrite LinkWriteHeld LiouvilleLambda List Listable ListAnimate ListContourPlot ListContourPlot3D ListConvolve ListCorrelate ListCurvePathPlot ListDeconvolve ListDensityPlot Listen ListFourierSequenceTransform ListInterpolation ListLineIntegralConvolutionPlot ListLinePlot ListLogLinearPlot ListLogLogPlot ListLogPlot ListPicker ListPickerBox ListPickerBoxBackground ListPickerBoxOptions ListPlay ListPlot ListPlot3D ListPointPlot3D ListPolarPlot ListQ ListStreamDensityPlot ListStreamPlot ListSurfacePlot3D ListVectorDensityPlot ListVectorPlot ListVectorPlot3D ListZTransform Literal LiteralSearch LocalClusteringCoefficient LocalizeVariables LocationEquivalenceTest LocationTest Locator LocatorAutoCreate LocatorBox LocatorBoxOptions LocatorCentering LocatorPane LocatorPaneBox LocatorPaneBoxOptions LocatorRegion Locked Log Log10 Log2 LogBarnesG LogGamma LogGammaDistribution LogicalExpand LogIntegral LogisticDistribution LogitModelFit LogLikelihood LogLinearPlot LogLogisticDistribution LogLogPlot LogMultinormalDistribution LogNormalDistribution LogPlot LogRankTest LogSeriesDistribution LongEqual Longest LongestAscendingSequence LongestCommonSequence LongestCommonSequencePositions LongestCommonSubsequence LongestCommonSubsequencePositions LongestMatch LongForm Longitude LongLeftArrow LongLeftRightArrow LongRightArrow Loopback LoopFreeGraphQ LowerCaseQ LowerLeftArrow LowerRightArrow LowerTriangularize LowpassFilter LQEstimatorGains LQGRegulator LQOutputRegulatorGains LQRegulatorGains LUBackSubstitution LucasL LuccioSamiComponents LUDecomposition LyapunovSolve LyonsGroupLy MachineID MachineName MachineNumberQ MachinePrecision MacintoshSystemPageSetup Magenta Magnification Magnify MainSolve MaintainDynamicCaches Majority MakeBoxes MakeExpression MakeRules MangoldtLambda ManhattanDistance Manipulate Manipulator MannWhitneyTest MantissaExponent Manual Map MapAll MapAt MapIndexed MAProcess MapThread MarcumQ MardiaCombinedTest MardiaKurtosisTest MardiaSkewnessTest MarginalDistribution MarkovProcessProperties Masking MatchingDissimilarity MatchLocalNameQ MatchLocalNames MatchQ Material MathematicaNotation MathieuC MathieuCharacteristicA MathieuCharacteristicB MathieuCharacteristicExponent MathieuCPrime MathieuGroupM11 MathieuGroupM12 MathieuGroupM22 MathieuGroupM23 MathieuGroupM24 MathieuS MathieuSPrime MathMLForm MathMLText Matrices MatrixExp MatrixForm MatrixFunction MatrixLog MatrixPlot MatrixPower MatrixQ MatrixRank Max MaxBend MaxDetect MaxExtraBandwidths MaxExtraConditions MaxFeatures MaxFilter Maximize MaxIterations MaxMemoryUsed MaxMixtureKernels MaxPlotPoints MaxPoints MaxRecursion MaxStableDistribution MaxStepFraction MaxSteps MaxStepSize MaxValue MaxwellDistribution McLaughlinGroupMcL Mean MeanClusteringCoefficient MeanDegreeConnectivity MeanDeviation MeanFilter MeanGraphDistance MeanNeighborDegree MeanShift MeanShiftFilter Median MedianDeviation MedianFilter Medium MeijerG MeixnerDistribution MemberQ MemoryConstrained MemoryInUse Menu MenuAppearance MenuCommandKey MenuEvaluator MenuItem MenuPacket MenuSortingValue MenuStyle MenuView MergeDifferences Mesh MeshFunctions MeshRange MeshShading MeshStyle Message MessageDialog MessageList MessageName MessageOptions MessagePacket Messages MessagesNotebook MetaCharacters MetaInformation Method MethodOptions MexicanHatWavelet MeyerWavelet Min MinDetect MinFilter MinimalPolynomial MinimalStateSpaceModel Minimize Minors MinRecursion MinSize MinStableDistribution Minus MinusPlus MinValue Missing MissingDataMethod MittagLefflerE MixedRadix MixedRadixQuantity MixtureDistribution Mod Modal Mode Modular ModularLambda Module Modulus MoebiusMu Moment Momentary MomentConvert MomentEvaluate MomentGeneratingFunction Monday Monitor MonomialList MonomialOrder MonsterGroupM MorletWavelet MorphologicalBinarize MorphologicalBranchPoints MorphologicalComponents MorphologicalEulerNumber MorphologicalGraph MorphologicalPerimeter MorphologicalTransform Most MouseAnnotation MouseAppearance MouseAppearanceTag MouseButtons Mouseover MousePointerNote MousePosition MovingAverage MovingMedian MoyalDistribution MultiedgeStyle MultilaunchWarning MultiLetterItalics MultiLetterStyle MultilineFunction Multinomial MultinomialDistribution MultinormalDistribution MultiplicativeOrder Multiplicity Multiselection MultivariateHypergeometricDistribution MultivariatePoissonDistribution MultivariateTDistribution N NakagamiDistribution NameQ Names NamespaceBox Nand NArgMax NArgMin NBernoulliB NCache NDSolve NDSolveValue Nearest NearestFunction NeedCurrentFrontEndPackagePacket NeedCurrentFrontEndSymbolsPacket NeedlemanWunschSimilarity Needs Negative NegativeBinomialDistribution NegativeMultinomialDistribution NeighborhoodGraph Nest NestedGreaterGreater NestedLessLess NestedScriptRules NestList NestWhile NestWhileList NevilleThetaC NevilleThetaD NevilleThetaN NevilleThetaS NewPrimitiveStyle NExpectation Next NextPrime NHoldAll NHoldFirst NHoldRest NicholsGridLines NicholsPlot NIntegrate NMaximize NMaxValue NMinimize NMinValue NominalVariables NonAssociative NoncentralBetaDistribution NoncentralChiSquareDistribution NoncentralFRatioDistribution NoncentralStudentTDistribution NonCommutativeMultiply NonConstants None NonlinearModelFit NonlocalMeansFilter NonNegative NonPositive Nor NorlundB Norm Normal NormalDistribution NormalGrouping Normalize NormalizedSquaredEuclideanDistance NormalsFunction NormFunction Not NotCongruent NotCupCap NotDoubleVerticalBar Notebook NotebookApply NotebookAutoSave NotebookClose NotebookConvertSettings NotebookCreate NotebookCreateReturnObject NotebookDefault NotebookDelete NotebookDirectory NotebookDynamicExpression NotebookEvaluate NotebookEventActions NotebookFileName NotebookFind NotebookFindReturnObject NotebookGet NotebookGetLayoutInformationPacket NotebookGetMisspellingsPacket NotebookInformation NotebookInterfaceObject NotebookLocate NotebookObject NotebookOpen NotebookOpenReturnObject NotebookPath NotebookPrint NotebookPut NotebookPutReturnObject NotebookRead NotebookResetGeneratedCells Notebooks NotebookSave NotebookSaveAs NotebookSelection NotebookSetupLayoutInformationPacket NotebooksMenu NotebookWrite NotElement NotEqualTilde NotExists NotGreater NotGreaterEqual NotGreaterFullEqual NotGreaterGreater NotGreaterLess NotGreaterSlantEqual NotGreaterTilde NotHumpDownHump NotHumpEqual NotLeftTriangle NotLeftTriangleBar NotLeftTriangleEqual NotLess NotLessEqual NotLessFullEqual NotLessGreater NotLessLess NotLessSlantEqual NotLessTilde NotNestedGreaterGreater NotNestedLessLess NotPrecedes NotPrecedesEqual NotPrecedesSlantEqual NotPrecedesTilde NotReverseElement NotRightTriangle NotRightTriangleBar NotRightTriangleEqual NotSquareSubset NotSquareSubsetEqual NotSquareSuperset NotSquareSupersetEqual NotSubset NotSubsetEqual NotSucceeds NotSucceedsEqual NotSucceedsSlantEqual NotSucceedsTilde NotSuperset NotSupersetEqual NotTilde NotTildeEqual NotTildeFullEqual NotTildeTilde NotVerticalBar NProbability NProduct NProductFactors NRoots NSolve NSum NSumTerms Null NullRecords NullSpace NullWords Number NumberFieldClassNumber NumberFieldDiscriminant NumberFieldFundamentalUnits NumberFieldIntegralBasis NumberFieldNormRepresentatives NumberFieldRegulator NumberFieldRootsOfUnity NumberFieldSignature NumberForm NumberFormat NumberMarks NumberMultiplier NumberPadding NumberPoint NumberQ NumberSeparator NumberSigns NumberString Numerator NumericFunction NumericQ NuttallWindow NValues NyquistGridLines NyquistPlot O ObservabilityGramian ObservabilityMatrix ObservableDecomposition ObservableModelQ OddQ Off Offset OLEData On ONanGroupON OneIdentity Opacity Open OpenAppend Opener OpenerBox OpenerBoxOptions OpenerView OpenFunctionInspectorPacket Opening OpenRead OpenSpecialOptions OpenTemporary OpenWrite Operate OperatingSystem OptimumFlowData Optional OptionInspectorSettings OptionQ Options OptionsPacket OptionsPattern OptionValue OptionValueBox OptionValueBoxOptions Or Orange Order OrderDistribution OrderedQ Ordering Orderless OrnsteinUhlenbeckProcess Orthogonalize Out Outer OutputAutoOverwrite OutputControllabilityMatrix OutputControllableModelQ OutputForm OutputFormData OutputGrouping OutputMathEditExpression OutputNamePacket OutputResponse OutputSizeLimit OutputStream Over OverBar OverDot Overflow OverHat Overlaps Overlay OverlayBox OverlayBoxOptions Overscript OverscriptBox OverscriptBoxOptions OverTilde OverVector OwenT OwnValues PackingMethod PaddedForm Padding PadeApproximant PadLeft PadRight PageBreakAbove PageBreakBelow PageBreakWithin PageFooterLines PageFooters PageHeaderLines PageHeaders PageHeight PageRankCentrality PageWidth PairedBarChart PairedHistogram PairedSmoothHistogram PairedTTest PairedZTest PaletteNotebook PalettePath Pane PaneBox PaneBoxOptions Panel PanelBox PanelBoxOptions Paneled PaneSelector PaneSelectorBox PaneSelectorBoxOptions PaperWidth ParabolicCylinderD ParagraphIndent ParagraphSpacing ParallelArray ParallelCombine ParallelDo ParallelEvaluate Parallelization Parallelize ParallelMap ParallelNeeds ParallelProduct ParallelSubmit ParallelSum ParallelTable ParallelTry Parameter ParameterEstimator ParameterMixtureDistribution ParameterVariables ParametricFunction ParametricNDSolve ParametricNDSolveValue ParametricPlot ParametricPlot3D ParentConnect ParentDirectory ParentForm Parenthesize ParentList ParetoDistribution Part PartialCorrelationFunction PartialD ParticleData Partition PartitionsP PartitionsQ ParzenWindow PascalDistribution PassEventsDown PassEventsUp Paste PasteBoxFormInlineCells PasteButton Path PathGraph PathGraphQ Pattern PatternSequence PatternTest PauliMatrix PaulWavelet Pause PausedTime PDF PearsonChiSquareTest PearsonCorrelationTest PearsonDistribution PerformanceGoal PeriodicInterpolation Periodogram PeriodogramArray PermutationCycles PermutationCyclesQ PermutationGroup PermutationLength PermutationList PermutationListQ PermutationMax PermutationMin PermutationOrder PermutationPower PermutationProduct PermutationReplace Permutations PermutationSupport Permute PeronaMalikFilter Perpendicular PERTDistribution PetersenGraph PhaseMargins Pi Pick PIDData PIDDerivativeFilter PIDFeedforward PIDTune Piecewise PiecewiseExpand PieChart PieChart3D PillaiTrace PillaiTraceTest Pink Pivoting PixelConstrained PixelValue PixelValuePositions Placed Placeholder PlaceholderReplace Plain PlanarGraphQ Play PlayRange Plot Plot3D Plot3Matrix PlotDivision PlotJoined PlotLabel PlotLayout PlotLegends PlotMarkers PlotPoints PlotRange PlotRangeClipping PlotRangePadding PlotRegion PlotStyle Plus PlusMinus Pochhammer PodStates PodWidth Point Point3DBox PointBox PointFigureChart PointForm PointLegend PointSize PoissonConsulDistribution PoissonDistribution PoissonProcess PoissonWindow PolarAxes PolarAxesOrigin PolarGridLines PolarPlot PolarTicks PoleZeroMarkers PolyaAeppliDistribution PolyGamma Polygon Polygon3DBox Polygon3DBoxOptions PolygonBox PolygonBoxOptions PolygonHoleScale PolygonIntersections PolygonScale PolyhedronData PolyLog PolynomialExtendedGCD PolynomialForm PolynomialGCD PolynomialLCM PolynomialMod PolynomialQ PolynomialQuotient PolynomialQuotientRemainder PolynomialReduce PolynomialRemainder Polynomials PopupMenu PopupMenuBox PopupMenuBoxOptions PopupView PopupWindow Position Positive PositiveDefiniteMatrixQ PossibleZeroQ Postfix PostScript Power PowerDistribution PowerExpand PowerMod PowerModList PowerSpectralDensity PowersRepresentations PowerSymmetricPolynomial Precedence PrecedenceForm Precedes PrecedesEqual PrecedesSlantEqual PrecedesTilde Precision PrecisionGoal PreDecrement PredictionRoot PreemptProtect PreferencesPath Prefix PreIncrement Prepend PrependTo PreserveImageOptions Previous PriceGraphDistribution PrimaryPlaceholder Prime PrimeNu PrimeOmega PrimePi PrimePowerQ PrimeQ Primes PrimeZetaP PrimitiveRoot PrincipalComponents PrincipalValue Print PrintAction PrintForm PrintingCopies PrintingOptions PrintingPageRange PrintingStartingPageNumber PrintingStyleEnvironment PrintPrecision PrintTemporary Prism PrismBox PrismBoxOptions PrivateCellOptions PrivateEvaluationOptions PrivateFontOptions PrivateFrontEndOptions PrivateNotebookOptions PrivatePaths Probability ProbabilityDistribution ProbabilityPlot ProbabilityPr ProbabilityScalePlot ProbitModelFit ProcessEstimator ProcessParameterAssumptions ProcessParameterQ ProcessStateDomain ProcessTimeDomain Product ProductDistribution ProductLog ProgressIndicator ProgressIndicatorBox ProgressIndicatorBoxOptions Projection Prolog PromptForm Properties Property PropertyList PropertyValue Proportion Proportional Protect Protected ProteinData Pruning PseudoInverse Purple Put PutAppend Pyramid PyramidBox PyramidBoxOptions QBinomial QFactorial QGamma QHypergeometricPFQ QPochhammer QPolyGamma QRDecomposition QuadraticIrrationalQ Quantile QuantilePlot Quantity QuantityForm QuantityMagnitude QuantityQ QuantityUnit Quartics QuartileDeviation Quartiles QuartileSkewness QueueingNetworkProcess QueueingProcess QueueProperties Quiet Quit Quotient QuotientRemainder RadialityCentrality RadicalBox RadicalBoxOptions RadioButton RadioButtonBar RadioButtonBox RadioButtonBoxOptions Radon RamanujanTau RamanujanTauL RamanujanTauTheta RamanujanTauZ Random RandomChoice RandomComplex RandomFunction RandomGraph RandomImage RandomInteger RandomPermutation RandomPrime RandomReal RandomSample RandomSeed RandomVariate RandomWalkProcess Range RangeFilter RangeSpecification RankedMax RankedMin Raster Raster3D Raster3DBox Raster3DBoxOptions RasterArray RasterBox RasterBoxOptions Rasterize RasterSize Rational RationalFunctions Rationalize Rationals Ratios Raw RawArray RawBoxes RawData RawMedium RayleighDistribution Re Read ReadList ReadProtected Real RealBlockDiagonalForm RealDigits RealExponent Reals Reap Record RecordLists RecordSeparators Rectangle RectangleBox RectangleBoxOptions RectangleChart RectangleChart3D RecurrenceFilter RecurrenceTable RecurringDigitsForm Red Reduce RefBox ReferenceLineStyle ReferenceMarkers ReferenceMarkerStyle Refine ReflectionMatrix ReflectionTransform Refresh RefreshRate RegionBinarize RegionFunction RegionPlot RegionPlot3D RegularExpression Regularization Reinstall Release ReleaseHold ReliabilityDistribution ReliefImage ReliefPlot Remove RemoveAlphaChannel RemoveAsynchronousTask Removed RemoveInputStreamMethod RemoveOutputStreamMethod RemoveProperty RemoveScheduledTask RenameDirectory RenameFile RenderAll RenderingOptions RenewalProcess RenkoChart Repeated RepeatedNull RepeatedString Replace ReplaceAll ReplaceHeldPart ReplaceImageValue ReplaceList ReplacePart ReplacePixelValue ReplaceRepeated Resampling Rescale RescalingTransform ResetDirectory ResetMenusPacket ResetScheduledTask Residue Resolve Rest Resultant ResumePacket Return ReturnExpressionPacket ReturnInputFormPacket ReturnPacket ReturnTextPacket Reverse ReverseBiorthogonalSplineWavelet ReverseElement ReverseEquilibrium ReverseGraph ReverseUpEquilibrium RevolutionAxis RevolutionPlot3D RGBColor RiccatiSolve RiceDistribution RidgeFilter RiemannR RiemannSiegelTheta RiemannSiegelZ Riffle Right RightArrow RightArrowBar RightArrowLeftArrow RightCosetRepresentative RightDownTeeVector RightDownVector RightDownVectorBar RightTee RightTeeArrow RightTeeVector RightTriangle RightTriangleBar RightTriangleEqual RightUpDownVector RightUpTeeVector RightUpVector RightUpVectorBar RightVector RightVectorBar RiskAchievementImportance RiskReductionImportance RogersTanimotoDissimilarity Root RootApproximant RootIntervals RootLocusPlot RootMeanSquare RootOfUnityQ RootReduce Roots RootSum Rotate RotateLabel RotateLeft RotateRight RotationAction RotationBox RotationBoxOptions RotationMatrix RotationTransform Round RoundImplies RoundingRadius Row RowAlignments RowBackgrounds RowBox RowHeights RowLines RowMinHeight RowReduce RowsEqual RowSpacings RSolve RudvalisGroupRu Rule RuleCondition RuleDelayed RuleForm RulerUnits Run RunScheduledTask RunThrough RuntimeAttributes RuntimeOptions RussellRaoDissimilarity SameQ SameTest SampleDepth SampledSoundFunction SampledSoundList SampleRate SamplingPeriod SARIMAProcess SARMAProcess SatisfiabilityCount SatisfiabilityInstances SatisfiableQ Saturday Save Saveable SaveAutoDelete SaveDefinitions SawtoothWave Scale Scaled ScaleDivisions ScaledMousePosition ScaleOrigin ScalePadding ScaleRanges ScaleRangeStyle ScalingFunctions ScalingMatrix ScalingTransform Scan ScheduledTaskActiveQ ScheduledTaskData ScheduledTaskObject ScheduledTasks SchurDecomposition ScientificForm ScreenRectangle ScreenStyleEnvironment ScriptBaselineShifts ScriptLevel ScriptMinSize ScriptRules ScriptSizeMultipliers Scrollbars ScrollingOptions ScrollPosition Sec Sech SechDistribution SectionGrouping SectorChart SectorChart3D SectorOrigin SectorSpacing SeedRandom Select Selectable SelectComponents SelectedCells SelectedNotebook Selection SelectionAnimate SelectionCell SelectionCellCreateCell SelectionCellDefaultStyle SelectionCellParentStyle SelectionCreateCell SelectionDebuggerTag SelectionDuplicateCell SelectionEvaluate SelectionEvaluateCreateCell SelectionMove SelectionPlaceholder SelectionSetStyle SelectWithContents SelfLoops SelfLoopStyle SemialgebraicComponentInstances SendMail Sequence SequenceAlignment SequenceForm SequenceHold SequenceLimit Series SeriesCoefficient SeriesData SessionTime Set SetAccuracy SetAlphaChannel SetAttributes Setbacks SetBoxFormNamesPacket SetDelayed SetDirectory SetEnvironment SetEvaluationNotebook SetFileDate SetFileLoadingContext SetNotebookStatusLine SetOptions SetOptionsPacket SetPrecision SetProperty SetSelectedNotebook SetSharedFunction SetSharedVariable SetSpeechParametersPacket SetStreamPosition SetSystemOptions Setter SetterBar SetterBox SetterBoxOptions Setting SetValue Shading Shallow ShannonWavelet ShapiroWilkTest Share Sharpen ShearingMatrix ShearingTransform ShenCastanMatrix Short ShortDownArrow Shortest ShortestMatch ShortestPathFunction ShortLeftArrow ShortRightArrow ShortUpArrow Show ShowAutoStyles ShowCellBracket ShowCellLabel ShowCellTags ShowClosedCellArea ShowContents ShowControls ShowCursorTracker ShowGroupOpenCloseIcon ShowGroupOpener ShowInvisibleCharacters ShowPageBreaks ShowPredictiveInterface ShowSelection ShowShortBoxForm ShowSpecialCharacters ShowStringCharacters ShowSyntaxStyles ShrinkingDelay ShrinkWrapBoundingBox SiegelTheta SiegelTukeyTest Sign Signature SignedRankTest SignificanceLevel SignPadding SignTest SimilarityRules SimpleGraph SimpleGraphQ Simplify Sin Sinc SinghMaddalaDistribution SingleEvaluation SingleLetterItalics SingleLetterStyle SingularValueDecomposition SingularValueList SingularValuePlot SingularValues Sinh SinhIntegral SinIntegral SixJSymbol Skeleton SkeletonTransform SkellamDistribution Skewness SkewNormalDistribution Skip SliceDistribution Slider Slider2D Slider2DBox Slider2DBoxOptions SliderBox SliderBoxOptions SlideView Slot SlotSequence Small SmallCircle Smaller SmithDelayCompensator SmithWatermanSimilarity SmoothDensityHistogram SmoothHistogram SmoothHistogram3D SmoothKernelDistribution SocialMediaData Socket SokalSneathDissimilarity Solve SolveAlways SolveDelayed Sort SortBy Sound SoundAndGraphics SoundNote SoundVolume Sow Space SpaceForm Spacer Spacings Span SpanAdjustments SpanCharacterRounding SpanFromAbove SpanFromBoth SpanFromLeft SpanLineThickness SpanMaxSize SpanMinSize SpanningCharacters SpanSymmetric SparseArray SpatialGraphDistribution Speak SpeakTextPacket SpearmanRankTest SpearmanRho Spectrogram SpectrogramArray Specularity SpellingCorrection SpellingDictionaries SpellingDictionariesPath SpellingOptions SpellingSuggestionsPacket Sphere SphereBox SphericalBesselJ SphericalBesselY SphericalHankelH1 SphericalHankelH2 SphericalHarmonicY SphericalPlot3D SphericalRegion SpheroidalEigenvalue SpheroidalJoiningFactor SpheroidalPS SpheroidalPSPrime SpheroidalQS SpheroidalQSPrime SpheroidalRadialFactor SpheroidalS1 SpheroidalS1Prime SpheroidalS2 SpheroidalS2Prime Splice SplicedDistribution SplineClosed SplineDegree SplineKnots SplineWeights Split SplitBy SpokenString Sqrt SqrtBox SqrtBoxOptions Square SquaredEuclideanDistance SquareFreeQ SquareIntersection SquaresR SquareSubset SquareSubsetEqual SquareSuperset SquareSupersetEqual SquareUnion SquareWave StabilityMargins StabilityMarginsStyle StableDistribution Stack StackBegin StackComplete StackInhibit StandardDeviation StandardDeviationFilter StandardForm Standardize StandbyDistribution Star StarGraph StartAsynchronousTask StartingStepSize StartOfLine StartOfString StartScheduledTask StartupSound StateDimensions StateFeedbackGains StateOutputEstimator StateResponse StateSpaceModel StateSpaceRealization StateSpaceTransform StationaryDistribution StationaryWaveletPacketTransform StationaryWaveletTransform StatusArea StatusCentrality StepMonitor StieltjesGamma StirlingS1 StirlingS2 StopAsynchronousTask StopScheduledTask StrataVariables StratonovichProcess StreamColorFunction StreamColorFunctionScaling StreamDensityPlot StreamPlot StreamPoints StreamPosition Streams StreamScale StreamStyle String StringBreak StringByteCount StringCases StringCount StringDrop StringExpression StringForm StringFormat StringFreeQ StringInsert StringJoin StringLength StringMatchQ StringPosition StringQ StringReplace StringReplaceList StringReplacePart StringReverse StringRotateLeft StringRotateRight StringSkeleton StringSplit StringTake StringToStream StringTrim StripBoxes StripOnInput StripWrapperBoxes StrokeForm StructuralImportance StructuredArray StructuredSelection StruveH StruveL Stub StudentTDistribution Style StyleBox StyleBoxAutoDelete StyleBoxOptions StyleData StyleDefinitions StyleForm StyleKeyMapping StyleMenuListing StyleNameDialogSettings StyleNames StylePrint StyleSheetPath Subfactorial Subgraph SubMinus SubPlus SubresultantPolynomialRemainders SubresultantPolynomials Subresultants Subscript SubscriptBox SubscriptBoxOptions Subscripted Subset SubsetEqual Subsets SubStar Subsuperscript SubsuperscriptBox SubsuperscriptBoxOptions Subtract SubtractFrom SubValues Succeeds SucceedsEqual SucceedsSlantEqual SucceedsTilde SuchThat Sum SumConvergence Sunday SuperDagger SuperMinus SuperPlus Superscript SuperscriptBox SuperscriptBoxOptions Superset SupersetEqual SuperStar Surd SurdForm SurfaceColor SurfaceGraphics SurvivalDistribution SurvivalFunction SurvivalModel SurvivalModelFit SuspendPacket SuzukiDistribution SuzukiGroupSuz SwatchLegend Switch Symbol SymbolName SymletWavelet Symmetric SymmetricGroup SymmetricMatrixQ SymmetricPolynomial SymmetricReduction Symmetrize SymmetrizedArray SymmetrizedArrayRules SymmetrizedDependentComponents SymmetrizedIndependentComponents SymmetrizedReplacePart SynchronousInitialization SynchronousUpdating Syntax SyntaxForm SyntaxInformation SyntaxLength SyntaxPacket SyntaxQ SystemDialogInput SystemException SystemHelpPath SystemInformation SystemInformationData SystemOpen SystemOptions SystemsModelDelay SystemsModelDelayApproximate SystemsModelDelete SystemsModelDimensions SystemsModelExtract SystemsModelFeedbackConnect SystemsModelLabels SystemsModelOrder SystemsModelParallelConnect SystemsModelSeriesConnect SystemsModelStateFeedbackConnect SystemStub Tab TabFilling Table TableAlignments TableDepth TableDirections TableForm TableHeadings TableSpacing TableView TableViewBox TabSpacings TabView TabViewBox TabViewBoxOptions TagBox TagBoxNote TagBoxOptions TaggingRules TagSet TagSetDelayed TagStyle TagUnset Take TakeWhile Tally Tan Tanh TargetFunctions TargetUnits TautologyQ TelegraphProcess TemplateBox TemplateBoxOptions TemplateSlotSequence TemporalData Temporary TemporaryVariable TensorContract TensorDimensions TensorExpand TensorProduct TensorQ TensorRank TensorReduce TensorSymmetry TensorTranspose TensorWedge Tetrahedron TetrahedronBox TetrahedronBoxOptions TeXForm TeXSave Text Text3DBox Text3DBoxOptions TextAlignment TextBand TextBoundingBox TextBox TextCell TextClipboardType TextData TextForm TextJustification TextLine TextPacket TextParagraph TextRecognize TextRendering TextStyle Texture TextureCoordinateFunction TextureCoordinateScaling Therefore ThermometerGauge Thick Thickness Thin Thinning ThisLink ThompsonGroupTh Thread ThreeJSymbol Threshold Through Throw Thumbnail Thursday Ticks TicksStyle Tilde TildeEqual TildeFullEqual TildeTilde TimeConstrained TimeConstraint Times TimesBy TimeSeriesForecast TimeSeriesInvertibility TimeUsed TimeValue TimeZone Timing Tiny TitleGrouping TitsGroupT ToBoxes ToCharacterCode ToColor ToContinuousTimeModel ToDate ToDiscreteTimeModel ToeplitzMatrix ToExpression ToFileName Together Toggle ToggleFalse Toggler TogglerBar TogglerBox TogglerBoxOptions ToHeldExpression ToInvertibleTimeSeries TokenWords Tolerance ToLowerCase ToNumberField TooBig Tooltip TooltipBox TooltipBoxOptions TooltipDelay TooltipStyle Top TopHatTransform TopologicalSort ToRadicals ToRules ToString Total TotalHeight TotalVariationFilter TotalWidth TouchscreenAutoZoom TouchscreenControlPlacement ToUpperCase Tr Trace TraceAbove TraceAction TraceBackward TraceDepth TraceDialog TraceForward TraceInternal TraceLevel TraceOff TraceOn TraceOriginal TracePrint TraceScan TrackedSymbols TradingChart TraditionalForm TraditionalFunctionNotation TraditionalNotation TraditionalOrder TransferFunctionCancel TransferFunctionExpand TransferFunctionFactor TransferFunctionModel TransferFunctionPoles TransferFunctionTransform TransferFunctionZeros TransformationFunction TransformationFunctions TransformationMatrix TransformedDistribution TransformedField Translate TranslationTransform TransparentColor Transpose TreeForm TreeGraph TreeGraphQ TreePlot TrendStyle TriangleWave TriangularDistribution Trig TrigExpand TrigFactor TrigFactorList Trigger TrigReduce TrigToExp TrimmedMean True TrueQ TruncatedDistribution TsallisQExponentialDistribution TsallisQGaussianDistribution TTest Tube TubeBezierCurveBox TubeBezierCurveBoxOptions TubeBox TubeBSplineCurveBox TubeBSplineCurveBoxOptions Tuesday TukeyLambdaDistribution TukeyWindow Tuples TuranGraph TuringMachine Transparent UnateQ Uncompress Undefined UnderBar Underflow Underlined Underoverscript UnderoverscriptBox UnderoverscriptBoxOptions Underscript UnderscriptBox UnderscriptBoxOptions UndirectedEdge UndirectedGraph UndirectedGraphQ UndocumentedTestFEParserPacket UndocumentedTestGetSelectionPacket Unequal Unevaluated UniformDistribution UniformGraphDistribution UniformSumDistribution Uninstall Union UnionPlus Unique UnitBox UnitConvert UnitDimensions Unitize UnitRootTest UnitSimplify UnitStep UnitTriangle UnitVector Unprotect UnsameQ UnsavedVariables Unset UnsetShared UntrackedVariables Up UpArrow UpArrowBar UpArrowDownArrow Update UpdateDynamicObjects UpdateDynamicObjectsSynchronous UpdateInterval UpDownArrow UpEquilibrium UpperCaseQ UpperLeftArrow UpperRightArrow UpperTriangularize Upsample UpSet UpSetDelayed UpTee UpTeeArrow UpValues URL URLFetch URLFetchAsynchronous URLSave URLSaveAsynchronous UseGraphicsRange Using UsingFrontEnd V2Get ValidationLength Value ValueBox ValueBoxOptions ValueForm ValueQ ValuesData Variables Variance VarianceEquivalenceTest VarianceEstimatorFunction VarianceGammaDistribution VarianceTest VectorAngle VectorColorFunction VectorColorFunctionScaling VectorDensityPlot VectorGlyphData VectorPlot VectorPlot3D VectorPoints VectorQ Vectors VectorScale VectorStyle Vee Verbatim Verbose VerboseConvertToPostScriptPacket VerifyConvergence VerifySolutions VerifyTestAssumptions Version VersionNumber VertexAdd VertexCapacity VertexColors VertexComponent VertexConnectivity VertexCoordinateRules VertexCoordinates VertexCorrelationSimilarity VertexCosineSimilarity VertexCount VertexCoverQ VertexDataCoordinates VertexDegree VertexDelete VertexDiceSimilarity VertexEccentricity VertexInComponent VertexInDegree VertexIndex VertexJaccardSimilarity VertexLabeling VertexLabels VertexLabelStyle VertexList VertexNormals VertexOutComponent VertexOutDegree VertexQ VertexRenderingFunction VertexReplace VertexShape VertexShapeFunction VertexSize VertexStyle VertexTextureCoordinates VertexWeight Vertical VerticalBar VerticalForm VerticalGauge VerticalSeparator VerticalSlider VerticalTilde ViewAngle ViewCenter ViewMatrix ViewPoint ViewPointSelectorSettings ViewPort ViewRange ViewVector ViewVertical VirtualGroupData Visible VisibleCell VoigtDistribution VonMisesDistribution WaitAll WaitAsynchronousTask WaitNext WaitUntil WakebyDistribution WalleniusHypergeometricDistribution WaringYuleDistribution WatershedComponents WatsonUSquareTest WattsStrogatzGraphDistribution WaveletBestBasis WaveletFilterCoefficients WaveletImagePlot WaveletListPlot WaveletMapIndexed WaveletMatrixPlot WaveletPhi WaveletPsi WaveletScale WaveletScalogram WaveletThreshold WeaklyConnectedComponents WeaklyConnectedGraphQ WeakStationarity WeatherData WeberE Wedge Wednesday WeibullDistribution WeierstrassHalfPeriods WeierstrassInvariants WeierstrassP WeierstrassPPrime WeierstrassSigma WeierstrassZeta WeightedAdjacencyGraph WeightedAdjacencyMatrix WeightedData WeightedGraphQ Weights WelchWindow WheelGraph WhenEvent Which While White Whitespace WhitespaceCharacter WhittakerM WhittakerW WienerFilter WienerProcess WignerD WignerSemicircleDistribution WilksW WilksWTest WindowClickSelect WindowElements WindowFloating WindowFrame WindowFrameElements WindowMargins WindowMovable WindowOpacity WindowSelected WindowSize WindowStatusArea WindowTitle WindowToolbars WindowWidth With WolframAlpha WolframAlphaDate WolframAlphaQuantity WolframAlphaResult Word WordBoundary WordCharacter WordData WordSearch WordSeparators WorkingPrecision Write WriteString Wronskian XMLElement XMLObject Xnor Xor Yellow YuleDissimilarity ZernikeR ZeroSymmetric ZeroTest ZeroWidthTimes Zeta ZetaZero ZipfDistribution ZTest ZTransform $Aborted $ActivationGroupID $ActivationKey $ActivationUserRegistered $AddOnsDirectory $AssertFunction $Assumptions $AsynchronousTask $BaseDirectory $BatchInput $BatchOutput $BoxForms $ByteOrdering $Canceled $CharacterEncoding $CharacterEncodings $CommandLine $CompilationTarget $ConditionHold $ConfiguredKernels $Context $ContextPath $ControlActiveSetting $CreationDate $CurrentLink $DateStringFormat $DefaultFont $DefaultFrontEnd $DefaultImagingDevice $DefaultPath $Display $DisplayFunction $DistributedContexts $DynamicEvaluation $Echo $Epilog $ExportFormats $Failed $FinancialDataSource $FormatType $FrontEnd $FrontEndSession $GeoLocation $HistoryLength $HomeDirectory $HTTPCookies $IgnoreEOF $ImagingDevices $ImportFormats $InitialDirectory $Input $InputFileName $InputStreamMethods $Inspector $InstallationDate $InstallationDirectory $InterfaceEnvironment $IterationLimit $KernelCount $KernelID $Language $LaunchDirectory $LibraryPath $LicenseExpirationDate $LicenseID $LicenseProcesses $LicenseServer $LicenseSubprocesses $LicenseType $Line $Linked $LinkSupported $LoadedFiles $MachineAddresses $MachineDomain $MachineDomains $MachineEpsilon $MachineID $MachineName $MachinePrecision $MachineType $MaxExtraPrecision $MaxLicenseProcesses $MaxLicenseSubprocesses $MaxMachineNumber $MaxNumber $MaxPiecewiseCases $MaxPrecision $MaxRootDegree $MessageGroups $MessageList $MessagePrePrint $Messages $MinMachineNumber $MinNumber $MinorReleaseNumber $MinPrecision $ModuleNumber $NetworkLicense $NewMessage $NewSymbol $Notebooks $NumberMarks $Off $OperatingSystem $Output $OutputForms $OutputSizeLimit $OutputStreamMethods $Packages $ParentLink $ParentProcessID $PasswordFile $PatchLevelID $Path $PathnameSeparator $PerformanceGoal $PipeSupported $Post $Pre $PreferencesDirectory $PrePrint $PreRead $PrintForms $PrintLiteral $ProcessID $ProcessorCount $ProcessorType $ProductInformation $ProgramName $RandomState $RecursionLimit $ReleaseNumber $RootDirectory $ScheduledTask $ScriptCommandLine $SessionID $SetParentLink $SharedFunctions $SharedVariables $SoundDisplay $SoundDisplayFunction $SuppressInputFormHeads $SynchronousEvaluation $SyntaxHandler $System $SystemCharacterEncoding $SystemID $SystemWordLength $TemporaryDirectory $TemporaryPrefix $TextStyle $TimedOut $TimeUnit $TimeZone $TopDirectory $TraceOff $TraceOn $TracePattern $TracePostAction $TracePreAction $Urgent $UserAddOnsDirectory $UserBaseDirectory $UserDocumentsDirectory $UserName $Version $VersionNumber", -c:[{cN:"comment",b:/\(\*/,e:/\*\)/},e.ASM,e.QSM,e.CNM,{cN:"list",b:/\{/,e:/\}/,i:/:/}]}}); \ No newline at end of file +c:[{cN:"comment",b:/\(\*/,e:/\*\)/},e.ASM,e.QSM,e.CNM,{b:/\{/,e:/\}/,i:/:/}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/matlab.js b/lib/highlight_js/assets/lang/matlab.js index ef7746c8c0a..4e6c9cd6105 100644 --- a/lib/highlight_js/assets/lang/matlab.js +++ b/lib/highlight_js/assets/lang/matlab.js @@ -1 +1 @@ -hljs.registerLanguage("matlab",function(e){var a=[e.CNM,{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]}],s={r:0,c:[{cN:"operator",b:/'['\.]*/}]};return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function",e:"$",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)"},{cN:"params",b:"\\[",e:"\\]"}]},{b:/[a-zA-Z_][a-zA-Z_0-9]*'['\.]*/,rB:!0,r:0,c:[{b:/[a-zA-Z_][a-zA-Z_0-9]*/,r:0},s.c[0]]},{cN:"matrix",b:"\\[",e:"\\]",c:a,r:0,starts:s},{cN:"cell",b:"\\{",e:/}/,c:a,r:0,starts:s},{b:/\)/,r:0,starts:s},e.C("^\\s*\\%\\{\\s*$","^\\s*\\%\\}\\s*$"),e.C("\\%","$")].concat(a)}}); \ No newline at end of file +hljs.registerLanguage("matlab",function(e){var a=[e.CNM,{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]}],s={r:0,c:[{b:/'['\.]*/}]};return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function",e:"$",c:[e.UTM,{cN:"params",v:[{b:"\\(",e:"\\)"},{b:"\\[",e:"\\]"}]}]},{b:/[a-zA-Z_][a-zA-Z_0-9]*'['\.]*/,rB:!0,r:0,c:[{b:/[a-zA-Z_][a-zA-Z_0-9]*/,r:0},s.c[0]]},{b:"\\[",e:"\\]",c:a,r:0,starts:s},{b:"\\{",e:/}/,c:a,r:0,starts:s},{b:/\)/,r:0,starts:s},e.C("^\\s*\\%\\{\\s*$","^\\s*\\%\\}\\s*$"),e.C("\\%","$")].concat(a)}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/maxima.js b/lib/highlight_js/assets/lang/maxima.js new file mode 100644 index 00000000000..bc2496549de --- /dev/null +++ b/lib/highlight_js/assets/lang/maxima.js @@ -0,0 +1 @@ +hljs.registerLanguage("maxima",function(e){var t="if then else elseif for thru do while unless step in and or not",a="true false unknown inf minf ind und %e %i %pi %phi %gamma",r=" abasep abs absint absolute_real_time acos acosh acot acoth acsc acsch activate addcol add_edge add_edges addmatrices addrow add_vertex add_vertices adjacency_matrix adjoin adjoint af agd airy airy_ai airy_bi airy_dai airy_dbi algsys alg_type alias allroots alphacharp alphanumericp amortization %and annuity_fv annuity_pv antid antidiff AntiDifference append appendfile apply apply1 apply2 applyb1 apropos args arit_amortization arithmetic arithsum array arrayapply arrayinfo arraymake arraysetapply ascii asec asech asin asinh askinteger asksign assoc assoc_legendre_p assoc_legendre_q assume assume_external_byte_order asympa at atan atan2 atanh atensimp atom atvalue augcoefmatrix augmented_lagrangian_method av average_degree backtrace bars barsplot barsplot_description base64 base64_decode bashindices batch batchload bc2 bdvac belln benefit_cost bern bernpoly bernstein_approx bernstein_expand bernstein_poly bessel bessel_i bessel_j bessel_k bessel_simplify bessel_y beta beta_incomplete beta_incomplete_generalized beta_incomplete_regularized bezout bfallroots bffac bf_find_root bf_fmin_cobyla bfhzeta bfloat bfloatp bfpsi bfpsi0 bfzeta biconnected_components bimetric binomial bipartition block blockmatrixp bode_gain bode_phase bothcoef box boxplot boxplot_description break bug_report build_info|10 buildq build_sample burn cabs canform canten cardinality carg cartan cartesian_product catch cauchy_matrix cbffac cdf_bernoulli cdf_beta cdf_binomial cdf_cauchy cdf_chi2 cdf_continuous_uniform cdf_discrete_uniform cdf_exp cdf_f cdf_gamma cdf_general_finite_discrete cdf_geometric cdf_gumbel cdf_hypergeometric cdf_laplace cdf_logistic cdf_lognormal cdf_negative_binomial cdf_noncentral_chi2 cdf_noncentral_student_t cdf_normal cdf_pareto cdf_poisson cdf_rank_sum cdf_rayleigh cdf_signed_rank cdf_student_t cdf_weibull cdisplay ceiling central_moment cequal cequalignore cf cfdisrep cfexpand cgeodesic cgreaterp cgreaterpignore changename changevar chaosgame charat charfun charfun2 charlist charp charpoly chdir chebyshev_t chebyshev_u checkdiv check_overlaps chinese cholesky christof chromatic_index chromatic_number cint circulant_graph clear_edge_weight clear_rules clear_vertex_label clebsch_gordan clebsch_graph clessp clesspignore close closefile cmetric coeff coefmatrix cograd col collapse collectterms columnop columnspace columnswap columnvector combination combine comp2pui compare compfile compile compile_file complement_graph complete_bipartite_graph complete_graph complex_number_p components compose_functions concan concat conjugate conmetderiv connected_components connect_vertices cons constant constantp constituent constvalue cont2part content continuous_freq contortion contour_plot contract contract_edge contragrad contrib_ode convert coord copy copy_file copy_graph copylist copymatrix cor cos cosh cot coth cov cov1 covdiff covect covers crc24sum create_graph create_list csc csch csetup cspline ctaylor ct_coordsys ctransform ctranspose cube_graph cuboctahedron_graph cunlisp cv cycle_digraph cycle_graph cylindrical days360 dblint deactivate declare declare_constvalue declare_dimensions declare_fundamental_dimensions declare_fundamental_units declare_qty declare_translated declare_unit_conversion declare_units declare_weights decsym defcon define define_alt_display define_variable defint defmatch defrule defstruct deftaylor degree_sequence del delete deleten delta demo demoivre denom depends derivdegree derivlist describe desolve determinant dfloat dgauss_a dgauss_b dgeev dgemm dgeqrf dgesv dgesvd diag diagmatrix diag_matrix diagmatrixp diameter diff digitcharp dimacs_export dimacs_import dimension dimensionless dimensions dimensions_as_list direct directory discrete_freq disjoin disjointp disolate disp dispcon dispform dispfun dispJordan display disprule dispterms distrib divide divisors divsum dkummer_m dkummer_u dlange dodecahedron_graph dotproduct dotsimp dpart draw draw2d draw3d drawdf draw_file draw_graph dscalar echelon edge_coloring edge_connectivity edges eigens_by_jacobi eigenvalues eigenvectors eighth einstein eivals eivects elapsed_real_time elapsed_run_time ele2comp ele2polynome ele2pui elem elementp elevation_grid elim elim_allbut eliminate eliminate_using ellipse elliptic_e elliptic_ec elliptic_eu elliptic_f elliptic_kc elliptic_pi ematrix empty_graph emptyp endcons entermatrix entertensor entier equal equalp equiv_classes erf erfc erf_generalized erfi errcatch error errormsg errors euler ev eval_string evenp every evolution evolution2d evundiff example exp expand expandwrt expandwrt_factored expint expintegral_chi expintegral_ci expintegral_e expintegral_e1 expintegral_ei expintegral_e_simplify expintegral_li expintegral_shi expintegral_si explicit explose exponentialize express expt exsec extdiff extract_linear_equations extremal_subset ezgcd %f f90 facsum factcomb factor factorfacsum factorial factorout factorsum facts fast_central_elements fast_linsolve fasttimes featurep fernfale fft fib fibtophi fifth filename_merge file_search file_type fillarray findde find_root find_root_abs find_root_error find_root_rel first fix flatten flength float floatnump floor flower_snark flush flush1deriv flushd flushnd flush_output fmin_cobyla forget fortran fourcos fourexpand fourier fourier_elim fourint fourintcos fourintsin foursimp foursin fourth fposition frame_bracket freeof freshline fresnel_c fresnel_s from_adjacency_matrix frucht_graph full_listify fullmap fullmapl fullratsimp fullratsubst fullsetify funcsolve fundamental_dimensions fundamental_units fundef funmake funp fv g0 g1 gamma gamma_greek gamma_incomplete gamma_incomplete_generalized gamma_incomplete_regularized gauss gauss_a gauss_b gaussprob gcd gcdex gcdivide gcfac gcfactor gd generalized_lambert_w genfact gen_laguerre genmatrix gensym geo_amortization geo_annuity_fv geo_annuity_pv geomap geometric geometric_mean geosum get getcurrentdirectory get_edge_weight getenv get_lu_factors get_output_stream_string get_pixel get_plot_option get_tex_environment get_tex_environment_default get_vertex_label gfactor gfactorsum ggf girth global_variances gn gnuplot_close gnuplot_replot gnuplot_reset gnuplot_restart gnuplot_start go Gosper GosperSum gr2d gr3d gradef gramschmidt graph6_decode graph6_encode graph6_export graph6_import graph_center graph_charpoly graph_eigenvalues graph_flow graph_order graph_periphery graph_product graph_size graph_union great_rhombicosidodecahedron_graph great_rhombicuboctahedron_graph grid_graph grind grobner_basis grotzch_graph hamilton_cycle hamilton_path hankel hankel_1 hankel_2 harmonic harmonic_mean hav heawood_graph hermite hessian hgfred hilbertmap hilbert_matrix hipow histogram histogram_description hodge horner hypergeometric i0 i1 %ibes ic1 ic2 ic_convert ichr1 ichr2 icosahedron_graph icosidodecahedron_graph icurvature ident identfor identity idiff idim idummy ieqn %if ifactors iframes ifs igcdex igeodesic_coords ilt image imagpart imetric implicit implicit_derivative implicit_plot indexed_tensor indices induced_subgraph inferencep inference_result infix info_display init_atensor init_ctensor in_neighbors innerproduct inpart inprod inrt integerp integer_partitions integrate intersect intersection intervalp intopois intosum invariant1 invariant2 inverse_fft inverse_jacobi_cd inverse_jacobi_cn inverse_jacobi_cs inverse_jacobi_dc inverse_jacobi_dn inverse_jacobi_ds inverse_jacobi_nc inverse_jacobi_nd inverse_jacobi_ns inverse_jacobi_sc inverse_jacobi_sd inverse_jacobi_sn invert invert_by_adjoint invert_by_lu inv_mod irr is is_biconnected is_bipartite is_connected is_digraph is_edge_in_graph is_graph is_graph_or_digraph ishow is_isomorphic isolate isomorphism is_planar isqrt isreal_p is_sconnected is_tree is_vertex_in_graph items_inference %j j0 j1 jacobi jacobian jacobi_cd jacobi_cn jacobi_cs jacobi_dc jacobi_dn jacobi_ds jacobi_nc jacobi_nd jacobi_ns jacobi_p jacobi_sc jacobi_sd jacobi_sn JF jn join jordan julia julia_set julia_sin %k kdels kdelta kill killcontext kostka kron_delta kronecker_product kummer_m kummer_u kurtosis kurtosis_bernoulli kurtosis_beta kurtosis_binomial kurtosis_chi2 kurtosis_continuous_uniform kurtosis_discrete_uniform kurtosis_exp kurtosis_f kurtosis_gamma kurtosis_general_finite_discrete kurtosis_geometric kurtosis_gumbel kurtosis_hypergeometric kurtosis_laplace kurtosis_logistic kurtosis_lognormal kurtosis_negative_binomial kurtosis_noncentral_chi2 kurtosis_noncentral_student_t kurtosis_normal kurtosis_pareto kurtosis_poisson kurtosis_rayleigh kurtosis_student_t kurtosis_weibull label labels lagrange laguerre lambda lambert_w laplace laplacian_matrix last lbfgs lc2kdt lcharp lc_l lcm lc_u ldefint ldisp ldisplay legendre_p legendre_q leinstein length let letrules letsimp levi_civita lfreeof lgtreillis lhs li liediff limit Lindstedt linear linearinterpol linear_program linear_regression line_graph linsolve listarray list_correlations listify list_matrix_entries list_nc_monomials listoftens listofvars listp lmax lmin load loadfile local locate_matrix_entry log logcontract log_gamma lopow lorentz_gauge lowercasep lpart lratsubst lreduce lriemann lsquares_estimates lsquares_estimates_approximate lsquares_estimates_exact lsquares_mse lsquares_residual_mse lsquares_residuals lsum ltreillis lu_backsub lucas lu_factor %m macroexpand macroexpand1 make_array makebox makefact makegamma make_graph make_level_picture makelist makeOrders make_poly_continent make_poly_country make_polygon make_random_state make_rgb_picture makeset make_string_input_stream make_string_output_stream make_transform mandelbrot mandelbrot_set map mapatom maplist matchdeclare matchfix mat_cond mat_fullunblocker mat_function mathml_display mat_norm matrix matrixmap matrixp matrix_size mattrace mat_trace mat_unblocker max max_clique max_degree max_flow maximize_lp max_independent_set max_matching maybe md5sum mean mean_bernoulli mean_beta mean_binomial mean_chi2 mean_continuous_uniform mean_deviation mean_discrete_uniform mean_exp mean_f mean_gamma mean_general_finite_discrete mean_geometric mean_gumbel mean_hypergeometric mean_laplace mean_logistic mean_lognormal mean_negative_binomial mean_noncentral_chi2 mean_noncentral_student_t mean_normal mean_pareto mean_poisson mean_rayleigh mean_student_t mean_weibull median median_deviation member mesh metricexpandall mgf1_sha1 min min_degree min_edge_cut minfactorial minimalPoly minimize_lp minimum_spanning_tree minor minpack_lsquares minpack_solve min_vertex_cover min_vertex_cut mkdir mnewton mod mode_declare mode_identity ModeMatrix moebius mon2schur mono monomial_dimensions multibernstein_poly multi_display_for_texinfo multi_elem multinomial multinomial_coeff multi_orbit multiplot_mode multi_pui multsym multthru mycielski_graph nary natural_unit nc_degree ncexpt ncharpoly negative_picture neighbors new newcontext newdet new_graph newline newton new_variable next_prime nicedummies niceindices ninth nofix nonarray noncentral_moment nonmetricity nonnegintegerp nonscalarp nonzeroandfreeof notequal nounify nptetrad npv nroots nterms ntermst nthroot nullity nullspace num numbered_boundaries numberp number_to_octets num_distinct_partitions numerval numfactor num_partitions nusum nzeta nzetai nzetar octets_to_number octets_to_oid odd_girth oddp ode2 ode_check odelin oid_to_octets op opena opena_binary openr openr_binary openw openw_binary operatorp opsubst optimize %or orbit orbits ordergreat ordergreatp orderless orderlessp orthogonal_complement orthopoly_recur orthopoly_weight outermap out_neighbors outofpois pade parabolic_cylinder_d parametric parametric_surface parg parGosper parse_string parse_timedate part part2cont partfrac partition partition_set partpol path_digraph path_graph pathname_directory pathname_name pathname_type pdf_bernoulli pdf_beta pdf_binomial pdf_cauchy pdf_chi2 pdf_continuous_uniform pdf_discrete_uniform pdf_exp pdf_f pdf_gamma pdf_general_finite_discrete pdf_geometric pdf_gumbel pdf_hypergeometric pdf_laplace pdf_logistic pdf_lognormal pdf_negative_binomial pdf_noncentral_chi2 pdf_noncentral_student_t pdf_normal pdf_pareto pdf_poisson pdf_rank_sum pdf_rayleigh pdf_signed_rank pdf_student_t pdf_weibull pearson_skewness permanent permut permutation permutations petersen_graph petrov pickapart picture_equalp picturep piechart piechart_description planar_embedding playback plog plot2d plot3d plotdf ploteq plsquares pochhammer points poisdiff poisexpt poisint poismap poisplus poissimp poissubst poistimes poistrim polar polarform polartorect polar_to_xy poly_add poly_buchberger poly_buchberger_criterion poly_colon_ideal poly_content polydecomp poly_depends_p poly_elimination_ideal poly_exact_divide poly_expand poly_expt poly_gcd polygon poly_grobner poly_grobner_equal poly_grobner_member poly_grobner_subsetp poly_ideal_intersection poly_ideal_polysaturation poly_ideal_polysaturation1 poly_ideal_saturation poly_ideal_saturation1 poly_lcm poly_minimization polymod poly_multiply polynome2ele polynomialp poly_normal_form poly_normalize poly_normalize_list poly_polysaturation_extension poly_primitive_part poly_pseudo_divide poly_reduced_grobner poly_reduction poly_saturation_extension poly_s_polynomial poly_subtract polytocompanion pop postfix potential power_mod powerseries powerset prefix prev_prime primep primes principal_components print printf printfile print_graph printpois printprops prodrac product properties propvars psi psubst ptriangularize pui pui2comp pui2ele pui2polynome pui_direct puireduc push put pv qput qrange qty quad_control quad_qag quad_qagi quad_qagp quad_qags quad_qawc quad_qawf quad_qawo quad_qaws quadrilateral quantile quantile_bernoulli quantile_beta quantile_binomial quantile_cauchy quantile_chi2 quantile_continuous_uniform quantile_discrete_uniform quantile_exp quantile_f quantile_gamma quantile_general_finite_discrete quantile_geometric quantile_gumbel quantile_hypergeometric quantile_laplace quantile_logistic quantile_lognormal quantile_negative_binomial quantile_noncentral_chi2 quantile_noncentral_student_t quantile_normal quantile_pareto quantile_poisson quantile_rayleigh quantile_student_t quantile_weibull quartile_skewness quit qunit quotient racah_v racah_w radcan radius random random_bernoulli random_beta random_binomial random_bipartite_graph random_cauchy random_chi2 random_continuous_uniform random_digraph random_discrete_uniform random_exp random_f random_gamma random_general_finite_discrete random_geometric random_graph random_graph1 random_gumbel random_hypergeometric random_laplace random_logistic random_lognormal random_negative_binomial random_network random_noncentral_chi2 random_noncentral_student_t random_normal random_pareto random_permutation random_poisson random_rayleigh random_regular_graph random_student_t random_tournament random_tree random_weibull range rank rat ratcoef ratdenom ratdiff ratdisrep ratexpand ratinterpol rational rationalize ratnumer ratnump ratp ratsimp ratsubst ratvars ratweight read read_array read_binary_array read_binary_list read_binary_matrix readbyte readchar read_hashed_array readline read_list read_matrix read_nested_list readonly read_xpm real_imagpart_to_conjugate realpart realroots rearray rectangle rectform rectform_log_if_constant recttopolar rediff reduce_consts reduce_order region region_boundaries region_boundaries_plus rem remainder remarray rembox remcomps remcon remcoord remfun remfunction remlet remove remove_constvalue remove_dimensions remove_edge remove_fundamental_dimensions remove_fundamental_units remove_plot_option remove_vertex rempart remrule remsym remvalue rename rename_file reset reset_displays residue resolvante resolvante_alternee1 resolvante_bipartite resolvante_diedrale resolvante_klein resolvante_klein3 resolvante_produit_sym resolvante_unitaire resolvante_vierer rest resultant return reveal reverse revert revert2 rgb2level rhs ricci riemann rinvariant risch rk rmdir rncombine romberg room rootscontract round row rowop rowswap rreduce run_testsuite %s save saving scalarp scaled_bessel_i scaled_bessel_i0 scaled_bessel_i1 scalefactors scanmap scatterplot scatterplot_description scene schur2comp sconcat scopy scsimp scurvature sdowncase sec sech second sequal sequalignore set_alt_display setdifference set_draw_defaults set_edge_weight setelmx setequalp setify setp set_partitions set_plot_option set_prompt set_random_state set_tex_environment set_tex_environment_default setunits setup_autoload set_up_dot_simplifications set_vertex_label seventh sexplode sf sha1sum sha256sum shortest_path shortest_weighted_path show showcomps showratvars sierpinskiale sierpinskimap sign signum similaritytransform simp_inequality simplify_sum simplode simpmetderiv simtran sin sinh sinsert sinvertcase sixth skewness skewness_bernoulli skewness_beta skewness_binomial skewness_chi2 skewness_continuous_uniform skewness_discrete_uniform skewness_exp skewness_f skewness_gamma skewness_general_finite_discrete skewness_geometric skewness_gumbel skewness_hypergeometric skewness_laplace skewness_logistic skewness_lognormal skewness_negative_binomial skewness_noncentral_chi2 skewness_noncentral_student_t skewness_normal skewness_pareto skewness_poisson skewness_rayleigh skewness_student_t skewness_weibull slength smake small_rhombicosidodecahedron_graph small_rhombicuboctahedron_graph smax smin smismatch snowmap snub_cube_graph snub_dodecahedron_graph solve solve_rec solve_rec_rat some somrac sort sparse6_decode sparse6_encode sparse6_export sparse6_import specint spherical spherical_bessel_j spherical_bessel_y spherical_hankel1 spherical_hankel2 spherical_harmonic spherical_to_xyz splice split sposition sprint sqfr sqrt sqrtdenest sremove sremovefirst sreverse ssearch ssort sstatus ssubst ssubstfirst staircase standardize standardize_inverse_trig starplot starplot_description status std std1 std_bernoulli std_beta std_binomial std_chi2 std_continuous_uniform std_discrete_uniform std_exp std_f std_gamma std_general_finite_discrete std_geometric std_gumbel std_hypergeometric std_laplace std_logistic std_lognormal std_negative_binomial std_noncentral_chi2 std_noncentral_student_t std_normal std_pareto std_poisson std_rayleigh std_student_t std_weibull stemplot stirling stirling1 stirling2 strim striml strimr string stringout stringp strong_components struve_h struve_l sublis sublist sublist_indices submatrix subsample subset subsetp subst substinpart subst_parallel substpart substring subvar subvarp sum sumcontract summand_to_rec supcase supcontext symbolp symmdifference symmetricp system take_channel take_inference tan tanh taylor taylorinfo taylorp taylor_simplifier taytorat tcl_output tcontract tellrat tellsimp tellsimpafter tentex tenth test_mean test_means_difference test_normality test_proportion test_proportions_difference test_rank_sum test_sign test_signed_rank test_variance test_variance_ratio tex tex1 tex_display texput %th third throw time timedate timer timer_info tldefint tlimit todd_coxeter toeplitz tokens to_lisp topological_sort to_poly to_poly_solve totaldisrep totalfourier totient tpartpol trace tracematrix trace_options transform_sample translate translate_file transpose treefale tree_reduce treillis treinat triangle triangularize trigexpand trigrat trigreduce trigsimp trunc truncate truncated_cube_graph truncated_dodecahedron_graph truncated_icosahedron_graph truncated_tetrahedron_graph tr_warnings_get tube tutte_graph ueivects uforget ultraspherical underlying_graph undiff union unique uniteigenvectors unitp units unit_step unitvector unorder unsum untellrat untimer untrace uppercasep uricci uriemann uvect vandermonde_matrix var var1 var_bernoulli var_beta var_binomial var_chi2 var_continuous_uniform var_discrete_uniform var_exp var_f var_gamma var_general_finite_discrete var_geometric var_gumbel var_hypergeometric var_laplace var_logistic var_lognormal var_negative_binomial var_noncentral_chi2 var_noncentral_student_t var_normal var_pareto var_poisson var_rayleigh var_student_t var_weibull vector vectorpotential vectorsimp verbify vers vertex_coloring vertex_connectivity vertex_degree vertex_distance vertex_eccentricity vertex_in_degree vertex_out_degree vertices vertices_to_cycle vertices_to_path %w weyl wheel_graph wiener_index wigner_3j wigner_6j wigner_9j with_stdout write_binary_data writebyte write_data writefile wronskian xreduce xthru %y Zeilberger zeroequiv zerofor zeromatrix zeromatrixp zeta zgeev zheev zlange zn_add_table zn_carmichael_lambda zn_characteristic_factors zn_determinant zn_factor_generators zn_invert_by_lu zn_log zn_mult_table absboxchar activecontexts adapt_depth additive adim aform algebraic algepsilon algexact aliases allbut all_dotsimp_denoms allocation allsym alphabetic animation antisymmetric arrays askexp assume_pos assume_pos_pred assumescalar asymbol atomgrad atrig1 axes axis_3d axis_bottom axis_left axis_right axis_top azimuth background background_color backsubst berlefact bernstein_explicit besselexpand beta_args_sum_to_integer beta_expand bftorat bftrunc bindtest border boundaries_array box boxchar breakup %c capping cauchysum cbrange cbtics center cflength cframe_flag cnonmet_flag color color_bar color_bar_tics colorbox columns commutative complex cone context contexts contour contour_levels cosnpiflag ctaypov ctaypt ctayswitch ctayvar ct_coords ctorsion_flag ctrgsimp cube current_let_rule_package cylinder data_file_name debugmode decreasing default_let_rule_package delay dependencies derivabbrev derivsubst detout diagmetric diff dim dimensions dispflag display2d|10 display_format_internal distribute_over doallmxops domain domxexpt domxmxops domxnctimes dontfactor doscmxops doscmxplus dot0nscsimp dot0simp dot1simp dotassoc dotconstrules dotdistrib dotexptsimp dotident dotscrules draw_graph_program draw_realpart edge_color edge_coloring edge_partition edge_type edge_width %edispflag elevation %emode endphi endtheta engineering_format_floats enhanced3d %enumer epsilon_lp erfflag erf_representation errormsg error_size error_syms error_type %e_to_numlog eval even evenfun evflag evfun ev_point expandwrt_denom expintexpand expintrep expon expop exptdispflag exptisolate exptsubst facexpand facsum_combine factlim factorflag factorial_expand factors_only fb feature features file_name file_output_append file_search_demo file_search_lisp file_search_maxima|10 file_search_tests file_search_usage file_type_lisp file_type_maxima|10 fill_color fill_density filled_func fixed_vertices flipflag float2bf font font_size fortindent fortspaces fpprec fpprintprec functions gamma_expand gammalim gdet genindex gensumnum GGFCFMAX GGFINFINITY globalsolve gnuplot_command gnuplot_curve_styles gnuplot_curve_titles gnuplot_default_term_command gnuplot_dumb_term_command gnuplot_file_args gnuplot_file_name gnuplot_out_file gnuplot_pdf_term_command gnuplot_pm3d gnuplot_png_term_command gnuplot_postamble gnuplot_preamble gnuplot_ps_term_command gnuplot_svg_term_command gnuplot_term gnuplot_view_args Gosper_in_Zeilberger gradefs grid grid2d grind halfangles head_angle head_both head_length head_type height hypergeometric_representation %iargs ibase icc1 icc2 icounter idummyx ieqnprint ifb ifc1 ifc2 ifg ifgi ifr iframe_bracket_form ifri igeowedge_flag ikt1 ikt2 imaginary inchar increasing infeval infinity inflag infolists inm inmc1 inmc2 intanalysis integer integervalued integrate_use_rootsof integration_constant integration_constant_counter interpolate_color intfaclim ip_grid ip_grid_in irrational isolate_wrt_times iterations itr julia_parameter %k1 %k2 keepfloat key key_pos kinvariant kt label label_alignment label_orientation labels lassociative lbfgs_ncorrections lbfgs_nfeval_max leftjust legend letrat let_rule_packages lfg lg lhospitallim limsubst linear linear_solver linechar linel|10 linenum line_type linewidth line_width linsolve_params linsolvewarn lispdisp listarith listconstvars listdummyvars lmxchar load_pathname loadprint logabs logarc logcb logconcoeffp logexpand lognegint logsimp logx logx_secondary logy logy_secondary logz lriem m1pbranch macroexpansion macros mainvar manual_demo maperror mapprint matrix_element_add matrix_element_mult matrix_element_transpose maxapplydepth maxapplyheight maxima_tempdir|10 maxima_userdir|10 maxnegex MAX_ORD maxposex maxpsifracdenom maxpsifracnum maxpsinegint maxpsiposint maxtayorder mesh_lines_color method mod_big_prime mode_check_errorp mode_checkp mode_check_warnp mod_test mod_threshold modular_linear_solver modulus multiplicative multiplicities myoptions nary negdistrib negsumdispflag newline newtonepsilon newtonmaxiter nextlayerfactor niceindicespref nm nmc noeval nolabels nonegative_lp noninteger nonscalar noun noundisp nouns np npi nticks ntrig numer numer_pbranch obase odd oddfun opacity opproperties opsubst optimprefix optionset orientation origin orthopoly_returns_intervals outative outchar packagefile palette partswitch pdf_file pfeformat phiresolution %piargs piece pivot_count_sx pivot_max_sx plot_format plot_options plot_realpart png_file pochhammer_max_index points pointsize point_size points_joined point_type poislim poisson poly_coefficient_ring poly_elimination_order polyfactor poly_grobner_algorithm poly_grobner_debug poly_monomial_order poly_primary_elimination_order poly_return_term_list poly_secondary_elimination_order poly_top_reduction_only posfun position powerdisp pred prederror primep_number_of_tests product_use_gamma program programmode promote_float_to_bigfloat prompt proportional_axes props psexpand ps_file radexpand radius radsubstflag rassociative ratalgdenom ratchristof ratdenomdivide rateinstein ratepsilon ratfac rational ratmx ratprint ratriemann ratsimpexpons ratvarswitch ratweights ratweyl ratwtlvl real realonly redraw refcheck resolution restart resultant ric riem rmxchar %rnum_list rombergabs rombergit rombergmin rombergtol rootsconmode rootsepsilon run_viewer same_xy same_xyz savedef savefactors scalar scalarmatrixp scale scale_lp setcheck setcheckbreak setval show_edge_color show_edges show_edge_type show_edge_width show_id show_label showtime show_vertex_color show_vertex_size show_vertex_type show_vertices show_weight simp simplified_output simplify_products simpproduct simpsum sinnpiflag solvedecomposes solveexplicit solvefactors solvenullwarn solveradcan solvetrigwarn space sparse sphere spring_embedding_depth sqrtdispflag stardisp startphi starttheta stats_numer stringdisp structures style sublis_apply_lambda subnumsimp sumexpand sumsplitfact surface surface_hide svg_file symmetric tab taylordepth taylor_logexpand taylor_order_coefficients taylor_truncate_polynomials tensorkill terminal testsuite_files thetaresolution timer_devalue title tlimswitch tr track transcompile transform transform_xy translate_fast_arrays transparent transrun tr_array_as_ref tr_bound_function_applyp tr_file_tty_messagesp tr_float_can_branch_complex tr_function_call_default trigexpandplus trigexpandtimes triginverses trigsign trivial_solutions tr_numer tr_optimize_max_loop tr_semicompile tr_state_vars tr_warn_bad_function_calls tr_warn_fexpr tr_warn_meval tr_warn_mode tr_warn_undeclared tr_warn_undefined_variable tstep ttyoff tube_extremes ufg ug %unitexpand unit_vectors uric uriem use_fast_arrays user_preamble usersetunits values vect_cross verbose vertex_color vertex_coloring vertex_partition vertex_size vertex_type view warnings weyl width windowname windowtitle wired_surface wireframe xaxis xaxis_color xaxis_secondary xaxis_type xaxis_width xlabel xlabel_secondary xlength xrange xrange_secondary xtics xtics_axis xtics_rotate xtics_rotate_secondary xtics_secondary xtics_secondary_axis xu_grid x_voxel xy_file xyplane xy_scale yaxis yaxis_color yaxis_secondary yaxis_type yaxis_width ylabel ylabel_secondary ylength yrange yrange_secondary ytics ytics_axis ytics_rotate ytics_rotate_secondary ytics_secondary ytics_secondary_axis yv_grid y_voxel yx_ratio zaxis zaxis_color zaxis_type zaxis_width zeroa zerob zerobern zeta%pi zlabel zlabel_rotate zlength zmin zn_primroot_limit zn_primroot_pretest",i="_ __ %|0 %%|0";return{l:"[A-Za-z_%][0-9A-Za-z_%]*",k:{keyword:t,literal:a,built_in:r,symbol:i},c:[{cN:"comment",b:"/\\*",e:"\\*/",c:["self"]},e.QSM,{cN:"number",r:0,v:[{b:"\\b(\\d+|\\d+\\.|\\.\\d+|\\d+\\.\\d+)[Ee][-+]?\\d+\\b"},{b:"\\b(\\d+|\\d+\\.|\\.\\d+|\\d+\\.\\d+)[Bb][-+]?\\d+\\b",r:10},{b:"\\b(\\.\\d+|\\d+\\.\\d+)\\b"},{b:"\\b(\\d+|0[0-9A-Za-z]+)\\.?\\b"}]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/mel.js b/lib/highlight_js/assets/lang/mel.js index 639a4a6594f..cb5f45347d2 100644 --- a/lib/highlight_js/assets/lang/mel.js +++ b/lib/highlight_js/assets/lang/mel.js @@ -1 +1 @@ -hljs.registerLanguage("mel",function(e){return{k:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",i:""},{b:"<=",r:0},{b:"=>",r:0},{b:"/\\\\"},{b:"\\\\/"}]},c={cN:"built_in",v:[{b:":-\\|-->"},{b:"=",r:0}]};return{aliases:["m","moo"],k:i,c:[s,c,t,_,n,e.NM,a,o,{b:/:-/}]}}); \ No newline at end of file +hljs.registerLanguage("mercury",function(e){var i={keyword:"module use_module import_module include_module end_module initialise mutable initialize finalize finalise interface implementation pred mode func type inst solver any_pred any_func is semidet det nondet multi erroneous failure cc_nondet cc_multi typeclass instance where pragma promise external trace atomic or_else require_complete_switch require_det require_semidet require_multi require_nondet require_cc_multi require_cc_nondet require_erroneous require_failure",meta:"inline no_inline type_spec source_file fact_table obsolete memo loop_check minimal_model terminates does_not_terminate check_termination promise_equivalent_clauses foreign_proc foreign_decl foreign_code foreign_type foreign_import_module foreign_export_enum foreign_export foreign_enum may_call_mercury will_not_call_mercury thread_safe not_thread_safe maybe_thread_safe promise_pure promise_semipure tabled_for_io local untrailed trailed attach_to_io_state can_pass_as_mercury_type stable will_not_throw_exception may_modify_trail will_not_modify_trail may_duplicate may_not_duplicate affects_liveness does_not_affect_liveness doesnt_affect_liveness no_sharing unknown_sharing sharing",built_in:"some all not if then else true fail false try catch catch_any semidet_true semidet_false semidet_fail impure_true impure semipure"},r=e.C("%","$"),t={cN:"number",b:"0'.\\|0[box][0-9a-fA-F]*"},_=e.inherit(e.ASM,{r:0}),n=e.inherit(e.QSM,{r:0}),a={cN:"subst",b:"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]",r:0};n.c.push(a);var o={cN:"built_in",v:[{b:"<=>"},{b:"<=",r:0},{b:"=>",r:0},{b:"/\\\\"},{b:"\\\\/"}]},l={cN:"built_in",v:[{b:":-\\|-->"},{b:"=",r:0}]};return{aliases:["m","moo"],k:i,c:[o,l,r,e.CBCM,t,e.NM,_,n,{b:/:-/}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/mipsasm.js b/lib/highlight_js/assets/lang/mipsasm.js new file mode 100644 index 00000000000..0662193ff1e --- /dev/null +++ b/lib/highlight_js/assets/lang/mipsasm.js @@ -0,0 +1 @@ +hljs.registerLanguage("mipsasm",function(s){return{cI:!0,aliases:["mips"],l:"\\.?"+s.IR,k:{meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .ltorg ",built_in:"$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $20 $21 $22 $23 $24 $25 $26 $27 $28 $29 $30 $31 zero at v0 v1 a0 a1 a2 a3 a4 a5 a6 a7 t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 s0 s1 s2 s3 s4 s5 s6 s7 s8 k0 k1 gp sp fp ra $f0 $f1 $f2 $f2 $f4 $f5 $f6 $f7 $f8 $f9 $f10 $f11 $f12 $f13 $f14 $f15 $f16 $f17 $f18 $f19 $f20 $f21 $f22 $f23 $f24 $f25 $f26 $f27 $f28 $f29 $f30 $f31 Context Random EntryLo0 EntryLo1 Context PageMask Wired EntryHi HWREna BadVAddr Count Compare SR IntCtl SRSCtl SRSMap Cause EPC PRId EBase Config Config1 Config2 Config3 LLAddr Debug DEPC DESAVE CacheErr ECC ErrorEPC TagLo DataLo TagHi DataHi WatchLo WatchHi PerfCtl PerfCnt "},c:[{cN:"keyword",b:"\\b(addi?u?|andi?|b(al)?|beql?|bgez(al)?l?|bgtzl?|blezl?|bltz(al)?l?|bnel?|cl[oz]|divu?|ext|ins|j(al)?|jalr(.hb)?|jr(.hb)?|lbu?|lhu?|ll|lui|lw[lr]?|maddu?|mfhi|mflo|movn|movz|move|msubu?|mthi|mtlo|mul|multu?|nop|nor|ori?|rotrv?|sb|sc|se[bh]|sh|sllv?|slti?u?|srav?|srlv?|subu?|sw[lr]?|xori?|wsbh|abs.[sd]|add.[sd]|alnv.ps|bc1[ft]l?|c.(s?f|un|u?eq|[ou]lt|[ou]le|ngle?|seq|l[et]|ng[et]).[sd]|(ceil|floor|round|trunc).[lw].[sd]|cfc1|cvt.d.[lsw]|cvt.l.[dsw]|cvt.ps.s|cvt.s.[dlw]|cvt.s.p[lu]|cvt.w.[dls]|div.[ds]|ldx?c1|luxc1|lwx?c1|madd.[sd]|mfc1|mov[fntz]?.[ds]|msub.[sd]|mth?c1|mul.[ds]|neg.[ds]|nmadd.[ds]|nmsub.[ds]|p[lu][lu].ps|recip.fmt|r?sqrt.[ds]|sdx?c1|sub.[ds]|suxc1|swx?c1|break|cache|d?eret|[de]i|ehb|mfc0|mtc0|pause|prefx?|rdhwr|rdpgpr|sdbbp|ssnop|synci?|syscall|teqi?|tgei?u?|tlb(p|r|w[ir])|tlti?u?|tnei?|wait|wrpgpr)",e:"\\s"},s.C("[;#]","$"),s.CBCM,s.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"title",b:"\\|",e:"\\|",i:"\\n",r:0},{cN:"number",v:[{b:"0x[0-9a-f]+"},{b:"\\b-?\\d+"}],r:0},{cN:"symbol",v:[{b:"^\\s*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{b:"^\\s*[0-9]+:"},{b:"[0-9]+[bf]"}],r:0}],i:"/"}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/mojolicious.js b/lib/highlight_js/assets/lang/mojolicious.js new file mode 100644 index 00000000000..5c76a546def --- /dev/null +++ b/lib/highlight_js/assets/lang/mojolicious.js @@ -0,0 +1 @@ +hljs.registerLanguage("mojolicious",function(e){return{sL:"xml",c:[{cN:"meta",b:"^__(END|DATA)__$"},{b:"^\\s*%{1,2}={0,2}",e:"$",sL:"perl"},{b:"<%{1,2}={0,2}",e:"={0,1}%>",sL:"perl",eB:!0,eE:!0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/monkey.js b/lib/highlight_js/assets/lang/monkey.js index cb123439af3..6bef9e18380 100644 --- a/lib/highlight_js/assets/lang/monkey.js +++ b/lib/highlight_js/assets/lang/monkey.js @@ -1 +1 @@ -hljs.registerLanguage("monkey",function(e){var n={cN:"number",r:0,v:[{b:"[$][a-fA-F0-9]+"},e.NM]};return{cI:!0,k:{keyword:"public private property continue exit extern new try catch eachin not abstract final select case default const local global field end if then else elseif endif while wend repeat until forever for to step next return module inline throw",built_in:"DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI",literal:"true false null and or shl shr mod"},c:[e.C("#rem","#end"),e.C("'","$",{r:0}),{cN:"function",bK:"function method",e:"[(=:]|$",i:/\n/,c:[e.UTM]},{cN:"class",bK:"class interface",e:"$",c:[{bK:"extends implements"},e.UTM]},{cN:"variable",b:"\\b(self|super)\\b"},{cN:"preprocessor",bK:"import",e:"$"},{cN:"preprocessor",b:"\\s*#",e:"$",k:"if else elseif endif end then"},{cN:"pi",b:"^\\s*strict\\b"},{bK:"alias",e:"=",c:[e.UTM]},e.QSM,n]}}); \ No newline at end of file +hljs.registerLanguage("monkey",function(e){var n={cN:"number",r:0,v:[{b:"[$][a-fA-F0-9]+"},e.NM]};return{cI:!0,k:{keyword:"public private property continue exit extern new try catch eachin not abstract final select case default const local global field end if then else elseif endif while wend repeat until forever for to step next return module inline throw import",built_in:"DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI",literal:"true false null and or shl shr mod"},i:/\/\*/,c:[e.C("#rem","#end"),e.C("'","$",{r:0}),{cN:"function",bK:"function method",e:"[(=:]|$",i:/\n/,c:[e.UTM]},{cN:"class",bK:"class interface",e:"$",c:[{bK:"extends implements"},e.UTM]},{cN:"built_in",b:"\\b(self|super)\\b"},{cN:"meta",b:"\\s*#",e:"$",k:{"meta-keyword":"if else elseif endif end then"}},{cN:"meta",b:"^\\s*strict\\b"},{bK:"alias",e:"=",c:[e.UTM]},e.QSM,n]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/nginx.js b/lib/highlight_js/assets/lang/nginx.js index 8131f37aad4..9e2df57c1f6 100644 --- a/lib/highlight_js/assets/lang/nginx.js +++ b/lib/highlight_js/assets/lang/nginx.js @@ -1 +1 @@ -hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"title",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}}); \ No newline at end of file +hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/nimrod.js b/lib/highlight_js/assets/lang/nimrod.js index 02774be244d..dfdb41db7f7 100644 --- a/lib/highlight_js/assets/lang/nimrod.js +++ b/lib/highlight_js/assets/lang/nimrod.js @@ -1 +1 @@ -hljs.registerLanguage("nimrod",function(t){return{aliases:["nim"],k:{keyword:"addr and as asm bind block break|0 case|0 cast const|0 continue|0 converter discard distinct|10 div do elif else|0 end|0 enum|0 except export finally for from generic if|0 import|0 in include|0 interface is isnot|10 iterator|10 let|0 macro method|10 mixin mod nil not notin|10 object|0 of or out proc|10 ptr raise ref|10 return shl shr static template|10 try|0 tuple type|0 using|0 var|0 when while|0 with without xor yield",literal:"shared guarded stdin stdout stderr result|10 true false"},c:[{cN:"decorator",b:/{\./,e:/\.}/,r:10},{cN:"string",b:/[a-zA-Z]\w*"/,e:/"/,c:[{b:/""/}]},{cN:"string",b:/([a-zA-Z]\w*)?"""/,e:/"""/},t.QSM,{cN:"type",b:/\b[A-Z]\w+\b/,r:0},{cN:"type",b:/\b(int|int8|int16|int32|int64|uint|uint8|uint16|uint32|uint64|float|float32|float64|bool|char|string|cstring|pointer|expr|stmt|void|auto|any|range|array|openarray|varargs|seq|set|clong|culong|cchar|cschar|cshort|cint|csize|clonglong|cfloat|cdouble|clongdouble|cuchar|cushort|cuint|culonglong|cstringarray|semistatic)\b/},{cN:"number",b:/\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/,r:0},{cN:"number",b:/\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/,r:0},{cN:"number",b:/\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/,r:0},{cN:"number",b:/\b(\d[_\d]*)('?[iIuUfF](8|16|32|64))?/,r:0},t.HCM]}}); \ No newline at end of file +hljs.registerLanguage("nimrod",function(t){return{aliases:["nim"],k:{keyword:"addr and as asm bind block break case cast const continue converter discard distinct div do elif else end enum except export finally for from generic if import in include interface is isnot iterator let macro method mixin mod nil not notin object of or out proc ptr raise ref return shl shr static template try tuple type using var when while with without xor yield",literal:"shared guarded stdin stdout stderr result true false",built_in:"int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 bool char string cstring pointer expr stmt void auto any range array openarray varargs seq set clong culong cchar cschar cshort cint csize clonglong cfloat cdouble clongdouble cuchar cushort cuint culonglong cstringarray semistatic"},c:[{cN:"meta",b:/{\./,e:/\.}/,r:10},{cN:"string",b:/[a-zA-Z]\w*"/,e:/"/,c:[{b:/""/}]},{cN:"string",b:/([a-zA-Z]\w*)?"""/,e:/"""/},t.QSM,{cN:"type",b:/\b[A-Z]\w+\b/,r:0},{cN:"number",r:0,v:[{b:/\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/},{b:/\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/},{b:/\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/},{b:/\b(\d[_\d]*)('?[iIuUfF](8|16|32|64))?/}]},t.HCM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/nix.js b/lib/highlight_js/assets/lang/nix.js index 562874efff6..984f0d29664 100644 --- a/lib/highlight_js/assets/lang/nix.js +++ b/lib/highlight_js/assets/lang/nix.js @@ -1 +1 @@ -hljs.registerLanguage("nix",function(e){var t={keyword:"rec with let in inherit assert if else then",constant:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},i={cN:"subst",b:/\$\{/,e:/}/,k:t},r={cN:"variable",b:/[a-zA-Z0-9-_]+(\s*=)/},n={cN:"string",b:"''",e:"''",c:[i]},s={cN:"string",b:'"',e:'"',c:[i]},a=[e.NM,e.HCM,e.CBCM,n,s,r];return i.c=a,{aliases:["nixos"],k:t,c:a}}); \ No newline at end of file +hljs.registerLanguage("nix",function(e){var r={keyword:"rec with let in inherit assert if else then",literal:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},t={cN:"subst",b:/\$\{/,e:/}/,k:r},i={b:/[a-zA-Z0-9-_]+(\s*=)/,rB:!0,r:0,c:[{cN:"attr",b:/\S+/}]},s={cN:"string",c:[t],v:[{b:"''",e:"''"},{b:'"',e:'"'}]},a=[e.NM,e.HCM,e.CBCM,s,i];return t.c=a,{aliases:["nixos"],k:r,c:a}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/nsis.js b/lib/highlight_js/assets/lang/nsis.js index d6c072dc8ba..62802cc468a 100644 --- a/lib/highlight_js/assets/lang/nsis.js +++ b/lib/highlight_js/assets/lang/nsis.js @@ -1 +1 @@ -hljs.registerLanguage("nsis",function(e){var t={cN:"symbol",b:"\\$(ADMINTOOLS|APPDATA|CDBURN_AREA|CMDLINE|COMMONFILES32|COMMONFILES64|COMMONFILES|COOKIES|DESKTOP|DOCUMENTS|EXEDIR|EXEFILE|EXEPATH|FAVORITES|FONTS|HISTORY|HWNDPARENT|INSTDIR|INTERNET_CACHE|LANGUAGE|LOCALAPPDATA|MUSIC|NETHOOD|OUTDIR|PICTURES|PLUGINSDIR|PRINTHOOD|PROFILE|PROGRAMFILES32|PROGRAMFILES64|PROGRAMFILES|QUICKLAUNCH|RECENT|RESOURCES_LOCALIZED|RESOURCES|SENDTO|SMPROGRAMS|SMSTARTUP|STARTMENU|SYSDIR|TEMP|TEMPLATES|VIDEOS|WINDIR)"},n={cN:"constant",b:"\\$+{[a-zA-Z0-9_]+}"},i={cN:"variable",b:"\\$+[a-zA-Z0-9_]+",i:"\\(\\){}"},r={cN:"constant",b:"\\$+\\([a-zA-Z0-9_]+\\)"},o={cN:"params",b:"(ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)"},l={cN:"constant",b:"\\!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|else|endif|error|execute|finalize|getdllversionsystem|ifdef|ifmacrodef|ifmacrondef|ifndef|if|include|insertmacro|macroend|macro|makensis|packhdr|searchparse|searchreplace|tempfile|undef|verbose|warning)"};return{cI:!1,k:{keyword:"Abort AddBrandingImage AddSize AllowRootDirInstall AllowSkipFiles AutoCloseWindow BGFont BGGradient BrandingText BringToFront Call CallInstDLL Caption ChangeUI CheckBitmap ClearErrors CompletedText ComponentText CopyFiles CRCCheck CreateDirectory CreateFont CreateShortCut Delete DeleteINISec DeleteINIStr DeleteRegKey DeleteRegValue DetailPrint DetailsButtonText DirText DirVar DirVerify EnableWindow EnumRegKey EnumRegValue Exch Exec ExecShell ExecWait ExpandEnvStrings File FileBufSize FileClose FileErrorText FileOpen FileRead FileReadByte FileReadUTF16LE FileReadWord FileSeek FileWrite FileWriteByte FileWriteUTF16LE FileWriteWord FindClose FindFirst FindNext FindWindow FlushINI FunctionEnd GetCurInstType GetCurrentAddress GetDlgItem GetDLLVersion GetDLLVersionLocal GetErrorLevel GetFileTime GetFileTimeLocal GetFullPathName GetFunctionAddress GetInstDirError GetLabelAddress GetTempFileName Goto HideWindow Icon IfAbort IfErrors IfFileExists IfRebootFlag IfSilent InitPluginsDir InstallButtonText InstallColors InstallDir InstallDirRegKey InstProgressFlags InstType InstTypeGetText InstTypeSetText IntCmp IntCmpU IntFmt IntOp IsWindow LangString LicenseBkColor LicenseData LicenseForceSelection LicenseLangString LicenseText LoadLanguageFile LockWindow LogSet LogText ManifestDPIAware ManifestSupportedOS MessageBox MiscButtonText Name Nop OutFile Page PageCallbacks PageExEnd Pop Push Quit ReadEnvStr ReadINIStr ReadRegDWORD ReadRegStr Reboot RegDLL Rename RequestExecutionLevel ReserveFile Return RMDir SearchPath SectionEnd SectionGetFlags SectionGetInstTypes SectionGetSize SectionGetText SectionGroupEnd SectionIn SectionSetFlags SectionSetInstTypes SectionSetSize SectionSetText SendMessage SetAutoClose SetBrandingImage SetCompress SetCompressor SetCompressorDictSize SetCtlColors SetCurInstType SetDatablockOptimize SetDateSave SetDetailsPrint SetDetailsView SetErrorLevel SetErrors SetFileAttributes SetFont SetOutPath SetOverwrite SetPluginUnload SetRebootFlag SetRegView SetShellVarContext SetSilent ShowInstDetails ShowUninstDetails ShowWindow SilentInstall SilentUnInstall Sleep SpaceTexts StrCmp StrCmpS StrCpy StrLen SubCaption SubSectionEnd Unicode UninstallButtonText UninstallCaption UninstallIcon UninstallSubCaption UninstallText UninstPage UnRegDLL Var VIAddVersionKey VIFileVersion VIProductVersion WindowIcon WriteINIStr WriteRegBin WriteRegDWORD WriteRegExpandStr WriteRegStr WriteUninstaller XPStyle",literal:"admin all auto both colored current false force hide highest lastused leave listonly none normal notset off on open print show silent silentlog smooth textonly true user "},c:[e.HCM,e.CBCM,{cN:"string",b:'"',e:'"',i:"\\n",c:[{cN:"symbol",b:"\\$(\\\\(n|r|t)|\\$)"},t,n,i,r]},e.C(";","$",{r:0}),{cN:"function",bK:"Function PageEx Section SectionGroup SubSection",e:"$"},l,n,i,r,o,e.NM,{cN:"literal",b:e.IR+"::"+e.IR}]}}); \ No newline at end of file +hljs.registerLanguage("nsis",function(e){var t={cN:"variable",b:"\\$(ADMINTOOLS|APPDATA|CDBURN_AREA|CMDLINE|COMMONFILES32|COMMONFILES64|COMMONFILES|COOKIES|DESKTOP|DOCUMENTS|EXEDIR|EXEFILE|EXEPATH|FAVORITES|FONTS|HISTORY|HWNDPARENT|INSTDIR|INTERNET_CACHE|LANGUAGE|LOCALAPPDATA|MUSIC|NETHOOD|OUTDIR|PICTURES|PLUGINSDIR|PRINTHOOD|PROFILE|PROGRAMFILES32|PROGRAMFILES64|PROGRAMFILES|QUICKLAUNCH|RECENT|RESOURCES_LOCALIZED|RESOURCES|SENDTO|SMPROGRAMS|SMSTARTUP|STARTMENU|SYSDIR|TEMP|TEMPLATES|VIDEOS|WINDIR)"},i={cN:"variable",b:"\\$+{[a-zA-Z0-9_]+}"},n={cN:"variable",b:"\\$+[a-zA-Z0-9_]+",i:"\\(\\){}"},r={cN:"variable",b:"\\$+\\([a-zA-Z0-9_]+\\)"},l={cN:"built_in",b:"(ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)"},o={cN:"keyword",b:"\\!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|else|endif|error|execute|finalize|getdllversionsystem|ifdef|ifmacrodef|ifmacrondef|ifndef|if|include|insertmacro|macroend|macro|makensis|packhdr|searchparse|searchreplace|tempfile|undef|verbose|warning)"};return{cI:!1,k:{keyword:"Abort AddBrandingImage AddSize AllowRootDirInstall AllowSkipFiles AutoCloseWindow BGFont BGGradient BrandingText BringToFront Call CallInstDLL Caption ChangeUI CheckBitmap ClearErrors CompletedText ComponentText CopyFiles CRCCheck CreateDirectory CreateFont CreateShortCut Delete DeleteINISec DeleteINIStr DeleteRegKey DeleteRegValue DetailPrint DetailsButtonText DirText DirVar DirVerify EnableWindow EnumRegKey EnumRegValue Exch Exec ExecShell ExecWait ExpandEnvStrings File FileBufSize FileClose FileErrorText FileOpen FileRead FileReadByte FileReadUTF16LE FileReadWord FileSeek FileWrite FileWriteByte FileWriteUTF16LE FileWriteWord FindClose FindFirst FindNext FindWindow FlushINI FunctionEnd GetCurInstType GetCurrentAddress GetDlgItem GetDLLVersion GetDLLVersionLocal GetErrorLevel GetFileTime GetFileTimeLocal GetFullPathName GetFunctionAddress GetInstDirError GetLabelAddress GetTempFileName Goto HideWindow Icon IfAbort IfErrors IfFileExists IfRebootFlag IfSilent InitPluginsDir InstallButtonText InstallColors InstallDir InstallDirRegKey InstProgressFlags InstType InstTypeGetText InstTypeSetText IntCmp IntCmpU IntFmt IntOp IsWindow LangString LicenseBkColor LicenseData LicenseForceSelection LicenseLangString LicenseText LoadLanguageFile LockWindow LogSet LogText ManifestDPIAware ManifestSupportedOS MessageBox MiscButtonText Name Nop OutFile Page PageCallbacks PageExEnd Pop Push Quit ReadEnvStr ReadINIStr ReadRegDWORD ReadRegStr Reboot RegDLL Rename RequestExecutionLevel ReserveFile Return RMDir SearchPath SectionEnd SectionGetFlags SectionGetInstTypes SectionGetSize SectionGetText SectionGroupEnd SectionIn SectionSetFlags SectionSetInstTypes SectionSetSize SectionSetText SendMessage SetAutoClose SetBrandingImage SetCompress SetCompressor SetCompressorDictSize SetCtlColors SetCurInstType SetDatablockOptimize SetDateSave SetDetailsPrint SetDetailsView SetErrorLevel SetErrors SetFileAttributes SetFont SetOutPath SetOverwrite SetPluginUnload SetRebootFlag SetRegView SetShellVarContext SetSilent ShowInstDetails ShowUninstDetails ShowWindow SilentInstall SilentUnInstall Sleep SpaceTexts StrCmp StrCmpS StrCpy StrLen SubCaption SubSectionEnd Unicode UninstallButtonText UninstallCaption UninstallIcon UninstallSubCaption UninstallText UninstPage UnRegDLL Var VIAddVersionKey VIFileVersion VIProductVersion WindowIcon WriteINIStr WriteRegBin WriteRegDWORD WriteRegExpandStr WriteRegStr WriteUninstaller XPStyle",literal:"admin all auto both colored current false force hide highest lastused leave listonly none normal notset off on open print show silent silentlog smooth textonly true user "},c:[e.HCM,e.CBCM,{cN:"string",b:'"',e:'"',i:"\\n",c:[{b:"\\$(\\\\(n|r|t)|\\$)"},t,i,n,r]},e.C(";","$",{r:0}),{cN:"function",bK:"Function PageEx Section SectionGroup SubSection",e:"$"},o,i,n,r,l,e.NM,{b:e.IR+"::"+e.IR}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/objectivec.js b/lib/highlight_js/assets/lang/objectivec.js index 2d69980a106..bb08557282f 100644 --- a/lib/highlight_js/assets/lang/objectivec.js +++ b/lib/highlight_js/assets/lang/objectivec.js @@ -1 +1 @@ -hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"(AV|CA|CF|CG|CI|MK|MP|NS|UI)\\w+"},i={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},o=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["m","mm","objc","obj-c"],k:i,l:o,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:o,c:[e.UTM]},{cN:"variable",b:"\\."+e.UIR,r:0}]}}); \ No newline at end of file +hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"(AV|CA|CF|CG|CI|MK|MP|NS|UI|XC)\\w+"},i={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},n=/[a-zA-Z@][a-zA-Z0-9_]*/,o="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:i,l:n,i:""}]}]},{cN:"class",b:"("+o.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:o,l:n,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/ocaml.js b/lib/highlight_js/assets/lang/ocaml.js index 95a4e523d89..05162084a79 100644 --- a/lib/highlight_js/assets/lang/ocaml.js +++ b/lib/highlight_js/assets/lang/ocaml.js @@ -1 +1 @@ -hljs.registerLanguage("ocaml",function(e){return{aliases:["ml"],k:{keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref",literal:"true false"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)"},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"tag",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*"},e.inherit(e.ASM,{cN:"char",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}}); \ No newline at end of file +hljs.registerLanguage("ocaml",function(e){return{aliases:["ml"],k:{keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref",literal:"true false"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)",r:0},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"type",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*",r:0},e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/openscad.js b/lib/highlight_js/assets/lang/openscad.js new file mode 100644 index 00000000000..9cd2f5b2b8a --- /dev/null +++ b/lib/highlight_js/assets/lang/openscad.js @@ -0,0 +1 @@ +hljs.registerLanguage("openscad",function(e){var r={cN:"keyword",b:"\\$(f[asn]|t|vp[rtd]|children)"},n={cN:"literal",b:"false|true|PI|undef"},o={cN:"number",b:"\\b\\d+(\\.\\d+)?(e-?\\d+)?",r:0},i=e.inherit(e.QSM,{i:null}),t={cN:"meta",k:{"meta-keyword":"include use"},b:"include|use <",e:">"},s={cN:"params",b:"\\(",e:"\\)",c:["self",o,i,r,n]},c={b:"[*!#%]",r:0},a={cN:"function",bK:"module function",e:"\\=|\\{",c:[s,e.UTM]};return{aliases:["scad"],k:{keyword:"function module include use for intersection_for if else \\%",literal:"false true PI undef",built_in:"circle square polygon text sphere cube cylinder polyhedron translate rotate scale resize mirror multmatrix color offset hull minkowski union difference intersection abs sign sin cos tan acos asin atan atan2 floor round ceil ln log pow sqrt exp rands min max concat lookup str chr search version version_num norm cross parent_module echo import import_dxf dxf_linear_extrude linear_extrude rotate_extrude surface projection render children dxf_cross dxf_dim let assign"},c:[e.CLCM,e.CBCM,o,t,i,r,c,a]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/parser3.js b/lib/highlight_js/assets/lang/parser3.js index b8fb48b8dfc..f388ab02949 100644 --- a/lib/highlight_js/assets/lang/parser3.js +++ b/lib/highlight_js/assets/lang/parser3.js @@ -1 +1 @@ -hljs.registerLanguage("parser3",function(r){var e=r.C("{","}",{c:["self"]});return{sL:"xml",r:0,c:[r.C("^#","$"),r.C("\\^rem{","}",{r:10,c:[e]}),{cN:"preprocessor",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},r.CNM]}}); \ No newline at end of file +hljs.registerLanguage("parser3",function(r){var e=r.C("{","}",{c:["self"]});return{sL:"xml",r:0,c:[r.C("^#","$"),r.C("\\^rem{","}",{r:10,c:[e]}),{cN:"meta",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},r.CNM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/perl.js b/lib/highlight_js/assets/lang/perl.js index 90dac8c8958..7498eb553aa 100644 --- a/lib/highlight_js/assets/lang/perl.js +++ b/lib/highlight_js/assets/lang/perl.js @@ -1 +1 @@ -hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},s={b:"->{",e:"}"},n={cN:"variable",v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=e.C("^(__END__|__DATA__)","\\n$",{r:5}),o=[e.BE,r,n],a=[n,e.HCM,i,e.C("^\\=\\w","\\=cut",{eW:!0}),s,{cN:"string",c:o,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,i,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",r:5},{cN:"operator",b:"-\\w\\b",r:0}];return r.c=a,s.c=a,{aliases:["pl"],k:t,c:a}}); \ No newline at end of file +hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},s={b:"->{",e:"}"},n={v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=[e.BE,r,n],o=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),s,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"function",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",eE:!0,r:5,c:[e.TM]},{b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=o,s.c=o,{aliases:["pl"],k:t,c:o}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/php.js b/lib/highlight_js/assets/lang/php.js index 5f53dba24db..0473f688b64 100644 --- a/lib/highlight_js/assets/lang/php.js +++ b/lib/highlight_js/assets/lang/php.js @@ -1 +1 @@ -hljs.registerLanguage("php",function(e){var c={cN:"variable",b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},i={cN:"preprocessor",b:/<\?(php)?|\?>/},a={cN:"string",c:[e.BE,i],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},n={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.CLCM,e.HCM,e.C("/\\*","\\*/",{c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"},i]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[e.BE]},i,c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,a,n]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},a,n]}}); \ No newline at end of file +hljs.registerLanguage("php",function(e){var c={b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},a={cN:"meta",b:/<\?(php)?|\?>/},i={cN:"string",c:[e.BE,a],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},t={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.HCM,e.C("//","$",{c:[a]}),e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},a,c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,i,t]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},i,t]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/powershell.js b/lib/highlight_js/assets/lang/powershell.js index a9fda41e98f..ce7ced70e93 100644 --- a/lib/highlight_js/assets/lang/powershell.js +++ b/lib/highlight_js/assets/lang/powershell.js @@ -1 +1 @@ -hljs.registerLanguage("powershell",function(e){var t={b:"`[\\s\\S]",r:0},r={cN:"variable",v:[{b:/\$[\w\d][\w\d_:]*/}]},o={cN:"string",b:/"/,e:/"/,c:[t,r,{cN:"variable",b:/\$[A-z]/,e:/[^A-z]/}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["ps"],l:/-?[A-z\.\-]+/,cI:!0,k:{keyword:"if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch",literal:"$null $true $false",built_in:"Add-Content Add-History Add-Member Add-PSSnapin Clear-Content Clear-Item Clear-Item Property Clear-Variable Compare-Object ConvertFrom-SecureString Convert-Path ConvertTo-Html ConvertTo-SecureString Copy-Item Copy-ItemProperty Export-Alias Export-Clixml Export-Console Export-Csv ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-Content Get-Credential Get-Culture Get-Date Get-EventLog Get-ExecutionPolicy Get-Help Get-History Get-Host Get-Item Get-ItemProperty Get-Location Get-Member Get-PfxCertificate Get-Process Get-PSDrive Get-PSProvider Get-PSSnapin Get-Service Get-TraceSource Get-UICulture Get-Unique Get-Variable Get-WmiObject Group-Object Import-Alias Import-Clixml Import-Csv Invoke-Expression Invoke-History Invoke-Item Join-Path Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Item New-ItemProperty New-Object New-PSDrive New-Service New-TimeSpan New-Variable Out-Default Out-File Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Remove-Item Remove-ItemProperty Remove-PSDrive Remove-PSSnapin Remove-Variable Rename-Item Rename-ItemProperty Resolve-Path Restart-Service Resume-Service Select-Object Select-String Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-Location Set-PSDebug Set-Service Set-TraceSource Set-Variable Sort-Object Split-Path Start-Service Start-Sleep Start-Transcript Stop-Process Stop-Service Stop-Transcript Suspend-Service Tee-Object Test-Path Trace-Command Update-FormatData Update-TypeData Where-Object Write-Debug Write-Error Write-Host Write-Output Write-Progress Write-Verbose Write-Warning",operator:"-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace"},c:[e.HCM,e.NM,o,a,r]}}); \ No newline at end of file +hljs.registerLanguage("powershell",function(e){var t={b:"`[\\s\\S]",r:0},r={cN:"variable",v:[{b:/\$[\w\d][\w\d_:]*/}]},o={cN:"literal",b:/\$(null|true|false)\b/},a={cN:"string",b:/"/,e:/"/,c:[t,r,{cN:"variable",b:/\$[A-z]/,e:/[^A-z]/}]},i={cN:"string",b:/'/,e:/'/};return{aliases:["ps"],l:/-?[A-z\.\-]+/,cI:!0,k:{keyword:"if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch",built_in:"Add-Content Add-History Add-Member Add-PSSnapin Clear-Content Clear-Item Clear-Item Property Clear-Variable Compare-Object ConvertFrom-SecureString Convert-Path ConvertTo-Html ConvertTo-SecureString Copy-Item Copy-ItemProperty Export-Alias Export-Clixml Export-Console Export-Csv ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-Content Get-Credential Get-Culture Get-Date Get-EventLog Get-ExecutionPolicy Get-Help Get-History Get-Host Get-Item Get-ItemProperty Get-Location Get-Member Get-PfxCertificate Get-Process Get-PSDrive Get-PSProvider Get-PSSnapin Get-Service Get-TraceSource Get-UICulture Get-Unique Get-Variable Get-WmiObject Group-Object Import-Alias Import-Clixml Import-Csv Invoke-Expression Invoke-History Invoke-Item Join-Path Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Item New-ItemProperty New-Object New-PSDrive New-Service New-TimeSpan New-Variable Out-Default Out-File Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Remove-Item Remove-ItemProperty Remove-PSDrive Remove-PSSnapin Remove-Variable Rename-Item Rename-ItemProperty Resolve-Path Restart-Service Resume-Service Select-Object Select-String Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-Location Set-PSDebug Set-Service Set-TraceSource Set-Variable Sort-Object Split-Path Start-Service Start-Sleep Start-Transcript Stop-Process Stop-Service Stop-Transcript Suspend-Service Tee-Object Test-Path Trace-Command Update-FormatData Update-TypeData Where-Object Write-Debug Write-Error Write-Host Write-Output Write-Progress Write-Verbose Write-Warning",nomarkup:"-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace"},c:[e.HCM,e.NM,a,i,o,r]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/processing.js b/lib/highlight_js/assets/lang/processing.js index 6c7f0e3cab7..ddd7bb19130 100644 --- a/lib/highlight_js/assets/lang/processing.js +++ b/lib/highlight_js/assets/lang/processing.js @@ -1 +1 @@ -hljs.registerLanguage("processing",function(e){return{k:{keyword:"BufferedReader PVector PFont PImage PGraphics HashMap boolean byte char color double float int long String Array FloatDict FloatList IntDict IntList JSONArray JSONObject Object StringDict StringList Table TableRow XML false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",constant:"P2D P3D HALF_PI PI QUARTER_PI TAU TWO_PI",variable:"displayHeight displayWidth mouseY mouseX mousePressed pmouseX pmouseY key keyCode pixels focused frameCount frameRate height width",title:"setup draw",built_in:"size createGraphics beginDraw createShape loadShape PShape arc ellipse line point quad rect triangle bezier bezierDetail bezierPoint bezierTangent curve curveDetail curvePoint curveTangent curveTightness shape shapeMode beginContour beginShape bezierVertex curveVertex endContour endShape quadraticVertex vertex ellipseMode noSmooth rectMode smooth strokeCap strokeJoin strokeWeight mouseClicked mouseDragged mouseMoved mousePressed mouseReleased mouseWheel keyPressed keyPressedkeyReleased keyTyped print println save saveFrame day hour millis minute month second year background clear colorMode fill noFill noStroke stroke alpha blue brightness color green hue lerpColor red saturation modelX modelY modelZ screenX screenY screenZ ambient emissive shininess specular add createImage beginCamera camera endCamera frustum ortho perspective printCamera printProjection cursor frameRate noCursor exit loop noLoop popStyle pushStyle redraw binary boolean byte char float hex int str unbinary unhex join match matchAll nf nfc nfp nfs split splitTokens trim append arrayCopy concat expand reverse shorten sort splice subset box sphere sphereDetail createInput createReader loadBytes loadJSONArray loadJSONObject loadStrings loadTable loadXML open parseXML saveTable selectFolder selectInput beginRaw beginRecord createOutput createWriter endRaw endRecord PrintWritersaveBytes saveJSONArray saveJSONObject saveStream saveStrings saveXML selectOutput popMatrix printMatrix pushMatrix resetMatrix rotate rotateX rotateY rotateZ scale shearX shearY translate ambientLight directionalLight lightFalloff lights lightSpecular noLights normal pointLight spotLight image imageMode loadImage noTint requestImage tint texture textureMode textureWrap blend copy filter get loadPixels set updatePixels blendMode loadShader PShaderresetShader shader createFont loadFont text textFont textAlign textLeading textMode textSize textWidth textAscent textDescent abs ceil constrain dist exp floor lerp log mag map max min norm pow round sq sqrt acos asin atan atan2 cos degrees radians sin tan noise noiseDetail noiseSeed random randomGaussian randomSeed"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM]}}); \ No newline at end of file +hljs.registerLanguage("processing",function(e){return{k:{keyword:"BufferedReader PVector PFont PImage PGraphics HashMap boolean byte char color double float int long String Array FloatDict FloatList IntDict IntList JSONArray JSONObject Object StringDict StringList Table TableRow XML false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",literal:"P2D P3D HALF_PI PI QUARTER_PI TAU TWO_PI",title:"setup draw",built_in:"displayHeight displayWidth mouseY mouseX mousePressed pmouseX pmouseY key keyCode pixels focused frameCount frameRate height width size createGraphics beginDraw createShape loadShape PShape arc ellipse line point quad rect triangle bezier bezierDetail bezierPoint bezierTangent curve curveDetail curvePoint curveTangent curveTightness shape shapeMode beginContour beginShape bezierVertex curveVertex endContour endShape quadraticVertex vertex ellipseMode noSmooth rectMode smooth strokeCap strokeJoin strokeWeight mouseClicked mouseDragged mouseMoved mousePressed mouseReleased mouseWheel keyPressed keyPressedkeyReleased keyTyped print println save saveFrame day hour millis minute month second year background clear colorMode fill noFill noStroke stroke alpha blue brightness color green hue lerpColor red saturation modelX modelY modelZ screenX screenY screenZ ambient emissive shininess specular add createImage beginCamera camera endCamera frustum ortho perspective printCamera printProjection cursor frameRate noCursor exit loop noLoop popStyle pushStyle redraw binary boolean byte char float hex int str unbinary unhex join match matchAll nf nfc nfp nfs split splitTokens trim append arrayCopy concat expand reverse shorten sort splice subset box sphere sphereDetail createInput createReader loadBytes loadJSONArray loadJSONObject loadStrings loadTable loadXML open parseXML saveTable selectFolder selectInput beginRaw beginRecord createOutput createWriter endRaw endRecord PrintWritersaveBytes saveJSONArray saveJSONObject saveStream saveStrings saveXML selectOutput popMatrix printMatrix pushMatrix resetMatrix rotate rotateX rotateY rotateZ scale shearX shearY translate ambientLight directionalLight lightFalloff lights lightSpecular noLights normal pointLight spotLight image imageMode loadImage noTint requestImage tint texture textureMode textureWrap blend copy filter get loadPixels set updatePixels blendMode loadShader PShaderresetShader shader createFont loadFont text textFont textAlign textLeading textMode textSize textWidth textAscent textDescent abs ceil constrain dist exp floor lerp log mag map max min norm pow round sq sqrt acos asin atan atan2 cos degrees radians sin tan noise noiseDetail noiseSeed random randomGaussian randomSeed"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/profile.js b/lib/highlight_js/assets/lang/profile.js index 06ec826acdd..b6882324e7f 100644 --- a/lib/highlight_js/assets/lang/profile.js +++ b/lib/highlight_js/assets/lang/profile.js @@ -1 +1 @@ -hljs.registerLanguage("profile",function(e){return{c:[e.CNM,{cN:"built_in",b:"{",e:"}$",eB:!0,eE:!0,c:[e.ASM,e.QSM],r:0},{cN:"filename",b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:!0},{cN:"header",b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{cN:"summary",b:"function calls",e:"$",c:[e.CNM],r:10},e.ASM,e.QSM,{cN:"function",b:"\\(",e:"\\)$",c:[e.UTM],r:0}]}}); \ No newline at end of file +hljs.registerLanguage("profile",function(e){return{c:[e.CNM,{b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:!0},{b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{b:"function calls",e:"$",c:[e.CNM],r:10},e.ASM,e.QSM,{cN:"string",b:"\\(",e:"\\)$",eB:!0,eE:!0,r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/prolog.js b/lib/highlight_js/assets/lang/prolog.js index bf53b52dd17..ece562e606a 100644 --- a/lib/highlight_js/assets/lang/prolog.js +++ b/lib/highlight_js/assets/lang/prolog.js @@ -1 +1 @@ -hljs.registerLanguage("prolog",function(c){var r={cN:"atom",b:/[a-z][A-Za-z0-9_]*/,r:0},b={cN:"name",v:[{b:/[A-Z][a-zA-Z0-9_]*/},{b:/_[A-Za-z0-9_]*/}],r:0},a={b:/\(/,e:/\)/,r:0},e={b:/\[/,e:/\]/},n={cN:"comment",b:/%/,e:/$/,c:[c.PWM]},t={cN:"string",b:/`/,e:/`/,c:[c.BE]},g={cN:"string",b:/0\'(\\\'|.)/},N={cN:"string",b:/0\'\\s/},o={b:/:-/},s=[r,b,a,o,e,n,c.CBCM,c.QSM,c.ASM,t,g,N,c.CNM];return a.c=s,e.c=s,{c:s.concat([{b:/\.$/}])}}); \ No newline at end of file +hljs.registerLanguage("prolog",function(c){var b={b:/[a-z][A-Za-z0-9_]*/,r:0},r={cN:"symbol",v:[{b:/[A-Z][a-zA-Z0-9_]*/},{b:/_[A-Za-z0-9_]*/}],r:0},e={b:/\(/,e:/\)/,r:0},n={b:/\[/,e:/\]/},a={cN:"comment",b:/%/,e:/$/,c:[c.PWM]},t={cN:"string",b:/`/,e:/`/,c:[c.BE]},g={cN:"string",b:/0\'(\\\'|.)/},s={cN:"string",b:/0\'\\s/},o={b:/:-/},N=[b,r,e,o,n,a,c.CBCM,c.QSM,c.ASM,t,g,s,c.CNM];return e.c=N,n.c=N,{c:N.concat([{b:/\.$/}])}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/protobuf.js b/lib/highlight_js/assets/lang/protobuf.js index cc430651809..2eb6a85d3f4 100644 --- a/lib/highlight_js/assets/lang/protobuf.js +++ b/lib/highlight_js/assets/lang/protobuf.js @@ -1 +1 @@ -hljs.registerLanguage("protobuf",function(e){return{k:{keyword:"package import option optional required repeated group",built_in:"double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 bool string bytes",literal:"true false"},c:[e.QSM,e.NM,e.CLCM,{cN:"class",bK:"message enum service",e:/\{/,i:/\n/,c:[e.inherit(e.TM,{starts:{eW:!0,eE:!0}})]},{cN:"function",bK:"rpc",e:/;/,eE:!0,k:"rpc returns"},{cN:"constant",b:/^\s*[A-Z_]+/,e:/\s*=/,eE:!0}]}}); \ No newline at end of file +hljs.registerLanguage("protobuf",function(e){return{k:{keyword:"package import option optional required repeated group",built_in:"double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 bool string bytes",literal:"true false"},c:[e.QSM,e.NM,e.CLCM,{cN:"class",bK:"message enum service",e:/\{/,i:/\n/,c:[e.inherit(e.TM,{starts:{eW:!0,eE:!0}})]},{cN:"function",bK:"rpc",e:/;/,eE:!0,k:"rpc returns"},{b:/^\s*[A-Z_]+/,e:/\s*=/,eE:!0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/puppet.js b/lib/highlight_js/assets/lang/puppet.js index d52bf464334..8b0987beaaa 100644 --- a/lib/highlight_js/assets/lang/puppet.js +++ b/lib/highlight_js/assets/lang/puppet.js @@ -1 +1 @@ -hljs.registerLanguage("puppet",function(e){var s="augeas computer cron exec file filebucket host interface k5login macauthorization mailalias maillist mcx mount nagios_command nagios_contact nagios_contactgroup nagios_host nagios_hostdependency nagios_hostescalation nagios_hostextinfo nagios_hostgroup nagios_service firewall nagios_servicedependency nagios_serviceescalation nagios_serviceextinfo nagios_servicegroup nagios_timeperiod notify package resources router schedule scheduled_task selboolean selmodule service ssh_authorized_key sshkey stage tidy user vlan yumrepo zfs zone zpool",r="alias audit before loglevel noop require subscribe tag owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check en_address ip_address realname command environment hour monute month monthday special target weekday creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey sslverify mounted",a={keyword:"and case class default define else elsif false if in import enherits node or true undef unless main settings $string "+s,literal:r,built_in:"architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version"},i=e.C("#","$"),o={cN:"string",c:[e.BE],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},n=[o,i,{cN:"keyword",bK:"class",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"(::)?[A-Za-z_]\\w*(::\\w+)*"}),i,o]},{cN:"keyword",b:"([a-zA-Z_(::)]+ *\\{)",c:[o,i],r:0},{cN:"keyword",b:"(\\}|\\{)",r:0},{cN:"function",b:"[a-zA-Z_]+\\s*=>"},{cN:"constant",b:"(::)?(\\b[A-Z][a-z_]*(::)?)+",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0}];return{aliases:["pp"],k:a,c:n}}); \ No newline at end of file +hljs.registerLanguage("puppet",function(e){var s={keyword:"and case default else elsif false if in import enherits node or true undef unless main settings $string ",literal:"alias audit before loglevel noop require subscribe tag owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check en_address ip_address realname command environment hour monute month monthday special target weekday creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey sslverify mounted",built_in:"architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version"},r=e.C("#","$"),a="([A-Za-z_]|::)(\\w|::)*",i=e.inherit(e.TM,{b:a}),o={cN:"variable",b:"\\$"+a},t={cN:"string",c:[e.BE,o],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]};return{aliases:["pp"],c:[r,o,t,{bK:"class",e:"\\{|;",i:/=/,c:[i,r]},{bK:"define",e:/\{/,c:[{cN:"section",b:e.IR,endsParent:!0}]},{b:e.IR+"\\s+\\{",rB:!0,e:/\S/,c:[{cN:"keyword",b:e.IR},{b:/\{/,e:/\}/,k:s,r:0,c:[t,r,{b:"[a-zA-Z_]+\\s*=>",rB:!0,e:"=>",c:[{cN:"attr",b:e.IR}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},o]}],r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/python.js b/lib/highlight_js/assets/lang/python.js index d3dd86c985f..d0975816b9d 100644 --- a/lib/highlight_js/assets/lang/python.js +++ b/lib/highlight_js/assets/lang/python.js @@ -1 +1 @@ -hljs.registerLanguage("python",function(e){var r={cN:"prompt",b:/^(>>>|\.\.\.) /},b={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},l={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},c={cN:"params",b:/\(/,e:/\)/,c:["self",r,l,b]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[r,l,b,e.HCM,{v:[{cN:"function",bK:"def",r:10},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,c]},{cN:"decorator",b:/@/,e:/$/},{b:/\b(print|exec)\(/}]}}); \ No newline at end of file +hljs.registerLanguage("python",function(e){var r={cN:"meta",b:/^(>>>|\.\.\.) /},b={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},a={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},l={cN:"params",b:/\(/,e:/\)/,c:["self",r,a,b]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[r,a,b,e.HCM,{v:[{cN:"function",bK:"def",r:10},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,l,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/q.js b/lib/highlight_js/assets/lang/q.js index 6e4bfc3fb5d..f6b87d9f842 100644 --- a/lib/highlight_js/assets/lang/q.js +++ b/lib/highlight_js/assets/lang/q.js @@ -1 +1 @@ -hljs.registerLanguage("q",function(e){var s={keyword:"do while select delete by update from",constant:"0b 1b",built_in:"neg not null string reciprocal floor ceiling signum mod xbar xlog and or each scan over prior mmu lsq inv md5 ltime gtime count first var dev med cov cor all any rand sums prds mins maxs fills deltas ratios avgs differ prev next rank reverse iasc idesc asc desc msum mcount mavg mdev xrank mmin mmax xprev rotate distinct group where flip type key til get value attr cut set upsert raze union inter except cross sv vs sublist enlist read0 read1 hopen hclose hdel hsym hcount peach system ltrim rtrim trim lower upper ssr view tables views cols xcols keys xkey xcol xasc xdesc fkeys meta lj aj aj0 ij pj asof uj ww wj wj1 fby xgroup ungroup ej save load rsave rload show csv parse eval min max avg wavg wsum sin cos tan sum",typename:"`float `double int `timestamp `timespan `datetime `time `boolean `symbol `char `byte `short `long `real `month `date `minute `second `guid"};return{aliases:["k","kdb"],k:s,l:/\b(`?)[A-Za-z0-9_]+\b/,c:[e.CLCM,e.QSM,e.CNM]}}); \ No newline at end of file +hljs.registerLanguage("q",function(e){var s={keyword:"do while select delete by update from",literal:"0b 1b",built_in:"neg not null string reciprocal floor ceiling signum mod xbar xlog and or each scan over prior mmu lsq inv md5 ltime gtime count first var dev med cov cor all any rand sums prds mins maxs fills deltas ratios avgs differ prev next rank reverse iasc idesc asc desc msum mcount mavg mdev xrank mmin mmax xprev rotate distinct group where flip type key til get value attr cut set upsert raze union inter except cross sv vs sublist enlist read0 read1 hopen hclose hdel hsym hcount peach system ltrim rtrim trim lower upper ssr view tables views cols xcols keys xkey xcol xasc xdesc fkeys meta lj aj aj0 ij pj asof uj ww wj wj1 fby xgroup ungroup ej save load rsave rload show csv parse eval min max avg wavg wsum sin cos tan sum",type:"`float `double int `timestamp `timespan `datetime `time `boolean `symbol `char `byte `short `long `real `month `date `minute `second `guid"};return{aliases:["k","kdb"],k:s,l:/(`?)[A-Za-z0-9_]+\b/,c:[e.CLCM,e.QSM,e.CNM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/qml.js b/lib/highlight_js/assets/lang/qml.js new file mode 100644 index 00000000000..dfe215cfa86 --- /dev/null +++ b/lib/highlight_js/assets/lang/qml.js @@ -0,0 +1 @@ +hljs.registerLanguage("qml",function(r){var e={keyword:"in of on if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await import",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Behavior bool color coordinate date double enumeration font geocircle georectangle geoshape int list matrix4x4 parent point quaternion real rect size string url var variant vector2d vector3d vector4dPromise"},t="[a-zA-Z_][a-zA-Z0-9\\._]*",a={cN:"keyword",b:"\\bproperty\\b",starts:{cN:"string",e:"(:|=|;|,|//|/\\*|$)",rE:!0}},n={cN:"keyword",b:"\\bsignal\\b",starts:{cN:"string",e:"(\\(|:|=|;|,|//|/\\*|$)",rE:!0}},o={cN:"attribute",b:"\\bid\\s*:",starts:{cN:"string",e:t,rE:!1}},i={b:t+"\\s*:",rB:!0,c:[{cN:"attribute",b:t,e:"\\s*:",eE:!0,r:0}],r:0},c={b:t+"\\s*{",e:"{",rB:!0,r:0,c:[r.inherit(r.TM,{b:t})]};return{aliases:["qt"],cI:!1,k:e,c:[{cN:"meta",b:/^\s*['"]use (strict|asm)['"]/},r.ASM,r.QSM,{cN:"string",b:"`",e:"`",c:[r.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},r.CLCM,r.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:r.CNR}],r:0},{b:"("+r.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[r.CLCM,r.CBCM,r.RM,{b:/\s*[);\]]/,r:0,sL:"xml"}],r:0},n,a,{cN:"function",bK:"function",e:/\{/,eE:!0,c:[r.inherit(r.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[r.CLCM,r.CBCM]}],i:/\[|%/},{b:"\\."+r.IR,r:0},o,i,c],i:/#/}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/roboconf.js b/lib/highlight_js/assets/lang/roboconf.js index 61918aa7fce..185875baba6 100644 --- a/lib/highlight_js/assets/lang/roboconf.js +++ b/lib/highlight_js/assets/lang/roboconf.js @@ -1 +1 @@ -hljs.registerLanguage("roboconf",function(e){var n="[a-zA-Z-_][^\n{\r\n]+\\{";return{aliases:["graph","instances"],cI:!0,k:"import",c:[{cN:"facet",b:"^facet "+n,e:"}",k:"facet installer exports children extends",c:[e.HCM]},{cN:"instance-of",b:"^instance of "+n,e:"}",k:"name count channels instance-data instance-state instance of",c:[{cN:"keyword",b:"[a-zA-Z-_]+( | )*:"},e.HCM]},{cN:"component",b:"^"+n,e:"}",l:"\\(?[a-zA-Z]+\\)?",k:"installer exports children extends imports facets alias (optional)",c:[{cN:"string",b:"\\.[a-zA-Z-_]+",e:"\\s|,|;",eE:!0},e.HCM]},e.HCM]}}); \ No newline at end of file +hljs.registerLanguage("roboconf",function(a){var e="[a-zA-Z-_][^\\n{]+\\{",n={cN:"attribute",b:/[a-zA-Z-_]+/,e:/\s*:/,eE:!0,starts:{e:";",r:0,c:[{cN:"variable",b:/\.[a-zA-Z-_]+/},{cN:"keyword",b:/\(optional\)/}]}};return{aliases:["graph","instances"],cI:!0,k:"import",c:[{b:"^facet "+e,e:"}",k:"facet",c:[n,a.HCM]},{b:"^\\s*instance of "+e,e:"}",k:"name count channels instance-data instance-state instance of",i:/\S/,c:["self",n,a.HCM]},{b:"^"+e,e:"}",c:[n,a.HCM]},a.HCM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/rsl.js b/lib/highlight_js/assets/lang/rsl.js index a67caeab20a..3f33a6f13cc 100644 --- a/lib/highlight_js/assets/lang/rsl.js +++ b/lib/highlight_js/assets/lang/rsl.js @@ -1 +1 @@ -hljs.registerLanguage("rsl",function(e){return{k:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},i:">|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r="and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",b={cN:"yardoctag",b:"@[A-Za-z]+"},a={cN:"value",b:"#<",e:">"},n=[e.C("#","$",{c:[b]}),e.C("^\\=begin","^\\=end",{c:[b],r:10}),e.C("^__END__","\\n$")],s={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,s],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}]},i={cN:"params",b:"\\(",e:"\\)",k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(n)},{cN:"function",bK:"def",e:" |$|;",r:0,c:[e.inherit(e.TM,{b:c}),i].concat(n)},{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[t,{b:c}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:[a,{cN:"regexp",c:[e.BE,s],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(n),r:0}].concat(n);s.c=d,i.c=d;var o="[>?]>",l="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",N=[{b:/^\s*=>/,cN:"status",starts:{e:"$",c:d}},{cN:"prompt",b:"^("+o+"|"+l+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,c:n.concat(N).concat(d)}}); \ No newline at end of file +hljs.registerLanguage("ruby",function(e){var r="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",b={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:b},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:b},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:r}),i].concat(s)},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[t,{b:r}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var l="[>?]>",o="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",w=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+l+"|"+o+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:b,i:/\/\*/,c:s.concat(w).concat(d)}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/ruleslanguage.js b/lib/highlight_js/assets/lang/ruleslanguage.js index e2741467d7f..62bcd2f3413 100644 --- a/lib/highlight_js/assets/lang/ruleslanguage.js +++ b/lib/highlight_js/assets/lang/ruleslanguage.js @@ -1 +1 @@ -hljs.registerLanguage("ruleslanguage",function(T){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN SAVE_UPDATE DETERMINANT LABEL REPORT REVENUE EACH IN FROM TOTAL CHARGE BLOCK AND OR CSV_FILE RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM NUMDAYS READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[T.CLCM,T.CBCM,T.ASM,T.QSM,T.CNM,{cN:"array",b:"#[a-zA-Z .]+"}]}}); \ No newline at end of file +hljs.registerLanguage("ruleslanguage",function(T){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN SAVE_UPDATE DETERMINANT LABEL REPORT REVENUE EACH IN FROM TOTAL CHARGE BLOCK AND OR CSV_FILE RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM NUMDAYS READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[T.CLCM,T.CBCM,T.ASM,T.QSM,T.CNM,{cN:"literal",v:[{b:"#\\s+[a-zA-Z\\ \\.]*",r:0},{b:"#[a-zA-Z\\ \\.]+"}]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/rust.js b/lib/highlight_js/assets/lang/rust.js index dd64320298d..0aec9695862 100644 --- a/lib/highlight_js/assets/lang/rust.js +++ b/lib/highlight_js/assets/lang/rust.js @@ -1 +1 @@ -hljs.registerLanguage("rust",function(e){var t=e.inherit(e.CBCM);return t.c.push("self"),{aliases:["rs"],k:{keyword:"alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self sizeof static struct super trait true type typeof unsafe unsized use virtual while yield int i8 i16 i32 i64 uint u8 u32 u64 float f32 f64 str char bool",built_in:"assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln!"},l:e.IR+"!?",i:""}]}}); \ No newline at end of file +hljs.registerLanguage("rust",function(e){var t="([uif](8|16|32|64|size))?",r=e.inherit(e.CBCM);r.c.push("self");var n="Copy Send Sized Sync Drop Fn FnMut FnOnce drop Box ToOwned Clone PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator Option Result SliceConcatExt String ToString Vec assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules!";return{aliases:["rs"],k:{keyword:"alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self Self sizeof static struct super trait true type typeof unsafe unsized use virtual while where yield int i8 i16 i32 i64 uint u8 u32 u64 float f32 f64 str char bool",literal:"true false Some None Ok Err",built_in:n},l:e.IR+"!?",i:""}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/scala.js b/lib/highlight_js/assets/lang/scala.js index 4a33dfe7ef9..4b593356f7b 100644 --- a/lib/highlight_js/assets/lang/scala.js +++ b/lib/highlight_js/assets/lang/scala.js @@ -1 +1 @@ -hljs.registerLanguage("scala",function(e){var t={cN:"annotation",b:"@[A-Za-z]+"},a={cN:"string",b:'u?r?"""',e:'"""',r:10},r={cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"},c={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},i={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0},l={cN:"class",bK:"class object trait type",e:/[:={\[(\n;]/,c:[{cN:"keyword",bK:"extends with",r:10},i]},n={cN:"function",bK:"def val",e:/[:={\[(\n;]/,c:[i]};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[e.CLCM,e.CBCM,a,e.QSM,r,c,n,l,e.CNM,t]}}); \ No newline at end of file +hljs.registerLanguage("scala",function(e){var t={cN:"meta",b:"@[A-Za-z]+"},a={cN:"subst",v:[{b:"\\$[A-Za-z0-9_]+"},{b:"\\${",e:"}"}]},r={cN:"string",v:[{b:'"',e:'"',i:"\\n",c:[e.BE]},{b:'"""',e:'"""',r:10},{b:'[a-z]+"',e:'"',i:"\\n",c:[e.BE,a]},{cN:"string",b:'[a-z]+"""',e:'"""',c:[a],r:10}]},c={cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"},i={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},s={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0},n={cN:"class",bK:"class object trait type",e:/[:={\[\n;]/,eE:!0,c:[{bK:"extends with",r:10},{b:/\[/,e:/\]/,eB:!0,eE:!0,r:0,c:[i]},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,r:0,c:[i]},s]},l={cN:"function",bK:"def",e:/[:={\[(\n;]/,eE:!0,c:[s]};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[e.CLCM,e.CBCM,r,c,i,l,n,e.CNM,t]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/scheme.js b/lib/highlight_js/assets/lang/scheme.js index c6f706bf9f2..64e8be48d39 100644 --- a/lib/highlight_js/assets/lang/scheme.js +++ b/lib/highlight_js/assets/lang/scheme.js @@ -1 +1 @@ -hljs.registerLanguage("scheme",function(e){var t="[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+",r="(\\-|\\+)?\\d+([./]\\d+)?",i=r+"[+\\-]"+r+"i",a={built_in:"case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules ' * + , ,@ - ... / ; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"},n={cN:"shebang",b:"^#!",e:"$"},c={cN:"literal",b:"(#t|#f|#\\\\"+t+"|#\\\\.)"},l={cN:"number",v:[{b:r,r:0},{b:i,r:0},{b:"#b[0-1]+(/[0-1]+)?"},{b:"#o[0-7]+(/[0-7]+)?"},{b:"#x[0-9a-f]+(/[0-9a-f]+)?"}]},s=e.QSM,o=[e.C(";","$",{r:0}),e.C("#\\|","\\|#")],u={b:t,r:0},p={cN:"variable",b:"'"+t},d={eW:!0,r:0},g={cN:"list",v:[{b:"\\(",e:"\\)"},{b:"\\[",e:"\\]"}],c:[{cN:"keyword",b:t,l:t,k:a},d]};return d.c=[c,l,s,u,p,g].concat(o),{i:/\S/,c:[n,l,s,p,g].concat(o)}}); \ No newline at end of file +hljs.registerLanguage("scheme",function(e){var t="[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+",r="(\\-|\\+)?\\d+([./]\\d+)?",a=r+"[+\\-]"+r+"i",i={"builtin-name":"case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules ' * + , ,@ - ... / ; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"},n={cN:"meta",b:"^#!",e:"$"},c={cN:"literal",b:"(#t|#f|#\\\\"+t+"|#\\\\.)"},l={cN:"number",v:[{b:r,r:0},{b:a,r:0},{b:"#b[0-1]+(/[0-1]+)?"},{b:"#o[0-7]+(/[0-7]+)?"},{b:"#x[0-9a-f]+(/[0-9a-f]+)?"}]},s=e.QSM,o=[e.C(";","$",{r:0}),e.C("#\\|","\\|#")],u={b:t,r:0},p={cN:"symbol",b:"'"+t},d={eW:!0,r:0},m={b:/'/,c:[{b:"\\(",e:"\\)",c:["self",c,s,l,u,p]}]},g={cN:"name",b:t,l:t,k:i},h={b:/lambda/,eW:!0,rB:!0,c:[g,{b:/\(/,e:/\)/,endsParent:!0,c:[u]}]},b={v:[{b:"\\(",e:"\\)"},{b:"\\[",e:"\\]"}],c:[h,g,d]};return d.c=[c,l,s,u,p,m,b].concat(o),{i:/\S/,c:[n,l,s,p,m,b].concat(o)}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/scilab.js b/lib/highlight_js/assets/lang/scilab.js index f97d0233588..9e15e7e0c2f 100644 --- a/lib/highlight_js/assets/lang/scilab.js +++ b/lib/highlight_js/assets/lang/scilab.js @@ -1 +1 @@ -hljs.registerLanguage("scilab",function(e){var n=[e.CNM,{cN:"string",b:"'|\"",e:"'|\"",c:[e.BE,{b:"''"}]}];return{aliases:["sci"],k:{keyword:"abort break case clear catch continue do elseif else endfunction end for functionglobal if pause return resume select try then while%f %F %t %T %pi %eps %inf %nan %e %i %z %s",built_in:"abs and acos asin atan ceil cd chdir clearglobal cosh cos cumprod deff disp errorexec execstr exists exp eye gettext floor fprintf fread fsolve imag isdef isemptyisinfisnan isvector lasterror length load linspace list listfiles log10 log2 logmax min msprintf mclose mopen ones or pathconvert poly printf prod pwd rand realround sinh sin size gsort sprintf sqrt strcat strcmps tring sum system tanh tantype typename warning zeros matrix"},i:'("|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function endfunction",e:"$",k:"function endfunction|10",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)"}]},{cN:"transposed_variable",b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:"",r:0},{cN:"matrix",b:"\\[",e:"\\]'*[\\.']*",r:0,c:n},e.C("//","$")].concat(n)}}); \ No newline at end of file +hljs.registerLanguage("scilab",function(e){var s=[e.CNM,{cN:"string",b:"'|\"",e:"'|\"",c:[e.BE,{b:"''"}]}];return{aliases:["sci"],l:/%?\w+/,k:{keyword:"abort break case clear catch continue do elseif else endfunction end for function global if pause return resume select try then while",literal:"%f %F %t %T %pi %eps %inf %nan %e %i %z %s",built_in:"abs and acos asin atan ceil cd chdir clearglobal cosh cos cumprod deff disp error exec execstr exists exp eye gettext floor fprintf fread fsolve imag isdef isempty isinfisnan isvector lasterror length load linspace list listfiles log10 log2 log max min msprintf mclose mopen ones or pathconvert poly printf prod pwd rand real round sinh sin size gsort sprintf sqrt strcat strcmps tring sum system tanh tan type typename warning zeros matrix"},i:'("|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function",e:"$",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)"}]},{b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:"",r:0},{b:"\\[",e:"\\]'*[\\.']*",r:0,c:s},e.C("//","$")].concat(s)}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/scss.js b/lib/highlight_js/assets/lang/scss.js index f09e8f1950a..9420f760c00 100644 --- a/lib/highlight_js/assets/lang/scss.js +++ b/lib/highlight_js/assets/lang/scss.js @@ -1 +1 @@ -hljs.registerLanguage("scss",function(e){{var t="[a-zA-Z-][a-zA-Z0-9_-]*",i={cN:"variable",b:"(\\$"+t+")\\b"},r={cN:"function",b:t+"\\(",rB:!0,eE:!0,e:"\\("},o={cN:"hexcolor",b:"#[0-9A-Fa-f]+"};({cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:!0,i:"[^\\s]",starts:{cN:"value",eW:!0,eE:!0,c:[r,o,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"important",b:"!important"}]}})}return{cI:!0,i:"[=/|']",c:[e.CLCM,e.CBCM,r,{cN:"id",b:"\\#[A-Za-z0-9_-]+",r:0},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"tag",b:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",r:0},{cN:"pseudo",b:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{cN:"pseudo",b:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},i,{cN:"attribute",b:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",i:"[^\\s]"},{cN:"value",b:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{cN:"value",b:":",e:";",c:[r,i,o,e.CSSNM,e.QSM,e.ASM,{cN:"important",b:"!important"}]},{cN:"at_rule",b:"@",e:"[{;]",k:"mixin include extend for if else each while charset import debug media page content font-face namespace warn",c:[r,i,e.QSM,e.ASM,o,e.CSSNM,{cN:"preprocessor",b:"\\s[A-Za-z0-9_.-]+",r:0}]}]}}); \ No newline at end of file +hljs.registerLanguage("scss",function(e){var t="[a-zA-Z-][a-zA-Z0-9_-]*",i={cN:"variable",b:"(\\$"+t+")\\b"},r={cN:"number",b:"#[0-9A-Fa-f]+"};({cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:!0,i:"[^\\s]",starts:{eW:!0,eE:!0,c:[r,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"meta",b:"!important"}]}});return{cI:!0,i:"[=/|']",c:[e.CLCM,e.CBCM,{cN:"selector-id",b:"\\#[A-Za-z0-9_-]+",r:0},{cN:"selector-class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"selector-attr",b:"\\[",e:"\\]",i:"$"},{cN:"selector-tag",b:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",r:0},{b:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{b:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},i,{cN:"attribute",b:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",i:"[^\\s]"},{b:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{b:":",e:";",c:[i,r,e.CSSNM,e.QSM,e.ASM,{cN:"meta",b:"!important"}]},{b:"@",e:"[{;]",k:"mixin include extend for if else each while charset import debug media page content font-face namespace warn",c:[i,e.QSM,e.ASM,r,e.CSSNM,{b:"\\s[A-Za-z0-9_.-]+",r:0}]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/smali.js b/lib/highlight_js/assets/lang/smali.js index 795a401c64a..4f459a2f9b6 100644 --- a/lib/highlight_js/assets/lang/smali.js +++ b/lib/highlight_js/assets/lang/smali.js @@ -1 +1 @@ -hljs.registerLanguage("smali",function(r){var t=["add","and","cmp","cmpg","cmpl","const","div","double","float","goto","if","int","long","move","mul","neg","new","nop","not","or","rem","return","shl","shr","sput","sub","throw","ushr","xor"],n=["aget","aput","array","check","execute","fill","filled","goto/16","goto/32","iget","instance","invoke","iput","monitor","packed","sget","sparse"],s=["transient","constructor","abstract","final","synthetic","public","private","protected","static","bridge","system"];return{aliases:["smali"],c:[{cN:"string",b:'"',e:'"',r:0},r.C("#","$",{r:0}),{cN:"keyword",b:"\\s*\\.end\\s[a-zA-Z0-9]*",r:1},{cN:"keyword",b:"^[ ]*\\.[a-zA-Z]*",r:0},{cN:"keyword",b:"\\s:[a-zA-Z_0-9]*",r:0},{cN:"keyword",b:"\\s("+s.join("|")+")",r:1},{cN:"keyword",b:"\\[",r:0},{cN:"instruction",b:"\\s("+t.join("|")+")\\s",r:1},{cN:"instruction",b:"\\s("+t.join("|")+")((\\-|/)[a-zA-Z0-9]+)+\\s",r:10},{cN:"instruction",b:"\\s("+n.join("|")+")((\\-|/)[a-zA-Z0-9]+)*\\s",r:10},{cN:"class",b:"L[^(;:\n]*;",r:0},{cN:"function",b:'( |->)[^(\n ;"]*\\(',r:0},{cN:"function",b:"\\)",r:0},{cN:"variable",b:"[vp][0-9]+",r:0}]}}); \ No newline at end of file +hljs.registerLanguage("smali",function(t){var s=["add","and","cmp","cmpg","cmpl","const","div","double","float","goto","if","int","long","move","mul","neg","new","nop","not","or","rem","return","shl","shr","sput","sub","throw","ushr","xor"],e=["aget","aput","array","check","execute","fill","filled","goto/16","goto/32","iget","instance","invoke","iput","monitor","packed","sget","sparse"],r=["transient","constructor","abstract","final","synthetic","public","private","protected","static","bridge","system"];return{aliases:["smali"],c:[{cN:"string",b:'"',e:'"',r:0},t.C("#","$",{r:0}),{cN:"keyword",v:[{b:"\\s*\\.end\\s[a-zA-Z0-9]*"},{b:"^[ ]*\\.[a-zA-Z]*",r:0},{b:"\\s:[a-zA-Z_0-9]*",r:0},{b:"\\s("+r.join("|")+")"}]},{cN:"built_in",v:[{b:"\\s("+s.join("|")+")\\s"},{b:"\\s("+s.join("|")+")((\\-|/)[a-zA-Z0-9]+)+\\s",r:10},{b:"\\s("+e.join("|")+")((\\-|/)[a-zA-Z0-9]+)*\\s",r:10}]},{cN:"class",b:"L[^(;:\n]*;",r:0},{b:"[vp][0-9]+"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/smalltalk.js b/lib/highlight_js/assets/lang/smalltalk.js index 0ffe8c4333d..46a1b9a567a 100644 --- a/lib/highlight_js/assets/lang/smalltalk.js +++ b/lib/highlight_js/assets/lang/smalltalk.js @@ -1 +1 @@ -hljs.registerLanguage("smalltalk",function(a){var r="[a-z][a-zA-Z0-9_]*",s={cN:"char",b:"\\$.{1}"},c={cN:"symbol",b:"#"+a.UIR};return{aliases:["st"],k:"self super nil true false thisContext",c:[a.C('"','"'),a.ASM,{cN:"class",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{cN:"method",b:r+":",r:0},a.CNM,c,s,{cN:"localvars",b:"\\|[ ]*"+r+"([ ]+"+r+")*[ ]*\\|",rB:!0,e:/\|/,i:/\S/,c:[{b:"(\\|[ ]*)?"+r}]},{cN:"array",b:"\\#\\(",e:"\\)",c:[a.ASM,s,a.CNM,c]}]}}); \ No newline at end of file +hljs.registerLanguage("smalltalk",function(e){var s="[a-z][a-zA-Z0-9_]*",a={cN:"string",b:"\\$.{1}"},r={cN:"symbol",b:"#"+e.UIR};return{aliases:["st"],k:"self super nil true false thisContext",c:[e.C('"','"'),e.ASM,{cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{b:s+":",r:0},e.CNM,r,a,{b:"\\|[ ]*"+s+"([ ]+"+s+")*[ ]*\\|",rB:!0,e:/\|/,i:/\S/,c:[{b:"(\\|[ ]*)?"+s}]},{b:"\\#\\(",e:"\\)",c:[e.ASM,a,e.CNM,r]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/sml.js b/lib/highlight_js/assets/lang/sml.js index 31a942095b5..7716c0d4132 100644 --- a/lib/highlight_js/assets/lang/sml.js +++ b/lib/highlight_js/assets/lang/sml.js @@ -1 +1 @@ -hljs.registerLanguage("sml",function(e){return{aliases:["ml"],k:{keyword:"abstype and andalso as case datatype do else end eqtype exception fn fun functor handle if in include infix infixr let local nonfix of op open orelse raise rec sharing sig signature struct structure then type val with withtype where while",built_in:"array bool char exn int list option order real ref string substring vector unit word",literal:"true false NONE SOME LESS EQUAL GREATER nil"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)"},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"tag",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*"},e.inherit(e.ASM,{cN:"char",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}}); \ No newline at end of file +hljs.registerLanguage("sml",function(e){return{aliases:["ml"],k:{keyword:"abstype and andalso as case datatype do else end eqtype exception fn fun functor handle if in include infix infixr let local nonfix of op open orelse raise rec sharing sig signature struct structure then type val with withtype where while",built_in:"array bool char exn int list option order real ref string substring vector unit word",literal:"true false NONE SOME LESS EQUAL GREATER nil"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:/\[(\|\|)?\]|\(\)/,r:0},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"type",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*"},e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/sqf.js b/lib/highlight_js/assets/lang/sqf.js new file mode 100644 index 00000000000..ea1d3a6fd8e --- /dev/null +++ b/lib/highlight_js/assets/lang/sqf.js @@ -0,0 +1 @@ +hljs.registerLanguage("sqf",function(e){var t=["!","-","+","!=","%","&&","*","/","=","==",">",">=","<","<=","or","plus","^",":",">>","abs","accTime","acos","action","actionKeys","actionKeysImages","actionKeysNames","actionKeysNamesArray","actionName","activateAddons","activatedAddons","activateKey","addAction","addBackpack","addBackpackCargo","addBackpackCargoGlobal","addBackpackGlobal","addCamShake","addCuratorAddons","addCuratorCameraArea","addCuratorEditableObjects","addCuratorEditingArea","addCuratorPoints","addEditorObject","addEventHandler","addGoggles","addGroupIcon","addHandgunItem","addHeadgear","addItem","addItemCargo","addItemCargoGlobal","addItemPool","addItemToBackpack","addItemToUniform","addItemToVest","addLiveStats","addMagazine","addMagazine array","addMagazineAmmoCargo","addMagazineCargo","addMagazineCargoGlobal","addMagazineGlobal","addMagazinePool","addMagazines","addMagazineTurret","addMenu","addMenuItem","addMissionEventHandler","addMPEventHandler","addMusicEventHandler","addPrimaryWeaponItem","addPublicVariableEventHandler","addRating","addResources","addScore","addScoreSide","addSecondaryWeaponItem","addSwitchableUnit","addTeamMember","addToRemainsCollector","addUniform","addVehicle","addVest","addWaypoint","addWeapon","addWeaponCargo","addWeaponCargoGlobal","addWeaponGlobal","addWeaponPool","addWeaponTurret","agent","agents","AGLToASL","aimedAtTarget","aimPos","airDensityRTD","airportSide","AISFinishHeal","alive","allControls","allCurators","allDead","allDeadMen","allDisplays","allGroups","allMapMarkers","allMines","allMissionObjects","allow3DMode","allowCrewInImmobile","allowCuratorLogicIgnoreAreas","allowDamage","allowDammage","allowFileOperations","allowFleeing","allowGetIn","allPlayers","allSites","allTurrets","allUnits","allUnitsUAV","allVariables","ammo","and","animate","animateDoor","animationPhase","animationState","append","armoryPoints","arrayIntersect","asin","ASLToAGL","ASLToATL","assert","assignAsCargo","assignAsCargoIndex","assignAsCommander","assignAsDriver","assignAsGunner","assignAsTurret","assignCurator","assignedCargo","assignedCommander","assignedDriver","assignedGunner","assignedItems","assignedTarget","assignedTeam","assignedVehicle","assignedVehicleRole","assignItem","assignTeam","assignToAirport","atan","atan2","atg","ATLToASL","attachedObject","attachedObjects","attachedTo","attachObject","attachTo","attackEnabled","backpack","backpackCargo","backpackContainer","backpackItems","backpackMagazines","backpackSpaceFor","behaviour","benchmark","binocular","blufor","boundingBox","boundingBoxReal","boundingCenter","breakOut","breakTo","briefingName","buildingExit","buildingPos","buttonAction","buttonSetAction","cadetMode","call","callExtension","camCommand","camCommit","camCommitPrepared","camCommitted","camConstuctionSetParams","camCreate","camDestroy","cameraEffect","cameraEffectEnableHUD","cameraInterest","cameraOn","cameraView","campaignConfigFile","camPreload","camPreloaded","camPrepareBank","camPrepareDir","camPrepareDive","camPrepareFocus","camPrepareFov","camPrepareFovRange","camPreparePos","camPrepareRelPos","camPrepareTarget","camSetBank","camSetDir","camSetDive","camSetFocus","camSetFov","camSetFovRange","camSetPos","camSetRelPos","camSetTarget","camTarget","camUseNVG","canAdd","canAddItemToBackpack","canAddItemToUniform","canAddItemToVest","cancelSimpleTaskDestination","canFire","canMove","canSlingLoad","canStand","canUnloadInCombat","captive","captiveNum","case","catch","cbChecked","cbSetChecked","ceil","cheatsEnabled","checkAIFeature","civilian","className","clearAllItemsFromBackpack","clearBackpackCargo","clearBackpackCargoGlobal","clearGroupIcons","clearItemCargo","clearItemCargoGlobal","clearItemPool","clearMagazineCargo","clearMagazineCargoGlobal","clearMagazinePool","clearOverlay","clearRadio","clearWeaponCargo","clearWeaponCargoGlobal","clearWeaponPool","closeDialog","closeDisplay","closeOverlay","collapseObjectTree","combatMode","commandArtilleryFire","commandChat","commander","commandFire","commandFollow","commandFSM","commandGetOut","commandingMenu","commandMove","commandRadio","commandStop","commandTarget","commandWatch","comment","commitOverlay","compile","compileFinal","completedFSM","composeText","configClasses","configFile","configHierarchy","configName","configProperties","configSourceMod","configSourceModList","connectTerminalToUAV","controlNull","controlsGroupCtrl","copyFromClipboard","copyToClipboard","copyWaypoints","cos","count","countEnemy","countFriendly","countSide","countType","countUnknown","createAgent","createCenter","createDialog","createDiaryLink","createDiaryRecord","createDiarySubject","createDisplay","createGearDialog","createGroup","createGuardedPoint","createLocation","createMarker","createMarkerLocal","createMenu","createMine","createMissionDisplay","createSimpleTask","createSite","createSoundSource","createTask","createTeam","createTrigger","createUnit","createUnit array","createVehicle","createVehicle array","createVehicleCrew","createVehicleLocal","crew","ctrlActivate","ctrlAddEventHandler","ctrlAutoScrollDelay","ctrlAutoScrollRewind","ctrlAutoScrollSpeed","ctrlChecked","ctrlClassName","ctrlCommit","ctrlCommitted","ctrlCreate","ctrlDelete","ctrlEnable","ctrlEnabled","ctrlFade","ctrlHTMLLoaded","ctrlIDC","ctrlIDD","ctrlMapAnimAdd","ctrlMapAnimClear","ctrlMapAnimCommit","ctrlMapAnimDone","ctrlMapCursor","ctrlMapMouseOver","ctrlMapScale","ctrlMapScreenToWorld","ctrlMapWorldToScreen","ctrlModel","ctrlModelDirAndUp","ctrlModelScale","ctrlParent","ctrlPosition","ctrlRemoveAllEventHandlers","ctrlRemoveEventHandler","ctrlScale","ctrlSetActiveColor","ctrlSetAutoScrollDelay","ctrlSetAutoScrollRewind","ctrlSetAutoScrollSpeed","ctrlSetBackgroundColor","ctrlSetChecked","ctrlSetEventHandler","ctrlSetFade","ctrlSetFocus","ctrlSetFont","ctrlSetFontH1","ctrlSetFontH1B","ctrlSetFontH2","ctrlSetFontH2B","ctrlSetFontH3","ctrlSetFontH3B","ctrlSetFontH4","ctrlSetFontH4B","ctrlSetFontH5","ctrlSetFontH5B","ctrlSetFontH6","ctrlSetFontH6B","ctrlSetFontHeight","ctrlSetFontHeightH1","ctrlSetFontHeightH2","ctrlSetFontHeightH3","ctrlSetFontHeightH4","ctrlSetFontHeightH5","ctrlSetFontHeightH6","ctrlSetFontP","ctrlSetFontPB","ctrlSetForegroundColor","ctrlSetModel","ctrlSetModelDirAndUp","ctrlSetModelScale","ctrlSetPosition","ctrlSetScale","ctrlSetStructuredText","ctrlSetText","ctrlSetTextColor","ctrlSetTooltip","ctrlSetTooltipColorBox","ctrlSetTooltipColorShade","ctrlSetTooltipColorText","ctrlShow","ctrlShown","ctrlText","ctrlTextHeight","ctrlType","ctrlVisible","curatorAddons","curatorCamera","curatorCameraArea","curatorCameraAreaCeiling","curatorCoef","curatorEditableObjects","curatorEditingArea","curatorEditingAreaType","curatorMouseOver","curatorPoints","curatorRegisteredObjects","curatorSelected","curatorWaypointCost","currentChannel","currentCommand","currentMagazine","currentMagazineDetail","currentMagazineDetailTurret","currentMagazineTurret","currentMuzzle","currentNamespace","currentTask","currentTasks","currentThrowable","currentVisionMode","currentWaypoint","currentWeapon","currentWeaponMode","currentWeaponTurret","currentZeroing","cursorTarget","customChat","customRadio","cutFadeOut","cutObj","cutRsc","cutText","damage","date","dateToNumber","daytime","deActivateKey","debriefingText","debugFSM","debugLog","default","deg","deleteAt","deleteCenter","deleteCollection","deleteEditorObject","deleteGroup","deleteIdentity","deleteLocation","deleteMarker","deleteMarkerLocal","deleteRange","deleteResources","deleteSite","deleteStatus","deleteTeam","deleteVehicle","deleteVehicleCrew","deleteWaypoint","detach","detectedMines","diag activeMissionFSMs","diag activeSQFScripts","diag activeSQSScripts","diag captureFrame","diag captureSlowFrame","diag fps","diag fpsMin","diag frameNo","diag log","diag logSlowFrame","diag tickTime","dialog","diarySubjectExists","didJIP","didJIPOwner","difficulty","difficultyEnabled","difficultyEnabledRTD","direction","directSay","disableAI","disableCollisionWith","disableConversation","disableDebriefingStats","disableSerialization","disableTIEquipment","disableUAVConnectability","disableUserInput","displayAddEventHandler","displayCtrl","displayNull","displayRemoveAllEventHandlers","displayRemoveEventHandler","displaySetEventHandler","dissolveTeam","distance","distance2D","distanceSqr","distributionRegion","do","doArtilleryFire","doFire","doFollow","doFSM","doGetOut","doMove","doorPhase","doStop","doTarget","doWatch","drawArrow","drawEllipse","drawIcon","drawIcon3D","drawLine","drawLine3D","drawLink","drawLocation","drawRectangle","driver","drop","east","echo","editObject","editorSetEventHandler","effectiveCommander","else","emptyPositions","enableAI","enableAIFeature","enableAttack","enableCamShake","enableCaustics","enableCollisionWith","enableCopilot","enableDebriefingStats","enableDiagLegend","enableEndDialog","enableEngineArtillery","enableEnvironment","enableFatigue","enableGunLights","enableIRLasers","enableMimics","enablePersonTurret","enableRadio","enableReload","enableRopeAttach","enableSatNormalOnDetail","enableSaving","enableSentences","enableSimulation","enableSimulationGlobal","enableTeamSwitch","enableUAVConnectability","enableUAVWaypoints","endLoadingScreen","endMission","engineOn","enginesIsOnRTD","enginesRpmRTD","enginesTorqueRTD","entities","estimatedEndServerTime","estimatedTimeLeft","evalObjectArgument","everyBackpack","everyContainer","exec","execEditorScript","execFSM","execVM","exit","exitWith","exp","expectedDestination","eyeDirection","eyePos","face","faction","fadeMusic","fadeRadio","fadeSound","fadeSpeech","failMission","false","fillWeaponsFromPool","find","findCover","findDisplay","findEditorObject","findEmptyPosition","findEmptyPositionReady","findNearestEnemy","finishMissionInit","finite","fire","fireAtTarget","firstBackpack","flag","flagOwner","fleeing","floor","flyInHeight","fog","fogForecast","fogParams","for","forceAddUniform","forceEnd","forceMap","forceRespawn","forceSpeed","forceWalk","forceWeaponFire","forceWeatherChange","forEach","forEachMember","forEachMemberAgent","forEachMemberTeam","format","formation","formationDirection","formationLeader","formationMembers","formationPosition","formationTask","formatText","formLeader","freeLook","from","fromEditor","fuel","fullCrew","gearSlotAmmoCount","gearSlotData","getAllHitPointsDamage","getAmmoCargo","getArray","getArtilleryAmmo","getArtilleryComputerSettings","getArtilleryETA","getAssignedCuratorLogic","getAssignedCuratorUnit","getBackpackCargo","getBleedingRemaining","getBurningValue","getCargoIndex","getCenterOfMass","getClientState","getConnectedUAV","getDammage","getDescription","getDir","getDirVisual","getDLCs","getEditorCamera","getEditorMode","getEditorObjectScope","getElevationOffset","getFatigue","getFriend","getFSMVariable","getFuelCargo","getGroupIcon","getGroupIconParams","getGroupIcons","getHideFrom","getHit","getHitIndex","getHitPointDamage","getItemCargo","getMagazineCargo","getMarkerColor","getMarkerPos","getMarkerSize","getMarkerType","getMass","getModelInfo","getNumber","getObjectArgument","getObjectChildren","getObjectDLC","getObjectMaterials","getObjectProxy","getObjectTextures","getObjectType","getObjectViewDistance","getOxygenRemaining","getPersonUsedDLCs","getPlayerChannel","getPlayerUID","getPos","getPosASL","getPosASLVisual","getPosASLW","getPosATL","getPosATLVisual","getPosVisual","getPosWorld","getRepairCargo","getResolution","getShadowDistance","getSlingLoad","getSpeed","getSuppression","getTerrainHeightASL","getText","getVariable","getWeaponCargo","getWPPos","glanceAt","globalChat","globalRadio","goggles","goto","group","groupChat","groupFromNetId","groupIconSelectable","groupIconsVisible","groupId","groupOwner","groupRadio","groupSelectedUnits","groupSelectUnit","grpNull","gunner","gusts","halt","handgunItems","handgunMagazine","handgunWeapon","handsHit","hasInterface","hasWeapon","hcAllGroups","hcGroupParams","hcLeader","hcRemoveAllGroups","hcRemoveGroup","hcSelected","hcSelectGroup","hcSetGroup","hcShowBar","hcShownBar","headgear","hideBody","hideObject","hideObjectGlobal","hint","hintC","hintCadet","hintSilent","hmd","hostMission","htmlLoad","HUDMovementLevels","humidity","if","image","importAllGroups","importance","in","incapacitatedState","independent","inflame","inflamed","inGameUISetEventHandler","inheritsFrom","initAmbientLife","inputAction","inRangeOfArtillery","insertEditorObject","intersect","isAbleToBreathe","isAgent","isArray","isAutoHoverOn","isAutonomous","isAutotest","isBleeding","isBurning","isClass","isCollisionLightOn","isCopilotEnabled","isDedicated","isDLCAvailable","isEngineOn","isEqualTo","isFlashlightOn","isFlatEmpty","isForcedWalk","isFormationLeader","isHidden","isInRemainsCollector","isInstructorFigureEnabled","isIRLaserOn","isKeyActive","isKindOf","isLightOn","isLocalized","isManualFire","isMarkedForCollection","isMultiplayer","isNil","isNull","isNumber","isObjectHidden","isObjectRTD","isOnRoad","isPipEnabled","isPlayer","isRealTime","isServer","isShowing3DIcons","isSteamMission","isStreamFriendlyUIEnabled","isText","isTouchingGround","isTurnedOut","isTutHintsEnabled","isUAVConnectable","isUAVConnected","isUniformAllowed","isWalking","isWeaponDeployed","isWeaponRested","itemCargo","items","itemsWithMagazines","join","joinAs","joinAsSilent","joinSilent","joinString","kbAddDatabase","kbAddDatabaseTargets","kbAddTopic","kbHasTopic","kbReact","kbRemoveTopic","kbTell","kbWasSaid","keyImage","keyName","knowsAbout","land","landAt","landResult","language","laserTarget","lbAdd","lbClear","lbColor","lbCurSel","lbData","lbDelete","lbIsSelected","lbPicture","lbSelection","lbSetColor","lbSetCurSel","lbSetData","lbSetPicture","lbSetPictureColor","lbSetPictureColorDisabled","lbSetPictureColorSelected","lbSetSelectColor","lbSetSelectColorRight","lbSetSelected","lbSetTooltip","lbSetValue","lbSize","lbSort","lbSortByValue","lbText","lbValue","leader","leaderboardDeInit","leaderboardGetRows","leaderboardInit","leaveVehicle","libraryCredits","libraryDisclaimers","lifeState","lightAttachObject","lightDetachObject","lightIsOn","lightnings","limitSpeed","linearConversion","lineBreak","lineIntersects","lineIntersectsObjs","lineIntersectsSurfaces","lineIntersectsWith","linkItem","list","listObjects","ln","lnbAddArray","lnbAddColumn","lnbAddRow","lnbClear","lnbColor","lnbCurSelRow","lnbData","lnbDeleteColumn","lnbDeleteRow","lnbGetColumnsPosition","lnbPicture","lnbSetColor","lnbSetColumnsPos","lnbSetCurSelRow","lnbSetData","lnbSetPicture","lnbSetText","lnbSetValue","lnbSize","lnbText","lnbValue","load","loadAbs","loadBackpack","loadFile","loadGame","loadIdentity","loadMagazine","loadOverlay","loadStatus","loadUniform","loadVest","local","localize","locationNull","locationPosition","lock","lockCameraTo","lockCargo","lockDriver","locked","lockedCargo","lockedDriver","lockedTurret","lockTurret","lockWP","log","logEntities","lookAt","lookAtPos","magazineCargo","magazines","magazinesAllTurrets","magazinesAmmo","magazinesAmmoCargo","magazinesAmmoFull","magazinesDetail","magazinesDetailBackpack","magazinesDetailUniform","magazinesDetailVest","magazinesTurret","magazineTurretAmmo","mapAnimAdd","mapAnimClear","mapAnimCommit","mapAnimDone","mapCenterOnCamera","mapGridPosition","markAsFinishedOnSteam","markerAlpha","markerBrush","markerColor","markerDir","markerPos","markerShape","markerSize","markerText","markerType","max","members","min","mineActive","mineDetectedBy","missionConfigFile","missionName","missionNamespace","missionStart","mod","modelToWorld","modelToWorldVisual","moonIntensity","morale","move","moveInAny","moveInCargo","moveInCommander","moveInDriver","moveInGunner","moveInTurret","moveObjectToEnd","moveOut","moveTime","moveTo","moveToCompleted","moveToFailed","musicVolume","name","name location","nameSound","nearEntities","nearestBuilding","nearestLocation","nearestLocations","nearestLocationWithDubbing","nearestObject","nearestObjects","nearObjects","nearObjectsReady","nearRoads","nearSupplies","nearTargets","needReload","netId","netObjNull","newOverlay","nextMenuItemIndex","nextWeatherChange","nil","nMenuItems","not","numberToDate","objectCurators","objectFromNetId","objectParent","objNull","objStatus","onBriefingGroup","onBriefingNotes","onBriefingPlan","onBriefingTeamSwitch","onCommandModeChanged","onDoubleClick","onEachFrame","onGroupIconClick","onGroupIconOverEnter","onGroupIconOverLeave","onHCGroupSelectionChanged","onMapSingleClick","onPlayerConnected","onPlayerDisconnected","onPreloadFinished","onPreloadStarted","onShowNewObject","onTeamSwitch","openCuratorInterface","openMap","openYoutubeVideo","opfor","or","orderGetIn","overcast","overcastForecast","owner","param","params","parseNumber","parseText","parsingNamespace","particlesQuality","pi","pickWeaponPool","pitch","playableSlotsNumber","playableUnits","playAction","playActionNow","player","playerRespawnTime","playerSide","playersNumber","playGesture","playMission","playMove","playMoveNow","playMusic","playScriptedMission","playSound","playSound3D","position","positionCameraToWorld","posScreenToWorld","posWorldToScreen","ppEffectAdjust","ppEffectCommit","ppEffectCommitted","ppEffectCreate","ppEffectDestroy","ppEffectEnable","ppEffectForceInNVG","precision","preloadCamera","preloadObject","preloadSound","preloadTitleObj","preloadTitleRsc","preprocessFile","preprocessFileLineNumbers","primaryWeapon","primaryWeaponItems","primaryWeaponMagazine","priority","private","processDiaryLink","productVersion","profileName","profileNamespace","profileNameSteam","progressLoadingScreen","progressPosition","progressSetPosition","publicVariable","publicVariableClient","publicVariableServer","pushBack","putWeaponPool","queryItemsPool","queryMagazinePool","queryWeaponPool","rad","radioChannelAdd","radioChannelCreate","radioChannelRemove","radioChannelSetCallSign","radioChannelSetLabel","radioVolume","rain","rainbow","random","rank","rankId","rating","rectangular","registeredTasks","registerTask","reload","reloadEnabled","remoteControl","remoteExec","remoteExecCall","removeAction","removeAllActions","removeAllAssignedItems","removeAllContainers","removeAllCuratorAddons","removeAllCuratorCameraAreas","removeAllCuratorEditingAreas","removeAllEventHandlers","removeAllHandgunItems","removeAllItems","removeAllItemsWithMagazines","removeAllMissionEventHandlers","removeAllMPEventHandlers","removeAllMusicEventHandlers","removeAllPrimaryWeaponItems","removeAllWeapons","removeBackpack","removeBackpackGlobal","removeCuratorAddons","removeCuratorCameraArea","removeCuratorEditableObjects","removeCuratorEditingArea","removeDrawIcon","removeDrawLinks","removeEventHandler","removeFromRemainsCollector","removeGoggles","removeGroupIcon","removeHandgunItem","removeHeadgear","removeItem","removeItemFromBackpack","removeItemFromUniform","removeItemFromVest","removeItems","removeMagazine","removeMagazineGlobal","removeMagazines","removeMagazinesTurret","removeMagazineTurret","removeMenuItem","removeMissionEventHandler","removeMPEventHandler","removeMusicEventHandler","removePrimaryWeaponItem","removeSecondaryWeaponItem","removeSimpleTask","removeSwitchableUnit","removeTeamMember","removeUniform","removeVest","removeWeapon","removeWeaponGlobal","removeWeaponTurret","requiredVersion","resetCamShake","resetSubgroupDirection","resistance","resize","resources","respawnVehicle","restartEditorCamera","reveal","revealMine","reverse","reversedMouseY","roadsConnectedTo","roleDescription","ropeAttachedObjects","ropeAttachedTo","ropeAttachEnabled","ropeAttachTo","ropeCreate","ropeCut","ropeEndPosition","ropeLength","ropes","ropeUnwind","ropeUnwound","rotorsForcesRTD","rotorsRpmRTD","round","runInitScript","safeZoneH","safeZoneW","safeZoneWAbs","safeZoneX","safeZoneXAbs","safeZoneY","saveGame","saveIdentity","saveJoysticks","saveOverlay","saveProfileNamespace","saveStatus","saveVar","savingEnabled","say","say2D","say3D","scopeName","score","scoreSide","screenToWorld","scriptDone","scriptName","scriptNull","scudState","secondaryWeapon","secondaryWeaponItems","secondaryWeaponMagazine","select","selectBestPlaces","selectDiarySubject","selectedEditorObjects","selectEditorObject","selectionPosition","selectLeader","selectNoPlayer","selectPlayer","selectWeapon","selectWeaponTurret","sendAUMessage","sendSimpleCommand","sendTask","sendTaskResult","sendUDPMessage","serverCommand","serverCommandAvailable","serverCommandExecutable","serverName","serverTime","set","setAccTime","setAirportSide","setAmmo","setAmmoCargo","setAperture","setApertureNew","setArmoryPoints","setAttributes","setAutonomous","setBehaviour","setBleedingRemaining","setCameraInterest","setCamShakeDefParams","setCamShakeParams","setCamUseTi","setCaptive","setCenterOfMass","setCollisionLight","setCombatMode","setCompassOscillation","setCuratorCameraAreaCeiling","setCuratorCoef","setCuratorEditingAreaType","setCuratorWaypointCost","setCurrentChannel","setCurrentTask","setCurrentWaypoint","setDamage","setDammage","setDate","setDebriefingText","setDefaultCamera","setDestination","setDetailMapBlendPars","setDir","setDirection","setDrawIcon","setDropInterval","setEditorMode","setEditorObjectScope","setEffectCondition","setFace","setFaceAnimation","setFatigue","setFlagOwner","setFlagSide","setFlagTexture","setFog","setFog array","setFormation","setFormationTask","setFormDir","setFriend","setFromEditor","setFSMVariable","setFuel","setFuelCargo","setGroupIcon","setGroupIconParams","setGroupIconsSelectable","setGroupIconsVisible","setGroupId","setGroupIdGlobal","setGroupOwner","setGusts","setHideBehind","setHit","setHitIndex","setHitPointDamage","setHorizonParallaxCoef","setHUDMovementLevels","setIdentity","setImportance","setLeader","setLightAmbient","setLightAttenuation","setLightBrightness","setLightColor","setLightDayLight","setLightFlareMaxDistance","setLightFlareSize","setLightIntensity","setLightnings","setLightUseFlare","setLocalWindParams","setMagazineTurretAmmo","setMarkerAlpha","setMarkerAlphaLocal","setMarkerBrush","setMarkerBrushLocal","setMarkerColor","setMarkerColorLocal","setMarkerDir","setMarkerDirLocal","setMarkerPos","setMarkerPosLocal","setMarkerShape","setMarkerShapeLocal","setMarkerSize","setMarkerSizeLocal","setMarkerText","setMarkerTextLocal","setMarkerType","setMarkerTypeLocal","setMass","setMimic","setMousePosition","setMusicEffect","setMusicEventHandler","setName","setNameSound","setObjectArguments","setObjectMaterial","setObjectProxy","setObjectTexture","setObjectTextureGlobal","setObjectViewDistance","setOvercast","setOwner","setOxygenRemaining","setParticleCircle","setParticleClass","setParticleFire","setParticleParams","setParticleRandom","setPilotLight","setPiPEffect","setPitch","setPlayable","setPlayerRespawnTime","setPos","setPosASL","setPosASL2","setPosASLW","setPosATL","setPosition","setPosWorld","setRadioMsg","setRain","setRainbow","setRandomLip","setRank","setRectangular","setRepairCargo","setShadowDistance","setSide","setSimpleTaskDescription","setSimpleTaskDestination","setSimpleTaskTarget","setSimulWeatherLayers","setSize","setSkill","setSkill array","setSlingLoad","setSoundEffect","setSpeaker","setSpeech","setSpeedMode","setStatValue","setSuppression","setSystemOfUnits","setTargetAge","setTaskResult","setTaskState","setTerrainGrid","setText","setTimeMultiplier","setTitleEffect","setTriggerActivation","setTriggerArea","setTriggerStatements","setTriggerText","setTriggerTimeout","setTriggerType","setType","setUnconscious","setUnitAbility","setUnitPos","setUnitPosWeak","setUnitRank","setUnitRecoilCoefficient","setUnloadInCombat","setUserActionText","setVariable","setVectorDir","setVectorDirAndUp","setVectorUp","setVehicleAmmo","setVehicleAmmoDef","setVehicleArmor","setVehicleId","setVehicleLock","setVehiclePosition","setVehicleTiPars","setVehicleVarName","setVelocity","setVelocityTransformation","setViewDistance","setVisibleIfTreeCollapsed","setWaves","setWaypointBehaviour","setWaypointCombatMode","setWaypointCompletionRadius","setWaypointDescription","setWaypointFormation","setWaypointHousePosition","setWaypointLoiterRadius","setWaypointLoiterType","setWaypointName","setWaypointPosition","setWaypointScript","setWaypointSpeed","setWaypointStatements","setWaypointTimeout","setWaypointType","setWaypointVisible","setWeaponReloadingTime","setWind","setWindDir","setWindForce","setWindStr","setWPPos","show3DIcons","showChat","showCinemaBorder","showCommandingMenu","showCompass","showCuratorCompass","showGPS","showHUD","showLegend","showMap","shownArtilleryComputer","shownChat","shownCompass","shownCuratorCompass","showNewEditorObject","shownGPS","shownHUD","shownMap","shownPad","shownRadio","shownUAVFeed","shownWarrant","shownWatch","showPad","showRadio","showSubtitles","showUAVFeed","showWarrant","showWatch","showWaypoint","side","sideChat","sideEnemy","sideFriendly","sideLogic","sideRadio","sideUnknown","simpleTasks","simulationEnabled","simulCloudDensity","simulCloudOcclusion","simulInClouds","simulWeatherSync","sin","size","sizeOf","skill","skillFinal","skipTime","sleep","sliderPosition","sliderRange","sliderSetPosition","sliderSetRange","sliderSetSpeed","sliderSpeed","slingLoadAssistantShown","soldierMagazines","someAmmo","sort","soundVolume","spawn","speaker","speed","speedMode","splitString","sqrt","squadParams","stance","startLoadingScreen","step","stop","stopped","str","sunOrMoon","supportInfo","suppressFor","surfaceIsWater","surfaceNormal","surfaceType","swimInDepth","switch","switchableUnits","switchAction","switchCamera","switchGesture","switchLight","switchMove","synchronizedObjects","synchronizedTriggers","synchronizedWaypoints","synchronizeObjectsAdd","synchronizeObjectsRemove","synchronizeTrigger","synchronizeWaypoint","synchronizeWaypoint trigger","systemChat","systemOfUnits","tan","targetKnowledge","targetsAggregate","targetsQuery","taskChildren","taskCompleted","taskDescription","taskDestination","taskHint","taskNull","taskParent","taskResult","taskState","teamMember","teamMemberNull","teamName","teams","teamSwitch","teamSwitchEnabled","teamType","terminate","terrainIntersect","terrainIntersectASL","text","text location","textLog","textLogFormat","tg","then","throw","time","timeMultiplier","titleCut","titleFadeOut","titleObj","titleRsc","titleText","to","toArray","toLower","toString","toUpper","triggerActivated","triggerActivation","triggerArea","triggerAttachedVehicle","triggerAttachObject","triggerAttachVehicle","triggerStatements","triggerText","triggerTimeout","triggerTimeoutCurrent","triggerType","true","try","turretLocal","turretOwner","turretUnit","tvAdd","tvClear","tvCollapse","tvCount","tvCurSel","tvData","tvDelete","tvExpand","tvPicture","tvSetCurSel","tvSetData","tvSetPicture","tvSetPictureColor","tvSetTooltip","tvSetValue","tvSort","tvSortByValue","tvText","tvValue","type","typeName","typeOf","UAVControl","uiNamespace","uiSleep","unassignCurator","unassignItem","unassignTeam","unassignVehicle","underwater","uniform","uniformContainer","uniformItems","uniformMagazines","unitAddons","unitBackpack","unitPos","unitReady","unitRecoilCoefficient","units","unitsBelowHeight","unlinkItem","unlockAchievement","unregisterTask","updateDrawIcon","updateMenuItem","updateObjectTree","useAudioTimeForMoves","vectorAdd","vectorCos","vectorCrossProduct","vectorDiff","vectorDir","vectorDirVisual","vectorDistance","vectorDistanceSqr","vectorDotProduct","vectorFromTo","vectorMagnitude","vectorMagnitudeSqr","vectorMultiply","vectorNormalized","vectorUp","vectorUpVisual","vehicle","vehicleChat","vehicleRadio","vehicles","vehicleVarName","velocity","velocityModelSpace","verifySignature","vest","vestContainer","vestItems","vestMagazines","viewDistance","visibleCompass","visibleGPS","visibleMap","visiblePosition","visiblePositionASL","visibleWatch","waitUntil","waves","waypointAttachedObject","waypointAttachedVehicle","waypointAttachObject","waypointAttachVehicle","waypointBehaviour","waypointCombatMode","waypointCompletionRadius","waypointDescription","waypointFormation","waypointHousePosition","waypointLoiterRadius","waypointLoiterType","waypointName","waypointPosition","waypoints","waypointScript","waypointsEnabledUAV","waypointShow","waypointSpeed","waypointStatements","waypointTimeout","waypointTimeoutCurrent","waypointType","waypointVisible","weaponAccessories","weaponCargo","weaponDirection","weaponLowered","weapons","weaponsItems","weaponsItemsCargo","weaponState","weaponsTurret","weightRTD","west","WFSideText","while","wind","windDir","windStr","wingsForcesRTD","with","worldName","worldSize","worldToModel","worldToModelVisual","worldToScreen"],a=["case","catch","default","do","else","exit","exitWith|5","for","forEach","from","if","switch","then","throw","to","try","while","with"],r=["!","-","+","!=","%","&&","*","/","=","==",">",">=","<","<=","^",":",">>"],o=["_forEachIndex|10","_this|10","_x|10"],i=["true","false","nil"],n=t.filter(function(e){return-1==a.indexOf(e)&&-1==i.indexOf(e)&&-1==r.indexOf(e)});n=n.concat(o);var s={cN:"string",r:0,v:[{b:'"',e:'"',c:[{b:'""'}]},{b:"'",e:"'",c:[{b:"''"}]}]},l={cN:"number",b:e.NR,r:0},c={cN:"string",v:[e.QSM,{b:"'\\\\?.",e:"'",i:"."}]},d={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef"},c:[{b:/\\\n/,r:0},{bK:"include",e:"$",k:{"meta-keyword":"include"},c:[c,{cN:"meta-string",b:"<",e:">",i:"\\n"}]},c,l,e.CLCM,e.CBCM]};return{aliases:["sqf"],cI:!0,k:{keyword:a.join(" "),built_in:n.join(" "),literal:i.join(" ")},c:[e.CLCM,e.CBCM,l,s,d]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/sql.js b/lib/highlight_js/assets/lang/sql.js index 2ff06448017..36a72225de1 100644 --- a/lib/highlight_js/assets/lang/sql.js +++ b/lib/highlight_js/assets/lang/sql.js @@ -1 +1 @@ -hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>]/,c:[{cN:"operator",bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate savepoint release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke",e:/;/,eW:!0,k:{keyword:"abs absolute acos action add adddate addtime aes_decrypt aes_encrypt after aggregate all allocate alter analyze and any are as asc ascii asin assertion at atan atan2 atn2 authorization authors avg backup before begin benchmark between bin binlog bit_and bit_count bit_length bit_or bit_xor both by cache call cascade cascaded case cast catalog ceil ceiling chain change changed char_length character_length charindex charset check checksum checksum_agg choose close coalesce coercibility collate collation collationproperty column columns columns_updated commit compress concat concat_ws concurrent connect connection connection_id consistent constraint constraints continue contributors conv convert convert_tz corresponding cos cot count count_big crc32 create cross cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime data database databases datalength date_add date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts datetimeoffsetfromparts day dayname dayofmonth dayofweek dayofyear deallocate declare decode default deferrable deferred degrees delayed delete des_decrypt des_encrypt des_key_file desc describe descriptor diagnostics difference disconnect distinct distinctrow div do domain double drop dumpfile each else elt enclosed encode encrypt end end-exec engine engines eomonth errors escape escaped event eventdata events except exception exec execute exists exp explain export_set extended external extract fast fetch field fields find_in_set first first_value floor flush for force foreign format found found_rows from from_base64 from_days from_unixtime full function get get_format get_lock getdate getutcdate global go goto grant grants greatest group group_concat grouping grouping_id gtid_subset gtid_subtract handler having help hex high_priority hosts hour ident_current ident_incr ident_seed identified identity if ifnull ignore iif ilike immediate in index indicator inet6_aton inet6_ntoa inet_aton inet_ntoa infile initially inner innodb input insert install instr intersect into is is_free_lock is_ipv4 is_ipv4_compat is_ipv4_mapped is_not is_not_null is_used_lock isdate isnull isolation join key kill language last last_day last_insert_id last_value lcase lead leading least leaves left len lenght level like limit lines ln load load_file local localtime localtimestamp locate lock log log10 log2 logfile logs low_priority lower lpad ltrim make_set makedate maketime master master_pos_wait match matched max md5 medium merge microsecond mid min minute mod mode module month monthname mutex name_const names national natural nchar next no no_write_to_binlog not now nullif nvarchar oct octet_length of old_password on only open optimize option optionally or ord order outer outfile output pad parse partial partition password patindex percent_rank percentile_cont percentile_disc period_add period_diff pi plugin position pow power pragma precision prepare preserve primary prior privileges procedure procedure_analyze processlist profile profiles public publishingservername purge quarter query quick quote quotename radians rand read references regexp relative relaylog release release_lock rename repair repeat replace replicate reset restore restrict return returns reverse revoke right rlike rollback rollup round row row_count rows rpad rtrim savepoint schema scroll sec_to_time second section select serializable server session session_user set sha sha1 sha2 share show sign sin size slave sleep smalldatetimefromparts snapshot some soname soundex sounds_like space sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sql_variant_property sqlstate sqrt square start starting status std stddev stddev_pop stddev_samp stdev stdevp stop str str_to_date straight_join strcmp string stuff subdate substr substring subtime subtring_index sum switchoffset sysdate sysdatetime sysdatetimeoffset system_user sysutcdatetime table tables tablespace tan temporary terminated tertiary_weights then time time_format time_to_sec timediff timefromparts timestamp timestampadd timestampdiff timezone_hour timezone_minute to to_base64 to_days to_seconds todatetimeoffset trailing transaction translation trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse ucase uncompress uncompressed_length unhex unicode uninstall union unique unix_timestamp unknown unlock update upgrade upped upper usage use user user_resources using utc_date utc_time utc_timestamp uuid uuid_short validate_password_strength value values var var_pop var_samp variables variance varp version view warnings week weekday weekofyear weight_string when whenever where with work write xml xor year yearweek zon",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int integer interval number numeric real serial smallint varchar varying int8 serial8 text"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}}); \ No newline at end of file +hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke",e:/;/,eW:!0,k:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/stan.js b/lib/highlight_js/assets/lang/stan.js new file mode 100644 index 00000000000..96c736ddc4d --- /dev/null +++ b/lib/highlight_js/assets/lang/stan.js @@ -0,0 +1 @@ +hljs.registerLanguage("stan",function(e){return{c:[e.HCM,e.CLCM,e.CBCM,{b:e.UIR,l:e.UIR,k:{name:"for in while repeat until if then else",symbol:"bernoulli bernoulli_logit binomial binomial_logit beta_binomial hypergeometric categorical categorical_logit ordered_logistic neg_binomial neg_binomial_2 neg_binomial_2_log poisson poisson_log multinomial normal exp_mod_normal skew_normal student_t cauchy double_exponential logistic gumbel lognormal chi_square inv_chi_square scaled_inv_chi_square exponential inv_gamma weibull frechet rayleigh wiener pareto pareto_type_2 von_mises uniform multi_normal multi_normal_prec multi_normal_cholesky multi_gp multi_gp_cholesky multi_student_t gaussian_dlm_obs dirichlet lkj_corr lkj_corr_cholesky wishart inv_wishart","selector-tag":"int real vector simplex unit_vector ordered positive_ordered row_vector matrix cholesky_factor_corr cholesky_factor_cov corr_matrix cov_matrix",title:"functions model data parameters quantities transformed generated",literal:"true false"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/stata.js b/lib/highlight_js/assets/lang/stata.js index 98b110022b6..96ba263c793 100644 --- a/lib/highlight_js/assets/lang/stata.js +++ b/lib/highlight_js/assets/lang/stata.js @@ -1 +1 @@ -hljs.registerLanguage("stata",function(e){return{aliases:["do","ado"],cI:!0,k:"if else in foreach for forv forva forval forvalu forvalue forvalues by bys bysort xi quietly qui capture about ac ac_7 acprplot acprplot_7 adjust ado adopath adoupdate alpha ameans an ano anov anova anova_estat anova_terms anovadef aorder ap app appe appen append arch arch_dr arch_estat arch_p archlm areg areg_p args arima arima_dr arima_estat arima_p as asmprobit asmprobit_estat asmprobit_lf asmprobit_mfx__dlg asmprobit_p ass asse asser assert avplot avplot_7 avplots avplots_7 bcskew0 bgodfrey binreg bip0_lf biplot bipp_lf bipr_lf bipr_p biprobit bitest bitesti bitowt blogit bmemsize boot bootsamp bootstrap bootstrap_8 boxco_l boxco_p boxcox boxcox_6 boxcox_p bprobit br break brier bro brow brows browse brr brrstat bs bs_7 bsampl_w bsample bsample_7 bsqreg bstat bstat_7 bstat_8 bstrap bstrap_7 ca ca_estat ca_p cabiplot camat canon canon_8 canon_8_p canon_estat canon_p cap caprojection capt captu captur capture cat cc cchart cchart_7 cci cd censobs_table centile cf char chdir checkdlgfiles checkestimationsample checkhlpfiles checksum chelp ci cii cl class classutil clear cli clis clist clo clog clog_lf clog_p clogi clogi_sw clogit clogit_lf clogit_p clogitp clogl_sw cloglog clonevar clslistarray cluster cluster_measures cluster_stop cluster_tree cluster_tree_8 clustermat cmdlog cnr cnre cnreg cnreg_p cnreg_sw cnsreg codebook collaps4 collapse colormult_nb colormult_nw compare compress conf confi confir confirm conren cons const constr constra constrai constrain constraint continue contract copy copyright copysource cor corc corr corr2data corr_anti corr_kmo corr_smc corre correl correla correlat correlate corrgram cou coun count cox cox_p cox_sw coxbase coxhaz coxvar cprplot cprplot_7 crc cret cretu cretur creturn cross cs cscript cscript_log csi ct ct_is ctset ctst_5 ctst_st cttost cumsp cumsp_7 cumul cusum cusum_7 cutil d datasig datasign datasigna datasignat datasignatu datasignatur datasignature datetof db dbeta de dec deco decod decode deff des desc descr descri describ describe destring dfbeta dfgls dfuller di di_g dir dirstats dis discard disp disp_res disp_s displ displa display distinct do doe doed doedi doedit dotplot dotplot_7 dprobit drawnorm drop ds ds_util dstdize duplicates durbina dwstat dydx e ed edi edit egen eivreg emdef en enc enco encod encode eq erase ereg ereg_lf ereg_p ereg_sw ereghet ereghet_glf ereghet_glf_sh ereghet_gp ereghet_ilf ereghet_ilf_sh ereghet_ip eret eretu eretur ereturn err erro error est est_cfexist est_cfname est_clickable est_expand est_hold est_table est_unhold est_unholdok estat estat_default estat_summ estat_vce_only esti estimates etodow etof etomdy ex exi exit expand expandcl fac fact facto factor factor_estat factor_p factor_pca_rotated factor_rotate factormat fcast fcast_compute fcast_graph fdades fdadesc fdadescr fdadescri fdadescrib fdadescribe fdasav fdasave fdause fh_st file open file read file close file filefilter fillin find_hlp_file findfile findit findit_7 fit fl fli flis flist for5_0 form forma format fpredict frac_154 frac_adj frac_chk frac_cox frac_ddp frac_dis frac_dv frac_in frac_mun frac_pp frac_pq frac_pv frac_wgt frac_xo fracgen fracplot fracplot_7 fracpoly fracpred fron_ex fron_hn fron_p fron_tn fron_tn2 frontier ftodate ftoe ftomdy ftowdate g gamhet_glf gamhet_gp gamhet_ilf gamhet_ip gamma gamma_d2 gamma_p gamma_sw gammahet gdi_hexagon gdi_spokes ge gen gene gener genera generat generate genrank genstd genvmean gettoken gl gladder gladder_7 glim_l01 glim_l02 glim_l03 glim_l04 glim_l05 glim_l06 glim_l07 glim_l08 glim_l09 glim_l10 glim_l11 glim_l12 glim_lf glim_mu glim_nw1 glim_nw2 glim_nw3 glim_p glim_v1 glim_v2 glim_v3 glim_v4 glim_v5 glim_v6 glim_v7 glm glm_6 glm_p glm_sw glmpred glo glob globa global glogit glogit_8 glogit_p gmeans gnbre_lf gnbreg gnbreg_5 gnbreg_p gomp_lf gompe_sw gomper_p gompertz gompertzhet gomphet_glf gomphet_glf_sh gomphet_gp gomphet_ilf gomphet_ilf_sh gomphet_ip gphdot gphpen gphprint gprefs gprobi_p gprobit gprobit_8 gr gr7 gr_copy gr_current gr_db gr_describe gr_dir gr_draw gr_draw_replay gr_drop gr_edit gr_editviewopts gr_example gr_example2 gr_export gr_print gr_qscheme gr_query gr_read gr_rename gr_replay gr_save gr_set gr_setscheme gr_table gr_undo gr_use graph graph7 grebar greigen greigen_7 greigen_8 grmeanby grmeanby_7 gs_fileinfo gs_filetype gs_graphinfo gs_stat gsort gwood h hadimvo hareg hausman haver he heck_d2 heckma_p heckman heckp_lf heckpr_p heckprob hel help hereg hetpr_lf hetpr_p hetprob hettest hexdump hilite hist hist_7 histogram hlogit hlu hmeans hotel hotelling hprobit hreg hsearch icd9 icd9_ff icd9p iis impute imtest inbase include inf infi infil infile infix inp inpu input ins insheet insp inspe inspec inspect integ inten intreg intreg_7 intreg_p intrg2_ll intrg_ll intrg_ll2 ipolate iqreg ir irf irf_create irfm iri is_svy is_svysum isid istdize ivprob_1_lf ivprob_lf ivprobit ivprobit_p ivreg ivreg_footnote ivtob_1_lf ivtob_lf ivtobit ivtobit_p jackknife jacknife jknife jknife_6 jknife_8 jkstat joinby kalarma1 kap kap_3 kapmeier kappa kapwgt kdensity kdensity_7 keep ksm ksmirnov ktau kwallis l la lab labe label labelbook ladder levels levelsof leverage lfit lfit_p li lincom line linktest lis list lloghet_glf lloghet_glf_sh lloghet_gp lloghet_ilf lloghet_ilf_sh lloghet_ip llogi_sw llogis_p llogist llogistic llogistichet lnorm_lf lnorm_sw lnorma_p lnormal lnormalhet lnormhet_glf lnormhet_glf_sh lnormhet_gp lnormhet_ilf lnormhet_ilf_sh lnormhet_ip lnskew0 loadingplot loc loca local log logi logis_lf logistic logistic_p logit logit_estat logit_p loglogs logrank loneway lookfor lookup lowess lowess_7 lpredict lrecomp lroc lroc_7 lrtest ls lsens lsens_7 lsens_x lstat ltable ltable_7 ltriang lv lvr2plot lvr2plot_7 m ma mac macr macro makecns man manova manova_estat manova_p manovatest mantel mark markin markout marksample mat mat_capp mat_order mat_put_rr mat_rapp mata mata_clear mata_describe mata_drop mata_matdescribe mata_matsave mata_matuse mata_memory mata_mlib mata_mosave mata_rename mata_which matalabel matcproc matlist matname matr matri matrix matrix_input__dlg matstrik mcc mcci md0_ md1_ md1debug_ md2_ md2debug_ mds mds_estat mds_p mdsconfig mdslong mdsmat mdsshepard mdytoe mdytof me_derd mean means median memory memsize meqparse mer merg merge mfp mfx mhelp mhodds minbound mixed_ll mixed_ll_reparm mkassert mkdir mkmat mkspline ml ml_5 ml_adjs ml_bhhhs ml_c_d ml_check ml_clear ml_cnt ml_debug ml_defd ml_e0 ml_e0_bfgs ml_e0_cycle ml_e0_dfp ml_e0i ml_e1 ml_e1_bfgs ml_e1_bhhh ml_e1_cycle ml_e1_dfp ml_e2 ml_e2_cycle ml_ebfg0 ml_ebfr0 ml_ebfr1 ml_ebh0q ml_ebhh0 ml_ebhr0 ml_ebr0i ml_ecr0i ml_edfp0 ml_edfr0 ml_edfr1 ml_edr0i ml_eds ml_eer0i ml_egr0i ml_elf ml_elf_bfgs ml_elf_bhhh ml_elf_cycle ml_elf_dfp ml_elfi ml_elfs ml_enr0i ml_enrr0 ml_erdu0 ml_erdu0_bfgs ml_erdu0_bhhh ml_erdu0_bhhhq ml_erdu0_cycle ml_erdu0_dfp ml_erdu0_nrbfgs ml_exde ml_footnote ml_geqnr ml_grad0 ml_graph ml_hbhhh ml_hd0 ml_hold ml_init ml_inv ml_log ml_max ml_mlout ml_mlout_8 ml_model ml_nb0 ml_opt ml_p ml_plot ml_query ml_rdgrd ml_repor ml_s_e ml_score ml_searc ml_technique ml_unhold mleval mlf_ mlmatbysum mlmatsum mlog mlogi mlogit mlogit_footnote mlogit_p mlopts mlsum mlvecsum mnl0_ mor more mov move mprobit mprobit_lf mprobit_p mrdu0_ mrdu1_ mvdecode mvencode mvreg mvreg_estat n nbreg nbreg_al nbreg_lf nbreg_p nbreg_sw nestreg net newey newey_7 newey_p news nl nl_7 nl_9 nl_9_p nl_p nl_p_7 nlcom nlcom_p nlexp2 nlexp2_7 nlexp2a nlexp2a_7 nlexp3 nlexp3_7 nlgom3 nlgom3_7 nlgom4 nlgom4_7 nlinit nllog3 nllog3_7 nllog4 nllog4_7 nlog_rd nlogit nlogit_p nlogitgen nlogittree nlpred no nobreak noi nois noisi noisil noisily note notes notes_dlg nptrend numlabel numlist odbc old_ver olo olog ologi ologi_sw ologit ologit_p ologitp on one onew onewa oneway op_colnm op_comp op_diff op_inv op_str opr opro oprob oprob_sw oprobi oprobi_p oprobit oprobitp opts_exclusive order orthog orthpoly ou out outf outfi outfil outfile outs outsh outshe outshee outsheet ovtest pac pac_7 palette parse parse_dissim pause pca pca_8 pca_display pca_estat pca_p pca_rotate pcamat pchart pchart_7 pchi pchi_7 pcorr pctile pentium pergram pergram_7 permute permute_8 personal peto_st pkcollapse pkcross pkequiv pkexamine pkexamine_7 pkshape pksumm pksumm_7 pl plo plot plugin pnorm pnorm_7 poisgof poiss_lf poiss_sw poisso_p poisson poisson_estat post postclose postfile postutil pperron pr prais prais_e prais_e2 prais_p predict predictnl preserve print pro prob probi probit probit_estat probit_p proc_time procoverlay procrustes procrustes_estat procrustes_p profiler prog progr progra program prop proportion prtest prtesti pwcorr pwd q\\s qby qbys qchi qchi_7 qladder qladder_7 qnorm qnorm_7 qqplot qqplot_7 qreg qreg_c qreg_p qreg_sw qu quadchk quantile quantile_7 que quer query range ranksum ratio rchart rchart_7 rcof recast reclink recode reg reg3 reg3_p regdw regr regre regre_p2 regres regres_p regress regress_estat regriv_p remap ren rena renam rename renpfix repeat replace report reshape restore ret retu retur return rm rmdir robvar roccomp roccomp_7 roccomp_8 rocf_lf rocfit rocfit_8 rocgold rocplot rocplot_7 roctab roctab_7 rolling rologit rologit_p rot rota rotat rotate rotatemat rreg rreg_p ru run runtest rvfplot rvfplot_7 rvpplot rvpplot_7 sa safesum sample sampsi sav save savedresults saveold sc sca scal scala scalar scatter scm_mine sco scob_lf scob_p scobi_sw scobit scor score scoreplot scoreplot_help scree screeplot screeplot_help sdtest sdtesti se search separate seperate serrbar serrbar_7 serset set set_defaults sfrancia sh she shel shell shewhart shewhart_7 signestimationsample signrank signtest simul simul_7 simulate simulate_8 sktest sleep slogit slogit_d2 slogit_p smooth snapspan so sor sort spearman spikeplot spikeplot_7 spikeplt spline_x split sqreg sqreg_p sret sretu sretur sreturn ssc st st_ct st_hc st_hcd st_hcd_sh st_is st_issys st_note st_promo st_set st_show st_smpl st_subid stack statsby statsby_8 stbase stci stci_7 stcox stcox_estat stcox_fr stcox_fr_ll stcox_p stcox_sw stcoxkm stcoxkm_7 stcstat stcurv stcurve stcurve_7 stdes stem stepwise stereg stfill stgen stir stjoin stmc stmh stphplot stphplot_7 stphtest stphtest_7 stptime strate strate_7 streg streg_sw streset sts sts_7 stset stsplit stsum sttocc sttoct stvary stweib su suest suest_8 sum summ summa summar summari summariz summarize sunflower sureg survcurv survsum svar svar_p svmat svy svy_disp svy_dreg svy_est svy_est_7 svy_estat svy_get svy_gnbreg_p svy_head svy_header svy_heckman_p svy_heckprob_p svy_intreg_p svy_ivreg_p svy_logistic_p svy_logit_p svy_mlogit_p svy_nbreg_p svy_ologit_p svy_oprobit_p svy_poisson_p svy_probit_p svy_regress_p svy_sub svy_sub_7 svy_x svy_x_7 svy_x_p svydes svydes_8 svygen svygnbreg svyheckman svyheckprob svyintreg svyintreg_7 svyintrg svyivreg svylc svylog_p svylogit svymarkout svymarkout_8 svymean svymlog svymlogit svynbreg svyolog svyologit svyoprob svyoprobit svyopts svypois svypois_7 svypoisson svyprobit svyprobt svyprop svyprop_7 svyratio svyreg svyreg_p svyregress svyset svyset_7 svyset_8 svytab svytab_7 svytest svytotal sw sw_8 swcnreg swcox swereg swilk swlogis swlogit swologit swoprbt swpois swprobit swqreg swtobit swweib symmetry symmi symplot symplot_7 syntax sysdescribe sysdir sysuse szroeter ta tab tab1 tab2 tab_or tabd tabdi tabdis tabdisp tabi table tabodds tabodds_7 tabstat tabu tabul tabula tabulat tabulate te tempfile tempname tempvar tes test testnl testparm teststd tetrachoric time_it timer tis tob tobi tobit tobit_p tobit_sw token tokeni tokeniz tokenize tostring total translate translator transmap treat_ll treatr_p treatreg trim trnb_cons trnb_mean trpoiss_d2 trunc_ll truncr_p truncreg tsappend tset tsfill tsline tsline_ex tsreport tsrevar tsrline tsset tssmooth tsunab ttest ttesti tut_chk tut_wait tutorial tw tware_st two twoway twoway__fpfit_serset twoway__function_gen twoway__histogram_gen twoway__ipoint_serset twoway__ipoints_serset twoway__kdensity_gen twoway__lfit_serset twoway__normgen_gen twoway__pci_serset twoway__qfit_serset twoway__scatteri_serset twoway__sunflower_gen twoway_ksm_serset ty typ type typeof u unab unabbrev unabcmd update us use uselabel var var_mkcompanion var_p varbasic varfcast vargranger varirf varirf_add varirf_cgraph varirf_create varirf_ctable varirf_describe varirf_dir varirf_drop varirf_erase varirf_graph varirf_ograph varirf_rename varirf_set varirf_table varlist varlmar varnorm varsoc varstable varstable_w varstable_w2 varwle vce vec vec_fevd vec_mkphi vec_p vec_p_w vecirf_create veclmar veclmar_w vecnorm vecnorm_w vecrank vecstable verinst vers versi versio version view viewsource vif vwls wdatetof webdescribe webseek webuse weib1_lf weib2_lf weib_lf weib_lf0 weibhet_glf weibhet_glf_sh weibhet_glfa weibhet_glfa_sh weibhet_gp weibhet_ilf weibhet_ilf_sh weibhet_ilfa weibhet_ilfa_sh weibhet_ip weibu_sw weibul_p weibull weibull_c weibull_s weibullhet wh whelp whi which whil while wilc_st wilcoxon win wind windo window winexec wntestb wntestb_7 wntestq xchart xchart_7 xcorr xcorr_7 xi xi_6 xmlsav xmlsave xmluse xpose xsh xshe xshel xshell xt_iis xt_tis xtab_p xtabond xtbin_p xtclog xtcloglog xtcloglog_8 xtcloglog_d2 xtcloglog_pa_p xtcloglog_re_p xtcnt_p xtcorr xtdata xtdes xtfront_p xtfrontier xtgee xtgee_elink xtgee_estat xtgee_makeivar xtgee_p xtgee_plink xtgls xtgls_p xthaus xthausman xtht_p xthtaylor xtile xtint_p xtintreg xtintreg_8 xtintreg_d2 xtintreg_p xtivp_1 xtivp_2 xtivreg xtline xtline_ex xtlogit xtlogit_8 xtlogit_d2 xtlogit_fe_p xtlogit_pa_p xtlogit_re_p xtmixed xtmixed_estat xtmixed_p xtnb_fe xtnb_lf xtnbreg xtnbreg_pa_p xtnbreg_refe_p xtpcse xtpcse_p xtpois xtpoisson xtpoisson_d2 xtpoisson_pa_p xtpoisson_refe_p xtpred xtprobit xtprobit_8 xtprobit_d2 xtprobit_re_p xtps_fe xtps_lf xtps_ren xtps_ren_8 xtrar_p xtrc xtrc_p xtrchh xtrefe_p xtreg xtreg_be xtreg_fe xtreg_ml xtreg_pa_p xtreg_re xtregar xtrere_p xtset xtsf_ll xtsf_llti xtsum xttab xttest0 xttobit xttobit_8 xttobit_p xttrans yx yxview__barlike_draw yxview_area_draw yxview_bar_draw yxview_dot_draw yxview_dropline_draw yxview_function_draw yxview_iarrow_draw yxview_ilabels_draw yxview_normal_draw yxview_pcarrow_draw yxview_pcbarrow_draw yxview_pccapsym_draw yxview_pcscatter_draw yxview_pcspike_draw yxview_rarea_draw yxview_rbar_draw yxview_rbarm_draw yxview_rcap_draw yxview_rcapsym_draw yxview_rconnected_draw yxview_rline_draw yxview_rscatter_draw yxview_rspike_draw yxview_spike_draw yxview_sunflower_draw zap_s zinb zinb_llf zinb_plf zip zip_llf zip_p zip_plf zt_ct_5 zt_hc_5 zt_hcd_5 zt_is_5 zt_iss_5 zt_sho_5 zt_smp_5 ztbase_5 ztcox_5 ztdes_5 ztereg_5 ztfill_5 ztgen_5 ztir_5 ztjoin_5 ztnb ztnb_p ztp ztp_p zts_5 ztset_5 ztspli_5 ztsum_5 zttoct_5 ztvary_5 ztweib_5",c:[{cN:"label",v:[{b:"\\$\\{?[a-zA-Z0-9_]+\\}?"},{b:"`[a-zA-Z0-9_]+'"}]},{cN:"string",v:[{b:'`"[^\r\n]*?"\''},{b:'"[^\r\n"]*"'}]},{cN:"literal",v:[{b:"\\b(abs|acos|asin|atan|atan2|atanh|ceil|cloglog|comb|cos|digamma|exp|floor|invcloglog|invlogit|ln|lnfact|lnfactorial|lngamma|log|log10|max|min|mod|reldif|round|sign|sin|sqrt|sum|tan|tanh|trigamma|trunc|betaden|Binomial|binorm|binormal|chi2|chi2tail|dgammapda|dgammapdada|dgammapdadx|dgammapdx|dgammapdxdx|F|Fden|Ftail|gammaden|gammap|ibeta|invbinomial|invchi2|invchi2tail|invF|invFtail|invgammap|invibeta|invnchi2|invnFtail|invnibeta|invnorm|invnormal|invttail|nbetaden|nchi2|nFden|nFtail|nibeta|norm|normal|normalden|normd|npnchi2|tden|ttail|uniform|abbrev|char|index|indexnot|length|lower|ltrim|match|plural|proper|real|regexm|regexr|regexs|reverse|rtrim|string|strlen|strlower|strltrim|strmatch|strofreal|strpos|strproper|strreverse|strrtrim|strtrim|strupper|subinstr|subinword|substr|trim|upper|word|wordcount|_caller|autocode|byteorder|chop|clip|cond|e|epsdouble|epsfloat|group|inlist|inrange|irecode|matrix|maxbyte|maxdouble|maxfloat|maxint|maxlong|mi|minbyte|mindouble|minfloat|minint|minlong|missing|r|recode|replay|return|s|scalar|d|date|day|dow|doy|halfyear|mdy|month|quarter|week|year|d|daily|dofd|dofh|dofm|dofq|dofw|dofy|h|halfyearly|hofd|m|mofd|monthly|q|qofd|quarterly|tin|twithin|w|weekly|wofd|y|yearly|yh|ym|yofd|yq|yw|cholesky|colnumb|colsof|corr|det|diag|diag0cnt|el|get|hadamard|I|inv|invsym|issym|issymmetric|J|matmissing|matuniform|mreldif|nullmat|rownumb|rowsof|sweep|syminv|trace|vec|vecdiag)(?=\\(|$)"}]},e.C("^[ ]*\\*.*$",!1),e.CLCM,e.CBCM]}}); \ No newline at end of file +hljs.registerLanguage("stata",function(e){return{aliases:["do","ado"],cI:!0,k:"if else in foreach for forv forva forval forvalu forvalue forvalues by bys bysort xi quietly qui capture about ac ac_7 acprplot acprplot_7 adjust ado adopath adoupdate alpha ameans an ano anov anova anova_estat anova_terms anovadef aorder ap app appe appen append arch arch_dr arch_estat arch_p archlm areg areg_p args arima arima_dr arima_estat arima_p as asmprobit asmprobit_estat asmprobit_lf asmprobit_mfx__dlg asmprobit_p ass asse asser assert avplot avplot_7 avplots avplots_7 bcskew0 bgodfrey binreg bip0_lf biplot bipp_lf bipr_lf bipr_p biprobit bitest bitesti bitowt blogit bmemsize boot bootsamp bootstrap bootstrap_8 boxco_l boxco_p boxcox boxcox_6 boxcox_p bprobit br break brier bro brow brows browse brr brrstat bs bs_7 bsampl_w bsample bsample_7 bsqreg bstat bstat_7 bstat_8 bstrap bstrap_7 ca ca_estat ca_p cabiplot camat canon canon_8 canon_8_p canon_estat canon_p cap caprojection capt captu captur capture cat cc cchart cchart_7 cci cd censobs_table centile cf char chdir checkdlgfiles checkestimationsample checkhlpfiles checksum chelp ci cii cl class classutil clear cli clis clist clo clog clog_lf clog_p clogi clogi_sw clogit clogit_lf clogit_p clogitp clogl_sw cloglog clonevar clslistarray cluster cluster_measures cluster_stop cluster_tree cluster_tree_8 clustermat cmdlog cnr cnre cnreg cnreg_p cnreg_sw cnsreg codebook collaps4 collapse colormult_nb colormult_nw compare compress conf confi confir confirm conren cons const constr constra constrai constrain constraint continue contract copy copyright copysource cor corc corr corr2data corr_anti corr_kmo corr_smc corre correl correla correlat correlate corrgram cou coun count cox cox_p cox_sw coxbase coxhaz coxvar cprplot cprplot_7 crc cret cretu cretur creturn cross cs cscript cscript_log csi ct ct_is ctset ctst_5 ctst_st cttost cumsp cumsp_7 cumul cusum cusum_7 cutil d datasig datasign datasigna datasignat datasignatu datasignatur datasignature datetof db dbeta de dec deco decod decode deff des desc descr descri describ describe destring dfbeta dfgls dfuller di di_g dir dirstats dis discard disp disp_res disp_s displ displa display distinct do doe doed doedi doedit dotplot dotplot_7 dprobit drawnorm drop ds ds_util dstdize duplicates durbina dwstat dydx e ed edi edit egen eivreg emdef en enc enco encod encode eq erase ereg ereg_lf ereg_p ereg_sw ereghet ereghet_glf ereghet_glf_sh ereghet_gp ereghet_ilf ereghet_ilf_sh ereghet_ip eret eretu eretur ereturn err erro error est est_cfexist est_cfname est_clickable est_expand est_hold est_table est_unhold est_unholdok estat estat_default estat_summ estat_vce_only esti estimates etodow etof etomdy ex exi exit expand expandcl fac fact facto factor factor_estat factor_p factor_pca_rotated factor_rotate factormat fcast fcast_compute fcast_graph fdades fdadesc fdadescr fdadescri fdadescrib fdadescribe fdasav fdasave fdause fh_st file open file read file close file filefilter fillin find_hlp_file findfile findit findit_7 fit fl fli flis flist for5_0 form forma format fpredict frac_154 frac_adj frac_chk frac_cox frac_ddp frac_dis frac_dv frac_in frac_mun frac_pp frac_pq frac_pv frac_wgt frac_xo fracgen fracplot fracplot_7 fracpoly fracpred fron_ex fron_hn fron_p fron_tn fron_tn2 frontier ftodate ftoe ftomdy ftowdate g gamhet_glf gamhet_gp gamhet_ilf gamhet_ip gamma gamma_d2 gamma_p gamma_sw gammahet gdi_hexagon gdi_spokes ge gen gene gener genera generat generate genrank genstd genvmean gettoken gl gladder gladder_7 glim_l01 glim_l02 glim_l03 glim_l04 glim_l05 glim_l06 glim_l07 glim_l08 glim_l09 glim_l10 glim_l11 glim_l12 glim_lf glim_mu glim_nw1 glim_nw2 glim_nw3 glim_p glim_v1 glim_v2 glim_v3 glim_v4 glim_v5 glim_v6 glim_v7 glm glm_6 glm_p glm_sw glmpred glo glob globa global glogit glogit_8 glogit_p gmeans gnbre_lf gnbreg gnbreg_5 gnbreg_p gomp_lf gompe_sw gomper_p gompertz gompertzhet gomphet_glf gomphet_glf_sh gomphet_gp gomphet_ilf gomphet_ilf_sh gomphet_ip gphdot gphpen gphprint gprefs gprobi_p gprobit gprobit_8 gr gr7 gr_copy gr_current gr_db gr_describe gr_dir gr_draw gr_draw_replay gr_drop gr_edit gr_editviewopts gr_example gr_example2 gr_export gr_print gr_qscheme gr_query gr_read gr_rename gr_replay gr_save gr_set gr_setscheme gr_table gr_undo gr_use graph graph7 grebar greigen greigen_7 greigen_8 grmeanby grmeanby_7 gs_fileinfo gs_filetype gs_graphinfo gs_stat gsort gwood h hadimvo hareg hausman haver he heck_d2 heckma_p heckman heckp_lf heckpr_p heckprob hel help hereg hetpr_lf hetpr_p hetprob hettest hexdump hilite hist hist_7 histogram hlogit hlu hmeans hotel hotelling hprobit hreg hsearch icd9 icd9_ff icd9p iis impute imtest inbase include inf infi infil infile infix inp inpu input ins insheet insp inspe inspec inspect integ inten intreg intreg_7 intreg_p intrg2_ll intrg_ll intrg_ll2 ipolate iqreg ir irf irf_create irfm iri is_svy is_svysum isid istdize ivprob_1_lf ivprob_lf ivprobit ivprobit_p ivreg ivreg_footnote ivtob_1_lf ivtob_lf ivtobit ivtobit_p jackknife jacknife jknife jknife_6 jknife_8 jkstat joinby kalarma1 kap kap_3 kapmeier kappa kapwgt kdensity kdensity_7 keep ksm ksmirnov ktau kwallis l la lab labe label labelbook ladder levels levelsof leverage lfit lfit_p li lincom line linktest lis list lloghet_glf lloghet_glf_sh lloghet_gp lloghet_ilf lloghet_ilf_sh lloghet_ip llogi_sw llogis_p llogist llogistic llogistichet lnorm_lf lnorm_sw lnorma_p lnormal lnormalhet lnormhet_glf lnormhet_glf_sh lnormhet_gp lnormhet_ilf lnormhet_ilf_sh lnormhet_ip lnskew0 loadingplot loc loca local log logi logis_lf logistic logistic_p logit logit_estat logit_p loglogs logrank loneway lookfor lookup lowess lowess_7 lpredict lrecomp lroc lroc_7 lrtest ls lsens lsens_7 lsens_x lstat ltable ltable_7 ltriang lv lvr2plot lvr2plot_7 m ma mac macr macro makecns man manova manova_estat manova_p manovatest mantel mark markin markout marksample mat mat_capp mat_order mat_put_rr mat_rapp mata mata_clear mata_describe mata_drop mata_matdescribe mata_matsave mata_matuse mata_memory mata_mlib mata_mosave mata_rename mata_which matalabel matcproc matlist matname matr matri matrix matrix_input__dlg matstrik mcc mcci md0_ md1_ md1debug_ md2_ md2debug_ mds mds_estat mds_p mdsconfig mdslong mdsmat mdsshepard mdytoe mdytof me_derd mean means median memory memsize meqparse mer merg merge mfp mfx mhelp mhodds minbound mixed_ll mixed_ll_reparm mkassert mkdir mkmat mkspline ml ml_5 ml_adjs ml_bhhhs ml_c_d ml_check ml_clear ml_cnt ml_debug ml_defd ml_e0 ml_e0_bfgs ml_e0_cycle ml_e0_dfp ml_e0i ml_e1 ml_e1_bfgs ml_e1_bhhh ml_e1_cycle ml_e1_dfp ml_e2 ml_e2_cycle ml_ebfg0 ml_ebfr0 ml_ebfr1 ml_ebh0q ml_ebhh0 ml_ebhr0 ml_ebr0i ml_ecr0i ml_edfp0 ml_edfr0 ml_edfr1 ml_edr0i ml_eds ml_eer0i ml_egr0i ml_elf ml_elf_bfgs ml_elf_bhhh ml_elf_cycle ml_elf_dfp ml_elfi ml_elfs ml_enr0i ml_enrr0 ml_erdu0 ml_erdu0_bfgs ml_erdu0_bhhh ml_erdu0_bhhhq ml_erdu0_cycle ml_erdu0_dfp ml_erdu0_nrbfgs ml_exde ml_footnote ml_geqnr ml_grad0 ml_graph ml_hbhhh ml_hd0 ml_hold ml_init ml_inv ml_log ml_max ml_mlout ml_mlout_8 ml_model ml_nb0 ml_opt ml_p ml_plot ml_query ml_rdgrd ml_repor ml_s_e ml_score ml_searc ml_technique ml_unhold mleval mlf_ mlmatbysum mlmatsum mlog mlogi mlogit mlogit_footnote mlogit_p mlopts mlsum mlvecsum mnl0_ mor more mov move mprobit mprobit_lf mprobit_p mrdu0_ mrdu1_ mvdecode mvencode mvreg mvreg_estat n nbreg nbreg_al nbreg_lf nbreg_p nbreg_sw nestreg net newey newey_7 newey_p news nl nl_7 nl_9 nl_9_p nl_p nl_p_7 nlcom nlcom_p nlexp2 nlexp2_7 nlexp2a nlexp2a_7 nlexp3 nlexp3_7 nlgom3 nlgom3_7 nlgom4 nlgom4_7 nlinit nllog3 nllog3_7 nllog4 nllog4_7 nlog_rd nlogit nlogit_p nlogitgen nlogittree nlpred no nobreak noi nois noisi noisil noisily note notes notes_dlg nptrend numlabel numlist odbc old_ver olo olog ologi ologi_sw ologit ologit_p ologitp on one onew onewa oneway op_colnm op_comp op_diff op_inv op_str opr opro oprob oprob_sw oprobi oprobi_p oprobit oprobitp opts_exclusive order orthog orthpoly ou out outf outfi outfil outfile outs outsh outshe outshee outsheet ovtest pac pac_7 palette parse parse_dissim pause pca pca_8 pca_display pca_estat pca_p pca_rotate pcamat pchart pchart_7 pchi pchi_7 pcorr pctile pentium pergram pergram_7 permute permute_8 personal peto_st pkcollapse pkcross pkequiv pkexamine pkexamine_7 pkshape pksumm pksumm_7 pl plo plot plugin pnorm pnorm_7 poisgof poiss_lf poiss_sw poisso_p poisson poisson_estat post postclose postfile postutil pperron pr prais prais_e prais_e2 prais_p predict predictnl preserve print pro prob probi probit probit_estat probit_p proc_time procoverlay procrustes procrustes_estat procrustes_p profiler prog progr progra program prop proportion prtest prtesti pwcorr pwd q\\s qby qbys qchi qchi_7 qladder qladder_7 qnorm qnorm_7 qqplot qqplot_7 qreg qreg_c qreg_p qreg_sw qu quadchk quantile quantile_7 que quer query range ranksum ratio rchart rchart_7 rcof recast reclink recode reg reg3 reg3_p regdw regr regre regre_p2 regres regres_p regress regress_estat regriv_p remap ren rena renam rename renpfix repeat replace report reshape restore ret retu retur return rm rmdir robvar roccomp roccomp_7 roccomp_8 rocf_lf rocfit rocfit_8 rocgold rocplot rocplot_7 roctab roctab_7 rolling rologit rologit_p rot rota rotat rotate rotatemat rreg rreg_p ru run runtest rvfplot rvfplot_7 rvpplot rvpplot_7 sa safesum sample sampsi sav save savedresults saveold sc sca scal scala scalar scatter scm_mine sco scob_lf scob_p scobi_sw scobit scor score scoreplot scoreplot_help scree screeplot screeplot_help sdtest sdtesti se search separate seperate serrbar serrbar_7 serset set set_defaults sfrancia sh she shel shell shewhart shewhart_7 signestimationsample signrank signtest simul simul_7 simulate simulate_8 sktest sleep slogit slogit_d2 slogit_p smooth snapspan so sor sort spearman spikeplot spikeplot_7 spikeplt spline_x split sqreg sqreg_p sret sretu sretur sreturn ssc st st_ct st_hc st_hcd st_hcd_sh st_is st_issys st_note st_promo st_set st_show st_smpl st_subid stack statsby statsby_8 stbase stci stci_7 stcox stcox_estat stcox_fr stcox_fr_ll stcox_p stcox_sw stcoxkm stcoxkm_7 stcstat stcurv stcurve stcurve_7 stdes stem stepwise stereg stfill stgen stir stjoin stmc stmh stphplot stphplot_7 stphtest stphtest_7 stptime strate strate_7 streg streg_sw streset sts sts_7 stset stsplit stsum sttocc sttoct stvary stweib su suest suest_8 sum summ summa summar summari summariz summarize sunflower sureg survcurv survsum svar svar_p svmat svy svy_disp svy_dreg svy_est svy_est_7 svy_estat svy_get svy_gnbreg_p svy_head svy_header svy_heckman_p svy_heckprob_p svy_intreg_p svy_ivreg_p svy_logistic_p svy_logit_p svy_mlogit_p svy_nbreg_p svy_ologit_p svy_oprobit_p svy_poisson_p svy_probit_p svy_regress_p svy_sub svy_sub_7 svy_x svy_x_7 svy_x_p svydes svydes_8 svygen svygnbreg svyheckman svyheckprob svyintreg svyintreg_7 svyintrg svyivreg svylc svylog_p svylogit svymarkout svymarkout_8 svymean svymlog svymlogit svynbreg svyolog svyologit svyoprob svyoprobit svyopts svypois svypois_7 svypoisson svyprobit svyprobt svyprop svyprop_7 svyratio svyreg svyreg_p svyregress svyset svyset_7 svyset_8 svytab svytab_7 svytest svytotal sw sw_8 swcnreg swcox swereg swilk swlogis swlogit swologit swoprbt swpois swprobit swqreg swtobit swweib symmetry symmi symplot symplot_7 syntax sysdescribe sysdir sysuse szroeter ta tab tab1 tab2 tab_or tabd tabdi tabdis tabdisp tabi table tabodds tabodds_7 tabstat tabu tabul tabula tabulat tabulate te tempfile tempname tempvar tes test testnl testparm teststd tetrachoric time_it timer tis tob tobi tobit tobit_p tobit_sw token tokeni tokeniz tokenize tostring total translate translator transmap treat_ll treatr_p treatreg trim trnb_cons trnb_mean trpoiss_d2 trunc_ll truncr_p truncreg tsappend tset tsfill tsline tsline_ex tsreport tsrevar tsrline tsset tssmooth tsunab ttest ttesti tut_chk tut_wait tutorial tw tware_st two twoway twoway__fpfit_serset twoway__function_gen twoway__histogram_gen twoway__ipoint_serset twoway__ipoints_serset twoway__kdensity_gen twoway__lfit_serset twoway__normgen_gen twoway__pci_serset twoway__qfit_serset twoway__scatteri_serset twoway__sunflower_gen twoway_ksm_serset ty typ type typeof u unab unabbrev unabcmd update us use uselabel var var_mkcompanion var_p varbasic varfcast vargranger varirf varirf_add varirf_cgraph varirf_create varirf_ctable varirf_describe varirf_dir varirf_drop varirf_erase varirf_graph varirf_ograph varirf_rename varirf_set varirf_table varlist varlmar varnorm varsoc varstable varstable_w varstable_w2 varwle vce vec vec_fevd vec_mkphi vec_p vec_p_w vecirf_create veclmar veclmar_w vecnorm vecnorm_w vecrank vecstable verinst vers versi versio version view viewsource vif vwls wdatetof webdescribe webseek webuse weib1_lf weib2_lf weib_lf weib_lf0 weibhet_glf weibhet_glf_sh weibhet_glfa weibhet_glfa_sh weibhet_gp weibhet_ilf weibhet_ilf_sh weibhet_ilfa weibhet_ilfa_sh weibhet_ip weibu_sw weibul_p weibull weibull_c weibull_s weibullhet wh whelp whi which whil while wilc_st wilcoxon win wind windo window winexec wntestb wntestb_7 wntestq xchart xchart_7 xcorr xcorr_7 xi xi_6 xmlsav xmlsave xmluse xpose xsh xshe xshel xshell xt_iis xt_tis xtab_p xtabond xtbin_p xtclog xtcloglog xtcloglog_8 xtcloglog_d2 xtcloglog_pa_p xtcloglog_re_p xtcnt_p xtcorr xtdata xtdes xtfront_p xtfrontier xtgee xtgee_elink xtgee_estat xtgee_makeivar xtgee_p xtgee_plink xtgls xtgls_p xthaus xthausman xtht_p xthtaylor xtile xtint_p xtintreg xtintreg_8 xtintreg_d2 xtintreg_p xtivp_1 xtivp_2 xtivreg xtline xtline_ex xtlogit xtlogit_8 xtlogit_d2 xtlogit_fe_p xtlogit_pa_p xtlogit_re_p xtmixed xtmixed_estat xtmixed_p xtnb_fe xtnb_lf xtnbreg xtnbreg_pa_p xtnbreg_refe_p xtpcse xtpcse_p xtpois xtpoisson xtpoisson_d2 xtpoisson_pa_p xtpoisson_refe_p xtpred xtprobit xtprobit_8 xtprobit_d2 xtprobit_re_p xtps_fe xtps_lf xtps_ren xtps_ren_8 xtrar_p xtrc xtrc_p xtrchh xtrefe_p xtreg xtreg_be xtreg_fe xtreg_ml xtreg_pa_p xtreg_re xtregar xtrere_p xtset xtsf_ll xtsf_llti xtsum xttab xttest0 xttobit xttobit_8 xttobit_p xttrans yx yxview__barlike_draw yxview_area_draw yxview_bar_draw yxview_dot_draw yxview_dropline_draw yxview_function_draw yxview_iarrow_draw yxview_ilabels_draw yxview_normal_draw yxview_pcarrow_draw yxview_pcbarrow_draw yxview_pccapsym_draw yxview_pcscatter_draw yxview_pcspike_draw yxview_rarea_draw yxview_rbar_draw yxview_rbarm_draw yxview_rcap_draw yxview_rcapsym_draw yxview_rconnected_draw yxview_rline_draw yxview_rscatter_draw yxview_rspike_draw yxview_spike_draw yxview_sunflower_draw zap_s zinb zinb_llf zinb_plf zip zip_llf zip_p zip_plf zt_ct_5 zt_hc_5 zt_hcd_5 zt_is_5 zt_iss_5 zt_sho_5 zt_smp_5 ztbase_5 ztcox_5 ztdes_5 ztereg_5 ztfill_5 ztgen_5 ztir_5 ztjoin_5 ztnb ztnb_p ztp ztp_p zts_5 ztset_5 ztspli_5 ztsum_5 zttoct_5 ztvary_5 ztweib_5",c:[{cN:"symbol",b:/`[a-zA-Z0-9_]+'/},{cN:"variable",b:/\$\{?[a-zA-Z0-9_]+\}?/},{cN:"string",v:[{b:'`"[^\r\n]*?"\''},{b:'"[^\r\n"]*"'}]},{cN:"built_in",v:[{b:"\\b(abs|acos|asin|atan|atan2|atanh|ceil|cloglog|comb|cos|digamma|exp|floor|invcloglog|invlogit|ln|lnfact|lnfactorial|lngamma|log|log10|max|min|mod|reldif|round|sign|sin|sqrt|sum|tan|tanh|trigamma|trunc|betaden|Binomial|binorm|binormal|chi2|chi2tail|dgammapda|dgammapdada|dgammapdadx|dgammapdx|dgammapdxdx|F|Fden|Ftail|gammaden|gammap|ibeta|invbinomial|invchi2|invchi2tail|invF|invFtail|invgammap|invibeta|invnchi2|invnFtail|invnibeta|invnorm|invnormal|invttail|nbetaden|nchi2|nFden|nFtail|nibeta|norm|normal|normalden|normd|npnchi2|tden|ttail|uniform|abbrev|char|index|indexnot|length|lower|ltrim|match|plural|proper|real|regexm|regexr|regexs|reverse|rtrim|string|strlen|strlower|strltrim|strmatch|strofreal|strpos|strproper|strreverse|strrtrim|strtrim|strupper|subinstr|subinword|substr|trim|upper|word|wordcount|_caller|autocode|byteorder|chop|clip|cond|e|epsdouble|epsfloat|group|inlist|inrange|irecode|matrix|maxbyte|maxdouble|maxfloat|maxint|maxlong|mi|minbyte|mindouble|minfloat|minint|minlong|missing|r|recode|replay|return|s|scalar|d|date|day|dow|doy|halfyear|mdy|month|quarter|week|year|d|daily|dofd|dofh|dofm|dofq|dofw|dofy|h|halfyearly|hofd|m|mofd|monthly|q|qofd|quarterly|tin|twithin|w|weekly|wofd|y|yearly|yh|ym|yofd|yq|yw|cholesky|colnumb|colsof|corr|det|diag|diag0cnt|el|get|hadamard|I|inv|invsym|issym|issymmetric|J|matmissing|matuniform|mreldif|nullmat|rownumb|rowsof|sweep|syminv|trace|vec|vecdiag)(?=\\(|$)"}]},e.C("^[ ]*\\*.*$",!1),e.CLCM,e.CBCM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/step21.js b/lib/highlight_js/assets/lang/step21.js index 932f1b1289e..052b8297a17 100644 --- a/lib/highlight_js/assets/lang/step21.js +++ b/lib/highlight_js/assets/lang/step21.js @@ -1 +1 @@ -hljs.registerLanguage("step21",function(e){var r="[A-Z_][A-Z0-9_.]*",i="END-ISO-10303-21;",l={literal:"",built_in:"",keyword:"HEADER ENDSEC DATA"},s={cN:"preprocessor",b:"ISO-10303-21;",r:10},t=[e.CLCM,e.CBCM,e.C("/\\*\\*!","\\*/"),e.CNM,e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"'",e:"'"},{cN:"label",v:[{b:"#",e:"\\d+",i:"\\W"}]}];return{aliases:["p21","step","stp"],cI:!0,l:r,k:l,c:[{cN:"preprocessor",b:i,r:10},s].concat(t)}}); \ No newline at end of file +hljs.registerLanguage("step21",function(e){var i="[A-Z_][A-Z0-9_.]*",r={keyword:"HEADER ENDSEC DATA"},t={cN:"meta",b:"ISO-10303-21;",r:10},n={cN:"meta",b:"END-ISO-10303-21;",r:10};return{aliases:["p21","step","stp"],cI:!0,l:i,k:r,c:[t,n,e.CLCM,e.CBCM,e.C("/\\*\\*!","\\*/"),e.CNM,e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"'",e:"'"},{cN:"symbol",v:[{b:"#",e:"\\d+",i:"\\W"}]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/stylus.js b/lib/highlight_js/assets/lang/stylus.js index d78cc84e40c..4f676a30709 100644 --- a/lib/highlight_js/assets/lang/stylus.js +++ b/lib/highlight_js/assets/lang/stylus.js @@ -1 +1 @@ -hljs.registerLanguage("stylus",function(t){var e={cN:"variable",b:"\\$"+t.IR},o={cN:"hexcolor",b:"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})",r:10},i=["charset","css","debug","extend","font-face","for","import","include","media","mixin","page","warn","while"],r=["after","before","first-letter","first-line","active","first-child","focus","hover","lang","link","visited"],n=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],a="[\\.\\s\\n\\[\\:,]",l=["align-content","align-items","align-self","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","auto","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","clip-path","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","font","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-variant-ligatures","font-weight","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inherit","initial","justify-content","left","letter-spacing","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","mask","max-height","max-width","min-height","min-width","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","perspective","perspective-origin","pointer-events","position","quotes","resize","right","tab-size","table-layout","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-indent","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","white-space","widows","width","word-break","word-spacing","word-wrap","z-index"],d=["\\{","\\}","\\?","(\\bReturn\\b)","(\\bEnd\\b)","(\\bend\\b)",";","#\\s","\\*\\s","===\\s","\\|","%"];return{aliases:["styl"],cI:!1,i:"("+d.join("|")+")",k:"if else for in",c:[t.QSM,t.ASM,t.CLCM,t.CBCM,o,{b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"class",b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"id",b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\b("+n.join("|")+")"+a,rB:!0,c:[{cN:"tag",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"}]},{cN:"pseudo",b:"&?:?:\\b("+r.join("|")+")"+a},{cN:"at_rule",b:"@("+i.join("|")+")\\b"},e,t.CSSNM,t.NM,{cN:"function",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*\\(.*\\)",i:"[\\n]",rB:!0,c:[{cN:"title",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"},{cN:"params",b:/\(/,e:/\)/,c:[o,e,t.ASM,t.CSSNM,t.NM,t.QSM]}]},{cN:"attribute",b:"\\b("+l.reverse().join("|")+")\\b"}]}}); \ No newline at end of file +hljs.registerLanguage("stylus",function(e){var t={cN:"variable",b:"\\$"+e.IR},o={cN:"number",b:"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})"},i=["charset","css","debug","extend","font-face","for","import","include","media","mixin","page","warn","while"],r=["after","before","first-letter","first-line","active","first-child","focus","hover","lang","link","visited"],n=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],a="[\\.\\s\\n\\[\\:,]",l=["align-content","align-items","align-self","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","auto","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","clip-path","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","font","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-variant-ligatures","font-weight","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inherit","initial","justify-content","left","letter-spacing","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","mask","max-height","max-width","min-height","min-width","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","perspective","perspective-origin","pointer-events","position","quotes","resize","right","tab-size","table-layout","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-indent","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","white-space","widows","width","word-break","word-spacing","word-wrap","z-index"],d=["\\?","(\\bReturn\\b)","(\\bEnd\\b)","(\\bend\\b)","(\\bdef\\b)",";","#\\s","\\*\\s","===\\s","\\|","%"];return{aliases:["styl"],cI:!1,k:"if else for in",i:"("+d.join("|")+")",c:[e.QSM,e.ASM,e.CLCM,e.CBCM,o,{b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"selector-class",b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"selector-id",b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\b("+n.join("|")+")"+a,rB:!0,c:[{cN:"selector-tag",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"&?:?:\\b("+r.join("|")+")"+a},{b:"@("+i.join("|")+")\\b"},t,e.CSSNM,e.NM,{cN:"function",b:"^[a-zA-Z][a-zA-Z0-9_-]*\\(.*\\)",i:"[\\n]",rB:!0,c:[{cN:"title",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"},{cN:"params",b:/\(/,e:/\)/,c:[o,t,e.ASM,e.CSSNM,e.NM,e.QSM]}]},{cN:"attribute",b:"\\b("+l.reverse().join("|")+")\\b",starts:{e:/;|$/,c:[o,t,e.ASM,e.QSM,e.CSSNM,e.NM,e.CBCM],i:/\./,r:0}}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/swift.js b/lib/highlight_js/assets/lang/swift.js index f4d42bce7c1..cf86f244eaa 100644 --- a/lib/highlight_js/assets/lang/swift.js +++ b/lib/highlight_js/assets/lang/swift.js @@ -1 +1 @@ -hljs.registerLanguage("swift",function(e){var i={keyword:"class deinit enum extension func import init let protocol static struct subscript typealias var break case continue default do else fallthrough if in for return switch where while as dynamicType is new super self Self Type __COLUMN__ __FILE__ __FUNCTION__ __LINE__ associativity didSet get infix inout left mutating none nonmutating operator override postfix precedence prefix right set unowned unowned safe unsafe weak willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue assert bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced join lexicographicalCompare map max maxElement min minElement numericCast partition posix print println quickSort reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith strideof strideofValue swap swift toString transcode underestimateCount unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafePointers withVaList"},t={cN:"type",b:"\\b[A-Z][\\w']*",r:0},n=e.C("/\\*","\\*/",{c:["self"]}),r={cN:"subst",b:/\\\(/,e:"\\)",k:i,c:[]},s={cN:"number",b:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",r:0},o=e.inherit(e.QSM,{c:[r,e.BE]});return r.c=[s],{k:i,c:[o,e.CLCM,n,t,s,{cN:"func",bK:"func",e:"{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/,i:/\(/}),{cN:"generics",b://,i:/>/},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:i,c:["self",s,o,e.CBCM,{b:":"}],i:/["']/}],i:/\[|%/},{cN:"class",bK:"struct protocol class extension enum",k:i,e:"\\{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/})]},{cN:"preprocessor",b:"(@assignment|@class_protocol|@exported|@final|@lazy|@noreturn|@NSCopying|@NSManaged|@objc|@optional|@required|@auto_closure|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix)"}]}}); \ No newline at end of file +hljs.registerLanguage("swift",function(e){var i={keyword:"__COLUMN__ __FILE__ __FUNCTION__ __LINE__ as as! as? associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},t={cN:"type",b:"\\b[A-Z][\\w']*",r:0},n=e.C("/\\*","\\*/",{c:["self"]}),r={cN:"subst",b:/\\\(/,e:"\\)",k:i,c:[]},a={cN:"number",b:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",r:0},o=e.inherit(e.QSM,{c:[r,e.BE]});return r.c=[a],{k:i,c:[o,e.CLCM,n,t,a,{cN:"function",bK:"func",e:"{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/,i:/\(/}),{b://,i:/>/},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:i,c:["self",a,o,e.CBCM,{b:":"}],i:/["']/}],i:/\[|%/},{cN:"class",bK:"struct protocol class extension enum",k:i,e:"\\{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/})]},{cN:"meta",b:"(@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain)"},{bK:"import",e:/$/,c:[e.CLCM,n]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/taggerscript.js b/lib/highlight_js/assets/lang/taggerscript.js new file mode 100644 index 00000000000..e85841b1dcb --- /dev/null +++ b/lib/highlight_js/assets/lang/taggerscript.js @@ -0,0 +1 @@ +hljs.registerLanguage("taggerscript",function(e){var c={cN:"comment",b:/\$noop\(/,e:/\)/,c:[{b:/\(/,e:/\)/,c:["self",{b:/\\./}]}],r:10},r={cN:"keyword",b:/\$(?!noop)[a-zA-Z][_a-zA-Z0-9]*/,e:/\(/,eE:!0},a={cN:"variable",b:/%[_a-zA-Z0-9:]*/,e:"%"},b={cN:"symbol",b:/\\./};return{c:[c,r,a,b]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/tcl.js b/lib/highlight_js/assets/lang/tcl.js index 67eb9974af2..0a74b0789ef 100644 --- a/lib/highlight_js/assets/lang/tcl.js +++ b/lib/highlight_js/assets/lang/tcl.js @@ -1 +1 @@ -hljs.registerLanguage("tcl",function(e){return{aliases:["tk"],k:"after append apply array auto_execok auto_import auto_load auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror binary break catch cd chan clock close concat continue dde dict encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent filename flush for foreach format gets glob global history http if incr info interp join lappend|10 lassign|10 lindex|10 linsert|10 list llength|10 load lrange|10 lrepeat|10 lreplace|10 lreverse|10 lsearch|10 lset|10 lsort|10 mathfunc mathop memory msgcat namespace open package parray pid pkg::create pkg_mkIndex platform platform::shell proc puts pwd read refchan regexp registry regsub|10 rename return safe scan seek set socket source split string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter tcl_wordBreakBefore tcltest tclvars tell time tm trace unknown unload unset update uplevel upvar variable vwait while",c:[e.C(";[ \\t]*#","$"),e.C("^[ \\t]*#","$"),{bK:"proc",e:"[\\{]",eE:!0,c:[{cN:"symbol",b:"[ \\t\\n\\r]+(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"[ \\t\\n\\r]",eW:!0,eE:!0}]},{cN:"variable",eE:!0,v:[{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\(([a-zA-Z0-9_])*\\)",e:"[^a-zA-Z0-9_\\}\\$]"},{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"(\\))?[^a-zA-Z0-9_\\}\\$]"}]},{cN:"string",c:[e.BE],v:[e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},{cN:"number",v:[e.BNM,e.CNM]}]}}); \ No newline at end of file +hljs.registerLanguage("tcl",function(e){return{aliases:["tk"],k:"after append apply array auto_execok auto_import auto_load auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror binary break catch cd chan clock close concat continue dde dict encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent filename flush for foreach format gets glob global history http if incr info interp join lappend|10 lassign|10 lindex|10 linsert|10 list llength|10 load lrange|10 lrepeat|10 lreplace|10 lreverse|10 lsearch|10 lset|10 lsort|10 mathfunc mathop memory msgcat namespace open package parray pid pkg::create pkg_mkIndex platform platform::shell proc puts pwd read refchan regexp registry regsub|10 rename return safe scan seek set socket source split string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter tcl_wordBreakBefore tcltest tclvars tell time tm trace unknown unload unset update uplevel upvar variable vwait while",c:[e.C(";[ \\t]*#","$"),e.C("^[ \\t]*#","$"),{bK:"proc",e:"[\\{]",eE:!0,c:[{cN:"title",b:"[ \\t\\n\\r]+(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"[ \\t\\n\\r]",eW:!0,eE:!0}]},{eE:!0,v:[{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\(([a-zA-Z0-9_])*\\)",e:"[^a-zA-Z0-9_\\}\\$]"},{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"(\\))?[^a-zA-Z0-9_\\}\\$]"}]},{cN:"string",c:[e.BE],v:[e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},{cN:"number",v:[e.BNM,e.CNM]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/tex.js b/lib/highlight_js/assets/lang/tex.js index cec61e254f0..eb7cc4cd208 100644 --- a/lib/highlight_js/assets/lang/tex.js +++ b/lib/highlight_js/assets/lang/tex.js @@ -1 +1 @@ -hljs.registerLanguage("tex",function(c){var e={cN:"command",b:"\\\\[a-zA-Zа-яА-я]+[\\*]?"},m={cN:"command",b:"\\\\[^a-zA-Zа-яА-я0-9]"},r={cN:"special",b:"[{}\\[\\]\\&#~]",r:0};return{c:[{b:"\\\\[a-zA-Zа-яА-я]+[\\*]? *= *-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",rB:!0,c:[e,m,{cN:"number",b:" *=",e:"-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?",eB:!0}],r:10},e,m,r,{cN:"formula",b:"\\$\\$",e:"\\$\\$",c:[e,m,r],r:0},{cN:"formula",b:"\\$",e:"\\$",c:[e,m,r],r:0},c.C("%","$",{r:0})]}}); \ No newline at end of file +hljs.registerLanguage("tex",function(c){var e={cN:"tag",b:/\\/,r:0,c:[{cN:"name",v:[{b:/[a-zA-Zа-яА-я]+[*]?/},{b:/[^a-zA-Zа-яА-я0-9]/}],starts:{eW:!0,r:0,c:[{cN:"string",v:[{b:/\[/,e:/\]/},{b:/\{/,e:/\}/}]},{b:/\s*=\s*/,eW:!0,r:0,c:[{cN:"number",b:/-?\d*\.?\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?/}]}]}}]};return{c:[e,{cN:"formula",c:[e],r:0,v:[{b:/\$\$/,e:/\$\$/},{b:/\$/,e:/\$/}]},c.C("%","$",{r:0})]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/tp.js b/lib/highlight_js/assets/lang/tp.js new file mode 100644 index 00000000000..8fbab025c17 --- /dev/null +++ b/lib/highlight_js/assets/lang/tp.js @@ -0,0 +1 @@ +hljs.registerLanguage("tp",function(O){var R={cN:"number",b:"[1-9][0-9]*",r:0},E={cN:"symbol",b:":[^\\]]+"},T={cN:"built_in",b:"(AR|P|PAYLOAD|PR|R|SR|RSR|LBL|VR|UALM|MESSAGE|UTOOL|UFRAME|TIMER| TIMER_OVERFLOW|JOINT_MAX_SPEED|RESUME_PROG|DIAG_REC)\\[",e:"\\]",c:["self",R,E]},N={cN:"built_in",b:"(AI|AO|DI|DO|F|RI|RO|UI|UO|GI|GO|SI|SO)\\[",e:"\\]",c:["self",R,O.QSM,E]};return{k:{keyword:"ABORT ACC ADJUST AND AP_LD BREAK CALL CNT COL CONDITION CONFIG DA DB DIV DETECT ELSE END ENDFOR ERR_NUM ERROR_PROG FINE FOR GP GUARD INC IF JMP LINEAR_MAX_SPEED LOCK MOD MONITOR OFFSET Offset OR OVERRIDE PAUSE PREG PTH RT_LD RUN SELECT SKIP Skip TA TB TO TOOL_OFFSET Tool_Offset UF UT UFRAME_NUM UTOOL_NUM UNLOCK WAIT X Y Z W P R STRLEN SUBSTR FINDSTR VOFFSET PROG ATTR MN POS",literal:"ON OFF max_speed LPOS JPOS ENABLE DISABLE START STOP RESET"},c:[T,N,{cN:"keyword",b:"/(PROG|ATTR|MN|POS|END)\\b"},{cN:"keyword",b:"(CALL|RUN|POINT_LOGIC|LBL)\\b"},{cN:"keyword",b:"\\b(ACC|CNT|Skip|Offset|PSPD|RT_LD|AP_LD|Tool_Offset)"},{cN:"number",b:"\\d+(sec|msec|mm/sec|cm/min|inch/min|deg/sec|mm|in|cm)?\\b",r:0},O.C("//","[;$]"),O.C("!","[;$]"),O.C("--eg:","$"),O.QSM,{cN:"string",b:"'",e:"'"},O.CNM,{cN:"variable",b:"\\$[A-Za-z0-9_]+"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/twig.js b/lib/highlight_js/assets/lang/twig.js index b3c4456bd5d..7b117ba2395 100644 --- a/lib/highlight_js/assets/lang/twig.js +++ b/lib/highlight_js/assets/lang/twig.js @@ -1 +1 @@ -hljs.registerLanguage("twig",function(e){var t={cN:"params",b:"\\(",e:"\\)"},a="attribute block constant cycle date dump include max min parent random range source template_from_string",r={cN:"function",bK:a,r:0,c:[t]},c={cN:"filter",b:/\|[A-Za-z_]+:?/,k:"abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse round slice sort split striptags title trim upper url_encode",c:[r]},n="autoescape block do embed extends filter flush for if import include macro sandbox set spaceless use verbatim";return n=n+" "+n.split(" ").map(function(e){return"end"+e}).join(" "),{aliases:["craftcms"],cI:!0,sL:"xml",subLanguageMode:"continuous",c:[e.C(/\{#/,/#}/),{cN:"template_tag",b:/\{%/,e:/%}/,k:n,c:[c,r]},{cN:"variable",b:/\{\{/,e:/}}/,c:[c,r]}]}}); \ No newline at end of file +hljs.registerLanguage("twig",function(e){var t={cN:"params",b:"\\(",e:"\\)"},a="attribute block constant cycle date dump include max min parent random range source template_from_string",r={bK:a,k:{name:a},r:0,c:[t]},c={b:/\|[A-Za-z_]+:?/,k:"abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse round slice sort split striptags title trim upper url_encode",c:[r]},s="autoescape block do embed extends filter flush for if import include macro sandbox set spaceless use verbatim";return s=s+" "+s.split(" ").map(function(e){return"end"+e}).join(" "),{aliases:["craftcms"],cI:!0,sL:"xml",c:[e.C(/\{#/,/#}/),{cN:"template-tag",b:/\{%/,e:/%}/,c:[{cN:"name",b:/\w+/,k:s,starts:{eW:!0,c:[c,r],r:0}}]},{cN:"template-variable",b:/\{\{/,e:/}}/,c:["self",c,r]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/typescript.js b/lib/highlight_js/assets/lang/typescript.js index 2c0658e9ad5..5239016ae26 100644 --- a/lib/highlight_js/assets/lang/typescript.js +++ b/lib/highlight_js/assets/lang/typescript.js @@ -1 +1 @@ -hljs.registerLanguage("typescript",function(e){return{aliases:["ts"],k:{keyword:"in if for while finally var new function|0 do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private get set super interface extendsstatic constructor implements enum export import declare type protected",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void"},c:[{cN:"pi",b:/^\s*('|")use strict('|")/,r:0},e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/\[|%/,r:0},{cN:"constructor",bK:"constructor",e:/\{/,eE:!0,r:10},{cN:"module",bK:"module",e:/\{/,eE:!0},{cN:"interface",bK:"interface",e:/\{/,eE:!0},{b:/\$[(.]/},{b:"\\."+e.IR,r:0}]}}); \ No newline at end of file +hljs.registerLanguage("typescript",function(e){var r={keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void"};return{aliases:["ts"],k:r,c:[{cN:"meta",b:/^\s*['"]use strict['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM],r:0},{cN:"function",b:"function",e:/[\{;]/,eE:!0,k:r,c:["self",e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/\[|%/,r:0},{bK:"constructor",e:/\{/,eE:!0},{bK:"module",e:/\{/,eE:!0},{bK:"interface",e:/\{/,eE:!0,k:"interface extends"},{b:/\$[(.]/},{b:"\\."+e.IR,r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/vala.js b/lib/highlight_js/assets/lang/vala.js index 35e405f84fa..157da9d57b4 100644 --- a/lib/highlight_js/assets/lang/vala.js +++ b/lib/highlight_js/assets/lang/vala.js @@ -1 +1 @@ -hljs.registerLanguage("vala",function(e){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object",literal:"false true null"},c:[{cN:"class",bK:"class interface delegate namespace",e:"{",eE:!0,i:"[^,:\\n\\s\\.]",c:[e.UTM]},e.CLCM,e.CBCM,{cN:"string",b:'"""',e:'"""',r:5},e.ASM,e.QSM,e.CNM,{cN:"preprocessor",b:"^#",e:"$",r:2},{cN:"constant",b:" [A-Z_]+ ",r:0}]}}); \ No newline at end of file +hljs.registerLanguage("vala",function(t){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override virtual delegate if while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object Gtk",literal:"false true null"},c:[{cN:"class",bK:"class interface namespace",e:"{",eE:!0,i:"[^,:\\n\\s\\.]",c:[t.UTM]},t.CLCM,t.CBCM,{cN:"string",b:'"""',e:'"""',r:5},t.ASM,t.QSM,t.CNM,{cN:"meta",b:"^#",e:"$",r:2}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/vbnet.js b/lib/highlight_js/assets/lang/vbnet.js index 7d7444dc7d9..d32cd0fcc82 100644 --- a/lib/highlight_js/assets/lang/vbnet.js +++ b/lib/highlight_js/assets/lang/vbnet.js @@ -1 +1 @@ -hljs.registerLanguage("vbnet",function(e){return{aliases:["vb"],cI:!0,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"//|{|}|endif|gosub|variant|wend",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),e.C("'","$",{rB:!0,c:[{cN:"xmlDocTag",b:"'''|",c:[e.PWM]},{cN:"xmlDocTag",b:"",c:[e.PWM]}]}),e.CNM,{cN:"preprocessor",b:"#",e:"$",k:"if else elseif end region externalsource"}]}}); \ No newline at end of file +hljs.registerLanguage("vbnet",function(e){return{aliases:["vb"],cI:!0,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"//|{|}|endif|gosub|variant|wend",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),e.C("'","$",{rB:!0,c:[{cN:"doctag",b:"'''|",c:[e.PWM]},{cN:"doctag",b:"",c:[e.PWM]}]}),e.CNM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elseif end region externalsource"}}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/vbscript-html.js b/lib/highlight_js/assets/lang/vbscript-html.js index e90c004c8d9..eb52b324e61 100644 --- a/lib/highlight_js/assets/lang/vbscript-html.js +++ b/lib/highlight_js/assets/lang/vbscript-html.js @@ -1 +1 @@ -hljs.registerLanguage("vbscript-html",function(s){return{sL:"xml",subLanguageMode:"continuous",c:[{b:"<%",e:"%>",sL:"vbscript"}]}}); \ No newline at end of file +hljs.registerLanguage("vbscript-html",function(r){return{sL:"xml",c:[{b:"<%",e:"%>",sL:"vbscript"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/verilog.js b/lib/highlight_js/assets/lang/verilog.js index 1da1fd36b26..b0842fa0469 100644 --- a/lib/highlight_js/assets/lang/verilog.js +++ b/lib/highlight_js/assets/lang/verilog.js @@ -1 +1 @@ -hljs.registerLanguage("verilog",function(e){return{aliases:["v"],cI:!0,k:{keyword:"always and assign begin buf bufif0 bufif1 case casex casez cmos deassign default defparam disable edge else end endcase endfunction endmodule endprimitive endspecify endtable endtask event for force forever fork function if ifnone initial inout input join macromodule module nand negedge nmos nor not notif0 notif1 or output parameter pmos posedge primitive pulldown pullup rcmos release repeat rnmos rpmos rtran rtranif0 rtranif1 specify specparam table task timescale tran tranif0 tranif1 wait while xnor xor",typename:"highz0 highz1 integer large medium pull0 pull1 real realtime reg scalared signed small strong0 strong1 supply0 supply0 supply1 supply1 time tri tri0 tri1 triand trior trireg vectored wand weak0 weak1 wire wor"},c:[e.CBCM,e.CLCM,e.QSM,{cN:"number",b:"\\b(\\d+'(b|h|o|d|B|H|O|D))?[0-9xzXZ]+",c:[e.BE],r:0},{cN:"typename",b:"\\.\\w+",r:0},{cN:"value",b:"#\\((?!parameter).+\\)"},{cN:"keyword",b:"\\+|-|\\*|/|%|<|>|=|#|`|\\!|&|\\||@|:|\\^|~|\\{|\\}",r:0}]}}); \ No newline at end of file +hljs.registerLanguage("verilog",function(e){return{aliases:["v"],cI:!1,k:{keyword:"always and assign begin buf bufif0 bufif1 case casex casez cmos deassign default defparam disable edge else end endcase endfunction endmodule endprimitive endspecify endtable endtask event for force forever fork function if ifnone initial inout input join macromodule module nand negedge nmos nor not notif0 notif1 or output parameter pmos posedge primitive pulldown pullup rcmos release repeat rnmos rpmos rtran rtranif0 rtranif1 specify specparam table task timescale tran tranif0 tranif1 wait while xnor xor highz0 highz1 integer large medium pull0 pull1 real realtime reg scalared signed small strong0 strong1 supply0 supply0 supply1 supply1 time tri tri0 tri1 triand trior trireg vectored wand weak0 weak1 wire wor"},c:[e.CBCM,e.CLCM,e.QSM,{cN:"number",b:"(\\b((\\d'(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+))|(\\B(('(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+))|(\\b([0-9xzXZ_])+)",c:[e.BE],r:0},{cN:"variable",b:"#\\((?!parameter).+\\)"}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/vhdl.js b/lib/highlight_js/assets/lang/vhdl.js index d6cae6290b1..4708c0f29c5 100644 --- a/lib/highlight_js/assets/lang/vhdl.js +++ b/lib/highlight_js/assets/lang/vhdl.js @@ -1 +1 @@ -hljs.registerLanguage("vhdl",function(e){var t="\\d(_|\\d)*",r="[eE][-+]?"+t,n=t+"(\\."+t+")?("+r+")?",o="\\w+",i=t+"#"+o+"(\\."+o+")?#("+r+")?",a="\\b("+i+"|"+n+")";return{cI:!0,k:{keyword:"abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",typename:"boolean bit character severity_level integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_ulogic std_ulogic_vector std_logic std_logic_vector unsigned signed boolean_vector integer_vector real_vector time_vector"},i:"{",c:[e.CBCM,e.C("--","$"),e.QSM,{cN:"number",b:a,r:0},{cN:"literal",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[e.BE]},{cN:"attribute",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[e.BE]}]}}); \ No newline at end of file +hljs.registerLanguage("vhdl",function(e){var r="\\d(_|\\d)*",t="[eE][-+]?"+r,o=r+"(\\."+r+")?("+t+")?",n="\\w+",i=r+"#"+n+"(\\."+n+")?#("+t+")?",a="\\b("+i+"|"+o+")";return{cI:!0,k:{keyword:"abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",built_in:"boolean bit character severity_level integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_ulogic std_ulogic_vector std_logic std_logic_vector unsigned signed boolean_vector integer_vector real_vector time_vector"},i:"{",c:[e.CBCM,e.C("--","$"),e.QSM,{cN:"number",b:a,r:0},{cN:"literal",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[e.BE]},{cN:"symbol",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[e.BE]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/vim.js b/lib/highlight_js/assets/lang/vim.js index 64b321060bd..4e8e6021ba8 100644 --- a/lib/highlight_js/assets/lang/vim.js +++ b/lib/highlight_js/assets/lang/vim.js @@ -1 +1 @@ -hljs.registerLanguage("vim",function(e){return{l:/[!#@\w]+/,k:{keyword:"N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope cp cpf cq cr cs cst cu cuna cunme cw d|0 delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu g|0 go gr grepa gu gv ha h|0 helpf helpg helpt hi hid his i|0 ia iabc if ij il im imapc ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs n|0 new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf q|0 quita qa r|0 rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv s|0 sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync t|0 tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up v|0 ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank",built_in:"abs acos add and append argc argidx argv asin atan atan2 browse browsedir bufexists buflisted bufloaded bufname bufnr bufwinnr byte2line byteidx call ceil changenr char2nr cindent clearmatches col complete complete_add complete_check confirm copy cos cosh count cscope_connection cursor deepcopy delete did_filetype diff_filler diff_hlID empty escape eval eventhandler executable exists exp expand extend feedkeys filereadable filewritable filter finddir findfile float2nr floor fmod fnameescape fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreground function garbagecollect get getbufline getbufvar getchar getcharmod getcmdline getcmdpos getcmdtype getcwd getfontname getfperm getfsize getftime getftype getline getloclist getmatches getpid getpos getqflist getreg getregtype gettabvar gettabwinvar getwinposx getwinposy getwinvar glob globpath has has_key haslocaldir hasmapto histadd histdel histget histnr hlexists hlID hostname iconv indent index input inputdialog inputlist inputrestore inputsave inputsecret insert invert isdirectory islocked items join keys len libcall libcallnr line line2byte lispindent localtime log log10 luaeval map maparg mapcheck match matchadd matcharg matchdelete matchend matchlist matchstr max min mkdir mode mzeval nextnonblank nr2char or pathshorten pow prevnonblank printf pumvisible py3eval pyeval range readfile reltime reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remove rename repeat resolve reverse round screenattr screenchar screencol screenrow search searchdecl searchpair searchpairpos searchpos server2client serverlist setbufvar setcmdpos setline setloclist setmatches setpos setqflist setreg settabvar settabwinvar setwinvar sha256 shellescape shiftwidth simplify sin sinh sort soundfold spellbadword spellsuggest split sqrt str2float str2nr strchars strdisplaywidth strftime stridx string strlen strpart strridx strtrans strwidth submatch substitute synconcealed synID synIDattr synIDtrans synstack system tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname tolower toupper tr trunc type undofile undotree values virtcol visualmode wildmenumode winbufnr wincol winheight winline winnr winrestcmd winrestview winsaveview winwidth writefile xor"},i:/[{:]/,c:[e.NM,e.ASM,{cN:"string",b:/"((\\")|[^"\n])*("|\n)/},{cN:"variable",b:/[bwtglsav]:[\w\d_]*/},{cN:"function",bK:"function function!",e:"$",r:0,c:[e.TM,{cN:"params",b:"\\(",e:"\\)"}]}]}}); \ No newline at end of file +hljs.registerLanguage("vim",function(e){return{l:/[!#@\w]+/,k:{keyword:"N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope cp cpf cq cr cs cst cu cuna cunme cw delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu go gr grepa gu gv ha helpf helpg helpt hi hid his ia iabc if ij il im imapc ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf quita qa rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank",built_in:"synIDtrans atan2 range matcharg did_filetype asin feedkeys xor argv complete_check add getwinposx getqflist getwinposy screencol clearmatches empty extend getcmdpos mzeval garbagecollect setreg ceil sqrt diff_hlID inputsecret get getfperm getpid filewritable shiftwidth max sinh isdirectory synID system inputrestore winline atan visualmode inputlist tabpagewinnr round getregtype mapcheck hasmapto histdel argidx findfile sha256 exists toupper getcmdline taglist string getmatches bufnr strftime winwidth bufexists strtrans tabpagebuflist setcmdpos remote_read printf setloclist getpos getline bufwinnr float2nr len getcmdtype diff_filler luaeval resolve libcallnr foldclosedend reverse filter has_key bufname str2float strlen setline getcharmod setbufvar index searchpos shellescape undofile foldclosed setqflist buflisted strchars str2nr virtcol floor remove undotree remote_expr winheight gettabwinvar reltime cursor tabpagenr finddir localtime acos getloclist search tanh matchend rename gettabvar strdisplaywidth type abs py3eval setwinvar tolower wildmenumode log10 spellsuggest bufloaded synconcealed nextnonblank server2client complete settabwinvar executable input wincol setmatches getftype hlID inputsave searchpair or screenrow line settabvar histadd deepcopy strpart remote_peek and eval getftime submatch screenchar winsaveview matchadd mkdir screenattr getfontname libcall reltimestr getfsize winnr invert pow getbufline byte2line soundfold repeat fnameescape tagfiles sin strwidth spellbadword trunc maparg log lispindent hostname setpos globpath remote_foreground getchar synIDattr fnamemodify cscope_connection stridx winbufnr indent min complete_add nr2char searchpairpos inputdialog values matchlist items hlexists strridx browsedir expand fmod pathshorten line2byte argc count getwinvar glob foldtextresult getreg foreground cosh matchdelete has char2nr simplify histget searchdecl iconv winrestcmd pumvisible writefile foldlevel haslocaldir keys cos matchstr foldtext histnr tan tempname getcwd byteidx getbufvar islocked escape eventhandler remote_send serverlist winrestview synstack pyeval prevnonblank readfile cindent filereadable changenr exp"},i:/[{:]/,c:[e.NM,e.ASM,{cN:"string",b:/"(\\"|\n\\|[^"\n])*"/},e.C('"',"$"),{cN:"variable",b:/[bwtglsav]:[\w\d_]*/},{cN:"function",bK:"function function!",e:"$",r:0,c:[e.TM,{cN:"params",b:"\\(",e:"\\)"}]},{cN:"symbol",b:/<[\w-]+>/}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/x86asm.js b/lib/highlight_js/assets/lang/x86asm.js index 294e6cae31a..acd647a953f 100644 --- a/lib/highlight_js/assets/lang/x86asm.js +++ b/lib/highlight_js/assets/lang/x86asm.js @@ -1 +1 @@ -hljs.registerLanguage("x86asm",function(s){return{cI:!0,l:"\\.?"+s.IR,k:{keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",literal:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l",pseudo:"db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times",preprocessor:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public ",built_in:"bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},c:[s.C(";","$",{r:0}),{cN:"number",b:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",r:0},{cN:"number",b:"\\$[0-9][0-9A-Fa-f]*",r:0},{cN:"number",b:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[HhXx]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{cN:"number",b:"\\b(?:0[HhXx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"},s.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"string",b:"`",e:"[^\\\\]`",r:0},{cN:"string",b:"\\.[A-Za-z0-9]+",r:0},{cN:"label",b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",r:0},{cN:"label",b:"^\\s*%%[A-Za-z0-9_$#@~.?]*:",r:0},{cN:"argument",b:"%[0-9]+",r:0},{cN:"built_in",b:"%!S+",r:0}]}}); \ No newline at end of file +hljs.registerLanguage("x86asm",function(s){return{cI:!0,l:"[.%]?"+s.IR,k:{keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",built_in:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr",meta:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},c:[s.C(";","$",{r:0}),{cN:"number",v:[{b:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",r:0},{b:"\\$[0-9][0-9A-Fa-f]*",r:0},{b:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{b:"\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"}]},s.QSM,{cN:"string",v:[{b:"'",e:"[^\\\\]'"},{b:"`",e:"[^\\\\]`"},{b:"\\.[A-Za-z0-9]+"}],r:0},{cN:"symbol",v:[{b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)"},{b:"^\\s*%%[A-Za-z0-9_$#@~.?]*:"}],r:0},{cN:"subst",b:"%[0-9]+",r:0},{cN:"subst",b:"%!S+",r:0}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/xl.js b/lib/highlight_js/assets/lang/xl.js index daaea52acf9..d08b3853a91 100644 --- a/lib/highlight_js/assets/lang/xl.js +++ b/lib/highlight_js/assets/lang/xl.js @@ -1 +1 @@ -hljs.registerLanguage("xl",function(e){var t="ObjectLoader Animate MovieCredits Slides Filters Shading Materials LensFlare Mapping VLCAudioVideo StereoDecoder PointCloud NetworkAccess RemoteControl RegExp ChromaKey Snowfall NodeJS Speech Charts",o={keyword:"if then else do while until for loop import with is as where when by data constant",literal:"true false nil",type:"integer real text name boolean symbol infix prefix postfix block tree",built_in:"in mod rem and or xor not abs sign floor ceil sqrt sin cos tan asin acos atan exp expm1 log log2 log10 log1p pi at",module:t,id:"text_length text_range text_find text_replace contains page slide basic_slide title_slide title subtitle fade_in fade_out fade_at clear_color color line_color line_width texture_wrap texture_transform texture scale_?x scale_?y scale_?z? translate_?x translate_?y translate_?z? rotate_?x rotate_?y rotate_?z? rectangle circle ellipse sphere path line_to move_to quad_to curve_to theme background contents locally time mouse_?x mouse_?y mouse_buttons"},a={cN:"constant",b:"[A-Z][A-Z_0-9]+",r:0},r={cN:"variable",b:"([A-Z][a-z_0-9]+)+",r:0},i={cN:"id",b:"[a-z][a-z_0-9]+",r:0},l={cN:"string",b:'"',e:'"',i:"\\n"},n={cN:"string",b:"'",e:"'",i:"\\n"},s={cN:"string",b:"<<",e:">>"},c={cN:"number",b:"[0-9]+#[0-9A-Z_]+(\\.[0-9-A-Z_]+)?#?([Ee][+-]?[0-9]+)?",r:10},_={cN:"import",bK:"import",e:"$",k:{keyword:"import",module:t},r:0,c:[l]},d={cN:"function",b:"[a-z].*->"};return{aliases:["tao"],l:/[a-zA-Z][a-zA-Z0-9_?]*/,k:o,c:[e.CLCM,e.CBCM,l,n,s,d,_,a,r,i,c,e.NM]}}); \ No newline at end of file +hljs.registerLanguage("xl",function(e){var t="ObjectLoader Animate MovieCredits Slides Filters Shading Materials LensFlare Mapping VLCAudioVideo StereoDecoder PointCloud NetworkAccess RemoteControl RegExp ChromaKey Snowfall NodeJS Speech Charts",o={keyword:"if then else do while until for loop import with is as where when by data constant integer real text name boolean symbol infix prefix postfix block tree",literal:"true false nil",built_in:"in mod rem and or xor not abs sign floor ceil sqrt sin cos tan asin acos atan exp expm1 log log2 log10 log1p pi at text_length text_range text_find text_replace contains page slide basic_slide title_slide title subtitle fade_in fade_out fade_at clear_color color line_color line_width texture_wrap texture_transform texture scale_?x scale_?y scale_?z? translate_?x translate_?y translate_?z? rotate_?x rotate_?y rotate_?z? rectangle circle ellipse sphere path line_to move_to quad_to curve_to theme background contents locally time mouse_?x mouse_?y mouse_buttons "+t},a={cN:"string",b:'"',e:'"',i:"\\n"},r={cN:"string",b:"'",e:"'",i:"\\n"},i={cN:"string",b:"<<",e:">>"},l={cN:"number",b:"[0-9]+#[0-9A-Z_]+(\\.[0-9-A-Z_]+)?#?([Ee][+-]?[0-9]+)?"},n={bK:"import",e:"$",k:o,c:[a]},s={cN:"function",b:/[a-z][^\n]*->/,rB:!0,e:/->/,c:[e.inherit(e.TM,{starts:{eW:!0,k:o}})]};return{aliases:["tao"],l:/[a-zA-Z][a-zA-Z0-9_?]*/,k:o,c:[e.CLCM,e.CBCM,a,r,i,s,n,l,e.NM]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/xml.js b/lib/highlight_js/assets/lang/xml.js index 403807f8c51..7b9bea07ef7 100644 --- a/lib/highlight_js/assets/lang/xml.js +++ b/lib/highlight_js/assets/lang/xml.js @@ -1 +1 @@ -hljs.registerLanguage("xml",function(t){var e="[A-Za-z0-9\\._:-]+",s={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"},c={eW:!0,i:/]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},t.C("",{r:10}),{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{title:"style"},c:[c],starts:{e:"",rE:!0,sL:"css"}},{cN:"tag",b:"|$)",e:">",k:{title:"script"},c:[c],starts:{e:"",rE:!0,sL:""}},s,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},c]}]}}); \ No newline at end of file +hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/xquery.js b/lib/highlight_js/assets/lang/xquery.js new file mode 100644 index 00000000000..a91a30a153e --- /dev/null +++ b/lib/highlight_js/assets/lang/xquery.js @@ -0,0 +1 @@ +hljs.registerLanguage("xquery",function(e){var t="for let if while then else return where group by xquery encoding versionmodule namespace boundary-space preserve strip default collation base-uri orderingcopy-namespaces order declare import schema namespace function option in allowing emptyat tumbling window sliding window start when only end when previous next stable ascendingdescending empty greatest least some every satisfies switch case typeswitch try catch andor to union intersect instance of treat as castable cast map array delete insert intoreplace value rename copy modify update",a="false true xs:string xs:integer element item xs:date xs:datetime xs:float xs:double xs:decimal QName xs:anyURI xs:long xs:int xs:short xs:byte attribute",s={b:/\$[a-zA-Z0-9\-]+/},n={cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},r={cN:"string",v:[{b:/"/,e:/"/,c:[{b:/""/,r:0}]},{b:/'/,e:/'/,c:[{b:/''/,r:0}]}]},i={cN:"meta",b:"%\\w+"},c={cN:"comment",b:"\\(:",e:":\\)",r:10,c:[{cN:"doctag",b:"@\\w+"}]},o={b:"{",e:"}"},l=[s,r,n,c,i,o];return o.c=l,{aliases:["xpath","xq"],cI:!1,l:/[a-zA-Z\$][a-zA-Z0-9_:\-]*/,i:/(proc)|(abstract)|(extends)|(until)|(#)/,k:{keyword:t,literal:a},c:l}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/yaml.js b/lib/highlight_js/assets/lang/yaml.js new file mode 100644 index 00000000000..3e938a79bd9 --- /dev/null +++ b/lib/highlight_js/assets/lang/yaml.js @@ -0,0 +1 @@ +hljs.registerLanguage("yaml",function(e){var a={literal:"{ } true false yes no Yes No True False null"},b="^[ \\-]*",r="[a-zA-Z_][\\w\\-]*",t={cN:"attr",v:[{b:b+r+":"},{b:b+'"'+r+'":'},{b:b+"'"+r+"':"}]},c={cN:"template-variable",v:[{b:"{{",e:"}}"},{b:"%{",e:"}"}]},l={cN:"string",r:0,v:[{b:/'/,e:/'/},{b:/"/,e:/"/}],c:[e.BE,c]};return{cI:!0,aliases:["yml","YAML","yaml"],c:[t,{cN:"meta",b:"^---s*$",r:10},{cN:"string",b:"[\\|>] *$",rE:!0,c:l.c,e:t.v[0].b},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0,r:0},{cN:"type",b:"!!"+e.UIR},{cN:"meta",b:"&"+e.UIR+"$"},{cN:"meta",b:"\\*"+e.UIR+"$"},{cN:"bullet",b:"^ *-",r:0},l,e.HCM,e.CNM],k:a}}); \ No newline at end of file diff --git a/lib/highlight_js/assets/lang/zephir.js b/lib/highlight_js/assets/lang/zephir.js new file mode 100644 index 00000000000..65815434126 --- /dev/null +++ b/lib/highlight_js/assets/lang/zephir.js @@ -0,0 +1 @@ +hljs.registerLanguage("zephir",function(e){var i={cN:"string",c:[e.BE],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},n={v:[e.BNM,e.CNM]};return{aliases:["zep"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var let while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally int uint long ulong char uchar double float bool boolean stringlikely unlikely",c:[e.CLCM,e.HCM,e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[e.BE]},{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",e.CBCM,i,n]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},i,n]}}); \ No newline at end of file diff --git a/lib/html_prettify.rb b/lib/html_prettify.rb new file mode 100644 index 00000000000..6d0b3d065bf --- /dev/null +++ b/lib/html_prettify.rb @@ -0,0 +1,407 @@ +# heavily based off +# https://github.com/vmg/redcarpet/blob/master/ext/redcarpet/html_smartypants.c +# and +# https://github.com/jmcnevin/rubypants/blob/master/lib/rubypants/core.rb +# 99% of the code here is by Jeremy McNevin +# +# This Source File is available under BSD/MIT license as well as standard GPL +# + +class HtmlPrettify < String + def self.render(html) + new(html).to_html + end + + # Create a new RubyPants instance with the text in +string+. + # + # Allowed elements in the options array: + # + # 0 :: do nothing + # 1 :: enable all, using only em-dash shortcuts + # 2 :: enable all, using old school en- and em-dash shortcuts (*default*) + # 3 :: enable all, using inverted old school en and em-dash shortcuts + # -1 :: stupefy (translate HTML entities to their ASCII-counterparts) + # + # If you don't like any of these defaults, you can pass symbols to change + # RubyPants' behavior: + # + # :quotes :: quotes + # :backticks :: backtick quotes (``double'' only) + # :allbackticks :: backtick quotes (``double'' and `single') + # :dashes :: dashes + # :oldschool :: old school dashes + # :inverted :: inverted old school dashes + # :ellipses :: ellipses + # :convertquotes :: convert " entities to + # " + # :stupefy :: translate RubyPants HTML entities + # to their ASCII counterparts. + # + # In addition, you can customize the HTML entities that will be injected by + # passing in a hash for the final argument. The defaults for these entities + # are as follows: + # + # :single_left_quote :: + # :double_left_quote :: + # :single_right_quote :: + # :double_right_quote :: + # :em_dash :: + # :en_dash :: + # :ellipsis :: + # :html_quote :: " + # + def initialize(string, options=[2], entities = {}) + super string + + @options = [*options] + @entities = default_entities.update(entities) + end + + # Apply SmartyPants transformations. + def to_html + do_quotes = do_backticks = do_dashes = do_ellipses = nil + + if @options.include?(0) + # Do nothing. + return self + elsif @options.include?(1) + # Do everything, turn all options on. + do_quotes = do_backticks = do_ellipses = true + do_dashes = :normal + elsif @options.include?(2) + # Do everything, turn all options on, use old school dash shorthand. + do_quotes = do_backticks = do_ellipses = true + do_dashes = :oldschool + elsif @options.include?(3) + # Do everything, turn all options on, use inverted old school + # dash shorthand. + do_quotes = do_backticks = do_ellipses = true + do_dashes = :inverted + elsif @options.include?(-1) + do_stupefy = true + else + do_quotes = @options.include?(:quotes) + do_backticks = @options.include?(:backticks) + do_backticks = :both if @options.include?(:allbackticks) + do_dashes = :normal if @options.include?(:dashes) + do_dashes = :oldschool if @options.include?(:oldschool) + do_dashes = :inverted if @options.include?(:inverted) + do_ellipses = @options.include?(:ellipses) + do_stupefy = @options.include?(:stupefy) + end + + # Parse the HTML + tokens = tokenize + + # Keep track of when we're inside
     or  tags.
    +    in_pre = false
    +
    +    # Here is the result stored in.
    +    result = ""
    +
    +    # This is a cheat, used to get some context for one-character
    +    # tokens that consist of just a quote char. What we do is remember
    +    # the last character of the previous text token, to use as context
    +    # to curl single- character quote tokens correctly.
    +    prev_token_last_char = nil
    +
    +    tokens.each do |token|
    +      if token.first == :tag
    +        result << token[1]
    +        if token[1] =~ %r!<(/?)(?:pre|code|kbd|script|math)[\s>]!
    +          in_pre = ($1 != "/")  # Opening or closing tag?
    +        end
    +      else
    +        t = token[1]
    +
    +        # Remember last char of this token before processing.
    +        last_char = t[-1].chr
    +
    +        unless in_pre
    +
    +          t.gsub!("'", "'")
    +
    +          t = process_escapes t
    +
    +          t.gsub!(""", '"')
    +
    +          if do_dashes
    +            t = educate_dashes t            if do_dashes == :normal
    +            t = educate_dashes_oldschool t  if do_dashes == :oldschool
    +            t = educate_dashes_inverted t   if do_dashes == :inverted
    +          end
    +
    +          t = educate_ellipses t  if do_ellipses
    +
    +          t = educate_fractions t
    +
    +          # Note: backticks need to be processed before quotes.
    +          if do_backticks
    +            t = educate_backticks t
    +            t = educate_single_backticks t  if do_backticks == :both
    +          end
    +
    +          if do_quotes
    +            if t == "'"
    +              # Special case: single-character ' token
    +              if prev_token_last_char =~ /\S/
    +                t = entity(:single_right_quote)
    +              else
    +                t = entity(:single_left_quote)
    +              end
    +            elsif t == '"'
    +              # Special case: single-character " token
    +              if prev_token_last_char =~ /\S/
    +                t = entity(:double_right_quote)
    +              else
    +                t = entity(:double_left_quote)
    +              end
    +            else
    +              # Normal case:
    +              t = educate_quotes t
    +            end
    +          end
    +
    +          t = stupefy_entities t  if do_stupefy
    +        end
    +
    +        prev_token_last_char = last_char
    +        result << t
    +      end
    +    end
    +
    +    # Done
    +    result
    +  end
    +
    +  protected
    +
    +  # Return the string, with after processing the following backslash
    +  # escape sequences. This is useful if you want to force a "dumb" quote
    +  # or other character to appear.
    +  #
    +  # Escaped are:
    +  #      \\    \"    \'    \.    \-    \`
    +  #
    +  def process_escapes(str)
    +    str = str.gsub('\\\\', '\')
    +    str.gsub!('\"',   '"')
    +    str.gsub!("\\\'", ''')
    +    str.gsub!('\.',   '.')
    +    str.gsub!('\-',   '-')
    +    str.gsub!('\`',   '`')
    +    str
    +  end
    +
    +  # The string, with each instance of "--" translated to an
    +  # em-dash HTML entity.
    +  #
    +  def educate_dashes(str)
    +    str.
    +      gsub(/--/, entity(:em_dash))
    +  end
    +
    +  # The string, with each instance of "--" translated to an
    +  # en-dash HTML entity, and each "---" translated to an
    +  # em-dash HTML entity.
    +  #
    +  def educate_dashes_oldschool(str)
    +    str.
    +      gsub(/---/, entity(:em_dash)).
    +      gsub(/--/,  entity(:en_dash))
    +  end
    +
    +  # Return the string, with each instance of "--" translated
    +  # to an em-dash HTML entity, and each "---" translated to
    +  # an en-dash HTML entity. Two reasons why: First, unlike the en- and
    +  # em-dash syntax supported by +educate_dashes_oldschool+, it's
    +  # compatible with existing entries written before SmartyPants 1.1,
    +  # back when "--" was only used for em-dashes.  Second,
    +  # em-dashes are more common than en-dashes, and so it sort of makes
    +  # sense that the shortcut should be shorter to type. (Thanks to
    +  # Aaron Swartz for the idea.)
    +  #
    +  def educate_dashes_inverted(str)
    +    str.
    +      gsub(/---/, entity(:en_dash)).
    +      gsub(/--/,  entity(:em_dash))
    +  end
    +
    +  # Return the string, with each instance of "..." translated
    +  # to an ellipsis HTML entity. Also converts the case where there are
    +  # spaces between the dots.
    +  #
    +  def educate_ellipses(str)
    +    str.
    +      gsub('...',   entity(:ellipsis)).
    +      gsub('. . .', entity(:ellipsis))
    +  end
    +
    +  # Return the string, with "``backticks''"-style single quotes
    +  # translated into HTML curly quote entities.
    +  #
    +  def educate_backticks(str)
    +    str.
    +      gsub("``", entity(:double_left_quote)).
    +      gsub("''", entity(:double_right_quote))
    +  end
    +
    +  # Return the string, with "`backticks'"-style single quotes
    +  # translated into HTML curly quote entities.
    +  #
    +  def educate_single_backticks(str)
    +    str.
    +      gsub("`", entity(:single_left_quote)).
    +      gsub("'", entity(:single_right_quote))
    +  end
    +
    +  def educate_fractions(str)
    +    str.gsub(/(\s+|^)(1\/4|1\/2|3\/4)([,.;\s]|$)/) do
    +      frac =
    +        if $2 == "1/2".freeze
    +          entity(:frac12)
    +        elsif $2 == "1/4".freeze
    +          entity(:frac14)
    +        elsif $2 == "3/4".freeze
    +          entity(:frac34)
    +        end
    +      "#{$1}#{frac}#{$3}"
    +    end
    +  end
    +
    +  # Return the string, with "educated" curly quote HTML entities.
    +  #
    +  def educate_quotes(str)
    +    punct_class = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]'
    +
    +    # normalize html
    +    str = str.dup
    +    # Special case if the very first character is a quote followed by
    +    # punctuation at a non-word-break. Close the quotes by brute
    +    # force:
    +    str.gsub!(/^'(?=#{punct_class}\B)/,
    +              entity(:single_right_quote))
    +    str.gsub!(/^"(?=#{punct_class}\B)/,
    +              entity(:double_right_quote))
    +
    +    # Special case for double sets of quotes, e.g.:
    +    #   

    He said, "'Quoted' words in a larger quote."

    + str.gsub!(/"'(?=\w)/, + "#{entity(:double_left_quote)}#{entity(:single_left_quote)}") + str.gsub!(/'"(?=\w)/, + "#{entity(:single_left_quote)}#{entity(:double_left_quote)}") + + # Special case for decade abbreviations (the '80s): + str.gsub!(/'(?=\d\ds)/, + entity(:single_right_quote)) + + close_class = %![^\ \t\r\n\\[\{\(\-]! + dec_dashes = "#{entity(:en_dash)}|#{entity(:em_dash)}" + + # Get most opening single quotes: + str.gsub!(/(\s| |=|--|&[mn]dash;|#{dec_dashes}|ȁ[34];)'(?=\w)/, + '\1' + entity(:single_left_quote)) + + # Single closing quotes: + str.gsub!(/(#{close_class})'/, + '\1' + entity(:single_right_quote)) + str.gsub!(/'(\s|s\b|$)/, + entity(:single_right_quote) + '\1') + + # Any remaining single quotes should be opening ones: + str.gsub!(/'/, + entity(:single_left_quote)) + + # Get most opening double quotes: + str.gsub!(/(\s| |=|--|&[mn]dash;|#{dec_dashes}|ȁ[34];)"(?=\w)/, + '\1' + entity(:double_left_quote)) + + # Double closing quotes: + str.gsub!(/(#{close_class})"/, + '\1' + entity(:double_right_quote)) + str.gsub!(/"(\s|s\b|$)/, + entity(:double_right_quote) + '\1') + + # Any remaining quotes should be opening ones: + str.gsub!(/"/, + entity(:double_left_quote)) + + str + end + + # Return the string, with each RubyPants HTML entity translated to + # its ASCII counterpart. + # + # Note: This is not reversible (but exactly the same as in SmartyPants) + # + def stupefy_entities(str) + new_str = str.dup + + { + :en_dash => '-', + :em_dash => '--', + :single_left_quote => "'", + :single_right_quote => "'", + :double_left_quote => '"', + :double_right_quote => '"', + :ellipsis => '...' + }.each do |k,v| + new_str.gsub!(/#{entity(k)}/, v) + end + + new_str + end + + # Return an array of the tokens comprising the string. Each token is + # either a tag (possibly with nested, tags contained therein, such + # as , or a run of text between + # tags. Each element of the array is a two-element array; the first + # is either :tag or :text; the second is the actual value. + # + # Based on the _tokenize() subroutine from Brad Choate's + # MTRegex plugin. + # + # This is actually the easier variant using tag_soup, as used by + # Chad Miller in the Python port of SmartyPants. + # + def tokenize + tag_soup = /([^<]*)(<[^>]*>)/ + + tokens = [] + + prev_end = 0 + + scan(tag_soup) do + tokens << [:text, $1] if $1 != "" + tokens << [:tag, $2] + prev_end = $~.end(0) + end + + if prev_end < size + tokens << [:text, self[prev_end..-1]] + end + + tokens + end + + def default_entities + { + single_left_quote: "‘", + double_left_quote: "“", + single_right_quote: "’", + double_right_quote: "”", + em_dash: "—", + en_dash: "–", + ellipsis: "…", + html_quote: """, + frac12: "½", + frac14: "¼", + frac34: "¾", + } + end + + def entity(key) + @entities[key] + end + +end diff --git a/lib/i18n/backend/discourse_i18n.rb b/lib/i18n/backend/discourse_i18n.rb new file mode 100644 index 00000000000..8b2ea237598 --- /dev/null +++ b/lib/i18n/backend/discourse_i18n.rb @@ -0,0 +1,104 @@ +require 'i18n/backend/pluralization' + +module I18n + module Backend + class DiscourseI18n < I18n::Backend::Simple + include I18n::Backend::Fallbacks + include I18n::Backend::Pluralization + + def available_locales + # in case you are wondering this is: + # Dir.glob( File.join(Rails.root, 'config', 'locales', 'client.*.yml') ) + # .map {|x| x.split('.')[-2]}.sort + LocaleSiteSetting.supported_locales.map(&:to_sym) + end + + def reload! + @overrides = {} + @pluralizers = {} + super + end + + # force explicit loading + def load_translations(*filenames) + unless filenames.empty? + filenames.flatten.each { |filename| load_file(filename) } + end + end + + def fallbacks(locale) + [locale, SiteSetting.default_locale.to_sym, :en].uniq.compact + end + + def exists?(locale, key) + fallbacks(locale).each do |fallback| + begin + return true if super(fallback, key) + rescue I18n::InvalidLocale + # we do nothing when the locale is invalid, as this is a fallback anyways. + end + end + + false + end + + def search(locale, query) + results = {} + + fallbacks(locale).each do |fallback| + find_results(/#{query}/i, results, translations[fallback]) + end + + results + end + + protected + def find_results(regexp, results, translations, path=nil) + return results if translations.blank? + + translations.each do |k_sym, v| + k = k_sym.to_s + key_path = path ? "#{path}.#{k}" : k + if v.is_a?(String) + unless results.has_key?(key_path) + results[key_path] = v if key_path =~ regexp || v =~ regexp + end + elsif v.is_a?(Hash) + find_results(regexp, results, v, key_path) + end + end + results + end + + # Support interpolation and pluralization of overrides by first looking up + # the original translations before applying our overrides. + def lookup(locale, key, scope = [], options = {}) + existing_translations = super(locale, key, scope, options) + + if options[:overrides] && existing_translations + if options[:count] + + remapped_translations = + if existing_translations.is_a?(Hash) + Hash[existing_translations.map { |k, v| ["#{key}.#{k}", v] }] + elsif existing_translations.is_a?(String) + Hash[[[key, existing_translations]]] + end + + result = {} + + remapped_translations.merge(options[:overrides]).each do |k, v| + result[k.split('.').last.to_sym] = v if k != key && k.start_with?(key.to_s) + end + return result if result.size > 0 + end + + return options[:overrides][key] if options[:overrides][key] + end + + existing_translations + end + + end + end +end diff --git a/lib/import_export/category_exporter.rb b/lib/import_export/category_exporter.rb new file mode 100644 index 00000000000..4036ed783f4 --- /dev/null +++ b/lib/import_export/category_exporter.rb @@ -0,0 +1,89 @@ +module ImportExport + class CategoryExporter + + attr_reader :export_data + + def initialize(category_id) + @category = Category.find(category_id) + @subcategories = Category.where(parent_category_id: category_id) + @export_data = { + users: [], + groups: [], + category: nil, + subcategories: [], + topics: [] + } + end + + def perform + puts "Exporting category #{@category.name}...", "" + export_categories + export_topics_and_users + self + end + + + CATEGORY_ATTRS = [:id, :name, :color, :created_at, :user_id, :slug, :description, :text_color, + :auto_close_hours, :logo_url, :background_url, :auto_close_based_on_last_post, + :topic_template, :suppress_from_homepage, :permissions_params] + + def export_categories + @export_data[:category] = CATEGORY_ATTRS.inject({}) { |h,a| h[a] = @category.send(a); h } + @subcategories.find_each do |subcat| + @export_data[:subcategories] << CATEGORY_ATTRS.inject({}) { |h,a| h[a] = subcat.send(a); h } + end + + # export groups that are mentioned in category permissions + group_names = [] + auto_group_names = Group::AUTO_GROUPS.keys.map(&:to_s) + + ([@export_data[:category]] + @export_data[:subcategories]).each do |c| + c[:permissions_params].each do |group_name, _| + group_names << group_name unless auto_group_names.include?(group_name.to_s) + end + end + + group_names.uniq! + export_groups(group_names) unless group_names.empty? + + self + end + + + GROUP_ATTRS = [ :id, :name, :created_at, :alias_level, :visible, + :automatic_membership_email_domains, :automatic_membership_retroactive, + :primary_group, :title, :grant_trust_level, :incoming_email] + + def export_groups(group_names) + group_names.each do |name| + group = Group.find_by_name(name) + group_attrs = GROUP_ATTRS.inject({}) { |h,a| h[a] = group.send(a); h } + group_attrs[:user_ids] = group.users.pluck(:id) + @export_data[:groups] << group_attrs + end + + self + end + + def export_topics_and_users + all_category_ids = [@category.id] + @subcategories.pluck(:id) + description_topic_ids = Category.where(id: all_category_ids).pluck(:topic_id) + topic_exporter = ImportExport::TopicExporter.new(Topic.where(category_id: all_category_ids).pluck(:id) - description_topic_ids) + topic_exporter.perform + @export_data[:users] = topic_exporter.export_data[:users] + @export_data[:topics] = topic_exporter.export_data[:topics] + self + end + + def save_to_file(filename=nil) + require 'json' + output_basename = filename || File.join("category-export-#{Time.now.strftime("%Y-%m-%d-%H%M%S")}.json") + File.open(output_basename, "w:UTF-8") do |f| + f.write(@export_data.to_json) + end + puts "Export saved to #{output_basename}" + output_basename + end + + end +end diff --git a/lib/import_export/category_importer.rb b/lib/import_export/category_importer.rb new file mode 100644 index 00000000000..9b21b7aa265 --- /dev/null +++ b/lib/import_export/category_importer.rb @@ -0,0 +1,83 @@ +require File.join(Rails.root, 'script', 'import_scripts', 'base.rb') + +module ImportExport + class CategoryImporter < ImportScripts::Base + def initialize(export_data) + @export_data = export_data + @topic_importer = TopicImporter.new(@export_data) + end + + def perform + RateLimiter.disable + + import_users + import_groups + import_categories + import_topics + self + ensure + RateLimiter.enable + end + + def import_groups + return if @export_data[:groups].empty? + + @export_data[:groups].each do |group_data| + g = group_data.dup + user_ids = g.delete(:user_ids) + external_id = g.delete(:id) + new_group = Group.find_by_name(g[:name]) || Group.create!(g) + user_ids.each do |external_user_id| + new_group.add( User.find(@topic_importer.new_user_id(external_user_id)) ) rescue ActiveRecord::RecordNotUnique + end + end + end + + def import_users + @topic_importer.import_users + end + + def import_categories + id = @export_data[:category].delete(:id) + + parent = CategoryCustomField.where(name: 'import_id', value: id.to_s).first.try(:category) + + unless parent + permissions = @export_data[:category].delete(:permissions_params) + parent = Category.new(@export_data[:category]) + parent.user_id = @topic_importer.new_user_id(@export_data[:category][:user_id]) # imported user's new id + parent.custom_fields["import_id"] = id + parent.permissions = permissions if permissions + parent.save! + set_category_description(parent, @export_data[:category][:description]) + end + + @export_data[:subcategories].each do |cat_attrs| + id = cat_attrs.delete(:id) + existing = CategoryCustomField.where(name: 'import_id', value: id.to_s).first.try(:category) + + unless existing + permissions = cat_attrs.delete(:permissions_params) + subcategory = Category.new(cat_attrs) + subcategory.parent_category_id = parent.id + subcategory.user_id = @topic_importer.new_user_id(cat_attrs[:user_id]) + subcategory.custom_fields["import_id"] = id + subcategory.permissions = permissions if permissions + subcategory.save! + set_category_description(subcategory, cat_attrs[:description]) + end + end + end + + def set_category_description(c, description) + post = c.topic.ordered_posts.first + post.raw = description + post.save! + post.rebake! + end + + def import_topics + @topic_importer.import_topics + end + end +end diff --git a/lib/import_export/import_export.rb b/lib/import_export/import_export.rb new file mode 100644 index 00000000000..4bb6fa9250d --- /dev/null +++ b/lib/import_export/import_export.rb @@ -0,0 +1,26 @@ +require "import_export/category_exporter" +require "import_export/category_importer" +require "import_export/topic_exporter" +require "import_export/topic_importer" +require "json" + +module ImportExport + + def self.export_category(category_id, filename=nil) + ImportExport::CategoryExporter.new(category_id).perform.save_to_file(filename) + end + + def self.import_category(filename) + export_data = ActiveSupport::HashWithIndifferentAccess.new(File.open(filename, "r:UTF-8") { |f| JSON.parse(f.read) }) + ImportExport::CategoryImporter.new(export_data).perform + end + + def self.export_topics(topic_ids) + ImportExport::TopicExporter.new(topic_ids).perform.save_to_file + end + + def self.import_topics(filename) + export_data = ActiveSupport::HashWithIndifferentAccess.new(File.open(filename, "r:UTF-8") { |f| JSON.parse(f.read) }) + ImportExport::TopicImporter.new(export_data).perform + end +end diff --git a/lib/import_export/topic_exporter.rb b/lib/import_export/topic_exporter.rb new file mode 100644 index 00000000000..78b4dc4d9eb --- /dev/null +++ b/lib/import_export/topic_exporter.rb @@ -0,0 +1,96 @@ +module ImportExport + class TopicExporter + + attr_reader :exported_user_ids, :export_data + + def initialize(topic_ids) + @topic_ids = topic_ids + @exported_user_ids = [] + @export_data = { + users: [], + topics: [] + } + end + + def perform + export_users + export_topics + # TODO: user actions + + self + end + + + USER_ATTRS = [:id, :email, :username, :name, :created_at, :trust_level, :active, :last_emailed_at] + + def export_users + # TODO: avatar + + @exported_user_ids = [] + @topic_ids.each do |topic_id| + t = Topic.find(topic_id) + t.posts.includes(user: [:user_profile]).find_each do |post| + u = post.user + unless @exported_user_ids.include?(u.id) + x = USER_ATTRS.inject({}) { |h, a| h[a] = u.send(a); h; } + @export_data[:users] << x.merge({ + bio_raw: u.user_profile.bio_raw, + website: u.user_profile.website, + location: u.user_profile.location + }) + @exported_user_ids << u.id + end + end + end + + self + end + + + def export_topics + @topic_ids.each do |topic_id| + t = Topic.find(topic_id) + puts t.title + export_topic(t) + end + puts "" + end + + + TOPIC_ATTRS = [:id, :title, :created_at, :views, :category_id, :closed, :archived, :archetype] + POST_ATTRS = [:id, :user_id, :post_number, :raw, :created_at, :reply_to_post_number, + :hidden, :hidden_reason_id, :wiki] + + def export_topic(topic) + topic_data = {} + + TOPIC_ATTRS.each do |a| + topic_data[a] = topic.send(a) + end + + topic_data[:posts] = [] + + topic.ordered_posts.find_each do |post| + h = POST_ATTRS.inject({}) { |h, a| h[a] = post.send(a); h; } + h[:raw] = h[:raw].gsub('src="/uploads', "src=\"#{Discourse.base_url_no_prefix}/uploads") + topic_data[:posts] << h + end + + @export_data[:topics] << topic_data + + self + end + + + def save_to_file(filename=nil) + require 'json' + output_basename = filename || File.join("topic-export-#{Time.now.strftime("%Y-%m-%d-%H%M%S")}.json") + File.open(output_basename, "w:UTF-8") do |f| + f.write(@export_data.to_json) + end + puts "Export saved to #{output_basename}" + output_basename + end + + end +end diff --git a/lib/import_export/topic_importer.rb b/lib/import_export/topic_importer.rb new file mode 100644 index 00000000000..e7fc2d8f365 --- /dev/null +++ b/lib/import_export/topic_importer.rb @@ -0,0 +1,78 @@ +require File.join(Rails.root, 'script', 'import_scripts', 'base.rb') + +module ImportExport + class TopicImporter < ImportScripts::Base + def initialize(export_data) + @export_data = export_data + end + + def perform + RateLimiter.disable + + import_users + import_topics + self + ensure + RateLimiter.enable + end + + def import_users + @export_data[:users].each do |u| + existing = User.where(email: u[:email]).first + if existing + if existing.custom_fields["import_id"] != u[:id] + existing.custom_fields["import_id"] = u[:id] + existing.save! + end + else + u = create_user(u, u[:id]) # see ImportScripts::Base + end + end + self + end + + def import_topics + @export_data[:topics].each do |t| + puts "" + print t[:title] + + first_post_attrs = t[:posts].first.merge( t.slice(*(TopicExporter::TOPIC_ATTRS - [:id, :category_id])) ) + first_post_attrs[:user_id] = new_user_id(first_post_attrs[:user_id]) + first_post_attrs[:category] = new_category_id(t[:category_id]) + + first_post = PostCustomField.where(name: "import_id", value: first_post_attrs[:id]).first.try(:post) + + unless first_post + first_post = create_post( first_post_attrs, first_post_attrs[:id] ) + end + + topic_id = first_post.topic_id + + t[:posts].each_with_index do |post_data, i| + next if i == 0 + print "." + existing = PostCustomField.where(name: "import_id", value: post_data[:id]).first.try(:post) + unless existing + create_post(post_data.merge({ + topic_id: topic_id, + user_id: new_user_id(post_data[:user_id]) + }), post_data[:id]) # see ImportScripts::Base + end + end + end + + puts "" + + self + end + + def new_user_id(external_user_id) + ucf = UserCustomField.where(name: "import_id", value: external_user_id.to_s).first + ucf ? ucf.user_id : Discourse::SYSTEM_USER_ID + end + + def new_category_id(external_category_id) + CategoryCustomField.where(name: "import_id", value: external_category_id).first.category_id rescue nil + end + end +end diff --git a/lib/javascripts/locale/fa_IR.js b/lib/javascripts/locale/fa_IR.js new file mode 100644 index 00000000000..a830b2cdc16 --- /dev/null +++ b/lib/javascripts/locale/fa_IR.js @@ -0,0 +1,3 @@ +MessageFormat.locale.fa_IR = function ( n ) { + return "other"; +}; diff --git a/lib/javascripts/locale/pl_PL.js b/lib/javascripts/locale/pl_PL.js new file mode 100644 index 00000000000..05437893163 --- /dev/null +++ b/lib/javascripts/locale/pl_PL.js @@ -0,0 +1,15 @@ +MessageFormat.locale.pl_PL = function (n) { + if (n == 1) { + return 'one'; + } + if ((n % 10) >= 2 && (n % 10) <= 4 && + ((n % 100) < 12 || (n % 100) > 14) && n == Math.floor(n)) { + return 'few'; + } + if ((n % 10) === 0 || n != 1 && (n % 10) == 1 || + ((n % 10) >= 5 && (n % 10) <= 9 || (n % 100) >= 12 && (n % 100) <= 14) && + n == Math.floor(n)) { + return 'many'; + } + return 'other'; +}; diff --git a/lib/javascripts/locale/tr_TR.js b/lib/javascripts/locale/tr_TR.js new file mode 100644 index 00000000000..83d9c02c960 --- /dev/null +++ b/lib/javascripts/locale/tr_TR.js @@ -0,0 +1,3 @@ +MessageFormat.locale.tr_TR = function(n) { + return 'other'; +}; diff --git a/lib/javascripts/moment.js b/lib/javascripts/moment.js index 03a2460105d..7299fa45c2a 100644 --- a/lib/javascripts/moment.js +++ b/lib/javascripts/moment.js @@ -1,468 +1,165 @@ //! moment.js -//! version : 2.8.1 +//! version : 2.11.2 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com -(function (undefined) { - /************************************ - Constants - ************************************/ +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + global.moment = factory() +}(this, function () { 'use strict'; - var moment, - VERSION = '2.8.1', - // the global-scope this is NOT the global object in Node.js - globalScope = typeof global !== 'undefined' ? global : this, - oldGlobalMoment, - round = Math.round, - i, + var hookCallback; - YEAR = 0, - MONTH = 1, - DATE = 2, - HOUR = 3, - MINUTE = 4, - SECOND = 5, - MILLISECOND = 6, + function utils_hooks__hooks () { + return hookCallback.apply(null, arguments); + } - // internal storage for locale config files - locales = {}, + // This is done to register the method called with moment() + // without creating circular dependencies. + function setHookCallback (callback) { + hookCallback = callback; + } - // extra moment internal properties (plugins register props here) - momentProperties = [], + function isArray(input) { + return Object.prototype.toString.call(input) === '[object Array]'; + } - // check for nodeJS - hasModule = (typeof module !== 'undefined' && module.exports), + function isDate(input) { + return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; + } - // ASP.NET json date format regex - aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, - aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/, - - // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html - // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere - isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, - - // format tokens - formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, - localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, - - // parsing token regexes - parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 - parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999 - parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999 - parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999 - parseTokenDigits = /\d+/, // nonzero number of digits - parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic. - parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z - parseTokenT = /T/i, // T (ISO separator) - parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 - parseTokenOrdinal = /\d{1,2}/, - - //strict parsing regexes - parseTokenOneDigit = /\d/, // 0 - 9 - parseTokenTwoDigits = /\d\d/, // 00 - 99 - parseTokenThreeDigits = /\d{3}/, // 000 - 999 - parseTokenFourDigits = /\d{4}/, // 0000 - 9999 - parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999 - parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf - - // iso 8601 regex - // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) - isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/, - - isoFormat = 'YYYY-MM-DDTHH:mm:ssZ', - - isoDates = [ - ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/], - ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/], - ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/], - ['GGGG-[W]WW', /\d{4}-W\d{2}/], - ['YYYY-DDD', /\d{4}-\d{3}/] - ], - - // iso time formats and regexes - isoTimes = [ - ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/], - ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], - ['HH:mm', /(T| )\d\d:\d\d/], - ['HH', /(T| )\d\d/] - ], - - // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"] - parseTimezoneChunker = /([\+\-]|\d\d)/gi, - - // getter and setter names - proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'), - unitMillisecondFactors = { - 'Milliseconds' : 1, - 'Seconds' : 1e3, - 'Minutes' : 6e4, - 'Hours' : 36e5, - 'Days' : 864e5, - 'Months' : 2592e6, - 'Years' : 31536e6 - }, - - unitAliases = { - ms : 'millisecond', - s : 'second', - m : 'minute', - h : 'hour', - d : 'day', - D : 'date', - w : 'week', - W : 'isoWeek', - M : 'month', - Q : 'quarter', - y : 'year', - DDD : 'dayOfYear', - e : 'weekday', - E : 'isoWeekday', - gg: 'weekYear', - GG: 'isoWeekYear' - }, - - camelFunctions = { - dayofyear : 'dayOfYear', - isoweekday : 'isoWeekday', - isoweek : 'isoWeek', - weekyear : 'weekYear', - isoweekyear : 'isoWeekYear' - }, - - // format function strings - formatFunctions = {}, - - // default relative time thresholds - relativeTimeThresholds = { - s: 45, // seconds to minute - m: 45, // minutes to hour - h: 22, // hours to day - d: 26, // days to month - M: 11 // months to year - }, - - // tokens to ordinalize and pad - ordinalizeTokens = 'DDD w W M D d'.split(' '), - paddedTokens = 'M D H h m s w W'.split(' '), - - formatTokenFunctions = { - M : function () { - return this.month() + 1; - }, - MMM : function (format) { - return this.localeData().monthsShort(this, format); - }, - MMMM : function (format) { - return this.localeData().months(this, format); - }, - D : function () { - return this.date(); - }, - DDD : function () { - return this.dayOfYear(); - }, - d : function () { - return this.day(); - }, - dd : function (format) { - return this.localeData().weekdaysMin(this, format); - }, - ddd : function (format) { - return this.localeData().weekdaysShort(this, format); - }, - dddd : function (format) { - return this.localeData().weekdays(this, format); - }, - w : function () { - return this.week(); - }, - W : function () { - return this.isoWeek(); - }, - YY : function () { - return leftZeroFill(this.year() % 100, 2); - }, - YYYY : function () { - return leftZeroFill(this.year(), 4); - }, - YYYYY : function () { - return leftZeroFill(this.year(), 5); - }, - YYYYYY : function () { - var y = this.year(), sign = y >= 0 ? '+' : '-'; - return sign + leftZeroFill(Math.abs(y), 6); - }, - gg : function () { - return leftZeroFill(this.weekYear() % 100, 2); - }, - gggg : function () { - return leftZeroFill(this.weekYear(), 4); - }, - ggggg : function () { - return leftZeroFill(this.weekYear(), 5); - }, - GG : function () { - return leftZeroFill(this.isoWeekYear() % 100, 2); - }, - GGGG : function () { - return leftZeroFill(this.isoWeekYear(), 4); - }, - GGGGG : function () { - return leftZeroFill(this.isoWeekYear(), 5); - }, - e : function () { - return this.weekday(); - }, - E : function () { - return this.isoWeekday(); - }, - a : function () { - return this.localeData().meridiem(this.hours(), this.minutes(), true); - }, - A : function () { - return this.localeData().meridiem(this.hours(), this.minutes(), false); - }, - H : function () { - return this.hours(); - }, - h : function () { - return this.hours() % 12 || 12; - }, - m : function () { - return this.minutes(); - }, - s : function () { - return this.seconds(); - }, - S : function () { - return toInt(this.milliseconds() / 100); - }, - SS : function () { - return leftZeroFill(toInt(this.milliseconds() / 10), 2); - }, - SSS : function () { - return leftZeroFill(this.milliseconds(), 3); - }, - SSSS : function () { - return leftZeroFill(this.milliseconds(), 3); - }, - Z : function () { - var a = -this.zone(), - b = '+'; - if (a < 0) { - a = -a; - b = '-'; - } - return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2); - }, - ZZ : function () { - var a = -this.zone(), - b = '+'; - if (a < 0) { - a = -a; - b = '-'; - } - return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2); - }, - z : function () { - return this.zoneAbbr(); - }, - zz : function () { - return this.zoneName(); - }, - X : function () { - return this.unix(); - }, - Q : function () { - return this.quarter(); - } - }, - - deprecations = {}, - - lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; - - // Pick the first defined of two or three arguments. dfl comes from - // default. - function dfl(a, b, c) { - switch (arguments.length) { - case 2: return a != null ? a : b; - case 3: return a != null ? a : b != null ? b : c; - default: throw new Error('Implement me'); + function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); } + return res; } - function defaultParsingFlags() { - // We need to deep clone this object, and es5 standard is not very - // helpful. - return { - empty : false, - unusedTokens : [], - unusedInput : [], - overflow : -2, - charsLeftOver : 0, - nullInput : false, - invalidMonth : null, - invalidFormat : false, - userInvalidated : false, - iso: false - }; + function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); } - function printMsg(msg) { - if (moment.suppressDeprecationWarnings === false && - typeof console !== 'undefined' && console.warn) { - console.warn("Deprecation warning: " + msg); - } - } - - function deprecate(msg, fn) { - var firstTime = true; - return extend(function () { - if (firstTime) { - printMsg(msg); - firstTime = false; - } - return fn.apply(this, arguments); - }, fn); - } - - function deprecateSimple(name, msg) { - if (!deprecations[name]) { - printMsg(msg); - deprecations[name] = true; - } - } - - function padToken(func, count) { - return function (a) { - return leftZeroFill(func.call(this, a), count); - }; - } - function ordinalizeToken(func, period) { - return function (a) { - return this.localeData().ordinal(func.call(this, a), period); - }; - } - - while (ordinalizeTokens.length) { - i = ordinalizeTokens.pop(); - formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i); - } - while (paddedTokens.length) { - i = paddedTokens.pop(); - formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2); - } - formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3); - - - /************************************ - Constructors - ************************************/ - - function Locale() { - } - - // Moment prototype object - function Moment(config, skipOverflow) { - if (skipOverflow !== false) { - checkOverflow(config); - } - copyConfig(this, config); - this._d = new Date(+config._d); - } - - // Duration Constructor - function Duration(duration) { - var normalizedInput = normalizeObjectUnits(duration), - years = normalizedInput.year || 0, - quarters = normalizedInput.quarter || 0, - months = normalizedInput.month || 0, - weeks = normalizedInput.week || 0, - days = normalizedInput.day || 0, - hours = normalizedInput.hour || 0, - minutes = normalizedInput.minute || 0, - seconds = normalizedInput.second || 0, - milliseconds = normalizedInput.millisecond || 0; - - // representation for dateAddRemove - this._milliseconds = +milliseconds + - seconds * 1e3 + // 1000 - minutes * 6e4 + // 1000 * 60 - hours * 36e5; // 1000 * 60 * 60 - // Because of dateAddRemove treats 24 hours as different from a - // day when working around DST, we need to store them separately - this._days = +days + - weeks * 7; - // It is impossible translate months into days without knowing - // which months you are are talking about, so we have to store - // it separately. - this._months = +months + - quarters * 3 + - years * 12; - - this._data = {}; - - this._locale = moment.localeData(); - - this._bubble(); - } - - /************************************ - Helpers - ************************************/ - - function extend(a, b) { for (var i in b) { - if (b.hasOwnProperty(i)) { + if (hasOwnProp(b, i)) { a[i] = b[i]; } } - if (b.hasOwnProperty('toString')) { + if (hasOwnProp(b, 'toString')) { a.toString = b.toString; } - if (b.hasOwnProperty('valueOf')) { + if (hasOwnProp(b, 'valueOf')) { a.valueOf = b.valueOf; } return a; } + function create_utc__createUTC (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); + } + + function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso : false + }; + } + + function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + return m._pf; + } + + function valid__isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m); + m._isValid = !isNaN(m._d.getTime()) && + flags.overflow < 0 && + !flags.empty && + !flags.invalidMonth && + !flags.invalidWeekday && + !flags.nullInput && + !flags.invalidFormat && + !flags.userInvalidated; + + if (m._strict) { + m._isValid = m._isValid && + flags.charsLeftOver === 0 && + flags.unusedTokens.length === 0 && + flags.bigHour === undefined; + } + } + return m._isValid; + } + + function valid__createInvalid (flags) { + var m = create_utc__createUTC(NaN); + if (flags != null) { + extend(getParsingFlags(m), flags); + } + else { + getParsingFlags(m).userInvalidated = true; + } + + return m; + } + + function isUndefined(input) { + return input === void 0; + } + + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + var momentProperties = utils_hooks__hooks.momentProperties = []; + function copyConfig(to, from) { var i, prop, val; - if (typeof from._isAMomentObject !== 'undefined') { + if (!isUndefined(from._isAMomentObject)) { to._isAMomentObject = from._isAMomentObject; } - if (typeof from._i !== 'undefined') { + if (!isUndefined(from._i)) { to._i = from._i; } - if (typeof from._f !== 'undefined') { + if (!isUndefined(from._f)) { to._f = from._f; } - if (typeof from._l !== 'undefined') { + if (!isUndefined(from._l)) { to._l = from._l; } - if (typeof from._strict !== 'undefined') { + if (!isUndefined(from._strict)) { to._strict = from._strict; } - if (typeof from._tzm !== 'undefined') { + if (!isUndefined(from._tzm)) { to._tzm = from._tzm; } - if (typeof from._isUTC !== 'undefined') { + if (!isUndefined(from._isUTC)) { to._isUTC = from._isUTC; } - if (typeof from._offset !== 'undefined') { + if (!isUndefined(from._offset)) { to._offset = from._offset; } - if (typeof from._pf !== 'undefined') { - to._pf = from._pf; + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); } - if (typeof from._locale !== 'undefined') { + if (!isUndefined(from._locale)) { to._locale = from._locale; } @@ -470,7 +167,7 @@ for (i in momentProperties) { prop = momentProperties[i]; val = from[prop]; - if (typeof val !== 'undefined') { + if (!isUndefined(val)) { to[prop] = val; } } @@ -479,7 +176,26 @@ return to; } - function absRound(number) { + var updateInProgress = false; + + // Moment prototype object + function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + // Prevent infinite loop in case updateOffset creates new moment + // objects. + if (updateInProgress === false) { + updateInProgress = true; + utils_hooks__hooks.updateOffset(this); + updateInProgress = false; + } + } + + function isMoment (obj) { + return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); + } + + function absFloor (number) { if (number < 0) { return Math.ceil(number); } else { @@ -487,91 +203,15 @@ } } - // left zero fill a number - // see http://jsperf.com/left-zero-filling for performance comparison - function leftZeroFill(number, targetLength, forceSign) { - var output = '' + Math.abs(number), - sign = number >= 0; + function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; - while (output.length < targetLength) { - output = '0' + output; - } - return (sign ? (forceSign ? '+' : '') : '-') + output; - } - - function positiveMomentsDifference(base, other) { - var res = {milliseconds: 0, months: 0}; - - res.months = other.month() - base.month() + - (other.year() - base.year()) * 12; - if (base.clone().add(res.months, 'M').isAfter(other)) { - --res.months; + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + value = absFloor(coercedNumber); } - res.milliseconds = +other - +(base.clone().add(res.months, 'M')); - - return res; - } - - function momentsDifference(base, other) { - var res; - other = makeAs(other, base); - if (base.isBefore(other)) { - res = positiveMomentsDifference(base, other); - } else { - res = positiveMomentsDifference(other, base); - res.milliseconds = -res.milliseconds; - res.months = -res.months; - } - - return res; - } - - // TODO: remove 'name' arg after deprecation is removed - function createAdder(direction, name) { - return function (val, period) { - var dur, tmp; - //invert the arguments, but complain about it - if (period !== null && !isNaN(+period)) { - deprecateSimple(name, "moment()." + name + "(period, number) is deprecated. Please use moment()." + name + "(number, period)."); - tmp = val; val = period; period = tmp; - } - - val = typeof val === 'string' ? +val : val; - dur = moment.duration(val, period); - addOrSubtractDurationFromMoment(this, dur, direction); - return this; - }; - } - - function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) { - var milliseconds = duration._milliseconds, - days = duration._days, - months = duration._months; - updateOffset = updateOffset == null ? true : updateOffset; - - if (milliseconds) { - mom._d.setTime(+mom._d + milliseconds * isAdding); - } - if (days) { - rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding); - } - if (months) { - rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding); - } - if (updateOffset) { - moment.updateOffset(mom, days || months); - } - } - - // check if is an array - function isArray(input) { - return Object.prototype.toString.call(input) === '[object Array]'; - } - - function isDate(input) { - return Object.prototype.toString.call(input) === '[object Date]' || - input instanceof Date; + return value; } // compare two arrays, return the number of differences @@ -589,142 +229,12 @@ return diffs + lengthDiff; } - function normalizeUnits(units) { - if (units) { - var lowered = units.toLowerCase().replace(/(.)s$/, '$1'); - units = unitAliases[units] || camelFunctions[lowered] || lowered; - } - return units; + function Locale() { } - function normalizeObjectUnits(inputObject) { - var normalizedInput = {}, - normalizedProp, - prop; - - for (prop in inputObject) { - if (inputObject.hasOwnProperty(prop)) { - normalizedProp = normalizeUnits(prop); - if (normalizedProp) { - normalizedInput[normalizedProp] = inputObject[prop]; - } - } - } - - return normalizedInput; - } - - function makeList(field) { - var count, setter; - - if (field.indexOf('week') === 0) { - count = 7; - setter = 'day'; - } - else if (field.indexOf('month') === 0) { - count = 12; - setter = 'month'; - } - else { - return; - } - - moment[field] = function (format, index) { - var i, getter, - method = moment._locale[field], - results = []; - - if (typeof format === 'number') { - index = format; - format = undefined; - } - - getter = function (i) { - var m = moment().utc().set(setter, i); - return method.call(moment._locale, m, format || ''); - }; - - if (index != null) { - return getter(index); - } - else { - for (i = 0; i < count; i++) { - results.push(getter(i)); - } - return results; - } - }; - } - - function toInt(argumentForCoercion) { - var coercedNumber = +argumentForCoercion, - value = 0; - - if (coercedNumber !== 0 && isFinite(coercedNumber)) { - if (coercedNumber >= 0) { - value = Math.floor(coercedNumber); - } else { - value = Math.ceil(coercedNumber); - } - } - - return value; - } - - function daysInMonth(year, month) { - return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); - } - - function weeksInYear(year, dow, doy) { - return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week; - } - - function daysInYear(year) { - return isLeapYear(year) ? 366 : 365; - } - - function isLeapYear(year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - } - - function checkOverflow(m) { - var overflow; - if (m._a && m._pf.overflow === -2) { - overflow = - m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : - m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : - m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : - m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : - m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : - m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : - -1; - - if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { - overflow = DATE; - } - - m._pf.overflow = overflow; - } - } - - function isValid(m) { - if (m._isValid == null) { - m._isValid = !isNaN(m._d.getTime()) && - m._pf.overflow < 0 && - !m._pf.empty && - !m._pf.invalidMonth && - !m._pf.nullInput && - !m._pf.invalidFormat && - !m._pf.userInvalidated; - - if (m._strict) { - m._isValid = m._isValid && - m._pf.charsLeftOver === 0 && - m._pf.unusedTokens.length === 0; - } - } - return m._isValid; - } + // internal storage for locale config files + var locales = {}; + var globalLocale; function normalizeLocale(key) { return key ? key.toLowerCase().replace('_', '-') : key; @@ -759,215 +269,196 @@ function loadLocale(name) { var oldLocale = null; - if (!locales[name] && hasModule) { + // TODO: Find a better way to register and load all the locales in Node + if (!locales[name] && (typeof module !== 'undefined') && + module && module.exports) { try { - oldLocale = moment.locale(); + oldLocale = globalLocale._abbr; require('./locale/' + name); - // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales - moment.locale(oldLocale); + // because defineLocale currently also sets the global locale, we + // want to undo that for lazy loaded locales + locale_locales__getSetGlobalLocale(oldLocale); } catch (e) { } } return locales[name]; } - // Return a moment from input, that is local/utc/zone equivalent to model. - function makeAs(input, model) { - return model._isUTC ? moment(input).zone(model._offset || 0) : - moment(input).local(); + // This function will load locale and then set the global locale. If + // no arguments are passed in, it will simply return the current global + // locale key. + function locale_locales__getSetGlobalLocale (key, values) { + var data; + if (key) { + if (isUndefined(values)) { + data = locale_locales__getLocale(key); + } + else { + data = defineLocale(key, values); + } + + if (data) { + // moment.duration._locale = moment._locale = data; + globalLocale = data; + } + } + + return globalLocale._abbr; } - /************************************ - Locale - ************************************/ + function defineLocale (name, values) { + if (values !== null) { + values.abbr = name; + locales[name] = locales[name] || new Locale(); + locales[name].set(values); + // backwards compat for now: also set the locale + locale_locales__getSetGlobalLocale(name); - extend(Locale.prototype, { - - set : function (config) { - var prop, i; - for (i in config) { - prop = config[i]; - if (typeof prop === 'function') { - this[i] = prop; - } else { - this['_' + i] = prop; - } - } - }, - - _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - months : function (m) { - return this._months[m.month()]; - }, - - _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - monthsShort : function (m) { - return this._monthsShort[m.month()]; - }, - - monthsParse : function (monthName) { - var i, mom, regex; - - if (!this._monthsParse) { - this._monthsParse = []; - } - - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - if (!this._monthsParse[i]) { - mom = moment.utc([2000, i]); - regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); - this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (this._monthsParse[i].test(monthName)) { - return i; - } - } - }, - - _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdays : function (m) { - return this._weekdays[m.day()]; - }, - - _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysShort : function (m) { - return this._weekdaysShort[m.day()]; - }, - - _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - weekdaysMin : function (m) { - return this._weekdaysMin[m.day()]; - }, - - weekdaysParse : function (weekdayName) { - var i, mom, regex; - - if (!this._weekdaysParse) { - this._weekdaysParse = []; - } - - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - if (!this._weekdaysParse[i]) { - mom = moment([2000, 1]).day(i); - regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); - this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (this._weekdaysParse[i].test(weekdayName)) { - return i; - } - } - }, - - _longDateFormat : { - LT : 'h:mm A', - L : 'MM/DD/YYYY', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY LT', - LLLL : 'dddd, MMMM D, YYYY LT' - }, - longDateFormat : function (key) { - var output = this._longDateFormat[key]; - if (!output && this._longDateFormat[key.toUpperCase()]) { - output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) { - return val.slice(1); - }); - this._longDateFormat[key] = output; - } - return output; - }, - - isPM : function (input) { - // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays - // Using charAt should be more compatible. - return ((input + '').toLowerCase().charAt(0) === 'p'); - }, - - _meridiemParse : /[ap]\.?m?\.?/i, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'pm' : 'PM'; - } else { - return isLower ? 'am' : 'AM'; - } - }, - - _calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - calendar : function (key, mom) { - var output = this._calendar[key]; - return typeof output === 'function' ? output.apply(mom) : output; - }, - - _relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - - relativeTime : function (number, withoutSuffix, string, isFuture) { - var output = this._relativeTime[string]; - return (typeof output === 'function') ? - output(number, withoutSuffix, string, isFuture) : - output.replace(/%d/i, number); - }, - - pastFuture : function (diff, output) { - var format = this._relativeTime[diff > 0 ? 'future' : 'past']; - return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); - }, - - ordinal : function (number) { - return this._ordinal.replace('%d', number); - }, - _ordinal : '%d', - - preparse : function (string) { - return string; - }, - - postformat : function (string) { - return string; - }, - - week : function (mom) { - return weekOfYear(mom, this._week.dow, this._week.doy).week; - }, - - _week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 1st is the first week of the year. - }, - - _invalidDate: 'Invalid date', - invalidDate: function () { - return this._invalidDate; + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; } - }); + } - /************************************ - Formatting - ************************************/ + // returns locale data + function locale_locales__getLocale (key) { + var locale; + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return globalLocale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } + + return chooseLocale(key); + } + + var aliases = {}; + + function addUnitAlias (unit, shorthand) { + var lowerCase = unit.toLowerCase(); + aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; + } + + function normalizeUnits(units) { + return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; + } + + function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; + + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } + + return normalizedInput; + } + + function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; + } + + function makeGetSet (unit, keepTime) { + return function (value) { + if (value != null) { + get_set__set(this, unit, value); + utils_hooks__hooks.updateOffset(this, keepTime); + return this; + } else { + return get_set__get(this, unit); + } + }; + } + + function get_set__get (mom, unit) { + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; + } + + function get_set__set (mom, unit, value) { + if (mom.isValid()) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + + // MOMENTS + + function getSet (units, value) { + var unit; + if (typeof units === 'object') { + for (unit in units) { + this.set(unit, units[unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; + } + + function zeroFill(number, targetLength, forceSign) { + var absNumber = '' + Math.abs(number), + zerosToFill = targetLength - absNumber.length, + sign = number >= 0; + return (sign ? (forceSign ? '+' : '') : '-') + + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; + } + + var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; + + var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; + + var formatFunctions = {}; + + var formatTokenFunctions = {}; + + // token: 'M' + // padded: ['MM', 2] + // ordinal: 'Mo' + // callback: function () { this.month() + 1 } + function addFormatToken (token, padded, ordinal, callback) { + var func = callback; + if (typeof callback === 'string') { + func = function () { + return this[callback](); + }; + } + if (token) { + formatTokenFunctions[token] = func; + } + if (padded) { + formatTokenFunctions[padded[0]] = function () { + return zeroFill(func.apply(this, arguments), padded[1], padded[2]); + }; + } + if (ordinal) { + formatTokenFunctions[ordinal] = function () { + return this.localeData().ordinal(func.apply(this, arguments), token); + }; + } + } function removeFormattingTokens(input) { if (input.match(/\[[\s\S]/)) { @@ -1003,10 +494,7 @@ } format = expandFormat(format, m.localeData()); - - if (!formatFunctions[format]) { - formatFunctions[format] = makeFormatFunction(format); - } + formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); return formatFunctions[format](m); } @@ -1028,292 +516,642 @@ return format; } + var match1 = /\d/; // 0 - 9 + var match2 = /\d\d/; // 00 - 99 + var match3 = /\d{3}/; // 000 - 999 + var match4 = /\d{4}/; // 0000 - 9999 + var match6 = /[+-]?\d{6}/; // -999999 - 999999 + var match1to2 = /\d\d?/; // 0 - 99 + var match3to4 = /\d\d\d\d?/; // 999 - 9999 + var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 + var match1to3 = /\d{1,3}/; // 0 - 999 + var match1to4 = /\d{1,4}/; // 0 - 9999 + var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 - /************************************ - Parsing - ************************************/ + var matchUnsigned = /\d+/; // 0 - inf + var matchSigned = /[+-]?\d+/; // -inf - inf + + var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z + var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z + + var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 + + // any word (or two) characters or numbers including two/three word month in arabic. + // includes scottish gaelic two word and hyphenated months + var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i; - // get the regex to find the next token - function getParseRegexForToken(token, config) { - var a, strict = config._strict; - switch (token) { - case 'Q': - return parseTokenOneDigit; - case 'DDDD': - return parseTokenThreeDigits; - case 'YYYY': - case 'GGGG': - case 'gggg': - return strict ? parseTokenFourDigits : parseTokenOneToFourDigits; - case 'Y': - case 'G': - case 'g': - return parseTokenSignedNumber; - case 'YYYYYY': - case 'YYYYY': - case 'GGGGG': - case 'ggggg': - return strict ? parseTokenSixDigits : parseTokenOneToSixDigits; - case 'S': - if (strict) { - return parseTokenOneDigit; + var regexes = {}; + + function addRegexToken (token, regex, strictRegex) { + regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { + return (isStrict && strictRegex) ? strictRegex : regex; + }; + } + + function getParseRegexForToken (token, config) { + if (!hasOwnProp(regexes, token)) { + return new RegExp(unescapeFormat(token)); + } + + return regexes[token](config._strict, config._locale); + } + + // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript + function unescapeFormat(s) { + return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + })); + } + + function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } + + var tokens = {}; + + function addParseToken (token, callback) { + var i, func = callback; + if (typeof token === 'string') { + token = [token]; + } + if (typeof callback === 'number') { + func = function (input, array) { + array[callback] = toInt(input); + }; + } + for (i = 0; i < token.length; i++) { + tokens[token[i]] = func; + } + } + + function addWeekParseToken (token, callback) { + addParseToken(token, function (input, array, config, token) { + config._w = config._w || {}; + callback(input, config._w, config, token); + }); + } + + function addTimeToArrayFromToken(token, input, config) { + if (input != null && hasOwnProp(tokens, token)) { + tokens[token](input, config._a, config, token); + } + } + + var YEAR = 0; + var MONTH = 1; + var DATE = 2; + var HOUR = 3; + var MINUTE = 4; + var SECOND = 5; + var MILLISECOND = 6; + var WEEK = 7; + var WEEKDAY = 8; + + function daysInMonth(year, month) { + return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); + } + + // FORMATTING + + addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; + }); + + addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); + }); + + addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); + }); + + // ALIASES + + addUnitAlias('month', 'M'); + + // PARSING + + addRegexToken('M', match1to2); + addRegexToken('MM', match1to2, match2); + addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); + }); + addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); + }); + + addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; + }); + + addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); + // if we didn't find a month name, mark the date as invalid. + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } + }); + + // LOCALES + + var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/; + var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); + function localeMonths (m, format) { + return isArray(this._months) ? this._months[m.month()] : + this._months[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; + } + + var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); + function localeMonthsShort (m, format) { + return isArray(this._monthsShort) ? this._monthsShort[m.month()] : + this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; + } + + function localeMonthsParse (monthName, format, strict) { + var i, mom, regex; + + if (!this._monthsParse) { + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + } + + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = create_utc__createUTC([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); } - /* falls through */ - case 'SS': - if (strict) { - return parseTokenTwoDigits; + if (!strict && !this._monthsParse[i]) { + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); } - /* falls through */ - case 'SSS': - if (strict) { - return parseTokenThreeDigits; + // test the regex + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { + return i; } - /* falls through */ - case 'DDD': - return parseTokenOneToThreeDigits; - case 'MMM': - case 'MMMM': - case 'dd': - case 'ddd': - case 'dddd': - return parseTokenWord; - case 'a': - case 'A': - return config._locale._meridiemParse; - case 'X': - return parseTokenTimestampMs; - case 'Z': - case 'ZZ': - return parseTokenTimezone; - case 'T': - return parseTokenT; - case 'SSSS': - return parseTokenDigits; - case 'MM': - case 'DD': - case 'YY': - case 'GG': - case 'gg': - case 'HH': - case 'hh': - case 'mm': - case 'ss': - case 'ww': - case 'WW': - return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits; - case 'M': - case 'D': - case 'd': - case 'H': - case 'h': - case 'm': - case 's': - case 'w': - case 'W': - case 'e': - case 'E': - return parseTokenOneOrTwoDigits; - case 'Do': - return parseTokenOrdinal; - default : - a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i')); + } + } + + // MOMENTS + + function setMonth (mom, value) { + var dayOfMonth; + + if (!mom.isValid()) { + // No op + return mom; + } + + // TODO: Move this out of here! + if (typeof value === 'string') { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (typeof value !== 'number') { + return mom; + } + } + + dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; + } + + function getSetMonth (value) { + if (value != null) { + setMonth(this, value); + utils_hooks__hooks.updateOffset(this, true); + return this; + } else { + return get_set__get(this, 'Month'); + } + } + + function getDaysInMonth () { + return daysInMonth(this.year(), this.month()); + } + + var defaultMonthsShortRegex = matchWord; + function monthsShortRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + return this._monthsShortStrictRegex && isStrict ? + this._monthsShortStrictRegex : this._monthsShortRegex; + } + } + + var defaultMonthsRegex = matchWord; + function monthsRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + return this._monthsStrictRegex && isStrict ? + this._monthsStrictRegex : this._monthsRegex; + } + } + + function computeMonthsParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var shortPieces = [], longPieces = [], mixedPieces = [], + i, mom; + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = create_utc__createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } + // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')$', 'i'); + this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')$', 'i'); + } + + function checkOverflow (m) { + var overflow; + var a = m._a; + + if (a && getParsingFlags(m).overflow === -2) { + overflow = + a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : + a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : + a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : + a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : + a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : + a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : + -1; + + if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } + + getParsingFlags(m).overflow = overflow; + } + + return m; + } + + function warn(msg) { + if (utils_hooks__hooks.suppressDeprecationWarnings === false && + (typeof console !== 'undefined') && console.warn) { + console.warn('Deprecation warning: ' + msg); + } + } + + function deprecate(msg, fn) { + var firstTime = true; + + return extend(function () { + if (firstTime) { + warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } + + var deprecations = {}; + + function deprecateSimple(name, msg) { + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } + } + + utils_hooks__hooks.suppressDeprecationWarnings = false; + + // iso 8601 regex + // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) + var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/; + var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/; + + var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; + + var isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], + ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], + ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], + ['GGGG-[W]WW', /\d{4}-W\d\d/, false], + ['YYYY-DDD', /\d{4}-\d{3}/], + ['YYYY-MM', /\d{4}-\d\d/, false], + ['YYYYYYMMDD', /[+-]\d{10}/], + ['YYYYMMDD', /\d{8}/], + // YYYYMM is NOT allowed by the standard + ['GGGG[W]WWE', /\d{4}W\d{3}/], + ['GGGG[W]WW', /\d{4}W\d{2}/, false], + ['YYYYDDD', /\d{7}/] + ]; + + // iso time formats and regexes + var isoTimes = [ + ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], + ['HH:mm:ss', /\d\d:\d\d:\d\d/], + ['HH:mm', /\d\d:\d\d/], + ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], + ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], + ['HHmmss', /\d\d\d\d\d\d/], + ['HHmm', /\d\d\d\d/], + ['HH', /\d\d/] + ]; + + var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; + + // date from iso format + function configFromISO(config) { + var i, l, + string = config._i, + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, dateFormat, timeFormat, tzFormat; + + if (match) { + getParsingFlags(config).iso = true; + + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; + break; + } + } + if (dateFormat == null) { + config._isValid = false; + return; + } + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + if (timeFormat == null) { + config._isValid = false; + return; + } + } + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; + } + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); + configFromStringAndFormat(config); + } else { + config._isValid = false; + } + } + + // date from iso format or fallback + function configFromString(config) { + var matched = aspNetJsonRegex.exec(config._i); + + if (matched !== null) { + config._d = new Date(+matched[1]); + return; + } + + configFromISO(config); + if (config._isValid === false) { + delete config._isValid; + utils_hooks__hooks.createFromInputFallback(config); + } + } + + utils_hooks__hooks.createFromInputFallback = deprecate( + 'moment construction falls back to js Date. This is ' + + 'discouraged and will be removed in upcoming major ' + + 'release. Please refer to ' + + 'https://github.com/moment/moment/issues/1407 for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } + ); + + function createDate (y, m, d, h, M, s, ms) { + //can't just apply() to create a date: + //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply + var date = new Date(y, m, d, h, M, s, ms); + + //the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { + date.setFullYear(y); + } + return date; + } + + function createUTCDate (y) { + var date = new Date(Date.UTC.apply(null, arguments)); + + //the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + return date; + } + + // FORMATTING + + addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; + }); + + addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; + }); + + addFormatToken(0, ['YYYY', 4], 0, 'year'); + addFormatToken(0, ['YYYYY', 5], 0, 'year'); + addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + + // ALIASES + + addUnitAlias('year', 'y'); + + // PARSING + + addRegexToken('Y', matchSigned); + addRegexToken('YY', match1to2, match2); + addRegexToken('YYYY', match1to4, match4); + addRegexToken('YYYYY', match1to6, match6); + addRegexToken('YYYYYY', match1to6, match6); + + addParseToken(['YYYYY', 'YYYYYY'], YEAR); + addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input); + }); + addParseToken('YY', function (input, array) { + array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input); + }); + addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); + }); + + // HELPERS + + function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; + } + + function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; + } + + // HOOKS + + utils_hooks__hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + }; + + // MOMENTS + + var getSetYear = makeGetSet('FullYear', false); + + function getIsLeapYear () { + return isLeapYear(this.year()); + } + + // start-of-first-week - start-of-year + function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + + return -fwdlw + fwd - 1; + } + + //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday + function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, resDayOfYear; + + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; + } + + return { + year: resYear, + dayOfYear: resDayOfYear + }; + } + + function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, resYear; + + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } + + return { + week: resWeek, + year: resYear + }; + } + + function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; + } + + // Pick the first defined of two or three arguments. + function defaults(a, b, c) { + if (a != null) { return a; } - } - - function timezoneMinutesFromString(string) { - string = string || ''; - var possibleTzMatches = (string.match(parseTokenTimezone) || []), - tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [], - parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0], - minutes = +(parts[1] * 60) + toInt(parts[2]); - - return parts[0] === '+' ? -minutes : minutes; - } - - // function to convert string input to date - function addTimeToArrayFromToken(token, input, config) { - var a, datePartArray = config._a; - - switch (token) { - // QUARTER - case 'Q': - if (input != null) { - datePartArray[MONTH] = (toInt(input) - 1) * 3; - } - break; - // MONTH - case 'M' : // fall through to MM - case 'MM' : - if (input != null) { - datePartArray[MONTH] = toInt(input) - 1; - } - break; - case 'MMM' : // fall through to MMMM - case 'MMMM' : - a = config._locale.monthsParse(input); - // if we didn't find a month name, mark the date as invalid. - if (a != null) { - datePartArray[MONTH] = a; - } else { - config._pf.invalidMonth = input; - } - break; - // DAY OF MONTH - case 'D' : // fall through to DD - case 'DD' : - if (input != null) { - datePartArray[DATE] = toInt(input); - } - break; - case 'Do' : - if (input != null) { - datePartArray[DATE] = toInt(parseInt(input, 10)); - } - break; - // DAY OF YEAR - case 'DDD' : // fall through to DDDD - case 'DDDD' : - if (input != null) { - config._dayOfYear = toInt(input); - } - - break; - // YEAR - case 'YY' : - datePartArray[YEAR] = moment.parseTwoDigitYear(input); - break; - case 'YYYY' : - case 'YYYYY' : - case 'YYYYYY' : - datePartArray[YEAR] = toInt(input); - break; - // AM / PM - case 'a' : // fall through to A - case 'A' : - config._isPm = config._locale.isPM(input); - break; - // 24 HOUR - case 'H' : // fall through to hh - case 'HH' : // fall through to hh - case 'h' : // fall through to hh - case 'hh' : - datePartArray[HOUR] = toInt(input); - break; - // MINUTE - case 'm' : // fall through to mm - case 'mm' : - datePartArray[MINUTE] = toInt(input); - break; - // SECOND - case 's' : // fall through to ss - case 'ss' : - datePartArray[SECOND] = toInt(input); - break; - // MILLISECOND - case 'S' : - case 'SS' : - case 'SSS' : - case 'SSSS' : - datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); - break; - // UNIX TIMESTAMP WITH MS - case 'X': - config._d = new Date(parseFloat(input) * 1000); - break; - // TIMEZONE - case 'Z' : // fall through to ZZ - case 'ZZ' : - config._useUTC = true; - config._tzm = timezoneMinutesFromString(input); - break; - // WEEKDAY - human - case 'dd': - case 'ddd': - case 'dddd': - a = config._locale.weekdaysParse(input); - // if we didn't get a weekday name, mark the date as invalid - if (a != null) { - config._w = config._w || {}; - config._w['d'] = a; - } else { - config._pf.invalidWeekday = input; - } - break; - // WEEK, WEEK DAY - numeric - case 'w': - case 'ww': - case 'W': - case 'WW': - case 'd': - case 'e': - case 'E': - token = token.substr(0, 1); - /* falls through */ - case 'gggg': - case 'GGGG': - case 'GGGGG': - token = token.substr(0, 2); - if (input) { - config._w = config._w || {}; - config._w[token] = toInt(input); - } - break; - case 'gg': - case 'GG': - config._w = config._w || {}; - config._w[token] = moment.parseTwoDigitYear(input); + if (b != null) { + return b; } + return c; } - function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - dow = 1; - doy = 4; - - // TODO: We need to take the current isoWeekYear, but that depends on - // how we interpret now (local, utc, fixed offset). So create - // a now version of current config (take local/utc/offset flags, and - // create now). - weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year); - week = dfl(w.W, 1); - weekday = dfl(w.E, 1); - } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; - - weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year); - week = dfl(w.w, 1); - - if (w.d != null) { - // weekday -- low day numbers are considered next week - weekday = w.d; - if (weekday < dow) { - ++week; - } - } else if (w.e != null) { - // local weekday -- counting starts from begining of week - weekday = w.e + dow; - } else { - // default to begining of week - weekday = dow; - } + function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(utils_hooks__hooks.now()); + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; } - temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow); - - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; } // convert an array to a date. // the array should mirror the parameters below // note: all values past the year are optional and will default to the lowest possible value. // [year, month, day , hour, minute, second, millisecond] - function dateFromConfig(config) { + function configFromArray (config) { var i, date, input = [], currentDate, yearToUse; if (config._d) { @@ -1329,13 +1167,13 @@ //if the day of the year is set, figure out what it is if (config._dayOfYear) { - yearToUse = dfl(config._a[YEAR], currentDate[YEAR]); + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); if (config._dayOfYear > daysInYear(yearToUse)) { - config._pf._overflowDayOfYear = true; + getParsingFlags(config)._overflowDayOfYear = true; } - date = makeUTCDate(yearToUse, 0, config._dayOfYear); + date = createUTCDate(yearToUse, 0, config._dayOfYear); config._a[MONTH] = date.getUTCMonth(); config._a[DATE] = date.getUTCDate(); } @@ -1354,57 +1192,93 @@ config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; } - config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); - // Apply timezone offset from input. The actual zone can be changed + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + // Apply timezone offset from input. The actual utcOffset can be changed // with parseZone. if (config._tzm != null) { - config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm); + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; } } - function dateFromObject(config) { - var normalizedInput; + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; - if (config._d) { - return; - } + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; - normalizedInput = normalizeObjectUnits(config._i); - config._a = [ - normalizedInput.year, - normalizedInput.month, - normalizedInput.day, - normalizedInput.hour, - normalizedInput.minute, - normalizedInput.second, - normalizedInput.millisecond - ]; - - dateFromConfig(config); - } - - function currentDateArray(config) { - var now = new Date(); - if (config._useUTC) { - return [ - now.getUTCFullYear(), - now.getUTCMonth(), - now.getUTCDate() - ]; + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } } else { - return [now.getFullYear(), now.getMonth(), now.getDate()]; + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year); + week = defaults(w.w, 1); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to begining of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; } } + // constant that refers to the ISO standard + utils_hooks__hooks.ISO_8601 = function () {}; + // date from string and format string - function makeDateFromStringAndFormat(config) { - if (config._f === moment.ISO_8601) { - parseISO(config); + function configFromStringAndFormat(config) { + // TODO: Move this to another part of the creation flow to prevent circular deps + if (config._f === utils_hooks__hooks.ISO_8601) { + configFromISO(config); return; } config._a = []; - config._pf.empty = true; + getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC` var string = '' + config._i, @@ -1417,10 +1291,12 @@ for (i = 0; i < tokens.length; i++) { token = tokens[i]; parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + // console.log('token', token, 'parsedInput', parsedInput, + // 'regex', getParseRegexForToken(token, config)); if (parsedInput) { skipped = string.substr(0, string.indexOf(parsedInput)); if (skipped.length > 0) { - config._pf.unusedInput.push(skipped); + getParsingFlags(config).unusedInput.push(skipped); } string = string.slice(string.indexOf(parsedInput) + parsedInput.length); totalParsedInputLength += parsedInput.length; @@ -1428,50 +1304,65 @@ // don't parse if it's not a known token if (formatTokenFunctions[token]) { if (parsedInput) { - config._pf.empty = false; + getParsingFlags(config).empty = false; } else { - config._pf.unusedTokens.push(token); + getParsingFlags(config).unusedTokens.push(token); } addTimeToArrayFromToken(token, parsedInput, config); } else if (config._strict && !parsedInput) { - config._pf.unusedTokens.push(token); + getParsingFlags(config).unusedTokens.push(token); } } // add remaining unparsed input length to the string - config._pf.charsLeftOver = stringLength - totalParsedInputLength; + getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; if (string.length > 0) { - config._pf.unusedInput.push(string); + getParsingFlags(config).unusedInput.push(string); } - // handle am pm - if (config._isPm && config._a[HOUR] < 12) { - config._a[HOUR] += 12; - } - // if is 12 am, change hours to 0 - if (config._isPm === false && config._a[HOUR] === 12) { - config._a[HOUR] = 0; + // clear _12h flag if hour is <= 12 + if (getParsingFlags(config).bigHour === true && + config._a[HOUR] <= 12 && + config._a[HOUR] > 0) { + getParsingFlags(config).bigHour = undefined; } + // handle meridiem + config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); - dateFromConfig(config); + configFromArray(config); checkOverflow(config); } - function unescapeFormat(s) { - return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { - return p1 || p2 || p3 || p4; - }); - } - // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript - function regexpEscape(s) { - return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + function meridiemFixWrap (locale, hour, meridiem) { + var isPm; + + if (meridiem == null) { + // nothing to do + return hour; + } + if (locale.meridiemHour != null) { + return locale.meridiemHour(hour, meridiem); + } else if (locale.isPM != null) { + // Fallback + isPm = locale.isPM(meridiem); + if (isPm && hour < 12) { + hour += 12; + } + if (!isPm && hour === 12) { + hour = 0; + } + return hour; + } else { + // this is not supposed to happen + return hour; + } } // date from string and array of format strings - function makeDateFromStringAndArray(config) { + function configFromStringAndArray(config) { var tempConfig, bestMoment, @@ -1480,7 +1371,7 @@ currentScore; if (config._f.length === 0) { - config._pf.invalidFormat = true; + getParsingFlags(config).invalidFormat = true; config._d = new Date(NaN); return; } @@ -1488,21 +1379,23 @@ for (i = 0; i < config._f.length; i++) { currentScore = 0; tempConfig = copyConfig({}, config); - tempConfig._pf = defaultParsingFlags(); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } tempConfig._f = config._f[i]; - makeDateFromStringAndFormat(tempConfig); + configFromStringAndFormat(tempConfig); - if (!isValid(tempConfig)) { + if (!valid__isValid(tempConfig)) { continue; } // if there is any input that was not parsed add a penalty for that format - currentScore += tempConfig._pf.charsLeftOver; + currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens - currentScore += tempConfig._pf.unusedTokens.length * 10; + currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; - tempConfig._pf.score = currentScore; + getParsingFlags(tempConfig).score = currentScore; if (scoreToBeat == null || currentScore < scoreToBeat) { scoreToBeat = currentScore; @@ -1513,251 +1406,130 @@ extend(config, bestMoment || tempConfig); } - // date from iso format - function parseISO(config) { - var i, l, - string = config._i, - match = isoRegex.exec(string); - - if (match) { - config._pf.iso = true; - for (i = 0, l = isoDates.length; i < l; i++) { - if (isoDates[i][1].exec(string)) { - // match[5] should be "T" or undefined - config._f = isoDates[i][0] + (match[6] || ' '); - break; - } - } - for (i = 0, l = isoTimes.length; i < l; i++) { - if (isoTimes[i][1].exec(string)) { - config._f += isoTimes[i][0]; - break; - } - } - if (string.match(parseTokenTimezone)) { - config._f += 'Z'; - } - makeDateFromStringAndFormat(config); - } else { - config._isValid = false; - } - } - - // date from iso format or fallback - function makeDateFromString(config) { - parseISO(config); - if (config._isValid === false) { - delete config._isValid; - moment.createFromInputFallback(config); - } - } - - function makeDateFromInput(config) { - var input = config._i, matched; - if (input === undefined) { - config._d = new Date(); - } else if (isDate(input)) { - config._d = new Date(+input); - } else if ((matched = aspNetJsonRegex.exec(input)) !== null) { - config._d = new Date(+matched[1]); - } else if (typeof input === 'string') { - makeDateFromString(config); - } else if (isArray(input)) { - config._a = input.slice(0); - dateFromConfig(config); - } else if (typeof(input) === 'object') { - dateFromObject(config); - } else if (typeof(input) === 'number') { - // from milliseconds - config._d = new Date(input); - } else { - moment.createFromInputFallback(config); - } - } - - function makeDate(y, m, d, h, M, s, ms) { - //can't just apply() to create a date: - //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply - var date = new Date(y, m, d, h, M, s, ms); - - //the date constructor doesn't accept years < 1970 - if (y < 1970) { - date.setFullYear(y); - } - return date; - } - - function makeUTCDate(y) { - var date = new Date(Date.UTC.apply(null, arguments)); - if (y < 1970) { - date.setUTCFullYear(y); - } - return date; - } - - function parseWeekday(input, locale) { - if (typeof input === 'string') { - if (!isNaN(input)) { - input = parseInt(input, 10); - } - else { - input = locale.weekdaysParse(input); - if (typeof input !== 'number') { - return null; - } - } - } - return input; - } - - /************************************ - Relative Time - ************************************/ - - - // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { - return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); - } - - function relativeTime(posNegDuration, withoutSuffix, locale) { - var duration = moment.duration(posNegDuration).abs(), - seconds = round(duration.as('s')), - minutes = round(duration.as('m')), - hours = round(duration.as('h')), - days = round(duration.as('d')), - months = round(duration.as('M')), - years = round(duration.as('y')), - - args = seconds < relativeTimeThresholds.s && ['s', seconds] || - minutes === 1 && ['m'] || - minutes < relativeTimeThresholds.m && ['mm', minutes] || - hours === 1 && ['h'] || - hours < relativeTimeThresholds.h && ['hh', hours] || - days === 1 && ['d'] || - days < relativeTimeThresholds.d && ['dd', days] || - months === 1 && ['M'] || - months < relativeTimeThresholds.M && ['MM', months] || - years === 1 && ['y'] || ['yy', years]; - - args[2] = withoutSuffix; - args[3] = +posNegDuration > 0; - args[4] = locale; - return substituteTimeAgo.apply({}, args); - } - - - /************************************ - Week of Year - ************************************/ - - - // firstDayOfWeek 0 = sun, 6 = sat - // the day of the week that starts the week - // (usually sunday or monday) - // firstDayOfWeekOfYear 0 = sun, 6 = sat - // the first week is the week that contains the first - // of this day of the week - // (eg. ISO weeks use thursday (4)) - function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) { - var end = firstDayOfWeekOfYear - firstDayOfWeek, - daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(), - adjustedMoment; - - - if (daysToDayOfWeek > end) { - daysToDayOfWeek -= 7; + function configFromObject(config) { + if (config._d) { + return; } - if (daysToDayOfWeek < end - 7) { - daysToDayOfWeek += 7; + var i = normalizeObjectUnits(config._i); + config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { + return obj && parseInt(obj, 10); + }); + + configFromArray(config); + } + + function createFromConfig (config) { + var res = new Moment(checkOverflow(prepareConfig(config))); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; } - adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd'); - return { - week: Math.ceil(adjustedMoment.dayOfYear() / 7), - year: adjustedMoment.year() - }; + return res; } - //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday - function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { - var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; - - d = d === 0 ? 7 : d; - weekday = weekday != null ? weekday : firstDayOfWeek; - daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); - dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; - - return { - year: dayOfYear > 0 ? year : year - 1, - dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear - }; - } - - /************************************ - Top Level Functions - ************************************/ - - function makeMoment(config) { + function prepareConfig (config) { var input = config._i, format = config._f; - config._locale = config._locale || moment.localeData(config._l); + config._locale = config._locale || locale_locales__getLocale(config._l); if (input === null || (format === undefined && input === '')) { - return moment.invalid({nullInput: true}); + return valid__createInvalid({nullInput: true}); } if (typeof input === 'string') { config._i = input = config._locale.preparse(input); } - if (moment.isMoment(input)) { - return new Moment(input, true); + if (isMoment(input)) { + return new Moment(checkOverflow(input)); + } else if (isArray(format)) { + configFromStringAndArray(config); } else if (format) { - if (isArray(format)) { - makeDateFromStringAndArray(config); - } else { - makeDateFromStringAndFormat(config); - } + configFromStringAndFormat(config); + } else if (isDate(input)) { + config._d = input; } else { - makeDateFromInput(config); + configFromInput(config); } - return new Moment(config); + if (!valid__isValid(config)) { + config._d = null; + } + + return config; } - moment = function (input, format, locale, strict) { - var c; + function configFromInput(config) { + var input = config._i; + if (input === undefined) { + config._d = new Date(utils_hooks__hooks.now()); + } else if (isDate(input)) { + config._d = new Date(+input); + } else if (typeof input === 'string') { + configFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + configFromArray(config); + } else if (typeof(input) === 'object') { + configFromObject(config); + } else if (typeof(input) === 'number') { + // from milliseconds + config._d = new Date(input); + } else { + utils_hooks__hooks.createFromInputFallback(config); + } + } - if (typeof(locale) === "boolean") { + function createLocalOrUTC (input, format, locale, strict, isUTC) { + var c = {}; + + if (typeof(locale) === 'boolean') { strict = locale; locale = undefined; } // object construction must be done this way. // https://github.com/moment/moment/issues/1423 - c = {}; c._isAMomentObject = true; + c._useUTC = c._isUTC = isUTC; + c._l = locale; c._i = input; c._f = format; - c._l = locale; c._strict = strict; - c._isUTC = false; - c._pf = defaultParsingFlags(); - return makeMoment(c); - }; + return createFromConfig(c); + } - moment.suppressDeprecationWarnings = false; + function local__createLocal (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, false); + } - moment.createFromInputFallback = deprecate( - 'moment construction falls back to js Date. This is ' + - 'discouraged and will be removed in upcoming major ' + - 'release. Please refer to ' + - 'https://github.com/moment/moment/issues/1407 for more info.', - function (config) { - config._d = new Date(config._i); + var prototypeMin = deprecate( + 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', + function () { + var other = local__createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return valid__createInvalid(); + } + } + ); + + var prototypeMax = deprecate( + 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', + function () { + var other = local__createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return valid__createInvalid(); + } } ); @@ -1772,72 +1544,297 @@ moments = moments[0]; } if (!moments.length) { - return moment(); + return local__createLocal(); } res = moments[0]; for (i = 1; i < moments.length; ++i) { - if (moments[i][fn](res)) { + if (!moments[i].isValid() || moments[i][fn](res)) { res = moments[i]; } } return res; } - moment.min = function () { + // TODO: Use [].sort instead? + function min () { var args = [].slice.call(arguments, 0); return pickBy('isBefore', args); - }; + } - moment.max = function () { + function max () { var args = [].slice.call(arguments, 0); return pickBy('isAfter', args); + } + + var now = function () { + return Date.now ? Date.now() : +(new Date()); }; - // creating with utc - moment.utc = function (input, format, locale, strict) { - var c; + function Duration (duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; - if (typeof(locale) === "boolean") { - strict = locale; - locale = undefined; + // representation for dateAddRemove + this._milliseconds = +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 36e5; // 1000 * 60 * 60 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + + weeks * 7; + // It is impossible translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + + quarters * 3 + + years * 12; + + this._data = {}; + + this._locale = locale_locales__getLocale(); + + this._bubble(); + } + + function isDuration (obj) { + return obj instanceof Duration; + } + + // FORMATTING + + function offset (token, separator) { + addFormatToken(token, 0, 0, function () { + var offset = this.utcOffset(); + var sign = '+'; + if (offset < 0) { + offset = -offset; + sign = '-'; + } + return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); + }); + } + + offset('Z', ':'); + offset('ZZ', ''); + + // PARSING + + addRegexToken('Z', matchShortOffset); + addRegexToken('ZZ', matchShortOffset); + addParseToken(['Z', 'ZZ'], function (input, array, config) { + config._useUTC = true; + config._tzm = offsetFromString(matchShortOffset, input); + }); + + // HELPERS + + // timezone chunker + // '+10:00' > ['10', '00'] + // '-1530' > ['-15', '30'] + var chunkOffset = /([\+\-]|\d\d)/gi; + + function offsetFromString(matcher, string) { + var matches = ((string || '').match(matcher) || []); + var chunk = matches[matches.length - 1] || []; + var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; + var minutes = +(parts[1] * 60) + toInt(parts[2]); + + return parts[0] === '+' ? minutes : -minutes; + } + + // Return a moment from input, that is local/utc/zone equivalent to model. + function cloneWithOffset(input, model) { + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res); + // Use low-level api, because this fn is low-level api. + res._d.setTime(+res._d + diff); + utils_hooks__hooks.updateOffset(res, false); + return res; + } else { + return local__createLocal(input).local(); } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c = {}; - c._isAMomentObject = true; - c._useUTC = true; - c._isUTC = true; - c._l = locale; - c._i = input; - c._f = format; - c._strict = strict; - c._pf = defaultParsingFlags(); + } - return makeMoment(c).utc(); - }; + function getDateOffset (m) { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return -Math.round(m._d.getTimezoneOffset() / 15) * 15; + } - // creating with unix timestamp (in seconds) - moment.unix = function (input) { - return moment(input * 1000); - }; + // HOOKS - // duration - moment.duration = function (input, key) { + // This function will be called whenever a moment is mutated. + // It is intended to keep the offset in sync with the timezone. + utils_hooks__hooks.updateOffset = function () {}; + + // MOMENTS + + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + function getSetOffset (input, keepLocalTime) { + var offset = this._offset || 0, + localAdjust; + if (!this.isValid()) { + return input != null ? this : NaN; + } + if (input != null) { + if (typeof input === 'string') { + input = offsetFromString(matchShortOffset, input); + } else if (Math.abs(input) < 16) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = getDateOffset(this); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.add(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + utils_hooks__hooks.updateOffset(this, true); + this._changeInProgress = null; + } + } + return this; + } else { + return this._isUTC ? offset : getDateOffset(this); + } + } + + function getSetZone (input, keepLocalTime) { + if (input != null) { + if (typeof input !== 'string') { + input = -input; + } + + this.utcOffset(input, keepLocalTime); + + return this; + } else { + return -this.utcOffset(); + } + } + + function setOffsetToUTC (keepLocalTime) { + return this.utcOffset(0, keepLocalTime); + } + + function setOffsetToLocal (keepLocalTime) { + if (this._isUTC) { + this.utcOffset(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.subtract(getDateOffset(this), 'm'); + } + } + return this; + } + + function setOffsetToParsedOffset () { + if (this._tzm) { + this.utcOffset(this._tzm); + } else if (typeof this._i === 'string') { + this.utcOffset(offsetFromString(matchOffset, this._i)); + } + return this; + } + + function hasAlignedHourOffset (input) { + if (!this.isValid()) { + return false; + } + input = input ? local__createLocal(input).utcOffset() : 0; + + return (this.utcOffset() - input) % 60 === 0; + } + + function isDaylightSavingTime () { + return ( + this.utcOffset() > this.clone().month(0).utcOffset() || + this.utcOffset() > this.clone().month(5).utcOffset() + ); + } + + function isDaylightSavingTimeShifted () { + if (!isUndefined(this._isDSTShifted)) { + return this._isDSTShifted; + } + + var c = {}; + + copyConfig(c, this); + c = prepareConfig(c); + + if (c._a) { + var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a); + this._isDSTShifted = this.isValid() && + compareArrays(c._a, other.toArray()) > 0; + } else { + this._isDSTShifted = false; + } + + return this._isDSTShifted; + } + + function isLocal () { + return this.isValid() ? !this._isUTC : false; + } + + function isUtcOffset () { + return this.isValid() ? this._isUTC : false; + } + + function isUtc () { + return this.isValid() ? this._isUTC && this._offset === 0 : false; + } + + // ASP.NET json date format regex + var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/; + + // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html + // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere + var isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/; + + function create__createDuration (input, key) { var duration = input, // matching against regexp is expensive, do it on demand match = null, sign, ret, - parseIso, diffRes; - if (moment.isDuration(input)) { + if (isDuration(input)) { duration = { - ms: input._milliseconds, - d: input._days, - M: input._months + ms : input._milliseconds, + d : input._days, + M : input._months }; } else if (typeof input === 'number') { duration = {}; @@ -1846,38 +1843,31 @@ } else { duration.milliseconds = input; } - } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) { + } else if (!!(match = aspNetRegex.exec(input))) { sign = (match[1] === '-') ? -1 : 1; duration = { - y: 0, - d: toInt(match[DATE]) * sign, - h: toInt(match[HOUR]) * sign, - m: toInt(match[MINUTE]) * sign, - s: toInt(match[SECOND]) * sign, - ms: toInt(match[MILLISECOND]) * sign + y : 0, + d : toInt(match[DATE]) * sign, + h : toInt(match[HOUR]) * sign, + m : toInt(match[MINUTE]) * sign, + s : toInt(match[SECOND]) * sign, + ms : toInt(match[MILLISECOND]) * sign }; - } else if (!!(match = isoDurationRegex.exec(input))) { + } else if (!!(match = isoRegex.exec(input))) { sign = (match[1] === '-') ? -1 : 1; - parseIso = function (inp) { - // We'd normally use ~~inp for this, but unfortunately it also - // converts floats to ints. - // inp may be undefined, so careful calling replace on it. - var res = inp && parseFloat(inp.replace(',', '.')); - // apply sign while we're at it - return (isNaN(res) ? 0 : res) * sign; - }; duration = { - y: parseIso(match[2]), - M: parseIso(match[3]), - d: parseIso(match[4]), - h: parseIso(match[5]), - m: parseIso(match[6]), - s: parseIso(match[7]), - w: parseIso(match[8]) + y : parseIso(match[2], sign), + M : parseIso(match[3], sign), + d : parseIso(match[4], sign), + h : parseIso(match[5], sign), + m : parseIso(match[6], sign), + s : parseIso(match[7], sign), + w : parseIso(match[8], sign) }; - } else if (typeof duration === 'object' && - ('from' in duration || 'to' in duration)) { - diffRes = momentsDifference(moment(duration.from), moment(duration.to)); + } else if (duration == null) {// checks for null or undefined + duration = {}; + } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to)); duration = {}; duration.ms = diffRes.milliseconds; @@ -1886,876 +1876,1335 @@ ret = new Duration(duration); - if (moment.isDuration(input) && input.hasOwnProperty('_locale')) { + if (isDuration(input) && hasOwnProp(input, '_locale')) { ret._locale = input._locale; } return ret; - }; + } - // version number - moment.version = VERSION; + create__createDuration.fn = Duration.prototype; - // default format - moment.defaultFormat = isoFormat; + function parseIso (inp, sign) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; + } - // constant that refers to the ISO standard - moment.ISO_8601 = function () {}; + function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; - // Plugins that add properties should also add the key here (null value), - // so we can properly clone ourselves. - moment.momentProperties = momentProperties; - - // This function will be called whenever a moment is mutated. - // It is intended to keep the offset in sync with the timezone. - moment.updateOffset = function () {}; - - // This function allows you to set a threshold for relative time strings - moment.relativeTimeThreshold = function (threshold, limit) { - if (relativeTimeThresholds[threshold] === undefined) { - return false; - } - if (limit === undefined) { - return relativeTimeThresholds[threshold]; - } - relativeTimeThresholds[threshold] = limit; - return true; - }; - - moment.lang = deprecate( - "moment.lang is deprecated. Use moment.locale instead.", - function (key, value) { - return moment.locale(key, value); - } - ); - - // This function will load locale and then set the global locale. If - // no arguments are passed in, it will simply return the current global - // locale key. - moment.locale = function (key, values) { - var data; - if (key) { - if (typeof(values) !== "undefined") { - data = moment.defineLocale(key, values); - } - else { - data = moment.localeData(key); - } - - if (data) { - moment.duration._locale = moment._locale = data; - } + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; } - return moment._locale._abbr; - }; + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); - moment.defineLocale = function (name, values) { - if (values !== null) { - values.abbr = name; - if (!locales[name]) { - locales[name] = new Locale(); - } - locales[name].set(values); + return res; + } - // backwards compat for now: also set the locale - moment.locale(name); + function momentsDifference(base, other) { + var res; + if (!(base.isValid() && other.isValid())) { + return {milliseconds: 0, months: 0}; + } - return locales[name]; + other = cloneWithOffset(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); } else { - // useful for testing - delete locales[name]; - return null; - } - }; - - moment.langData = deprecate( - "moment.langData is deprecated. Use moment.localeData instead.", - function (key) { - return moment.localeData(key); - } - ); - - // returns locale data - moment.localeData = function (key) { - var locale; - - if (key && key._locale && key._locale._abbr) { - key = key._locale._abbr; + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; } - if (!key) { - return moment._locale; - } - - if (!isArray(key)) { - //short-circuit everything else - locale = loadLocale(key); - if (locale) { - return locale; - } - key = [key]; - } - - return chooseLocale(key); - }; - - // compare moment object - moment.isMoment = function (obj) { - return obj instanceof Moment || - (obj != null && obj.hasOwnProperty('_isAMomentObject')); - }; - - // for typechecking Duration objects - moment.isDuration = function (obj) { - return obj instanceof Duration; - }; - - for (i = lists.length - 1; i >= 0; --i) { - makeList(lists[i]); + return res; } - moment.normalizeUnits = function (units) { - return normalizeUnits(units); - }; - - moment.invalid = function (flags) { - var m = moment.utc(NaN); - if (flags != null) { - extend(m._pf, flags); - } - else { - m._pf.userInvalidated = true; - } - - return m; - }; - - moment.parseZone = function () { - return moment.apply(null, arguments).parseZone(); - }; - - moment.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); - }; - - /************************************ - Moment Prototype - ************************************/ - - - extend(moment.fn = Moment.prototype, { - - clone : function () { - return moment(this); - }, - - valueOf : function () { - return +this._d + ((this._offset || 0) * 60000); - }, - - unix : function () { - return Math.floor(+this / 1000); - }, - - toString : function () { - return this.clone().locale('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); - }, - - toDate : function () { - return this._offset ? new Date(+this) : this._d; - }, - - toISOString : function () { - var m = moment(this).utc(); - if (0 < m.year() && m.year() <= 9999) { - return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); - } else { - return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); - } - }, - - toArray : function () { - var m = this; - return [ - m.year(), - m.month(), - m.date(), - m.hours(), - m.minutes(), - m.seconds(), - m.milliseconds() - ]; - }, - - isValid : function () { - return isValid(this); - }, - - isDSTShifted : function () { - if (this._a) { - return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; + // TODO: remove 'name' arg after deprecation is removed + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).'); + tmp = val; val = period; period = tmp; } - return false; - }, - - parsingFlags : function () { - return extend({}, this._pf); - }, - - invalidAt: function () { - return this._pf.overflow; - }, - - utc : function (keepLocalTime) { - return this.zone(0, keepLocalTime); - }, - - local : function (keepLocalTime) { - if (this._isUTC) { - this.zone(0, keepLocalTime); - this._isUTC = false; - - if (keepLocalTime) { - this.add(this._d.getTimezoneOffset(), 'm'); - } - } + val = typeof val === 'string' ? +val : val; + dur = create__createDuration(val, period); + add_subtract__addSubtract(this, dur, direction); return this; - }, - - format : function (inputString) { - var output = formatMoment(this, inputString || moment.defaultFormat); - return this.localeData().postformat(output); - }, - - add : createAdder(1, 'add'), - - subtract : createAdder(-1, 'subtract'), - - diff : function (input, units, asFloat) { - var that = makeAs(input, this), - zoneDiff = (this.zone() - that.zone()) * 6e4, - diff, output; - - units = normalizeUnits(units); - - if (units === 'year' || units === 'month') { - // average number of days in the months in the given dates - diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2 - // difference in months - output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); - // adjust by taking difference in days, average number of days - // and dst in the given months. - output += ((this - moment(this).startOf('month')) - - (that - moment(that).startOf('month'))) / diff; - // same as above but with zones, to negate all dst - output -= ((this.zone() - moment(this).startOf('month').zone()) - - (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff; - if (units === 'year') { - output = output / 12; - } - } else { - diff = (this - that); - output = units === 'second' ? diff / 1e3 : // 1000 - units === 'minute' ? diff / 6e4 : // 1000 * 60 - units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60 - units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst - units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst - diff; - } - return asFloat ? output : absRound(output); - }, - - from : function (time, withoutSuffix) { - return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); - }, - - fromNow : function (withoutSuffix) { - return this.from(moment(), withoutSuffix); - }, - - calendar : function (time) { - // We want to compare the start of today, vs this. - // Getting start-of-today depends on whether we're zone'd or not. - var now = time || moment(), - sod = makeAs(now, this).startOf('day'), - diff = this.diff(sod, 'days', true), - format = diff < -6 ? 'sameElse' : - diff < -1 ? 'lastWeek' : - diff < 0 ? 'lastDay' : - diff < 1 ? 'sameDay' : - diff < 2 ? 'nextDay' : - diff < 7 ? 'nextWeek' : 'sameElse'; - return this.format(this.localeData().calendar(format, this)); - }, - - isLeapYear : function () { - return isLeapYear(this.year()); - }, - - isDST : function () { - return (this.zone() < this.clone().month(0).zone() || - this.zone() < this.clone().month(5).zone()); - }, - - day : function (input) { - var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); - if (input != null) { - input = parseWeekday(input, this.localeData()); - return this.add(input - day, 'd'); - } else { - return day; - } - }, - - month : makeAccessor('Month', true), - - startOf : function (units) { - units = normalizeUnits(units); - // the following switch intentionally omits break keywords - // to utilize falling through the cases. - switch (units) { - case 'year': - this.month(0); - /* falls through */ - case 'quarter': - case 'month': - this.date(1); - /* falls through */ - case 'week': - case 'isoWeek': - case 'day': - this.hours(0); - /* falls through */ - case 'hour': - this.minutes(0); - /* falls through */ - case 'minute': - this.seconds(0); - /* falls through */ - case 'second': - this.milliseconds(0); - /* falls through */ - } - - // weeks are a special case - if (units === 'week') { - this.weekday(0); - } else if (units === 'isoWeek') { - this.isoWeekday(1); - } - - // quarters are also special - if (units === 'quarter') { - this.month(Math.floor(this.month() / 3) * 3); - } - - return this; - }, - - endOf: function (units) { - units = normalizeUnits(units); - return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); - }, - - isAfter: function (input, units) { - units = typeof units !== 'undefined' ? units : 'millisecond'; - return +this.clone().startOf(units) > +moment(input).startOf(units); - }, - - isBefore: function (input, units) { - units = typeof units !== 'undefined' ? units : 'millisecond'; - return +this.clone().startOf(units) < +moment(input).startOf(units); - }, - - isSame: function (input, units) { - units = units || 'ms'; - return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); - }, - - min: deprecate( - 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', - function (other) { - other = moment.apply(null, arguments); - return other < this ? this : other; - } - ), - - max: deprecate( - 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', - function (other) { - other = moment.apply(null, arguments); - return other > this ? this : other; - } - ), - - // keepLocalTime = true means only change the timezone, without - // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]--> - // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone - // +0200, so we adjust the time as needed, to be valid. - // - // Keeping the time actually adds/subtracts (one hour) - // from the actual represented time. That is why we call updateOffset - // a second time. In case it wants us to change the offset again - // _changeInProgress == true case, then we have to adjust, because - // there is no such time in the given timezone. - zone : function (input, keepLocalTime) { - var offset = this._offset || 0, - localAdjust; - if (input != null) { - if (typeof input === 'string') { - input = timezoneMinutesFromString(input); - } - if (Math.abs(input) < 16) { - input = input * 60; - } - if (!this._isUTC && keepLocalTime) { - localAdjust = this._d.getTimezoneOffset(); - } - this._offset = input; - this._isUTC = true; - if (localAdjust != null) { - this.subtract(localAdjust, 'm'); - } - if (offset !== input) { - if (!keepLocalTime || this._changeInProgress) { - addOrSubtractDurationFromMoment(this, - moment.duration(offset - input, 'm'), 1, false); - } else if (!this._changeInProgress) { - this._changeInProgress = true; - moment.updateOffset(this, true); - this._changeInProgress = null; - } - } - } else { - return this._isUTC ? offset : this._d.getTimezoneOffset(); - } - return this; - }, - - zoneAbbr : function () { - return this._isUTC ? 'UTC' : ''; - }, - - zoneName : function () { - return this._isUTC ? 'Coordinated Universal Time' : ''; - }, - - parseZone : function () { - if (this._tzm) { - this.zone(this._tzm); - } else if (typeof this._i === 'string') { - this.zone(this._i); - } - return this; - }, - - hasAlignedHourOffset : function (input) { - if (!input) { - input = 0; - } - else { - input = moment(input).zone(); - } - - return (this.zone() - input) % 60 === 0; - }, - - daysInMonth : function () { - return daysInMonth(this.year(), this.month()); - }, - - dayOfYear : function (input) { - var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); - }, - - quarter : function (input) { - return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); - }, - - weekYear : function (input) { - var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year; - return input == null ? year : this.add((input - year), 'y'); - }, - - isoWeekYear : function (input) { - var year = weekOfYear(this, 1, 4).year; - return input == null ? year : this.add((input - year), 'y'); - }, - - week : function (input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); - }, - - isoWeek : function (input) { - var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); - }, - - weekday : function (input) { - var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; - return input == null ? weekday : this.add(input - weekday, 'd'); - }, - - isoWeekday : function (input) { - // behaves the same as moment#day except - // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) - // as a setter, sunday should belong to the previous week. - return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); - }, - - isoWeeksInYear : function () { - return weeksInYear(this.year(), 1, 4); - }, - - weeksInYear : function () { - var weekInfo = this.localeData()._week; - return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); - }, - - get : function (units) { - units = normalizeUnits(units); - return this[units](); - }, - - set : function (units, value) { - units = normalizeUnits(units); - if (typeof this[units] === 'function') { - this[units](value); - } - return this; - }, - - // If passed a locale key, it will set the locale for this - // instance. Otherwise, it will return the locale configuration - // variables for this instance. - locale : function (key) { - if (key === undefined) { - return this._locale._abbr; - } else { - this._locale = moment.localeData(key); - return this; - } - }, - - lang : deprecate( - "moment().lang() is deprecated. Use moment().localeData() instead.", - function (key) { - if (key === undefined) { - return this.localeData(); - } else { - this._locale = moment.localeData(key); - return this; - } - } - ), - - localeData : function () { - return this._locale; - } - }); - - function rawMonthSetter(mom, value) { - var dayOfMonth; - - // TODO: Move this out of here! - if (typeof value === 'string') { - value = mom.localeData().monthsParse(value); - // TODO: Another silent failure? - if (typeof value !== 'number') { - return mom; - } - } - - dayOfMonth = Math.min(mom.date(), - daysInMonth(mom.year(), value)); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); - return mom; - } - - function rawGetter(mom, unit) { - return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit](); - } - - function rawSetter(mom, unit, value) { - if (unit === 'Month') { - return rawMonthSetter(mom, value); - } else { - return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } - - function makeAccessor(unit, keepTime) { - return function (value) { - if (value != null) { - rawSetter(this, unit, value); - moment.updateOffset(this, keepTime); - return this; - } else { - return rawGetter(this, unit); - } }; } - moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false); - moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false); - moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false); + function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = duration._days, + months = duration._months; + + if (!mom.isValid()) { + // No op + return; + } + + updateOffset = updateOffset == null ? true : updateOffset; + + if (milliseconds) { + mom._d.setTime(+mom._d + milliseconds * isAdding); + } + if (days) { + get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding); + } + if (months) { + setMonth(mom, get_set__get(mom, 'Month') + months * isAdding); + } + if (updateOffset) { + utils_hooks__hooks.updateOffset(mom, days || months); + } + } + + var add_subtract__add = createAdder(1, 'add'); + var add_subtract__subtract = createAdder(-1, 'subtract'); + + function moment_calendar__calendar (time, formats) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || local__createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + diff = this.diff(sod, 'days', true), + format = diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; + + var output = formats && (isFunction(formats[format]) ? formats[format]() : formats[format]); + + return this.format(output || this.localeData().calendar(format, this, local__createLocal(now))); + } + + function clone () { + return new Moment(this); + } + + function isAfter (input, units) { + var localInput = isMoment(input) ? input : local__createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return +this > +localInput; + } else { + return +localInput < +this.clone().startOf(units); + } + } + + function isBefore (input, units) { + var localInput = isMoment(input) ? input : local__createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return +this < +localInput; + } else { + return +this.clone().endOf(units) < +localInput; + } + } + + function isBetween (from, to, units) { + return this.isAfter(from, units) && this.isBefore(to, units); + } + + function isSame (input, units) { + var localInput = isMoment(input) ? input : local__createLocal(input), + inputMs; + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units || 'millisecond'); + if (units === 'millisecond') { + return +this === +localInput; + } else { + inputMs = +localInput; + return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units)); + } + } + + function isSameOrAfter (input, units) { + return this.isSame(input, units) || this.isAfter(input,units); + } + + function isSameOrBefore (input, units) { + return this.isSame(input, units) || this.isBefore(input,units); + } + + function diff (input, units, asFloat) { + var that, + zoneDelta, + delta, output; + + if (!this.isValid()) { + return NaN; + } + + that = cloneWithOffset(input, this); + + if (!that.isValid()) { + return NaN; + } + + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + + units = normalizeUnits(units); + + if (units === 'year' || units === 'month' || units === 'quarter') { + output = monthDiff(this, that); + if (units === 'quarter') { + output = output / 3; + } else if (units === 'year') { + output = output / 12; + } + } else { + delta = this - that; + output = units === 'second' ? delta / 1e3 : // 1000 + units === 'minute' ? delta / 6e4 : // 1000 * 60 + units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60 + units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst + units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst + delta; + } + return asFloat ? output : absFloor(output); + } + + function monthDiff (a, b) { + // difference in months + var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), + // b is in (anchor - 1 month, anchor + 1 month) + anchor = a.clone().add(wholeMonthDiff, 'months'), + anchor2, adjust; + + if (b - anchor < 0) { + anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor - anchor2); + } else { + anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor2 - anchor); + } + + return -(wholeMonthDiff + adjust); + } + + utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; + + function toString () { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); + } + + function moment_format__toISOString () { + var m = this.clone().utc(); + if (0 < m.year() && m.year() <= 9999) { + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + return this.toDate().toISOString(); + } else { + return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } + } else { + return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } + } + + function format (inputString) { + var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat); + return this.localeData().postformat(output); + } + + function from (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + local__createLocal(time).isValid())) { + return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function fromNow (withoutSuffix) { + return this.from(local__createLocal(), withoutSuffix); + } + + function to (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + local__createLocal(time).isValid())) { + return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function toNow (withoutSuffix) { + return this.to(local__createLocal(), withoutSuffix); + } + + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration + // variables for this instance. + function locale (key) { + var newLocaleData; + + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = locale_locales__getLocale(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } + return this; + } + } + + var lang = deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } + ); + + function localeData () { + return this._locale; + } + + function startOf (units) { + units = normalizeUnits(units); + // the following switch intentionally omits break keywords + // to utilize falling through the cases. + switch (units) { + case 'year': + this.month(0); + /* falls through */ + case 'quarter': + case 'month': + this.date(1); + /* falls through */ + case 'week': + case 'isoWeek': + case 'day': + this.hours(0); + /* falls through */ + case 'hour': + this.minutes(0); + /* falls through */ + case 'minute': + this.seconds(0); + /* falls through */ + case 'second': + this.milliseconds(0); + } + + // weeks are a special case + if (units === 'week') { + this.weekday(0); + } + if (units === 'isoWeek') { + this.isoWeekday(1); + } + + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + + return this; + } + + function endOf (units) { + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond') { + return this; + } + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); + } + + function to_type__valueOf () { + return +this._d - ((this._offset || 0) * 60000); + } + + function unix () { + return Math.floor(+this / 1000); + } + + function toDate () { + return this._offset ? new Date(+this) : this._d; + } + + function toArray () { + var m = this; + return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; + } + + function toObject () { + var m = this; + return { + years: m.year(), + months: m.month(), + date: m.date(), + hours: m.hours(), + minutes: m.minutes(), + seconds: m.seconds(), + milliseconds: m.milliseconds() + }; + } + + function toJSON () { + // JSON.stringify(new Date(NaN)) === 'null' + return this.isValid() ? this.toISOString() : 'null'; + } + + function moment_valid__isValid () { + return valid__isValid(this); + } + + function parsingFlags () { + return extend({}, getParsingFlags(this)); + } + + function invalidAt () { + return getParsingFlags(this).overflow; + } + + function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict + }; + } + + // FORMATTING + + addFormatToken(0, ['gg', 2], 0, function () { + return this.weekYear() % 100; + }); + + addFormatToken(0, ['GG', 2], 0, function () { + return this.isoWeekYear() % 100; + }); + + function addWeekYearFormatToken (token, getter) { + addFormatToken(0, [token, token.length], 0, getter); + } + + addWeekYearFormatToken('gggg', 'weekYear'); + addWeekYearFormatToken('ggggg', 'weekYear'); + addWeekYearFormatToken('GGGG', 'isoWeekYear'); + addWeekYearFormatToken('GGGGG', 'isoWeekYear'); + + // ALIASES + + addUnitAlias('weekYear', 'gg'); + addUnitAlias('isoWeekYear', 'GG'); + + // PARSING + + addRegexToken('G', matchSigned); + addRegexToken('g', matchSigned); + addRegexToken('GG', match1to2, match2); + addRegexToken('gg', match1to2, match2); + addRegexToken('GGGG', match1to4, match4); + addRegexToken('gggg', match1to4, match4); + addRegexToken('GGGGG', match1to6, match6); + addRegexToken('ggggg', match1to6, match6); + + addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); + }); + + addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { + week[token] = utils_hooks__hooks.parseTwoDigitYear(input); + }); + + // MOMENTS + + function getSetWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, + this.week(), + this.weekday(), + this.localeData()._week.dow, + this.localeData()._week.doy); + } + + function getSetISOWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, this.isoWeek(), this.isoWeekday(), 1, 4); + } + + function getISOWeeksInYear () { + return weeksInYear(this.year(), 1, 4); + } + + function getWeeksInYear () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); + } + + function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + if (week > weeksTarget) { + week = weeksTarget; + } + return setWeekAll.call(this, input, week, weekday, dow, doy); + } + } + + function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + + // console.log("got", weekYear, week, weekday, "set", date.toISOString()); + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; + } + + // FORMATTING + + addFormatToken('Q', 0, 'Qo', 'quarter'); + + // ALIASES + + addUnitAlias('quarter', 'Q'); + + // PARSING + + addRegexToken('Q', match1); + addParseToken('Q', function (input, array) { + array[MONTH] = (toInt(input) - 1) * 3; + }); + + // MOMENTS + + function getSetQuarter (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); + } + + // FORMATTING + + addFormatToken('w', ['ww', 2], 'wo', 'week'); + addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); + + // ALIASES + + addUnitAlias('week', 'w'); + addUnitAlias('isoWeek', 'W'); + + // PARSING + + addRegexToken('w', match1to2); + addRegexToken('ww', match1to2, match2); + addRegexToken('W', match1to2); + addRegexToken('WW', match1to2, match2); + + addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); + }); + + // HELPERS + + // LOCALES + + function localeWeek (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; + } + + var defaultLocaleWeek = { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + }; + + function localeFirstDayOfWeek () { + return this._week.dow; + } + + function localeFirstDayOfYear () { + return this._week.doy; + } + + // MOMENTS + + function getSetWeek (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + function getSetISOWeek (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + // FORMATTING + + addFormatToken('D', ['DD', 2], 'Do', 'date'); + + // ALIASES + + addUnitAlias('date', 'D'); + + // PARSING + + addRegexToken('D', match1to2); + addRegexToken('DD', match1to2, match2); + addRegexToken('Do', function (isStrict, locale) { + return isStrict ? locale._ordinalParse : locale._ordinalParseLenient; + }); + + addParseToken(['D', 'DD'], DATE); + addParseToken('Do', function (input, array) { + array[DATE] = toInt(input.match(match1to2)[0], 10); + }); + + // MOMENTS + + var getSetDayOfMonth = makeGetSet('Date', true); + + // FORMATTING + + addFormatToken('d', 0, 'do', 'day'); + + addFormatToken('dd', 0, 0, function (format) { + return this.localeData().weekdaysMin(this, format); + }); + + addFormatToken('ddd', 0, 0, function (format) { + return this.localeData().weekdaysShort(this, format); + }); + + addFormatToken('dddd', 0, 0, function (format) { + return this.localeData().weekdays(this, format); + }); + + addFormatToken('e', 0, 0, 'weekday'); + addFormatToken('E', 0, 0, 'isoWeekday'); + + // ALIASES + + addUnitAlias('day', 'd'); + addUnitAlias('weekday', 'e'); + addUnitAlias('isoWeekday', 'E'); + + // PARSING + + addRegexToken('d', match1to2); + addRegexToken('e', match1to2); + addRegexToken('E', match1to2); + addRegexToken('dd', matchWord); + addRegexToken('ddd', matchWord); + addRegexToken('dddd', matchWord); + + addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); + // if we didn't get a weekday name, mark the date as invalid + if (weekday != null) { + week.d = weekday; + } else { + getParsingFlags(config).invalidWeekday = input; + } + }); + + addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { + week[token] = toInt(input); + }); + + // HELPERS + + function parseWeekday(input, locale) { + if (typeof input !== 'string') { + return input; + } + + if (!isNaN(input)) { + return parseInt(input, 10); + } + + input = locale.weekdaysParse(input); + if (typeof input === 'number') { + return input; + } + + return null; + } + + // LOCALES + + var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); + function localeWeekdays (m, format) { + return isArray(this._weekdays) ? this._weekdays[m.day()] : + this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; + } + + var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); + function localeWeekdaysShort (m) { + return this._weekdaysShort[m.day()]; + } + + var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); + function localeWeekdaysMin (m) { + return this._weekdaysMin[m.day()]; + } + + function localeWeekdaysParse (weekdayName, format, strict) { + var i, mom, regex; + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + + mom = local__createLocal([2000, 1]).day(i); + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i'); + } + if (!this._weekdaysParse[i]) { + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } + } + + // MOMENTS + + function getSetDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } + } + + function getSetLocaleDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); + } + + function getSetISODayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); + } + + // FORMATTING + + addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); + + // ALIASES + + addUnitAlias('dayOfYear', 'DDD'); + + // PARSING + + addRegexToken('DDD', match1to3); + addRegexToken('DDDD', match3); + addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); + }); + + // HELPERS + + // MOMENTS + + function getSetDayOfYear (input) { + var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); + } + + // FORMATTING + + function hFormat() { + return this.hours() % 12 || 12; + } + + addFormatToken('H', ['HH', 2], 0, 'hour'); + addFormatToken('h', ['hh', 2], 0, hFormat); + + addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); + }); + + addFormatToken('hmmss', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); + + addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); + }); + + addFormatToken('Hmmss', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); + + function meridiem (token, lowercase) { + addFormatToken(token, 0, 0, function () { + return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); + }); + } + + meridiem('a', true); + meridiem('A', false); + + // ALIASES + + addUnitAlias('hour', 'h'); + + // PARSING + + function matchMeridiem (isStrict, locale) { + return locale._meridiemParse; + } + + addRegexToken('a', matchMeridiem); + addRegexToken('A', matchMeridiem); + addRegexToken('H', match1to2); + addRegexToken('h', match1to2); + addRegexToken('HH', match1to2, match2); + addRegexToken('hh', match1to2, match2); + + addRegexToken('hmm', match3to4); + addRegexToken('hmmss', match5to6); + addRegexToken('Hmm', match3to4); + addRegexToken('Hmmss', match5to6); + + addParseToken(['H', 'HH'], HOUR); + addParseToken(['a', 'A'], function (input, array, config) { + config._isPm = config._locale.isPM(input); + config._meridiem = input; + }); + addParseToken(['h', 'hh'], function (input, array, config) { + array[HOUR] = toInt(input); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + }); + addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + }); + + // LOCALES + + function localeIsPM (input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return ((input + '').toLowerCase().charAt(0) === 'p'); + } + + var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; + function localeMeridiem (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } + } + + + // MOMENTS + // Setting the hour should keep the time, because the user explicitly // specified which hour he wants. So trying to maintain the same hour (in // a new timezone) makes sense. Adding/subtracting hours does not follow // this rule. - moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true); - // moment.fn.month is defined separately - moment.fn.date = makeAccessor('Date', true); - moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true)); - moment.fn.year = makeAccessor('FullYear', true); - moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true)); + var getSetHour = makeGetSet('Hours', true); - // add plural methods - moment.fn.days = moment.fn.day; - moment.fn.months = moment.fn.month; - moment.fn.weeks = moment.fn.week; - moment.fn.isoWeeks = moment.fn.isoWeek; - moment.fn.quarters = moment.fn.quarter; + // FORMATTING - // add aliased format methods - moment.fn.toJSON = moment.fn.toISOString; + addFormatToken('m', ['mm', 2], 0, 'minute'); - /************************************ - Duration Prototype - ************************************/ + // ALIASES + addUnitAlias('minute', 'm'); - function daysToYears (days) { - // 400 years have 146097 days (taking into account leap year rules) - return days * 400 / 146097; - } + // PARSING - function yearsToDays (years) { - // years * 365 + absRound(years / 4) - - // absRound(years / 100) + absRound(years / 400); - return years * 146097 / 400; - } + addRegexToken('m', match1to2); + addRegexToken('mm', match1to2, match2); + addParseToken(['m', 'mm'], MINUTE); - extend(moment.duration.fn = Duration.prototype, { + // MOMENTS - _bubble : function () { - var milliseconds = this._milliseconds, - days = this._days, - months = this._months, - data = this._data, - seconds, minutes, hours, years = 0; + var getSetMinute = makeGetSet('Minutes', false); - // The following code bubbles up values, see the tests for - // examples of what that means. - data.milliseconds = milliseconds % 1000; + // FORMATTING - seconds = absRound(milliseconds / 1000); - data.seconds = seconds % 60; + addFormatToken('s', ['ss', 2], 0, 'second'); - minutes = absRound(seconds / 60); - data.minutes = minutes % 60; + // ALIASES - hours = absRound(minutes / 60); - data.hours = hours % 24; + addUnitAlias('second', 's'); - days += absRound(hours / 24); + // PARSING - // Accurately convert days to years, assume start from year 0. - years = absRound(daysToYears(days)); - days -= absRound(yearsToDays(years)); + addRegexToken('s', match1to2); + addRegexToken('ss', match1to2, match2); + addParseToken(['s', 'ss'], SECOND); - // 30 days to a month - // TODO (iskren): Use anchor date (like 1st Jan) to compute this. - months += absRound(days / 30); - days %= 30; + // MOMENTS - // 12 months -> 1 year - years += absRound(months / 12); - months %= 12; + var getSetSecond = makeGetSet('Seconds', false); - data.days = days; - data.months = months; - data.years = years; - }, + // FORMATTING - abs : function () { - this._milliseconds = Math.abs(this._milliseconds); - this._days = Math.abs(this._days); - this._months = Math.abs(this._months); - - this._data.milliseconds = Math.abs(this._data.milliseconds); - this._data.seconds = Math.abs(this._data.seconds); - this._data.minutes = Math.abs(this._data.minutes); - this._data.hours = Math.abs(this._data.hours); - this._data.months = Math.abs(this._data.months); - this._data.years = Math.abs(this._data.years); - - return this; - }, - - weeks : function () { - return absRound(this.days() / 7); - }, - - valueOf : function () { - return this._milliseconds + - this._days * 864e5 + - (this._months % 12) * 2592e6 + - toInt(this._months / 12) * 31536e6; - }, - - humanize : function (withSuffix) { - var output = relativeTime(this, !withSuffix, this.localeData()); - - if (withSuffix) { - output = this.localeData().pastFuture(+this, output); - } - - return this.localeData().postformat(output); - }, - - add : function (input, val) { - // supports only 2.0-style add(1, 's') or add(moment) - var dur = moment.duration(input, val); - - this._milliseconds += dur._milliseconds; - this._days += dur._days; - this._months += dur._months; - - this._bubble(); - - return this; - }, - - subtract : function (input, val) { - var dur = moment.duration(input, val); - - this._milliseconds -= dur._milliseconds; - this._days -= dur._days; - this._months -= dur._months; - - this._bubble(); - - return this; - }, - - get : function (units) { - units = normalizeUnits(units); - return this[units.toLowerCase() + 's'](); - }, - - as : function (units) { - var days, months; - units = normalizeUnits(units); - - days = this._days + this._milliseconds / 864e5; - if (units === 'month' || units === 'year') { - months = this._months + daysToYears(days) * 12; - return units === 'month' ? months : months / 12; - } else { - days += yearsToDays(this._months / 12); - switch (units) { - case 'week': return days / 7; - case 'day': return days; - case 'hour': return days * 24; - case 'minute': return days * 24 * 60; - case 'second': return days * 24 * 60 * 60; - case 'millisecond': return days * 24 * 60 * 60 * 1000; - default: throw new Error('Unknown unit ' + units); - } - } - }, - - lang : moment.fn.lang, - locale : moment.fn.locale, - - toIsoString : deprecate( - "toIsoString() is deprecated. Please use toISOString() instead " + - "(notice the capitals)", - function () { - return this.toISOString(); - } - ), - - toISOString : function () { - // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js - var years = Math.abs(this.years()), - months = Math.abs(this.months()), - days = Math.abs(this.days()), - hours = Math.abs(this.hours()), - minutes = Math.abs(this.minutes()), - seconds = Math.abs(this.seconds() + this.milliseconds() / 1000); - - if (!this.asSeconds()) { - // this is the same as C#'s (Noda) and python (isodate)... - // but not other JS (goog.date) - return 'P0D'; - } - - return (this.asSeconds() < 0 ? '-' : '') + - 'P' + - (years ? years + 'Y' : '') + - (months ? months + 'M' : '') + - (days ? days + 'D' : '') + - ((hours || minutes || seconds) ? 'T' : '') + - (hours ? hours + 'H' : '') + - (minutes ? minutes + 'M' : '') + - (seconds ? seconds + 'S' : ''); - }, - - localeData : function () { - return this._locale; - } + addFormatToken('S', 0, 0, function () { + return ~~(this.millisecond() / 100); }); - function makeDurationGetter(name) { - moment.duration.fn[name] = function () { - return this._data[name]; - }; + addFormatToken(0, ['SS', 2], 0, function () { + return ~~(this.millisecond() / 10); + }); + + addFormatToken(0, ['SSS', 3], 0, 'millisecond'); + addFormatToken(0, ['SSSS', 4], 0, function () { + return this.millisecond() * 10; + }); + addFormatToken(0, ['SSSSS', 5], 0, function () { + return this.millisecond() * 100; + }); + addFormatToken(0, ['SSSSSS', 6], 0, function () { + return this.millisecond() * 1000; + }); + addFormatToken(0, ['SSSSSSS', 7], 0, function () { + return this.millisecond() * 10000; + }); + addFormatToken(0, ['SSSSSSSS', 8], 0, function () { + return this.millisecond() * 100000; + }); + addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { + return this.millisecond() * 1000000; + }); + + + // ALIASES + + addUnitAlias('millisecond', 'ms'); + + // PARSING + + addRegexToken('S', match1to3, match1); + addRegexToken('SS', match1to3, match2); + addRegexToken('SSS', match1to3, match3); + + var token; + for (token = 'SSSS'; token.length <= 9; token += 'S') { + addRegexToken(token, matchUnsigned); } - for (i in unitMillisecondFactors) { - if (unitMillisecondFactors.hasOwnProperty(i)) { - makeDurationGetter(i.toLowerCase()); + function parseMs(input, array) { + array[MILLISECOND] = toInt(('0.' + input) * 1000); + } + + for (token = 'S'; token.length <= 9; token += 'S') { + addParseToken(token, parseMs); + } + // MOMENTS + + var getSetMillisecond = makeGetSet('Milliseconds', false); + + // FORMATTING + + addFormatToken('z', 0, 0, 'zoneAbbr'); + addFormatToken('zz', 0, 0, 'zoneName'); + + // MOMENTS + + function getZoneAbbr () { + return this._isUTC ? 'UTC' : ''; + } + + function getZoneName () { + return this._isUTC ? 'Coordinated Universal Time' : ''; + } + + var momentPrototype__proto = Moment.prototype; + + momentPrototype__proto.add = add_subtract__add; + momentPrototype__proto.calendar = moment_calendar__calendar; + momentPrototype__proto.clone = clone; + momentPrototype__proto.diff = diff; + momentPrototype__proto.endOf = endOf; + momentPrototype__proto.format = format; + momentPrototype__proto.from = from; + momentPrototype__proto.fromNow = fromNow; + momentPrototype__proto.to = to; + momentPrototype__proto.toNow = toNow; + momentPrototype__proto.get = getSet; + momentPrototype__proto.invalidAt = invalidAt; + momentPrototype__proto.isAfter = isAfter; + momentPrototype__proto.isBefore = isBefore; + momentPrototype__proto.isBetween = isBetween; + momentPrototype__proto.isSame = isSame; + momentPrototype__proto.isSameOrAfter = isSameOrAfter; + momentPrototype__proto.isSameOrBefore = isSameOrBefore; + momentPrototype__proto.isValid = moment_valid__isValid; + momentPrototype__proto.lang = lang; + momentPrototype__proto.locale = locale; + momentPrototype__proto.localeData = localeData; + momentPrototype__proto.max = prototypeMax; + momentPrototype__proto.min = prototypeMin; + momentPrototype__proto.parsingFlags = parsingFlags; + momentPrototype__proto.set = getSet; + momentPrototype__proto.startOf = startOf; + momentPrototype__proto.subtract = add_subtract__subtract; + momentPrototype__proto.toArray = toArray; + momentPrototype__proto.toObject = toObject; + momentPrototype__proto.toDate = toDate; + momentPrototype__proto.toISOString = moment_format__toISOString; + momentPrototype__proto.toJSON = toJSON; + momentPrototype__proto.toString = toString; + momentPrototype__proto.unix = unix; + momentPrototype__proto.valueOf = to_type__valueOf; + momentPrototype__proto.creationData = creationData; + + // Year + momentPrototype__proto.year = getSetYear; + momentPrototype__proto.isLeapYear = getIsLeapYear; + + // Week Year + momentPrototype__proto.weekYear = getSetWeekYear; + momentPrototype__proto.isoWeekYear = getSetISOWeekYear; + + // Quarter + momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter; + + // Month + momentPrototype__proto.month = getSetMonth; + momentPrototype__proto.daysInMonth = getDaysInMonth; + + // Week + momentPrototype__proto.week = momentPrototype__proto.weeks = getSetWeek; + momentPrototype__proto.isoWeek = momentPrototype__proto.isoWeeks = getSetISOWeek; + momentPrototype__proto.weeksInYear = getWeeksInYear; + momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear; + + // Day + momentPrototype__proto.date = getSetDayOfMonth; + momentPrototype__proto.day = momentPrototype__proto.days = getSetDayOfWeek; + momentPrototype__proto.weekday = getSetLocaleDayOfWeek; + momentPrototype__proto.isoWeekday = getSetISODayOfWeek; + momentPrototype__proto.dayOfYear = getSetDayOfYear; + + // Hour + momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour; + + // Minute + momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute; + + // Second + momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond; + + // Millisecond + momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond; + + // Offset + momentPrototype__proto.utcOffset = getSetOffset; + momentPrototype__proto.utc = setOffsetToUTC; + momentPrototype__proto.local = setOffsetToLocal; + momentPrototype__proto.parseZone = setOffsetToParsedOffset; + momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset; + momentPrototype__proto.isDST = isDaylightSavingTime; + momentPrototype__proto.isDSTShifted = isDaylightSavingTimeShifted; + momentPrototype__proto.isLocal = isLocal; + momentPrototype__proto.isUtcOffset = isUtcOffset; + momentPrototype__proto.isUtc = isUtc; + momentPrototype__proto.isUTC = isUtc; + + // Timezone + momentPrototype__proto.zoneAbbr = getZoneAbbr; + momentPrototype__proto.zoneName = getZoneName; + + // Deprecations + momentPrototype__proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); + momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); + momentPrototype__proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); + momentPrototype__proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone); + + var momentPrototype = momentPrototype__proto; + + function moment__createUnix (input) { + return local__createLocal(input * 1000); + } + + function moment__createInZone () { + return local__createLocal.apply(null, arguments).parseZone(); + } + + var defaultCalendar = { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }; + + function locale_calendar__calendar (key, mom, now) { + var output = this._calendar[key]; + return isFunction(output) ? output.call(mom, now) : output; + } + + var defaultLongDateFormat = { + LTS : 'h:mm:ss A', + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' + }; + + function longDateFormat (key) { + var format = this._longDateFormat[key], + formatUpper = this._longDateFormat[key.toUpperCase()]; + + if (format || !formatUpper) { + return format; } + + this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); + + return this._longDateFormat[key]; } - moment.duration.fn.asMilliseconds = function () { - return this.as('ms'); - }; - moment.duration.fn.asSeconds = function () { - return this.as('s'); - }; - moment.duration.fn.asMinutes = function () { - return this.as('m'); - }; - moment.duration.fn.asHours = function () { - return this.as('h'); - }; - moment.duration.fn.asDays = function () { - return this.as('d'); - }; - moment.duration.fn.asWeeks = function () { - return this.as('weeks'); - }; - moment.duration.fn.asMonths = function () { - return this.as('M'); - }; - moment.duration.fn.asYears = function () { - return this.as('y'); + var defaultInvalidDate = 'Invalid date'; + + function invalidDate () { + return this._invalidDate; + } + + var defaultOrdinal = '%d'; + var defaultOrdinalParse = /\d{1,2}/; + + function ordinal (number) { + return this._ordinal.replace('%d', number); + } + + function preParsePostFormat (string) { + return string; + } + + var defaultRelativeTime = { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' }; - /************************************ - Default Locale - ************************************/ + function relative__relativeTime (number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return (isFunction(output)) ? + output(number, withoutSuffix, string, isFuture) : + output.replace(/%d/i, number); + } + function pastFuture (diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return isFunction(format) ? format(output) : format.replace(/%s/i, output); + } - // Set default locale, other locale will inherit from English. - moment.locale('en', { + function locale_set__set (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _ordinalParseLenient. + this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source); + } + + var prototype__proto = Locale.prototype; + + prototype__proto._calendar = defaultCalendar; + prototype__proto.calendar = locale_calendar__calendar; + prototype__proto._longDateFormat = defaultLongDateFormat; + prototype__proto.longDateFormat = longDateFormat; + prototype__proto._invalidDate = defaultInvalidDate; + prototype__proto.invalidDate = invalidDate; + prototype__proto._ordinal = defaultOrdinal; + prototype__proto.ordinal = ordinal; + prototype__proto._ordinalParse = defaultOrdinalParse; + prototype__proto.preparse = preParsePostFormat; + prototype__proto.postformat = preParsePostFormat; + prototype__proto._relativeTime = defaultRelativeTime; + prototype__proto.relativeTime = relative__relativeTime; + prototype__proto.pastFuture = pastFuture; + prototype__proto.set = locale_set__set; + + // Month + prototype__proto.months = localeMonths; + prototype__proto._months = defaultLocaleMonths; + prototype__proto.monthsShort = localeMonthsShort; + prototype__proto._monthsShort = defaultLocaleMonthsShort; + prototype__proto.monthsParse = localeMonthsParse; + prototype__proto._monthsRegex = defaultMonthsRegex; + prototype__proto.monthsRegex = monthsRegex; + prototype__proto._monthsShortRegex = defaultMonthsShortRegex; + prototype__proto.monthsShortRegex = monthsShortRegex; + + // Week + prototype__proto.week = localeWeek; + prototype__proto._week = defaultLocaleWeek; + prototype__proto.firstDayOfYear = localeFirstDayOfYear; + prototype__proto.firstDayOfWeek = localeFirstDayOfWeek; + + // Day of Week + prototype__proto.weekdays = localeWeekdays; + prototype__proto._weekdays = defaultLocaleWeekdays; + prototype__proto.weekdaysMin = localeWeekdaysMin; + prototype__proto._weekdaysMin = defaultLocaleWeekdaysMin; + prototype__proto.weekdaysShort = localeWeekdaysShort; + prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort; + prototype__proto.weekdaysParse = localeWeekdaysParse; + + // Hours + prototype__proto.isPM = localeIsPM; + prototype__proto._meridiemParse = defaultLocaleMeridiemParse; + prototype__proto.meridiem = localeMeridiem; + + function lists__get (format, index, field, setter) { + var locale = locale_locales__getLocale(); + var utc = create_utc__createUTC().set(setter, index); + return locale[field](utc, format); + } + + function list (format, index, field, count, setter) { + if (typeof format === 'number') { + index = format; + format = undefined; + } + + format = format || ''; + + if (index != null) { + return lists__get(format, index, field, setter); + } + + var i; + var out = []; + for (i = 0; i < count; i++) { + out[i] = lists__get(format, i, field, setter); + } + return out; + } + + function lists__listMonths (format, index) { + return list(format, index, 'months', 12, 'month'); + } + + function lists__listMonthsShort (format, index) { + return list(format, index, 'monthsShort', 12, 'month'); + } + + function lists__listWeekdays (format, index) { + return list(format, index, 'weekdays', 7, 'day'); + } + + function lists__listWeekdaysShort (format, index) { + return list(format, index, 'weekdaysShort', 7, 'day'); + } + + function lists__listWeekdaysMin (format, index) { + return list(format, index, 'weekdaysMin', 7, 'day'); + } + + locale_locales__getSetGlobalLocale('en', { + ordinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal : function (number) { var b = number % 10, output = (toInt(number % 100 / 10) === 1) ? 'th' : @@ -2766,43 +3215,392 @@ } }); - /* EMBED_LOCALES */ + // Side effect imports + utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale); + utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale); - /************************************ - Exposing Moment - ************************************/ + var mathAbs = Math.abs; - function makeGlobal(shouldDeprecate) { - /*global ender:false */ - if (typeof ender !== 'undefined') { - return; - } - oldGlobalMoment = globalScope.moment; - if (shouldDeprecate) { - globalScope.moment = deprecate( - 'Accessing Moment through the global scope is ' + - 'deprecated, and will be removed in an upcoming ' + - 'release.', - moment); + function duration_abs__abs () { + var data = this._data; + + this._milliseconds = mathAbs(this._milliseconds); + this._days = mathAbs(this._days); + this._months = mathAbs(this._months); + + data.milliseconds = mathAbs(data.milliseconds); + data.seconds = mathAbs(data.seconds); + data.minutes = mathAbs(data.minutes); + data.hours = mathAbs(data.hours); + data.months = mathAbs(data.months); + data.years = mathAbs(data.years); + + return this; + } + + function duration_add_subtract__addSubtract (duration, input, value, direction) { + var other = create__createDuration(input, value); + + duration._milliseconds += direction * other._milliseconds; + duration._days += direction * other._days; + duration._months += direction * other._months; + + return duration._bubble(); + } + + // supports only 2.0-style add(1, 's') or add(duration) + function duration_add_subtract__add (input, value) { + return duration_add_subtract__addSubtract(this, input, value, 1); + } + + // supports only 2.0-style subtract(1, 's') or subtract(duration) + function duration_add_subtract__subtract (input, value) { + return duration_add_subtract__addSubtract(this, input, value, -1); + } + + function absCeil (number) { + if (number < 0) { + return Math.floor(number); } else { - globalScope.moment = moment; + return Math.ceil(number); } } - // CommonJS module is defined - if (hasModule) { - module.exports = moment; - } else if (typeof define === 'function' && define.amd) { - define('moment', function (require, exports, module) { - if (module.config && module.config() && module.config().noGlobal === true) { - // release the global variable - globalScope.moment = oldGlobalMoment; - } + function bubble () { + var milliseconds = this._milliseconds; + var days = this._days; + var months = this._months; + var data = this._data; + var seconds, minutes, hours, years, monthsFromDays; - return moment; - }); - makeGlobal(true); - } else { - makeGlobal(); + // if we have a mix of positive and negative values, bubble down first + // check: https://github.com/moment/moment/issues/2166 + if (!((milliseconds >= 0 && days >= 0 && months >= 0) || + (milliseconds <= 0 && days <= 0 && months <= 0))) { + milliseconds += absCeil(monthsToDays(months) + days) * 864e5; + days = 0; + months = 0; + } + + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; + + seconds = absFloor(milliseconds / 1000); + data.seconds = seconds % 60; + + minutes = absFloor(seconds / 60); + data.minutes = minutes % 60; + + hours = absFloor(minutes / 60); + data.hours = hours % 24; + + days += absFloor(hours / 24); + + // convert days to months + monthsFromDays = absFloor(daysToMonths(days)); + months += monthsFromDays; + days -= absCeil(monthsToDays(monthsFromDays)); + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + data.days = days; + data.months = months; + data.years = years; + + return this; } -}).call(this); + + function daysToMonths (days) { + // 400 years have 146097 days (taking into account leap year rules) + // 400 years have 12 months === 4800 + return days * 4800 / 146097; + } + + function monthsToDays (months) { + // the reverse of daysToMonths + return months * 146097 / 4800; + } + + function as (units) { + var days; + var months; + var milliseconds = this._milliseconds; + + units = normalizeUnits(units); + + if (units === 'month' || units === 'year') { + days = this._days + milliseconds / 864e5; + months = this._months + daysToMonths(days); + return units === 'month' ? months : months / 12; + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(monthsToDays(this._months)); + switch (units) { + case 'week' : return days / 7 + milliseconds / 6048e5; + case 'day' : return days + milliseconds / 864e5; + case 'hour' : return days * 24 + milliseconds / 36e5; + case 'minute' : return days * 1440 + milliseconds / 6e4; + case 'second' : return days * 86400 + milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 864e5) + milliseconds; + default: throw new Error('Unknown unit ' + units); + } + } + } + + // TODO: Use this.as('ms')? + function duration_as__valueOf () { + return ( + this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6 + ); + } + + function makeAs (alias) { + return function () { + return this.as(alias); + }; + } + + var asMilliseconds = makeAs('ms'); + var asSeconds = makeAs('s'); + var asMinutes = makeAs('m'); + var asHours = makeAs('h'); + var asDays = makeAs('d'); + var asWeeks = makeAs('w'); + var asMonths = makeAs('M'); + var asYears = makeAs('y'); + + function duration_get__get (units) { + units = normalizeUnits(units); + return this[units + 's'](); + } + + function makeGetter(name) { + return function () { + return this._data[name]; + }; + } + + var milliseconds = makeGetter('milliseconds'); + var seconds = makeGetter('seconds'); + var minutes = makeGetter('minutes'); + var hours = makeGetter('hours'); + var days = makeGetter('days'); + var months = makeGetter('months'); + var years = makeGetter('years'); + + function weeks () { + return absFloor(this.days() / 7); + } + + var round = Math.round; + var thresholds = { + s: 45, // seconds to minute + m: 45, // minutes to hour + h: 22, // hours to day + d: 26, // days to month + M: 11 // months to year + }; + + // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + } + + function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) { + var duration = create__createDuration(posNegDuration).abs(); + var seconds = round(duration.as('s')); + var minutes = round(duration.as('m')); + var hours = round(duration.as('h')); + var days = round(duration.as('d')); + var months = round(duration.as('M')); + var years = round(duration.as('y')); + + var a = seconds < thresholds.s && ['s', seconds] || + minutes <= 1 && ['m'] || + minutes < thresholds.m && ['mm', minutes] || + hours <= 1 && ['h'] || + hours < thresholds.h && ['hh', hours] || + days <= 1 && ['d'] || + days < thresholds.d && ['dd', days] || + months <= 1 && ['M'] || + months < thresholds.M && ['MM', months] || + years <= 1 && ['y'] || ['yy', years]; + + a[2] = withoutSuffix; + a[3] = +posNegDuration > 0; + a[4] = locale; + return substituteTimeAgo.apply(null, a); + } + + // This function allows you to set a threshold for relative time strings + function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) { + if (thresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return thresholds[threshold]; + } + thresholds[threshold] = limit; + return true; + } + + function humanize (withSuffix) { + var locale = this.localeData(); + var output = duration_humanize__relativeTime(this, !withSuffix, locale); + + if (withSuffix) { + output = locale.pastFuture(+this, output); + } + + return locale.postformat(output); + } + + var iso_string__abs = Math.abs; + + function iso_string__toISOString() { + // for ISO strings we do not use the normal bubbling rules: + // * milliseconds bubble up until they become hours + // * days do not bubble at all + // * months bubble up until they become years + // This is because there is no context-free conversion between hours and days + // (think of clock changes) + // and also not between days and months (28-31 days per month) + var seconds = iso_string__abs(this._milliseconds) / 1000; + var days = iso_string__abs(this._days); + var months = iso_string__abs(this._months); + var minutes, hours, years; + + // 3600 seconds -> 60 minutes -> 1 hour + minutes = absFloor(seconds / 60); + hours = absFloor(minutes / 60); + seconds %= 60; + minutes %= 60; + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + var Y = years; + var M = months; + var D = days; + var h = hours; + var m = minutes; + var s = seconds; + var total = this.asSeconds(); + + if (!total) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } + + return (total < 0 ? '-' : '') + + 'P' + + (Y ? Y + 'Y' : '') + + (M ? M + 'M' : '') + + (D ? D + 'D' : '') + + ((h || m || s) ? 'T' : '') + + (h ? h + 'H' : '') + + (m ? m + 'M' : '') + + (s ? s + 'S' : ''); + } + + var duration_prototype__proto = Duration.prototype; + + duration_prototype__proto.abs = duration_abs__abs; + duration_prototype__proto.add = duration_add_subtract__add; + duration_prototype__proto.subtract = duration_add_subtract__subtract; + duration_prototype__proto.as = as; + duration_prototype__proto.asMilliseconds = asMilliseconds; + duration_prototype__proto.asSeconds = asSeconds; + duration_prototype__proto.asMinutes = asMinutes; + duration_prototype__proto.asHours = asHours; + duration_prototype__proto.asDays = asDays; + duration_prototype__proto.asWeeks = asWeeks; + duration_prototype__proto.asMonths = asMonths; + duration_prototype__proto.asYears = asYears; + duration_prototype__proto.valueOf = duration_as__valueOf; + duration_prototype__proto._bubble = bubble; + duration_prototype__proto.get = duration_get__get; + duration_prototype__proto.milliseconds = milliseconds; + duration_prototype__proto.seconds = seconds; + duration_prototype__proto.minutes = minutes; + duration_prototype__proto.hours = hours; + duration_prototype__proto.days = days; + duration_prototype__proto.weeks = weeks; + duration_prototype__proto.months = months; + duration_prototype__proto.years = years; + duration_prototype__proto.humanize = humanize; + duration_prototype__proto.toISOString = iso_string__toISOString; + duration_prototype__proto.toString = iso_string__toISOString; + duration_prototype__proto.toJSON = iso_string__toISOString; + duration_prototype__proto.locale = locale; + duration_prototype__proto.localeData = localeData; + + // Deprecations + duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString); + duration_prototype__proto.lang = lang; + + // Side effect imports + + // FORMATTING + + addFormatToken('X', 0, 0, 'unix'); + addFormatToken('x', 0, 0, 'valueOf'); + + // PARSING + + addRegexToken('x', matchSigned); + addRegexToken('X', matchTimestamp); + addParseToken('X', function (input, array, config) { + config._d = new Date(parseFloat(input, 10) * 1000); + }); + addParseToken('x', function (input, array, config) { + config._d = new Date(toInt(input)); + }); + + // Side effect imports + + + utils_hooks__hooks.version = '2.11.2'; + + setHookCallback(local__createLocal); + + utils_hooks__hooks.fn = momentPrototype; + utils_hooks__hooks.min = min; + utils_hooks__hooks.max = max; + utils_hooks__hooks.now = now; + utils_hooks__hooks.utc = create_utc__createUTC; + utils_hooks__hooks.unix = moment__createUnix; + utils_hooks__hooks.months = lists__listMonths; + utils_hooks__hooks.isDate = isDate; + utils_hooks__hooks.locale = locale_locales__getSetGlobalLocale; + utils_hooks__hooks.invalid = valid__createInvalid; + utils_hooks__hooks.duration = create__createDuration; + utils_hooks__hooks.isMoment = isMoment; + utils_hooks__hooks.weekdays = lists__listWeekdays; + utils_hooks__hooks.parseZone = moment__createInZone; + utils_hooks__hooks.localeData = locale_locales__getLocale; + utils_hooks__hooks.isDuration = isDuration; + utils_hooks__hooks.monthsShort = lists__listMonthsShort; + utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin; + utils_hooks__hooks.defineLocale = defineLocale; + utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort; + utils_hooks__hooks.normalizeUnits = normalizeUnits; + utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold; + utils_hooks__hooks.prototype = momentPrototype; + + var _moment = utils_hooks__hooks; + + return _moment; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/af.js b/lib/javascripts/moment_locale/af.js index 2777e58e77f..1a96bf4735f 100644 --- a/lib/javascripts/moment_locale/af.js +++ b/lib/javascripts/moment_locale/af.js @@ -1,22 +1,25 @@ -// moment.js locale configuration -// locale : afrikaans (af) -// author : Werner Mollentze : https://github.com/wernerm +//! moment.js locale configuration +//! locale : afrikaans (af) +//! author : Werner Mollentze : https://github.com/wernerm -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('af', { - months : "Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember".split("_"), - monthsShort : "Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des".split("_"), - weekdays : "Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag".split("_"), - weekdaysShort : "Son_Maa_Din_Woe_Don_Vry_Sat".split("_"), - weekdaysMin : "So_Ma_Di_Wo_Do_Vr_Sa".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var af = moment.defineLocale('af', { + months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'), + weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'), + weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'), + meridiemParse: /vm|nm/i, + isPM : function (input) { + return /^nm$/i.test(input); + }, meridiem : function (hours, minutes, isLower) { if (hours < 12) { return isLower ? 'vm' : 'VM'; @@ -25,11 +28,12 @@ } }, longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { sameDay : '[Vandag om] LT', @@ -40,20 +44,21 @@ sameElse : 'L' }, relativeTime : { - future : "oor %s", - past : "%s gelede", - s : "'n paar sekondes", - m : "'n minuut", - mm : "%d minute", - h : "'n uur", - hh : "%d ure", - d : "'n dag", - dd : "%d dae", - M : "'n maand", - MM : "%d maande", - y : "'n jaar", - yy : "%d jaar" + future : 'oor %s', + past : '%s gelede', + s : '\'n paar sekondes', + m : '\'n minuut', + mm : '%d minute', + h : '\'n uur', + hh : '%d ure', + d : '\'n dag', + dd : '%d dae', + M : '\'n maand', + MM : '%d maande', + y : '\'n jaar', + yy : '%d jaar' }, + ordinalParse: /\d{1,2}(ste|de)/, ordinal : function (number) { return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter }, @@ -62,4 +67,7 @@ doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar. } }); -})); + + return af; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ar-ma.js b/lib/javascripts/moment_locale/ar-ma.js index c8add2ddeb7..9bddd5ac4f4 100644 --- a/lib/javascripts/moment_locale/ar-ma.js +++ b/lib/javascripts/moment_locale/ar-ma.js @@ -1,32 +1,32 @@ -// moment.js locale configuration -// locale : Moroccan Arabic (ar-ma) -// author : ElFadili Yassine : https://github.com/ElFadiliY -// author : Abdel Said : https://github.com/abdelsaid +//! moment.js locale configuration +//! locale : Moroccan Arabic (ar-ma) +//! author : ElFadili Yassine : https://github.com/ElFadiliY +//! author : Abdel Said : https://github.com/abdelsaid -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('ar-ma', { - months : "يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"), - monthsShort : "يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"), - weekdays : "الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"), - weekdaysShort : "احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"), - weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var ar_ma = moment.defineLocale('ar-ma', { + months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { - sameDay: "[اليوم على الساعة] LT", + sameDay: '[اليوم على الساعة] LT', nextDay: '[غدا على الساعة] LT', nextWeek: 'dddd [على الساعة] LT', lastDay: '[أمس على الساعة] LT', @@ -34,23 +34,26 @@ sameElse: 'L' }, relativeTime : { - future : "في %s", - past : "منذ %s", - s : "ثوان", - m : "دقيقة", - mm : "%d دقائق", - h : "ساعة", - hh : "%d ساعات", - d : "يوم", - dd : "%d أيام", - M : "شهر", - MM : "%d أشهر", - y : "سنة", - yy : "%d سنوات" + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' }, week : { dow : 6, // Saturday is the first day of the week. doy : 12 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return ar_ma; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ar-sa.js b/lib/javascripts/moment_locale/ar-sa.js index 64e209137ea..7541c52dc14 100644 --- a/lib/javascripts/moment_locale/ar-sa.js +++ b/lib/javascripts/moment_locale/ar-sa.js @@ -1,16 +1,15 @@ -// moment.js locale configuration -// locale : Arabic Saudi Arabia (ar-sa) -// author : Suhail Alkowaileet : https://github.com/xsoh +//! moment.js locale configuration +//! locale : Arabic Saudi Arabia (ar-sa) +//! author : Suhail Alkowaileet : https://github.com/xsoh + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var symbolMap = { '1': '١', '2': '٢', @@ -35,28 +34,33 @@ '٠': '0' }; - return moment.defineLocale('ar-sa', { - months : "يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"), - monthsShort : "يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"), - weekdays : "الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"), - weekdaysShort : "أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"), - weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"), + var ar_sa = moment.defineLocale('ar-sa', { + months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; }, meridiem : function (hour, minute, isLower) { if (hour < 12) { - return "ص"; + return 'ص'; } else { - return "م"; + return 'م'; } }, calendar : { - sameDay: "[اليوم على الساعة] LT", + sameDay: '[اليوم على الساعة] LT', nextDay: '[غدا على الساعة] LT', nextWeek: 'dddd [على الساعة] LT', lastDay: '[أمس على الساعة] LT', @@ -64,22 +68,22 @@ sameElse: 'L' }, relativeTime : { - future : "في %s", - past : "منذ %s", - s : "ثوان", - m : "دقيقة", - mm : "%d دقائق", - h : "ساعة", - hh : "%d ساعات", - d : "يوم", - dd : "%d أيام", - M : "شهر", - MM : "%d أشهر", - y : "سنة", - yy : "%d سنوات" + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' }, preparse: function (string) { - return string.replace(/[۰-۹]/g, function (match) { + return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { return numberMap[match]; }).replace(/،/g, ','); }, @@ -93,4 +97,7 @@ doy : 12 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return ar_sa; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ar-tn.js b/lib/javascripts/moment_locale/ar-tn.js new file mode 100644 index 00000000000..b4ee8fc6ded --- /dev/null +++ b/lib/javascripts/moment_locale/ar-tn.js @@ -0,0 +1,57 @@ +//! moment.js locale configuration +//! locale : Tunisian Arabic (ar-tn) + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var ar_tn = moment.defineLocale('ar-tn', { + months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'في %s', + past: 'منذ %s', + s: 'ثوان', + m: 'دقيقة', + mm: '%d دقائق', + h: 'ساعة', + hh: '%d ساعات', + d: 'يوم', + dd: '%d أيام', + M: 'شهر', + MM: '%d أشهر', + y: 'سنة', + yy: '%d سنوات' + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + return ar_tn; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ar.js b/lib/javascripts/moment_locale/ar.js index 2af64ee3a92..3613c594b40 100644 --- a/lib/javascripts/moment_locale/ar.js +++ b/lib/javascripts/moment_locale/ar.js @@ -1,17 +1,17 @@ -// moment.js locale configuration -// locale : Arabic (ar) -// author : Abdel Said : https://github.com/abdelsaid -// changes in months, weekdays : Ahmed Elkhatib +//! moment.js locale configuration +//! Locale: Arabic (ar) +//! Author: Abdel Said: https://github.com/abdelsaid +//! Changes in months, weekdays: Ahmed Elkhatib +//! Native plural forms: forabi https://github.com/forabi + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var symbolMap = { '1': '١', '2': '٢', @@ -34,53 +34,89 @@ '٨': '8', '٩': '9', '٠': '0' - }; + }, pluralForm = function (n) { + return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; + }, plurals = { + s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], + m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], + h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], + d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], + M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], + y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] + }, pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; + }, months = [ + 'كانون الثاني يناير', + 'شباط فبراير', + 'آذار مارس', + 'نيسان أبريل', + 'أيار مايو', + 'حزيران يونيو', + 'تموز يوليو', + 'آب أغسطس', + 'أيلول سبتمبر', + 'تشرين الأول أكتوبر', + 'تشرين الثاني نوفمبر', + 'كانون الأول ديسمبر' + ]; - return moment.defineLocale('ar', { - months : "يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول".split("_"), - monthsShort : "يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول".split("_"), - weekdays : "الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"), - weekdaysShort : "أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"), - weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"), + var ar = moment.defineLocale('ar', { + months : months, + monthsShort : months, + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/\u200FM/\u200FYYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; }, meridiem : function (hour, minute, isLower) { if (hour < 12) { - return "ص"; + return 'ص'; } else { - return "م"; + return 'م'; } }, calendar : { - sameDay: "[اليوم على الساعة] LT", - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', sameElse: 'L' }, relativeTime : { - future : "في %s", - past : "منذ %s", - s : "ثوان", - m : "دقيقة", - mm : "%d دقائق", - h : "ساعة", - hh : "%d ساعات", - d : "يوم", - dd : "%d أيام", - M : "شهر", - MM : "%d أشهر", - y : "سنة", - yy : "%d سنوات" + future : 'بعد %s', + past : 'منذ %s', + s : pluralize('s'), + m : pluralize('m'), + mm : pluralize('m'), + h : pluralize('h'), + hh : pluralize('h'), + d : pluralize('d'), + dd : pluralize('d'), + M : pluralize('M'), + MM : pluralize('M'), + y : pluralize('y'), + yy : pluralize('y') }, preparse: function (string) { - return string.replace(/[۰-۹]/g, function (match) { + return string.replace(/\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { return numberMap[match]; }).replace(/،/g, ','); }, @@ -94,4 +130,7 @@ doy : 12 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return ar; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/az.js b/lib/javascripts/moment_locale/az.js index a6a5aff964e..5ff9b088c49 100644 --- a/lib/javascripts/moment_locale/az.js +++ b/lib/javascripts/moment_locale/az.js @@ -1,53 +1,49 @@ -// moment.js locale configuration -// locale : azerbaijani (az) -// author : topchiyev : https://github.com/topchiyev +//! moment.js locale configuration +//! locale : azerbaijani (az) +//! author : topchiyev : https://github.com/topchiyev + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var suffixes = { - 1: "-inci", - 5: "-inci", - 8: "-inci", - 70: "-inci", - 80: "-inci", - - 2: "-nci", - 7: "-nci", - 20: "-nci", - 50: "-nci", - - 3: "-üncü", - 4: "-üncü", - 100: "-üncü", - - 6: "-ncı", - - 9: "-uncu", - 10: "-uncu", - 30: "-uncu", - - 60: "-ıncı", - 90: "-ıncı" + 1: '-inci', + 5: '-inci', + 8: '-inci', + 70: '-inci', + 80: '-inci', + 2: '-nci', + 7: '-nci', + 20: '-nci', + 50: '-nci', + 3: '-üncü', + 4: '-üncü', + 100: '-üncü', + 6: '-ncı', + 9: '-uncu', + 10: '-uncu', + 30: '-uncu', + 60: '-ıncı', + 90: '-ıncı' }; - return moment.defineLocale('az', { - months : "yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"), - monthsShort : "yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"), - weekdays : "Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə".split("_"), - weekdaysShort : "Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən".split("_"), - weekdaysMin : "Bz_BE_ÇA_Çə_CA_Cü_Şə".split("_"), + + var az = moment.defineLocale('az', { + months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'), + monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'), + weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'), + weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'), + weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { sameDay : '[bugün saat] LT', @@ -58,39 +54,43 @@ sameElse : 'L' }, relativeTime : { - future : "%s sonra", - past : "%s əvvəl", - s : "birneçə saniyyə", - m : "bir dəqiqə", - mm : "%d dəqiqə", - h : "bir saat", - hh : "%d saat", - d : "bir gün", - dd : "%d gün", - M : "bir ay", - MM : "%d ay", - y : "bir il", - yy : "%d il" + future : '%s sonra', + past : '%s əvvəl', + s : 'birneçə saniyyə', + m : 'bir dəqiqə', + mm : '%d dəqiqə', + h : 'bir saat', + hh : '%d saat', + d : 'bir gün', + dd : '%d gün', + M : 'bir ay', + MM : '%d ay', + y : 'bir il', + yy : '%d il' + }, + meridiemParse: /gecə|səhər|gündüz|axşam/, + isPM : function (input) { + return /^(gündüz|axşam)$/.test(input); }, meridiem : function (hour, minute, isLower) { if (hour < 4) { - return "gecə"; + return 'gecə'; } else if (hour < 12) { - return "səhər"; + return 'səhər'; } else if (hour < 17) { - return "gündüz"; + return 'gündüz'; } else { - return "axşam"; + return 'axşam'; } }, + ordinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/, ordinal : function (number) { if (number === 0) { // special case for zero - return number + "-ıncı"; + return number + '-ıncı'; } var a = number % 10, b = number % 100 - a, c = number >= 100 ? 100 : null; - return number + (suffixes[a] || suffixes[b] || suffixes[c]); }, week : { @@ -98,4 +98,7 @@ doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return az; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/be.js b/lib/javascripts/moment_locale/be.js index 6e0aef1b8d1..c6294b34f4d 100644 --- a/lib/javascripts/moment_locale/be.js +++ b/lib/javascripts/moment_locale/be.js @@ -1,23 +1,21 @@ -// moment.js locale configuration -// locale : belarusian (be) -// author : Dmitry Demidov : https://github.com/demidov91 -// author: Praleska: http://praleska.pro/ -// Author : Menelion Elensúle : https://github.com/Oire +//! moment.js locale configuration +//! locale : belarusian (be) +//! author : Dmitry Demidov : https://github.com/demidov91 +//! author: Praleska: http://praleska.pro/ +//! Author : Menelion Elensúle : https://github.com/Oire + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function plural(word, num) { var forms = word.split('_'); return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); } - function relativeTimeWithPlural(number, withoutSuffix, key) { var format = { 'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін', @@ -37,44 +35,26 @@ } } - function monthsCaseReplace(m, format) { - var months = { - 'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'), - 'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_') + var be = moment.defineLocale('be', { + months : { + format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'), + standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_') }, - - nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - } - - function weekdaysCaseReplace(m, format) { - var weekdays = { - 'nominative': 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), - 'accusative': 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_') - }, - - nounCase = (/\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/).test(format) ? - 'accusative' : - 'nominative'; - - return weekdays[nounCase][m.day()]; - } - - return moment.defineLocale('be', { - months : monthsCaseReplace, monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'), - weekdays : weekdaysCaseReplace, - weekdaysShort : "нд_пн_ат_ср_чц_пт_сб".split("_"), - weekdaysMin : "нд_пн_ат_ср_чц_пт_сб".split("_"), + weekdays : { + format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'), + standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), + isFormat: /\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/ + }, + weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY г.", - LLL : "D MMMM YYYY г., LT", - LLLL : "dddd, D MMMM YYYY г., LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY г.', + LLL : 'D MMMM YYYY г., HH:mm', + LLLL : 'dddd, D MMMM YYYY г., HH:mm' }, calendar : { sameDay: '[Сёння ў] LT', @@ -99,34 +79,36 @@ sameElse: 'L' }, relativeTime : { - future : "праз %s", - past : "%s таму", - s : "некалькі секунд", + future : 'праз %s', + past : '%s таму', + s : 'некалькі секунд', m : relativeTimeWithPlural, mm : relativeTimeWithPlural, h : relativeTimeWithPlural, hh : relativeTimeWithPlural, - d : "дзень", + d : 'дзень', dd : relativeTimeWithPlural, - M : "месяц", + M : 'месяц', MM : relativeTimeWithPlural, - y : "год", + y : 'год', yy : relativeTimeWithPlural }, - - + meridiemParse: /ночы|раніцы|дня|вечара/, + isPM : function (input) { + return /^(дня|вечара)$/.test(input); + }, meridiem : function (hour, minute, isLower) { if (hour < 4) { - return "ночы"; + return 'ночы'; } else if (hour < 12) { - return "раніцы"; + return 'раніцы'; } else if (hour < 17) { - return "дня"; + return 'дня'; } else { - return "вечара"; + return 'вечара'; } }, - + ordinalParse: /\d{1,2}-(і|ы|га)/, ordinal: function (number, period) { switch (period) { case 'M': @@ -141,10 +123,12 @@ return number; } }, - week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return be; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/bg.js b/lib/javascripts/moment_locale/bg.js index b8a8c326ad0..169e1238a19 100644 --- a/lib/javascripts/moment_locale/bg.js +++ b/lib/javascripts/moment_locale/bg.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : bulgarian (bg) -// author : Krasen Borisov : https://github.com/kraz +//! moment.js locale configuration +//! locale : bulgarian (bg) +//! author : Krasen Borisov : https://github.com/kraz -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('bg', { - months : "януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"), - monthsShort : "янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"), - weekdays : "неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"), - weekdaysShort : "нед_пон_вто_сря_чет_пет_съб".split("_"), - weekdaysMin : "нд_пн_вт_ср_чт_пт_сб".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var bg = moment.defineLocale('bg', { + months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'), + monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'), + weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'), + weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'), + weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), longDateFormat : { - LT : "H:mm", - L : "D.MM.YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'D.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' }, calendar : { sameDay : '[Днес в] LT', @@ -45,20 +45,21 @@ sameElse : 'L' }, relativeTime : { - future : "след %s", - past : "преди %s", - s : "няколко секунди", - m : "минута", - mm : "%d минути", - h : "час", - hh : "%d часа", - d : "ден", - dd : "%d дни", - M : "месец", - MM : "%d месеца", - y : "година", - yy : "%d години" + future : 'след %s', + past : 'преди %s', + s : 'няколко секунди', + m : 'минута', + mm : '%d минути', + h : 'час', + hh : '%d часа', + d : 'ден', + dd : '%d дни', + M : 'месец', + MM : '%d месеца', + y : 'година', + yy : '%d години' }, + ordinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, ordinal : function (number) { var lastDigit = number % 10, last2Digits = number % 100; @@ -83,4 +84,7 @@ doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return bg; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/bn.js b/lib/javascripts/moment_locale/bn.js index 8ceb8eb0a4f..4eca5ee9ebc 100644 --- a/lib/javascripts/moment_locale/bn.js +++ b/lib/javascripts/moment_locale/bn.js @@ -1,16 +1,15 @@ -// moment.js locale configuration -// locale : Bengali (bn) -// author : Kaushik Gandhi : https://github.com/kaushikgandhi +//! moment.js locale configuration +//! locale : Bengali (bn) +//! author : Kaushik Gandhi : https://github.com/kaushikgandhi + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var symbolMap = { '1': '১', '2': '২', @@ -36,18 +35,19 @@ '০': '0' }; - return moment.defineLocale('bn', { - months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split("_"), - monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split("_"), - weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split("_"), - weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split("_"), - weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split("_"), + var bn = moment.defineLocale('bn', { + months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'), + monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split('_'), + weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রবার_শনিবার'.split('_'), + weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্র_শনি'.split('_'), + weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split('_'), longDateFormat : { - LT : "A h:mm সময়", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY, LT", - LLLL : "dddd, D MMMM YYYY, LT" + LT : 'A h:mm সময়', + LTS : 'A h:mm:ss সময়', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm সময়', + LLLL : 'dddd, D MMMM YYYY, A h:mm সময়' }, calendar : { sameDay : '[আজ] LT', @@ -58,19 +58,19 @@ sameElse : 'L' }, relativeTime : { - future : "%s পরে", - past : "%s আগে", - s : "কএক সেকেন্ড", - m : "এক মিনিট", - mm : "%d মিনিট", - h : "এক ঘন্টা", - hh : "%d ঘন্টা", - d : "এক দিন", - dd : "%d দিন", - M : "এক মাস", - MM : "%d মাস", - y : "এক বছর", - yy : "%d বছর" + future : '%s পরে', + past : '%s আগে', + s : 'কয়েক সেকেন্ড', + m : 'এক মিনিট', + mm : '%d মিনিট', + h : 'এক ঘন্টা', + hh : '%d ঘন্টা', + d : 'এক দিন', + dd : '%d দিন', + M : 'এক মাস', + MM : '%d মাস', + y : 'এক বছর', + yy : '%d বছর' }, preparse: function (string) { return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) { @@ -82,20 +82,24 @@ return symbolMap[match]; }); }, + meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/, + isPM: function (input) { + return /^(দুপুর|বিকাল|রাত)$/.test(input); + }, //Bengali is a vast language its spoken //in different forms in various parts of the world. //I have just generalized with most common one used meridiem : function (hour, minute, isLower) { if (hour < 4) { - return "রাত"; + return 'রাত'; } else if (hour < 10) { - return "শকাল"; + return 'সকাল'; } else if (hour < 17) { - return "দুপুর"; + return 'দুপুর'; } else if (hour < 20) { - return "বিকেল"; + return 'বিকাল'; } else { - return "রাত"; + return 'রাত'; } }, week : { @@ -103,4 +107,7 @@ doy : 6 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return bn; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/bo.js b/lib/javascripts/moment_locale/bo.js index f1567abf5ee..3ab33896f0c 100644 --- a/lib/javascripts/moment_locale/bo.js +++ b/lib/javascripts/moment_locale/bo.js @@ -1,16 +1,15 @@ -// moment.js locale configuration -// locale : tibetan (bo) -// author : Thupten N. Chakrishar : https://github.com/vajradog +//! moment.js locale configuration +//! locale : tibetan (bo) +//! author : Thupten N. Chakrishar : https://github.com/vajradog + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var symbolMap = { '1': '༡', '2': '༢', @@ -36,18 +35,19 @@ '༠': '0' }; - return moment.defineLocale('bo', { - months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split("_"), - monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split("_"), - weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split("_"), - weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split("_"), - weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split("_"), + var bo = moment.defineLocale('bo', { + months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), + monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), + weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'), + weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), + weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), longDateFormat : { - LT : "A h:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY, LT", - LLLL : "dddd, D MMMM YYYY, LT" + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' }, calendar : { sameDay : '[དི་རིང] LT', @@ -58,19 +58,19 @@ sameElse : 'L' }, relativeTime : { - future : "%s ལ་", - past : "%s སྔན་ལ", - s : "ལམ་སང", - m : "སྐར་མ་གཅིག", - mm : "%d སྐར་མ", - h : "ཆུ་ཚོད་གཅིག", - hh : "%d ཆུ་ཚོད", - d : "ཉིན་གཅིག", - dd : "%d ཉིན་", - M : "ཟླ་བ་གཅིག", - MM : "%d ཟླ་བ", - y : "ལོ་གཅིག", - yy : "%d ལོ" + future : '%s ལ་', + past : '%s སྔན་ལ', + s : 'ལམ་སང', + m : 'སྐར་མ་གཅིག', + mm : '%d སྐར་མ', + h : 'ཆུ་ཚོད་གཅིག', + hh : '%d ཆུ་ཚོད', + d : 'ཉིན་གཅིག', + dd : '%d ཉིན་', + M : 'ཟླ་བ་གཅིག', + MM : '%d ཟླ་བ', + y : 'ལོ་གཅིག', + yy : '%d ལོ' }, preparse: function (string) { return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) { @@ -82,17 +82,21 @@ return symbolMap[match]; }); }, + meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/, + isPM: function (input) { + return /^(ཉིན་གུང|དགོང་དག|མཚན་མོ)$/.test(input); + }, meridiem : function (hour, minute, isLower) { if (hour < 4) { - return "མཚན་མོ"; + return 'མཚན་མོ'; } else if (hour < 10) { - return "ཞོགས་ཀས"; + return 'ཞོགས་ཀས'; } else if (hour < 17) { - return "ཉིན་གུང"; + return 'ཉིན་གུང'; } else if (hour < 20) { - return "དགོང་དག"; + return 'དགོང་དག'; } else { - return "མཚན་མོ"; + return 'མཚན་མོ'; } }, week : { @@ -100,4 +104,7 @@ doy : 6 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return bo; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/br.js b/lib/javascripts/moment_locale/br.js index fb11fe1e579..2896cfb6a43 100644 --- a/lib/javascripts/moment_locale/br.js +++ b/lib/javascripts/moment_locale/br.js @@ -1,25 +1,23 @@ -// moment.js locale configuration -// locale : breton (br) -// author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou +//! moment.js locale configuration +//! locale : breton (br) +//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function relativeTimeWithMutation(number, withoutSuffix, key) { var format = { - 'mm': "munutenn", - 'MM': "miz", - 'dd': "devezh" + 'mm': 'munutenn', + 'MM': 'miz', + 'dd': 'devezh' }; return number + ' ' + mutation(format[key], number); } - function specialMutationForYears(number) { switch (lastNumber(number)) { case 1: @@ -32,21 +30,18 @@ return number + ' vloaz'; } } - function lastNumber(number) { if (number > 9) { return lastNumber(number % 10); } return number; } - function mutation(text, number) { if (number === 2) { return softMutation(text); } return text; } - function softMutation(text) { var mutationTable = { 'm': 'v', @@ -59,18 +54,19 @@ return mutationTable[text.charAt(0)] + text.substring(1); } - return moment.defineLocale('br', { - months : "Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"), - monthsShort : "Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"), - weekdays : "Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"), - weekdaysShort : "Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"), - weekdaysMin : "Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"), + var br = moment.defineLocale('br', { + months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'), + monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'), + weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'), + weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'), + weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'), longDateFormat : { - LT : "h[e]mm A", - L : "DD/MM/YYYY", - LL : "D [a viz] MMMM YYYY", - LLL : "D [a viz] MMMM YYYY LT", - LLLL : "dddd, D [a viz] MMMM YYYY LT" + LT : 'h[e]mm A', + LTS : 'h[e]mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D [a viz] MMMM YYYY', + LLL : 'D [a viz] MMMM YYYY h[e]mm A', + LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A' }, calendar : { sameDay : '[Hiziv da] LT', @@ -81,20 +77,21 @@ sameElse : 'L' }, relativeTime : { - future : "a-benn %s", - past : "%s 'zo", - s : "un nebeud segondennoù", - m : "ur vunutenn", + future : 'a-benn %s', + past : '%s \'zo', + s : 'un nebeud segondennoù', + m : 'ur vunutenn', mm : relativeTimeWithMutation, - h : "un eur", - hh : "%d eur", - d : "un devezh", + h : 'un eur', + hh : '%d eur', + d : 'un devezh', dd : relativeTimeWithMutation, - M : "ur miz", + M : 'ur miz', MM : relativeTimeWithMutation, - y : "ur bloaz", + y : 'ur bloaz', yy : specialMutationForYears }, + ordinalParse: /\d{1,2}(añ|vet)/, ordinal : function (number) { var output = (number === 1) ? 'añ' : 'vet'; return number + output; @@ -104,4 +101,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return br; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/bs.js b/lib/javascripts/moment_locale/bs.js index d69015abbef..e0b3dae21eb 100644 --- a/lib/javascripts/moment_locale/bs.js +++ b/lib/javascripts/moment_locale/bs.js @@ -1,19 +1,18 @@ -// moment.js locale configuration -// locale : bosnian (bs) -// author : Nedim Cholich : https://github.com/frontyard -// based on (hr) translation by Bojan Marković +//! moment.js locale configuration +//! locale : bosnian (bs) +//! author : Nedim Cholich : https://github.com/frontyard +//! based on (hr) translation by Bojan Marković + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function translate(number, withoutSuffix, key) { - var result = number + " "; + var result = number + ' '; switch (key) { case 'm': return withoutSuffix ? 'jedna minuta' : 'jedne minute'; @@ -65,23 +64,23 @@ } } - return moment.defineLocale('bs', { - months : "januar_februar_mart_april_maj_juni_juli_avgust_septembar_oktobar_novembar_decembar".split("_"), - monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"), - weekdays : "nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"), - weekdaysShort : "ned._pon._uto._sri._čet._pet._sub.".split("_"), - weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"), + var bs = moment.defineLocale('bs', { + months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'), + weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), longDateFormat : { - LT : "H:mm", - L : "DD. MM. YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd, D. MMMM YYYY LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD. MM. YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' }, calendar : { sameDay : '[danas u] LT', nextDay : '[sutra u] LT', - nextWeek : function () { switch (this.day()) { case 0: @@ -115,24 +114,28 @@ sameElse : 'L' }, relativeTime : { - future : "za %s", - past : "prije %s", - s : "par sekundi", + future : 'za %s', + past : 'prije %s', + s : 'par sekundi', m : translate, mm : translate, h : translate, hh : translate, - d : "dan", + d : 'dan', dd : translate, - M : "mjesec", + M : 'mjesec', MM : translate, - y : "godinu", + y : 'godinu', yy : translate }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return bs; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ca.js b/lib/javascripts/moment_locale/ca.js index 932c1cbda74..15f75fe99c9 100644 --- a/lib/javascripts/moment_locale/ca.js +++ b/lib/javascripts/moment_locale/ca.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : catalan (ca) -// author : Juan G. Hurtado : https://github.com/juanghurtado +//! moment.js locale configuration +//! locale : catalan (ca) +//! author : Juan G. Hurtado : https://github.com/juanghurtado -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('ca', { - months : "gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"), - monthsShort : "gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"), - weekdays : "diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"), - weekdaysShort : "dg._dl._dt._dc._dj._dv._ds.".split("_"), - weekdaysMin : "Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var ca = moment.defineLocale('ca', { + months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'), + monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'), + weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'), + weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'), + weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'), longDateFormat : { - LT : "H:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd D MMMM YYYY H:mm' }, calendar : { sameDay : function () { @@ -43,24 +43,37 @@ sameElse : 'L' }, relativeTime : { - future : "en %s", - past : "fa %s", - s : "uns segons", - m : "un minut", - mm : "%d minuts", - h : "una hora", - hh : "%d hores", - d : "un dia", - dd : "%d dies", - M : "un mes", - MM : "%d mesos", - y : "un any", - yy : "%d anys" + future : 'en %s', + past : 'fa %s', + s : 'uns segons', + m : 'un minut', + mm : '%d minuts', + h : 'una hora', + hh : '%d hores', + d : 'un dia', + dd : '%d dies', + M : 'un mes', + MM : '%d mesos', + y : 'un any', + yy : '%d anys' + }, + ordinalParse: /\d{1,2}(r|n|t|è|a)/, + ordinal : function (number, period) { + var output = (number === 1) ? 'r' : + (number === 2) ? 'n' : + (number === 3) ? 'r' : + (number === 4) ? 't' : 'è'; + if (period === 'w' || period === 'W') { + output = 'a'; + } + return number + output; }, - ordinal : '%dº', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return ca; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/cs.js b/lib/javascripts/moment_locale/cs.js index 085bba06f4b..5854f70e2e1 100644 --- a/lib/javascripts/moment_locale/cs.js +++ b/lib/javascripts/moment_locale/cs.js @@ -1,25 +1,22 @@ -// moment.js locale configuration -// locale : czech (cs) -// author : petrbela : https://github.com/petrbela +//! moment.js locale configuration +//! locale : czech (cs) +//! author : petrbela : https://github.com/petrbela -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - var months = "leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"), - monthsShort = "led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_"); +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'), + monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'); function plural(n) { return (n > 1) && (n < 5) && (~~(n / 10) !== 1); } - function translate(number, withoutSuffix, key, isFuture) { - var result = number + " "; + var result = number + ' '; switch (key) { case 's': // a few seconds / in a few seconds / a few seconds ago return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami'; @@ -71,7 +68,7 @@ } } - return moment.defineLocale('cs', { + var cs = moment.defineLocale('cs', { months : months, monthsShort : monthsShort, monthsParse : (function (months, monthsShort) { @@ -82,18 +79,33 @@ } return _monthsParse; }(months, monthsShort)), - weekdays : "neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"), - weekdaysShort : "ne_po_út_st_čt_pá_so".split("_"), - weekdaysMin : "ne_po_út_st_čt_pá_so".split("_"), + shortMonthsParse : (function (monthsShort) { + var i, _shortMonthsParse = []; + for (i = 0; i < 12; i++) { + _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i'); + } + return _shortMonthsParse; + }(monthsShort)), + longMonthsParse : (function (months) { + var i, _longMonthsParse = []; + for (i = 0; i < 12; i++) { + _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i'); + } + return _longMonthsParse; + }(months)), + weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'), + weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'), + weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'), longDateFormat : { - LT: "H.mm", - L : "DD. MM. YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd D. MMMM YYYY LT" + LT: 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd D. MMMM YYYY H:mm' }, calendar : { - sameDay: "[dnes v] LT", + sameDay: '[dnes v] LT', nextDay: '[zítra v] LT', nextWeek: function () { switch (this.day()) { @@ -129,11 +141,11 @@ return '[minulou sobotu v] LT'; } }, - sameElse: "L" + sameElse: 'L' }, relativeTime : { - future : "za %s", - past : "před %s", + future : 'za %s', + past : 'před %s', s : translate, m : translate, mm : translate, @@ -146,10 +158,14 @@ y : translate, yy : translate }, + ordinalParse : /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return cs; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/cv.js b/lib/javascripts/moment_locale/cv.js index 0a290d8fafa..a1d87e18461 100644 --- a/lib/javascripts/moment_locale/cv.js +++ b/lib/javascripts/moment_locale/cv.js @@ -1,59 +1,63 @@ -// moment.js locale configuration -// locale : chuvash (cv) -// author : Anatoly Mironov : https://github.com/mirontoli +//! moment.js locale configuration +//! locale : chuvash (cv) +//! author : Anatoly Mironov : https://github.com/mirontoli -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('cv', { - months : "кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав".split("_"), - monthsShort : "кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш".split("_"), - weekdays : "вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун".split("_"), - weekdaysShort : "выр_тун_ытл_юн_кĕç_эрн_шăм".split("_"), - weekdaysMin : "вр_тн_ыт_юн_кç_эр_шм".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var cv = moment.defineLocale('cv', { + months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'), + monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'), + weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'), + weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'), + weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD-MM-YYYY", - LL : "YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]", - LLL : "YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT", - LLLL : "dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]', + LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm', + LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm' }, calendar : { sameDay: '[Паян] LT [сехетре]', nextDay: '[Ыран] LT [сехетре]', - lastDay: '[Ĕнер] LT [сехетре]', - nextWeek: '[Çитес] dddd LT [сехетре]', - lastWeek: '[Иртнĕ] dddd LT [сехетре]', + lastDay: '[Ӗнер] LT [сехетре]', + nextWeek: '[Ҫитес] dddd LT [сехетре]', + lastWeek: '[Иртнӗ] dddd LT [сехетре]', sameElse: 'L' }, relativeTime : { future : function (output) { - var affix = /сехет$/i.exec(output) ? "рен" : /çул$/i.exec(output) ? "тан" : "ран"; + var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран'; return output + affix; }, - past : "%s каялла", - s : "пĕр-ик çеккунт", - m : "пĕр минут", - mm : "%d минут", - h : "пĕр сехет", - hh : "%d сехет", - d : "пĕр кун", - dd : "%d кун", - M : "пĕр уйăх", - MM : "%d уйăх", - y : "пĕр çул", - yy : "%d çул" + past : '%s каялла', + s : 'пӗр-ик ҫеккунт', + m : 'пӗр минут', + mm : '%d минут', + h : 'пӗр сехет', + hh : '%d сехет', + d : 'пӗр кун', + dd : '%d кун', + M : 'пӗр уйӑх', + MM : '%d уйӑх', + y : 'пӗр ҫул', + yy : '%d ҫул' }, - ordinal : '%d-мĕш', + ordinalParse: /\d{1,2}-мӗш/, + ordinal : '%d-мӗш', week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return cv; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/cy.js b/lib/javascripts/moment_locale/cy.js index 6231a52e51d..64dfe43f50b 100644 --- a/lib/javascripts/moment_locale/cy.js +++ b/lib/javascripts/moment_locale/cy.js @@ -1,29 +1,29 @@ -// moment.js locale configuration -// locale : Welsh (cy) -// author : Robert Allen +//! moment.js locale configuration +//! locale : Welsh (cy) +//! author : Robert Allen -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale("cy", { - months: "Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"), - monthsShort: "Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"), - weekdays: "Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"), - weekdaysShort: "Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"), - weekdaysMin: "Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var cy = moment.defineLocale('cy', { + months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'), + monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'), + weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'), + weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'), + weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'), // time formats are the same as en-gb longDateFormat: { - LT: "HH:mm", - L: "DD/MM/YYYY", - LL: "D MMMM YYYY", - LLL: "D MMMM YYYY LT", - LLLL: "dddd, D MMMM YYYY LT" + LT: 'HH:mm', + LTS : 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' }, calendar: { sameDay: '[Heddiw am] LT', @@ -34,20 +34,21 @@ sameElse: 'L' }, relativeTime: { - future: "mewn %s", - past: "%s yn ôl", - s: "ychydig eiliadau", - m: "munud", - mm: "%d munud", - h: "awr", - hh: "%d awr", - d: "diwrnod", - dd: "%d diwrnod", - M: "mis", - MM: "%d mis", - y: "blwyddyn", - yy: "%d flynedd" + future: 'mewn %s', + past: '%s yn ôl', + s: 'ychydig eiliadau', + m: 'munud', + mm: '%d munud', + h: 'awr', + hh: '%d awr', + d: 'diwrnod', + dd: '%d diwrnod', + M: 'mis', + MM: '%d mis', + y: 'blwyddyn', + yy: '%d flynedd' }, + ordinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/, // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh ordinal: function (number) { var b = number, @@ -56,7 +57,6 @@ '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed ]; - if (b > 20) { if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) { output = 'fed'; // not 30ain, 70ain or 90ain @@ -66,7 +66,6 @@ } else if (b > 0) { output = lookup[b]; } - return number + output; }, week : { @@ -74,4 +73,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return cy; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/da.js b/lib/javascripts/moment_locale/da.js index 9c1c68fab1d..70b4c0da43f 100644 --- a/lib/javascripts/moment_locale/da.js +++ b/lib/javascripts/moment_locale/da.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : danish (da) -// author : Ulrik Nielsen : https://github.com/mrbase +//! moment.js locale configuration +//! locale : danish (da) +//! author : Ulrik Nielsen : https://github.com/mrbase -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('da', { - months : "januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"), - monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"), - weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"), - weekdaysShort : "søn_man_tir_ons_tor_fre_lør".split("_"), - weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var da = moment.defineLocale('da', { + months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'), + weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd [d.] D. MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd [d.] D. MMMM YYYY HH:mm' }, calendar : { sameDay : '[I dag kl.] LT', @@ -33,24 +33,28 @@ sameElse : 'L' }, relativeTime : { - future : "om %s", - past : "%s siden", - s : "få sekunder", - m : "et minut", - mm : "%d minutter", - h : "en time", - hh : "%d timer", - d : "en dag", - dd : "%d dage", - M : "en måned", - MM : "%d måneder", - y : "et år", - yy : "%d år" + future : 'om %s', + past : '%s siden', + s : 'få sekunder', + m : 'et minut', + mm : '%d minutter', + h : 'en time', + hh : '%d timer', + d : 'en dag', + dd : '%d dage', + M : 'en måned', + MM : '%d måneder', + y : 'et år', + yy : '%d år' }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return da; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/de-at.js b/lib/javascripts/moment_locale/de-at.js index 48d1b88135b..20da9cf613c 100644 --- a/lib/javascripts/moment_locale/de-at.js +++ b/lib/javascripts/moment_locale/de-at.js @@ -1,18 +1,18 @@ -// moment.js locale configuration -// locale : austrian german (de-at) -// author : lluchs : https://github.com/lluchs -// author: Menelion Elensúle: https://github.com/Oire -// author : Martin Groller : https://github.com/MadMG +//! moment.js locale configuration +//! locale : austrian german (de-at) +//! author : lluchs : https://github.com/lluchs +//! author: Menelion Elensúle: https://github.com/Oire +//! author : Martin Groller : https://github.com/MadMG +//! author : Mikolaj Dadela : https://github.com/mik01aj + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function processRelativeTime(number, withoutSuffix, key, isFuture) { var format = { 'm': ['eine Minute', 'einer Minute'], @@ -27,35 +27,36 @@ return withoutSuffix ? format[key][0] : format[key][1]; } - return moment.defineLocale('de-at', { - months : "Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"), - monthsShort : "Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"), - weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"), - weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"), - weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"), + var de_at = moment.defineLocale('de-at', { + months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), longDateFormat : { - LT: "HH:mm [Uhr]", - L : "DD.MM.YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd, D. MMMM YYYY LT" + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' }, calendar : { - sameDay: "[Heute um] LT", - sameElse: "L", - nextDay: '[Morgen um] LT', - nextWeek: 'dddd [um] LT', - lastDay: '[Gestern um] LT', - lastWeek: '[letzten] dddd [um] LT' + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' }, relativeTime : { - future : "in %s", - past : "vor %s", - s : "ein paar Sekunden", + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', m : processRelativeTime, - mm : "%d Minuten", + mm : '%d Minuten', h : processRelativeTime, - hh : "%d Stunden", + hh : '%d Stunden', d : processRelativeTime, dd : processRelativeTime, M : processRelativeTime, @@ -63,10 +64,14 @@ y : processRelativeTime, yy : processRelativeTime }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return de_at; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/de.js b/lib/javascripts/moment_locale/de.js index 0c389f92f4d..41c81a1af63 100644 --- a/lib/javascripts/moment_locale/de.js +++ b/lib/javascripts/moment_locale/de.js @@ -1,17 +1,17 @@ -// moment.js locale configuration -// locale : german (de) -// author : lluchs : https://github.com/lluchs -// author: Menelion Elensúle: https://github.com/Oire +//! moment.js locale configuration +//! locale : german (de) +//! author : lluchs : https://github.com/lluchs +//! author: Menelion Elensúle: https://github.com/Oire +//! author : Mikolaj Dadela : https://github.com/mik01aj + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function processRelativeTime(number, withoutSuffix, key, isFuture) { var format = { 'm': ['eine Minute', 'einer Minute'], @@ -26,35 +26,36 @@ return withoutSuffix ? format[key][0] : format[key][1]; } - return moment.defineLocale('de', { - months : "Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"), - monthsShort : "Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"), - weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"), - weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"), - weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"), + var de = moment.defineLocale('de', { + months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), longDateFormat : { - LT: "HH:mm [Uhr]", - L : "DD.MM.YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd, D. MMMM YYYY LT" + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' }, calendar : { - sameDay: "[Heute um] LT", - sameElse: "L", - nextDay: '[Morgen um] LT', - nextWeek: 'dddd [um] LT', - lastDay: '[Gestern um] LT', - lastWeek: '[letzten] dddd [um] LT' + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' }, relativeTime : { - future : "in %s", - past : "vor %s", - s : "ein paar Sekunden", + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', m : processRelativeTime, - mm : "%d Minuten", + mm : '%d Minuten', h : processRelativeTime, - hh : "%d Stunden", + hh : '%d Stunden', d : processRelativeTime, dd : processRelativeTime, M : processRelativeTime, @@ -62,10 +63,14 @@ y : processRelativeTime, yy : processRelativeTime }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return de; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/dv.js b/lib/javascripts/moment_locale/dv.js new file mode 100644 index 00000000000..5fc59b668b7 --- /dev/null +++ b/lib/javascripts/moment_locale/dv.js @@ -0,0 +1,99 @@ +//! moment.js locale configuration +//! locale : dhivehi (dv) +//! author : Jawish Hameed : https://github.com/jawish + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var months = [ + 'ޖެނުއަރީ', + 'ފެބްރުއަރީ', + 'މާރިޗު', + 'އޭޕްރީލު', + 'މޭ', + 'ޖޫން', + 'ޖުލައި', + 'އޯގަސްޓު', + 'ސެޕްޓެމްބަރު', + 'އޮކްޓޯބަރު', + 'ނޮވެމްބަރު', + 'ޑިސެމްބަރު' + ], weekdays = [ + 'އާދިއްތަ', + 'ހޯމަ', + 'އަންގާރަ', + 'ބުދަ', + 'ބުރާސްފަތި', + 'ހުކުރު', + 'ހޮނިހިރު' + ]; + + var dv = moment.defineLocale('dv', { + months : months, + monthsShort : months, + weekdays : weekdays, + weekdaysShort : weekdays, + weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'), + longDateFormat : { + + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/M/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /މކ|މފ/, + isPM : function (input) { + return '' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'މކ'; + } else { + return 'މފ'; + } + }, + calendar : { + sameDay : '[މިއަދު] LT', + nextDay : '[މާދަމާ] LT', + nextWeek : 'dddd LT', + lastDay : '[އިއްޔެ] LT', + lastWeek : '[ފާއިތުވި] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ތެރޭގައި %s', + past : 'ކުރިން %s', + s : 'ސިކުންތުކޮޅެއް', + m : 'މިނިޓެއް', + mm : 'މިނިޓު %d', + h : 'ގަޑިއިރެއް', + hh : 'ގަޑިއިރު %d', + d : 'ދުވަހެއް', + dd : 'ދުވަސް %d', + M : 'މަހެއް', + MM : 'މަސް %d', + y : 'އަހަރެއް', + yy : 'އަހަރު %d' + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week : { + dow : 7, // Sunday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + return dv; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/el.js b/lib/javascripts/moment_locale/el.js index 7f31628d360..d86666dcaf6 100644 --- a/lib/javascripts/moment_locale/el.js +++ b/lib/javascripts/moment_locale/el.js @@ -1,30 +1,33 @@ -// moment.js locale configuration -// locale : modern greek (el) -// author : Aggelos Karalias : https://github.com/mehiel +//! moment.js locale configuration +//! locale : modern greek (el) +//! author : Aggelos Karalias : https://github.com/mehiel -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; } -}(function (moment) { - return moment.defineLocale('el', { - monthsNominativeEl : "Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"), - monthsGenitiveEl : "Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"), + + + var el = moment.defineLocale('el', { + monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'), + monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'), months : function (momentToFormat, format) { - if (/D/.test(format.substring(0, format.indexOf("MMMM")))) { // if there is a day number before 'MMMM' + if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM' return this._monthsGenitiveEl[momentToFormat.month()]; } else { return this._monthsNominativeEl[momentToFormat.month()]; } }, - monthsShort : "Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"), - weekdays : "Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"), - weekdaysShort : "Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"), - weekdaysMin : "Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"), + monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'), + weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'), + weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'), + weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'), meridiem : function (hours, minutes, isLower) { if (hours > 11) { return isLower ? 'μμ' : 'ΜΜ'; @@ -32,12 +35,17 @@ return isLower ? 'πμ' : 'ΠΜ'; } }, + isPM : function (input) { + return ((input + '').toLowerCase()[0] === 'μ'); + }, + meridiemParse : /[ΠΜ]\.?Μ?\.?/i, longDateFormat : { - LT : "h:mm A", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' }, calendarEl : { sameDay : '[Σήμερα {}] LT', @@ -57,34 +65,34 @@ calendar : function (key, mom) { var output = this._calendarEl[key], hours = mom && mom.hours(); - - if (typeof output === 'function') { + if (isFunction(output)) { output = output.apply(mom); } - - return output.replace("{}", (hours % 12 === 1 ? "στη" : "στις")); + return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις')); }, relativeTime : { - future : "σε %s", - past : "%s πριν", - s : "δευτερόλεπτα", - m : "ένα λεπτό", - mm : "%d λεπτά", - h : "μία ώρα", - hh : "%d ώρες", - d : "μία μέρα", - dd : "%d μέρες", - M : "ένας μήνας", - MM : "%d μήνες", - y : "ένας χρόνος", - yy : "%d χρόνια" - }, - ordinal : function (number) { - return number + 'η'; + future : 'σε %s', + past : '%s πριν', + s : 'λίγα δευτερόλεπτα', + m : 'ένα λεπτό', + mm : '%d λεπτά', + h : 'μία ώρα', + hh : '%d ώρες', + d : 'μία μέρα', + dd : '%d μέρες', + M : 'ένας μήνας', + MM : '%d μήνες', + y : 'ένας χρόνος', + yy : '%d χρόνια' }, + ordinalParse: /\d{1,2}η/, + ordinal: '%dη', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4st is the first week of the year. } }); -})); + + return el; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/en-au.js b/lib/javascripts/moment_locale/en-au.js index 852ecc9f033..58608c18345 100644 --- a/lib/javascripts/moment_locale/en-au.js +++ b/lib/javascripts/moment_locale/en-au.js @@ -1,27 +1,27 @@ -// moment.js locale configuration -// locale : australian english (en-au) +//! moment.js locale configuration +//! locale : australian english (en-au) -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('en-au', { - months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), - monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), - weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), - weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), - weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var en_au = moment.defineLocale('en-au', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), longDateFormat : { - LT : "h:mm A", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' }, calendar : { sameDay : '[Today at] LT', @@ -32,20 +32,21 @@ sameElse : 'L' }, relativeTime : { - future : "in %s", - past : "%s ago", - s : "a few seconds", - m : "a minute", - mm : "%d minutes", - h : "an hour", - hh : "%d hours", - d : "a day", - dd : "%d days", - M : "a month", - MM : "%d months", - y : "a year", - yy : "%d years" + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' }, + ordinalParse: /\d{1,2}(st|nd|rd|th)/, ordinal : function (number) { var b = number % 10, output = (~~(number % 100 / 10) === 1) ? 'th' : @@ -59,4 +60,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return en_au; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/en-ca.js b/lib/javascripts/moment_locale/en-ca.js index ce253a83355..f0ee032e624 100644 --- a/lib/javascripts/moment_locale/en-ca.js +++ b/lib/javascripts/moment_locale/en-ca.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : canadian english (en-ca) -// author : Jonathan Abourbih : https://github.com/jonbca +//! moment.js locale configuration +//! locale : canadian english (en-ca) +//! author : Jonathan Abourbih : https://github.com/jonbca -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('en-ca', { - months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), - monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), - weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), - weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), - weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var en_ca = moment.defineLocale('en-ca', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), longDateFormat : { - LT : "h:mm A", - L : "YYYY-MM-DD", - LL : "D MMMM, YYYY", - LLL : "D MMMM, YYYY LT", - LLLL : "dddd, D MMMM, YYYY LT" + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'YYYY-MM-DD', + LL : 'D MMMM, YYYY', + LLL : 'D MMMM, YYYY h:mm A', + LLLL : 'dddd, D MMMM, YYYY h:mm A' }, calendar : { sameDay : '[Today at] LT', @@ -33,20 +33,21 @@ sameElse : 'L' }, relativeTime : { - future : "in %s", - past : "%s ago", - s : "a few seconds", - m : "a minute", - mm : "%d minutes", - h : "an hour", - hh : "%d hours", - d : "a day", - dd : "%d days", - M : "a month", - MM : "%d months", - y : "a year", - yy : "%d years" + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' }, + ordinalParse: /\d{1,2}(st|nd|rd|th)/, ordinal : function (number) { var b = number % 10, output = (~~(number % 100 / 10) === 1) ? 'th' : @@ -56,4 +57,7 @@ return number + output; } }); -})); + + return en_ca; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/en-gb.js b/lib/javascripts/moment_locale/en-gb.js index 14ccbab3ed8..47b2c209b73 100644 --- a/lib/javascripts/moment_locale/en-gb.js +++ b/lib/javascripts/moment_locale/en-gb.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : great britain english (en-gb) -// author : Chris Gedrim : https://github.com/chrisgedrim +//! moment.js locale configuration +//! locale : great britain english (en-gb) +//! author : Chris Gedrim : https://github.com/chrisgedrim -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('en-gb', { - months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), - monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), - weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), - weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), - weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var en_gb = moment.defineLocale('en-gb', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { sameDay : '[Today at] LT', @@ -33,20 +33,21 @@ sameElse : 'L' }, relativeTime : { - future : "in %s", - past : "%s ago", - s : "a few seconds", - m : "a minute", - mm : "%d minutes", - h : "an hour", - hh : "%d hours", - d : "a day", - dd : "%d days", - M : "a month", - MM : "%d months", - y : "a year", - yy : "%d years" + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' }, + ordinalParse: /\d{1,2}(st|nd|rd|th)/, ordinal : function (number) { var b = number % 10, output = (~~(number % 100 / 10) === 1) ? 'th' : @@ -60,4 +61,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return en_gb; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/en-ie.js b/lib/javascripts/moment_locale/en-ie.js new file mode 100644 index 00000000000..c0ff10c405d --- /dev/null +++ b/lib/javascripts/moment_locale/en-ie.js @@ -0,0 +1,67 @@ +//! moment.js locale configuration +//! locale : Irish english (en-ie) +//! author : Chris Cartlidge : https://github.com/chriscartlidge + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var en_ie = moment.defineLocale('en-ie', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + ordinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + return en_ie; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/en-nz.js b/lib/javascripts/moment_locale/en-nz.js new file mode 100644 index 00000000000..14a50ea4bd2 --- /dev/null +++ b/lib/javascripts/moment_locale/en-nz.js @@ -0,0 +1,66 @@ +//! moment.js locale configuration +//! locale : New Zealand english (en-nz) + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var en_nz = moment.defineLocale('en-nz', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + ordinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + return en_nz; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/eo.js b/lib/javascripts/moment_locale/eo.js index 318385b9502..92772dffa4c 100644 --- a/lib/javascripts/moment_locale/eo.js +++ b/lib/javascripts/moment_locale/eo.js @@ -1,30 +1,34 @@ -// moment.js locale configuration -// locale : esperanto (eo) -// author : Colin Dean : https://github.com/colindean -// komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko. -// Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni! +//! moment.js locale configuration +//! locale : esperanto (eo) +//! author : Colin Dean : https://github.com/colindean +//! komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko. +//! Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni! -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('eo', { - months : "januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro".split("_"), - monthsShort : "jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec".split("_"), - weekdays : "Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato".split("_"), - weekdaysShort : "Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab".split("_"), - weekdaysMin : "Di_Lu_Ma_Me_Ĵa_Ve_Sa".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var eo = moment.defineLocale('eo', { + months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'), + weekdays : 'Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato'.split('_'), + weekdaysShort : 'Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab'.split('_'), + weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "YYYY-MM-DD", - LL : "D[-an de] MMMM, YYYY", - LLL : "D[-an de] MMMM, YYYY LT", - LLLL : "dddd, [la] D[-an de] MMMM, YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D[-an de] MMMM, YYYY', + LLL : 'D[-an de] MMMM, YYYY HH:mm', + LLLL : 'dddd, [la] D[-an de] MMMM, YYYY HH:mm' + }, + meridiemParse: /[ap]\.t\.m/i, + isPM: function (input) { + return input.charAt(0).toLowerCase() === 'p'; }, meridiem : function (hours, minutes, isLower) { if (hours > 11) { @@ -42,24 +46,28 @@ sameElse : 'L' }, relativeTime : { - future : "je %s", - past : "antaŭ %s", - s : "sekundoj", - m : "minuto", - mm : "%d minutoj", - h : "horo", - hh : "%d horoj", - d : "tago",//ne 'diurno', ĉar estas uzita por proksimumo - dd : "%d tagoj", - M : "monato", - MM : "%d monatoj", - y : "jaro", - yy : "%d jaroj" + future : 'je %s', + past : 'antaŭ %s', + s : 'sekundoj', + m : 'minuto', + mm : '%d minutoj', + h : 'horo', + hh : '%d horoj', + d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo + dd : '%d tagoj', + M : 'monato', + MM : '%d monatoj', + y : 'jaro', + yy : '%d jaroj' }, - ordinal : "%da", + ordinalParse: /\d{1,2}a/, + ordinal : '%da', week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return eo; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/es.js b/lib/javascripts/moment_locale/es.js index ed0b5644506..efb51a31d0b 100644 --- a/lib/javascripts/moment_locale/es.js +++ b/lib/javascripts/moment_locale/es.js @@ -1,21 +1,20 @@ -// moment.js locale configuration -// locale : spanish (es) -// author : Julio Napurí : https://github.com/julionc +//! moment.js locale configuration +//! locale : spanish (es) +//! author : Julio Napurí : https://github.com/julionc -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - var monthsShortDot = "ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"), - monthsShort = "ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"); +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; - return moment.defineLocale('es', { - months : "enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"), + + var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); + + var es = moment.defineLocale('es', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), monthsShort : function (m, format) { if (/-MMM-/.test(format)) { return monthsShort[m.month()]; @@ -23,15 +22,16 @@ return monthsShortDot[m.month()]; } }, - weekdays : "domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"), - weekdaysShort : "dom._lun._mar._mié._jue._vie._sáb.".split("_"), - weekdaysMin : "Do_Lu_Ma_Mi_Ju_Vi_Sá".split("_"), + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), longDateFormat : { - LT : "H:mm", - L : "DD/MM/YYYY", - LL : "D [de] MMMM [del] YYYY", - LLL : "D [de] MMMM [del] YYYY LT", - LLLL : "dddd, D [de] MMMM [del] YYYY LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY H:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' }, calendar : { sameDay : function () { @@ -52,24 +52,28 @@ sameElse : 'L' }, relativeTime : { - future : "en %s", - past : "hace %s", - s : "unos segundos", - m : "un minuto", - mm : "%d minutos", - h : "una hora", - hh : "%d horas", - d : "un día", - dd : "%d días", - M : "un mes", - MM : "%d meses", - y : "un año", - yy : "%d años" + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' }, + ordinalParse : /\d{1,2}º/, ordinal : '%dº', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return es; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/et.js b/lib/javascripts/moment_locale/et.js index 2241529d231..09043bfad65 100644 --- a/lib/javascripts/moment_locale/et.js +++ b/lib/javascripts/moment_locale/et.js @@ -1,17 +1,16 @@ -// moment.js locale configuration -// locale : estonian (et) -// author : Henry Kehlmann : https://github.com/madhenry -// improvements : Illimar Tambek : https://github.com/ragulka +//! moment.js locale configuration +//! locale : estonian (et) +//! author : Henry Kehlmann : https://github.com/madhenry +//! improvements : Illimar Tambek : https://github.com/ragulka + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function processRelativeTime(number, withoutSuffix, key, isFuture) { var format = { 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'], @@ -31,18 +30,19 @@ return isFuture ? format[key][0] : format[key][1]; } - return moment.defineLocale('et', { - months : "jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"), - monthsShort : "jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"), - weekdays : "pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev".split("_"), - weekdaysShort : "P_E_T_K_N_R_L".split("_"), - weekdaysMin : "P_E_T_K_N_R_L".split("_"), + var et = moment.defineLocale('et', { + months : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'), + monthsShort : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'), + weekdays : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'), + weekdaysShort : 'P_E_T_K_N_R_L'.split('_'), + weekdaysMin : 'P_E_T_K_N_R_L'.split('_'), longDateFormat : { - LT : "H:mm", - L : "DD.MM.YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd, D. MMMM YYYY LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' }, calendar : { sameDay : '[Täna,] LT', @@ -53,8 +53,8 @@ sameElse : 'L' }, relativeTime : { - future : "%s pärast", - past : "%s tagasi", + future : '%s pärast', + past : '%s tagasi', s : processRelativeTime, m : processRelativeTime, mm : processRelativeTime, @@ -67,10 +67,14 @@ y : processRelativeTime, yy : processRelativeTime }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return et; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/eu.js b/lib/javascripts/moment_locale/eu.js index fe2dddb7bf6..52db117692a 100644 --- a/lib/javascripts/moment_locale/eu.js +++ b/lib/javascripts/moment_locale/eu.js @@ -1,32 +1,32 @@ -// moment.js locale configuration -// locale : euskara (eu) -// author : Eneko Illarramendi : https://github.com/eillarra +//! moment.js locale configuration +//! locale : euskara (eu) +//! author : Eneko Illarramendi : https://github.com/eillarra -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('eu', { - months : "urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"), - monthsShort : "urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"), - weekdays : "igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"), - weekdaysShort : "ig._al._ar._az._og._ol._lr.".split("_"), - weekdaysMin : "ig_al_ar_az_og_ol_lr".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var eu = moment.defineLocale('eu', { + months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'), + monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'), + weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'), + weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'), + weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "YYYY-MM-DD", - LL : "YYYY[ko] MMMM[ren] D[a]", - LLL : "YYYY[ko] MMMM[ren] D[a] LT", - LLLL : "dddd, YYYY[ko] MMMM[ren] D[a] LT", - l : "YYYY-M-D", - ll : "YYYY[ko] MMM D[a]", - lll : "YYYY[ko] MMM D[a] LT", - llll : "ddd, YYYY[ko] MMM D[a] LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY[ko] MMMM[ren] D[a]', + LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm', + LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm', + l : 'YYYY-M-D', + ll : 'YYYY[ko] MMM D[a]', + lll : 'YYYY[ko] MMM D[a] HH:mm', + llll : 'ddd, YYYY[ko] MMM D[a] HH:mm' }, calendar : { sameDay : '[gaur] LT[etan]', @@ -37,24 +37,28 @@ sameElse : 'L' }, relativeTime : { - future : "%s barru", - past : "duela %s", - s : "segundo batzuk", - m : "minutu bat", - mm : "%d minutu", - h : "ordu bat", - hh : "%d ordu", - d : "egun bat", - dd : "%d egun", - M : "hilabete bat", - MM : "%d hilabete", - y : "urte bat", - yy : "%d urte" + future : '%s barru', + past : 'duela %s', + s : 'segundo batzuk', + m : 'minutu bat', + mm : '%d minutu', + h : 'ordu bat', + hh : '%d ordu', + d : 'egun bat', + dd : '%d egun', + M : 'hilabete bat', + MM : '%d hilabete', + y : 'urte bat', + yy : '%d urte' }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return eu; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/fa.js b/lib/javascripts/moment_locale/fa.js index 68af5193fd0..de40e6f9374 100644 --- a/lib/javascripts/moment_locale/fa.js +++ b/lib/javascripts/moment_locale/fa.js @@ -1,16 +1,15 @@ -// moment.js locale configuration -// locale : Persian (fa) -// author : Ebrahim Byagowi : https://github.com/ebraminio +//! moment.js locale configuration +//! locale : Persian (fa) +//! author : Ebrahim Byagowi : https://github.com/ebraminio + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var symbolMap = { '1': '۱', '2': '۲', @@ -35,7 +34,7 @@ '۰': '0' }; - return moment.defineLocale('fa', { + var fa = moment.defineLocale('fa', { months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), @@ -43,16 +42,21 @@ weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'), longDateFormat : { LT : 'HH:mm', + LTS : 'HH:mm:ss', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + meridiemParse: /قبل از ظهر|بعد از ظهر/, + isPM: function (input) { + return /بعد از ظهر/.test(input); }, meridiem : function (hour, minute, isLower) { if (hour < 12) { - return "قبل از ظهر"; + return 'قبل از ظهر'; } else { - return "بعد از ظهر"; + return 'بعد از ظهر'; } }, calendar : { @@ -88,10 +92,14 @@ return symbolMap[match]; }).replace(/,/g, '،'); }, + ordinalParse: /\d{1,2}م/, ordinal : '%dم', week : { dow : 6, // Saturday is the first day of the week. doy : 12 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return fa; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/fi.js b/lib/javascripts/moment_locale/fi.js index 2afc5e89ac6..4f9161bdd38 100644 --- a/lib/javascripts/moment_locale/fi.js +++ b/lib/javascripts/moment_locale/fi.js @@ -1,24 +1,22 @@ -// moment.js locale configuration -// locale : finnish (fi) -// author : Tarmo Aidantausta : https://github.com/bleadof +//! moment.js locale configuration +//! locale : finnish (fi) +//! author : Tarmo Aidantausta : https://github.com/bleadof + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '), numbersFuture = [ 'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden', numbersPast[7], numbersPast[8], numbersPast[9] ]; - function translate(number, withoutSuffix, key, isFuture) { - var result = ""; + var result = ''; switch (key) { case 's': return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; @@ -48,30 +46,30 @@ result = isFuture ? 'vuoden' : 'vuotta'; break; } - result = verbalNumber(number, isFuture) + " " + result; + result = verbalNumber(number, isFuture) + ' ' + result; return result; } - function verbalNumber(number, isFuture) { return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number; } - return moment.defineLocale('fi', { - months : "tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"), - monthsShort : "tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"), - weekdays : "sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"), - weekdaysShort : "su_ma_ti_ke_to_pe_la".split("_"), - weekdaysMin : "su_ma_ti_ke_to_pe_la".split("_"), + var fi = moment.defineLocale('fi', { + months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'), + monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'), + weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'), + weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'), + weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'), longDateFormat : { - LT : "HH.mm", - L : "DD.MM.YYYY", - LL : "Do MMMM[ta] YYYY", - LLL : "Do MMMM[ta] YYYY, [klo] LT", - LLLL : "dddd, Do MMMM[ta] YYYY, [klo] LT", - l : "D.M.YYYY", - ll : "Do MMM YYYY", - lll : "Do MMM YYYY, [klo] LT", - llll : "ddd, Do MMM YYYY, [klo] LT" + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD.MM.YYYY', + LL : 'Do MMMM[ta] YYYY', + LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm', + LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm', + l : 'D.M.YYYY', + ll : 'Do MMM YYYY', + lll : 'Do MMM YYYY, [klo] HH.mm', + llll : 'ddd, Do MMM YYYY, [klo] HH.mm' }, calendar : { sameDay : '[tänään] [klo] LT', @@ -82,8 +80,8 @@ sameElse : 'L' }, relativeTime : { - future : "%s päästä", - past : "%s sitten", + future : '%s päästä', + past : '%s sitten', s : translate, m : translate, mm : translate, @@ -96,10 +94,14 @@ y : translate, yy : translate }, - ordinal : "%d.", + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return fi; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/fo.js b/lib/javascripts/moment_locale/fo.js index cdc9eda1647..460b6cd81c0 100644 --- a/lib/javascripts/moment_locale/fo.js +++ b/lib/javascripts/moment_locale/fo.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : faroese (fo) -// author : Ragnar Johannesen : https://github.com/ragnar123 +//! moment.js locale configuration +//! locale : faroese (fo) +//! author : Ragnar Johannesen : https://github.com/ragnar123 -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('fo', { - months : "januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember".split("_"), - monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"), - weekdays : "sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur".split("_"), - weekdaysShort : "sun_mán_týs_mik_hós_frí_ley".split("_"), - weekdaysMin : "su_má_tý_mi_hó_fr_le".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var fo = moment.defineLocale('fo', { + months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'), + weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'), + weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D. MMMM, YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D. MMMM, YYYY HH:mm' }, calendar : { sameDay : '[Í dag kl.] LT', @@ -33,24 +33,28 @@ sameElse : 'L' }, relativeTime : { - future : "um %s", - past : "%s síðani", - s : "fá sekund", - m : "ein minutt", - mm : "%d minuttir", - h : "ein tími", - hh : "%d tímar", - d : "ein dagur", - dd : "%d dagar", - M : "ein mánaði", - MM : "%d mánaðir", - y : "eitt ár", - yy : "%d ár" + future : 'um %s', + past : '%s síðani', + s : 'fá sekund', + m : 'ein minutt', + mm : '%d minuttir', + h : 'ein tími', + hh : '%d tímar', + d : 'ein dagur', + dd : '%d dagar', + M : 'ein mánaði', + MM : '%d mánaðir', + y : 'eitt ár', + yy : '%d ár' }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return fo; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/fr-ca.js b/lib/javascripts/moment_locale/fr-ca.js index 714b11b2bfe..f15ec8dc079 100644 --- a/lib/javascripts/moment_locale/fr-ca.js +++ b/lib/javascripts/moment_locale/fr-ca.js @@ -1,31 +1,31 @@ -// moment.js locale configuration -// locale : canadian french (fr-ca) -// author : Jonathan Abourbih : https://github.com/jonbca +//! moment.js locale configuration +//! locale : canadian french (fr-ca) +//! author : Jonathan Abourbih : https://github.com/jonbca -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('fr-ca', { - months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"), - monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"), - weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"), - weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"), - weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var fr_ca = moment.defineLocale('fr-ca', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "YYYY-MM-DD", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { - sameDay: "[Aujourd'hui à] LT", + sameDay: '[Aujourd\'hui à] LT', nextDay: '[Demain à] LT', nextWeek: 'dddd [à] LT', lastDay: '[Hier à] LT', @@ -33,22 +33,26 @@ sameElse: 'L' }, relativeTime : { - future : "dans %s", - past : "il y a %s", - s : "quelques secondes", - m : "une minute", - mm : "%d minutes", - h : "une heure", - hh : "%d heures", - d : "un jour", - dd : "%d jours", - M : "un mois", - MM : "%d mois", - y : "un an", - yy : "%d ans" + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' }, + ordinalParse: /\d{1,2}(er|e)/, ordinal : function (number) { - return number + (number === 1 ? 'er' : ''); + return number + (number === 1 ? 'er' : 'e'); } }); -})); + + return fr_ca; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/fr-ch.js b/lib/javascripts/moment_locale/fr-ch.js new file mode 100644 index 00000000000..9503d80f7d7 --- /dev/null +++ b/lib/javascripts/moment_locale/fr-ch.js @@ -0,0 +1,62 @@ +//! moment.js locale configuration +//! locale : swiss french (fr) +//! author : Gaspard Bucher : https://github.com/gaspard + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var fr_ch = moment.defineLocale('fr-ch', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Aujourd\'hui à] LT', + nextDay: '[Demain à] LT', + nextWeek: 'dddd [à] LT', + lastDay: '[Hier à] LT', + lastWeek: 'dddd [dernier à] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + ordinalParse: /\d{1,2}(er|e)/, + ordinal : function (number) { + return number + (number === 1 ? 'er' : 'e'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + return fr_ch; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/fr.js b/lib/javascripts/moment_locale/fr.js index 106ab11bee4..8ef95c9fb6e 100644 --- a/lib/javascripts/moment_locale/fr.js +++ b/lib/javascripts/moment_locale/fr.js @@ -1,31 +1,31 @@ -// moment.js locale configuration -// locale : french (fr) -// author : John Fischer : https://github.com/jfroffice +//! moment.js locale configuration +//! locale : french (fr) +//! author : John Fischer : https://github.com/jfroffice -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('fr', { - months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"), - monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"), - weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"), - weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"), - weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var fr = moment.defineLocale('fr', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { - sameDay: "[Aujourd'hui à] LT", + sameDay: '[Aujourd\'hui à] LT', nextDay: '[Demain à] LT', nextWeek: 'dddd [à] LT', lastDay: '[Hier à] LT', @@ -33,20 +33,21 @@ sameElse: 'L' }, relativeTime : { - future : "dans %s", - past : "il y a %s", - s : "quelques secondes", - m : "une minute", - mm : "%d minutes", - h : "une heure", - hh : "%d heures", - d : "un jour", - dd : "%d jours", - M : "un mois", - MM : "%d mois", - y : "un an", - yy : "%d ans" + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' }, + ordinalParse: /\d{1,2}(er|)/, ordinal : function (number) { return number + (number === 1 ? 'er' : ''); }, @@ -55,4 +56,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return fr; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/fy.js b/lib/javascripts/moment_locale/fy.js new file mode 100644 index 00000000000..d1b709c122b --- /dev/null +++ b/lib/javascripts/moment_locale/fy.js @@ -0,0 +1,71 @@ +//! moment.js locale configuration +//! locale : frisian (fy) +//! author : Robin van der Vliet : https://github.com/robin0van0der0v + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'); + + var fy = moment.defineLocale('fy', { + months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'), + monthsShort : function (m, format) { + if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'), + weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'), + weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[hjoed om] LT', + nextDay: '[moarn om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[juster om] LT', + lastWeek: '[ôfrûne] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'oer %s', + past : '%s lyn', + s : 'in pear sekonden', + m : 'ien minút', + mm : '%d minuten', + h : 'ien oere', + hh : '%d oeren', + d : 'ien dei', + dd : '%d dagen', + M : 'ien moanne', + MM : '%d moannen', + y : 'ien jier', + yy : '%d jierren' + }, + ordinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + return fy; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/gd.js b/lib/javascripts/moment_locale/gd.js new file mode 100644 index 00000000000..578e5674b9e --- /dev/null +++ b/lib/javascripts/moment_locale/gd.js @@ -0,0 +1,76 @@ +//! moment.js locale configuration +//! locale : great britain scottish gealic (gd) +//! author : Jon Ashdown : https://github.com/jonashdown + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var months = [ + 'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd' + ]; + + var monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh']; + + var weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne']; + + var weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis']; + + var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa']; + + var gd = moment.defineLocale('gd', { + months : months, + monthsShort : monthsShort, + monthsParseExact : true, + weekdays : weekdays, + weekdaysShort : weekdaysShort, + weekdaysMin : weekdaysMin, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[An-diugh aig] LT', + nextDay : '[A-màireach aig] LT', + nextWeek : 'dddd [aig] LT', + lastDay : '[An-dè aig] LT', + lastWeek : 'dddd [seo chaidh] [aig] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ann an %s', + past : 'bho chionn %s', + s : 'beagan diogan', + m : 'mionaid', + mm : '%d mionaidean', + h : 'uair', + hh : '%d uairean', + d : 'latha', + dd : '%d latha', + M : 'mìos', + MM : '%d mìosan', + y : 'bliadhna', + yy : '%d bliadhna' + }, + ordinalParse : /\d{1,2}(d|na|mh)/, + ordinal : function (number) { + var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + return gd; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/gl.js b/lib/javascripts/moment_locale/gl.js index e82065f33dc..ef8e7043b89 100644 --- a/lib/javascripts/moment_locale/gl.js +++ b/lib/javascripts/moment_locale/gl.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : galician (gl) -// author : Juan G. Hurtado : https://github.com/juanghurtado +//! moment.js locale configuration +//! locale : galician (gl) +//! author : Juan G. Hurtado : https://github.com/juanghurtado -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('gl', { - months : "Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro".split("_"), - monthsShort : "Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.".split("_"), - weekdays : "Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado".split("_"), - weekdaysShort : "Dom._Lun._Mar._Mér._Xov._Ven._Sáb.".split("_"), - weekdaysMin : "Do_Lu_Ma_Mé_Xo_Ve_Sá".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var gl = moment.defineLocale('gl', { + months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'), + monthsShort : 'Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.'.split('_'), + weekdays : 'Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado'.split('_'), + weekdaysShort : 'Dom._Lun._Mar._Mér._Xov._Ven._Sáb.'.split('_'), + weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'), longDateFormat : { - LT : "H:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd D MMMM YYYY H:mm' }, calendar : { sameDay : function () { @@ -44,28 +44,32 @@ }, relativeTime : { future : function (str) { - if (str === "uns segundos") { - return "nuns segundos"; + if (str === 'uns segundos') { + return 'nuns segundos'; } - return "en " + str; + return 'en ' + str; }, - past : "hai %s", - s : "uns segundos", - m : "un minuto", - mm : "%d minutos", - h : "unha hora", - hh : "%d horas", - d : "un día", - dd : "%d días", - M : "un mes", - MM : "%d meses", - y : "un ano", - yy : "%d anos" + past : 'hai %s', + s : 'uns segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'unha hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un ano', + yy : '%d anos' }, + ordinalParse : /\d{1,2}º/, ordinal : '%dº', week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return gl; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/he.js b/lib/javascripts/moment_locale/he.js index 0af4e0988d5..6a259be8b60 100644 --- a/lib/javascripts/moment_locale/he.js +++ b/lib/javascripts/moment_locale/he.js @@ -1,34 +1,34 @@ -// moment.js locale configuration -// locale : Hebrew (he) -// author : Tomer Cohen : https://github.com/tomer -// author : Moshe Simantov : https://github.com/DevelopmentIL -// author : Tal Ater : https://github.com/TalAter +//! moment.js locale configuration +//! locale : Hebrew (he) +//! author : Tomer Cohen : https://github.com/tomer +//! author : Moshe Simantov : https://github.com/DevelopmentIL +//! author : Tal Ater : https://github.com/TalAter -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('he', { - months : "ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"), - monthsShort : "ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"), - weekdays : "ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"), - weekdaysShort : "א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳".split("_"), - weekdaysMin : "א_ב_ג_ד_ה_ו_ש".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var he = moment.defineLocale('he', { + months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'), + monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'), + weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'), + weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'), + weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D [ב]MMMM YYYY", - LLL : "D [ב]MMMM YYYY LT", - LLLL : "dddd, D [ב]MMMM YYYY LT", - l : "D/M/YYYY", - ll : "D MMM YYYY", - lll : "D MMM YYYY LT", - llll : "ddd, D MMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [ב]MMMM YYYY', + LLL : 'D [ב]MMMM YYYY HH:mm', + LLLL : 'dddd, D [ב]MMMM YYYY HH:mm', + l : 'D/M/YYYY', + ll : 'D MMM YYYY', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd, D MMM YYYY HH:mm' }, calendar : { sameDay : '[היום ב־]LT', @@ -39,39 +39,44 @@ sameElse : 'L' }, relativeTime : { - future : "בעוד %s", - past : "לפני %s", - s : "מספר שניות", - m : "דקה", - mm : "%d דקות", - h : "שעה", + future : 'בעוד %s', + past : 'לפני %s', + s : 'מספר שניות', + m : 'דקה', + mm : '%d דקות', + h : 'שעה', hh : function (number) { if (number === 2) { - return "שעתיים"; + return 'שעתיים'; } - return number + " שעות"; + return number + ' שעות'; }, - d : "יום", + d : 'יום', dd : function (number) { if (number === 2) { - return "יומיים"; + return 'יומיים'; } - return number + " ימים"; + return number + ' ימים'; }, - M : "חודש", + M : 'חודש', MM : function (number) { if (number === 2) { - return "חודשיים"; + return 'חודשיים'; } - return number + " חודשים"; + return number + ' חודשים'; }, - y : "שנה", + y : 'שנה', yy : function (number) { if (number === 2) { - return "שנתיים"; + return 'שנתיים'; + } else if (number % 10 === 0 && number !== 10) { + return number + ' שנה'; } - return number + " שנים"; + return number + ' שנים'; } } }); -})); + + return he; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/hi.js b/lib/javascripts/moment_locale/hi.js index 6dd7098c27d..0542ef791e2 100644 --- a/lib/javascripts/moment_locale/hi.js +++ b/lib/javascripts/moment_locale/hi.js @@ -1,16 +1,15 @@ -// moment.js locale configuration -// locale : hindi (hi) -// author : Mayank Singhal : https://github.com/mayanksinghal +//! moment.js locale configuration +//! locale : hindi (hi) +//! author : Mayank Singhal : https://github.com/mayanksinghal + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var symbolMap = { '1': '१', '2': '२', @@ -36,18 +35,19 @@ '०': '0' }; - return moment.defineLocale('hi', { - months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split("_"), - monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split("_"), - weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split("_"), - weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split("_"), - weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split("_"), + var hi = moment.defineLocale('hi', { + months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'), + monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'), + weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), longDateFormat : { - LT : "A h:mm बजे", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY, LT", - LLLL : "dddd, D MMMM YYYY, LT" + LT : 'A h:mm बजे', + LTS : 'A h:mm:ss बजे', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm बजे', + LLLL : 'dddd, D MMMM YYYY, A h:mm बजे' }, calendar : { sameDay : '[आज] LT', @@ -58,19 +58,19 @@ sameElse : 'L' }, relativeTime : { - future : "%s में", - past : "%s पहले", - s : "कुछ ही क्षण", - m : "एक मिनट", - mm : "%d मिनट", - h : "एक घंटा", - hh : "%d घंटे", - d : "एक दिन", - dd : "%d दिन", - M : "एक महीने", - MM : "%d महीने", - y : "एक वर्ष", - yy : "%d वर्ष" + future : '%s में', + past : '%s पहले', + s : 'कुछ ही क्षण', + m : 'एक मिनट', + mm : '%d मिनट', + h : 'एक घंटा', + hh : '%d घंटे', + d : 'एक दिन', + dd : '%d दिन', + M : 'एक महीने', + MM : '%d महीने', + y : 'एक वर्ष', + yy : '%d वर्ष' }, preparse: function (string) { return string.replace(/[१२३४५६७८९०]/g, function (match) { @@ -84,17 +84,32 @@ }, // Hindi notation for meridiems are quite fuzzy in practice. While there exists // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi. + meridiemParse: /रात|सुबह|दोपहर|शाम/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सुबह') { + return hour; + } else if (meridiem === 'दोपहर') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'शाम') { + return hour + 12; + } + }, meridiem : function (hour, minute, isLower) { if (hour < 4) { - return "रात"; + return 'रात'; } else if (hour < 10) { - return "सुबह"; + return 'सुबह'; } else if (hour < 17) { - return "दोपहर"; + return 'दोपहर'; } else if (hour < 20) { - return "शाम"; + return 'शाम'; } else { - return "रात"; + return 'रात'; } }, week : { @@ -102,4 +117,7 @@ doy : 6 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return hi; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/hr.js b/lib/javascripts/moment_locale/hr.js index 20fe8c1d662..26923838c94 100644 --- a/lib/javascripts/moment_locale/hr.js +++ b/lib/javascripts/moment_locale/hr.js @@ -1,20 +1,17 @@ -// moment.js locale configuration -// locale : hrvatski (hr) -// author : Bojan Marković : https://github.com/bmarkovic +//! moment.js locale configuration +//! locale : hrvatski (hr) +//! author : Bojan Marković : https://github.com/bmarkovic + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; -// based on (sl) translation by Robert Sedovšek -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function translate(number, withoutSuffix, key) { - var result = number + " "; + var result = number + ' '; switch (key) { case 'm': return withoutSuffix ? 'jedna minuta' : 'jedne minute'; @@ -66,23 +63,26 @@ } } - return moment.defineLocale('hr', { - months : "sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_"), - monthsShort : "sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"), - weekdays : "nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"), - weekdaysShort : "ned._pon._uto._sri._čet._pet._sub.".split("_"), - weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"), + var hr = moment.defineLocale('hr', { + months : { + format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'), + standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_') + }, + monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'), + weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), longDateFormat : { - LT : "H:mm", - L : "DD. MM. YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd, D. MMMM YYYY LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD. MM. YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' }, calendar : { sameDay : '[danas u] LT', nextDay : '[sutra u] LT', - nextWeek : function () { switch (this.day()) { case 0: @@ -116,24 +116,28 @@ sameElse : 'L' }, relativeTime : { - future : "za %s", - past : "prije %s", - s : "par sekundi", + future : 'za %s', + past : 'prije %s', + s : 'par sekundi', m : translate, mm : translate, h : translate, hh : translate, - d : "dan", + d : 'dan', dd : translate, - M : "mjesec", + M : 'mjesec', MM : translate, - y : "godinu", + y : 'godinu', yy : translate }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return hr; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/hu.js b/lib/javascripts/moment_locale/hu.js index 910f0868b5a..2708672742a 100644 --- a/lib/javascripts/moment_locale/hu.js +++ b/lib/javascripts/moment_locale/hu.js @@ -1,22 +1,19 @@ -// moment.js locale configuration -// locale : hungarian (hu) -// author : Adam Brunner : https://github.com/adambrunner +//! moment.js locale configuration +//! locale : hungarian (hu) +//! author : Adam Brunner : https://github.com/adambrunner + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' '); - function translate(number, withoutSuffix, key, isFuture) { var num = number, suffix; - switch (key) { case 's': return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce'; @@ -41,26 +38,29 @@ case 'yy': return num + (isFuture || withoutSuffix ? ' év' : ' éve'); } - return ''; } - function week(isFuture) { return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]'; } - return moment.defineLocale('hu', { - months : "január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"), - monthsShort : "jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"), - weekdays : "vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"), - weekdaysShort : "vas_hét_kedd_sze_csüt_pén_szo".split("_"), - weekdaysMin : "v_h_k_sze_cs_p_szo".split("_"), + var hu = moment.defineLocale('hu', { + months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'), + monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'), + weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'), + weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'), + weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'), longDateFormat : { - LT : "H:mm", - L : "YYYY.MM.DD.", - LL : "YYYY. MMMM D.", - LLL : "YYYY. MMMM D., LT", - LLLL : "YYYY. MMMM D., dddd LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'YYYY.MM.DD.', + LL : 'YYYY. MMMM D.', + LLL : 'YYYY. MMMM D. H:mm', + LLLL : 'YYYY. MMMM D., dddd H:mm' + }, + meridiemParse: /de|du/i, + isPM: function (input) { + return input.charAt(1).toLowerCase() === 'u'; }, meridiem : function (hours, minutes, isLower) { if (hours < 12) { @@ -82,8 +82,8 @@ sameElse : 'L' }, relativeTime : { - future : "%s múlva", - past : "%s", + future : '%s múlva', + past : '%s', s : translate, m : translate, mm : translate, @@ -96,10 +96,14 @@ y : translate, yy : translate }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return hu; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/hy-am.js b/lib/javascripts/moment_locale/hy-am.js index b6984a2794a..7350bfbe457 100644 --- a/lib/javascripts/moment_locale/hy-am.js +++ b/lib/javascripts/moment_locale/hy-am.js @@ -1,53 +1,31 @@ -// moment.js locale configuration -// locale : Armenian (hy-am) -// author : Armendarabyan : https://github.com/armendarabyan +//! moment.js locale configuration +//! locale : Armenian (hy-am) +//! author : Armendarabyan : https://github.com/armendarabyan -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - function monthsCaseReplace(m, format) { - var months = { - 'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'), - 'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_') +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var hy_am = moment.defineLocale('hy-am', { + months : { + format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'), + standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_') }, - - nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - } - - function monthsShortCaseReplace(m, format) { - var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'); - - return monthsShort[m.month()]; - } - - function weekdaysCaseReplace(m, format) { - var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'); - - return weekdays[m.day()]; - } - - return moment.defineLocale('hy-am', { - months : monthsCaseReplace, - monthsShort : monthsShortCaseReplace, - weekdays : weekdaysCaseReplace, - weekdaysShort : "կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"), - weekdaysMin : "կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"), + monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'), + weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'), + weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY թ.", - LLL : "D MMMM YYYY թ., LT", - LLLL : "dddd, D MMMM YYYY թ., LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY թ.', + LLL : 'D MMMM YYYY թ., HH:mm', + LLLL : 'dddd, D MMMM YYYY թ., HH:mm' }, calendar : { sameDay: '[այսօր] LT', @@ -62,33 +40,36 @@ sameElse: 'L' }, relativeTime : { - future : "%s հետո", - past : "%s առաջ", - s : "մի քանի վայրկյան", - m : "րոպե", - mm : "%d րոպե", - h : "ժամ", - hh : "%d ժամ", - d : "օր", - dd : "%d օր", - M : "ամիս", - MM : "%d ամիս", - y : "տարի", - yy : "%d տարի" + future : '%s հետո', + past : '%s առաջ', + s : 'մի քանի վայրկյան', + m : 'րոպե', + mm : '%d րոպե', + h : 'ժամ', + hh : '%d ժամ', + d : 'օր', + dd : '%d օր', + M : 'ամիս', + MM : '%d ամիս', + y : 'տարի', + yy : '%d տարի' + }, + meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/, + isPM: function (input) { + return /^(ցերեկվա|երեկոյան)$/.test(input); }, - meridiem : function (hour) { if (hour < 4) { - return "գիշերվա"; + return 'գիշերվա'; } else if (hour < 12) { - return "առավոտվա"; + return 'առավոտվա'; } else if (hour < 17) { - return "ցերեկվա"; + return 'ցերեկվա'; } else { - return "երեկոյան"; + return 'երեկոյան'; } }, - + ordinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/, ordinal: function (number, period) { switch (period) { case 'DDD': @@ -103,10 +84,12 @@ return number; } }, - week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return hy_am; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/id.js b/lib/javascripts/moment_locale/id.js index 6043f30a239..09461a5d5a6 100644 --- a/lib/javascripts/moment_locale/id.js +++ b/lib/javascripts/moment_locale/id.js @@ -1,29 +1,42 @@ -// moment.js locale configuration -// locale : Bahasa Indonesia (id) -// author : Mohammad Satrio Utomo : https://github.com/tyok -// reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan +//! moment.js locale configuration +//! locale : Bahasa Indonesia (id) +//! author : Mohammad Satrio Utomo : https://github.com/tyok +//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('id', { - months : "Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"), - monthsShort : "Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des".split("_"), - weekdays : "Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"), - weekdaysShort : "Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"), - weekdaysMin : "Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var id = moment.defineLocale('id', { + months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'), + weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'), + weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'), longDateFormat : { - LT : "HH.mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY [pukul] LT", - LLLL : "dddd, D MMMM YYYY [pukul] LT" + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|siang|sore|malam/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'siang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sore' || meridiem === 'malam') { + return hour + 12; + } }, meridiem : function (hours, minutes, isLower) { if (hours < 11) { @@ -45,23 +58,26 @@ sameElse : 'L' }, relativeTime : { - future : "dalam %s", - past : "%s yang lalu", - s : "beberapa detik", - m : "semenit", - mm : "%d menit", - h : "sejam", - hh : "%d jam", - d : "sehari", - dd : "%d hari", - M : "sebulan", - MM : "%d bulan", - y : "setahun", - yy : "%d tahun" + future : 'dalam %s', + past : '%s yang lalu', + s : 'beberapa detik', + m : 'semenit', + mm : '%d menit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' }, week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return id; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/is.js b/lib/javascripts/moment_locale/is.js index ed2240644f9..f1ed257a474 100644 --- a/lib/javascripts/moment_locale/is.js +++ b/lib/javascripts/moment_locale/is.js @@ -1,16 +1,15 @@ -// moment.js locale configuration -// locale : icelandic (is) -// author : Hinrik Örn Sigurðsson : https://github.com/hinrik +//! moment.js locale configuration +//! locale : icelandic (is) +//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function plural(n) { if (n % 100 === 11) { return true; @@ -19,9 +18,8 @@ } return true; } - function translate(number, withoutSuffix, key, isFuture) { - var result = number + " "; + var result = number + ' '; switch (key) { case 's': return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum'; @@ -79,18 +77,19 @@ } } - return moment.defineLocale('is', { - months : "janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"), - monthsShort : "jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"), - weekdays : "sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"), - weekdaysShort : "sun_mán_þri_mið_fim_fös_lau".split("_"), - weekdaysMin : "Su_Má_Þr_Mi_Fi_Fö_La".split("_"), + var is = moment.defineLocale('is', { + months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'), + weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'), + weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'), + weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'), longDateFormat : { - LT : "H:mm", - L : "DD/MM/YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY [kl.] LT", - LLLL : "dddd, D. MMMM YYYY [kl.] LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] H:mm', + LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm' }, calendar : { sameDay : '[í dag kl.] LT', @@ -101,12 +100,12 @@ sameElse : 'L' }, relativeTime : { - future : "eftir %s", - past : "fyrir %s síðan", + future : 'eftir %s', + past : 'fyrir %s síðan', s : translate, m : translate, mm : translate, - h : "klukkustund", + h : 'klukkustund', hh : translate, d : translate, dd : translate, @@ -115,10 +114,14 @@ y : translate, yy : translate }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return is; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/it.js b/lib/javascripts/moment_locale/it.js index a151ccc62ae..e8b2c950c7f 100644 --- a/lib/javascripts/moment_locale/it.js +++ b/lib/javascripts/moment_locale/it.js @@ -1,59 +1,70 @@ -// moment.js locale configuration -// locale : italian (it) -// author : Lorenzo : https://github.com/aliem -// author: Mattia Larentis: https://github.com/nostalgiaz +//! moment.js locale configuration +//! locale : italian (it) +//! author : Lorenzo : https://github.com/aliem +//! author: Mattia Larentis: https://github.com/nostalgiaz -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('it', { - months : "gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"), - monthsShort : "gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"), - weekdays : "Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"), - weekdaysShort : "Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"), - weekdaysMin : "D_L_Ma_Me_G_V_S".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var it = moment.defineLocale('it', { + months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'), + monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), + weekdays : 'Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato'.split('_'), + weekdaysShort : 'Dom_Lun_Mar_Mer_Gio_Ven_Sab'.split('_'), + weekdaysMin : 'Do_Lu_Ma_Me_Gi_Ve_Sa'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { sameDay: '[Oggi alle] LT', nextDay: '[Domani alle] LT', nextWeek: 'dddd [alle] LT', lastDay: '[Ieri alle] LT', - lastWeek: '[lo scorso] dddd [alle] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[la scorsa] dddd [alle] LT'; + default: + return '[lo scorso] dddd [alle] LT'; + } + }, sameElse: 'L' }, relativeTime : { future : function (s) { - return ((/^[0-9].+$/).test(s) ? "tra" : "in") + " " + s; + return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s; }, - past : "%s fa", - s : "alcuni secondi", - m : "un minuto", - mm : "%d minuti", - h : "un'ora", - hh : "%d ore", - d : "un giorno", - dd : "%d giorni", - M : "un mese", - MM : "%d mesi", - y : "un anno", - yy : "%d anni" + past : '%s fa', + s : 'alcuni secondi', + m : 'un minuto', + mm : '%d minuti', + h : 'un\'ora', + hh : '%d ore', + d : 'un giorno', + dd : '%d giorni', + M : 'un mese', + MM : '%d mesi', + y : 'un anno', + yy : '%d anni' }, + ordinalParse : /\d{1,2}º/, ordinal: '%dº', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return it; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ja.js b/lib/javascripts/moment_locale/ja.js index 34c4b890d8e..6c6e85930cf 100644 --- a/lib/javascripts/moment_locale/ja.js +++ b/lib/javascripts/moment_locale/ja.js @@ -1,34 +1,38 @@ -// moment.js locale configuration -// locale : japanese (ja) -// author : LI Long : https://github.com/baryon +//! moment.js locale configuration +//! locale : japanese (ja) +//! author : LI Long : https://github.com/baryon -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('ja', { - months : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - weekdays : "日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"), - weekdaysShort : "日_月_火_水_木_金_土".split("_"), - weekdaysMin : "日_月_火_水_木_金_土".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var ja = moment.defineLocale('ja', { + months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'), + weekdaysShort : '日_月_火_水_木_金_土'.split('_'), + weekdaysMin : '日_月_火_水_木_金_土'.split('_'), longDateFormat : { - LT : "Ah時m分", - L : "YYYY/MM/DD", - LL : "YYYY年M月D日", - LLL : "YYYY年M月D日LT", - LLLL : "YYYY年M月D日LT dddd" + LT : 'Ah時m分', + LTS : 'Ah時m分s秒', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日Ah時m分', + LLLL : 'YYYY年M月D日Ah時m分 dddd' + }, + meridiemParse: /午前|午後/i, + isPM : function (input) { + return input === '午後'; }, meridiem : function (hour, minute, isLower) { if (hour < 12) { - return "午前"; + return '午前'; } else { - return "午後"; + return '午後'; } }, calendar : { @@ -40,19 +44,22 @@ sameElse : 'L' }, relativeTime : { - future : "%s後", - past : "%s前", - s : "数秒", - m : "1分", - mm : "%d分", - h : "1時間", - hh : "%d時間", - d : "1日", - dd : "%d日", - M : "1ヶ月", - MM : "%dヶ月", - y : "1年", - yy : "%d年" + future : '%s後', + past : '%s前', + s : '数秒', + m : '1分', + mm : '%d分', + h : '1時間', + hh : '%d時間', + d : '1日', + dd : '%d日', + M : '1ヶ月', + MM : '%dヶ月', + y : '1年', + yy : '%d年' } }); -})); + + return ja; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/jv.js b/lib/javascripts/moment_locale/jv.js new file mode 100644 index 00000000000..d3b85a4c06d --- /dev/null +++ b/lib/javascripts/moment_locale/jv.js @@ -0,0 +1,83 @@ +//! moment.js locale configuration +//! locale : Boso Jowo (jv) +//! author : Rony Lantip : https://github.com/lantip +//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var jv = moment.defineLocale('jv', { + months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'), + weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'), + weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'), + weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /enjing|siyang|sonten|ndalu/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'enjing') { + return hour; + } else if (meridiem === 'siyang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sonten' || meridiem === 'ndalu') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'enjing'; + } else if (hours < 15) { + return 'siyang'; + } else if (hours < 19) { + return 'sonten'; + } else { + return 'ndalu'; + } + }, + calendar : { + sameDay : '[Dinten puniko pukul] LT', + nextDay : '[Mbenjang pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kala wingi pukul] LT', + lastWeek : 'dddd [kepengker pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'wonten ing %s', + past : '%s ingkang kepengker', + s : 'sawetawis detik', + m : 'setunggal menit', + mm : '%d menit', + h : 'setunggal jam', + hh : '%d jam', + d : 'sedinten', + dd : '%d dinten', + M : 'sewulan', + MM : '%d wulan', + y : 'setaun', + yy : '%d taun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + return jv; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ka.js b/lib/javascripts/moment_locale/ka.js index 31345243644..f052c3ac332 100644 --- a/lib/javascripts/moment_locale/ka.js +++ b/lib/javascripts/moment_locale/ka.js @@ -1,54 +1,35 @@ -// moment.js locale configuration -// locale : Georgian (ka) -// author : Irakli Janiashvili : https://github.com/irakli-janiashvili +//! moment.js locale configuration +//! locale : Georgian (ka) +//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - function monthsCaseReplace(m, format) { - var months = { - 'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'), - 'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_') +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var ka = moment.defineLocale('ka', { + months : { + standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'), + format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_') }, - - nounCase = (/D[oD] *MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - } - - function weekdaysCaseReplace(m, format) { - var weekdays = { - 'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'), - 'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_') + monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'), + weekdays : { + standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'), + format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'), + isFormat: /(წინა|შემდეგ)/ }, - - nounCase = (/(წინა|შემდეგ)/).test(format) ? - 'accusative' : - 'nominative'; - - return weekdays[nounCase][m.day()]; - } - - return moment.defineLocale('ka', { - months : monthsCaseReplace, - monthsShort : "იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ".split("_"), - weekdays : weekdaysCaseReplace, - weekdaysShort : "კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ".split("_"), - weekdaysMin : "კვ_ორ_სა_ოთ_ხუ_პა_შა".split("_"), + weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'), + weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'), longDateFormat : { - LT : "h:mm A", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' }, calendar : { sameDay : '[დღეს] LT[-ზე]', @@ -61,47 +42,48 @@ relativeTime : { future : function (s) { return (/(წამი|წუთი|საათი|წელი)/).test(s) ? - s.replace(/ი$/, "ში") : - s + "ში"; + s.replace(/ი$/, 'ში') : + s + 'ში'; }, past : function (s) { if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) { - return s.replace(/(ი|ე)$/, "ის წინ"); + return s.replace(/(ი|ე)$/, 'ის წინ'); } if ((/წელი/).test(s)) { - return s.replace(/წელი$/, "წლის წინ"); + return s.replace(/წელი$/, 'წლის წინ'); } }, - s : "რამდენიმე წამი", - m : "წუთი", - mm : "%d წუთი", - h : "საათი", - hh : "%d საათი", - d : "დღე", - dd : "%d დღე", - M : "თვე", - MM : "%d თვე", - y : "წელი", - yy : "%d წელი" + s : 'რამდენიმე წამი', + m : 'წუთი', + mm : '%d წუთი', + h : 'საათი', + hh : '%d საათი', + d : 'დღე', + dd : '%d დღე', + M : 'თვე', + MM : '%d თვე', + y : 'წელი', + yy : '%d წელი' }, + ordinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/, ordinal : function (number) { if (number === 0) { return number; } - if (number === 1) { - return number + "-ლი"; + return number + '-ლი'; } - if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) { - return "მე-" + number; + return 'მე-' + number; } - - return number + "-ე"; + return number + '-ე'; }, week : { dow : 1, doy : 7 } }); -})); + + return ka; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/kk.js b/lib/javascripts/moment_locale/kk.js new file mode 100644 index 00000000000..81acd0bf620 --- /dev/null +++ b/lib/javascripts/moment_locale/kk.js @@ -0,0 +1,87 @@ +//! moment.js locale configuration +//! locale : kazakh (kk) +//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var suffixes = { + 0: '-ші', + 1: '-ші', + 2: '-ші', + 3: '-ші', + 4: '-ші', + 5: '-ші', + 6: '-шы', + 7: '-ші', + 8: '-ші', + 9: '-шы', + 10: '-шы', + 20: '-шы', + 30: '-шы', + 40: '-шы', + 50: '-ші', + 60: '-шы', + 70: '-ші', + 80: '-ші', + 90: '-шы', + 100: '-ші' + }; + + var kk = moment.defineLocale('kk', { + months : 'Қаңтар_Ақпан_Наурыз_Сәуір_Мамыр_Маусым_Шілде_Тамыз_Қыркүйек_Қазан_Қараша_Желтоқсан'.split('_'), + monthsShort : 'Қаң_Ақп_Нау_Сәу_Мам_Мау_Шіл_Там_Қыр_Қаз_Қар_Жел'.split('_'), + weekdays : 'Жексенбі_Дүйсенбі_Сейсенбі_Сәрсенбі_Бейсенбі_Жұма_Сенбі'.split('_'), + weekdaysShort : 'Жек_Дүй_Сей_Сәр_Бей_Жұм_Сен'.split('_'), + weekdaysMin : 'Жк_Дй_Сй_Ср_Бй_Жм_Сн'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Бүгін сағат] LT', + nextDay : '[Ертең сағат] LT', + nextWeek : 'dddd [сағат] LT', + lastDay : '[Кеше сағат] LT', + lastWeek : '[Өткен аптаның] dddd [сағат] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ішінде', + past : '%s бұрын', + s : 'бірнеше секунд', + m : 'бір минут', + mm : '%d минут', + h : 'бір сағат', + hh : '%d сағат', + d : 'бір күн', + dd : '%d күн', + M : 'бір ай', + MM : '%d ай', + y : 'бір жыл', + yy : '%d жыл' + }, + ordinalParse: /\d{1,2}-(ші|шы)/, + ordinal : function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes[number] || suffixes[a] || suffixes[b]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + return kk; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/km.js b/lib/javascripts/moment_locale/km.js index f457e8d1307..56466c91383 100644 --- a/lib/javascripts/moment_locale/km.js +++ b/lib/javascripts/moment_locale/km.js @@ -1,31 +1,31 @@ -// moment.js locale configuration -// locale : khmer (km) -// author : Kruy Vanna : https://github.com/kruyvanna +//! moment.js locale configuration +//! locale : khmer (km) +//! author : Kruy Vanna : https://github.com/kruyvanna -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('km', { - months: "មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"), - monthsShort: "មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"), - weekdays: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"), - weekdaysShort: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"), - weekdaysMin: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var km = moment.defineLocale('km', { + months: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'), + monthsShort: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'), + weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), + weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), + weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), longDateFormat: { - LT: "HH:mm", - L: "DD/MM/YYYY", - LL: "D MMMM YYYY", - LLL: "D MMMM YYYY LT", - LLLL: "dddd, D MMMM YYYY LT" + LT: 'HH:mm', + LTS : 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' }, calendar: { - sameDay: '[ថ្ងៃនៈ ម៉ោង] LT', + sameDay: '[ថ្ងៃនេះ ម៉ោង] LT', nextDay: '[ស្អែក ម៉ោង] LT', nextWeek: 'dddd [ម៉ោង] LT', lastDay: '[ម្សិលមិញ ម៉ោង] LT', @@ -33,23 +33,26 @@ sameElse: 'L' }, relativeTime: { - future: "%sទៀត", - past: "%sមុន", - s: "ប៉ុន្មានវិនាទី", - m: "មួយនាទី", - mm: "%d នាទី", - h: "មួយម៉ោង", - hh: "%d ម៉ោង", - d: "មួយថ្ងៃ", - dd: "%d ថ្ងៃ", - M: "មួយខែ", - MM: "%d ខែ", - y: "មួយឆ្នាំ", - yy: "%d ឆ្នាំ" + future: '%sទៀត', + past: '%sមុន', + s: 'ប៉ុន្មានវិនាទី', + m: 'មួយនាទី', + mm: '%d នាទី', + h: 'មួយម៉ោង', + hh: '%d ម៉ោង', + d: 'មួយថ្ងៃ', + dd: '%d ថ្ងៃ', + M: 'មួយខែ', + MM: '%d ខែ', + y: 'មួយឆ្នាំ', + yy: '%d ឆ្នាំ' }, week: { dow: 1, // Monday is the first day of the week. doy: 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return km; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ko.js b/lib/javascripts/moment_locale/ko.js index 7de2e51033c..151554ab39e 100644 --- a/lib/javascripts/moment_locale/ko.js +++ b/lib/javascripts/moment_locale/ko.js @@ -1,34 +1,32 @@ -// moment.js locale configuration -// locale : korean (ko) -// -// authors -// -// - Kyungwook, Park : https://github.com/kyungw00k -// - Jeeeyul Lee -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('ko', { - months : "1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"), - monthsShort : "1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"), - weekdays : "일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"), - weekdaysShort : "일_월_화_수_목_금_토".split("_"), - weekdaysMin : "일_월_화_수_목_금_토".split("_"), +//! moment.js locale configuration +//! locale : korean (ko) +//! +//! authors +//! +//! - Kyungwook, Park : https://github.com/kyungw00k +//! - Jeeeyul Lee + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var ko = moment.defineLocale('ko', { + months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'), + weekdaysShort : '일_월_화_수_목_금_토'.split('_'), + weekdaysMin : '일_월_화_수_목_금_토'.split('_'), longDateFormat : { - LT : "A h시 mm분", - L : "YYYY.MM.DD", - LL : "YYYY년 MMMM D일", - LLL : "YYYY년 MMMM D일 LT", - LLLL : "YYYY년 MMMM D일 dddd LT" - }, - meridiem : function (hour, minute, isUpper) { - return hour < 12 ? '오전' : '오후'; + LT : 'A h시 m분', + LTS : 'A h시 m분 s초', + L : 'YYYY.MM.DD', + LL : 'YYYY년 MMMM D일', + LLL : 'YYYY년 MMMM D일 A h시 m분', + LLLL : 'YYYY년 MMMM D일 dddd A h시 m분' }, calendar : { sameDay : '오늘 LT', @@ -39,25 +37,32 @@ sameElse : 'L' }, relativeTime : { - future : "%s 후", - past : "%s 전", - s : "몇초", - ss : "%d초", - m : "일분", - mm : "%d분", - h : "한시간", - hh : "%d시간", - d : "하루", - dd : "%d일", - M : "한달", - MM : "%d달", - y : "일년", - yy : "%d년" + future : '%s 후', + past : '%s 전', + s : '몇초', + ss : '%d초', + m : '일분', + mm : '%d분', + h : '한시간', + hh : '%d시간', + d : '하루', + dd : '%d일', + M : '한달', + MM : '%d달', + y : '일년', + yy : '%d년' }, + ordinalParse : /\d{1,2}일/, ordinal : '%d일', - meridiemParse : /(오전|오후)/, + meridiemParse : /오전|오후/, isPM : function (token) { - return token === "오후"; + return token === '오후'; + }, + meridiem : function (hour, minute, isUpper) { + return hour < 12 ? '오전' : '오후'; } }); -})); + + return ko; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/lb.js b/lib/javascripts/moment_locale/lb.js index c878b79c134..6713c08a9ca 100644 --- a/lib/javascripts/moment_locale/lb.js +++ b/lib/javascripts/moment_locale/lb.js @@ -1,20 +1,15 @@ -// moment.js locale configuration -// locale : Luxembourgish (lb) -// author : mweimerskirch : https://github.com/mweimerskirch, David Raison : https://github.com/kwisatz +//! moment.js locale configuration +//! locale : Luxembourgish (lb) +//! author : mweimerskirch : https://github.com/mweimerskirch, David Raison : https://github.com/kwisatz + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; -// Note: Luxembourgish has a very particular phonological rule ("Eifeler Regel") that causes the -// deletion of the final "n" in certain contexts. That's what the "eifelerRegelAppliesToWeekday" -// and "eifelerRegelAppliesToNumber" methods are meant for -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function processRelativeTime(number, withoutSuffix, key, isFuture) { var format = { 'm': ['eng Minutt', 'enger Minutt'], @@ -25,26 +20,23 @@ }; return withoutSuffix ? format[key][0] : format[key][1]; } - function processFutureTime(string) { var number = string.substr(0, string.indexOf(' ')); if (eifelerRegelAppliesToNumber(number)) { - return "a " + string; + return 'a ' + string; } - return "an " + string; + return 'an ' + string; } - function processPastTime(string) { var number = string.substr(0, string.indexOf(' ')); if (eifelerRegelAppliesToNumber(number)) { - return "viru " + string; + return 'viru ' + string; } - return "virun " + string; + return 'virun ' + string; } - /** - * Returns true if the word before the given number loses the "-n" ending. - * e.g. "an 10 Deeg" but "a 5 Deeg" + * Returns true if the word before the given number loses the '-n' ending. + * e.g. 'an 10 Deeg' but 'a 5 Deeg' * * @param number {integer} * @returns {boolean} @@ -83,27 +75,28 @@ } } - return moment.defineLocale('lb', { - months: "Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"), - monthsShort: "Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"), - weekdays: "Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg".split("_"), - weekdaysShort: "So._Mé._Dë._Më._Do._Fr._Sa.".split("_"), - weekdaysMin: "So_Mé_Dë_Më_Do_Fr_Sa".split("_"), + var lb = moment.defineLocale('lb', { + months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), + weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'), + weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'), + weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'), longDateFormat: { - LT: "H:mm [Auer]", - L: "DD.MM.YYYY", - LL: "D. MMMM YYYY", - LLL: "D. MMMM YYYY LT", - LLLL: "dddd, D. MMMM YYYY LT" + LT: 'H:mm [Auer]', + LTS: 'H:mm:ss [Auer]', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm [Auer]', + LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]' }, calendar: { - sameDay: "[Haut um] LT", - sameElse: "L", + sameDay: '[Haut um] LT', + sameElse: 'L', nextDay: '[Muer um] LT', nextWeek: 'dddd [um] LT', lastDay: '[Gëschter um] LT', lastWeek: function () { - // Different date string for "Dënschdeg" (Tuesday) and "Donneschdeg" (Thursday) due to phonological rule + // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule switch (this.day()) { case 2: case 4: @@ -116,22 +109,26 @@ relativeTime : { future : processFutureTime, past : processPastTime, - s : "e puer Sekonnen", + s : 'e puer Sekonnen', m : processRelativeTime, - mm : "%d Minutten", + mm : '%d Minutten', h : processRelativeTime, - hh : "%d Stonnen", + hh : '%d Stonnen', d : processRelativeTime, - dd : "%d Deeg", + dd : '%d Deeg', M : processRelativeTime, - MM : "%d Méint", + MM : '%d Méint', y : processRelativeTime, - yy : "%d Joer" + yy : '%d Joer' }, + ordinalParse: /\d{1,2}\./, ordinal: '%d.', week: { dow: 1, // Monday is the first day of the week. doy: 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return lb; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/lo.js b/lib/javascripts/moment_locale/lo.js new file mode 100644 index 00000000000..7475f273840 --- /dev/null +++ b/lib/javascripts/moment_locale/lo.js @@ -0,0 +1,69 @@ +//! moment.js locale configuration +//! locale : lao (lo) +//! author : Ryan Hart : https://github.com/ryanhart2 + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var lo = moment.defineLocale('lo', { + months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), + monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), + weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'ວັນdddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/, + isPM: function (input) { + return input === 'ຕອນແລງ'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ຕອນເຊົ້າ'; + } else { + return 'ຕອນແລງ'; + } + }, + calendar : { + sameDay : '[ມື້ນີ້ເວລາ] LT', + nextDay : '[ມື້ອື່ນເວລາ] LT', + nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT', + lastDay : '[ມື້ວານນີ້ເວລາ] LT', + lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ອີກ %s', + past : '%sຜ່ານມາ', + s : 'ບໍ່ເທົ່າໃດວິນາທີ', + m : '1 ນາທີ', + mm : '%d ນາທີ', + h : '1 ຊົ່ວໂມງ', + hh : '%d ຊົ່ວໂມງ', + d : '1 ມື້', + dd : '%d ມື້', + M : '1 ເດືອນ', + MM : '%d ເດືອນ', + y : '1 ປີ', + yy : '%d ປີ' + }, + ordinalParse: /(ທີ່)\d{1,2}/, + ordinal : function (number) { + return 'ທີ່' + number; + } + }); + + return lo; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/lt.js b/lib/javascripts/moment_locale/lt.js index 7d7b93f10a9..72566bfee99 100644 --- a/lib/javascripts/moment_locale/lt.js +++ b/lib/javascripts/moment_locale/lt.js @@ -1,52 +1,45 @@ -// moment.js locale configuration -// locale : Lithuanian (lt) -// author : Mindaugas Mozūras : https://github.com/mmozuras +//! moment.js locale configuration +//! locale : Lithuanian (lt) +//! author : Mindaugas Mozūras : https://github.com/mmozuras + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var units = { - "m" : "minutė_minutės_minutę", - "mm": "minutės_minučių_minutes", - "h" : "valanda_valandos_valandą", - "hh": "valandos_valandų_valandas", - "d" : "diena_dienos_dieną", - "dd": "dienos_dienų_dienas", - "M" : "mėnuo_mėnesio_mėnesį", - "MM": "mėnesiai_mėnesių_mėnesius", - "y" : "metai_metų_metus", - "yy": "metai_metų_metus" - }, - weekDays = "sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis".split("_"); - + 'm' : 'minutė_minutės_minutę', + 'mm': 'minutės_minučių_minutes', + 'h' : 'valanda_valandos_valandą', + 'hh': 'valandos_valandų_valandas', + 'd' : 'diena_dienos_dieną', + 'dd': 'dienos_dienų_dienas', + 'M' : 'mėnuo_mėnesio_mėnesį', + 'MM': 'mėnesiai_mėnesių_mėnesius', + 'y' : 'metai_metų_metus', + 'yy': 'metai_metų_metus' + }; function translateSeconds(number, withoutSuffix, key, isFuture) { if (withoutSuffix) { - return "kelios sekundės"; + return 'kelios sekundės'; } else { - return isFuture ? "kelių sekundžių" : "kelias sekundes"; + return isFuture ? 'kelių sekundžių' : 'kelias sekundes'; } } - function translateSingular(number, withoutSuffix, key, isFuture) { return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]); } - function special(number) { return number % 10 === 0 || (number > 10 && number < 20); } - function forms(key) { - return units[key].split("_"); + return units[key].split('_'); } - function translate(number, withoutSuffix, key, isFuture) { - var result = number + " "; + var result = number + ' '; if (number === 1) { return result + translateSingular(number, withoutSuffix, key[0], isFuture); } else if (withoutSuffix) { @@ -59,42 +52,42 @@ } } } - - function relativeWeekDay(moment, format) { - var nominative = format.indexOf('dddd HH:mm') === -1, - weekDay = weekDays[moment.day()]; - - return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + "į"; - } - - return moment.defineLocale("lt", { - months : "sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"), - monthsShort : "sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"), - weekdays : relativeWeekDay, - weekdaysShort : "Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"), - weekdaysMin : "S_P_A_T_K_Pn_Š".split("_"), + var lt = moment.defineLocale('lt', { + months : { + format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'), + standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_') + }, + monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'), + weekdays : { + format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'), + standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'), + isFormat: /dddd HH:mm/ + }, + weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'), + weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "YYYY-MM-DD", - LL : "YYYY [m.] MMMM D [d.]", - LLL : "YYYY [m.] MMMM D [d.], LT [val.]", - LLLL : "YYYY [m.] MMMM D [d.], dddd, LT [val.]", - l : "YYYY-MM-DD", - ll : "YYYY [m.] MMMM D [d.]", - lll : "YYYY [m.] MMMM D [d.], LT [val.]", - llll : "YYYY [m.] MMMM D [d.], ddd, LT [val.]" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY [m.] MMMM D [d.]', + LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]', + l : 'YYYY-MM-DD', + ll : 'YYYY [m.] MMMM D [d.]', + lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]' }, calendar : { - sameDay : "[Šiandien] LT", - nextDay : "[Rytoj] LT", - nextWeek : "dddd LT", - lastDay : "[Vakar] LT", - lastWeek : "[Praėjusį] dddd LT", - sameElse : "L" + sameDay : '[Šiandien] LT', + nextDay : '[Rytoj] LT', + nextWeek : 'dddd LT', + lastDay : '[Vakar] LT', + lastWeek : '[Praėjusį] dddd LT', + sameElse : 'L' }, relativeTime : { - future : "po %s", - past : "prieš %s", + future : 'po %s', + past : 'prieš %s', s : translateSeconds, m : translateSingular, mm : translate, @@ -107,6 +100,7 @@ y : translateSingular, yy : translate }, + ordinalParse: /\d{1,2}-oji/, ordinal : function (number) { return number + '-oji'; }, @@ -115,4 +109,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return lt; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/lv.js b/lib/javascripts/moment_locale/lv.js index 0df007d7480..d1864a187e5 100644 --- a/lib/javascripts/moment_locale/lv.js +++ b/lib/javascripts/moment_locale/lv.js @@ -1,49 +1,64 @@ -// moment.js locale configuration -// locale : latvian (lv) -// author : Kristaps Karlsons : https://github.com/skakri +//! moment.js locale configuration +//! locale : latvian (lv) +//! author : Kristaps Karlsons : https://github.com/skakri +//! author : Jānis Elmeris : https://github.com/JanisE + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var units = { - 'mm': 'minūti_minūtes_minūte_minūtes', - 'hh': 'stundu_stundas_stunda_stundas', - 'dd': 'dienu_dienas_diena_dienas', - 'MM': 'mēnesi_mēnešus_mēnesis_mēneši', - 'yy': 'gadu_gadus_gads_gadi' + 'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), + 'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), + 'h': 'stundas_stundām_stunda_stundas'.split('_'), + 'hh': 'stundas_stundām_stunda_stundas'.split('_'), + 'd': 'dienas_dienām_diena_dienas'.split('_'), + 'dd': 'dienas_dienām_diena_dienas'.split('_'), + 'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + 'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + 'y': 'gada_gadiem_gads_gadi'.split('_'), + 'yy': 'gada_gadiem_gads_gadi'.split('_') }; - - function format(word, number, withoutSuffix) { - var forms = word.split('_'); + /** + * @param withoutSuffix boolean true = a length of time; false = before/after a period of time. + */ + function format(forms, number, withoutSuffix) { if (withoutSuffix) { + // E.g. "21 minūte", "3 minūtes". return number % 10 === 1 && number !== 11 ? forms[2] : forms[3]; } else { + // E.g. "21 minūtes" as in "pēc 21 minūtes". + // E.g. "3 minūtēm" as in "pēc 3 minūtēm". return number % 10 === 1 && number !== 11 ? forms[0] : forms[1]; } } - function relativeTimeWithPlural(number, withoutSuffix, key) { return number + ' ' + format(units[key], number, withoutSuffix); } + function relativeTimeWithSingular(number, withoutSuffix, key) { + return format(units[key], number, withoutSuffix); + } + function relativeSeconds(number, withoutSuffix) { + return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm'; + } - return moment.defineLocale('lv', { - months : "janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"), - monthsShort : "jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"), - weekdays : "svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"), - weekdaysShort : "Sv_P_O_T_C_Pk_S".split("_"), - weekdaysMin : "Sv_P_O_T_C_Pk_S".split("_"), + var lv = moment.defineLocale('lv', { + months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'), + weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'), + weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "YYYY. [gada] D. MMMM", - LLL : "YYYY. [gada] D. MMMM, LT", - LLLL : "YYYY. [gada] D. MMMM, dddd, LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY.', + LL : 'YYYY. [gada] D. MMMM', + LLL : 'YYYY. [gada] D. MMMM, HH:mm', + LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm' }, calendar : { sameDay : '[Šodien pulksten] LT', @@ -54,24 +69,28 @@ sameElse : 'L' }, relativeTime : { - future : "%s vēlāk", - past : "%s agrāk", - s : "dažas sekundes", - m : "minūti", + future : 'pēc %s', + past : 'pirms %s', + s : relativeSeconds, + m : relativeTimeWithSingular, mm : relativeTimeWithPlural, - h : "stundu", + h : relativeTimeWithSingular, hh : relativeTimeWithPlural, - d : "dienu", + d : relativeTimeWithSingular, dd : relativeTimeWithPlural, - M : "mēnesi", + M : relativeTimeWithSingular, MM : relativeTimeWithPlural, - y : "gadu", + y : relativeTimeWithSingular, yy : relativeTimeWithPlural }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return lv; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/me.js b/lib/javascripts/moment_locale/me.js new file mode 100644 index 00000000000..e2c1f750e13 --- /dev/null +++ b/lib/javascripts/moment_locale/me.js @@ -0,0 +1,109 @@ +//! moment.js locale configuration +//! locale : Montenegrin (me) +//! author : Miodrag Nikač : https://github.com/miodragnikac + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var translator = { + words: { //Different grammatical cases + m: ['jedan minut', 'jednog minuta'], + mm: ['minut', 'minuta', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mjesec', 'mjeseca', 'mjeseci'], + yy: ['godina', 'godine', 'godina'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator.correctGrammaticalCase(number, wordKey); + } + } + }; + + var me = moment.defineLocale('me', { + months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'], + monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'], + weekdays: ['nedjelja', 'ponedjeljak', 'utorak', 'srijeda', 'četvrtak', 'petak', 'subota'], + weekdaysShort: ['ned.', 'pon.', 'uto.', 'sri.', 'čet.', 'pet.', 'sub.'], + weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'], + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD. MM. YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sjutra u] LT', + + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[juče u] LT', + lastWeek : function () { + var lastWeekDays = [ + '[prošle] [nedjelje] [u] LT', + '[prošlog] [ponedjeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srijede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'nekoliko sekundi', + m : translator.translate, + mm : translator.translate, + h : translator.translate, + hh : translator.translate, + d : 'dan', + dd : translator.translate, + M : 'mjesec', + MM : translator.translate, + y : 'godinu', + yy : translator.translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + return me; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/mk.js b/lib/javascripts/moment_locale/mk.js index 2d8a739abb1..89b5414c115 100644 --- a/lib/javascripts/moment_locale/mk.js +++ b/lib/javascripts/moment_locale/mk.js @@ -1,64 +1,65 @@ -// moment.js locale configuration -// locale : macedonian (mk) -// author : Borislav Mickov : https://github.com/B0k0 +//! moment.js locale configuration +//! locale : macedonian (mk) +//! author : Borislav Mickov : https://github.com/B0k0 -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('mk', { - months : "јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември".split("_"), - monthsShort : "јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек".split("_"), - weekdays : "недела_понеделник_вторник_среда_четврток_петок_сабота".split("_"), - weekdaysShort : "нед_пон_вто_сре_чет_пет_саб".split("_"), - weekdaysMin : "нe_пo_вт_ср_че_пе_сa".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var mk = moment.defineLocale('mk', { + months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'), + monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'), + weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'), + weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'), + weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'), longDateFormat : { - LT : "H:mm", - L : "D.MM.YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'D.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' }, calendar : { sameDay : '[Денес во] LT', nextDay : '[Утре во] LT', - nextWeek : 'dddd [во] LT', + nextWeek : '[Во] dddd [во] LT', lastDay : '[Вчера во] LT', lastWeek : function () { switch (this.day()) { case 0: case 3: case 6: - return '[Во изминатата] dddd [во] LT'; + return '[Изминатата] dddd [во] LT'; case 1: case 2: case 4: case 5: - return '[Во изминатиот] dddd [во] LT'; + return '[Изминатиот] dddd [во] LT'; } }, sameElse : 'L' }, relativeTime : { - future : "после %s", - past : "пред %s", - s : "неколку секунди", - m : "минута", - mm : "%d минути", - h : "час", - hh : "%d часа", - d : "ден", - dd : "%d дена", - M : "месец", - MM : "%d месеци", - y : "година", - yy : "%d години" + future : 'после %s', + past : 'пред %s', + s : 'неколку секунди', + m : 'минута', + mm : '%d минути', + h : 'час', + hh : '%d часа', + d : 'ден', + dd : '%d дена', + M : 'месец', + MM : '%d месеци', + y : 'година', + yy : '%d години' }, + ordinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, ordinal : function (number) { var lastDigit = number % 10, last2Digits = number % 100; @@ -83,4 +84,7 @@ doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return mk; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ml.js b/lib/javascripts/moment_locale/ml.js index d3cee1d3f30..9e241f26912 100644 --- a/lib/javascripts/moment_locale/ml.js +++ b/lib/javascripts/moment_locale/ml.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : malayalam (ml) -// author : Floyd Pink : https://github.com/floydpink +//! moment.js locale configuration +//! locale : malayalam (ml) +//! author : Floyd Pink : https://github.com/floydpink -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('ml', { - months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split("_"), - monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split("_"), - weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split("_"), - weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split("_"), - weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var ml = moment.defineLocale('ml', { + months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'), + monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'), + weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'), + weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'), + weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'), longDateFormat : { - LT : "A h:mm -നു", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY, LT", - LLLL : "dddd, D MMMM YYYY, LT" + LT : 'A h:mm -നു', + LTS : 'A h:mm:ss -നു', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm -നു', + LLLL : 'dddd, D MMMM YYYY, A h:mm -നു' }, calendar : { sameDay : '[ഇന്ന്] LT', @@ -33,32 +33,39 @@ sameElse : 'L' }, relativeTime : { - future : "%s കഴിഞ്ഞ്", - past : "%s മുൻപ്", - s : "അൽപ നിമിഷങ്ങൾ", - m : "ഒരു മിനിറ്റ്", - mm : "%d മിനിറ്റ്", - h : "ഒരു മണിക്കൂർ", - hh : "%d മണിക്കൂർ", - d : "ഒരു ദിവസം", - dd : "%d ദിവസം", - M : "ഒരു മാസം", - MM : "%d മാസം", - y : "ഒരു വർഷം", - yy : "%d വർഷം" + future : '%s കഴിഞ്ഞ്', + past : '%s മുൻപ്', + s : 'അൽപ നിമിഷങ്ങൾ', + m : 'ഒരു മിനിറ്റ്', + mm : '%d മിനിറ്റ്', + h : 'ഒരു മണിക്കൂർ', + hh : '%d മണിക്കൂർ', + d : 'ഒരു ദിവസം', + dd : '%d ദിവസം', + M : 'ഒരു മാസം', + MM : '%d മാസം', + y : 'ഒരു വർഷം', + yy : '%d വർഷം' + }, + meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i, + isPM : function (input) { + return /^(ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി)$/.test(input); }, meridiem : function (hour, minute, isLower) { if (hour < 4) { - return "രാത്രി"; + return 'രാത്രി'; } else if (hour < 12) { - return "രാവിലെ"; + return 'രാവിലെ'; } else if (hour < 17) { - return "ഉച്ച കഴിഞ്ഞ്"; + return 'ഉച്ച കഴിഞ്ഞ്'; } else if (hour < 20) { - return "വൈകുന്നേരം"; + return 'വൈകുന്നേരം'; } else { - return "രാത്രി"; + return 'രാത്രി'; } } }); -})); + + return ml; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/mr.js b/lib/javascripts/moment_locale/mr.js index 8cbfe7cf97d..77a3fa2f06c 100644 --- a/lib/javascripts/moment_locale/mr.js +++ b/lib/javascripts/moment_locale/mr.js @@ -1,16 +1,16 @@ -// moment.js locale configuration -// locale : Marathi (mr) -// author : Harshad Kale : https://github.com/kalehv +//! moment.js locale configuration +//! locale : Marathi (mr) +//! author : Harshad Kale : https://github.com/kalehv +//! author : Vivek Athalye : https://github.com/vnathalye + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var symbolMap = { '1': '१', '2': '२', @@ -36,18 +36,55 @@ '०': '0' }; - return moment.defineLocale('mr', { - months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split("_"), - monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split("_"), - weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split("_"), - weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split("_"), - weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split("_"), + function relativeTimeMr(number, withoutSuffix, string, isFuture) + { + var output = ''; + if (withoutSuffix) { + switch (string) { + case 's': output = 'काही सेकंद'; break; + case 'm': output = 'एक मिनिट'; break; + case 'mm': output = '%d मिनिटे'; break; + case 'h': output = 'एक तास'; break; + case 'hh': output = '%d तास'; break; + case 'd': output = 'एक दिवस'; break; + case 'dd': output = '%d दिवस'; break; + case 'M': output = 'एक महिना'; break; + case 'MM': output = '%d महिने'; break; + case 'y': output = 'एक वर्ष'; break; + case 'yy': output = '%d वर्षे'; break; + } + } + else { + switch (string) { + case 's': output = 'काही सेकंदां'; break; + case 'm': output = 'एका मिनिटा'; break; + case 'mm': output = '%d मिनिटां'; break; + case 'h': output = 'एका तासा'; break; + case 'hh': output = '%d तासां'; break; + case 'd': output = 'एका दिवसा'; break; + case 'dd': output = '%d दिवसां'; break; + case 'M': output = 'एका महिन्या'; break; + case 'MM': output = '%d महिन्यां'; break; + case 'y': output = 'एका वर्षा'; break; + case 'yy': output = '%d वर्षां'; break; + } + } + return output.replace(/%d/i, number); + } + + var mr = moment.defineLocale('mr', { + months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'), + monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'), + weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), longDateFormat : { - LT : "A h:mm वाजता", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY, LT", - LLLL : "dddd, D MMMM YYYY, LT" + LT : 'A h:mm वाजता', + LTS : 'A h:mm:ss वाजता', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm वाजता', + LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता' }, calendar : { sameDay : '[आज] LT', @@ -58,19 +95,19 @@ sameElse : 'L' }, relativeTime : { - future : "%s नंतर", - past : "%s पूर्वी", - s : "सेकंद", - m: "एक मिनिट", - mm: "%d मिनिटे", - h : "एक तास", - hh : "%d तास", - d : "एक दिवस", - dd : "%d दिवस", - M : "एक महिना", - MM : "%d महिने", - y : "एक वर्ष", - yy : "%d वर्षे" + future: '%sमध्ये', + past: '%sपूर्वी', + s: relativeTimeMr, + m: relativeTimeMr, + mm: relativeTimeMr, + h: relativeTimeMr, + hh: relativeTimeMr, + d: relativeTimeMr, + dd: relativeTimeMr, + M: relativeTimeMr, + MM: relativeTimeMr, + y: relativeTimeMr, + yy: relativeTimeMr }, preparse: function (string) { return string.replace(/[१२३४५६७८९०]/g, function (match) { @@ -82,18 +119,32 @@ return symbolMap[match]; }); }, - meridiem: function (hour, minute, isLower) - { + meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात्री') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सकाळी') { + return hour; + } else if (meridiem === 'दुपारी') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'सायंकाळी') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { if (hour < 4) { - return "रात्री"; + return 'रात्री'; } else if (hour < 10) { - return "सकाळी"; + return 'सकाळी'; } else if (hour < 17) { - return "दुपारी"; + return 'दुपारी'; } else if (hour < 20) { - return "सायंकाळी"; + return 'सायंकाळी'; } else { - return "रात्री"; + return 'रात्री'; } }, week : { @@ -101,4 +152,7 @@ doy : 6 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return mr; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ms-my.js b/lib/javascripts/moment_locale/ms-my.js index eee412f6bcd..38c31387806 100644 --- a/lib/javascripts/moment_locale/ms-my.js +++ b/lib/javascripts/moment_locale/ms-my.js @@ -1,28 +1,41 @@ -// moment.js locale configuration -// locale : Bahasa Malaysia (ms-MY) -// author : Weldan Jamili : https://github.com/weldan +//! moment.js locale configuration +//! locale : Bahasa Malaysia (ms-MY) +//! author : Weldan Jamili : https://github.com/weldan -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('ms-my', { - months : "Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"), - monthsShort : "Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"), - weekdays : "Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"), - weekdaysShort : "Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"), - weekdaysMin : "Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var ms_my = moment.defineLocale('ms-my', { + months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), longDateFormat : { - LT : "HH.mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY [pukul] LT", - LLLL : "dddd, D MMMM YYYY [pukul] LT" + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } }, meridiem : function (hours, minutes, isLower) { if (hours < 11) { @@ -44,23 +57,26 @@ sameElse : 'L' }, relativeTime : { - future : "dalam %s", - past : "%s yang lepas", - s : "beberapa saat", - m : "seminit", - mm : "%d minit", - h : "sejam", - hh : "%d jam", - d : "sehari", - dd : "%d hari", - M : "sebulan", - MM : "%d bulan", - y : "setahun", - yy : "%d tahun" + future : 'dalam %s', + past : '%s yang lepas', + s : 'beberapa saat', + m : 'seminit', + mm : '%d minit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' }, week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return ms_my; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ms.js b/lib/javascripts/moment_locale/ms.js new file mode 100644 index 00000000000..fbbb734d1d5 --- /dev/null +++ b/lib/javascripts/moment_locale/ms.js @@ -0,0 +1,82 @@ +//! moment.js locale configuration +//! locale : Bahasa Malaysia (ms-MY) +//! author : Weldan Jamili : https://github.com/weldan + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var ms = moment.defineLocale('ms', { + months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Esok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kelmarin pukul] LT', + lastWeek : 'dddd [lepas pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dalam %s', + past : '%s yang lepas', + s : 'beberapa saat', + m : 'seminit', + mm : '%d minit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + return ms; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/my.js b/lib/javascripts/moment_locale/my.js index 442d5693c1e..71e99f0ed80 100644 --- a/lib/javascripts/moment_locale/my.js +++ b/lib/javascripts/moment_locale/my.js @@ -1,16 +1,15 @@ -// moment.js locale configuration -// locale : Burmese (my) -// author : Squar team, mysquar.com +//! moment.js locale configuration +//! locale : Burmese (my) +//! author : Squar team, mysquar.com + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var symbolMap = { '1': '၁', '2': '၂', @@ -34,18 +33,21 @@ '၉': '9', '၀': '0' }; - return moment.defineLocale('my', { - months: "ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ".split("_"), - monthsShort: "ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ".split("_"), - weekdays: "တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ".split("_"), - weekdaysShort: "နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ".split("_"), - weekdaysMin: "နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ".split("_"), + + var my = moment.defineLocale('my', { + months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'), + monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'), + weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'), + weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + longDateFormat: { - LT: "HH:mm", - L: "DD/MM/YYYY", - LL: "D MMMM YYYY", - LLL: "D MMMM YYYY LT", - LLLL: "dddd D MMMM YYYY LT" + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm' }, calendar: { sameDay: '[ယနေ.] LT [မှာ]', @@ -56,19 +58,19 @@ sameElse: 'L' }, relativeTime: { - future: "လာမည့် %s မှာ", - past: "လွန်ခဲ့သော %s က", - s: "စက္ကန်.အနည်းငယ်", - m: "တစ်မိနစ်", - mm: "%d မိနစ်", - h: "တစ်နာရီ", - hh: "%d နာရီ", - d: "တစ်ရက်", - dd: "%d ရက်", - M: "တစ်လ", - MM: "%d လ", - y: "တစ်နှစ်", - yy: "%d နှစ်" + future: 'လာမည့် %s မှာ', + past: 'လွန်ခဲ့သော %s က', + s: 'စက္ကန်.အနည်းငယ်', + m: 'တစ်မိနစ်', + mm: '%d မိနစ်', + h: 'တစ်နာရီ', + hh: '%d နာရီ', + d: 'တစ်ရက်', + dd: '%d ရက်', + M: 'တစ်လ', + MM: '%d လ', + y: 'တစ်နှစ်', + yy: '%d နှစ်' }, preparse: function (string) { return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) { @@ -85,4 +87,7 @@ doy: 4 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return my; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/nb.js b/lib/javascripts/moment_locale/nb.js index 5e4a511a37f..b8d76c63150 100644 --- a/lib/javascripts/moment_locale/nb.js +++ b/lib/javascripts/moment_locale/nb.js @@ -1,29 +1,29 @@ -// moment.js locale configuration -// locale : norwegian bokmål (nb) -// authors : Espen Hovlandsdal : https://github.com/rexxars -// Sigurd Gartmann : https://github.com/sigurdga +//! moment.js locale configuration +//! locale : norwegian bokmål (nb) +//! authors : Espen Hovlandsdal : https://github.com/rexxars +//! Sigurd Gartmann : https://github.com/sigurdga -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('nb', { - months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"), - monthsShort : "jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"), - weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"), - weekdaysShort : "sø._ma._ti._on._to._fr._lø.".split("_"), - weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var nb = moment.defineLocale('nb', { + months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'), + weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'), + weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), longDateFormat : { - LT : "H.mm", - L : "DD.MM.YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY [kl.] LT", - LLLL : "dddd D. MMMM YYYY [kl.] LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] HH:mm', + LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' }, calendar : { sameDay: '[i dag kl.] LT', @@ -34,24 +34,28 @@ sameElse: 'L' }, relativeTime : { - future : "om %s", - past : "for %s siden", - s : "noen sekunder", - m : "ett minutt", - mm : "%d minutter", - h : "en time", - hh : "%d timer", - d : "en dag", - dd : "%d dager", - M : "en måned", - MM : "%d måneder", - y : "ett år", - yy : "%d år" + future : 'om %s', + past : 'for %s siden', + s : 'noen sekunder', + m : 'ett minutt', + mm : '%d minutter', + h : 'en time', + hh : '%d timer', + d : 'en dag', + dd : '%d dager', + M : 'en måned', + MM : '%d måneder', + y : 'ett år', + yy : '%d år' }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return nb; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/nb_NO.js b/lib/javascripts/moment_locale/nb_NO.js deleted file mode 100644 index faa1aa2378e..00000000000 --- a/lib/javascripts/moment_locale/nb_NO.js +++ /dev/null @@ -1,46 +0,0 @@ -// moment.js language configuration -// language : norwegian bokmål (nb) -// author : Espen Hovlandsdal : https://github.com/rexxars - -moment.lang('nb_NO', { - months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"), - monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"), - weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"), - weekdaysShort : "søn_man_tir_ons_tor_fre_lør".split("_"), - weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "YYYY-MM-DD", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" - }, - calendar : { - sameDay: '[I dag klokken] LT', - nextDay: '[I morgen klokken] LT', - nextWeek: 'dddd [klokken] LT', - lastDay: '[I går klokken] LT', - lastWeek: '[Forrige] dddd [klokken] LT', - sameElse: 'L' - }, - relativeTime : { - future : "om %s", - past : "for %s siden", - s : "noen sekunder", - m : "ett minutt", - mm : "%d minutter", - h : "en time", - hh : "%d timer", - d : "en dag", - dd : "%d dager", - M : "en måned", - MM : "%d måneder", - y : "ett år", - yy : "%d år" - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } -}); diff --git a/lib/javascripts/moment_locale/ne.js b/lib/javascripts/moment_locale/ne.js index 836fb4d476f..347640156b6 100644 --- a/lib/javascripts/moment_locale/ne.js +++ b/lib/javascripts/moment_locale/ne.js @@ -1,16 +1,15 @@ -// moment.js locale configuration -// locale : nepali/nepalese -// author : suvash : https://github.com/suvash +//! moment.js locale configuration +//! locale : nepali/nepalese +//! author : suvash : https://github.com/suvash + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var symbolMap = { '1': '१', '2': '२', @@ -36,18 +35,19 @@ '०': '0' }; - return moment.defineLocale('ne', { - months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split("_"), - monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split("_"), - weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split("_"), - weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split("_"), - weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split("_"), + var ne = moment.defineLocale('ne', { + months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'), + monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'), + weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'), + weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'), + weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'), longDateFormat : { - LT : "Aको h:mm बजे", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY, LT", - LLLL : "dddd, D MMMM YYYY, LT" + LT : 'Aको h:mm बजे', + LTS : 'Aको h:mm:ss बजे', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, Aको h:mm बजे', + LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे' }, preparse: function (string) { return string.replace(/[१२३४५६७८९०]/g, function (match) { @@ -59,47 +59,63 @@ return symbolMap[match]; }); }, + meridiemParse: /राति|बिहान|दिउँसो|साँझ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'राति') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'बिहान') { + return hour; + } else if (meridiem === 'दिउँसो') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'साँझ') { + return hour + 12; + } + }, meridiem : function (hour, minute, isLower) { if (hour < 3) { - return "राती"; - } else if (hour < 10) { - return "बिहान"; - } else if (hour < 15) { - return "दिउँसो"; - } else if (hour < 18) { - return "बेलुका"; + return 'राति'; + } else if (hour < 12) { + return 'बिहान'; + } else if (hour < 16) { + return 'दिउँसो'; } else if (hour < 20) { - return "साँझ"; + return 'साँझ'; } else { - return "राती"; + return 'राति'; } }, calendar : { sameDay : '[आज] LT', - nextDay : '[भोली] LT', + nextDay : '[भोलि] LT', nextWeek : '[आउँदो] dddd[,] LT', lastDay : '[हिजो] LT', lastWeek : '[गएको] dddd[,] LT', sameElse : 'L' }, relativeTime : { - future : "%sमा", - past : "%s अगाडी", - s : "केही समय", - m : "एक मिनेट", - mm : "%d मिनेट", - h : "एक घण्टा", - hh : "%d घण्टा", - d : "एक दिन", - dd : "%d दिन", - M : "एक महिना", - MM : "%d महिना", - y : "एक बर्ष", - yy : "%d बर्ष" + future : '%sमा', + past : '%s अगाडि', + s : 'केही क्षण', + m : 'एक मिनेट', + mm : '%d मिनेट', + h : 'एक घण्टा', + hh : '%d घण्टा', + d : 'एक दिन', + dd : '%d दिन', + M : 'एक महिना', + MM : '%d महिना', + y : 'एक बर्ष', + yy : '%d बर्ष' }, week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return ne; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/nl.js b/lib/javascripts/moment_locale/nl.js index 15776736ca8..1ae4700d6a9 100644 --- a/lib/javascripts/moment_locale/nl.js +++ b/lib/javascripts/moment_locale/nl.js @@ -1,21 +1,20 @@ -// moment.js locale configuration -// locale : dutch (nl) -// author : Joris Röling : https://github.com/jjupiter +//! moment.js locale configuration +//! locale : dutch (nl) +//! author : Joris Röling : https://github.com/jjupiter -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - var monthsShortWithDots = "jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"), - monthsShortWithoutDots = "jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"); +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; - return moment.defineLocale('nl', { - months : "januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"), + + var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); + + var nl = moment.defineLocale('nl', { + months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), monthsShort : function (m, format) { if (/-MMM-/.test(format)) { return monthsShortWithoutDots[m.month()]; @@ -23,15 +22,16 @@ return monthsShortWithDots[m.month()]; } }, - weekdays : "zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"), - weekdaysShort : "zo._ma._di._wo._do._vr._za.".split("_"), - weekdaysMin : "Zo_Ma_Di_Wo_Do_Vr_Za".split("_"), + weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), + weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), + weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD-MM-YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { sameDay: '[vandaag om] LT', @@ -42,20 +42,21 @@ sameElse: 'L' }, relativeTime : { - future : "over %s", - past : "%s geleden", - s : "een paar seconden", - m : "één minuut", - mm : "%d minuten", - h : "één uur", - hh : "%d uur", - d : "één dag", - dd : "%d dagen", - M : "één maand", - MM : "%d maanden", - y : "één jaar", - yy : "%d jaar" + future : 'over %s', + past : '%s geleden', + s : 'een paar seconden', + m : 'één minuut', + mm : '%d minuten', + h : 'één uur', + hh : '%d uur', + d : 'één dag', + dd : '%d dagen', + M : 'één maand', + MM : '%d maanden', + y : 'één jaar', + yy : '%d jaar' }, + ordinalParse: /\d{1,2}(ste|de)/, ordinal : function (number) { return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); }, @@ -64,4 +65,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return nl; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/nn.js b/lib/javascripts/moment_locale/nn.js index e479b4582cc..3910bb9be6e 100644 --- a/lib/javascripts/moment_locale/nn.js +++ b/lib/javascripts/moment_locale/nn.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : norwegian nynorsk (nn) -// author : https://github.com/mechuwind +//! moment.js locale configuration +//! locale : norwegian nynorsk (nn) +//! author : https://github.com/mechuwind -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('nn', { - months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"), - monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"), - weekdays : "sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"), - weekdaysShort : "sun_mån_tys_ons_tor_fre_lau".split("_"), - weekdaysMin : "su_må_ty_on_to_fr_lø".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var nn = moment.defineLocale('nn', { + months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'), + weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'), + weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] H:mm', + LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' }, calendar : { sameDay: '[I dag klokka] LT', @@ -33,24 +33,28 @@ sameElse: 'L' }, relativeTime : { - future : "om %s", - past : "for %s sidan", - s : "nokre sekund", - m : "eit minutt", - mm : "%d minutt", - h : "ein time", - hh : "%d timar", - d : "ein dag", - dd : "%d dagar", - M : "ein månad", - MM : "%d månader", - y : "eit år", - yy : "%d år" + future : 'om %s', + past : 'for %s sidan', + s : 'nokre sekund', + m : 'eit minutt', + mm : '%d minutt', + h : 'ein time', + hh : '%d timar', + d : 'ein dag', + dd : '%d dagar', + M : 'ein månad', + MM : '%d månader', + y : 'eit år', + yy : '%d år' }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return nn; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/pl.js b/lib/javascripts/moment_locale/pl.js index 75e978bd239..fa8157943b4 100644 --- a/lib/javascripts/moment_locale/pl.js +++ b/lib/javascripts/moment_locale/pl.js @@ -1,25 +1,22 @@ -// moment.js locale configuration -// locale : polish (pl) -// author : Rafal Hirsz : https://github.com/evoL +//! moment.js locale configuration +//! locale : polish (pl) +//! author : Rafal Hirsz : https://github.com/evoL -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - var monthsNominative = "styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"), - monthsSubjective = "stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_"); +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'), + monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_'); function plural(n) { return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1); } - function translate(number, withoutSuffix, key) { - var result = number + " "; + var result = number + ' '; switch (key) { case 'm': return withoutSuffix ? 'minuta' : 'minutę'; @@ -36,24 +33,30 @@ } } - return moment.defineLocale('pl', { + var pl = moment.defineLocale('pl', { months : function (momentToFormat, format) { - if (/D MMMM/.test(format)) { + if (format === '') { + // Hack: if format empty we know this is used to generate + // RegExp by moment. Give then back both valid forms of months + // in RegExp ready format. + return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')'; + } else if (/D MMMM/.test(format)) { return monthsSubjective[momentToFormat.month()]; } else { return monthsNominative[momentToFormat.month()]; } }, - monthsShort : "sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"), - weekdays : "niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"), - weekdaysShort : "nie_pon_wt_śr_czw_pt_sb".split("_"), - weekdaysMin : "N_Pn_Wt_Śr_Cz_Pt_So".split("_"), + monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'), + weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'), + weekdaysShort : 'nie_pon_wt_śr_czw_pt_sb'.split('_'), + weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { sameDay: '[Dziś o] LT', @@ -75,24 +78,28 @@ sameElse: 'L' }, relativeTime : { - future : "za %s", - past : "%s temu", - s : "kilka sekund", + future : 'za %s', + past : '%s temu', + s : 'kilka sekund', m : translate, mm : translate, h : translate, hh : translate, - d : "1 dzień", + d : '1 dzień', dd : '%d dni', - M : "miesiąc", + M : 'miesiąc', MM : translate, - y : "rok", + y : 'rok', yy : translate }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return pl; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/pt-br.js b/lib/javascripts/moment_locale/pt-br.js index d577018facc..06747f6fda0 100644 --- a/lib/javascripts/moment_locale/pt-br.js +++ b/lib/javascripts/moment_locale/pt-br.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : brazilian portuguese (pt-br) -// author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira +//! moment.js locale configuration +//! locale : brazilian portuguese (pt-br) +//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('pt-br', { - months : "janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"), - monthsShort : "jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"), - weekdays : "domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"), - weekdaysShort : "dom_seg_ter_qua_qui_sex_sáb".split("_"), - weekdaysMin : "dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var pt_br = moment.defineLocale('pt-br', { + months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'), + monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), + weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'), + weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D [de] MMMM [de] YYYY", - LLL : "D [de] MMMM [de] YYYY [às] LT", - LLLL : "dddd, D [de] MMMM [de] YYYY [às] LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY [às] HH:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm' }, calendar : { sameDay: '[Hoje às] LT', @@ -37,20 +37,24 @@ sameElse: 'L' }, relativeTime : { - future : "em %s", - past : "%s atrás", - s : "segundos", - m : "um minuto", - mm : "%d minutos", - h : "uma hora", - hh : "%d horas", - d : "um dia", - dd : "%d dias", - M : "um mês", - MM : "%d meses", - y : "um ano", - yy : "%d anos" + future : 'em %s', + past : '%s atrás', + s : 'poucos segundos', + m : 'um minuto', + mm : '%d minutos', + h : 'uma hora', + hh : '%d horas', + d : 'um dia', + dd : '%d dias', + M : 'um mês', + MM : '%d meses', + y : 'um ano', + yy : '%d anos' }, + ordinalParse: /\d{1,2}º/, ordinal : '%dº' }); -})); + + return pt_br; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/pt.js b/lib/javascripts/moment_locale/pt.js index 808641483df..bdb913fc0f7 100644 --- a/lib/javascripts/moment_locale/pt.js +++ b/lib/javascripts/moment_locale/pt.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : portuguese (pt) -// author : Jefferson : https://github.com/jalex79 +//! moment.js locale configuration +//! locale : portuguese (pt) +//! author : Jefferson : https://github.com/jalex79 -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('pt', { - months : "janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"), - monthsShort : "jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"), - weekdays : "domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"), - weekdaysShort : "dom_seg_ter_qua_qui_sex_sáb".split("_"), - weekdaysMin : "dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var pt = moment.defineLocale('pt', { + months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'), + monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), + weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'), + weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D [de] MMMM [de] YYYY", - LLL : "D [de] MMMM [de] YYYY LT", - LLLL : "dddd, D [de] MMMM [de] YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY HH:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm' }, calendar : { sameDay: '[Hoje às] LT', @@ -37,24 +37,28 @@ sameElse: 'L' }, relativeTime : { - future : "em %s", - past : "há %s", - s : "segundos", - m : "um minuto", - mm : "%d minutos", - h : "uma hora", - hh : "%d horas", - d : "um dia", - dd : "%d dias", - M : "um mês", - MM : "%d meses", - y : "um ano", - yy : "%d anos" + future : 'em %s', + past : 'há %s', + s : 'segundos', + m : 'um minuto', + mm : '%d minutos', + h : 'uma hora', + hh : '%d horas', + d : 'um dia', + dd : '%d dias', + M : 'um mês', + MM : '%d meses', + y : 'um ano', + yy : '%d anos' }, + ordinalParse: /\d{1,2}º/, ordinal : '%dº', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return pt; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/pt_BR.js b/lib/javascripts/moment_locale/pt_BR.js deleted file mode 100644 index 5ffc39ee587..00000000000 --- a/lib/javascripts/moment_locale/pt_BR.js +++ /dev/null @@ -1,46 +0,0 @@ -// moment.js language configuration -// language : brazilian portuguese (pt-br) -// author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira - -moment.lang('pt_BR', { - months : "Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"), - monthsShort : "Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"), - weekdays : "Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado".split("_"), - weekdaysShort : "Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"), - weekdaysMin : "Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D [de] MMMM [de] YYYY", - LLL : "D [de] MMMM [de] YYYY LT", - LLLL : "dddd, D [de] MMMM [de] YYYY LT" - }, - calendar : { - sameDay: '[Hoje às] LT', - nextDay: '[Amanhã às] LT', - nextWeek: 'dddd [às] LT', - lastDay: '[Ontem às] LT', - lastWeek: function () { - return (this.day() === 0 || this.day() === 6) ? - '[Último] dddd [às] LT' : // Saturday + Sunday - '[Última] dddd [às] LT'; // Monday - Friday - }, - sameElse: 'L' - }, - relativeTime : { - future : "em %s", - past : "%s atrás", - s : "segundos", - m : "um minuto", - mm : "%d minutos", - h : "uma hora", - hh : "%d horas", - d : "um dia", - dd : "%d dias", - M : "um mês", - MM : "%d meses", - y : "um ano", - yy : "%d anos" - }, - ordinal : '%dº' -}); diff --git a/lib/javascripts/moment_locale/ro.js b/lib/javascripts/moment_locale/ro.js index 21a3293191a..fb9226758ca 100644 --- a/lib/javascripts/moment_locale/ro.js +++ b/lib/javascripts/moment_locale/ro.js @@ -1,17 +1,16 @@ -// moment.js locale configuration -// locale : romanian (ro) -// author : Vlad Gurdiga : https://github.com/gurdiga -// author : Valentin Agachi : https://github.com/avaly +//! moment.js locale configuration +//! locale : romanian (ro) +//! author : Vlad Gurdiga : https://github.com/gurdiga +//! author : Valentin Agachi : https://github.com/avaly + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function relativeTimeWithPlural(number, withoutSuffix, key) { var format = { 'mm': 'minute', @@ -24,25 +23,25 @@ if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) { separator = ' de '; } - return number + separator + format[key]; } - return moment.defineLocale('ro', { - months : "ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"), - monthsShort : "ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"), - weekdays : "duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"), - weekdaysShort : "Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"), - weekdaysMin : "Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"), + var ro = moment.defineLocale('ro', { + months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'), + monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'), + weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'), + weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'), + weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'), longDateFormat : { - LT : "H:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY H:mm", - LLLL : "dddd, D MMMM YYYY H:mm" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' }, calendar : { - sameDay: "[azi la] LT", + sameDay: '[azi la] LT', nextDay: '[mâine la] LT', nextWeek: 'dddd [la] LT', lastDay: '[ieri la] LT', @@ -50,18 +49,18 @@ sameElse: 'L' }, relativeTime : { - future : "peste %s", - past : "%s în urmă", - s : "câteva secunde", - m : "un minut", + future : 'peste %s', + past : '%s în urmă', + s : 'câteva secunde', + m : 'un minut', mm : relativeTimeWithPlural, - h : "o oră", + h : 'o oră', hh : relativeTimeWithPlural, - d : "o zi", + d : 'o zi', dd : relativeTimeWithPlural, - M : "o lună", + M : 'o lună', MM : relativeTimeWithPlural, - y : "un an", + y : 'un an', yy : relativeTimeWithPlural }, week : { @@ -69,4 +68,7 @@ doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return ro; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ru.js b/lib/javascripts/moment_locale/ru.js index 3ae8d23b7c8..442ddf80031 100644 --- a/lib/javascripts/moment_locale/ru.js +++ b/lib/javascripts/moment_locale/ru.js @@ -1,22 +1,20 @@ -// moment.js locale configuration -// locale : russian (ru) -// author : Viktorminator : https://github.com/Viktorminator -// Author : Menelion Elensúle : https://github.com/Oire +//! moment.js locale configuration +//! locale : russian (ru) +//! author : Viktorminator : https://github.com/Viktorminator +//! Author : Menelion Elensúle : https://github.com/Oire + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function plural(word, num) { var forms = word.split('_'); return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); } - function relativeTimeWithPlural(number, withoutSuffix, key) { var format = { 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут', @@ -32,116 +30,116 @@ return number + ' ' + plural(format[key], +number); } } + var monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i]; - function monthsCaseReplace(m, format) { - var months = { - 'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'), - 'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_') + var ru = moment.defineLocale('ru', { + months : { + format: 'Января_Февраля_Марта_Апреля_Мая_Июня_Июля_Августа_Сентября_Октября_Ноября_Декабря'.split('_'), + standalone: 'Январь_Февраль_Март_Апрель_Май_Июнь_Июль_Август_Сентябрь_Октябрь_Ноябрь_Декабрь'.split('_') }, - - nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - } - - function monthsShortCaseReplace(m, format) { - var monthsShort = { - 'nominative': 'янв_фев_мар_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'), - 'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_') + monthsShort : { + format: 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_'), + standalone: 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_') }, - - nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return monthsShort[nounCase][m.month()]; - } - - function weekdaysCaseReplace(m, format) { - var weekdays = { - 'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'), - 'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_') + weekdays : { + standalone: 'Воскресенье_Понедельник_Вторник_Среда_Четверг_Пятница_Суббота'.split('_'), + format: 'Воскресенье_Понедельник_Вторник_Среду_Четверг_Пятницу_Субботу'.split('_'), + isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/ }, - - nounCase = (/\[ ?[Вв] ?(?:прошлую|следующую)? ?\] ?dddd/).test(format) ? - 'accusative' : - 'nominative'; - - return weekdays[nounCase][m.day()]; - } - - return moment.defineLocale('ru', { - months : monthsCaseReplace, - monthsShort : monthsShortCaseReplace, - weekdays : weekdaysCaseReplace, - weekdaysShort : "вс_пн_вт_ср_чт_пт_сб".split("_"), - weekdaysMin : "вс_пн_вт_ср_чт_пт_сб".split("_"), - monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i], + weekdaysShort : 'Вс_Пн_Вт_Ср_Чт_Пт_Сб'.split('_'), + weekdaysMin : 'Вс_Пн_Вт_Ср_Чт_Пт_Сб'.split('_'), + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY г.", - LLL : "D MMMM YYYY г., LT", - LLLL : "dddd, D MMMM YYYY г., LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY г.', + LLL : 'D MMMM YYYY г., HH:mm', + LLLL : 'dddd, D MMMM YYYY г., HH:mm' }, calendar : { sameDay: '[Сегодня в] LT', nextDay: '[Завтра в] LT', lastDay: '[Вчера в] LT', - nextWeek: function () { - return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT'; + nextWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В следующее] dddd [в] LT'; + case 1: + case 2: + case 4: + return '[В следующий] dddd [в] LT'; + case 3: + case 5: + case 6: + return '[В следующую] dddd [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd [в] LT'; + } else { + return '[В] dddd [в] LT'; + } + } }, - lastWeek: function () { - switch (this.day()) { - case 0: - return '[В прошлое] dddd [в] LT'; - case 1: - case 2: - case 4: - return '[В прошлый] dddd [в] LT'; - case 3: - case 5: - case 6: - return '[В прошлую] dddd [в] LT'; + lastWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В прошлое] dddd [в] LT'; + case 1: + case 2: + case 4: + return '[В прошлый] dddd [в] LT'; + case 3: + case 5: + case 6: + return '[В прошлую] dddd [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd [в] LT'; + } else { + return '[В] dddd [в] LT'; + } } }, sameElse: 'L' }, relativeTime : { - future : "через %s", - past : "%s назад", - s : "несколько секунд", + future : 'через %s', + past : '%s назад', + s : 'несколько секунд', m : relativeTimeWithPlural, mm : relativeTimeWithPlural, - h : "час", + h : 'час', hh : relativeTimeWithPlural, - d : "день", + d : 'день', dd : relativeTimeWithPlural, - M : "месяц", + M : 'месяц', MM : relativeTimeWithPlural, - y : "год", + y : 'год', yy : relativeTimeWithPlural }, - meridiemParse: /ночи|утра|дня|вечера/i, isPM : function (input) { return /^(дня|вечера)$/.test(input); }, - meridiem : function (hour, minute, isLower) { if (hour < 4) { - return "ночи"; + return 'ночи'; } else if (hour < 12) { - return "утра"; + return 'утра'; } else if (hour < 17) { - return "дня"; + return 'дня'; } else { - return "вечера"; + return 'вечера'; } }, - + ordinalParse: /\d{1,2}-(й|го|я)/, ordinal: function (number, period) { switch (period) { case 'M': @@ -157,10 +155,12 @@ return number; } }, - week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return ru; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/se.js b/lib/javascripts/moment_locale/se.js new file mode 100644 index 00000000000..06be0d6ba13 --- /dev/null +++ b/lib/javascripts/moment_locale/se.js @@ -0,0 +1,61 @@ +//! moment.js locale configuration +//! locale : Northern Sami (se) +//! authors : Bård Rolstad Henriksen : https://github.com/karamell + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + + var se = moment.defineLocale('se', { + months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'), + monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'), + weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'), + weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'), + weekdaysMin : 's_v_m_g_d_b_L'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'MMMM D. [b.] YYYY', + LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm', + LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm' + }, + calendar : { + sameDay: '[otne ti] LT', + nextDay: '[ihttin ti] LT', + nextWeek: 'dddd [ti] LT', + lastDay: '[ikte ti] LT', + lastWeek: '[ovddit] dddd [ti] LT', + sameElse: 'L' + }, + relativeTime : { + future : '%s geažes', + past : 'maŋit %s', + s : 'moadde sekunddat', + m : 'okta minuhta', + mm : '%d minuhtat', + h : 'okta diimmu', + hh : '%d diimmut', + d : 'okta beaivi', + dd : '%d beaivvit', + M : 'okta mánnu', + MM : '%d mánut', + y : 'okta jahki', + yy : '%d jagit' + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + return se; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/si.js b/lib/javascripts/moment_locale/si.js new file mode 100644 index 00000000000..d86c9e3b8e2 --- /dev/null +++ b/lib/javascripts/moment_locale/si.js @@ -0,0 +1,66 @@ +//! moment.js locale configuration +//! locale : Sinhalese (si) +//! author : Sampath Sitinamaluwa : https://github.com/sampathsris + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + /*jshint -W100*/ + var si = moment.defineLocale('si', { + months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'), + monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'), + weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'), + weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'), + weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'), + longDateFormat : { + LT : 'a h:mm', + LTS : 'a h:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY MMMM D', + LLL : 'YYYY MMMM D, a h:mm', + LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss' + }, + calendar : { + sameDay : '[අද] LT[ට]', + nextDay : '[හෙට] LT[ට]', + nextWeek : 'dddd LT[ට]', + lastDay : '[ඊයේ] LT[ට]', + lastWeek : '[පසුගිය] dddd LT[ට]', + sameElse : 'L' + }, + relativeTime : { + future : '%sකින්', + past : '%sකට පෙර', + s : 'තත්පර කිහිපය', + m : 'මිනිත්තුව', + mm : 'මිනිත්තු %d', + h : 'පැය', + hh : 'පැය %d', + d : 'දිනය', + dd : 'දින %d', + M : 'මාසය', + MM : 'මාස %d', + y : 'වසර', + yy : 'වසර %d' + }, + ordinalParse: /\d{1,2} වැනි/, + ordinal : function (number) { + return number + ' වැනි'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'ප.ව.' : 'පස් වරු'; + } else { + return isLower ? 'පෙ.ව.' : 'පෙර වරු'; + } + } + }); + + return si; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/sk.js b/lib/javascripts/moment_locale/sk.js index d03fff875b4..52838a3a626 100644 --- a/lib/javascripts/moment_locale/sk.js +++ b/lib/javascripts/moment_locale/sk.js @@ -1,26 +1,23 @@ -// moment.js locale configuration -// locale : slovak (sk) -// author : Martin Minka : https://github.com/k2s -// based on work of petrbela : https://github.com/petrbela +//! moment.js locale configuration +//! locale : slovak (sk) +//! author : Martin Minka : https://github.com/k2s +//! based on work of petrbela : https://github.com/petrbela -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - var months = "január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"), - monthsShort = "jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_"); +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'), + monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_'); function plural(n) { return (n > 1) && (n < 5); } - function translate(number, withoutSuffix, key, isFuture) { - var result = number + " "; + var result = number + ' '; switch (key) { case 's': // a few seconds / in a few seconds / a few seconds ago return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami'; @@ -72,29 +69,22 @@ } } - return moment.defineLocale('sk', { + var sk = moment.defineLocale('sk', { months : months, monthsShort : monthsShort, - monthsParse : (function (months, monthsShort) { - var i, _monthsParse = []; - for (i = 0; i < 12; i++) { - // use custom parser to solve problem with July (červenec) - _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i'); - } - return _monthsParse; - }(months, monthsShort)), - weekdays : "nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"), - weekdaysShort : "ne_po_ut_st_št_pi_so".split("_"), - weekdaysMin : "ne_po_ut_st_št_pi_so".split("_"), + weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'), + weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'), + weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'), longDateFormat : { - LT: "H:mm", - L : "DD.MM.YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd D. MMMM YYYY LT" + LT: 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd D. MMMM YYYY H:mm' }, calendar : { - sameDay: "[dnes o] LT", + sameDay: '[dnes o] LT', nextDay: '[zajtra o] LT', nextWeek: function () { switch (this.day()) { @@ -130,11 +120,11 @@ return '[minulú sobotu o] LT'; } }, - sameElse: "L" + sameElse: 'L' }, relativeTime : { - future : "za %s", - past : "pred %s", + future : 'za %s', + past : 'pred %s', s : translate, m : translate, mm : translate, @@ -147,10 +137,14 @@ y : translate, yy : translate }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return sk; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/sl.js b/lib/javascripts/moment_locale/sl.js index 6174ae63e2e..68d261e271c 100644 --- a/lib/javascripts/moment_locale/sl.js +++ b/lib/javascripts/moment_locale/sl.js @@ -1,89 +1,99 @@ -// moment.js locale configuration -// locale : slovenian (sl) -// author : Robert Sedovšek : https://github.com/sedovsek +//! moment.js locale configuration +//! locale : slovenian (sl) +//! author : Robert Sedovšek : https://github.com/sedovsek -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - function translate(number, withoutSuffix, key) { - var result = number + " "; +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var result = number + ' '; switch (key) { + case 's': + return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami'; case 'm': return withoutSuffix ? 'ena minuta' : 'eno minuto'; case 'mm': if (number === 1) { - result += 'minuta'; + result += withoutSuffix ? 'minuta' : 'minuto'; } else if (number === 2) { - result += 'minuti'; - } else if (number === 3 || number === 4) { - result += 'minute'; + result += withoutSuffix || isFuture ? 'minuti' : 'minutama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'minute' : 'minutami'; } else { - result += 'minut'; + result += withoutSuffix || isFuture ? 'minut' : 'minutami'; } return result; case 'h': return withoutSuffix ? 'ena ura' : 'eno uro'; case 'hh': if (number === 1) { - result += 'ura'; + result += withoutSuffix ? 'ura' : 'uro'; } else if (number === 2) { - result += 'uri'; - } else if (number === 3 || number === 4) { - result += 'ure'; + result += withoutSuffix || isFuture ? 'uri' : 'urama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'ure' : 'urami'; } else { - result += 'ur'; + result += withoutSuffix || isFuture ? 'ur' : 'urami'; } return result; + case 'd': + return withoutSuffix || isFuture ? 'en dan' : 'enim dnem'; case 'dd': if (number === 1) { - result += 'dan'; + result += withoutSuffix || isFuture ? 'dan' : 'dnem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'dni' : 'dnevoma'; } else { - result += 'dni'; + result += withoutSuffix || isFuture ? 'dni' : 'dnevi'; } return result; + case 'M': + return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem'; case 'MM': if (number === 1) { - result += 'mesec'; + result += withoutSuffix || isFuture ? 'mesec' : 'mesecem'; } else if (number === 2) { - result += 'meseca'; - } else if (number === 3 || number === 4) { - result += 'mesece'; + result += withoutSuffix || isFuture ? 'meseca' : 'mesecema'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'mesece' : 'meseci'; } else { - result += 'mesecev'; + result += withoutSuffix || isFuture ? 'mesecev' : 'meseci'; } return result; + case 'y': + return withoutSuffix || isFuture ? 'eno leto' : 'enim letom'; case 'yy': if (number === 1) { - result += 'leto'; + result += withoutSuffix || isFuture ? 'leto' : 'letom'; } else if (number === 2) { - result += 'leti'; - } else if (number === 3 || number === 4) { - result += 'leta'; + result += withoutSuffix || isFuture ? 'leti' : 'letoma'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'leta' : 'leti'; } else { - result += 'let'; + result += withoutSuffix || isFuture ? 'let' : 'leti'; } return result; } } - return moment.defineLocale('sl', { - months : "januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"), - monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"), - weekdays : "nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"), - weekdaysShort : "ned._pon._tor._sre._čet._pet._sob.".split("_"), - weekdaysMin : "ne_po_to_sr_če_pe_so".split("_"), + var sl = moment.defineLocale('sl', { + months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'), + monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'), + weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), + weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'), + weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'), longDateFormat : { - LT : "H:mm", - L : "DD. MM. YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd, D. MMMM YYYY LT" + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD. MM. YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' }, calendar : { sameDay : '[danes ob] LT', @@ -108,9 +118,11 @@ lastWeek : function () { switch (this.day()) { case 0: + return '[prejšnjo] [nedeljo] [ob] LT'; case 3: + return '[prejšnjo] [sredo] [ob] LT'; case 6: - return '[prejšnja] dddd [ob] LT'; + return '[prejšnjo] [soboto] [ob] LT'; case 1: case 2: case 4: @@ -121,24 +133,28 @@ sameElse : 'L' }, relativeTime : { - future : "čez %s", - past : "%s nazaj", - s : "nekaj sekund", - m : translate, - mm : translate, - h : translate, - hh : translate, - d : "en dan", - dd : translate, - M : "en mesec", - MM : translate, - y : "eno leto", - yy : translate + future : 'čez %s', + past : 'pred %s', + s : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return sl; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/sq.js b/lib/javascripts/moment_locale/sq.js index 4a3dfea725a..69dca2017cc 100644 --- a/lib/javascripts/moment_locale/sq.js +++ b/lib/javascripts/moment_locale/sq.js @@ -1,33 +1,37 @@ -// moment.js locale configuration -// locale : Albanian (sq) -// author : Flakërim Ismani : https://github.com/flakerimi -// author: Menelion Elensúle: https://github.com/Oire (tests) -// author : Oerd Cukalla : https://github.com/oerd (fixes) +//! moment.js locale configuration +//! locale : Albanian (sq) +//! author : Flakërim Ismani : https://github.com/flakerimi +//! author: Menelion Elensúle: https://github.com/Oire (tests) +//! author : Oerd Cukalla : https://github.com/oerd (fixes) -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('sq', { - months : "Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor".split("_"), - monthsShort : "Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj".split("_"), - weekdays : "E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë".split("_"), - weekdaysShort : "Die_Hën_Mar_Mër_Enj_Pre_Sht".split("_"), - weekdaysMin : "D_H_Ma_Më_E_P_Sh".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var sq = moment.defineLocale('sq', { + months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'), + monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'), + weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'), + weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'), + weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'), + meridiemParse: /PD|MD/, + isPM: function (input) { + return input.charAt(0) === 'M'; + }, meridiem : function (hours, minutes, isLower) { return hours < 12 ? 'PD' : 'MD'; }, longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { sameDay : '[Sot në] LT', @@ -38,24 +42,28 @@ sameElse : 'L' }, relativeTime : { - future : "në %s", - past : "%s më parë", - s : "disa sekonda", - m : "një minutë", - mm : "%d minuta", - h : "një orë", - hh : "%d orë", - d : "një ditë", - dd : "%d ditë", - M : "një muaj", - MM : "%d muaj", - y : "një vit", - yy : "%d vite" + future : 'në %s', + past : '%s më parë', + s : 'disa sekonda', + m : 'një minutë', + mm : '%d minuta', + h : 'një orë', + hh : '%d orë', + d : 'një ditë', + dd : '%d ditë', + M : 'një muaj', + MM : '%d muaj', + y : 'një vit', + yy : '%d vite' }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return sq; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/sr-cyrl.js b/lib/javascripts/moment_locale/sr-cyrl.js index ef6e7ce4bbc..c72cca77076 100644 --- a/lib/javascripts/moment_locale/sr-cyrl.js +++ b/lib/javascripts/moment_locale/sr-cyrl.js @@ -1,16 +1,15 @@ -// moment.js locale configuration -// locale : Serbian-cyrillic (sr-cyrl) -// author : Milan Janačković : https://github.com/milan-j +//! moment.js locale configuration +//! locale : Serbian-cyrillic (sr-cyrl) +//! author : Milan Janačković : https://github.com/milan-j + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var translator = { words: { //Different grammatical cases m: ['један минут', 'једне минуте'], @@ -34,23 +33,23 @@ } }; - return moment.defineLocale('sr-cyrl', { + var sr_cyrl = moment.defineLocale('sr-cyrl', { months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'], monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'], weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'], weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'], weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'], longDateFormat: { - LT: "H:mm", - L: "DD. MM. YYYY", - LL: "D. MMMM YYYY", - LLL: "D. MMMM YYYY LT", - LLLL: "dddd, D. MMMM YYYY LT" + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD. MM. YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' }, calendar: { sameDay: '[данас у] LT', nextDay: '[сутра у] LT', - nextWeek: function () { switch (this.day()) { case 0: @@ -82,24 +81,28 @@ sameElse : 'L' }, relativeTime : { - future : "за %s", - past : "пре %s", - s : "неколико секунди", + future : 'за %s', + past : 'пре %s', + s : 'неколико секунди', m : translator.translate, mm : translator.translate, h : translator.translate, hh : translator.translate, - d : "дан", + d : 'дан', dd : translator.translate, - M : "месец", + M : 'месец', MM : translator.translate, - y : "годину", + y : 'годину', yy : translator.translate }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return sr_cyrl; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/sr.js b/lib/javascripts/moment_locale/sr.js index 86e8e84a6bf..4dab6f48ce3 100644 --- a/lib/javascripts/moment_locale/sr.js +++ b/lib/javascripts/moment_locale/sr.js @@ -1,16 +1,15 @@ -// moment.js locale configuration -// locale : Serbian-latin (sr) -// author : Milan Janačković : https://github.com/milan-j +//! moment.js locale configuration +//! locale : Serbian-latin (sr) +//! author : Milan Janačković : https://github.com/milan-j + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var translator = { words: { //Different grammatical cases m: ['jedan minut', 'jedne minute'], @@ -34,23 +33,23 @@ } }; - return moment.defineLocale('sr', { + var sr = moment.defineLocale('sr', { months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'], monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'], weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'], weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'], weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'], longDateFormat: { - LT: "H:mm", - L: "DD. MM. YYYY", - LL: "D. MMMM YYYY", - LLL: "D. MMMM YYYY LT", - LLLL: "dddd, D. MMMM YYYY LT" + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD. MM. YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' }, calendar: { sameDay: '[danas u] LT', nextDay: '[sutra u] LT', - nextWeek: function () { switch (this.day()) { case 0: @@ -82,24 +81,28 @@ sameElse : 'L' }, relativeTime : { - future : "za %s", - past : "pre %s", - s : "nekoliko sekundi", + future : 'za %s', + past : 'pre %s', + s : 'nekoliko sekundi', m : translator.translate, mm : translator.translate, h : translator.translate, hh : translator.translate, - d : "dan", + d : 'dan', dd : translator.translate, - M : "mesec", + M : 'mesec', MM : translator.translate, - y : "godinu", + y : 'godinu', yy : translator.translate }, + ordinalParse: /\d{1,2}\./, ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return sr; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/sv.js b/lib/javascripts/moment_locale/sv.js index 9e39a30109a..5af3bb72c46 100644 --- a/lib/javascripts/moment_locale/sv.js +++ b/lib/javascripts/moment_locale/sv.js @@ -1,52 +1,53 @@ -// moment.js locale configuration -// locale : swedish (sv) -// author : Jens Alm : https://github.com/ulmus +//! moment.js locale configuration +//! locale : swedish (sv) +//! author : Jens Alm : https://github.com/ulmus -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('sv', { - months : "januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"), - monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"), - weekdays : "söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"), - weekdaysShort : "sön_mån_tis_ons_tor_fre_lör".split("_"), - weekdaysMin : "sö_må_ti_on_to_fr_lö".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var sv = moment.defineLocale('sv', { + months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'), + weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'), + weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "YYYY-MM-DD", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { sameDay: '[Idag] LT', nextDay: '[Imorgon] LT', lastDay: '[Igår] LT', - nextWeek: 'dddd LT', - lastWeek: '[Förra] dddd[en] LT', + nextWeek: '[På] dddd LT', + lastWeek: '[I] dddd[s] LT', sameElse: 'L' }, relativeTime : { - future : "om %s", - past : "för %s sedan", - s : "några sekunder", - m : "en minut", - mm : "%d minuter", - h : "en timme", - hh : "%d timmar", - d : "en dag", - dd : "%d dagar", - M : "en månad", - MM : "%d månader", - y : "ett år", - yy : "%d år" + future : 'om %s', + past : 'för %s sedan', + s : 'några sekunder', + m : 'en minut', + mm : '%d minuter', + h : 'en timme', + hh : '%d timmar', + d : 'en dag', + dd : '%d dagar', + M : 'en månad', + MM : '%d månader', + y : 'ett år', + yy : '%d år' }, + ordinalParse: /\d{1,2}(e|a)/, ordinal : function (number) { var b = number % 10, output = (~~(number % 100 / 10) === 1) ? 'e' : @@ -60,4 +61,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return sv; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/sw.js b/lib/javascripts/moment_locale/sw.js new file mode 100644 index 00000000000..8017f7d4736 --- /dev/null +++ b/lib/javascripts/moment_locale/sw.js @@ -0,0 +1,58 @@ +//! moment.js locale configuration +//! locale : swahili (sw) +//! author : Fahad Kassim : https://github.com/fadsel + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var sw = moment.defineLocale('sw', { + months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'), + weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'), + weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[leo saa] LT', + nextDay : '[kesho saa] LT', + nextWeek : '[wiki ijayo] dddd [saat] LT', + lastDay : '[jana] LT', + lastWeek : '[wiki iliyopita] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s baadaye', + past : 'tokea %s', + s : 'hivi punde', + m : 'dakika moja', + mm : 'dakika %d', + h : 'saa limoja', + hh : 'masaa %d', + d : 'siku moja', + dd : 'masiku %d', + M : 'mwezi mmoja', + MM : 'miezi %d', + y : 'mwaka mmoja', + yy : 'miaka %d' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + return sw; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/ta.js b/lib/javascripts/moment_locale/ta.js index 963d40349f4..27665095542 100644 --- a/lib/javascripts/moment_locale/ta.js +++ b/lib/javascripts/moment_locale/ta.js @@ -1,53 +1,52 @@ -// moment.js locale configuration -// locale : tamil (ta) -// author : Arjunkumar Krishnamoorthy : https://github.com/tk120404 +//! moment.js locale configuration +//! locale : tamil (ta) +//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404 -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - /*var symbolMap = { - '1': '௧', - '2': '௨', - '3': '௩', - '4': '௪', - '5': '௫', - '6': '௬', - '7': '௭', - '8': '௮', - '9': '௯', - '0': '௦' - }, - numberMap = { - '௧': '1', - '௨': '2', - '௩': '3', - '௪': '4', - '௫': '5', - '௬': '6', - '௭': '7', - '௮': '8', - '௯': '9', - '௦': '0' - }; */ +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; - return moment.defineLocale('ta', { - months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split("_"), - monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split("_"), - weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split("_"), - weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split("_"), - weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split("_"), + + var symbolMap = { + '1': '௧', + '2': '௨', + '3': '௩', + '4': '௪', + '5': '௫', + '6': '௬', + '7': '௭', + '8': '௮', + '9': '௯', + '0': '௦' + }, numberMap = { + '௧': '1', + '௨': '2', + '௩': '3', + '௪': '4', + '௫': '5', + '௬': '6', + '௭': '7', + '௮': '8', + '௯': '9', + '௦': '0' + }; + + var ta = moment.defineLocale('ta', { + months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), + monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), + weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'), + weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'), + weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY, LT", - LLLL : "dddd, D MMMM YYYY, LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, HH:mm', + LLLL : 'dddd, D MMMM YYYY, HH:mm' }, calendar : { sameDay : '[இன்று] LT', @@ -58,21 +57,25 @@ sameElse : 'L' }, relativeTime : { - future : "%s இல்", - past : "%s முன்", - s : "ஒரு சில விநாடிகள்", - m : "ஒரு நிமிடம்", - mm : "%d நிமிடங்கள்", - h : "ஒரு மணி நேரம்", - hh : "%d மணி நேரம்", - d : "ஒரு நாள்", - dd : "%d நாட்கள்", - M : "ஒரு மாதம்", - MM : "%d மாதங்கள்", - y : "ஒரு வருடம்", - yy : "%d ஆண்டுகள்" + future : '%s இல்', + past : '%s முன்', + s : 'ஒரு சில விநாடிகள்', + m : 'ஒரு நிமிடம்', + mm : '%d நிமிடங்கள்', + h : 'ஒரு மணி நேரம்', + hh : '%d மணி நேரம்', + d : 'ஒரு நாள்', + dd : '%d நாட்கள்', + M : 'ஒரு மாதம்', + MM : '%d மாதங்கள்', + y : 'ஒரு வருடம்', + yy : '%d ஆண்டுகள்' }, -/* preparse: function (string) { + ordinalParse: /\d{1,2}வது/, + ordinal : function (number) { + return number + 'வது'; + }, + preparse: function (string) { return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) { return numberMap[match]; }); @@ -81,27 +84,38 @@ return string.replace(/\d/g, function (match) { return symbolMap[match]; }); - },*/ - ordinal : function (number) { - return number + 'வது'; }, - - // refer http://ta.wikipedia.org/s/1er1 - + meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/, meridiem : function (hour, minute, isLower) { - if (hour >= 6 && hour <= 10) { - return " காலை"; - } else if (hour >= 10 && hour <= 14) { - return " நண்பகல்"; - } else if (hour >= 14 && hour <= 18) { - return " எற்பாடு"; - } else if (hour >= 18 && hour <= 20) { - return " மாலை"; - } else if (hour >= 20 && hour <= 24) { - return " இரவு"; - } else if (hour >= 0 && hour <= 6) { - return " வைகறை"; + if (hour < 2) { + return ' யாமம்'; + } else if (hour < 6) { + return ' வைகறை'; // வைகறை + } else if (hour < 10) { + return ' காலை'; // காலை + } else if (hour < 14) { + return ' நண்பகல்'; // நண்பகல் + } else if (hour < 18) { + return ' எற்பாடு'; // எற்பாடு + } else if (hour < 22) { + return ' மாலை'; // மாலை + } else { + return ' யாமம்'; + } + }, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'யாமம்') { + return hour < 2 ? hour : hour + 12; + } else if (meridiem === 'வைகறை' || meridiem === 'காலை') { + return hour; + } else if (meridiem === 'நண்பகல்') { + return hour >= 10 ? hour : hour + 12; + } else { + return hour + 12; } }, week : { @@ -109,4 +123,7 @@ doy : 6 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return ta; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/te.js b/lib/javascripts/moment_locale/te.js new file mode 100644 index 00000000000..775651df177 --- /dev/null +++ b/lib/javascripts/moment_locale/te.js @@ -0,0 +1,88 @@ +//! moment.js locale configuration +//! locale : telugu (te) +//! author : Krishna Chaitanya Thota : https://github.com/kcthota + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var te = moment.defineLocale('te', { + months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'), + monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'), + weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'), + weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'), + weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' + }, + calendar : { + sameDay : '[నేడు] LT', + nextDay : '[రేపు] LT', + nextWeek : 'dddd, LT', + lastDay : '[నిన్న] LT', + lastWeek : '[గత] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s లో', + past : '%s క్రితం', + s : 'కొన్ని క్షణాలు', + m : 'ఒక నిమిషం', + mm : '%d నిమిషాలు', + h : 'ఒక గంట', + hh : '%d గంటలు', + d : 'ఒక రోజు', + dd : '%d రోజులు', + M : 'ఒక నెల', + MM : '%d నెలలు', + y : 'ఒక సంవత్సరం', + yy : '%d సంవత్సరాలు' + }, + ordinalParse : /\d{1,2}వ/, + ordinal : '%dవ', + meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'రాత్రి') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ఉదయం') { + return hour; + } else if (meridiem === 'మధ్యాహ్నం') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'సాయంత్రం') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'రాత్రి'; + } else if (hour < 10) { + return 'ఉదయం'; + } else if (hour < 17) { + return 'మధ్యాహ్నం'; + } else if (hour < 20) { + return 'సాయంత్రం'; + } else { + return 'రాత్రి'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + return te; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/th.js b/lib/javascripts/moment_locale/th.js index 30b41e69aa0..ac325429dfb 100644 --- a/lib/javascripts/moment_locale/th.js +++ b/lib/javascripts/moment_locale/th.js @@ -1,34 +1,38 @@ -// moment.js locale configuration -// locale : thai (th) -// author : Kridsada Thanabulpong : https://github.com/sirn +//! moment.js locale configuration +//! locale : thai (th) +//! author : Kridsada Thanabulpong : https://github.com/sirn -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('th', { - months : "มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"), - monthsShort : "มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"), - weekdays : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"), - weekdaysShort : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"), // yes, three characters difference - weekdaysMin : "อา._จ._อ._พ._พฤ._ศ._ส.".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var th = moment.defineLocale('th', { + months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'), + monthsShort : 'มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา'.split('_'), + weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'), + weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference + weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'), longDateFormat : { - LT : "H นาฬิกา m นาที", - L : "YYYY/MM/DD", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY เวลา LT", - LLLL : "วันddddที่ D MMMM YYYY เวลา LT" + LT : 'H นาฬิกา m นาที', + LTS : 'H นาฬิกา m นาที s วินาที', + L : 'YYYY/MM/DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY เวลา H นาฬิกา m นาที', + LLLL : 'วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที' + }, + meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/, + isPM: function (input) { + return input === 'หลังเที่ยง'; }, meridiem : function (hour, minute, isLower) { if (hour < 12) { - return "ก่อนเที่ยง"; + return 'ก่อนเที่ยง'; } else { - return "หลังเที่ยง"; + return 'หลังเที่ยง'; } }, calendar : { @@ -40,19 +44,22 @@ sameElse : 'L' }, relativeTime : { - future : "อีก %s", - past : "%sที่แล้ว", - s : "ไม่กี่วินาที", - m : "1 นาที", - mm : "%d นาที", - h : "1 ชั่วโมง", - hh : "%d ชั่วโมง", - d : "1 วัน", - dd : "%d วัน", - M : "1 เดือน", - MM : "%d เดือน", - y : "1 ปี", - yy : "%d ปี" + future : 'อีก %s', + past : '%sที่แล้ว', + s : 'ไม่กี่วินาที', + m : '1 นาที', + mm : '%d นาที', + h : '1 ชั่วโมง', + hh : '%d ชั่วโมง', + d : '1 วัน', + dd : '%d วัน', + M : '1 เดือน', + MM : '%d เดือน', + y : '1 ปี', + yy : '%d ปี' } }); -})); + + return th; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/tl-ph.js b/lib/javascripts/moment_locale/tl-ph.js index dfacf18df33..d101fd92567 100644 --- a/lib/javascripts/moment_locale/tl-ph.js +++ b/lib/javascripts/moment_locale/tl-ph.js @@ -1,31 +1,31 @@ -// moment.js locale configuration -// locale : Tagalog/Filipino (tl-ph) -// author : Dan Hagman +//! moment.js locale configuration +//! locale : Tagalog/Filipino (tl-ph) +//! author : Dan Hagman -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('tl-ph', { - months : "Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"), - monthsShort : "Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"), - weekdays : "Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"), - weekdaysShort : "Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"), - weekdaysMin : "Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var tl_ph = moment.defineLocale('tl-ph', { + months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'), + monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'), + weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'), + weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'), + weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "MM/D/YYYY", - LL : "MMMM D, YYYY", - LLL : "MMMM D, YYYY LT", - LLLL : "dddd, MMMM DD, YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'MM/D/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY HH:mm', + LLLL : 'dddd, MMMM DD, YYYY HH:mm' }, calendar : { - sameDay: "[Ngayon sa] LT", + sameDay: '[Ngayon sa] LT', nextDay: '[Bukas sa] LT', nextWeek: 'dddd [sa] LT', lastDay: '[Kahapon sa] LT', @@ -33,20 +33,21 @@ sameElse: 'L' }, relativeTime : { - future : "sa loob ng %s", - past : "%s ang nakalipas", - s : "ilang segundo", - m : "isang minuto", - mm : "%d minuto", - h : "isang oras", - hh : "%d oras", - d : "isang araw", - dd : "%d araw", - M : "isang buwan", - MM : "%d buwan", - y : "isang taon", - yy : "%d taon" + future : 'sa loob ng %s', + past : '%s ang nakalipas', + s : 'ilang segundo', + m : 'isang minuto', + mm : '%d minuto', + h : 'isang oras', + hh : '%d oras', + d : 'isang araw', + dd : '%d araw', + M : 'isang buwan', + MM : '%d buwan', + y : 'isang taon', + yy : '%d taon' }, + ordinalParse: /\d{1,2}/, ordinal : function (number) { return number; }, @@ -55,4 +56,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return tl_ph; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/tlh.js b/lib/javascripts/moment_locale/tlh.js new file mode 100644 index 00000000000..4ae53ef719d --- /dev/null +++ b/lib/javascripts/moment_locale/tlh.js @@ -0,0 +1,119 @@ +//! moment.js locale configuration +//! locale : Klingon (tlh) +//! author : Dominika Kruk : https://github.com/amaranthrose + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_'); + + function translateFuture(output) { + var time = output; + time = (output.indexOf('jaj') !== -1) ? + time.slice(0, -3) + 'leS' : + (output.indexOf('jar') !== -1) ? + time.slice(0, -3) + 'waQ' : + (output.indexOf('DIS') !== -1) ? + time.slice(0, -3) + 'nem' : + time + ' pIq'; + return time; + } + + function translatePast(output) { + var time = output; + time = (output.indexOf('jaj') !== -1) ? + time.slice(0, -3) + 'Hu’' : + (output.indexOf('jar') !== -1) ? + time.slice(0, -3) + 'wen' : + (output.indexOf('DIS') !== -1) ? + time.slice(0, -3) + 'ben' : + time + ' ret'; + return time; + } + + function translate(number, withoutSuffix, string, isFuture) { + var numberNoun = numberAsNoun(number); + switch (string) { + case 'mm': + return numberNoun + ' tup'; + case 'hh': + return numberNoun + ' rep'; + case 'dd': + return numberNoun + ' jaj'; + case 'MM': + return numberNoun + ' jar'; + case 'yy': + return numberNoun + ' DIS'; + } + } + + function numberAsNoun(number) { + var hundred = Math.floor((number % 1000) / 100), + ten = Math.floor((number % 100) / 10), + one = number % 10, + word = ''; + if (hundred > 0) { + word += numbersNouns[hundred] + 'vatlh'; + } + if (ten > 0) { + word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH'; + } + if (one > 0) { + word += ((word !== '') ? ' ' : '') + numbersNouns[one]; + } + return (word === '') ? 'pagh' : word; + } + + var tlh = moment.defineLocale('tlh', { + months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'), + monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'), + weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[DaHjaj] LT', + nextDay: '[wa’leS] LT', + nextWeek: 'LLL', + lastDay: '[wa’Hu’] LT', + lastWeek: 'LLL', + sameElse: 'L' + }, + relativeTime : { + future : translateFuture, + past : translatePast, + s : 'puS lup', + m : 'wa’ tup', + mm : translate, + h : 'wa’ rep', + hh : translate, + d : 'wa’ jaj', + dd : translate, + M : 'wa’ jar', + MM : translate, + y : 'wa’ DIS', + yy : translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + return tlh; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/tr.js b/lib/javascripts/moment_locale/tr.js index e6c2adab7cf..638edbb0252 100644 --- a/lib/javascripts/moment_locale/tr.js +++ b/lib/javascripts/moment_locale/tr.js @@ -1,55 +1,50 @@ -// moment.js locale configuration -// locale : turkish (tr) -// authors : Erhan Gundogan : https://github.com/erhangundogan, -// Burak Yiğit Kaya: https://github.com/BYK +//! moment.js locale configuration +//! locale : turkish (tr) +//! authors : Erhan Gundogan : https://github.com/erhangundogan, +//! Burak Yiğit Kaya: https://github.com/BYK + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { var suffixes = { - 1: "'inci", - 5: "'inci", - 8: "'inci", - 70: "'inci", - 80: "'inci", - - 2: "'nci", - 7: "'nci", - 20: "'nci", - 50: "'nci", - - 3: "'üncü", - 4: "'üncü", - 100: "'üncü", - - 6: "'ncı", - - 9: "'uncu", - 10: "'uncu", - 30: "'uncu", - - 60: "'ıncı", - 90: "'ıncı" + 1: '\'inci', + 5: '\'inci', + 8: '\'inci', + 70: '\'inci', + 80: '\'inci', + 2: '\'nci', + 7: '\'nci', + 20: '\'nci', + 50: '\'nci', + 3: '\'üncü', + 4: '\'üncü', + 100: '\'üncü', + 6: '\'ncı', + 9: '\'uncu', + 10: '\'uncu', + 30: '\'uncu', + 60: '\'ıncı', + 90: '\'ıncı' }; - return moment.defineLocale('tr', { - months : "Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"), - monthsShort : "Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"), - weekdays : "Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"), - weekdaysShort : "Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"), - weekdaysMin : "Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"), + var tr = moment.defineLocale('tr', { + months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'), + monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'), + weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'), + weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'), + weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { sameDay : '[bugün saat] LT', @@ -60,28 +55,28 @@ sameElse : 'L' }, relativeTime : { - future : "%s sonra", - past : "%s önce", - s : "birkaç saniye", - m : "bir dakika", - mm : "%d dakika", - h : "bir saat", - hh : "%d saat", - d : "bir gün", - dd : "%d gün", - M : "bir ay", - MM : "%d ay", - y : "bir yıl", - yy : "%d yıl" + future : '%s sonra', + past : '%s önce', + s : 'birkaç saniye', + m : 'bir dakika', + mm : '%d dakika', + h : 'bir saat', + hh : '%d saat', + d : 'bir gün', + dd : '%d gün', + M : 'bir ay', + MM : '%d ay', + y : 'bir yıl', + yy : '%d yıl' }, + ordinalParse: /\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/, ordinal : function (number) { if (number === 0) { // special case for zero - return number + "'ıncı"; + return number + '\'ıncı'; } var a = number % 10, b = number % 100 - a, c = number >= 100 ? 100 : null; - return number + (suffixes[a] || suffixes[b] || suffixes[c]); }, week : { @@ -89,4 +84,7 @@ doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return tr; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/tzl.js b/lib/javascripts/moment_locale/tzl.js new file mode 100644 index 00000000000..498f7c040ef --- /dev/null +++ b/lib/javascripts/moment_locale/tzl.js @@ -0,0 +1,87 @@ +//! moment.js locale configuration +//! locale : talossan (tzl) +//! author : Robin van der Vliet : https://github.com/robin0van0der0v with the help of Iustì Canun + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + + // After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals. + // This is currently too difficult (maybe even impossible) to add. + var tzl = moment.defineLocale('tzl', { + months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'), + monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'), + weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'), + weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'), + weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM [dallas] YYYY', + LLL : 'D. MMMM [dallas] YYYY HH.mm', + LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm' + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'd\'o' : 'D\'O'; + } else { + return isLower ? 'd\'a' : 'D\'A'; + } + }, + calendar : { + sameDay : '[oxhi à] LT', + nextDay : '[demà à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[ieiri à] LT', + lastWeek : '[sür el] dddd [lasteu à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'osprei %s', + past : 'ja%s', + s : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 's': ['viensas secunds', '\'iensas secunds'], + 'm': ['\'n míut', '\'iens míut'], + 'mm': [number + ' míuts', '' + number + ' míuts'], + 'h': ['\'n þora', '\'iensa þora'], + 'hh': [number + ' þoras', '' + number + ' þoras'], + 'd': ['\'n ziua', '\'iensa ziua'], + 'dd': [number + ' ziuas', '' + number + ' ziuas'], + 'M': ['\'n mes', '\'iens mes'], + 'MM': [number + ' mesen', '' + number + ' mesen'], + 'y': ['\'n ar', '\'iens ar'], + 'yy': [number + ' ars', '' + number + ' ars'] + }; + return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]); + } + + return tzl; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/tzm-latn.js b/lib/javascripts/moment_locale/tzm-latn.js index 1411e161b3c..712f5f5e418 100644 --- a/lib/javascripts/moment_locale/tzm-latn.js +++ b/lib/javascripts/moment_locale/tzm-latn.js @@ -1,31 +1,31 @@ -// moment.js locale configuration -// locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn) -// author : Abdel Said : https://github.com/abdelsaid +//! moment.js locale configuration +//! locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn) +//! author : Abdel Said : https://github.com/abdelsaid -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('tzm-latn', { - months : "innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"), - monthsShort : "innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"), - weekdays : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"), - weekdaysShort : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"), - weekdaysMin : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var tzm_latn = moment.defineLocale('tzm-latn', { + months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), + monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), + weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { - sameDay: "[asdkh g] LT", + sameDay: '[asdkh g] LT', nextDay: '[aska g] LT', nextWeek: 'dddd [g] LT', lastDay: '[assant g] LT', @@ -33,23 +33,26 @@ sameElse: 'L' }, relativeTime : { - future : "dadkh s yan %s", - past : "yan %s", - s : "imik", - m : "minuḍ", - mm : "%d minuḍ", - h : "saɛa", - hh : "%d tassaɛin", - d : "ass", - dd : "%d ossan", - M : "ayowr", - MM : "%d iyyirn", - y : "asgas", - yy : "%d isgasn" + future : 'dadkh s yan %s', + past : 'yan %s', + s : 'imik', + m : 'minuḍ', + mm : '%d minuḍ', + h : 'saɛa', + hh : '%d tassaɛin', + d : 'ass', + dd : '%d ossan', + M : 'ayowr', + MM : '%d iyyirn', + y : 'asgas', + yy : '%d isgasn' }, week : { dow : 6, // Saturday is the first day of the week. doy : 12 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return tzm_latn; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/tzm.js b/lib/javascripts/moment_locale/tzm.js index 615eb979cda..6b8acc08ee4 100644 --- a/lib/javascripts/moment_locale/tzm.js +++ b/lib/javascripts/moment_locale/tzm.js @@ -1,31 +1,31 @@ -// moment.js locale configuration -// locale : Morocco Central Atlas Tamaziɣt (tzm) -// author : Abdel Said : https://github.com/abdelsaid +//! moment.js locale configuration +//! locale : Morocco Central Atlas Tamaziɣt (tzm) +//! author : Abdel Said : https://github.com/abdelsaid -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('tzm', { - months : "ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"), - monthsShort : "ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"), - weekdays : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"), - weekdaysShort : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"), - weekdaysMin : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var tzm = moment.defineLocale('tzm', { + months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), + monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), + weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" + LT : 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { - sameDay: "[ⴰⵙⴷⵅ ⴴ] LT", + sameDay: '[ⴰⵙⴷⵅ ⴴ] LT', nextDay: '[ⴰⵙⴽⴰ ⴴ] LT', nextWeek: 'dddd [ⴴ] LT', lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT', @@ -33,23 +33,26 @@ sameElse: 'L' }, relativeTime : { - future : "ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s", - past : "ⵢⴰⵏ %s", - s : "ⵉⵎⵉⴽ", - m : "ⵎⵉⵏⵓⴺ", - mm : "%d ⵎⵉⵏⵓⴺ", - h : "ⵙⴰⵄⴰ", - hh : "%d ⵜⴰⵙⵙⴰⵄⵉⵏ", - d : "ⴰⵙⵙ", - dd : "%d oⵙⵙⴰⵏ", - M : "ⴰⵢoⵓⵔ", - MM : "%d ⵉⵢⵢⵉⵔⵏ", - y : "ⴰⵙⴳⴰⵙ", - yy : "%d ⵉⵙⴳⴰⵙⵏ" + future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s', + past : 'ⵢⴰⵏ %s', + s : 'ⵉⵎⵉⴽ', + m : 'ⵎⵉⵏⵓⴺ', + mm : '%d ⵎⵉⵏⵓⴺ', + h : 'ⵙⴰⵄⴰ', + hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ', + d : 'ⴰⵙⵙ', + dd : '%d oⵙⵙⴰⵏ', + M : 'ⴰⵢoⵓⵔ', + MM : '%d ⵉⵢⵢⵉⵔⵏ', + y : 'ⴰⵙⴳⴰⵙ', + yy : '%d ⵉⵙⴳⴰⵙⵏ' }, week : { dow : 6, // Saturday is the first day of the week. doy : 12 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return tzm; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/uk.js b/lib/javascripts/moment_locale/uk.js index f27d9f3e311..80c34973c55 100644 --- a/lib/javascripts/moment_locale/uk.js +++ b/lib/javascripts/moment_locale/uk.js @@ -1,26 +1,24 @@ -// moment.js locale configuration -// locale : ukrainian (uk) -// author : zemlanin : https://github.com/zemlanin -// Author : Menelion Elensúle : https://github.com/Oire +//! moment.js locale configuration +//! locale : ukrainian (uk) +//! author : zemlanin : https://github.com/zemlanin +//! Author : Menelion Elensúle : https://github.com/Oire + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { function plural(word, num) { var forms = word.split('_'); return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); } - function relativeTimeWithPlural(number, withoutSuffix, key) { var format = { - 'mm': 'хвилина_хвилини_хвилин', - 'hh': 'година_години_годин', + 'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин', + 'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин', 'dd': 'день_дні_днів', 'MM': 'місяць_місяці_місяців', 'yy': 'рік_роки_років' @@ -35,54 +33,41 @@ return number + ' ' + plural(format[key], +number); } } - - function monthsCaseReplace(m, format) { - var months = { - 'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'), - 'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_') - }, - - nounCase = (/D[oD]? *MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - } - function weekdaysCaseReplace(m, format) { var weekdays = { 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'), 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'), 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_') }, - nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ? 'accusative' : ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ? 'genitive' : 'nominative'); - return weekdays[nounCase][m.day()]; } - function processHoursFunction(str) { return function () { return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT'; }; } - return moment.defineLocale('uk', { - months : monthsCaseReplace, - monthsShort : "січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"), + var uk = moment.defineLocale('uk', { + months : { + 'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'), + 'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_') + }, + monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'), weekdays : weekdaysCaseReplace, - weekdaysShort : "нд_пн_вт_ср_чт_пт_сб".split("_"), - weekdaysMin : "нд_пн_вт_ср_чт_пт_сб".split("_"), + weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY р.", - LLL : "D MMMM YYYY р., LT", - LLLL : "dddd, D MMMM YYYY р., LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY р.', + LLL : 'D MMMM YYYY р., HH:mm', + LLLL : 'dddd, D MMMM YYYY р., HH:mm' }, calendar : { sameDay: processHoursFunction('[Сьогодні '), @@ -105,35 +90,37 @@ sameElse: 'L' }, relativeTime : { - future : "за %s", - past : "%s тому", - s : "декілька секунд", + future : 'за %s', + past : '%s тому', + s : 'декілька секунд', m : relativeTimeWithPlural, mm : relativeTimeWithPlural, - h : "годину", + h : 'годину', hh : relativeTimeWithPlural, - d : "день", + d : 'день', dd : relativeTimeWithPlural, - M : "місяць", + M : 'місяць', MM : relativeTimeWithPlural, - y : "рік", + y : 'рік', yy : relativeTimeWithPlural }, - // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason - + meridiemParse: /ночі|ранку|дня|вечора/, + isPM: function (input) { + return /^(дня|вечора)$/.test(input); + }, meridiem : function (hour, minute, isLower) { if (hour < 4) { - return "ночі"; + return 'ночі'; } else if (hour < 12) { - return "ранку"; + return 'ранку'; } else if (hour < 17) { - return "дня"; + return 'дня'; } else { - return "вечора"; + return 'вечора'; } }, - + ordinalParse: /\d{1,2}-(й|го)/, ordinal: function (number, period) { switch (period) { case 'M': @@ -148,10 +135,12 @@ return number; } }, - week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 1st is the first week of the year. } }); -})); + + return uk; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/uz.js b/lib/javascripts/moment_locale/uz.js index 7cf541c5279..fcf594e6a77 100644 --- a/lib/javascripts/moment_locale/uz.js +++ b/lib/javascripts/moment_locale/uz.js @@ -1,28 +1,28 @@ -// moment.js locale configuration -// locale : uzbek (uz) -// author : Sardor Muminov : https://github.com/muminoff +//! moment.js locale configuration +//! locale : uzbek (uz) +//! author : Sardor Muminov : https://github.com/muminoff -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('uz', { - months : "январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"), - monthsShort : "янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"), - weekdays : "Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба".split("_"), - weekdaysShort : "Якш_Душ_Сеш_Чор_Пай_Жум_Шан".split("_"), - weekdaysMin : "Як_Ду_Се_Чо_Па_Жу_Ша".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var uz = moment.defineLocale('uz', { + months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), + monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'), + weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'), + weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "D MMMM YYYY, dddd LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'D MMMM YYYY, dddd HH:mm' }, calendar : { sameDay : '[Бугун соат] LT [да]', @@ -33,23 +33,26 @@ sameElse : 'L' }, relativeTime : { - future : "Якин %s ичида", - past : "Бир неча %s олдин", - s : "фурсат", - m : "бир дакика", - mm : "%d дакика", - h : "бир соат", - hh : "%d соат", - d : "бир кун", - dd : "%d кун", - M : "бир ой", - MM : "%d ой", - y : "бир йил", - yy : "%d йил" + future : 'Якин %s ичида', + past : 'Бир неча %s олдин', + s : 'фурсат', + m : 'бир дакика', + mm : '%d дакика', + h : 'бир соат', + hh : '%d соат', + d : 'бир кун', + dd : '%d кун', + M : 'бир ой', + MM : '%d ой', + y : 'бир йил', + yy : '%d йил' }, week : { dow : 1, // Monday is the first day of the week. doy : 7 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return uz; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/vi.js b/lib/javascripts/moment_locale/vi.js index 3f8f5f5afc0..0e7ba8c353f 100644 --- a/lib/javascripts/moment_locale/vi.js +++ b/lib/javascripts/moment_locale/vi.js @@ -1,35 +1,35 @@ -// moment.js locale configuration -// locale : vietnamese (vi) -// author : Bang Nguyen : https://github.com/bangnk +//! moment.js locale configuration +//! locale : vietnamese (vi) +//! author : Bang Nguyen : https://github.com/bangnk -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('vi', { - months : "tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"), - monthsShort : "Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"), - weekdays : "chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"), - weekdaysShort : "CN_T2_T3_T4_T5_T6_T7".split("_"), - weekdaysMin : "CN_T2_T3_T4_T5_T6_T7".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var vi = moment.defineLocale('vi', { + months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'), + monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'), + weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'), + weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM [năm] YYYY", - LLL : "D MMMM [năm] YYYY LT", - LLLL : "dddd, D MMMM [năm] YYYY LT", - l : "DD/M/YYYY", - ll : "D MMM YYYY", - lll : "D MMM YYYY LT", - llll : "ddd, D MMM YYYY LT" + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM [năm] YYYY', + LLL : 'D MMMM [năm] YYYY HH:mm', + LLLL : 'dddd, D MMMM [năm] YYYY HH:mm', + l : 'DD/M/YYYY', + ll : 'D MMM YYYY', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd, D MMM YYYY HH:mm' }, calendar : { - sameDay: "[Hôm nay lúc] LT", + sameDay: '[Hôm nay lúc] LT', nextDay: '[Ngày mai lúc] LT', nextWeek: 'dddd [tuần tới lúc] LT', lastDay: '[Hôm qua lúc] LT', @@ -37,20 +37,21 @@ sameElse: 'L' }, relativeTime : { - future : "%s tới", - past : "%s trước", - s : "vài giây", - m : "một phút", - mm : "%d phút", - h : "một giờ", - hh : "%d giờ", - d : "một ngày", - dd : "%d ngày", - M : "một tháng", - MM : "%d tháng", - y : "một năm", - yy : "%d năm" + future : '%s tới', + past : '%s trước', + s : 'vài giây', + m : 'một phút', + mm : '%d phút', + h : 'một giờ', + hh : '%d giờ', + d : 'một ngày', + dd : '%d ngày', + M : 'một tháng', + MM : '%d tháng', + y : 'một năm', + yy : '%d năm' }, + ordinalParse: /\d{1,2}/, ordinal : function (number) { return number; }, @@ -59,4 +60,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return vi; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/zh-cn.js b/lib/javascripts/moment_locale/zh-cn.js index 78ea965b8f3..aec5ede49e1 100644 --- a/lib/javascripts/moment_locale/zh-cn.js +++ b/lib/javascripts/moment_locale/zh-cn.js @@ -1,103 +1,119 @@ -// moment.js locale configuration -// locale : chinese (zh-cn) -// author : suupic : https://github.com/suupic -// author : Zeno Zeng : https://github.com/zenozeng +//! moment.js locale configuration +//! locale : chinese (zh-cn) +//! author : suupic : https://github.com/suupic +//! author : Zeno Zeng : https://github.com/zenozeng -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('zh-cn', { - months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"), - monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"), - weekdaysShort : "周日_周一_周二_周三_周四_周五_周六".split("_"), - weekdaysMin : "日_一_二_三_四_五_六".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var zh_cn = moment.defineLocale('zh-cn', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), longDateFormat : { - LT : "Ah点mm", - L : "YYYY-MM-DD", - LL : "YYYY年MMMD日", - LLL : "YYYY年MMMD日LT", - LLLL : "YYYY年MMMD日ddddLT", - l : "YYYY-MM-DD", - ll : "YYYY年MMMD日", - lll : "YYYY年MMMD日LT", - llll : "YYYY年MMMD日ddddLT" + LT : 'Ah点mm分', + LTS : 'Ah点m分s秒', + L : 'YYYY-MM-DD', + LL : 'YYYY年MMMD日', + LLL : 'YYYY年MMMD日Ah点mm分', + LLLL : 'YYYY年MMMD日ddddAh点mm分', + l : 'YYYY-MM-DD', + ll : 'YYYY年MMMD日', + lll : 'YYYY年MMMD日Ah点mm分', + llll : 'YYYY年MMMD日ddddAh点mm分' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || + meridiem === '上午') { + return hour; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } else { + // '中午' + return hour >= 11 ? hour : hour + 12; + } }, meridiem : function (hour, minute, isLower) { var hm = hour * 100 + minute; if (hm < 600) { - return "凌晨"; + return '凌晨'; } else if (hm < 900) { - return "早上"; + return '早上'; } else if (hm < 1130) { - return "上午"; + return '上午'; } else if (hm < 1230) { - return "中午"; + return '中午'; } else if (hm < 1800) { - return "下午"; + return '下午'; } else { - return "晚上"; + return '晚上'; } }, calendar : { sameDay : function () { - return this.minutes() === 0 ? "[今天]Ah[点整]" : "[今天]LT"; + return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT'; }, nextDay : function () { - return this.minutes() === 0 ? "[明天]Ah[点整]" : "[明天]LT"; + return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT'; }, lastDay : function () { - return this.minutes() === 0 ? "[昨天]Ah[点整]" : "[昨天]LT"; + return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT'; }, nextWeek : function () { var startOfWeek, prefix; startOfWeek = moment().startOf('week'); prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]'; - return this.minutes() === 0 ? prefix + "dddAh点整" : prefix + "dddAh点mm"; + return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm'; }, lastWeek : function () { var startOfWeek, prefix; startOfWeek = moment().startOf('week'); prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]'; - return this.minutes() === 0 ? prefix + "dddAh点整" : prefix + "dddAh点mm"; + return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm'; }, sameElse : 'LL' }, + ordinalParse: /\d{1,2}(日|月|周)/, ordinal : function (number, period) { switch (period) { - case "d": - case "D": - case "DDD": - return number + "日"; - case "M": - return number + "月"; - case "w": - case "W": - return number + "周"; + case 'd': + case 'D': + case 'DDD': + return number + '日'; + case 'M': + return number + '月'; + case 'w': + case 'W': + return number + '周'; default: return number; } }, relativeTime : { - future : "%s内", - past : "%s前", - s : "几秒", - m : "1分钟", - mm : "%d分钟", - h : "1小时", - hh : "%d小时", - d : "1天", - dd : "%d天", - M : "1个月", - MM : "%d个月", - y : "1年", - yy : "%d年" + future : '%s内', + past : '%s前', + s : '几秒', + m : '1 分钟', + mm : '%d 分钟', + h : '1 小时', + hh : '%d 小时', + d : '1 天', + dd : '%d 天', + M : '1 个月', + MM : '%d 个月', + y : '1 年', + yy : '%d 年' }, week : { // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 @@ -105,4 +121,7 @@ doy : 4 // The week that contains Jan 4th is the first week of the year. } }); -})); + + return zh_cn; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/zh-tw.js b/lib/javascripts/moment_locale/zh-tw.js index edb1fb9879c..bf3a333c41e 100644 --- a/lib/javascripts/moment_locale/zh-tw.js +++ b/lib/javascripts/moment_locale/zh-tw.js @@ -1,45 +1,58 @@ -// moment.js locale configuration -// locale : traditional chinese (zh-tw) -// author : Ben : https://github.com/ben-lin +//! moment.js locale configuration +//! locale : traditional chinese (zh-tw) +//! author : Ben : https://github.com/ben-lin -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - return moment.defineLocale('zh-tw', { - months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"), - monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"), - weekdaysShort : "週日_週一_週二_週三_週四_週五_週六".split("_"), - weekdaysMin : "日_一_二_三_四_五_六".split("_"), +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + && typeof require === 'function' ? factory(require('../moment')) : + typeof define === 'function' && define.amd ? define(['moment'], factory) : + factory(global.moment) +}(this, function (moment) { 'use strict'; + + + var zh_tw = moment.defineLocale('zh-tw', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), longDateFormat : { - LT : "Ah點mm", - L : "YYYY年MMMD日", - LL : "YYYY年MMMD日", - LLL : "YYYY年MMMD日LT", - LLLL : "YYYY年MMMD日ddddLT", - l : "YYYY年MMMD日", - ll : "YYYY年MMMD日", - lll : "YYYY年MMMD日LT", - llll : "YYYY年MMMD日ddddLT" + LT : 'Ah點mm分', + LTS : 'Ah點m分s秒', + L : 'YYYY年MMMD日', + LL : 'YYYY年MMMD日', + LLL : 'YYYY年MMMD日Ah點mm分', + LLLL : 'YYYY年MMMD日ddddAh點mm分', + l : 'YYYY年MMMD日', + ll : 'YYYY年MMMD日', + lll : 'YYYY年MMMD日Ah點mm分', + llll : 'YYYY年MMMD日ddddAh點mm分' + }, + meridiemParse: /早上|上午|中午|下午|晚上/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } }, meridiem : function (hour, minute, isLower) { var hm = hour * 100 + minute; if (hm < 900) { - return "早上"; + return '早上'; } else if (hm < 1130) { - return "上午"; + return '上午'; } else if (hm < 1230) { - return "中午"; + return '中午'; } else if (hm < 1800) { - return "下午"; + return '下午'; } else { - return "晚上"; + return '晚上'; } }, calendar : { @@ -50,35 +63,39 @@ lastWeek : '[上]ddddLT', sameElse : 'L' }, + ordinalParse: /\d{1,2}(日|月|週)/, ordinal : function (number, period) { switch (period) { - case "d" : - case "D" : - case "DDD" : - return number + "日"; - case "M" : - return number + "月"; - case "w" : - case "W" : - return number + "週"; + case 'd' : + case 'D' : + case 'DDD' : + return number + '日'; + case 'M' : + return number + '月'; + case 'w' : + case 'W' : + return number + '週'; default : return number; } }, relativeTime : { - future : "%s內", - past : "%s前", - s : "幾秒", - m : "一分鐘", - mm : "%d分鐘", - h : "一小時", - hh : "%d小時", - d : "一天", - dd : "%d天", - M : "一個月", - MM : "%d個月", - y : "一年", - yy : "%d年" + future : '%s內', + past : '%s前', + s : '幾秒', + m : '一分鐘', + mm : '%d分鐘', + h : '一小時', + hh : '%d小時', + d : '一天', + dd : '%d天', + M : '一個月', + MM : '%d個月', + y : '一年', + yy : '%d年' } }); -})); + + return zh_tw; + +})); \ No newline at end of file diff --git a/lib/javascripts/moment_locale/zh_CN.js b/lib/javascripts/moment_locale/zh_CN.js deleted file mode 100644 index 11fc0342efd..00000000000 --- a/lib/javascripts/moment_locale/zh_CN.js +++ /dev/null @@ -1,73 +0,0 @@ -// moment.js language configuration -// language : chinese -// author : suupic : https://github.com/suupic - -moment.lang('zh-cn', { - months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"), - monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"), - weekdaysShort : "周日_周一_周二_周三_周四_周五_周六".split("_"), - weekdaysMin : "日_一_二_三_四_五_六".split("_"), - longDateFormat : { - LT : "Ah点mm", - L : "YYYY年MMMD日", - LL : "YYYY年MMMD日", - LLL : "YYYY年MMMD日LT", - LLLL : "YYYY年MMMD日ddddLT", - l : "YYYY年MMMD日", - ll : "YYYY年MMMD日", - lll : "YYYY年MMMD日LT", - llll : "YYYY年MMMD日ddddLT" - }, - meridiem : function (hour, minute, isLower) { - if (hour < 9) { - return "早上"; - } else if (hour < 11 && minute < 30) { - return "上午"; - } else if (hour < 13 && minute < 30) { - return "中午"; - } else if (hour < 18) { - return "下午"; - } else { - return "晚上"; - } - }, - calendar : { - sameDay : '[今天]LT', - nextDay : '[明天]LT', - nextWeek : '[下]ddddLT', - lastDay : '[昨天]LT', - lastWeek : '[上]ddddLT', - sameElse : 'L' - }, - ordinal : function (number, period) { - switch (period) { - case "d" : - case "D" : - case "DDD" : - return number + "日"; - case "M" : - return number + "月"; - case "w" : - case "W" : - return number + "周"; - default : - return number; - } - }, - relativeTime : { - future : "%s内", - past : "%s前", - s : "几秒", - m : "1分钟", - mm : "%d分钟", - h : "1小时", - hh : "%d小时", - d : "1天", - dd : "%d天", - M : "1个月", - MM : "%d个月", - y : "1年", - yy : "%d年" - } -}); diff --git a/lib/javascripts/moment_locale/zh_TW.js b/lib/javascripts/moment_locale/zh_TW.js deleted file mode 100644 index 8ac45323aeb..00000000000 --- a/lib/javascripts/moment_locale/zh_TW.js +++ /dev/null @@ -1,73 +0,0 @@ -// moment.js language configuration -// language : traditional chinese (zh-tw) -// author : Ben : https://github.com/ben-lin - -moment.lang('zh-tw', { - months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"), - monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"), - weekdaysShort : "週日_週一_週二_週三_週四_週五_週六".split("_"), - weekdaysMin : "日_一_二_三_四_五_六".split("_"), - longDateFormat : { - LT : "Ah點mm", - L : "YYYY年MMMD日", - LL : "YYYY年MMMD日", - LLL : "YYYY年MMMD日LT", - LLLL : "YYYY年MMMD日ddddLT", - l : "YYYY年MMMD日", - ll : "YYYY年MMMD日", - lll : "YYYY年MMMD日LT", - llll : "YYYY年MMMD日ddddLT" - }, - meridiem : function (hour, minute, isLower) { - if (hour < 9) { - return "早上"; - } else if (hour < 11 && minute < 30) { - return "上午"; - } else if (hour < 13 && minute < 30) { - return "中午"; - } else if (hour < 18) { - return "下午"; - } else { - return "晚上"; - } - }, - calendar : { - sameDay : '[今天]LT', - nextDay : '[明天]LT', - nextWeek : '[下]ddddLT', - lastDay : '[昨天]LT', - lastWeek : '[上]ddddLT', - sameElse : 'L' - }, - ordinal : function (number, period) { - switch (period) { - case "d" : - case "D" : - case "DDD" : - return number + "日"; - case "M" : - return number + "月"; - case "w" : - case "W" : - return number + "週"; - default : - return number; - } - }, - relativeTime : { - future : "%s內", - past : "%s前", - s : "幾秒", - m : "一分鐘", - mm : "%d分鐘", - h : "一小時", - hh : "%d小時", - d : "一天", - dd : "%d天", - M : "一個月", - MM : "%d個月", - y : "一年", - yy : "%d年" - } -}); diff --git a/lib/js_locale_helper.rb b/lib/js_locale_helper.rb index af06c334092..1374235eb4f 100644 --- a/lib/js_locale_helper.rb +++ b/lib/js_locale_helper.rb @@ -123,7 +123,16 @@ module JsLocaleHelper end def self.moment_locale(locale_str) + # moment.js uses a different naming scheme for locale files + locale_str = locale_str.tr('_', '-').downcase filename = Rails.root + "lib/javascripts/moment_locale/#{locale_str}.js" + + unless File.exists?(filename) + # try the language without the territory + locale_str = locale_str.partition('-').first + filename = Rails.root + "lib/javascripts/moment_locale/#{locale_str}.js" + end + if File.exists?(filename) File.read(filename) << "\n" end || "" diff --git a/lib/letter_avatar.rb b/lib/letter_avatar.rb index abde76ec080..7c79c033e9d 100644 --- a/lib/letter_avatar.rb +++ b/lib/letter_avatar.rb @@ -1,5 +1,18 @@ class LetterAvatar + class Identity + attr_accessor :color, :letter + + def self.from_username(username) + identity = new + identity.color = LetterAvatar::COLORS[ + Digest::MD5.hexdigest(username)[0...15].to_i(16) % LetterAvatar::COLORS.length + ] + identity.letter = username[0].upcase + identity + end + end + # BUMP UP if avatar algorithm changes VERSION = 5 @@ -9,19 +22,6 @@ class LetterAvatar class << self - class Identity - attr_accessor :color, :letter - - def self.from_username(username) - identity = new - identity.color = LetterAvatar::COLORS[ - Digest::MD5.hexdigest(username)[0...15].to_i(16) % LetterAvatar::COLORS.length - ] - identity.letter = username[0].upcase - identity - end - end - def version "#{VERSION}_#{image_magick_version}" end @@ -32,7 +32,7 @@ class LetterAvatar def generate(username, size, opts = nil) DistributedMutex.synchronize("letter_avatar_#{version}_#{username}") do - identity = Identity.from_username(username) + identity = (opts && opts[:identity]) || LetterAvatar::Identity.from_username(username) cache = true cache = false if opts && opts[:cache] == false diff --git a/lib/locale_file_walker.rb b/lib/locale_file_walker.rb new file mode 100644 index 00000000000..4f11ea9ff86 --- /dev/null +++ b/lib/locale_file_walker.rb @@ -0,0 +1,49 @@ +require 'psych' +require 'set' + +class LocaleFileWalker + protected + + def handle_document(document) + # we want to ignore the language (first key), so let's start at -1 + handle_nodes(document.root.children, -1, []) + end + + def handle_nodes(nodes, depth, parents) + if nodes + consecutive_scalars = 0 + nodes.each do |node| + consecutive_scalars = handle_node(node, depth, parents, consecutive_scalars) + end + end + end + + def handle_node(node, depth, parents, consecutive_scalars) + node_is_scalar = node.is_a?(Psych::Nodes::Scalar) + + if node_is_scalar + handle_scalar(node, depth, parents) if valid_scalar?(depth, consecutive_scalars) + elsif node.is_a?(Psych::Nodes::Alias) + handle_alias(node, depth, parents) + elsif node.is_a?(Psych::Nodes::Mapping) + handle_mapping(node, depth, parents) + handle_nodes(node.children, depth + 1, parents.dup) + end + + node_is_scalar ? consecutive_scalars + 1 : 0 + end + + def valid_scalar?(depth, consecutive_scalars) + depth >= 0 && consecutive_scalars.even? + end + + def handle_scalar(node, depth, parents) + parents[depth] = node.value + end + + def handle_alias(node, depth, parents) + end + + def handle_mapping(node, depth, parents) + end +end diff --git a/lib/memory_diagnostics.rb b/lib/memory_diagnostics.rb index d79d84407be..a49480677a9 100644 --- a/lib/memory_diagnostics.rb +++ b/lib/memory_diagnostics.rb @@ -21,7 +21,8 @@ module MemoryDiagnostics require 'objspace' diff = diff.map do |id| ObjectSpace._id2ref(id) rescue nil - end.compact! + end + diff.compact! report = "#{diff.length} objects have leaked\n" diff --git a/lib/middleware/anonymous_cache.rb b/lib/middleware/anonymous_cache.rb index a65eb2df1a4..a79b4225663 100644 --- a/lib/middleware/anonymous_cache.rb +++ b/lib/middleware/anonymous_cache.rb @@ -64,8 +64,13 @@ module Middleware CurrentUser.has_auth_cookie?(@env) end + def no_cache_bypass + request = Rack::Request.new(@env) + request.cookies['_bypass_cache'].nil? + end + def cacheable? - !!(!has_auth_cookie? && get?) + !!(!has_auth_cookie? && get? && no_cache_bypass) end def cached diff --git a/lib/mobile_detection.rb b/lib/mobile_detection.rb index 0e00bb876bc..a9e2702de1b 100644 --- a/lib/mobile_detection.rb +++ b/lib/mobile_detection.rb @@ -1,6 +1,6 @@ module MobileDetection def self.mobile_device?(user_agent) - user_agent =~ /Mobile|webOS|Nexus 7/ && !(user_agent =~ /iPad/) + user_agent =~ /Mobile/ && !(user_agent =~ /iPad/) end # we need this as a reusable chunk that is called from the cache diff --git a/lib/new_post_manager.rb b/lib/new_post_manager.rb index 901e7417e6f..f354a277ad1 100644 --- a/lib/new_post_manager.rb +++ b/lib/new_post_manager.rb @@ -69,9 +69,9 @@ class NewPostManager def self.user_needs_approval?(manager) user = manager.user - return false if user.staff? + return false if user.staff? || user.staged - (user.post_count < SiteSetting.approve_post_count) || + (user.trust_level <= TrustLevel.levels[:basic] && user.post_count < SiteSetting.approve_post_count) || (user.trust_level < SiteSetting.approve_unless_trust_level.to_i) || is_fast_typer?(manager) || matches_auto_block_regex?(manager) @@ -82,14 +82,11 @@ class NewPostManager result = manager.enqueue('default') - block = is_fast_typer?(manager) - - block ||= matches_auto_block_regex?(manager) - - manager.user.update_columns(blocked: true) if block + if is_fast_typer?(manager) || matches_auto_block_regex?(manager) + UserBlocker.block(manager.user, Discourse.system_user, keep_posts: true) + end result - end end @@ -105,7 +102,6 @@ class NewPostManager end def perform - # We never queue private messages return perform_create_post if @args[:archetype] == Archetype.private_message if args[:topic_id] && Topic.where(id: args[:topic_id], archetype: Archetype.private_message).exists? @@ -145,7 +141,6 @@ class NewPostManager def perform_create_post result = NewPostResult.new(:create_post) - creator = PostCreator.new(@user, @args) post = creator.create result.check_errors_from(creator) diff --git a/lib/onebox/engine/discourse_local_onebox.rb b/lib/onebox/engine/discourse_local_onebox.rb index db4075b43e2..9ac748e27fd 100644 --- a/lib/onebox/engine/discourse_local_onebox.rb +++ b/lib/onebox/engine/discourse_local_onebox.rb @@ -14,8 +14,10 @@ module Onebox if other.kind_of?(URI) uri = other begin - route = Rails.application.routes.recognize_path(uri.path) + route = Rails.application.routes.recognize_path(uri.path.sub(Discourse.base_uri, "")) case route[:controller] + when 'uploads' + super when 'topics' # super will use matches_regexp to match the domain name super @@ -32,14 +34,25 @@ module Onebox def to_html uri = URI::parse(@url) - route = Rails.application.routes.recognize_path(uri.path) - + route = Rails.application.routes.recognize_path(uri.path.sub(Discourse.base_uri, "")) + url = @url.sub(/[&?]source_topic_id=(\d+)/, "") + source_topic_id = $1.to_i # Figure out what kind of onebox to show based on the URL case route[:controller] + when 'uploads' + + url.gsub!("http:", "https:") if SiteSetting.use_https + if File.extname(uri.path) =~ /^.(mov|mp4|webm|ogv)$/ + return "#{url}" + elsif File.extname(uri.path) =~ /^.(mp3|ogg|wav)$/ + return "" + else + return false + end when 'topics' - linked = "#{@url}" + linked = "#{url}" if route[:post_number].present? && route[:post_number].to_i > 1 # Post Link post = Post.find_by(topic_id: route[:topic_id], post_number: route[:post_number].to_i) @@ -50,13 +63,15 @@ module Onebox topic = post.topic slug = Slug.for(topic.title) - excerpt = post.excerpt(SiteSetting.post_onebox_maxlength) + excerpt = post.excerpt(SiteSetting.post_onebox_maxlength, { keep_emoji_codes: true }) excerpt.gsub!("\n"," ") # hack to make it render for now excerpt.gsub!("[/quote]", "[quote]") quote = "[quote=\"#{post.user.username}, topic:#{topic.id}, slug:#{slug}, post:#{post.post_number}\"]#{excerpt}[/quote]" - cooked = PrettyText.cook(quote) + args = {} + args[:topic_id] = source_topic_id if source_topic_id > 0 + cooked = PrettyText.cook(quote, args) return cooked else @@ -77,8 +92,8 @@ module Onebox end quote = post.excerpt(SiteSetting.post_onebox_maxlength) - args = { original_url: @url, - title: topic.title, + args = { original_url: url, + title: PrettyText.unescape_emoji(topic.title), avatar: PrettyText.avatar_img(topic.user.avatar_template, 'tiny'), posts_count: topic.posts_count, last_post: FreedomPatches::Rails4.time_ago_in_words(topic.last_posted_at, false, scope: :'datetime.distance_in_words_verbose'), diff --git a/lib/onebox/templates/discourse_topic_onebox.hbs b/lib/onebox/templates/discourse_topic_onebox.hbs index a070f974f1f..b9ca0aff51b 100644 --- a/lib/onebox/templates/discourse_topic_onebox.hbs +++ b/lib/onebox/templates/discourse_topic_onebox.hbs @@ -2,7 +2,7 @@
    {{{avatar}}} - {{title}} {{{category_html}}} + {{{title}}} {{{category_html}}}
    {{{quote}}}
    diff --git a/lib/oneboxer.rb b/lib/oneboxer.rb index 50aa8bc7b06..a2152e2d8a6 100644 --- a/lib/oneboxer.rb +++ b/lib/oneboxer.rb @@ -76,12 +76,30 @@ module Oneboxer doc end - def self.apply(string_or_doc) + def self.append_source_topic_id(url, topic_id) + # hack urls to create proper expansions + if url =~ Regexp.new("^#{Discourse.base_url.gsub(".","\\.")}.*$", true) + uri = URI.parse(url) rescue nil + if uri && uri.path + route = Rails.application.routes.recognize_path(uri.path) rescue nil + if route && route[:controller] == 'topics' + url += (url =~ /\?/ ? "&" : "?") + "source_topic_id=#{topic_id}" + end + end + end + url + end + + def self.apply(string_or_doc, args=nil) doc = string_or_doc doc = Nokogiri::HTML::fragment(doc) if doc.is_a?(String) changed = false Oneboxer.each_onebox_link(doc) do |url, element| + + if args && args[:topic_id] + url = append_source_topic_id(url, args[:topic_id]) + end onebox, _preview = yield(url,element) if onebox parsed_onebox = Nokogiri::HTML::fragment(onebox) @@ -138,4 +156,3 @@ module Oneboxer end end - diff --git a/lib/plugin/auth_provider.rb b/lib/plugin/auth_provider.rb index 367f9a65164..cbc12c6f450 100644 --- a/lib/plugin/auth_provider.rb +++ b/lib/plugin/auth_provider.rb @@ -1,9 +1,26 @@ class Plugin::AuthProvider - attr_accessor :glyph, :background_color, :title, - :message, :frame_width, :frame_height, :authenticator + + def self.auth_attributes + [:glyph, :background_color, :title, :message, :frame_width, :frame_height, :authenticator, + :title_setting, :enabled_setting, :full_screen_login] + end + + attr_accessor(*auth_attributes) def name authenticator.name end + def to_json + result = {name: name} + result['titleOverride'] = title if title + result['titleSetting'] = title_setting if title_setting + result['enabledSetting'] = enabled_setting if enabled_setting + result['messageOverride'] = message if message + result['frameWidth'] = frame_width if frame_width + result['frameHeight'] = frame_height if frame_height + result['fullScreenLogin'] = full_screen_login if full_screen_login + result.to_json + end + end diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb index d51adc4f139..7fb3735de1d 100644 --- a/lib/plugin/instance.rb +++ b/lib/plugin/instance.rb @@ -17,8 +17,13 @@ class Plugin::Instance } end - def seed_data - @seed_data ||= {} + # Memoized hash readers + [:seed_data, :emojis].each do |att| + class_eval %Q{ + def #{att} + @#{att} ||= HashWithIndifferentAccess.new({}) + end + } end def self.find_all(parent_path) @@ -49,7 +54,7 @@ class Plugin::Instance delegate :name, to: :metadata def add_to_serializer(serializer, attr, define_include_method=true, &block) - klass = "#{serializer.to_s.classify}Serializer".constantize + klass = "#{serializer.to_s.classify}Serializer".constantize rescue "#{serializer.to_s}Serializer".constantize klass.attributes(attr) unless attr.to_s.start_with?("include_") @@ -62,10 +67,14 @@ class Plugin::Instance klass.send(:define_method, "include_#{attr}?") { plugin.enabled? } end + def whitelist_staff_user_custom_field(field) + User.register_plugin_staff_custom_field(field, self) + end + # Extend a class but check that the plugin is enabled # for class methods use `add_class_method` def add_to_class(klass, attr, &block) - klass = klass.to_s.classify.constantize + klass = klass.to_s.classify.constantize rescue klass.to_s.constantize hidden_method_name = :"#{attr}_without_enable_check" klass.send(:define_method, hidden_method_name, &block) @@ -117,19 +126,23 @@ class Plugin::Instance # will make sure all the assets this plugin needs are registered def generate_automatic_assets! paths = [] + assets = [] + automatic_assets.each do |path, contents| - unless File.exists? path - ensure_directory path - File.open(path,"w") do |f| - f.write(contents) - end - end + write_asset(path, contents) paths << path + assets << [path] + end + + automatic_server_assets.each do |path, contents| + write_asset(path, contents) + paths << path + assets << [path, :server_side] end delete_extra_automatic_assets(paths) - paths + assets end def delete_extra_automatic_assets(good_paths) @@ -213,18 +226,17 @@ class Plugin::Instance seed_data[key] = value end + def register_emoji(name, url) + emojis[name] = url + end + def automatic_assets css = styles.join("\n") js = javascripts.join("\n") auth_providers.each do |auth| - overrides = "" - overrides = ", titleOverride: '#{auth.title}'" if auth.title - overrides << ", messageOverride: '#{auth.message}'" if auth.message - overrides << ", frameWidth: '#{auth.frame_width}'" if auth.frame_width - overrides << ", frameHeight: '#{auth.frame_height}'" if auth.frame_height - js << "Discourse.LoginMethod.register(Discourse.LoginMethod.create({name: '#{auth.name}'#{overrides}}));\n" + js << "Discourse.LoginMethod.register(Discourse.LoginMethod.create(#{auth.to_json}));\n" if auth.glyph css << ".btn-social.#{auth.name}:before{ content: '#{auth.glyph}'; }\n" @@ -246,9 +258,40 @@ class Plugin::Instance hash = Digest::SHA1.hexdigest asset ["#{auto_generated_path}/plugin_#{hash}.#{extension}", asset] end - end + def automatic_server_assets + js = "" + + unless emojis.blank? + js << "Discourse.Emoji.addCustomEmojis(function() {" << "\n" + + if @enabled_site_setting.present? + js << "if (Discourse.SiteSettings.#{@enabled_site_setting}) {" << "\n" + end + + emojis.each do |name, url| + js << "Discourse.Dialect.registerEmoji('#{name}', '#{url}');" << "\n" + end + + if @enabled_site_setting.present? + js << "}" << "\n" + end + + js << "});" << "\n" + end + + result = [] + + if js.present? + # Generate an IIFE for the JS + asset = "(function(){#{js}})();" + hash = Digest::SHA1.hexdigest(asset) + result << ["#{auto_generated_path}/plugin_#{hash}.js", asset] + end + + result + end # note, we need to be able to parse seperately to activation. # this allows us to present information about a plugin in the UI @@ -268,7 +311,7 @@ class Plugin::Instance self.instance_eval File.read(path), path if auto_assets = generate_automatic_assets! - assets.concat auto_assets.map{|a| [a]} + assets.concat(auto_assets) end register_assets! unless assets.blank? @@ -305,7 +348,8 @@ class Plugin::Instance def auth_provider(opts) provider = Plugin::AuthProvider.new - [:glyph, :background_color, :title, :message, :frame_width, :frame_height, :authenticator].each do |sym| + + Plugin::AuthProvider.auth_attributes.each do |sym| provider.send "#{sym}=", opts.delete(sym) end auth_providers << provider @@ -358,4 +402,13 @@ class Plugin::Instance end end + private + + def write_asset(path, contents) + unless File.exists?(path) + ensure_directory(path) + File.open(path,"w") { |f| f.write(contents) } + end + end + end diff --git a/lib/post_action_creator.rb b/lib/post_action_creator.rb new file mode 100644 index 00000000000..e995db1a298 --- /dev/null +++ b/lib/post_action_creator.rb @@ -0,0 +1,20 @@ +# creates post actions based on a post and a user +class PostActionCreator + + def initialize(user, post) + @user = user + @post = post + end + + def perform(action) + guardian.ensure_post_can_act!(@post, action, taken_actions: PostAction.counts_for([@post].compact, @user)[@post.try(:id)]) + PostAction.act(@user, @post, action) + end + + private + + def guardian + @guardian ||= Guardian.new(@user) + end + +end diff --git a/lib/post_creator.rb b/lib/post_creator.rb index 21b07963f57..62bc2a57934 100644 --- a/lib/post_creator.rb +++ b/lib/post_creator.rb @@ -57,6 +57,7 @@ class PostCreator opts[:title] = pg_clean_up(opts[:title]) if opts[:title] && opts[:title].include?("\u0000") opts[:raw] = pg_clean_up(opts[:raw]) if opts[:raw] && opts[:raw].include?("\u0000") opts.delete(:reply_to_post_number) unless opts[:topic_id] + @guardian = opts[:guardian] if opts[:guardian] @spam = false end @@ -133,6 +134,7 @@ class PostCreator create_embedded_topic ensure_in_allowed_users if guardian.is_staff? + unarchive_message @post.advance_draft_sequence @post.save_reply_relationships end @@ -170,13 +172,13 @@ class PostCreator def self.before_create_tasks(post) set_reply_info(post) - post.word_count = post.raw.scan(/\w+/).size + post.word_count = post.raw.scan(/[[:word:]]+/).size post.post_number ||= Topic.next_post_number(post.topic_id, post.reply_to_post_number.present?) cooking_options = post.cooking_options || {} cooking_options[:topic_id] = post.topic_id - post.cooked ||= post.cook(post.raw, cooking_options) + post.cooked ||= post.cook(post.raw, cooking_options.symbolize_keys) post.sort_order = post.post_number post.last_version_at ||= Time.now end @@ -260,10 +262,26 @@ class PostCreator end def ensure_in_allowed_users - return unless @topic.private_message? + return unless @topic.private_message? && @topic.id unless @topic.topic_allowed_users.where(user_id: @user.id).exists? - @topic.topic_allowed_users.create!(user_id: @user.id) + unless @topic.topic_allowed_groups.where('group_id IN ( + SELECT group_id FROM group_users where user_id = ? + )',@user.id).exists? + @topic.topic_allowed_users.create!(user_id: @user.id) + end + end + end + + def unarchive_message + return unless @topic.private_message? && @topic.id + + UserArchivedMessage.where(topic_id: @topic.id).pluck(:user_id).each do |user_id| + UserArchivedMessage.move_to_inbox!(user_id, @topic.id) + end + + GroupArchivedMessage.where(topic_id: @topic.id).pluck(:group_id).each do |group_id| + GroupArchivedMessage.move_to_inbox!(group_id, @topic.id) end end @@ -341,8 +359,10 @@ class PostCreator @user.user_stat.first_post_created_at = @post.created_at end - @user.user_stat.post_count += 1 - @user.user_stat.topic_count += 1 if @post.is_first_post? + unless @post.topic.private_message? + @user.user_stat.post_count += 1 + @user.user_stat.topic_count += 1 if @post.is_first_post? + end # We don't count replies to your own topics if !@opts[:import_mode] && @user.id != @topic.user_id @@ -382,8 +402,11 @@ class PostCreator post_number: @post.post_number, msecs: 5000) - - TopicUser.auto_track(@user.id, @topic.id, TopicUser.notification_reasons[:created_post]) + if @user.staged + TopicUser.auto_watch(@user.id, @topic.id) + else + TopicUser.auto_track(@user.id, @topic.id, TopicUser.notification_reasons[:created_post]) + end end def enqueue_jobs diff --git a/lib/post_destroyer.rb b/lib/post_destroyer.rb index 394b6ccc43f..9d35572f0f9 100644 --- a/lib/post_destroyer.rb +++ b/lib/post_destroyer.rb @@ -5,7 +5,7 @@ class PostDestroyer def self.destroy_old_hidden_posts - Post.where(deleted_at: nil) + Post.where(deleted_at: nil, hidden: true) .where("hidden_at < ?", 30.days.ago) .find_each do |post| PostDestroyer.new(Discourse.system_user, post).destroy @@ -65,6 +65,7 @@ class PostDestroyer def staff_recovered @post.recover! @post.publish_change_to_clients! :recovered + TopicTrackingState.publish_recover(@post.topic) if @post.topic && @post.post_number == 1 end # When a post is properly deleted. Well, it's still soft deleted, but it will no longer @@ -96,6 +97,7 @@ class PostDestroyer feature_users_in_the_topic if @post.topic @post.publish_change_to_clients! :deleted if @post.topic + TopicTrackingState.publish_delete(@post.topic) if @post.topic && @post.post_number == 1 end # When a user 'deletes' their own post. We just change the text. diff --git a/lib/post_jobs_enqueuer.rb b/lib/post_jobs_enqueuer.rb index d4e1354aaae..c5f1f6a9d15 100644 --- a/lib/post_jobs_enqueuer.rb +++ b/lib/post_jobs_enqueuer.rb @@ -7,8 +7,8 @@ class PostJobsEnqueuer end def enqueue_jobs - # We need to enqueue jobs after the transaction. Otherwise they might begin before the data has - # been comitted. + # We need to enqueue jobs after the transaction. + # Otherwise they might begin before the data has been comitted. enqueue_post_alerts unless @opts[:import_mode] feature_topic_users unless @opts[:import_mode] trigger_post_post_process diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb index 6a97b166558..9881274d725 100644 --- a/lib/post_revisor.rb +++ b/lib/post_revisor.rb @@ -154,6 +154,7 @@ class PostRevisor POST_TRACKED_FIELDS.each do |field| return true if @fields.has_key?(field) && @fields[field] != @post.send(field) end + advance_draft_sequence false end @@ -174,7 +175,8 @@ class PostRevisor end def ninja_edit? - @revised_at - @last_version_at <= SiteSetting.ninja_edit_window.to_i + return false if @post.has_active_flag? + @revised_at - @last_version_at <= SiteSetting.editing_grace_period.to_i end def owner_changed? @@ -229,10 +231,10 @@ class PostRevisor end @post.last_editor_id = @editor.id - @post.word_count = @fields[:raw].scan(/\w+/).size if @fields.has_key?(:raw) + @post.word_count = @fields[:raw].scan(/[[:word:]]+/).size if @fields.has_key?(:raw) @post.self_edits += 1 if self_edit? - clear_flags_and_unhide_post + remove_flags_and_unhide_post @post.extract_quoted_post_numbers @@ -269,9 +271,11 @@ class PostRevisor @editor == @post.user end - def clear_flags_and_unhide_post + def remove_flags_and_unhide_post return unless editing_a_flagged_and_hidden_post? - PostAction.clear_flags!(@post, Discourse.system_user) + @post.post_actions.where(post_action_type_id: PostActionType.flag_types.values).each do |action| + action.remove_act!(Discourse.system_user) + end @post.unhide! end @@ -393,11 +397,15 @@ class PostRevisor body = @post.cooked matches = body.scan(/\(.*)\<\/p\>/) - if matches && matches[0] && matches[0][0] - new_description = matches[0][0] - new_description = nil if new_description == I18n.t("category.replace_paragraph") + + matches.each do |match| + next if match[0] =~ /\ @secs} + @max - arr.size + end + private def seconds_to_wait diff --git a/lib/rate_limiter/limit_exceeded.rb b/lib/rate_limiter/limit_exceeded.rb index 2b85b467b07..787bcdd381b 100644 --- a/lib/rate_limiter/limit_exceeded.rb +++ b/lib/rate_limiter/limit_exceeded.rb @@ -2,9 +2,30 @@ class RateLimiter # A rate limit has been exceeded. class LimitExceeded < StandardError - attr_accessor :available_in - def initialize(available_in) + attr_reader :type + + def initialize(available_in, type=nil) @available_in = available_in + @type = type + end + + def description + time_left = "" + if @available_in < 1.minute.to_i + time_left = I18n.t("rate_limiter.seconds", count: @available_in) + elsif @available_in < 1.hour.to_i + time_left = I18n.t("rate_limiter.minutes", count: (@available_in / 1.minute.to_i)) + else + time_left = I18n.t("rate_limiter.hours", count: (@available_in / 1.hour.to_i)) + end + + if @type.present? + type_key = @type.tr("-", "_") + msg = I18n.t("rate_limiter.by_type.#{type_key}", time_left: time_left, default: "") + return msg if msg.present? + end + + I18n.t("rate_limiter.too_many_requests", time_left: time_left) end end diff --git a/lib/scheduler/manager.rb b/lib/scheduler/manager.rb index 2f2b42d4a97..78d1de7fa4c 100644 --- a/lib/scheduler/manager.rb +++ b/lib/scheduler/manager.rb @@ -10,7 +10,6 @@ module Scheduler class Manager attr_accessor :random_ratio, :redis - class Runner def initialize(manager) @mutex = Mutex.new @@ -157,7 +156,6 @@ module Scheduler lock do schedule_info(klass).schedule! end - end def remove(klass) @@ -203,8 +201,8 @@ module Scheduler def schedule_next_job(hostname=nil) (key, due), _ = redis.zrange Manager.queue_key(hostname), 0, 0, withscores: true - return unless key + if due.to_i <= Time.now.to_i klass = get_klass(key) unless klass diff --git a/lib/search.rb b/lib/search.rb index e99e6036129..5bfd9d4e2ed 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -76,7 +76,7 @@ class Search def self.prepare_data(search_data) data = search_data.squish # TODO rmmseg is designed for chinese, we need something else for Korean / Japanese - if ['zh_TW', 'zh_CN', 'ja', 'ko'].include?(SiteSetting.default_locale) + if ['zh_TW', 'zh_CN', 'ja', 'ko'].include?(SiteSetting.default_locale) || SiteSetting.search_tokenize_chinese_japanese_korean unless defined? RMMSeg require 'rmmseg' RMMSeg::Dictionary.load_dictionaries @@ -94,6 +94,40 @@ class Search data end + def self.word_to_date(str) + + if str =~ /^[0-9]{1,3}$/ + return Time.zone.now.beginning_of_day.days_ago(str.to_i) + end + + if str =~ /^([12][0-9]{3})(-([0-1]?[0-9]))?(-([0-3]?[0-9]))?$/ + year = $1.to_i + month = $2 ? $3.to_i : 1 + day = $4 ? $5.to_i : 1 + + return if day==0 || month==0 || day > 31 || month > 12 + + return Time.zone.parse("#{year}-#{month}-#{day}") rescue nil + end + + if str.downcase == "yesterday" + return Time.zone.now.beginning_of_day.yesterday + end + + titlecase = str.downcase.titlecase + + if Date::DAYNAMES.include?(titlecase) + return Time.zone.now.beginning_of_week(str.downcase.to_sym) + end + + if idx = (Date::MONTHNAMES.find_index(titlecase) || + Date::ABBR_MONTHNAMES.find_index(titlecase)) + delta = Time.zone.now.month - idx + delta += 12 if delta < 0 + Time.zone.now.beginning_of_month.months_ago(delta) + end + end + def initialize(term, opts=nil) @opts = opts || {} @guardian = @opts[:guardian] || Guardian.new @@ -185,6 +219,18 @@ class Search posts.where("posts.post_number = 1") end + advanced_filter(/in:pinned/) do |posts| + posts.where("topics.pinned_at IS NOT NULL") + end + + advanced_filter(/in:unpinned/) do |posts| + if @guardian.user + posts.where("topics.pinned_at IS NOT NULL AND topics.id IN ( + SELECT topic_id FROM topic_users WHERE user_id = ? AND cleared_pinned_at IS NOT NULL + )", @guardian.user.id) + end + end + advanced_filter(/badge:(.*)/) do |posts,match| badge_id = Badge.where('name ilike ? OR id = ?', match, match.to_i).pluck(:id).first if badge_id @@ -243,7 +289,7 @@ class Search end advanced_filter(/user:(.+)/) do |posts,match| - user_id = User.where('username_lower = ? OR id = ?', match.downcase, match.to_i).pluck(:id).first + user_id = User.where(staged: false).where('username_lower = ? OR id = ?', match.downcase, match.to_i).pluck(:id).first if user_id posts.where("posts.user_id = #{user_id}") else @@ -251,14 +297,20 @@ class Search end end - advanced_filter(/min_age:(\d+)/) do |posts,match| - n = match.to_i - posts.where("topics.created_at > ?", n.days.ago) + advanced_filter(/before:(.*)/) do |posts,match| + if date = Search.word_to_date(match) + posts.where("posts.created_at < ?", date) + else + posts + end end - advanced_filter(/max_age:(\d+)/) do |posts,match| - n = match.to_i - posts.where("topics.created_at < ?", n.days.ago) + advanced_filter(/after:(.*)/) do |posts,match| + if date = Search.word_to_date(match) + posts.where("posts.created_at > ?", date) + else + posts + end end private @@ -379,12 +431,16 @@ class Search end def user_search + return if SiteSetting.hide_user_profiles_from_public && !@guardian.user + users = User.includes(:user_search_data) - .where("active = true AND user_search_data.search_data @@ #{ts_query("simple")}") + .references(:user_search_data) + .where(active: true) + .where(staged: false) + .where("user_search_data.search_data @@ #{ts_query("simple")}") .order("CASE WHEN username_lower = '#{@original_term.downcase}' THEN 0 ELSE 1 END") .order("last_posted_at DESC") .limit(@limit) - .references(:user_search_data) users.each do |user| @results.add(user) @@ -438,7 +494,15 @@ class Search if @search_context.is_a?(User) if opts[:private_messages] - posts = posts.where("topics.id IN (SELECT topic_id FROM topic_allowed_users WHERE user_id = ?)", @search_context.id) + posts = posts.where("topics.id IN (SELECT topic_id + FROM topic_allowed_users + WHERE user_id = :user_id + UNION ALL + SELECT tg.topic_id + FROM topic_allowed_groups tg + JOIN group_users gu ON gu.user_id = :user_id AND + gu.group_id = tg.group_id)", + user_id: @search_context.id) else posts = posts.where("posts.user_id = #{@search_context.id}") end diff --git a/lib/search/grouped_search_results.rb b/lib/search/grouped_search_results.rb index 387696c300c..2fa450bb745 100644 --- a/lib/search/grouped_search_results.rb +++ b/lib/search/grouped_search_results.rb @@ -25,6 +25,14 @@ class Search @users = [] end + def find_user_data(guardian) + if user = guardian.user + topics = @posts.map(&:topic) + topic_lookup = TopicUser.lookup_for(user, topics) + topics.each { |ft| ft.user_data = topic_lookup[ft.id] } + end + end + def blurb(post) GroupedSearchResults.blurb_for(post.cooked, @term, @blurb_length) end diff --git a/lib/sidekiq/pausable.rb b/lib/sidekiq/pausable.rb index 3ef356c8312..c7cd9b5928d 100644 --- a/lib/sidekiq/pausable.rb +++ b/lib/sidekiq/pausable.rb @@ -68,15 +68,13 @@ end # server middleware that will reschedule work whenever Sidekiq is paused class Sidekiq::Pausable - attr_reader :delay - def initialize(delay = 5.seconds) @delay = delay end def call(worker, msg, queue) if Sidekiq.paused? - worker.class.perform_in(delay, *msg['args']) + worker.class.perform_in(@delay, *msg['args']) else yield end diff --git a/lib/site_setting_extension.rb b/lib/site_setting_extension.rb index 90be6860fc3..7912d8dbea2 100644 --- a/lib/site_setting_extension.rb +++ b/lib/site_setting_extension.rb @@ -21,18 +21,18 @@ module SiteSettingExtension end def types - @types ||= Enum.new(:string, - :time, - :fixnum, - :float, - :bool, - :null, - :enum, - :list, - :url_list, - :host_list, - :category_list, - :value_list) + @types ||= Enum.new(string: 1, + time: 2, + fixnum: 3, + float: 4, + bool: 5, + null: 6, + enum: 7, + list: 8, + url_list: 9, + host_list: 10, + category_list: 11, + value_list: 12) end def mutex @@ -121,9 +121,11 @@ module SiteSettingExtension # exists it will be used instead of the setting and the setting will be hidden. # Useful for things like API keys on multisite. if opts[:shadowed_by_global] && GlobalSetting.respond_to?(name) - hidden_settings << name - shadowed_settings << name - current_value = GlobalSetting.send(name) + unless (val = GlobalSetting.send(name)) == ''.freeze + hidden_settings << name + shadowed_settings << name + current_value = val + end end if opts[:refresh] @@ -149,7 +151,7 @@ module SiteSettingExtension # just like a setting, except that it is available in javascript via DiscourseSession def client_setting(name, default = nil, opts = {}) setting(name, default, opts) - client_settings << name + client_settings << name.to_sym end def settings_hash @@ -371,8 +373,8 @@ module SiteSettingExtension protected def clear_cache! - SiteText.text_for_cache.clear Rails.cache.delete(SiteSettingExtension.client_settings_cache_key) + Site.clear_anon_cache! end def diff_hash(new_hash, old) diff --git a/lib/site_text_class_methods.rb b/lib/site_text_class_methods.rb deleted file mode 100644 index 7ff9b0a1c22..00000000000 --- a/lib/site_text_class_methods.rb +++ /dev/null @@ -1,66 +0,0 @@ -module SiteTextClassMethods - - def text_types - @types || [] - end - - def find_text_type(ct) - SiteText.text_types.find {|t| t.text_type == ct.to_sym} - end - - def add_text_type(text_type, opts=nil) - opts ||= {} - @types ||= [] - format = opts[:format] || :markdown - @types << SiteTextType.new(text_type, format, opts) - end - - def text_for_cache - @text_for_cache ||= DistributedCache.new("text_for_cache") - end - - def text_for(text_type, replacements=nil) - text = nil - text = text_for_cache[text_type] if replacements.blank? - text ||= uncached_text_for(text_type, replacements) - end - - def uncached_text_for(text_type, replacements=nil) - store_cache = replacements.blank? - - replacements ||= {} - replacements = {site_name: SiteSetting.title}.merge!(replacements) - replacements = SiteSetting.settings_hash.merge!(replacements) - - site_text = SiteText.select(:value).find_by(text_type: text_type) - - result = "" - if site_text.blank? - ct = find_text_type(text_type) - result = ct.default_text.dup if ct.present? - else - result = site_text.value.dup - end - - result.gsub!(/\%\{[^}]+\}/) do |m| - replacements[m[2..-2].to_sym] || m - end - - if store_cache - result.freeze - text_for_cache[text_type] = result - end - - result - end - - def find_or_new(text_type) - site_text = SiteText.find_by(text_type: text_type) - return site_text if site_text.present? - - site_text = SiteText.new - site_text.text_type = text_type - site_text - end - -end diff --git a/lib/system_message.rb b/lib/system_message.rb index 176298839cc..d38b5113f57 100644 --- a/lib/system_message.rb +++ b/lib/system_message.rb @@ -23,12 +23,22 @@ class SystemMessage title = I18n.t("system_messages.#{type}.subject_template", params) raw = I18n.t("system_messages.#{type}.text_body_template", params) - PostCreator.create(Discourse.site_contact_user, + creator = PostCreator.new(Discourse.site_contact_user, title: title, raw: raw, archetype: Archetype.private_message, target_usernames: @recipient.username, - subtype: TopicSubtype.system_message) + subtype: TopicSubtype.system_message, + skip_validations: true) + + post = creator.create + if creator.errors.present? + raise StandardError, creator.errors.to_s + end + + UserArchivedMessage.create!(user: Discourse.site_contact_user, topic: post.topic) + + post end def create_from_system_user(type, params = {}) @@ -50,7 +60,7 @@ class SystemMessage site_name: SiteSetting.title, username: @recipient.username, user_preferences_url: "#{Discourse.base_url}/users/#{@recipient.username_lower}/preferences", - new_user_tips: SiteText.text_for(:usage_tips, base_url: Discourse.base_url), + new_user_tips: I18n.t('system_messages.usage_tips.text_body_template', base_url: Discourse.base_url), site_password: "", base_url: Discourse.base_url, } diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index a6fc5d09ff8..ed695bc7da5 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -75,18 +75,25 @@ task 'assets:precompile:before' do end task 'assets:precompile:css' => 'environment' do - puts "Start compiling CSS: #{Time.zone.now}" - RailsMultisite::ConnectionManagement.each_connection do |db| - # Heroku precompiles assets before db migration, so tables may not exist. - # css will get precompiled during first request instead in that case. - if ActiveRecord::Base.connection.table_exists?(ColorScheme.table_name) - puts "Compiling css for #{db}" - [:desktop, :mobile, :desktop_rtl, :mobile_rtl].each do |target| - puts DiscourseStylesheets.compile(target) + if ENV["DONT_PRECOMPILE_CSS"] == "1" + STDERR.puts "Skipping CSS precompilation, ensure CSS lives in a shared directory across hosts" + else + STDERR.puts "Start compiling CSS: #{Time.zone.now}" + + RailsMultisite::ConnectionManagement.each_connection do |db| + # Heroku precompiles assets before db migration, so tables may not exist. + # css will get precompiled during first request instead in that case. + + if ActiveRecord::Base.connection.table_exists?(ColorScheme.table_name) + STDERR.puts "Compiling css for #{db}" + [:desktop, :mobile, :desktop_rtl, :mobile_rtl].each do |target| + STDERR.puts "target: #{target} #{DiscourseStylesheets.compile(target)}" + end end end + + STDERR.puts "Done compiling CSS: #{Time.zone.now}" end - puts "Done compiling CSS: #{Time.zone.now}" end def assets_path @@ -95,8 +102,8 @@ end def compress_node(from,to) to_path = "#{assets_path}/#{to}" - - source_map_root = (d=File.dirname(from)) == "." ? "/assets" : "/assets/#{d}" + assets = cdn_relative_path("/assets") + source_map_root = assets + ((d=File.dirname(from)) == "." ? "" : "/#{d}") source_map_url = cdn_path "/assets/#{to}.map" cmd = "uglifyjs '#{assets_path}/#{from}' -p relative -c -m -o '#{to_path}' --source-map-root '#{source_map_root}' --source-map '#{assets_path}/#{to}.map' --source-map-url '#{source_map_url}'" @@ -115,7 +122,7 @@ def compress_ruby(from,to) data = File.read("#{assets_path}/#{from}") uglified, map = Uglifier.new(comments: :none, - screw_ie8: false, + screw_ie8: true, source_filename: File.basename(from), output_filename: File.basename(to) ) @@ -128,7 +135,7 @@ end def gzip(path) STDERR.puts "gzip #{path}" - STDERR.puts `gzip -f -c -9 #{path} > #{path}.gz` + STDERR.puts `gzip -f -c -7 #{path} > #{path}.gz` end def compress(from,to) @@ -162,7 +169,7 @@ task 'assets:precompile' => 'assets:precompile:before' do STDERR.puts "Compressing: #{file}" # We can specify some files to never minify - unless to_skip.include?(info['logical_path']) + unless (ENV["DONT_MINIFY"] == "1") || to_skip.include?(info['logical_path']) FileUtils.mv(path, _path) compress(_file,file) end diff --git a/lib/tasks/auto_annotate_models.rake b/lib/tasks/auto_annotate_models.rake index fb1be240b3f..dde0cc03644 100644 --- a/lib/tasks/auto_annotate_models.rake +++ b/lib/tasks/auto_annotate_models.rake @@ -1,7 +1,7 @@ # NOTE: only doing this in development as some production environments (Heroku) # NOTE: are sensitive to local FS writes, and besides -- it's just not proper # NOTE: to have a dev-mode tool do its thing in production. -if(Rails.env.development?) +if(Rails.env.development? || Rails.env.test?) task :set_annotation_options do # You can override any of these by setting an environment variable of the # same name. @@ -18,8 +18,10 @@ if(Rails.env.development?) 'require' => "", 'exclude_tests' => "true", 'exclude_fixtures' => "true", + 'exclude_helpers' => "true", 'exclude_factories' => "true", 'exclude_serializers' => "true", + 'exclude_controllers' => "true", 'ignore_model_sub_dir' => "false", 'skip_on_db_migrate' => "true", 'format_bare' => "true", diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index ab40a807c22..e34ac22d418 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -7,14 +7,16 @@ end task 'db:migrate' => ['environment', 'set_locale'] do SeedFu.seed + SiteSetting.last_vacuum = Time.now.to_i if SiteSetting.last_vacuum == 0 + if SiteSetting.vacuum_db_days > 0 && SiteSetting.last_vacuum < (Time.now.to_i - SiteSetting.vacuum_db_days.days.to_i) - puts "Running VACUUM FULL ANALYZE to reclaim DB space, this may take a while" + puts "Running VACUUM ANALYZE to reclaim DB space, this may take a while" puts "Set to run every #{SiteSetting.vacuum_db_days} days (search for vacuum in site settings)" puts "#{Time.now} starting..." begin - Topic.exec_sql("VACUUM FULL ANALYZE") + Topic.exec_sql("VACUUM ANALYZE") rescue => e puts "VACUUM failed, skipping" puts e.to_s diff --git a/lib/tasks/emails.rake b/lib/tasks/emails.rake new file mode 100644 index 00000000000..1ab9c71d357 --- /dev/null +++ b/lib/tasks/emails.rake @@ -0,0 +1,56 @@ +def process_popmail(popmail) + begin + mail_string = popmail.pop + Email::Receiver.new(mail_string).process + rescue + putc "!" + else + putc "." + end +end + +desc "use this task to import a mailbox into Disourse" +task "emails:import" => :environment do + begin + unless SiteSetting.email_in + puts "ERROR: you should enable the 'email_in' site setting before running this task" + exit(1) + end + + address = ENV["ADDRESS"].presence || "pop.gmail.com" + port = (ENV["PORT"].presence || 995).to_i + ssl = (ENV["SSL"].presence || "1") == "1" + username = ENV["USERNAME"].presence + password = ENV["PASSWORD"].presence + + if username.blank? + puts "ERROR: expecting USERNAME= rake emails:import" + exit(2) + elsif password.blank? + puts "ERROR: expecting PASSWORD= rake emails:import" + exit(3) + end + + RateLimiter.disable + + mails_left = 1 + pop3 = Net::POP3.new(address, port) + pop3.enable_ssl if ssl + + while mails_left > 0 + pop3.start(username, password) do |pop| + pop.delete_all do |p| + process_popmail(p) + end + mails_left = pop.n_mails + end + end + + puts "Done" + rescue Net::POPAuthenticationError + puts "AUTH EXCEPTION: please make sure your credentials are correct." + exit(10) + ensure + RateLimiter.enable + end +end diff --git a/lib/tasks/posts.rake b/lib/tasks/posts.rake index 5f661e5500c..37fb02bfafd 100644 --- a/lib/tasks/posts.rake +++ b/lib/tasks/posts.rake @@ -8,6 +8,24 @@ task 'posts:refresh_oneboxes' => :environment do ENV['RAILS_DB'] ? rebake_posts(invalidate_oneboxes: true) : rebake_posts_all_sites(invalidate_oneboxes: true) end +desc 'Rebake all posts with a quote using a letter_avatar' +task 'posts:fix_letter_avatars' => :environment do + return unless SiteSetting.external_system_avatars_enabled + + search = Post.where("user_id <> -1") + .where("raw LIKE '%/letter\_avatar/%' OR cooked LIKE '%/letter\_avatar/%'") + + rebaked = 0 + total = search.count + + search.order(updated_at: :asc).find_each do |post| + rebake_post(post) + print_status(rebaked += 1, total) + end + + puts "", "#{rebaked} posts done!", "" +end + def rebake_posts_all_sites(opts = {}) RailsMultisite::ConnectionManagement.each_connection do |db| rebake_posts(opts) @@ -33,7 +51,7 @@ def rebake_posts(opts = {}) puts "", "#{rebaked} posts done!", "-" * 50 end -def rebake_post(post, opts) +def rebake_post(post, opts = {}) post.rebake!(opts) rescue => e puts "", "Failed to rebake (topic_id: #{post.topic_id}, post_id: #{post.id})", e, e.backtrace.join("\n") diff --git a/lib/tasks/uploads.rake b/lib/tasks/uploads.rake index dbbf8908297..9000c9b8b98 100644 --- a/lib/tasks/uploads.rake +++ b/lib/tasks/uploads.rake @@ -134,7 +134,7 @@ def migrate_to_s3 # retrieve the path to the local file path = local.path_for(upload) # make sure the file exists locally - if !File.exists?(path) + if !path or !File.exists?(path) putc "X" next end diff --git a/lib/text_sentinel.rb b/lib/text_sentinel.rb index 1210ad379b2..8e01a588813 100644 --- a/lib/text_sentinel.rb +++ b/lib/text_sentinel.rb @@ -73,7 +73,7 @@ class TextSentinel def seems_quiet? # We don't allow all upper case content in english - not((@text =~ /[A-Z]+/) && !(@text =~ /[^[:ascii:]]/) && (@text == @text.upcase)) + SiteSetting.allow_uppercase_posts || not((@text =~ /[A-Z]+/) && !(@text =~ /[^[:ascii:]]/) && (@text == @text.upcase)) end end diff --git a/lib/topic_creator.rb b/lib/topic_creator.rb index cff51e7c89a..d0548885d3d 100644 --- a/lib/topic_creator.rb +++ b/lib/topic_creator.rb @@ -64,15 +64,29 @@ class TopicCreator topic.notifier.watch_topic!(topic.user_id) end - user_ids = topic.topic_allowed_users(true).pluck(:user_id) - user_ids += topic.topic_allowed_groups(true).map { |t| t.group.users.pluck(:id) }.flatten - - user_ids.uniq.reject{ |id| id == topic.user_id }.each do |user_id| - topic.notifier.watch_topic!(user_id, nil) unless user_id == -1 + topic.topic_allowed_users(true).each do |tau| + next if tau.user_id == -1 || tau.user_id == topic.user_id + topic.notifier.watch!(tau.user_id) end - CategoryUser.auto_watch_new_topic(topic) - CategoryUser.auto_track_new_topic(topic) + topic.topic_allowed_groups(true).each do |tag| + tag.group.group_users.each do |gu| + next if gu.user_id == -1 || gu.user_id == topic.user_id + action = case gu.notification_level + when TopicUser.notification_levels[:tracking] then "track!" + when TopicUser.notification_levels[:regular] then "regular!" + when TopicUser.notification_levels[:muted] then "mute!" + when TopicUser.notification_levels[:watching] then "watch!" + else "track!" + end + topic.notifier.send(action, gu.user_id) + end + end + + unless topic.private_message? + CategoryUser.auto_watch_new_topic(topic) + CategoryUser.auto_track_new_topic(topic) + end end def setup_topic_params @@ -95,7 +109,7 @@ class TopicCreator category = find_category - @guardian.ensure_can_create!(Topic, category) unless @opts[:skip_validations] + @guardian.ensure_can_create!(Topic, category) unless (@opts[:skip_validations] || @opts[:archetype] == Archetype.private_message) topic_params[:category_id] = category.id if category.present? @@ -150,22 +164,36 @@ class TopicCreator def add_users(topic, usernames) return unless usernames - User.where(username: usernames.split(',')).each do |user| + + names = usernames.split(',').flatten + len = 0 + + User.where(username: names).each do |user| check_can_send_permission!(topic, user) @added_users << user topic.topic_allowed_users.build(user_id: user.id) + len += 1 end + + rollback_with!(topic, :target_user_not_found) unless len == names.length end def add_groups(topic, groups) return unless groups - Group.where(name: groups.split(',')).each do |group| + names = groups.split(',').flatten + len = 0 + + Group.where(name: names).each do |group| check_can_send_permission!(topic, group) topic.topic_allowed_groups.build(group_id: group.id) + len += 1 + group.update_columns(has_messages: true) unless group.has_messages end + + rollback_with!(topic, :target_group_not_found) unless len == names.length end def check_can_send_permission!(topic, obj) - rollback_with!(topic, :cant_send_pm) unless @guardian.can_send_private_message?(obj) + rollback_with!(topic, :cant_send_pm) unless @opts[:skip_validations] || @guardian.can_send_private_message?(obj) end end diff --git a/lib/topic_query.rb b/lib/topic_query.rb index 73d47fd4ada..1c061107c4b 100644 --- a/lib/topic_query.rb +++ b/lib/topic_query.rb @@ -6,6 +6,7 @@ require_dependency 'topic_list' require_dependency 'suggested_topics_builder' require_dependency 'topic_query_sql' +require_dependency 'avatar_lookup' class TopicQuery # Could be rewritten to %i if Ruby 1.9 is no longer supported @@ -28,6 +29,7 @@ class TopicQuery search slow_platform filter + group_name q) # Maps `order` to a columns in `topics` @@ -42,10 +44,14 @@ class TopicQuery 'created' => 'created_at' } + cattr_accessor :results_filter_callbacks + self.results_filter_callbacks = [] + def initialize(user=nil, options={}) options.assert_valid_keys(VALID_OPTIONS) @options = options.dup @user = user + @guardian = Guardian.new(@user) end def joined_topic_user(list=nil) @@ -54,16 +60,62 @@ class TopicQuery # Return a list of suggested topics for a topic def list_suggested_for(topic) + return if topic.private_message? && !@user + builder = SuggestedTopicsBuilder.new(topic) + pm_params = + if topic.private_message? + + group_ids = topic.topic_allowed_groups + .where('group_id IN (SELECT group_id FROM group_users WHERE user_id = :user_id)', user_id: @user.id) + .pluck(:group_id) + { + topic: topic, + my_group_ids: group_ids, + target_group_ids: topic.topic_allowed_groups.pluck(:group_id), + target_user_ids: topic.topic_allowed_users.pluck(:user_id) - [@user.id] + } + end + # When logged in we start with different results if @user - builder.add_results(unread_results(topic: topic, per_page: builder.results_left), :high) - builder.add_results(new_results(topic: topic, per_page: builder.category_results_left)) unless builder.full? - end - builder.add_results(random_suggested(topic, builder.results_left, builder.excluded_topic_ids)) unless builder.full? + if topic.private_message? - create_list(:suggested, {unordered: true}, builder.results) + builder.add_results(new_messages( + pm_params.merge(count: builder.results_left) + )) unless builder.full? + + builder.add_results(unread_messages( + pm_params.merge(count: builder.results_left) + )) unless builder.full? + + else + builder.add_results(unread_results(topic: topic, per_page: builder.results_left), :high) + builder.add_results(new_results(topic: topic, per_page: builder.category_results_left)) unless builder.full? + end + end + + if topic.private_message? + + builder.add_results(related_messages_group( + pm_params.merge(count: [3, builder.results_left].max, + exclude: builder.excluded_topic_ids) + )) if pm_params[:my_group_ids].present? + + builder.add_results(related_messages_user( + pm_params.merge(count: [3, builder.results_left].max, + exclude: builder.excluded_topic_ids) + )) + else + builder.add_results(random_suggested(topic, builder.results_left, builder.excluded_topic_ids)) unless builder.full? + end + + params = {unordered: true} + if topic.private_message? + params[:preload_posters] = true + end + create_list(:suggested, params, builder.results) end # The latest view of topics @@ -112,23 +164,61 @@ class TopicQuery end end + def not_archived(list, user) + list.joins("LEFT JOIN user_archived_messages um + ON um.user_id = #{user.id.to_i} AND um.topic_id = topics.id") + .where('um.user_id IS NULL') + end + def list_private_messages(user) - list = private_messages_for(user) + list = private_messages_for(user, :user) + + list = not_archived(list, user) + .where('NOT (topics.participant_count = 1 AND topics.user_id = ?)', user.id) + + create_list(:private_messages, {}, list) + end + + def list_private_messages_archive(user) + list = private_messages_for(user, :user) + list = list.joins(:user_archived_messages).where('user_archived_messages.user_id = ?', user.id) create_list(:private_messages, {}, list) end def list_private_messages_sent(user) - list = private_messages_for(user) - list = list.where(user_id: user.id) + list = private_messages_for(user, :user) + list = list.where('EXISTS ( + SELECT 1 FROM posts + WHERE posts.topic_id = topics.id AND + posts.user_id = ? + )', user.id) + list = not_archived(list, user) create_list(:private_messages, {}, list) end def list_private_messages_unread(user) - list = private_messages_for(user) + list = private_messages_for(user, :user) list = list.where("tu.last_read_post_number IS NULL OR tu.last_read_post_number < topics.highest_post_number") create_list(:private_messages, {}, list) end + def list_private_messages_group(user) + list = private_messages_for(user, :group) + group_id = Group.where('name ilike ?', @options[:group_name]).pluck(:id).first + list = list.joins("LEFT JOIN group_archived_messages gm ON gm.topic_id = topics.id AND + gm.group_id = #{group_id.to_i}") + list = list.where("gm.id IS NULL") + create_list(:private_messages, {}, list) + end + + def list_private_messages_group_archive(user) + list = private_messages_for(user, :group) + group_id = Group.where('name ilike ?', @options[:group_name]).pluck(:id).first + list = list.joins("JOIN group_archived_messages gm ON gm.topic_id = topics.id AND + gm.group_id = #{group_id.to_i}") + create_list(:private_messages, {}, list) + end + def list_category_topic_ids(category) query = default_results(category: category.id) pinned_ids = query.where('pinned_at IS NOT NULL AND category_id = ?', category.id) @@ -156,7 +246,6 @@ class TopicQuery end def prioritize_pinned_topics(topics, options) - pinned_clause = options[:category_id] ? "topics.category_id = #{options[:category_id].to_i} AND" : "pinned_globally AND " pinned_clause << " pinned_at IS NOT NULL " if @user @@ -185,36 +274,71 @@ class TopicQuery topics = yield(topics) if block_given? options = options.merge(@options) - if (options[:order] || "activity") == "activity" && !options[:unordered] + if ["activity","default"].include?(options[:order] || "activity") && + !options[:unordered] && + filter != :private_messages topics = prioritize_pinned_topics(topics, options) end - topics = topics.to_a.each do |t| + topics = topics.to_a + + if options[:preload_posters] + user_ids = [] + topics.each do |ft| + user_ids << ft.user_id << ft.last_post_user_id << ft.featured_user_ids << ft.allowed_user_ids + end + + avatar_lookup = AvatarLookup.new(user_ids) + topics.each do |t| + t.posters = t.posters_summary(avatar_lookup: avatar_lookup) + end + end + + topics.each do |t| + t.allowed_user_ids = filter == :private_messages ? t.allowed_users.map{|u| u.id} : [] end - list = TopicList.new(filter, @user, topics.to_a, options.merge(@options)) + list = TopicList.new(filter, @user, topics, options.merge(@options)) list.per_page = per_page_setting list end def latest_results(options={}) result = default_results(options) + result = remove_muted_topics(result, @user) unless options && options[:state] == "muted".freeze result = remove_muted_categories(result, @user, exclude: options[:category]) + + # plugins can remove topics here: + self.class.results_filter_callbacks.each do |filter_callback| + result = filter_callback.call(:latest, result, @user, options) + end + result end def unread_results(options={}) result = TopicQuery.unread_filter(default_results(options.reverse_merge(:unordered => true))) .order('CASE WHEN topics.user_id = tu.user_id THEN 1 ELSE 2 END') + + self.class.results_filter_callbacks.each do |filter_callback| + result = filter_callback.call(:unread, result, @user, options) + end + suggested_ordering(result, options) end def new_results(options={}) # TODO does this make sense or should it be ordered on created_at # it is ordering on bumped_at now - result = TopicQuery.new_filter(default_results(options.reverse_merge(:unordered => true)), @user.treat_as_new_topic_start_date) + result = TopicQuery.new_filter(default_results(options.reverse_merge(:unordered => true)), @user.user_option.treat_as_new_topic_start_date) + result = remove_muted_topics(result, @user) result = remove_muted_categories(result, @user, exclude: options[:category]) + + self.class.results_filter_callbacks.each do |filter_callback| + result = filter_callback.call(:new, result, @user, options) + end + suggested_ordering(result, options) end @@ -224,17 +348,27 @@ class TopicQuery @options[:slow_platform] ? 15 : 30 end - - def private_messages_for(user) + def private_messages_for(user, type) options = @options options.reverse_merge!(per_page: per_page_setting) - # Start with a list of all topics - result = Topic.includes(:allowed_users) - .where("topics.id IN (SELECT topic_id FROM topic_allowed_users WHERE user_id = #{user.id.to_i})") - .joins("LEFT OUTER JOIN topic_users AS tu ON (topics.id = tu.topic_id AND tu.user_id = #{user.id.to_i})") - .order("topics.bumped_at DESC") - .private_messages + result = Topic + + if type == :group + result = result.includes(:allowed_groups) + result = result.where("topics.id IN (SELECT topic_id FROM topic_allowed_groups + WHERE group_id IN ( + SELECT group_id FROM group_users WHERE user_id = #{user.id.to_i}) AND + group_id IN (SELECT id FROM groups WHERE name ilike ?) + )", @options[:group_name]) + elsif type == :user + result = result.includes(:allowed_users) + result = result.where("topics.id IN (SELECT topic_id FROM topic_allowed_users WHERE user_id = #{user.id.to_i})") + end + + result = result.joins("LEFT OUTER JOIN topic_users AS tu ON (topics.id = tu.topic_id AND tu.user_id = #{user.id.to_i})") + .order("topics.bumped_at DESC") + .private_messages result = result.limit(options[:per_page]) unless options[:limit] == false result = result.visible if options[:visible] || @user.nil? || @user.regular? @@ -267,6 +401,11 @@ class TopicQuery return result.includes(:first_post).order("(SELECT like_count FROM posts p3 WHERE p3.topic_id = topics.id AND p3.post_number = 1) #{sort_dir}") end + if sort_column.start_with?('custom_fields') + field = sort_column.split('.')[1] + return result.order("(SELECT CASE WHEN EXISTS (SELECT true FROM topic_custom_fields tcf WHERE tcf.topic_id::integer = topics.id::integer AND tcf.name = '#{field}') THEN (SELECT value::integer FROM topic_custom_fields tcf WHERE tcf.topic_id::integer = topics.id::integer AND tcf.name = '#{field}') ELSE 0 END) #{sort_dir}") + end + result.order("topics.#{sort_column} #{sort_dir}") end @@ -359,7 +498,7 @@ class TopicQuery when 'unlisted' result = result.where('NOT topics.visible') when 'deleted' - guardian = Guardian.new(@user) + guardian = @guardian if guardian.is_staff? result = result.where('topics.deleted_at IS NOT NULL') require_deleted_clause = false @@ -391,9 +530,16 @@ class TopicQuery result = result.where('topics.posts_count <= ?', options[:max_posts]) if options[:max_posts].present? result = result.where('topics.posts_count >= ?', options[:min_posts]) if options[:min_posts].present? - Guardian.new(@user).filter_allowed_categories(result) + @guardian.filter_allowed_categories(result) end + def remove_muted_topics(list, user) + if user + list = list.where('COALESCE(tu.notification_level,1) > :muted', muted: TopicUser.notification_levels[:muted]) + end + + list + end def remove_muted_categories(list, user, opts=nil) category_id = get_category_id(opts[:exclude]) if opts @@ -407,14 +553,92 @@ class TopicQuery AND cu.category_id = topics.category_id AND cu.notification_level = :muted AND cu.category_id <> :category_id + AND (tu.notification_level IS NULL OR tu.notification_level < :tracking) )", user_id: user.id, muted: CategoryUser.notification_levels[:muted], + tracking: TopicUser.notification_levels[:tracking], category_id: category_id || -1) end list end + def new_messages(params) + + TopicQuery.new_filter(messages_for_groups_or_user(params[:my_group_ids]), 10.years.ago) + .limit(params[:count]) + + end + + def unread_messages(params) + TopicQuery.unread_filter(messages_for_groups_or_user(params[:my_group_ids])) + .limit(params[:count]) + end + + def related_messages_user(params) + messages_for_user + .limit(params[:count]) + .where('topics.id IN ( + SELECT ta.topic_id + FROM topic_allowed_users ta + WHERE ta.user_id IN (:user_ids) + ) OR + topics.id IN ( + SELECT tg.topic_id + FROM topic_allowed_groups tg + WHERE tg.group_id IN (:group_ids) + ) + ', user_ids: (params[:target_user_ids] || []) + [-10], + group_ids: ((params[:target_group_ids] - params[:my_group_ids]) || []) + [-10]) + + end + + def related_messages_group(params) + messages_for_groups_or_user(params[:my_group_ids]) + .limit(params[:count]) + .where('topics.id IN ( + SELECT ta.topic_id + FROM topic_allowed_users ta + WHERE ta.user_id IN (:user_ids) + ) OR + topics.id IN ( + SELECT tg.topic_id + FROM topic_allowed_groups tg + WHERE tg.group_id IN (:group_ids) + ) + ', user_ids: (params[:target_user_ids] || []) + [-10], + group_ids: ((params[:target_group_ids] - params[:my_group_ids]) || []) + [-10]) + + end + + def messages_for_groups_or_user(group_ids) + if group_ids.present? + base_messages + .where('topics.id IN ( + SELECT topic_id + FROM topic_allowed_groups tg + JOIN group_users gu ON gu.user_id = :user_id AND gu.group_id = tg.group_id + WHERE gu.group_id IN (:group_ids) + )', user_id: @user.id, group_ids: group_ids) + else + messages_for_user + end + end + + def messages_for_user + base_messages.where('topics.id IN ( + SELECT topic_id + FROM topic_allowed_users + WHERE user_id = :user_id + )', user_id: @user.id) + end + + def base_messages + Topic + .where('topics.archetype = ?', Archetype.private_message) + .joins("LEFT JOIN topic_users tu ON topics.id = tu.topic_id AND tu.user_id = #{@user.id.to_i}") + .order('topics.bumped_at DESC') + end def random_suggested(topic, count, excluded_topic_ids=[]) result = default_results(unordered: true, per_page: count).where(closed: false, archived: false) diff --git a/lib/topic_view.rb b/lib/topic_view.rb index 24a49d24cf3..9f84dd8063b 100644 --- a/lib/topic_view.rb +++ b/lib/topic_view.rb @@ -16,6 +16,10 @@ class TopicView 20 end + def self.default_post_custom_fields + @default_post_custom_fields ||= ["action_code_who"] + end + def self.post_custom_fields_whitelisters @post_custom_fields_whitelisters ||= Set.new end @@ -25,7 +29,8 @@ class TopicView end def self.whitelisted_post_custom_fields(user) - post_custom_fields_whitelisters.map { |w| w.call(user) }.flatten.uniq + wpcf = default_post_custom_fields + post_custom_fields_whitelisters.map { |w| w.call(user) } + wpcf.flatten.uniq end def initialize(topic_id, user=nil, options={}) @@ -38,10 +43,7 @@ class TopicView self.instance_variable_set("@#{key}".to_sym, value) end - # work around people somehow sending in arrays, - # arrays are not supported - @page = @page.to_i rescue 1 - @page = 1 if @page.zero? + @page = 1 if (!@page || @page.zero?) @chunk_size = options[:slow_platform] ? TopicView.slow_chunk_size : TopicView.chunk_size @limit ||= @chunk_size @@ -52,13 +54,11 @@ class TopicView filter_posts(options) - if SiteSetting.public_user_custom_fields.present? && @posts - @user_custom_fields = User.custom_fields_for_ids(@posts.map(&:user_id), SiteSetting.public_user_custom_fields.split('|')) - end - - if @guardian.is_staff? && SiteSetting.staff_user_custom_fields.present? && @posts - @user_custom_fields ||= {} - @user_custom_fields.deep_merge!(User.custom_fields_for_ids(@posts.map(&:user_id), SiteSetting.staff_user_custom_fields.split('|'))) + if @posts + added_fields = User.whitelisted_user_custom_fields(@guardian) + if added_fields.present? + @user_custom_fields = User.custom_fields_for_ids(@posts.map(&:user_id), added_fields) + end end whitelisted_fields = TopicView.whitelisted_post_custom_fields(@user) @@ -159,9 +159,18 @@ class TopicView (excerpt || "").gsub(/\n/, ' ').strip end + def read_time + return nil if @post_number.present? && @post_number.to_i != 1 # only show for topic URLs + (@topic.word_count/SiteSetting.read_time_word_count).floor if @topic.word_count + end + + def like_count + return nil if @post_number.present? && @post_number.to_i != 1 # only show for topic URLs + @topic.like_count + end + def image_url - return nil if desired_post.blank? - desired_post.user.try(:small_avatar_url) + @topic.image_url || SiteSetting.default_opengraph_image_url end def filter_posts(opts = {}) @@ -169,7 +178,7 @@ class TopicView return filter_posts_by_ids(opts[:post_ids]) if opts[:post_ids].present? return filter_best(opts[:best], opts) if opts[:best].present? - filter_posts_paged(opts[:page].to_i) + filter_posts_paged(@page) end def primary_group_names @@ -186,7 +195,8 @@ class TopicView result[g[0]] = g[1] end end - result + + @group_names = result end # Find the sort order for a post in the topic @@ -280,7 +290,6 @@ class TopicView end def suggested_topics - return nil if topic.private_message? @suggested_topics ||= TopicQuery.new(@user).list_suggested_for(topic) end diff --git a/lib/topics_bulk_action.rb b/lib/topics_bulk_action.rb index 337c32eac1a..541d283a1a0 100644 --- a/lib/topics_bulk_action.rb +++ b/lib/topics_bulk_action.rb @@ -1,14 +1,17 @@ class TopicsBulkAction - def initialize(user, topic_ids, operation) + def initialize(user, topic_ids, operation, options={}) @user = user @topic_ids = topic_ids @operation = operation @changed_ids = [] + @options = options end def self.operations - @operations ||= %w(change_category close archive change_notification_level reset_read dismiss_posts delete) + @operations ||= %w(change_category close archive change_notification_level + reset_read dismiss_posts delete unlist archive_messages + move_messages_to_inbox) end def self.register_operation(name, &block) @@ -24,6 +27,43 @@ class TopicsBulkAction private + def find_group + return unless @options[:group] + + group = Group.where('name ilike ?', @options[:group]).first + raise Discourse::InvalidParameters.new(:group) unless group + unless group.group_users.where(user_id: @user.id).exists? + raise Discourse::InvalidParameters.new(:group) + end + group + end + + def move_messages_to_inbox + group = find_group + topics.each do |t| + if guardian.can_see?(t) && t.private_message? + if group + GroupArchivedMessage.move_to_inbox!(group.id, t.id) + else + UserArchivedMessage.move_to_inbox!(@user.id,t.id) + end + end + end + end + + def archive_messages + group = find_group + topics.each do |t| + if guardian.can_see?(t) && t.private_message? + if group + GroupArchivedMessage.archive!(group.id, t.id) + else + UserArchivedMessage.archive!(@user.id, t.id) + end + end + end + end + def dismiss_posts sql = " UPDATE topic_users tu @@ -66,6 +106,15 @@ class TopicsBulkAction end end + def unlist + topics.each do |t| + if guardian.can_moderate?(t) + t.update_status('visible', false, @user) + @changed_ids << t.id + end + end + end + def archive topics.each do |t| if guardian.can_moderate?(t) diff --git a/lib/trust_level.rb b/lib/trust_level.rb index a81f5fb3831..a3044bcdd3b 100644 --- a/lib/trust_level.rb +++ b/lib/trust_level.rb @@ -14,7 +14,7 @@ class TrustLevel end def levels - @levels ||= Enum.new(:newuser, :basic, :regular, :leader, :elder, start: 0) + @levels ||= Enum.new(:newuser, :basic, :member, :regular, :leader, start: 0) end def all diff --git a/lib/user_name_suggester.rb b/lib/user_name_suggester.rb index 4819a3f879b..e809be0b41a 100644 --- a/lib/user_name_suggester.rb +++ b/lib/user_name_suggester.rb @@ -1,4 +1,5 @@ module UserNameSuggester + GENERIC_NAMES = ['i', 'me', 'info', 'support', 'admin', 'webmaster', 'hello', 'mail', 'office', 'contact', 'team'] def self.suggest(name, allow_username = nil) return unless name.present? @@ -11,7 +12,7 @@ module UserNameSuggester # When 'walter@white.com' take 'walter' name = Regexp.last_match[1] # When 'me@eviltrout.com' take 'eviltrout' - name = Regexp.last_match[2] if ['i', 'me'].include?(name) + name = Regexp.last_match[2] if GENERIC_NAMES.include?(name) end name end @@ -35,15 +36,27 @@ module UserNameSuggester def self.sanitize_username(name) name = ActiveSupport::Inflector.transliterate(name) - name = name.gsub(/^[^[:alnum:]]+|\W+$/, "") - .gsub(/\W+/, "_") - .gsub(/^\_+/, '') - .gsub(/[\-_\.]{2,}/, "_") + # 1. replace characters that aren't allowed with '_' + name.gsub!(UsernameValidator::CONFUSING_EXTENSIONS, "_") + name.gsub!(/[^\w.-]/, "_") + # 2. removes unallowed leading characters + name.gsub!(/^\W+/, "") + # 3. removes unallowed trailing characters + name = remove_unallowed_trailing_characters(name) + # 4. unify special characters + name.gsub!(/[-_.]{2,}/, "_") + name + end + + def self.remove_unallowed_trailing_characters(name) + name.gsub!(/[^A-Za-z0-9]+$/, "") name end def self.rightsize_username(name) - name.ljust(User.username_length.begin, '1')[0, User.username_length.end] + name = name[0, User.username_length.end] + name = remove_unallowed_trailing_characters(name) + name.ljust(User.username_length.begin, '1') end end diff --git a/lib/validators/allow_user_locale_enabled_validator.rb b/lib/validators/allow_user_locale_enabled_validator.rb new file mode 100644 index 00000000000..ebae4be4509 --- /dev/null +++ b/lib/validators/allow_user_locale_enabled_validator.rb @@ -0,0 +1,18 @@ +class AllowUserLocaleEnabledValidator + + def initialize(opts={}) + @opts = opts + end + + def valid_value?(val) + # only validate when enabling setting locale from headers + return true if val == "f" + # ensure that allow_user_locale is enabled + SiteSetting.allow_user_locale + end + + def error_message + I18n.t("site_settings.errors.user_locale_not_enabled"); + end + +end \ No newline at end of file diff --git a/lib/validators/password_validator.rb b/lib/validators/password_validator.rb index cb7cb457e2d..7b8ee765e2a 100644 --- a/lib/validators/password_validator.rb +++ b/lib/validators/password_validator.rb @@ -6,15 +6,21 @@ class PasswordValidator < ActiveModel::EachValidator return unless record.password_required? if value.nil? record.errors.add(attribute, :blank) + elsif value.length < SiteSetting.min_admin_password_length && (record.admin? || is_developer?(record.email)) + record.errors.add(attribute, :too_short, count: SiteSetting.min_admin_password_length) elsif value.length < SiteSetting.min_password_length record.errors.add(attribute, :too_short, count: SiteSetting.min_password_length) elsif record.username.present? && value == record.username record.errors.add(attribute, :same_as_username) - elsif record.username.present? && value == record.email + elsif record.email.present? && value == record.email record.errors.add(attribute, :same_as_email) elsif SiteSetting.block_common_passwords && CommonPasswords.common_password?(value) record.errors.add(attribute, :common) end end + def is_developer?(value) + Rails.configuration.respond_to?(:developer_emails) && Rails.configuration.developer_emails.include?(value) + end + end diff --git a/lib/validators/pop3_polling_enabled_setting_validator.rb b/lib/validators/pop3_polling_enabled_setting_validator.rb new file mode 100644 index 00000000000..f62e252bbbe --- /dev/null +++ b/lib/validators/pop3_polling_enabled_setting_validator.rb @@ -0,0 +1,44 @@ +require "net/pop" + +class POP3PollingEnabledSettingValidator + + def initialize(opts={}) + @opts = opts + end + + def valid_value?(val) + # only validate when enabling polling + return true if val == "f" + # ensure we can authenticate + SiteSetting.pop3_polling_host.present? && + SiteSetting.pop3_polling_username.present? && + SiteSetting.pop3_polling_password.present? && + authentication_works? + end + + def error_message + if SiteSetting.pop3_polling_host.blank? + I18n.t("site_settings.errors.pop3_polling_host_is_empty") + elsif SiteSetting.pop3_polling_username.blank? + I18n.t("site_settings.errors.pop3_polling_username_is_empty") + elsif SiteSetting.pop3_polling_password.blank? + I18n.t("site_settings.errors.pop3_polling_password_is_empty") + elsif !authentication_works? + I18n.t("site_settings.errors.pop3_polling_authentication_failed") + end + end + + private + + def authentication_works? + @authentication_works ||= begin + pop3 = Net::POP3.new(SiteSetting.pop3_polling_host, SiteSetting.pop3_polling_port) + pop3.enable_ssl(OpenSSL::SSL::VERIFY_NONE) if SiteSetting.pop3_polling_ssl + pop3.auth_only(SiteSetting.pop3_polling_username, SiteSetting.pop3_polling_password) + rescue Net::POPAuthenticationError + false + else + true + end + end +end diff --git a/lib/validators/post_validator.rb b/lib/validators/post_validator.rb index fc16571476d..206d0bfbc98 100644 --- a/lib/validators/post_validator.rb +++ b/lib/validators/post_validator.rb @@ -1,24 +1,28 @@ require_dependency 'validators/stripped_length_validator' + module Validators; end + class Validators::PostValidator < ActiveModel::Validator def validate(record) presence(record) - unless Discourse.static_doc_topic_ids.include?(record.topic_id) && record.acting_user.try(:admin?) - stripped_length(record) - raw_quality(record) - max_posts_validator(record) - max_mention_validator(record) - max_images_validator(record) - max_attachments_validator(record) - max_links_validator(record) - unique_post_validator(record) - end + + return if record.acting_user.try(:staged?) + return if Discourse.static_doc_topic_ids.include?(record.topic_id) && record.acting_user.try(:admin?) + + stripped_length(record) + raw_quality(record) + max_posts_validator(record) + max_mention_validator(record) + max_images_validator(record) + max_attachments_validator(record) + max_links_validator(record) + unique_post_validator(record) end def presence(post) - post.errors.add(:raw, :blank, options) if post.raw.blank? + unless options[:skip_topic] post.errors.add(:topic_id, :blank, options) if post.topic_id.blank? end @@ -32,7 +36,7 @@ class Validators::PostValidator < ActiveModel::Validator range = if post.topic.try(:private_message?) # private message SiteSetting.private_message_post_length - elsif ( post.is_first_post? || (post.topic.present? && post.topic.posts_count == 0) ) + elsif post.is_first_post? || (post.topic.present? && post.topic.posts_count == 0) # creating/editing first post SiteSetting.first_post_length else @@ -50,10 +54,12 @@ class Validators::PostValidator < ActiveModel::Validator # Ensure maximum amount of mentions in a post def max_mention_validator(post) + return if post.acting_user.try(:staff?) + if acting_user_is_trusted?(post) - add_error_if_count_exceeded(post, :too_many_mentions, post.raw_mentions.size, SiteSetting.max_mentions_per_post) + add_error_if_count_exceeded(post, :no_mentions_allowed, :too_many_mentions, post.raw_mentions.size, SiteSetting.max_mentions_per_post) else - add_error_if_count_exceeded(post, :too_many_mentions_newuser, post.raw_mentions.size, SiteSetting.newuser_max_mentions_per_post) + add_error_if_count_exceeded(post, :no_mentions_allowed_newuser, :too_many_mentions_newuser, post.raw_mentions.size, SiteSetting.newuser_max_mentions_per_post) end end @@ -65,17 +71,17 @@ class Validators::PostValidator < ActiveModel::Validator # Ensure new users can not put too many images in a post def max_images_validator(post) - add_error_if_count_exceeded(post, :too_many_images, post.image_count, SiteSetting.newuser_max_images) unless acting_user_is_trusted?(post) + add_error_if_count_exceeded(post, :no_images_allowed, :too_many_images, post.image_count, SiteSetting.newuser_max_images) unless acting_user_is_trusted?(post) end # Ensure new users can not put too many attachments in a post def max_attachments_validator(post) - add_error_if_count_exceeded(post, :too_many_attachments, post.attachment_count, SiteSetting.newuser_max_attachments) unless acting_user_is_trusted?(post) + add_error_if_count_exceeded(post, :no_attachments_allowed, :too_many_attachments, post.attachment_count, SiteSetting.newuser_max_attachments) unless acting_user_is_trusted?(post) end # Ensure new users can not put too many links in a post def max_links_validator(post) - add_error_if_count_exceeded(post, :too_many_links, post.link_count, SiteSetting.newuser_max_links) unless acting_user_is_trusted?(post) + add_error_if_count_exceeded(post, :no_links_allowed, :too_many_links, post.link_count, SiteSetting.newuser_max_links) unless acting_user_is_trusted?(post) end # Stop us from posting the same thing too quickly @@ -98,7 +104,13 @@ class Validators::PostValidator < ActiveModel::Validator post.acting_user.present? && post.acting_user.has_trust_level?(TrustLevel[1]) end - def add_error_if_count_exceeded(post, key_for_translation, current_count, max_count) - post.errors.add(:base, I18n.t(key_for_translation, count: max_count)) if current_count > max_count + def add_error_if_count_exceeded(post, not_allowed_translation_key, limit_translation_key, current_count, max_count) + if current_count > max_count + if max_count == 0 + post.errors.add(:base, I18n.t(not_allowed_translation_key)) + else + post.errors.add(:base, I18n.t(limit_translation_key, count: max_count)) + end + end end end diff --git a/lib/validators/reply_by_email_enabled_validator.rb b/lib/validators/reply_by_email_enabled_validator.rb new file mode 100644 index 00000000000..e7333de0f6c --- /dev/null +++ b/lib/validators/reply_by_email_enabled_validator.rb @@ -0,0 +1,23 @@ +class ReplyByEmailEnabledValidator + + def initialize(opts={}) + @opts = opts + end + + def valid_value?(val) + # only validate when enabling reply by email + return true if val == "f" + # ensure reply_by_email_address is configured && polling is working + SiteSetting.reply_by_email_address.present? && + SiteSetting.email_polling_enabled? + end + + def error_message + if SiteSetting.reply_by_email_address.blank? + I18n.t("site_settings.errors.reply_by_email_address_is_empty") + else + I18n.t("site_settings.errors.email_polling_disabled") + end + end + +end diff --git a/lib/validators/upload_validator.rb b/lib/validators/upload_validator.rb index 985fe928d9a..b200fc16c32 100644 --- a/lib/validators/upload_validator.rb +++ b/lib/validators/upload_validator.rb @@ -5,6 +5,8 @@ module Validators; end class Validators::UploadValidator < ActiveModel::Validator def validate(upload) + return true if upload.is_attachment_for_group_message && SiteSetting.allow_all_attachments_for_group_messages + extension = File.extname(upload.original_filename)[1..-1] || "" if is_authorized?(upload, extension) diff --git a/plugins/discourse-details/LICENSE b/plugins/discourse-details/LICENSE new file mode 100644 index 00000000000..e87025e8d91 --- /dev/null +++ b/plugins/discourse-details/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Discourse + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/plugins/discourse-details/README.md b/plugins/discourse-details/README.md new file mode 100644 index 00000000000..8018a66b8a0 --- /dev/null +++ b/plugins/discourse-details/README.md @@ -0,0 +1,27 @@ +### discourse-details + +HTML 5.1 `
    ` polyfill for [Discourse](https://www.discourse.org). + +NOTE: Does not work on IE9, but we don't support IE9 as of Jan 1 2016. + +## Usage + +In your posts, surround text with `[details=your summary]` ... `[/details]`. +For example: + +``` + I watched the murder mystery on TV last night. [details=Who did it?]The butler did it[/details]. +``` + +## Installation + +Follow our [Install a Plugin](https://meta.discourse.org/t/install-a-plugin/19157) howto, using +`git clone https://github.com/discourse/discourse-details.git` as the plugin command. + +## Issues + +If you have issues or suggestions for the plugin, please bring them up on [Discourse Meta](https://meta.discourse.org). + +## License + +MIT diff --git a/plugins/discourse-details/assets/javascripts/details.js b/plugins/discourse-details/assets/javascripts/details.js new file mode 100644 index 00000000000..54436783b3d --- /dev/null +++ b/plugins/discourse-details/assets/javascripts/details.js @@ -0,0 +1,58 @@ +(function(document, $) { + + // cf. http://mths.be/details + var hasNativeSupport = (function(doc) { + var fake, el = doc.createElement("details"); + // fail-fast + if (!("open" in el)) { return false; } + // figure out a root node + var root = doc.body || (function() { + var de = doc.documentElement; + fake = true; + return de.insertBefore(doc.createElement("body"), de.firstElementChild || de.firstChild); + })(); + // setup test element + el.innerHTML = "ab"; + el.style.display = "block"; + // add test element to the root node + root.appendChild(el); + // can we open it? + var diff = el.offsetHeight; + el.open = true; + diff = diff !== el.offsetHeight; + // cleanup + root.removeChild(el); + if (fake) { root.parentNode.removeChild(root); } + // return the result + return diff; + })(document); + + function toggleOpen($details) { + $details.toggleClass("open"); + } + + $.fn.details = function() { + if (hasNativeSupport) { return this; } + + return this.each(function() { + var $details = $(this), + $firstSummary = $("summary", $details).first(); + + $firstSummary.prop("tabIndex", 0); + + $firstSummary.on("keydown", function(event) { + if (event.keyCode === 32 /* SPACE */ || event.keyCode === 13 /* ENTER */) { + toggleOpen($details); + return false; + } + }); + + $firstSummary.on("click", function() { + $firstSummary.focus(); + toggleOpen($details); + }); + + }); + }; + +})(document, jQuery); diff --git a/plugins/discourse-details/assets/javascripts/details_dialect.js b/plugins/discourse-details/assets/javascripts/details_dialect.js new file mode 100644 index 00000000000..858f887a904 --- /dev/null +++ b/plugins/discourse-details/assets/javascripts/details_dialect.js @@ -0,0 +1,28 @@ +(function() { + + function insertDetails(_, summary, details) { + return "
    " + summary + "" + details + "
    "; + } + + // replace all [details] BBCode with HTML 5.1 equivalent + function replaceDetails(text) { + text = text || ""; + + while (text !== (text = text.replace(/\[details=([^\]]+)\]((?:(?!\[details=[^\]]+\]|\[\/details\])[\S\s])*)\[\/details\]/ig, insertDetails))); + + // add new lines to make sure we *always* have a

    element after and around

    + // otherwise we can't hide the content since we can't target text nodes via CSS + return text.replace(/<\/summary>/ig, "\n\n") + .replace(/<\/details>/ig, "\n\n\n\n"); + } + + Discourse.Dialect.addPreProcessor(function(text) { + if (Discourse.SiteSettings.details_enabled) { + text = replaceDetails(text); + } + return text; + }); + + Discourse.Markdown.whiteListTag("details", "class", "elided"); + +})(); diff --git a/plugins/discourse-details/assets/javascripts/initializers/apply-details.js.es6 b/plugins/discourse-details/assets/javascripts/initializers/apply-details.js.es6 new file mode 100644 index 00000000000..367607f8f2c --- /dev/null +++ b/plugins/discourse-details/assets/javascripts/initializers/apply-details.js.es6 @@ -0,0 +1,11 @@ +import { withPluginApi } from 'discourse/lib/plugin-api'; + +export default { + name: "apply-details", + + initialize() { + withPluginApi('0.1', api => { + api.decorateCooked($elem => $("details", $elem).details()); + }); + } +}; diff --git a/plugins/discourse-details/assets/stylesheets/details.scss b/plugins/discourse-details/assets/stylesheets/details.scss new file mode 100644 index 00000000000..bbe4ab9013a --- /dev/null +++ b/plugins/discourse-details/assets/stylesheets/details.scss @@ -0,0 +1,72 @@ +details { + position: relative; +} + +details > *, +details .lightbox-wrapper { + display: none; +} + +details, +summary { + outline: none; +} + +summary:first-of-type { + cursor: pointer; + display: block; +} + +summary:before { + content: '\25BA'; + margin-right: .25em; +} + +details[open] > summary:before, +details.open > summary:before { + content: '\25BC'; +} + +details[open] > summary:first-of-type ~ *, +details.open > summary:first-of-type ~ * { + display: block; +} + +/* hide native indicator */ +summary::-webkit-details-marker { + display: none; +} + +/* FF: hide div generated by lazyYT plugin */ +details .lazyYT-container { + display: none; +} + + +.elided { + + summary:before { + content: '' !important; + } + + summary { + @include unselectable; + box-sizing: border-box; + margin: 0; + padding: 0; + color: #aaa; + background: #f1f1f1; + border: 1px solid #ddd; + width: 20px; + display: flex; + text-align: center; + vertical-align: middle; + line-height: 12px; + } + + summary:hover { + color: #222; + background: #d8d8d8; + border-color: #cdcdcd; + } +} diff --git a/plugins/discourse-details/config/locales/server.en.yml b/plugins/discourse-details/config/locales/server.en.yml new file mode 100644 index 00000000000..cca3dd701ce --- /dev/null +++ b/plugins/discourse-details/config/locales/server.en.yml @@ -0,0 +1,3 @@ +en: + site_settings: + details_enabled: "Enable the details plugin. If you change this, you must rebake all posts with: \"rake posts:rebake\"." diff --git a/plugins/discourse-details/config/settings.yml b/plugins/discourse-details/config/settings.yml new file mode 100644 index 00000000000..9add46e43e9 --- /dev/null +++ b/plugins/discourse-details/config/settings.yml @@ -0,0 +1,4 @@ +plugins: + details_enabled: + default: true + client: true diff --git a/plugins/discourse-details/plugin.rb b/plugins/discourse-details/plugin.rb new file mode 100644 index 00000000000..41a1a61a713 --- /dev/null +++ b/plugins/discourse-details/plugin.rb @@ -0,0 +1,28 @@ +# name: discourse-details +# about: HTML5.1 Details polyfill for Discourse +# version: 0.4 +# authors: Régis Hanol +# url: https://github.com/discourse/discourse/tree/master/plugins/discourse-details + +enabled_site_setting :details_enabled + +register_asset "javascripts/details.js" +register_asset "javascripts/details_dialect.js", :server_side + +register_asset "stylesheets/details.scss" + +after_initialize do + + Email::Styles.register_plugin_style do |fragment| + # remove all elided content + fragment.css("details.elided").each { |d| d.remove } + + # replace all details with their summary in emails + fragment.css("details").each do |details| + summary = details.css("summary")[0] + summary.name = "p" + details.replace(summary) + end + end + +end diff --git a/plugins/lazyYT/assets/javascripts/initializers/lazyYT.js.es6 b/plugins/lazyYT/assets/javascripts/initializers/lazyYT.js.es6 index 0743a30c371..34950f184df 100644 --- a/plugins/lazyYT/assets/javascripts/initializers/lazyYT.js.es6 +++ b/plugins/lazyYT/assets/javascripts/initializers/lazyYT.js.es6 @@ -1,13 +1,18 @@ -/** - Apply lazyYT when the app boots -**/ -import { decorateCooked } from 'discourse/lib/plugin-api'; +import { withPluginApi } from 'discourse/lib/plugin-api'; export default { name: "apply-lazyYT", - initialize: function(container) { - decorateCooked(container, function($elem) { - $('.lazyYT', $elem).lazyYT(); + initialize() { + withPluginApi('0.1', api => { + api.decorateCooked($elem => $('.lazyYT', $elem).lazyYT({ + onPlay(e, $el) { + // don't cloak posts that have playing videos in them + const postId = parseInt($el.closest('article').data('post-id')); + if (postId) { + api.preventCloak(postId); + } + } + })); }); } }; diff --git a/plugins/lazyYT/assets/javascripts/lazyYT.js b/plugins/lazyYT/assets/javascripts/lazyYT.js index bce00775813..10673ebd13c 100644 --- a/plugins/lazyYT/assets/javascripts/lazyYT.js +++ b/plugins/lazyYT/assets/javascripts/lazyYT.js @@ -6,9 +6,12 @@ * Contributors: https://github.com/tylerpearson/lazyYT/graphs/contributors || https://github.com/daugilas/lazyYT/graphs/contributors * * Usage:
    loading...
    +* +* Note: Discourse has forked this from the original, beware when updating the file. +* */ -;(function ($) { +(function ($) { 'use strict'; function setUp($el, settings) { @@ -100,10 +103,15 @@ .addClass('lazyYT-image-loaded') .on('click', function (e) { e.preventDefault(); + if (!$el.hasClass('lazyYT-video-loaded') && $thumb.hasClass('lazyYT-image-loaded')) { $el.html('') .addClass('lazyYT-video-loaded'); } + + if (settings.onPlay) { + settings.onPlay(e, $el); + } }); } @@ -122,4 +130,4 @@ }); }; -}(jQuery)); +})(jQuery); diff --git a/plugins/lazyYT/plugin.rb b/plugins/lazyYT/plugin.rb index ba7e858c3f7..70475b73afa 100644 --- a/plugins/lazyYT/plugin.rb +++ b/plugins/lazyYT/plugin.rb @@ -17,7 +17,7 @@ class Onebox::Engine::YoutubeOnebox alias_method :yt_onebox_to_html, :to_html def to_html - if video_id + if video_id && !params['list'] video_width = (params['width'] && params['width'].to_i <= 695) ? params['width'] : 480 # embed width video_height = (params['height'] && params['height'].to_i <= 500) ? params['height'] : 270 # embed height diff --git a/plugins/poll/assets/javascripts/components/poll-results-standard.js.es6 b/plugins/poll/assets/javascripts/components/poll-results-standard.js.es6 index 4382fdea77e..0e44215049f 100644 --- a/plugins/poll/assets/javascripts/components/poll-results-standard.js.es6 +++ b/plugins/poll/assets/javascripts/components/poll-results-standard.js.es6 @@ -1,13 +1,30 @@ +import evenRound from "discourse/plugins/poll/lib/even-round"; +import computed from "ember-addons/ember-computed-decorators"; + export default Em.Component.extend({ tagName: "ul", classNames: ["results"], - options: function() { - const voters = this.get("poll.voters"); + @computed("poll.voters", "poll.type", "poll.options.[]") + options(voters, type) { + const options = this.get("poll.options"); - this.get("poll.options").forEach(option => { - const percentage = voters === 0 ? 0 : Math.floor(100 * option.get("votes") / voters), - style = "width: " + percentage + "%".htmlSafe(); + let percentages = voters === 0 ? + Array(options.length).fill(0) : + _.map(options, o => 100 * o.get("votes") / voters); + + // properly round percentages + if (type === "multiple") { + // when the poll is multiple choices, just "round down" + percentages = percentages.map(p => Math.floor(p)); + } else { + // when the poll is single choice, adds up to 100% + percentages = evenRound(percentages); + } + + options.forEach((option, i) => { + const percentage = percentages[i]; + const style = new Ember.Handlebars.SafeString(`width: ${percentage}%`); option.setProperties({ percentage, @@ -16,7 +33,7 @@ export default Em.Component.extend({ }); }); - return this.get("poll.options"); - }.property("poll.voters", "poll.options.[]") + return options; + } }); diff --git a/plugins/poll/assets/javascripts/controllers/poll.js.es6 b/plugins/poll/assets/javascripts/controllers/poll.js.es6 index 1a9c3943d34..dc5e549a39a 100644 --- a/plugins/poll/assets/javascripts/controllers/poll.js.es6 +++ b/plugins/poll/assets/javascripts/controllers/poll.js.es6 @@ -8,14 +8,14 @@ export default Ember.Controller.extend({ // shows the results when // - poll is closed - // - topic is archived/closed + // - topic is archived // - user wants to see the results - showingResults: Em.computed.or("isClosed", "post.topic.closed", "post.topic.archived", "showResults"), + showingResults: Em.computed.or("isClosed", "post.topic.archived", "showResults"), showResultsDisabled: Em.computed.equal("poll.voters", 0), - hideResultsDisabled: Em.computed.or("isClosed", "post.topic.closed", "post.topic.archived"), + hideResultsDisabled: Em.computed.or("isClosed", "post.topic.archived"), - @computed("model", "vote") + @computed("model", "vote", "model.voters", "model.options", "model.status") poll(poll, vote) { if (poll) { const options = _.map(poll.get("options"), o => Em.Object.create(o)); @@ -100,12 +100,11 @@ export default Ember.Controller.extend({ castVotesDisabled: Em.computed.not("canCastVotes"), - @computed("loading", "post.user_id", "post.topic.closed", "post.topic.archived") - canToggleStatus(loading, userId, topicClosed, topicArchived) { + @computed("loading", "post.user_id", "post.topic.archived") + canToggleStatus(loading, userId, topicArchived) { return this.currentUser && (this.currentUser.get("id") === userId || this.currentUser.get("staff")) && !loading && - !topicClosed && !topicArchived; }, diff --git a/plugins/poll/assets/javascripts/initializers/extend-for-poll.js.es6 b/plugins/poll/assets/javascripts/initializers/extend-for-poll.js.es6 index 2e086fbc5ec..68fe20140ee 100644 --- a/plugins/poll/assets/javascripts/initializers/extend-for-poll.js.es6 +++ b/plugins/poll/assets/javascripts/initializers/extend-for-poll.js.es6 @@ -1,81 +1,107 @@ -import PostView from "discourse/views/post"; -import { on } from "ember-addons/ember-computed-decorators"; +import { withPluginApi } from 'discourse/lib/plugin-api'; function createPollView(container, post, poll, vote) { - const controller = container.lookup("controller:poll", { singleton: false }), - view = container.lookup("view:poll"); + const controller = container.lookup("controller:poll", { singleton: false }); + const view = container.lookup("view:poll"); controller.set("vote", vote); - controller.setProperties({ model: Em.Object.create(poll), post }); + controller.setProperties({ model: poll, post }); view.set("controller", controller); return view; } +let _pollViews; + +function initializePolls(api) { + + const TopicController = api.container.lookupFactory('controller:topic'); + TopicController.reopen({ + subscribe(){ + this._super(); + this.messageBus.subscribe("/polls/" + this.get("model.id"), msg => { + const post = this.get('model.postStream').findLoadedPost(msg.post_id); + if (post) { + post.set('polls', msg.polls); + } + }); + }, + unsubscribe(){ + this.messageBus.unsubscribe('/polls/*'); + this._super(); + } + }); + + const Post = api.container.lookupFactory('model:post'); + Post.reopen({ + _polls: null, + pollsObject: null, + + // we need a proper ember object so it is bindable + pollsChanged: function(){ + const polls = this.get("polls"); + if (polls) { + this._polls = this._polls || {}; + _.map(polls, (v,k) => { + const existing = this._polls[k]; + if (existing) { + this._polls[k].setProperties(v); + } else { + this._polls[k] = Em.Object.create(v); + } + }); + this.set("pollsObject", this._polls); + } + }.observes("polls") + }); + + function cleanUpPollViews() { + if (_pollViews) { + Object.keys(_pollViews).forEach(pollName => _pollViews[pollName].destroy()); + } + _pollViews = null; + } + + function createPollViews($elem, helper) { + const $polls = $('.poll', $elem); + if (!$polls.length) { return; } + + const post = helper.getModel(); + api.preventCloak(post.id); + const votes = post.get('polls_votes') || {}; + + post.pollsChanged(); + + const polls = post.get("pollsObject"); + if (!polls) { return; } + + cleanUpPollViews(); + const postPollViews = {}; + + $polls.each((idx, pollElem) => { + const $div = $("
    "); + const $poll = $(pollElem); + + const pollName = $poll.data("poll-name"); + const pollId = `${pollName}-${post.id}`; + const pollView = createPollView(helper.container, post, polls[pollName], votes[pollName]); + + $poll.replaceWith($div); + Em.run.next(() => pollView.renderer.replaceIn(pollView, $div[0])); + postPollViews[pollId] = pollView; + }); + + _pollViews = postPollViews; + } + + api.decorateCooked(createPollViews, { onlyStream: true }); + api.cleanupStream(cleanUpPollViews); +} + export default { name: "extend-for-poll", - initialize(container) { - - const messageBus = container.lookup("message-bus:main"); - - // listen for back-end to tell us when a post has a poll - messageBus.subscribe("/polls", data => { - const post = container.lookup("controller:topic").get('model.postStream').findLoadedPost(data.post_id); - // HACK to trigger the "postViewUpdated" event - Em.run.next(() => post.set("cooked", post.get("cooked") + " ")); - }); - - // overwrite polls - PostView.reopen({ - - @on("postViewInserted", "postViewUpdated") - _createPollViews($post) { - const post = this.get("post"), - polls = post.get("polls"), - votes = post.get("polls_votes") || {}; - - // don't even bother when there's no poll - if (!polls) { return; } - - // clean-up if needed - this._cleanUpPollViews(); - - const pollViews = {}; - - // iterate over all polls - $(".poll", $post).each(function() { - const $div = $("
    "), - $poll = $(this), - pollName = $poll.data("poll-name"), - pollView = createPollView(container, post, polls[pollName], votes[pollName]); - - $poll.replaceWith($div); - Em.run.next(() => pollView.renderer.replaceIn(pollView, $div[0])); - pollViews[pollName] = pollView; - }); - - messageBus.subscribe(`/polls/${this.get("post.id")}`, results => { - if (results && results.polls) { - _.forEach(results.polls, poll => { - if (pollViews[poll.name]) { - pollViews[poll.name].get("controller").set("model", Em.Object.create(poll)); - } - }); - } - }); - - this.set("pollViews", pollViews); - }, - - @on("willClearRender") - _cleanUpPollViews() { - messageBus.unsubscribe(`/polls/${this.get("post.id")}`); - - if (this.get("pollViews")) { - _.forEach(this.get("pollViews"), v => v.destroy()); - } - } - }); + initialize() { + withPluginApi('0.1', initializePolls); } }; diff --git a/plugins/poll/assets/javascripts/lib/even-round.js.es6 b/plugins/poll/assets/javascripts/lib/even-round.js.es6 new file mode 100644 index 00000000000..0395f1f16a6 --- /dev/null +++ b/plugins/poll/assets/javascripts/lib/even-round.js.es6 @@ -0,0 +1,17 @@ +// stolen from http://stackoverflow.com/a/13484088/11983 +function sumsUpTo100(percentages) { + return percentages.map(p => Math.floor(p)).reduce((a, b) => a + b) === 100; +} + +export default (percentages) => { + const sumOfDecimals = Math.ceil(percentages.map(a => a % 1).reduce((a, b) => a + b)); + // compensate error by adding 1 to the first n "non-zero" items + for (let i = 0, max = percentages.length; i < sumOfDecimals && i < max; i++) { + if (percentages[i] > 0) { + percentages[i] = ++percentages[i]; + // quit early when there is a rounding issue + if (sumsUpTo100(percentages)) break; + } + } + return percentages.map(p => Math.floor(p)); +}; diff --git a/plugins/poll/config/locales/client.ar.yml b/plugins/poll/config/locales/client.ar.yml index 4c3a9ec5e4f..58aa3b2df47 100644 --- a/plugins/poll/config/locales/client.ar.yml +++ b/plugins/poll/config/locales/client.ar.yml @@ -9,42 +9,60 @@ ar: js: poll: voters: - zero: "لا يوجد مصوتون" - one: "مصوت" - two: "مصوتان" - few: "مصوتون قليلون" - many: "مصوتون كثيرون" - other: "المصوتين" + zero: "لا يوجد مصوتون." + one: "مصوت." + two: "مصوتان." + few: "مصوتون قليلون." + many: "مصوتون كثيرون." + other: "المصوتون" total_votes: - zero: "مجموع عدم التصويت" - one: "مجموع التصويت" - two: "مجموع التصويتان" - few: "مجموع الأصوات القليلة" - many: "مجموع الأصوات الكثيرة" - other: "مجموع الأصوات" + zero: "مجموع عدم التصويت." + one: "مجموع التصويت." + two: "مجموع التصويتان." + few: "مجموع الأصوات القليلة." + many: "مجموع الأصوات الكثيرة." + other: "مجموع الأصوات." average_rating: "متوسط التصنيف: %{average} " multiple: help: - at_least_min_options: "من المفترض أن تختار على الأقل %{count} خيارات ." - up_to_max_options: "يجب عليك إختيار على الأكثر %{count} خيارات ." - x_options: "يجب عليك إختيار %{count} خيارات ." + at_least_min_options: + zero: "لا يجب عليك اختيار أي خيار." + one: "يجب عليك أن تختار خيار واحد على الأقل." + two: "يجب عليك أن تختار خياران على الأقل." + few: "يجب عليك أن تختار %{count} بعض الخيارات على الأقل." + many: "يجب عليك أن تختار %{count} عدة خيارات على الأقل." + other: "يجب عليك الاختيار على الأقل." + up_to_max_options: + zero: "لا يمكنك اختيار أي خيار." + one: "يمكنك إختيار مايصل إلى خيار واحد فقط." + two: "يمكنك إختيار مايصل إلى خيارانفقط." + few: "يمكنك إختيار بعض %{count} الخيارات ." + many: "يمكنك إختيار عدة %{count} خيارات ." + other: "يمكنك اختيار حتى %{count} خيارات." + x_options: + zero: "لا يجب عليك إختيار أي خيار." + one: "يجب عليك إختيار خيارواحدخياران فقط." + few: "يجب عليك إختيار %{count} بعض الخيارات." + many: "يجب عليك إختيار %{count} عدة خيارات." + other: "يجب عليك إختيار %{count} خيارات." between_min_and_max_options: "يجب عليك إختيار بين %{min} و %{max} خيارات ." cast-votes: - title: "إدراج تصويتك ." + title: "إدراج صوتك." label: "صوت اﻵن!" show-results: - title: "عرض نتائج التصويت" - label: "عرض النتائج" + title: "عرض نتائج التصويت." + label: "عرض النتائج." hide-results: - title: "العودة إلى تصويتاتك" - label: "إخفاء النتائج" + title: "العودة إلى أصواتك." + label: "إخفاء النتائج." open: - title: "فتح التصويت " - label: "فتح" - confirm: "هل بالفعل تاريد فتح هذا التصويت ؟" + title: "فتح التصويت." + label: "فتح." + confirm: "هل أنت متأكد من فتح هذا التصويت؟" close: - title: "إغلاق التصويت" - label: "إغلاق" - confirm: "هل أنت متأكد من إنك تريد إغلاق هذا التصويت ؟" - error_while_toggling_status: "هناك خطاء عند محاولة تبديل حالة التصويت ." - error_while_casting_votes: "هناك خطاء عن محاولة إدراج صوتك ." + title: "إغلاق التصويت." + label: "إغلاق." + confirm: "هل أنت متأكد من إغلاق هذا التصويت؟" + error_while_toggling_status: "حدث خطأ عند محاولتك لتبديل حالة التصويت." + error_while_casting_votes: "حدث خطأ عند محاولة إدراج صوتك." diff --git a/plugins/poll/config/locales/client.bs_BA.yml b/plugins/poll/config/locales/client.bs_BA.yml index 7b73cd2f229..f9e1081bc1e 100644 --- a/plugins/poll/config/locales/client.bs_BA.yml +++ b/plugins/poll/config/locales/client.bs_BA.yml @@ -5,4 +5,15 @@ # To work with us on translations, join this project: # https://www.transifex.com/projects/p/discourse-org/ -bs_BA: {} +bs_BA: + js: + poll: + voters: + one: "glasač" + few: "glasača" + other: "glasača" + total_votes: + one: "ukupan glas" + few: "ukupno glasova" + other: "ukupno glasova" + average_rating: "Prosječna ocjena: %{average}." diff --git a/plugins/poll/config/locales/client.cs.yml b/plugins/poll/config/locales/client.cs.yml index d6a32ba183a..c9726fcdf02 100644 --- a/plugins/poll/config/locales/client.cs.yml +++ b/plugins/poll/config/locales/client.cs.yml @@ -17,9 +17,6 @@ cs: few: "hlasy celkem" other: "hlasů celkem" average_rating: "Průměrné hodnocení: %{average}." - multiple: - help: - at_least_min_options: "Musíte zvolit alespoň %{count} možností." cast-votes: title: "Hlasujte" label: "Hlasovat!" diff --git a/plugins/poll/config/locales/client.da.yml b/plugins/poll/config/locales/client.da.yml index 7f31c2d0f93..4747966e3ad 100644 --- a/plugins/poll/config/locales/client.da.yml +++ b/plugins/poll/config/locales/client.da.yml @@ -17,9 +17,15 @@ da: average_rating: "Gennemsnitlig rating: %{average}." multiple: help: - at_least_min_options: "Du skal mindst vælge %{count} muligheder." - up_to_max_options: "Du kan vælge op til %{count} muligheder." - x_options: "Du skal vælge %{count} muligheder." + at_least_min_options: + one: "Du skal mindst vælge 1 mulighed." + other: "Du skal mindst vælge %{count} muligheder." + up_to_max_options: + one: "Du kan vælge op til 1 mulighed." + other: "Du kan vælge op til %{count} muligheder." + x_options: + one: "Du skal vælge 1 mulighed." + other: "Du skal vælge %{count} muligheder." between_min_and_max_options: "Du kan vælge mellem %{min} og %{max} muligheder." cast-votes: title: "Afgiv dine stemmer" @@ -31,7 +37,7 @@ da: title: "Tilbage til dine stemmer" label: "Skjul resultat" open: - title: "Åbn afstemning" + title: "Åbn afstemningen" label: "Åbn" confirm: "Er du sikker på, at du vil åbne denne afstemning?" close: diff --git a/plugins/poll/config/locales/client.de.yml b/plugins/poll/config/locales/client.de.yml index 7833ece385e..9b8ef70d00b 100644 --- a/plugins/poll/config/locales/client.de.yml +++ b/plugins/poll/config/locales/client.de.yml @@ -17,9 +17,15 @@ de: average_rating: "Durchschnittliche Bewertung: %{average}" multiple: help: - at_least_min_options: "Du musst mindestens %{count} Optionen auswählen." - up_to_max_options: "Du kannst bis zu %{count} Optionen auswählen." - x_options: "Du musst %{count} Optionen auswählen." + at_least_min_options: + one: "Du musst mindestens eine Option auswählen." + other: "Du musst mindestens %{count} Optionen auswählen." + up_to_max_options: + one: "Du kannst genau eine Option auswählen." + other: "Du kannst bis zu %{count} Optionen auswählen." + x_options: + one: "Du musst eine Option auswählen." + other: "Du musst %{count} Optionen auswählen." between_min_and_max_options: "Du kannst zwischen %{min} und %{max} Optionen auswählen." cast-votes: title: "Gib deine Stimmen ab" diff --git a/plugins/poll/config/locales/client.en.yml b/plugins/poll/config/locales/client.en.yml index 586a8dfaf59..59b508c8853 100644 --- a/plugins/poll/config/locales/client.en.yml +++ b/plugins/poll/config/locales/client.en.yml @@ -29,9 +29,15 @@ en: multiple: help: - at_least_min_options: "You must choose at least %{count} options." - up_to_max_options: "You may choose up to %{count} options." - x_options: "You must choose %{count} options." + at_least_min_options: + one: "You must choose at least 1 option." + other: "You must choose at least %{count} options." + up_to_max_options: + one: "You may choose up to 1 option." + other: "You may choose up to %{count} options." + x_options: + one: "You must choose 1 option." + other: "You must choose %{count} options." between_min_and_max_options: "You may choose between %{min} and %{max} options." cast-votes: diff --git a/plugins/poll/config/locales/client.es.yml b/plugins/poll/config/locales/client.es.yml index 828b06f07c3..61b840d6713 100644 --- a/plugins/poll/config/locales/client.es.yml +++ b/plugins/poll/config/locales/client.es.yml @@ -17,9 +17,15 @@ es: average_rating: "Puntuación media: %{average}." multiple: help: - at_least_min_options: "Debes elegir al menos %{count} opciones." - up_to_max_options: "Puedes escoger hasta %{count} opciones." - x_options: "Debes elegir %{count} opciones." + at_least_min_options: + one: "Debes elegir al menos 1 opción." + other: "Debes elegir al menos %{count} opciones." + up_to_max_options: + one: "Puedes elegir hasta 1 opción." + other: "Puedes elegir hasta %{count} opciones." + x_options: + one: "Debes elegir 1 opción." + other: "Debes elegir %{count} opciones." between_min_and_max_options: "Puedes escoger entre %{min} y %{max} opciones." cast-votes: title: "Votar" diff --git a/plugins/poll/config/locales/client.fa_IR.yml b/plugins/poll/config/locales/client.fa_IR.yml index e3f743f115a..63b09f0016a 100644 --- a/plugins/poll/config/locales/client.fa_IR.yml +++ b/plugins/poll/config/locales/client.fa_IR.yml @@ -15,9 +15,12 @@ fa_IR: average_rating: "میانگین امتیاز: %{average}." multiple: help: - at_least_min_options: "حداقل %{count} گزینه باید انتخاب شود." - up_to_max_options: "می‌توانید تا %{count} گزینه را انتخاب کنید." - x_options: "%{count} گزینه باید انتخاب شود" + at_least_min_options: + other: "حداقل %{count} گزینه باید انتخاب شود." + up_to_max_options: + other: "می‌توانید تا %{count} گزینه را انتخاب کنید." + x_options: + other: "%{count} گزینه باید انتخاب شود" between_min_and_max_options: "می‌توانید بین %{min} تا %{max} گزینه را انتخاب کنید." cast-votes: title: "انداختن رأی شما" diff --git a/plugins/poll/config/locales/client.fi.yml b/plugins/poll/config/locales/client.fi.yml index 1b31427f790..729042eec89 100644 --- a/plugins/poll/config/locales/client.fi.yml +++ b/plugins/poll/config/locales/client.fi.yml @@ -10,16 +10,22 @@ fi: poll: voters: one: "äänestäjä" - other: "äänestäjät" + other: "äänestäjää" total_votes: one: "ääni" other: "ääntä" - average_rating: "Keskivertoarvio: %{average}." + average_rating: "Keskiarvo: %{average}" multiple: help: - at_least_min_options: "Sinun täytyy valita vähintään %{count} vaihtoehtoa." - up_to_max_options: "Voit valita enintään %{count} vaihtoehtoa." - x_options: "Sinun täytyy valita %{count} vaihtoehtoa." + at_least_min_options: + one: "Sinun täytyy valita vähintään yksi vaihtoehto." + other: "Sinun täytyy valita vähintään %{count} vaihtoehtoa." + up_to_max_options: + one: "Voit valita enintään yhden vaihtoehdon." + other: "Voit valita enintään %{count} vaihtoehtoa." + x_options: + one: "Sinun täytyy valita yksi vaihtoehto." + other: "Sinun täytyy valita %{count} vaihtoehtoa." between_min_and_max_options: "Voit valita %{min}-%{max}%{average}" multiple: help: - at_least_min_options: "Vous devez choisir au moins %{count} options." - up_to_max_options: "Vous pouvez choisir jusque %{count} options." - x_options: "Vous devez choisir %{count} options." + at_least_min_options: + one: "Vous devez choisir au moins une option." + other: "Vous devez choisir au moins %{count} options." + up_to_max_options: + one: "Vous pouvez choisir une option." + other: "Vous pouvez choisir jusqu’à %{count} options." + x_options: + one: "Vous devez choisir une option." + other: "Vous devez choisir %{count} options." between_min_and_max_options: "Vous devez choisir entre %{min} et %{max} options." cast-votes: title: "Distribuez vos votes" diff --git a/plugins/poll/config/locales/client.gl.yml b/plugins/poll/config/locales/client.gl.yml new file mode 100644 index 00000000000..3cdfb4b0001 --- /dev/null +++ b/plugins/poll/config/locales/client.gl.yml @@ -0,0 +1,48 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +gl: + js: + poll: + voters: + one: "votante" + other: "votantes" + total_votes: + one: "votos totais" + other: "votos totais" + average_rating: "Valoración media: %{average}." + multiple: + help: + at_least_min_options: + one: "Debes seleccionar cando menos 1 opción." + other: "Debes seleccionar cando menos %{count} opcións." + up_to_max_options: + one: "Podes escoller 1 única opción." + other: "Podes escoller até %{count} opcións." + x_options: + one: "Debes escoller 1 opción." + other: "Debes escoller %{count} opcións." + between_min_and_max_options: "Debes escoller entre %{min} e %{max} opcións." + cast-votes: + title: "Vota" + label: "Vota agora!" + show-results: + title: "Mostrar os resultados da votación" + label: "Mostrar os resultados" + hide-results: + title: "Volver aos teus votos" + label: "Ocultar os resultados" + open: + title: "Abrir a enquisa" + label: "Abrir" + confirm: "Confirmas a apertura da enquisa?" + close: + title: "Pechar a enquisa" + label: "Pechar" + confirm: "Confirmas o peche desta enquisa?" + error_while_toggling_status: "Produciuse un erro durante o cambio do estado da enquisa." + error_while_casting_votes: "Produciuse un erro durante a emisión do teu voto." diff --git a/plugins/poll/config/locales/client.he.yml b/plugins/poll/config/locales/client.he.yml index 8c846785818..ced11e01909 100644 --- a/plugins/poll/config/locales/client.he.yml +++ b/plugins/poll/config/locales/client.he.yml @@ -17,9 +17,15 @@ he: average_rating: "דירוג ממוצע: %{average}." multiple: help: - at_least_min_options: "עליך לבחור לפחות %{count} אפשרויות" - up_to_max_options: "באפשרותך לבחור עד %{count} אפשרויות." - x_options: "עליך לבחור %{count} אפשרויות. " + at_least_min_options: + one: "עליך לבחור לפחות אפשרות 1." + other: "עליך לבחור לפחות %{count} אפשרויות." + up_to_max_options: + one: "באפשרותך לבחור עד אפשרות %{count}." + other: "באפשרותך לבחור עד %{count} אפשרויות." + x_options: + one: "עליך לבחור אפשרות 1." + other: "עליך לבחור %{count} אפשרויות." between_min_and_max_options: "באפשרותך לבחור בין %{min} עד %{max} אפשרויות." cast-votes: title: "שליחת הצבעות" diff --git a/plugins/poll/config/locales/client.id.yml b/plugins/poll/config/locales/client.id.yml index 9d940ae9702..a217ccdb806 100644 --- a/plugins/poll/config/locales/client.id.yml +++ b/plugins/poll/config/locales/client.id.yml @@ -8,13 +8,20 @@ id: js: poll: + voters: + other: "pemilih" + total_votes: + other: "jumlah pemilih" average_rating: "Rata-rata rating: %{average}." multiple: help: - at_least_min_options: "Kamu wajib memilih setidaknya %{count} pilihan." - up_to_max_options: "Kamu boleh memilih maksimum %{count} pilihan." - x_options: "Kamu harus memilih %{count} pilihan." - between_min_and_max_options: "Kamu hanya bisa memilih minimum %{min} pilihan dan maximum %{max} pilihan." + at_least_min_options: + other: "Anda harus memilih %{count} pilihan." + up_to_max_options: + other: "Anda dapat memilih maksimum %{count} pilihan." + x_options: + other: "Anda harus memilih %{count} pilihan." + between_min_and_max_options: "Anda hanya bisa memilih minimum %{min} pilihan dan maximum %{max} pilihan." cast-votes: title: "Gunakan suaramu" label: "Pilih sekarang!" @@ -24,3 +31,13 @@ id: hide-results: title: "Kembali ke suaramu" label: "Sembunyikan hasil" + open: + title: "Buka Polling" + label: "Buka" + confirm: "Apakah Anda yakin ingin membuka akun ini?" + close: + title: "Tutup polling" + label: "Tutup" + confirm: "Apakah Anda yakin ingin menutup akun ini?" + error_while_toggling_status: "Terjadi kesalahan ketika merubah status polling ini." + error_while_casting_votes: "Terjadi kesalahan ketika merubah status." diff --git a/plugins/poll/config/locales/client.it.yml b/plugins/poll/config/locales/client.it.yml index e5ab646bd34..8b148970b08 100644 --- a/plugins/poll/config/locales/client.it.yml +++ b/plugins/poll/config/locales/client.it.yml @@ -17,9 +17,15 @@ it: average_rating: "Voto medio: %{average}." multiple: help: - at_least_min_options: "Devi scegliere almeno %{count} opzioni." - up_to_max_options: "Puoi scegliere fino a %{count} opzioni." - x_options: "Devi scegliere %{count} opzioni." + at_least_min_options: + one: "Devi scegliere almeno una opzione." + other: "Devi scegliere almeno %{count} opzioni." + up_to_max_options: + one: "Puoi scegliere fino a una opzione." + other: "Puoi scegliere fino a %{count} opzioni." + x_options: + one: "Devi scegliere una opzione." + other: "Devi scegliere %{count} opzioni." between_min_and_max_options: "Puoi scegliere tra %{min} e %{max} opzioni." cast-votes: title: "Vota" diff --git a/plugins/poll/config/locales/client.ja.yml b/plugins/poll/config/locales/client.ja.yml index 2d01b7c38e7..a3b3f1bbb41 100644 --- a/plugins/poll/config/locales/client.ja.yml +++ b/plugins/poll/config/locales/client.ja.yml @@ -15,9 +15,12 @@ ja: average_rating: "平均評価: %{average}." multiple: help: - at_least_min_options: "少なくとも %{count} 個のオプションを選んでください。" - up_to_max_options: "%{count} 個のオプションまで選択することができます。" - x_options: "%{count} 個のオプションを選択してください。" + at_least_min_options: + other: "少なくとも %{count} 個のオプションを選んでください。" + up_to_max_options: + other: "%{count} 個のオプションまで選択することができます。" + x_options: + other: "%{count} 個のオプションを選択してください。" between_min_and_max_options: "%{min}%{max} のオプションから選択することができます。" cast-votes: title: "投票する" diff --git a/plugins/poll/config/locales/client.ko.yml b/plugins/poll/config/locales/client.ko.yml index ad715c3ee44..52454181ce6 100644 --- a/plugins/poll/config/locales/client.ko.yml +++ b/plugins/poll/config/locales/client.ko.yml @@ -15,9 +15,12 @@ ko: average_rating: "평균: %{average}." multiple: help: - at_least_min_options: "적어도 %{count}개는 선택해야 합니다." - up_to_max_options: "%{count}개까지만 선택할 수 있습니다." - x_options: "정확히 %{count}개를 선택해야 합니다." + at_least_min_options: + other: "적어도 %{count}개의 옵션은 선택해야 합니다." + up_to_max_options: + other: "옵션은 %{count} 개까지 선택할 수 있습니다." + x_options: + other: "옵션은 %{count} 개 선택해야 합니다." between_min_and_max_options: "%{min}개에서 %{max}개까지 선택할 수 있습니다." cast-votes: title: "표 던지기" diff --git a/plugins/poll/config/locales/client.nb_NO.yml b/plugins/poll/config/locales/client.nb_NO.yml index 0039a0d65b4..98214dcfef3 100644 --- a/plugins/poll/config/locales/client.nb_NO.yml +++ b/plugins/poll/config/locales/client.nb_NO.yml @@ -17,9 +17,6 @@ nb_NO: average_rating: "Gjennomsnitt: %{average}." multiple: help: - at_least_min_options: "Du må velge minst %{count} alternativer." - up_to_max_options: "Du kan velge opptil %{count} alternativer." - x_options: "Du må velge %{count} alternativer." between_min_and_max_options: "Du kan velge mellom %{min} og %{max} alternativer." cast-votes: title: "Stem nå" diff --git a/plugins/poll/config/locales/client.nl.yml b/plugins/poll/config/locales/client.nl.yml index de778280c0e..c042e7cb9b1 100644 --- a/plugins/poll/config/locales/client.nl.yml +++ b/plugins/poll/config/locales/client.nl.yml @@ -17,9 +17,15 @@ nl: average_rating: "Gemiddeld cijfer: %{average}." multiple: help: - at_least_min_options: "Kies tenminste %{count} opties." - up_to_max_options: "Je kunt maximaal %{count} opties kiezen." - x_options: "Kies %{count} opties." + at_least_min_options: + one: "U dient tenminste 1 optie te kiezen." + other: "Kies tenminste %{count} opties." + up_to_max_options: + one: "U kunt maximaal 1 optie kiezen." + other: "Je kan maximaal %{count} opties kiezen." + x_options: + one: "Je moet 1 optie kiezen." + other: "Je moet %{count} opties kiezen." between_min_and_max_options: "Je kan tussen %{min} en %{max} opties kiezen." cast-votes: title: "Geef je stem" diff --git a/plugins/poll/config/locales/client.pl_PL.yml b/plugins/poll/config/locales/client.pl_PL.yml index b344003fdd2..cd2cc463759 100644 --- a/plugins/poll/config/locales/client.pl_PL.yml +++ b/plugins/poll/config/locales/client.pl_PL.yml @@ -19,9 +19,18 @@ pl_PL: average_rating: "Średnia ocena: %{average}." multiple: help: - at_least_min_options: "Musisz wybrać co najmniej %{count} pozycje." - up_to_max_options: "Możesz wybrać co najwyżej %{count} pozycje." - x_options: "Musisz wybrać %{count} pozycje." + at_least_min_options: + one: "Musisz wybrać przynajmniej jedną pozycje." + few: "Musisz wybrać co najmniej %{count} pozycje." + other: "Musisz wybrać co najmniej %{count} pozycje." + up_to_max_options: + one: "Możesz wybrać maksymalnie 1 opcję." + few: "Możesz wybrać maksymalnie %{count} opcje." + other: "Możesz wybrać maksymalnie %{count} opcji." + x_options: + one: "Musisz wybrać jedną opcję." + few: "Musisz wybrać %{count} opcje." + other: "Musisz wybrać %{count} opcji." between_min_and_max_options: "Możesz wybrać pomiędzy %{min} a %{max} pozycjami." cast-votes: title: "Oddaj głos" diff --git a/plugins/poll/config/locales/client.pt.yml b/plugins/poll/config/locales/client.pt.yml index 9d7df2719fe..9c14e9f45ca 100644 --- a/plugins/poll/config/locales/client.pt.yml +++ b/plugins/poll/config/locales/client.pt.yml @@ -17,9 +17,15 @@ pt: average_rating: "Classificação média: %{average}." multiple: help: - at_least_min_options: "Deve escolher pelo menos %{count} opções." - up_to_max_options: "Pode escolher até %{count} opções." - x_options: "Deve escolher %{count} opções." + at_least_min_options: + one: "Deve escolher pelo menos 1 opção." + other: "Deve escolher pelo menos %{count} opções." + up_to_max_options: + one: "Pode escolher até 1 opção." + other: "Pode escolher até %{count} opções." + x_options: + one: "Deve escolher 1 opção." + other: "Deve escolher %{count} opções." between_min_and_max_options: "Pode escolher entre %{min} e %{max} opções." cast-votes: title: "Votar" diff --git a/plugins/poll/config/locales/client.pt_BR.yml b/plugins/poll/config/locales/client.pt_BR.yml index 7fec94ebd8a..50579d08c77 100644 --- a/plugins/poll/config/locales/client.pt_BR.yml +++ b/plugins/poll/config/locales/client.pt_BR.yml @@ -8,12 +8,24 @@ pt_BR: js: poll: + voters: + one: "votante" + other: "votantes" + total_votes: + one: "voto total" + other: "votos totais" average_rating: "Resultado médio: %{average}." multiple: help: - at_least_min_options: "Você precisa escolher ao menos %{count} opções." - up_to_max_options: "Você pode escolher %{count} opções." - x_options: "Você precisa escolher %{count} opções." + at_least_min_options: + one: "Você deve escolher pelo menos 1 opção." + other: "Você deve escolher pelo menos %{count} opções." + up_to_max_options: + one: "Você deve escolher até 1 opção." + other: "Você deve escolher até %{count} opções." + x_options: + one: "Você deve escolher 1 opção." + other: "Você deve escolher %{count} opções." between_min_and_max_options: "Você pode escolher entre %{min} e %{max} opções." cast-votes: title: "Seus votos" diff --git a/plugins/poll/config/locales/client.ro.yml b/plugins/poll/config/locales/client.ro.yml index e1e2ff32410..82b8d8830ab 100644 --- a/plugins/poll/config/locales/client.ro.yml +++ b/plugins/poll/config/locales/client.ro.yml @@ -8,12 +8,29 @@ ro: js: poll: + voters: + one: "participant" + few: "participanți" + other: "participanți" + total_votes: + one: "un vot" + few: "total voturi" + other: "total voturi" average_rating: "Media: %{average}." multiple: help: - at_least_min_options: "Trebuie să alegeți cel puțin %{count} opțiuni." - up_to_max_options: "Puteţi alege cel mult %{count} opţiuni." - x_options: "Trebuie să alegeți %{count} opțiuni." + at_least_min_options: + one: "Trebuie să selectați cel puțin 1 opțiune." + few: "Trebuie să selectați cel puțin %{count} opțiuni." + other: "Trebuie să selectați cel puțin %{count} opțiuni." + up_to_max_options: + one: "Puteţi alege cel mult o %{count} opţiune." + few: "Puteţi selecta cel mult 1 opţiune." + other: "Puteți selecta până la %{count} opțiuni." + x_options: + one: "Trebuie să selectați 1 opțiune." + few: "Trebuie să selectați %{count} opțiuni." + other: "Trebuie să alegeți %{count} opțiuni." between_min_and_max_options: "Puteţi alege între %{min} şi %{max} opţiuni." cast-votes: title: "Exprimaţi-vă votul" @@ -29,8 +46,8 @@ ro: label: "Deschis" confirm: "Sunteţi sigur că doriţi să deschideţi acest sondaj?" close: - title: "Închide sondaj" - label: "Închis" + title: "Închideți sondajul" + label: "Închideți" confirm: "Sunteţi sigur că vreţi să închideţi acest sondaj?" error_while_toggling_status: "A apărut o eroare în timpul schimbării stării acestui sondaj." error_while_casting_votes: "A apărut o eroare în timpul exprimării votului dvs." diff --git a/plugins/poll/config/locales/client.ru.yml b/plugins/poll/config/locales/client.ru.yml index 8f73a0a4438..8dd85117e61 100644 --- a/plugins/poll/config/locales/client.ru.yml +++ b/plugins/poll/config/locales/client.ru.yml @@ -8,13 +8,35 @@ ru: js: poll: - average_rating: "Примерный рейтинг: %{average}." + voters: + one: "голос" + few: "голоса" + many: "голосов" + other: "голосов" + total_votes: + one: "голос" + few: "голоса" + many: "голосов" + other: "голосов" + average_rating: "Средний рейтинг: %{average}." multiple: help: - at_least_min_options: "Вы должны выбрать как минимум %{count} ответов." - up_to_max_options: "Вы можете выбрать не более %{count} вариантов ответов." - x_options: "Вы должны выбрать %{count} варианта ответа." - between_min_and_max_options: "Вы можете выбрать от %{min} до %{max} ответов." + at_least_min_options: + one: "Необходимо выбрать хотя бы 1 ответ." + few: "Необходимо выбрать хотя бы %{count} ответа." + many: "Необходимо выбрать хотя бы %{count} ответов." + other: "Необходимо выбрать хотя бы %{count} ответов." + up_to_max_options: + one: "Можно выбрать только 1 ответ." + few: "Можно выбрать до %{count} ответов." + many: "Можно выбрать до %{count} ответов." + other: "Можно выбрать до %{count} ответов." + x_options: + one: "Необходимо выбрать 1 ответ." + few: "Необходимо выбрать %{count} ответа." + many: "Необходимо выбрать %{count} ответов." + other: "Необходимо выбрать %{count} ответов." + between_min_and_max_options: "Можно выбрать от %{min} до %{max} ответов." cast-votes: title: "Проголосуйте" label: "Голосовать!" @@ -22,15 +44,15 @@ ru: title: "Показать результаты" label: "Показать результаты" hide-results: - title: "Вернуться к голосованию" + title: "Вернуться к опросу" label: "Скрыть результаты" open: - title: "Открыть голосование" + title: "Открыть опрос" label: "Открыть" - confirm: "Вы уверены, что хотите открыть это голосование?" + confirm: "Вы уверены, что хотите открыть этот опрос?" close: - title: "Закрыть голосование" + title: "Закрыть опрос" label: "Закрыть" - confirm: "Вы уверены, что хотите закрыть это голосование?" - error_while_toggling_status: "Произошла ошибка смены статуса голосования." - error_while_casting_votes: "Произошла ошибка в голосовании." + confirm: "Вы уверены, что хотите закрыть этот опрос?" + error_while_toggling_status: "Произошла ошибка при смене статуса опроса." + error_while_casting_votes: "Произошла ошибка во время обработки вашего голоса." diff --git a/plugins/poll/config/locales/client.sk.yml b/plugins/poll/config/locales/client.sk.yml new file mode 100644 index 00000000000..2ae88650f99 --- /dev/null +++ b/plugins/poll/config/locales/client.sk.yml @@ -0,0 +1,53 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +sk: + js: + poll: + voters: + one: "volič" + few: "voliči" + other: "voliči" + total_votes: + one: "hlas celkom" + few: "hlasy celkom" + other: "hlasov celkom" + average_rating: "Priemerné hodnotenie: %{average}." + multiple: + help: + at_least_min_options: + one: "Musíte si vybrať minimálne %{count} možnosť." + few: "Musíte si vybrať minimálne %{count} možnosti." + other: "Musíte si vybrať minimálne %{count} možností." + up_to_max_options: + one: "Môžete si vybrať maximálne %{count} možnosť." + few: "Môžete si vybrať maximálne %{count} možnosti." + other: "Môžete si vybrať maximálne %{count} možností." + x_options: + one: "Musíte si vybrať %{count} možnosť." + few: "Musíte si vybrať %{count} možnosti." + other: "Musíte si vybrať %{count} možností." + between_min_and_max_options: "Môžete si vybrať medzi možnosťami %{min}%{max}." + cast-votes: + title: "Hlasovať" + label: "Hlasuj teraz!" + show-results: + title: "Zobraz výsledky hlasovania" + label: "Zobraz výsledky" + hide-results: + title: "Návrat na odovzdané hlasy" + label: "Skyť výsledky" + open: + title: "Zahájiť hlasovanie" + label: "Zahájiť" + confirm: "Ste si istý, že chcete zahájiť toto hlasovanie?" + close: + title: "Zatvoriť hlasovanie" + label: "Zatvoriť" + confirm: "Ste si istý, že chcete zatvoriť toto hlasovanie?" + error_while_toggling_status: "Pri zmene stavu hlasovania sa vyskytla chyba." + error_while_casting_votes: "Pri hlasovaní sa vyskytla chyba." diff --git a/plugins/poll/config/locales/client.sq.yml b/plugins/poll/config/locales/client.sq.yml index 5efd604a257..36f8b9af858 100644 --- a/plugins/poll/config/locales/client.sq.yml +++ b/plugins/poll/config/locales/client.sq.yml @@ -17,9 +17,6 @@ sq: average_rating: "Vlerësimi mesatar: %{average}." multiple: help: - at_least_min_options: "Ju duhet të zgjidhni të paktën %{count} opsionet." - up_to_max_options: "You may choose up to %{count} options." - x_options: "You must choose %{count} options." between_min_and_max_options: "You may choose between %{min} and %{max} options." cast-votes: title: "Cast your votes" diff --git a/plugins/poll/config/locales/client.sv.yml b/plugins/poll/config/locales/client.sv.yml index 421ff6218fd..2491b50380e 100644 --- a/plugins/poll/config/locales/client.sv.yml +++ b/plugins/poll/config/locales/client.sv.yml @@ -8,12 +8,24 @@ sv: js: poll: + voters: + one: "röst" + other: "röster" + total_votes: + one: "totalt antal röst" + other: "totalt antal röster" average_rating: "Medelbetyg: %{average}." multiple: help: - at_least_min_options: "Du måste välja minst %{count} alternativ." - up_to_max_options: "Du kan välja upp till %{count} alternativ." - x_options: "Du måste välja %{count} alternativ." + at_least_min_options: + one: "Du måste välja minst 1 alternativ." + other: "Du måste välja minst %{count} alternativ." + up_to_max_options: + one: "Du kan välja upp till 1 alternativ" + other: "Du kan välja upp till %{count} alternativ." + x_options: + one: "Du måste välja 1 alternativ." + other: "Du måste välja %{count} alternativ." between_min_and_max_options: "Du kan välja mellan %{min} och %{max} alternativ." cast-votes: title: "Lägg dina röster" diff --git a/plugins/poll/config/locales/client.tr_TR.yml b/plugins/poll/config/locales/client.tr_TR.yml index 2e6792746d2..4b9e75273e9 100644 --- a/plugins/poll/config/locales/client.tr_TR.yml +++ b/plugins/poll/config/locales/client.tr_TR.yml @@ -15,9 +15,12 @@ tr_TR: average_rating: "Ortalama oran: %{average}." multiple: help: - at_least_min_options: "En az %{count} seçim yapmalısınız." - up_to_max_options: "En fazla %{count} seçim yapabilirsiniz." - x_options: "%{count} seçim yapmalısınız." + at_least_min_options: + other: "En az %{count} seçim yapmalısınız." + up_to_max_options: + other: "En fazla %{count} seçim yapabilirsiniz." + x_options: + other: "%{count} seçim yapmalısınız." between_min_and_max_options: "%{min} ve %{max} seçenekleri arasında seçim yapabilirsiniz." cast-votes: title: "Oyunuzu kullanın" diff --git a/plugins/poll/config/locales/client.vi.yml b/plugins/poll/config/locales/client.vi.yml new file mode 100644 index 00000000000..30d6e6a699d --- /dev/null +++ b/plugins/poll/config/locales/client.vi.yml @@ -0,0 +1,43 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +vi: + js: + poll: + voters: + other: "Người bầu chọn" + total_votes: + other: "tổng số bình chọn" + average_rating: "Đánh giá trung bình: %{average}." + multiple: + help: + at_least_min_options: + other: "Bạn phải chọn ít nhất %{count} tùy chọn." + up_to_max_options: + other: "Bạn có thể chọn lên tới %{count} tùy chọn." + x_options: + other: "Bạn phải chọn %{count} tùy chọn." + between_min_and_max_options: "Bạn có thể chọn giữa %{min}%{max}." + cast-votes: + title: "Bỏ phiếu của bạn" + label: "Bình chọn ngay!" + show-results: + title: "Hiển thị kết quả cuộc thăm dò" + label: "Hiện kết quả" + hide-results: + title: "Trở lại bầu chọn của bạn" + label: "Ẩn kết quả" + open: + title: "Mở bình chọn" + label: "Mở" + confirm: "Bạn có chắc mở bình chọn này?" + close: + title: "Đóng bình chọn" + label: "Đóng lại" + confirm: "Bạn có chắc chắn muốn đóng bình chọn này?" + error_while_toggling_status: "Có lỗi trong khi chuyển đổi qua lại các trạng thái của bình chọn này." + error_while_casting_votes: "Có lỗi trong khi tạo mãu bầu chọn của bạn" diff --git a/plugins/poll/config/locales/client.zh_CN.yml b/plugins/poll/config/locales/client.zh_CN.yml index cd3958a6a38..7a7744543da 100644 --- a/plugins/poll/config/locales/client.zh_CN.yml +++ b/plugins/poll/config/locales/client.zh_CN.yml @@ -15,9 +15,12 @@ zh_CN: average_rating: "平均排名:%{average}。" multiple: help: - at_least_min_options: "你至少要选择 %{count} 个选项。" - up_to_max_options: "你最多可以选择 %{count} 个选项。" - x_options: "你必须选择 %{count} 个选项。" + at_least_min_options: + other: "你必须选择至少 %{count} 个选项。" + up_to_max_options: + other: "你可以选择最多 %{count} 个选项。" + x_options: + other: "你必须选择 %{count} 个选项。" between_min_and_max_options: "你可以选择 %{min}%{max} 个选项。" cast-votes: title: "投你的票" diff --git a/plugins/poll/config/locales/server.ar.yml b/plugins/poll/config/locales/server.ar.yml index 7fcef197a32..2b595208fd4 100644 --- a/plugins/poll/config/locales/server.ar.yml +++ b/plugins/poll/config/locales/server.ar.yml @@ -7,27 +7,41 @@ ar: site_settings: - poll_enabled: "المستخدمين المسموح لهم إنشاء استطلاع رأي" - poll_maximum_options: "أقصى عدد من الخيارات المسموحة في استطلاع الرأي." + poll_enabled: "أيمكن للمستخدمين إنشاء تصويتات؟" + poll_maximum_options: "أقصى عدد للخيارات في كلّ تصويت." poll: - multiple_polls_without_name: "هناك عدة استطلاعات رأي بدون اسم. استخدم خاصية 'name' لتحديد استطلاعاتك الفريدة." - multiple_polls_with_same_name: "هناك عدة استطلاعات رأي متشابهة بالاسم : %{name}. استخدم خاصية 'name' لتحدي استطلاعك الفريد." - default_poll_must_have_at_least_2_options: "استطلاع الرأي يجب أن يكون على الأقل 2 من الخيارات." - named_poll_must_have_at_least_2_options: "استطلاع الرأي المسمى %{name} يجب أن يكون على الأقل 2 من الخيارات." - default_poll_must_have_less_options: "استطلاع الرأي يجب أن يكون أقل من %{max} الخيارات." - named_poll_must_have_less_options: "استطلاع الرأي المسمى %{name} يجب أقل من %{max} الخيارات." - default_poll_must_have_different_options: "استطلاع الرأي يجب أن يكون مختلف الخيارات." - named_poll_must_have_different_options: "استطلاع الرأي المسمى %{name} يجب أن يكون مختلف الخيارات." - default_poll_with_multiple_choices_has_invalid_parameters: "معلمات استطلاع الرأي ذات الخيار المتعدد غير صالحة." - named_poll_with_multiple_choices_has_invalid_parameters: "معلمات استطلاع الرأي المسمى %{name} ذات الخيار المتعدد غير صالحة." - requires_at_least_1_valid_option: "يجب أن تختار أختيار 1 صحيح على الأقل." - cannot_change_polls_after_5_minutes: "لا يمكنك إضافة أو حذف أو إعادة تسمية استطلاعات الرأي بعد الـ5 دقائق اﻷولى." - op_cannot_edit_options_after_5_minutes: "لا تستطيع إضافة أو حذف خيارات استطلاع الرأي بعد أول 5 دقائق. أرجو أن تتصل بالمسؤول إذا احتجت لتحرير خيارات الرأي." - staff_cannot_add_or_remove_options_after_5_minutes: "لا تستطيع إضافة أو حذف خيارات استطلاع الرأي بعد أول 5 دقائق. يجب عليك إغلاق هذا الموضوع وإنشاء جديد بدلا عنه." - no_polls_associated_with_this_post: "لا استطلاعات رأي مرتبطة مع هذا الاستطلاع." - no_poll_with_this_name: "استطلاع الرأي المسمى %{name} غير مرتبط مع هذا الاستطلاع." - post_is_deleted: "لا يمكنك عمل حذف مشاركة." - topic_must_be_open_to_vote: "الموضوع يجب أن يكون مفتوح للتصويت." - poll_must_be_open_to_vote: "يجب أن تكون الاستطلاعات مفتوحة للتصويت." - topic_must_be_open_to_toggle_status: "الموضوع يجب أن يكون مفتوح لتبديل الحالة." - only_staff_or_op_can_toggle_status: "فقط الأعضاء العاملين أو المعلنين الأصليين يمكنهم تبديل حالة الاستطلاع." + multiple_polls_without_name: "توجد بضعة تصويتات بلا اسم. استخدم خاصية 'name' لتمييزها." + multiple_polls_with_same_name: "توجد بضعة تصويتات بالاسم %{name} نفسه. استخدم خاصية 'name' لتمييزها." + default_poll_must_have_at_least_2_options: "على التصويت توفير خيارين على الأقل." + named_poll_must_have_at_least_2_options: "على التصويت ذو الاسم %{name} توفير خيارين على الأقل." + default_poll_must_have_less_options: + zero: "على التصويت ألا يوفّر أي خيار." + one: "على التصويت توفير خيار واحد على الأقل." + two: "على التصويت توفير خيارين على الأقل." + few: "على التصويت توفير %{count} خيارات على الأقل." + many: "على التصويت توفير %{count} خيارا على الأقل." + other: "على التصويت توفير %{count} خيار على الأقل." + named_poll_must_have_less_options: + zero: "على التصويت ذو الاسم %{name} ألا يوفّر أي خيار." + one: "على التصويت ذو الاسم %{name} توفير خيار واحد على الأقل." + two: "على التصويت ذو الاسم %{name} توفير خيارين على الأقل." + few: "على التصويت ذو الاسم %{name} توفير %{count} خيارات على الأقل." + many: "على التصويت ذو الاسم %{name} توفير %{count} خيارا على الأقل." + other: "على التصويت ذو الاسم %{name} توفير %{count} خيار على الأقل." + default_poll_must_have_different_options: "على التصويت توفير خيارات مختلفة." + named_poll_must_have_different_options: "على التصويت ذو الاسم %{name} توفير خيارات مختلفة." + default_poll_with_multiple_choices_has_invalid_parameters: "للتصويت متعدد الخيارات معلمات غير صالحة." + named_poll_with_multiple_choices_has_invalid_parameters: "للتصويت متعدد الخيارات ذو الاسم %{name} معلمات غير صالحة." + requires_at_least_1_valid_option: "عليك اختيار خيار واحد صالح على الأقل." + cannot_change_polls_after_5_minutes: "لا يمكنك إضافة تصويتات، أو حذفها أو إعادة تسميتها بعد مضي 5 دقائق." + op_cannot_edit_options_after_5_minutes: "لا يمكنك إضافة تصويتات، أو حذفها أو إعادة تسميتها بعد مضي 5 دقائق. من فضلك راسل مشرفا إن احتجت إلى تعديل أحد خيارات التصويت." + staff_cannot_add_or_remove_options_after_5_minutes: "لا يمكنك إضافة تصويتات، أو حذفها أو إعادة تسميتها بعد مضي 5 دقائق. عليك إغلاق هذا الموضوع وإنشاء آخر بدله." + no_polls_associated_with_this_post: "لا تصويتات مرتبطة مع هذه المشاركة." + no_poll_with_this_name: "لا تصويت بالاسم %{name} مرتبط مع هذه المشاركة." + post_is_deleted: "لا شيء تفعله مع مشاركة محذوفة. " + topic_must_be_open_to_vote: "على الموضوع أن يكون مفتوحا للتصويت." + poll_must_be_open_to_vote: "على المشاركة أن تكون مفتوحة للتصويت." + topic_must_be_open_to_toggle_status: "على الموضوع أن يكون مفتوحا لتبديل الحالة." + only_staff_or_op_can_toggle_status: "يمكن فقط لأعضاء الطاقم أو المشارِك الأصلي تبديل حالة التصويت." + email: + link_to_poll: "انقر لعرض التصويت." diff --git a/plugins/poll/config/locales/server.bs_BA.yml b/plugins/poll/config/locales/server.bs_BA.yml index 7b73cd2f229..17b984e3993 100644 --- a/plugins/poll/config/locales/server.bs_BA.yml +++ b/plugins/poll/config/locales/server.bs_BA.yml @@ -5,4 +5,7 @@ # To work with us on translations, join this project: # https://www.transifex.com/projects/p/discourse-org/ -bs_BA: {} +bs_BA: + site_settings: + poll_enabled: "Dozvolite korisnicima da kreiraju ankete?" + poll_maximum_options: "Najveći broj dopuštenih izbora u anketi." diff --git a/plugins/poll/config/locales/server.cs.yml b/plugins/poll/config/locales/server.cs.yml index a89da214785..26c43911238 100644 --- a/plugins/poll/config/locales/server.cs.yml +++ b/plugins/poll/config/locales/server.cs.yml @@ -14,8 +14,6 @@ cs: multiple_polls_with_same_name: "Víc hlasování má stejné jméno: %{name}. Použijte atribut 'name' pro jednoznačnou identifikaci vašich hlasování." default_poll_must_have_at_least_2_options: "Hlasování musí mít alespoň 2 odpovědi." named_poll_must_have_at_least_2_options: "Hlasování %{name} musí mít alespoň 2 odpovědi." - default_poll_must_have_less_options: "Hlasování nesmí mít víc než %{max} odpovědí." - named_poll_must_have_less_options: "Hlasování %{name} nesmí mít víc než %{max} odpovědí." default_poll_must_have_different_options: "Hlasování musí mít různé odpovědi." named_poll_must_have_different_options: "Hlasování %{name} musí mít různé odpovědi." requires_at_least_1_valid_option: "Musíte vybrat alespoň jednu platnou odpověď." diff --git a/plugins/poll/config/locales/server.da.yml b/plugins/poll/config/locales/server.da.yml index ba7e89bf41b..0ad4aa946ab 100644 --- a/plugins/poll/config/locales/server.da.yml +++ b/plugins/poll/config/locales/server.da.yml @@ -14,8 +14,12 @@ da: multiple_polls_with_same_name: "Der er flere afstemninger med samme navn %{name}. Brug attributten 'name' for at identificere dine afstemninger." default_poll_must_have_at_least_2_options: "Afstemningen skal mindst have 2 muligheder." named_poll_must_have_at_least_2_options: "Afstemningen %{name} skal mindst have 2 valgmuligheder." - default_poll_must_have_less_options: "Afstemningen skal have mindre end %{max} muligheder." - named_poll_must_have_less_options: "Afstemningen %{name} skal have mindre end %{max} valgmuligheder." + default_poll_must_have_less_options: + one: "Afstemningen må ikke have nogen muligheder." + other: "Afstemningen skal have mindre end %{max} muligheder." + named_poll_must_have_less_options: + one: "Afstemningen %{name} må ikke have nogen valgmuligheder." + other: "Afstemningen %{name} skal have mindre end %{max} valgmuligheder." default_poll_must_have_different_options: "Afstemningen skal have forskellige muligheder." named_poll_must_have_different_options: "Afstemningen %{name} skal have forskellige valgmuligheder." default_poll_with_multiple_choices_has_invalid_parameters: "Afstemning med flere valgmuligheder har ugyldige parametre." @@ -31,3 +35,5 @@ da: poll_must_be_open_to_vote: "Afstemning skal være åben for at kunne stemme." topic_must_be_open_to_toggle_status: "Emnet skal være åbent for at ændre status." only_staff_or_op_can_toggle_status: "Kun personalet eller emnets opretter kan ændre status for en afstemning" + email: + link_to_poll: "Klik for at se afstemningen." diff --git a/plugins/poll/config/locales/server.de.yml b/plugins/poll/config/locales/server.de.yml index 6a7916a8979..e1672ac3d2a 100644 --- a/plugins/poll/config/locales/server.de.yml +++ b/plugins/poll/config/locales/server.de.yml @@ -14,8 +14,12 @@ de: multiple_polls_with_same_name: "Es gibt mehre Umfragen mit dem selben Namen: %{name}. Benutze das Attribute 'name', um deine Umfragen eindeutig identifizierbar zu machen." default_poll_must_have_at_least_2_options: "Umfragen müssen mindestens 2 Optionen haben." named_poll_must_have_at_least_2_options: "Die Umfrage mit dem Namen %{name} muss mindestens 2 Optionen haben." - default_poll_must_have_less_options: "Die Umfrage muss weniger als %{max} Optionen haben." - named_poll_must_have_less_options: "Die Umfrage mit dem Namen %{name} muss weniger als %{max} Optionen haben." + default_poll_must_have_less_options: + one: "Die Umfrage muss weniger als eine Option haben." + other: "Die Umfrage muss weniger als %{count} Optionen haben." + named_poll_must_have_less_options: + one: "Die Umfrage mit dem Namen %{name} muss weniger als eine Option haben." + other: "Die Umfrage mit dem Namen %{name} muss weniger als %{count} Optionen haben." default_poll_must_have_different_options: "Die Umfrage muss unterschiedliche Optionen haben." named_poll_must_have_different_options: "Die Umfrage mit dem Namen %{name} muss unterschiedliche Optionen haben." default_poll_with_multiple_choices_has_invalid_parameters: "Die Mehrfachauswahl-Umfrage hat ungültige Parameter." @@ -31,3 +35,5 @@ de: poll_must_be_open_to_vote: "Die Umfrage muss zum Abstimmen gestartet sein." topic_must_be_open_to_toggle_status: "Damit du den Status ändern kannst, muss das Thema geöffnet sein." only_staff_or_op_can_toggle_status: "Nur Mitarbeiter und der Autor des Beitrags können den Status der Umfrage ändern." + email: + link_to_poll: "Klicke hier, um die Umfrage zu sehen." diff --git a/plugins/poll/config/locales/server.en.yml b/plugins/poll/config/locales/server.en.yml index dd1e4a5da9f..1ef088e0e40 100644 --- a/plugins/poll/config/locales/server.en.yml +++ b/plugins/poll/config/locales/server.en.yml @@ -26,8 +26,12 @@ en: default_poll_must_have_at_least_2_options: "Poll must have at least 2 options." named_poll_must_have_at_least_2_options: "Poll named %{name} must have at least 2 options." - default_poll_must_have_less_options: "Poll must have less than %{max} options." - named_poll_must_have_less_options: "Poll named %{name} must have less than %{max} options." + default_poll_must_have_less_options: + one: "Poll must have less than 1 option." + other: "Poll must have less than %{count} options." + named_poll_must_have_less_options: + one: "Poll named %{name} must have less than 1 option." + other: "Poll named %{name} must have less than %{count} options." default_poll_must_have_different_options: "Poll must have different options." named_poll_must_have_different_options: "Poll named %{name} must have different options." @@ -51,3 +55,6 @@ en: topic_must_be_open_to_toggle_status: "The topic must be open to toggle status." only_staff_or_op_can_toggle_status: "Only a staff member or the original poster can toggle a poll status." + + email: + link_to_poll: "Click to view the poll." diff --git a/plugins/poll/config/locales/server.es.yml b/plugins/poll/config/locales/server.es.yml index 09b1b0ba78a..1792d5cf91d 100644 --- a/plugins/poll/config/locales/server.es.yml +++ b/plugins/poll/config/locales/server.es.yml @@ -14,8 +14,12 @@ es: multiple_polls_with_same_name: "Hay varias encuestas con el mismo nombre: %{name}. Usa la etiqueta 'name' para diferenciar tus encuestas." default_poll_must_have_at_least_2_options: "La encuesta debe tener al menos 2 opciones." named_poll_must_have_at_least_2_options: "La encuesta llamada %{name} debe tener al menos 2 opciones." - default_poll_must_have_less_options: "La encuesta debe tener menos de %{max} opciones." - named_poll_must_have_less_options: "La encuesta llamada %{name} debe tener menos de %{max} opciones." + default_poll_must_have_less_options: + one: "Las encuestas deben tener menos de 1 opción." + other: "Las encuestas deben tener menos de %{count} opciones." + named_poll_must_have_less_options: + one: "La encuesta llamada %{name} debe tener menos de 1 opción." + other: "La encuesta llamada %{name} debe tener menos de %{count} opciones." default_poll_must_have_different_options: "La encuesta debe tener diferentes opciones." named_poll_must_have_different_options: "La encuesta llamada %{name} debe tener diferentes opciones." default_poll_with_multiple_choices_has_invalid_parameters: "La encuesta con múltiples opciones tiene parámetros no válidos." @@ -31,3 +35,5 @@ es: poll_must_be_open_to_vote: "La encuesta debe estar abierta para votar." topic_must_be_open_to_toggle_status: "Este tema debe estar abierto para cambiar entre estados." only_staff_or_op_can_toggle_status: "Solo un moderador, administrador o el autor original del post puede cambiar el estado de una encuesta." + email: + link_to_poll: "Haz clic para ver la encuesta." diff --git a/plugins/poll/config/locales/server.fa_IR.yml b/plugins/poll/config/locales/server.fa_IR.yml index 1bb4e1cf579..35a1842d702 100644 --- a/plugins/poll/config/locales/server.fa_IR.yml +++ b/plugins/poll/config/locales/server.fa_IR.yml @@ -14,8 +14,10 @@ fa_IR: multiple_polls_with_same_name: "چند نظرسنجی با اسم برابر وجود دارند: %{name}.استفاده کن از 'اسم/code>' ویژگی ٬ تا نظرسنجی منحصر به فرد را تشخیص دهد." default_poll_must_have_at_least_2_options: "نظرسنجی باید حداقل 2 گزینه داشته باشد." named_poll_must_have_at_least_2_options: "اسم نظرسنجی %{name} باید حداقل 2 گزینه داشته باشد. " - default_poll_must_have_less_options: "Poll must have less than %{max} options." - named_poll_must_have_less_options: "Poll named %{name} must have less than %{max} options." + default_poll_must_have_less_options: + other: "نظرسنجی باید کمتر از %{count} گزینه داشته باشد." + named_poll_must_have_less_options: + other: "نظرسنجی با نام %{name} باید کمتر از %{count} گزینه داشته باشد." default_poll_must_have_different_options: "نظرسنجی باید گزینه های متفاوت داشته باشد. " named_poll_must_have_different_options: "Poll named %{name} must have different options." default_poll_with_multiple_choices_has_invalid_parameters: "در نظرسنجی چند گزینه‌ای پارامترهای نامعتبری وجود دارد." @@ -31,3 +33,5 @@ fa_IR: poll_must_be_open_to_vote: "نظرسنجی باید باز باشد برای رای گیری." topic_must_be_open_to_toggle_status: "جستار باید برای تغییر وضیعت باز باشد. " only_staff_or_op_can_toggle_status: "فقط کارمندان یا ارسال کنندگان پست می توانند وضعیت نظرسنجی را تغییر دهند. " + email: + link_to_poll: "برای دیدن نظرسنجی کلیک کنید." diff --git a/plugins/poll/config/locales/server.fi.yml b/plugins/poll/config/locales/server.fi.yml index c70cc428f5b..554c6a362e9 100644 --- a/plugins/poll/config/locales/server.fi.yml +++ b/plugins/poll/config/locales/server.fi.yml @@ -14,8 +14,12 @@ fi: multiple_polls_with_same_name: "Useamman kyselyn nimi on %{name}. Anna kaikille eri nimet 'name'-määreellä." default_poll_must_have_at_least_2_options: "Äänestyksessä pitää olla vähintään 2 vaihtoehtoa." named_poll_must_have_at_least_2_options: "Äänestyksessä nimeltä %{name} pitää olla vähintään 2 vaihtoehtoa." - default_poll_must_have_less_options: "Äänestyksessä pitää olla vähemmän, kuin %{max} vaihtoehtoa." - named_poll_must_have_less_options: "Äänestyksen nimeltä %{name} pitää sisältää vähemmän, kuin %{max} vaihtoehtoa." + default_poll_must_have_less_options: + one: "Äänestyksessä pitää olla vähemmän, kuin yksi vaihtoehto." + other: "Äänestyksessä pitää olla vähemmän, kuin %{count} vaihtoehtoa." + named_poll_must_have_less_options: + one: "Äänestyksessä %{name} pitää olla vähemmän kuin yksi vaihtoehto." + other: "Äänestyksessä %{name} pitää olla vähemmän kuin %{count} vaihtoehtoa." default_poll_must_have_different_options: "Äänestysvaihtoehtojen on erottava toisistaan." named_poll_must_have_different_options: "Äänestyksen nimeltä %{name} vaihtoehtojen on erottava toisistaan." default_poll_with_multiple_choices_has_invalid_parameters: "Kysely, jossa on useita vaihtoehtoja sisältää epäkelpoja parametreja." @@ -23,7 +27,7 @@ fi: requires_at_least_1_valid_option: "Sinun täytyy valita vähintään 1 vaihtoehto." cannot_change_polls_after_5_minutes: "Et voi lisätä, poistaa tai muuttaa kyselyn vaihtoehtoja ensimmäisen 5 minuutin jälkeen." op_cannot_edit_options_after_5_minutes: "Et voi lisätä, poistaa tai muuttaa kyselyn vaihtoehtoja ensimmäisen 5 minuutin jälkeen. Ota yhteyttä valvojaan, jos sinun täytyy muokata kyselyn vaihtoehtoja." - staff_cannot_add_or_remove_options_after_5_minutes: "Et voi lisätä, poistaa tai muuttaa kyselyn vaihtoehtoja ensimmäisen 5 minuutin jälkeen. Sinun tulee poistaa tämä ketju ja avata uusi sen sijaan." + staff_cannot_add_or_remove_options_after_5_minutes: "Et voi lisätä, poistaa tai muuttaa kyselyn vaihtoehtoja ensimmäisen 5 minuutin jälkeen. Sinun tulee poistaa tämä ketju ja luoda uusi sen sijaan." no_polls_associated_with_this_post: "Tämä viesti ei sisällä äänestyskyselyä." no_poll_with_this_name: "Tämä viesti ei sisällä äänestyskyselyä nimeltä %{name}." post_is_deleted: "Ei voi tehdä poistetulle viestille" @@ -31,3 +35,5 @@ fi: poll_must_be_open_to_vote: "Vain avoimessa kyselyssä voi äänestää." topic_must_be_open_to_toggle_status: "Vain avoimessa ketjussa voi muuttaa äänestyksen tilaa." only_staff_or_op_can_toggle_status: "Vain henkilökunta tai kyselyn laatija voi muuttaa äänestyksen tilaa." + email: + link_to_poll: "Siirry äänestykseen klikkaamalla tästä" diff --git a/plugins/poll/config/locales/server.fr.yml b/plugins/poll/config/locales/server.fr.yml index 287c6d583a7..181a3a3a2fe 100644 --- a/plugins/poll/config/locales/server.fr.yml +++ b/plugins/poll/config/locales/server.fr.yml @@ -14,8 +14,12 @@ fr: multiple_polls_with_same_name: "Plusieurs sondages ont le même noms : %{name}. Utilisez l'attribut 'name' pour donner un identifiant unique aux sondages." default_poll_must_have_at_least_2_options: "Un sondage doit contenir au moins deux options." named_poll_must_have_at_least_2_options: "Le sondage %{name} doit contenir au moins deux options." - default_poll_must_have_less_options: "Un sondage peut contenir jusque %{max} options." - named_poll_must_have_less_options: "Le sondage %{name} peut contenir jusque %{max} options." + default_poll_must_have_less_options: + one: "Un sondage peut contenir une option." + other: "Un sondage peut contenir jusque %{count} options." + named_poll_must_have_less_options: + one: "Le sondage % {name} peut contenir une option." + other: "Le sondage % {name} peut contenir jusqu’à % {count} options." default_poll_must_have_different_options: "Les sondages doivent contenir des options différentes les unes des autres." named_poll_must_have_different_options: "Le sondage %{name} doit contenir des options différentes." default_poll_with_multiple_choices_has_invalid_parameters: "Le sondage à choix multiples possède des paramètres invalides." @@ -31,3 +35,5 @@ fr: poll_must_be_open_to_vote: "Le sondage doit être ouvert pour pouvoir voter." topic_must_be_open_to_toggle_status: "Le sujet doit être ouvert pour modifier le statut." only_staff_or_op_can_toggle_status: "Seuls les responsables ou l'utilisateur qui a créé ce sujet peuvent modifier le statut d'un sondage." + email: + link_to_poll: "Cliquez ici pour voir le sondage." diff --git a/plugins/poll/config/locales/server.gl.yml b/plugins/poll/config/locales/server.gl.yml new file mode 100644 index 00000000000..161239af6bd --- /dev/null +++ b/plugins/poll/config/locales/server.gl.yml @@ -0,0 +1,39 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +gl: + site_settings: + poll_enabled: "Queres permitir os usuarios crear enquisas?" + poll_maximum_options: "Número máximo de opcións permitidas nunha enquisa." + poll: + multiple_polls_without_name: "Hai múltiples enquisas sen nome. Utiliza o atributo 'nome' para singularizar as túas enquisas." + multiple_polls_with_same_name: "Hai múltiples enquisas co mesmo nome: %{name}. Utiliza o atributo 'nome' para singularizar as túas enquisas." + default_poll_must_have_at_least_2_options: "A enquisa debe ter alomenos 2 opcións." + named_poll_must_have_at_least_2_options: "A enquisa chamada %{name} debe ter alomenos 2 opcións." + default_poll_must_have_less_options: + one: "A enquisa debe ter cando menos 1 opción." + other: "A enquisa debe ter alomenos %{count} opcións." + named_poll_must_have_less_options: + one: "A enquisa chamada %{name} debe ter menos de 1 opción." + other: "A enquisa chamada %{name} debe ter menos de %{count} opcións." + default_poll_must_have_different_options: "A enquisa debe ter diferentes opcións." + named_poll_must_have_different_options: "A enquisa chamada strong>%{name} debe ter diferentes opcións." + default_poll_with_multiple_choices_has_invalid_parameters: "A enquisa con varios apartados ten parámetros incorrectos." + named_poll_with_multiple_choices_has_invalid_parameters: "A enquisa chamada %{name} con varios apartados ten parámetros incorrectos." + requires_at_least_1_valid_option: "Debes seleccionar alomenos 1 opción válida." + cannot_change_polls_after_5_minutes: "Non podes engadir, retirar ou renomear enquisas despois dos primeiros 5 minutos." + op_cannot_edit_options_after_5_minutes: "Non podes engadir nin retirar opcións da enquisa despois de 5 minutos. Contacta cun moderador se precisas editar unha opción da enquisa." + staff_cannot_add_or_remove_options_after_5_minutes: "Non podes engadir nin retirar opcións da enquisa despois de 5 minutos. Deberías pechar este tema e crear outro novo para substituílo." + no_polls_associated_with_this_post: "Non hai enquisas asociadas con esta publicación." + no_poll_with_this_name: "Non hai ningunha enquisa chamada %{name} asociada con esta publicación." + post_is_deleted: "Non se pode actuar sobre unha publicación eliminada." + topic_must_be_open_to_vote: "O tema debe estar aberto para votalo." + poll_must_be_open_to_vote: "A enquisa debe estar aberta para votala." + topic_must_be_open_to_toggle_status: "O tema debe estar aberto para cambiarlle o estado." + only_staff_or_op_can_toggle_status: "Soamente un membro do equipo ou o publicador orixinal poden trocar o estado dunha enquisa." + email: + link_to_poll: "Preme para ver a enquisa." diff --git a/plugins/poll/config/locales/server.he.yml b/plugins/poll/config/locales/server.he.yml index 9711891cc5d..0c6044d8adb 100644 --- a/plugins/poll/config/locales/server.he.yml +++ b/plugins/poll/config/locales/server.he.yml @@ -14,8 +14,12 @@ he: multiple_polls_with_same_name: "יש מספר סקרים עם אותו שם %{name}. השתמש במאפיין 'name' לזהות באופן יחודי את הסקרים שלך. " default_poll_must_have_at_least_2_options: "לסקר צריך להיות לפחות שתי אפשרויות." named_poll_must_have_at_least_2_options: "לסקר בשם %{name} צריך שיהיה לפחות שתי אפשרויות." - default_poll_must_have_less_options: "לסקר צריך שיהיו פחות מ %{max} אפשרויות. " - named_poll_must_have_less_options: "לסקר בשם %{name} צריך שיהיו פחות מ %{max} אפשרויות. " + default_poll_must_have_less_options: + one: "לסקר חייב להיות פחות מאפשרות אחת." + other: "לסקר חייב להיות פחות מ-%{count} אפשרויות." + named_poll_must_have_less_options: + one: "לסקר בשם %{name} צריך להיות פחות מאפשרות אחת." + other: "לסקר בשם %{name} צריך להיות פחות מ-%{count} אפשרויות." default_poll_must_have_different_options: "לסקר צריך שיהיה אפשרויות שונות. " named_poll_must_have_different_options: "לסקר בשם %{name} צריך שיהיו אפשרויות שונות. " default_poll_with_multiple_choices_has_invalid_parameters: "לסקר עם בחירה מרובה יש פרמטרים לא תקינים. " @@ -31,3 +35,5 @@ he: poll_must_be_open_to_vote: "הסקר צריך להיות פתוח להזמנות." topic_must_be_open_to_toggle_status: "הנושא צריך להיות פתוח לשינויים בסטטוס." only_staff_or_op_can_toggle_status: "רק חבר צוות או המפרסם המקורי יכול לשנות סטטוס של סקר. " + email: + link_to_poll: "לחץ כדיל לצפות בסקר." diff --git a/plugins/poll/config/locales/server.id.yml b/plugins/poll/config/locales/server.id.yml index 2112cad6a27..2e2abaaa52f 100644 --- a/plugins/poll/config/locales/server.id.yml +++ b/plugins/poll/config/locales/server.id.yml @@ -5,4 +5,33 @@ # To work with us on translations, join this project: # https://www.transifex.com/projects/p/discourse-org/ -id: {} +id: + site_settings: + poll_enabled: "Perbolehkan pengguna untuk membuat polling?" + poll_maximum_options: "Nomor maksimum dari pilihan yang diperbolehkan di sebuah polling." + poll: + multiple_polls_without_name: "Ada beberapa polling tanpa sebuah nama. Gunakan atribut 'nama' untuk membuat identitas polling anda unik." + multiple_polls_with_same_name: "Ada beberapa polling dengan nama yang sama: %{name}. Gunakan atribut 'nama' untuk mengidentifikasi polling anda secara unik." + default_poll_must_have_at_least_2_options: "Polling harus memiliki setidaknya 2 pilihan." + named_poll_must_have_at_least_2_options: "Polling dengan nama %{name} harus memiliki setidaknya 2 pilihan." + default_poll_must_have_less_options: + other: "Polling harus kurang dari %{count} pilihan." + named_poll_must_have_less_options: + other: "Polling dengan nama %{name} harus kurang dari %{count} pilihan." + default_poll_must_have_different_options: "Polling harus memiliki pilihan yang berbeda." + named_poll_must_have_different_options: "Polling dengan nama %{name} harus memiliki pilihan yang berbeda." + default_poll_with_multiple_choices_has_invalid_parameters: "Polling dengan pilihan ganda parameternya tidak benar." + named_poll_with_multiple_choices_has_invalid_parameters: "Polling dengan nama %{name} dengan pilihan ganda parameternya tidak benar." + requires_at_least_1_valid_option: "Anda harus memilih setidaknya 1 pilihan yang benar." + cannot_change_polls_after_5_minutes: "Anda tidak dapat menambah, menghapus atau merename polling setelah 15 menit pertama." + op_cannot_edit_options_after_5_minutes: "Anda tidak dapat menambah atau menghapus pilihan polling setelah 15 menit pertama. Silahkan kontak moderator jika anda ingin merubah pilihan pada sebuah polling." + staff_cannot_add_or_remove_options_after_5_minutes: "Anda tidak dapat menambah atau menghapus pilihan polling setelah 15 menit pertama. Anda harus menutup topik ini dan membuat yang baru." + no_polls_associated_with_this_post: "Tidak ada polling yang terkait dengan pos ini." + no_poll_with_this_name: "Tidak ada pollig %{name} yang terkait dengan pos ini." + post_is_deleted: "Tidak dapat beraksi pada sebuah pos yang dihapus." + topic_must_be_open_to_vote: "Topik harus terbuka untuk dinilai." + poll_must_be_open_to_vote: "Polling harus terbuka untuk dinilai." + topic_must_be_open_to_toggle_status: "Topik harus terbuka untuk merubah status." + only_staff_or_op_can_toggle_status: "Hanya anggota staf atau penerbit asli yang dapat merubah status polling." + email: + link_to_poll: "Klik untuk menampilkan polling." diff --git a/plugins/poll/config/locales/server.it.yml b/plugins/poll/config/locales/server.it.yml index 2ece567bf89..04e4c37823b 100644 --- a/plugins/poll/config/locales/server.it.yml +++ b/plugins/poll/config/locales/server.it.yml @@ -14,8 +14,12 @@ it: multiple_polls_with_same_name: "Ci sono più sondaggi con lo stesso nome: %{name}. Usa l'attributo 'name' per identificare univocamente i tuoi sondaggi." default_poll_must_have_at_least_2_options: "Il sondaggio deve avere almeno due opzioni." named_poll_must_have_at_least_2_options: "Il sondaggio con nome %{name} deve avere almeno due opzioni." - default_poll_must_have_less_options: "Il sondaggio deve avere meno di %{max} opzioni." - named_poll_must_have_less_options: "Il sondaggio dal nome %{name} deve avere meno di %{max} opzioni." + default_poll_must_have_less_options: + one: "Il sondaggio deve avere meno di una opzione." + other: "Il sondaggio deve avere meno di %{count} opzioni." + named_poll_must_have_less_options: + one: "Il sondaggio %{name} deve avere meno di una opzione." + other: "Il sondaggio %{name} deve avere meno di %{count} opzioni." default_poll_must_have_different_options: "Il sondaggio deve avere opzioni diverse." named_poll_must_have_different_options: "Il sondaggio dal nome %{name} deve avere opzioni diverse." default_poll_with_multiple_choices_has_invalid_parameters: "Il sondaggio a scelta multipla ha parametri non validi." @@ -31,3 +35,5 @@ it: poll_must_be_open_to_vote: "Il sondaggio deve essere aperto per poter votare." topic_must_be_open_to_toggle_status: "L'argomento deve essere aperto per commutare lo stato." only_staff_or_op_can_toggle_status: "Solo un membro dello staff o l'autore originale possono commutare lo stato di un sondaggio." + email: + link_to_poll: "Clicca per vedere il sondaggio." diff --git a/plugins/poll/config/locales/server.ja.yml b/plugins/poll/config/locales/server.ja.yml index 2caae933626..6353abfeb56 100644 --- a/plugins/poll/config/locales/server.ja.yml +++ b/plugins/poll/config/locales/server.ja.yml @@ -14,8 +14,10 @@ ja: multiple_polls_with_same_name: "同じ名前: %{name} の複数の投票があります。一意に投票結果を識別するために、属性'name'を使用します。" default_poll_must_have_at_least_2_options: "投票は少なくとも2つのオプションが必要です。" named_poll_must_have_at_least_2_options: "投票 %{name} は少なくとも2つのオプションが必要です。" - default_poll_must_have_less_options: "投票オプションは %{max} 未満です。" - named_poll_must_have_less_options: "投票 %{name} のオプションは %{max} 未満です。" + default_poll_must_have_less_options: + other: "投票は%{count}オプション以下でなければいけません。" + named_poll_must_have_less_options: + other: "投票 %{name} は%{count}オプション以下でなければいけません。" default_poll_must_have_different_options: "投票は異なるオプションが必要です。" named_poll_must_have_different_options: "投票 %{name} は異なるオプションが必要です。" default_poll_with_multiple_choices_has_invalid_parameters: "複数の選択肢をもつ投票に無効なパラメータがあります。" @@ -31,3 +33,5 @@ ja: poll_must_be_open_to_vote: "投票するにはオープンになっている必要があります。" topic_must_be_open_to_toggle_status: "状態を切り替えるには、トピックがオープンになっている必要があります。" only_staff_or_op_can_toggle_status: "スタッフやオリジナル投稿者のみが投票状態を切り替えることができます。" + email: + link_to_poll: "クリックして投票を表示。" diff --git a/plugins/poll/config/locales/server.ko.yml b/plugins/poll/config/locales/server.ko.yml index c8066f3a2c3..ed8f31661e4 100644 --- a/plugins/poll/config/locales/server.ko.yml +++ b/plugins/poll/config/locales/server.ko.yml @@ -14,8 +14,6 @@ ko: multiple_polls_with_same_name: "같은 이름 %{name} 의 설문조사가 여러개 있습니다. 'name' 속성을 사용하여 설문조사를 개별적으로 구분해 보세요." default_poll_must_have_at_least_2_options: "설문조사에 적어도 2개의 항목은 있어야합니다." named_poll_must_have_at_least_2_options: "%{name} 설문조사에 적어도 2개의 항목이 있어야 합니다." - default_poll_must_have_less_options: "설문조사 항목은 %{max}개보다 적어야합니다." - named_poll_must_have_less_options: "%{name} 설문조사의 항목이 %{max}개보다 적어야 합니다." default_poll_must_have_different_options: "한 설문조사 안에 항목 내용들이 각각 달라야 합니다." named_poll_must_have_different_options: "%{name} 설문조사의 항목 내용들이 달라야 합니다." default_poll_with_multiple_choices_has_invalid_parameters: "복수응답 가능한 설문조사가 잘못된 매개변수를 가지고 있습니다." diff --git a/plugins/poll/config/locales/server.nb_NO.yml b/plugins/poll/config/locales/server.nb_NO.yml index 8d5c7e686d0..03d3f0b3291 100644 --- a/plugins/poll/config/locales/server.nb_NO.yml +++ b/plugins/poll/config/locales/server.nb_NO.yml @@ -14,8 +14,6 @@ nb_NO: multiple_polls_with_same_name: "Det er flere spørreundersøkelser med samme navn: %{name}. Bruk 'name' attributten til å identifisere spørreundersøkelsene dine." default_poll_must_have_at_least_2_options: "Spørrsundersøkelser må inneholde minst 2 alternativer." named_poll_must_have_at_least_2_options: "Spørresundersøkelsen %{name} må ha minst 2 svaralternativer." - default_poll_must_have_less_options: "Spørreundersøkelsen må ha mindre enn %{max} svaralternativer." - named_poll_must_have_less_options: "Spørresundersøkelsen %{name} må ha mindre enn %{max} svaralternativer." default_poll_must_have_different_options: "Spørreundersøkelsen må ha ulike alternativer." named_poll_must_have_different_options: "Spørresundersøkelsen %{name} må ha ulike svaralternativer." default_poll_with_multiple_choices_has_invalid_parameters: "Spørreundersøkelsen med flere svaralternativer har ugyldige parametere." diff --git a/plugins/poll/config/locales/server.nl.yml b/plugins/poll/config/locales/server.nl.yml index 232d9150048..8eeb5e19f4d 100644 --- a/plugins/poll/config/locales/server.nl.yml +++ b/plugins/poll/config/locales/server.nl.yml @@ -14,8 +14,12 @@ nl: multiple_polls_with_same_name: "Er zijn meerdere polls met dezelfde naam : %{name}. Gebruik het 'naam' attribuut om je polls te identificeren." default_poll_must_have_at_least_2_options: "De poll moet minimaal 2 opties hebben." named_poll_must_have_at_least_2_options: "De poll genaamd %{name} moet minimaal 2 opties hebben." - default_poll_must_have_less_options: "De poll moet minder dan %{max} opties hebben." - named_poll_must_have_less_options: "De poll genaamd %{name} moet minder dan %{max} opties hebben." + default_poll_must_have_less_options: + one: "Poll dient minder dan een optie te hebben." + other: "Poll dient minder dan %{count} opties te hebben." + named_poll_must_have_less_options: + one: "De poll genaamd %{name} moet minder dan 1 optie hebben." + other: "De poll met de naam %{name} moet minder dan %{count} opties bevatten." default_poll_must_have_different_options: "Polls moeten verschillende opties hebben." named_poll_must_have_different_options: "De poll genaamd %{name} moet verschillende opties hebben." default_poll_with_multiple_choices_has_invalid_parameters: "De poll met meerdere keuzes heeft ongeldige parameters." @@ -31,3 +35,5 @@ nl: poll_must_be_open_to_vote: "De poll moet geopend zijn om te kunnen stemmen." topic_must_be_open_to_toggle_status: "Het topic moet geopend zijn om de status te kunnen veranderen." only_staff_or_op_can_toggle_status: "Alleen een staflid of de oorspronkelijke plaatser van een bericht kan de status van een poll veranderen." + email: + link_to_poll: "Klik om de poll te bekijken." diff --git a/plugins/poll/config/locales/server.pl_PL.yml b/plugins/poll/config/locales/server.pl_PL.yml index f8646b19330..0f2b9a368b0 100644 --- a/plugins/poll/config/locales/server.pl_PL.yml +++ b/plugins/poll/config/locales/server.pl_PL.yml @@ -14,12 +14,18 @@ pl_PL: multiple_polls_with_same_name: "Istnieje kilka ankiet o tej samej nazwie: %{name}. Użyj atrybutu 'name', aby umożliwić ich jednoznaczną identyfikację." default_poll_must_have_at_least_2_options: "Ankieta musi posiadać co najmniej 2 opcje." named_poll_must_have_at_least_2_options: "Ankieta %{name} musi posiadać co najmniej 2 opcje do wyboru." - default_poll_must_have_less_options: "Ankieta musi posiadać mniej niż %{max} opcji do wyboru." - named_poll_must_have_less_options: "Ankieta %{name} musi posiadać mniej niż %{max} opcji do wyboru." + default_poll_must_have_less_options: + one: "Ankieta musi posiadać mniej niż 1 opcję do wyboru." + few: "Ankieta musi posiadać co najmniej %{count} pozycje." + other: "Ankieta musi posiadać co najmniej %{count} pozycji." + named_poll_must_have_less_options: + one: "Ankieta %{name} musi posiadać mniej niż 1 opcję." + few: "Ankieta %{name} musi posiadać mniej niż %{count} opcje." + other: "Ankieta %{name} musi posiadać mniej niż %{count} opcji." default_poll_must_have_different_options: "Ankieta musi posiadać kilka różnych opcji do wyboru." named_poll_must_have_different_options: "Ankieta %{name} musi posiadać kilka różnych opcji do wyboru." - default_poll_with_multiple_choices_has_invalid_parameters: "Sonda wielokrotnego wyboru posiada nieprawidłowe parametry." - named_poll_with_multiple_choices_has_invalid_parameters: "Sonda wielokrotnego wyboru o nazwie %{name} posiada nieprawidłowe parametry." + default_poll_with_multiple_choices_has_invalid_parameters: "Ankieta wielokrotnego wyboru posiada nieprawidłowe parametry." + named_poll_with_multiple_choices_has_invalid_parameters: "Ankieta wielokrotnego wyboru o nazwie %{name} posiada nieprawidłowe parametry." requires_at_least_1_valid_option: "Musisz wybrać co najmniej 1 poprawną opcje." cannot_change_polls_after_5_minutes: "Po upływie 5 minut ankiety nie mogą być zmieniane." op_cannot_edit_options_after_5_minutes: "Po upływie 5 minut nie można dodawać lub usuwać opcji wyboru w ankietach. Skontaktuj się z moderatorem jeśli naprawdę musisz zmienić opcję w tej ankiecie." @@ -31,3 +37,5 @@ pl_PL: poll_must_be_open_to_vote: "Głosowanie jest możliwe tylko w otwartych ankietach." topic_must_be_open_to_toggle_status: "Zmiana statusu jest możliwa jedynie w otwartych tematach." only_staff_or_op_can_toggle_status: "Status może być zmieniony przez autora wpisu lub członka załogi serwisu." + email: + link_to_poll: "Kliknij, aby zobaczyć ankietę." diff --git a/plugins/poll/config/locales/server.pt.yml b/plugins/poll/config/locales/server.pt.yml index ed455c1b507..6a8c13a7e57 100644 --- a/plugins/poll/config/locales/server.pt.yml +++ b/plugins/poll/config/locales/server.pt.yml @@ -14,8 +14,12 @@ pt: multiple_polls_with_same_name: "Há múltiplas votações com o mesmo nome: %{name}. Utilize o atributo 'nome' para identificar as suas votações de maneira única." default_poll_must_have_at_least_2_options: "Votação deve ter pelo menos 2 opções." named_poll_must_have_at_least_2_options: "Votação com o nome %{name} deve ter pelo menos 2 opções." - default_poll_must_have_less_options: "Votação deve ter menos que %{max} opções." - named_poll_must_have_less_options: "Votação com o nome %{name} deve ter menos que %{max} opções." + default_poll_must_have_less_options: + one: "Votação deve ter menos que 1 opção." + other: "Votação deve ter menos que %{count} opções." + named_poll_must_have_less_options: + one: "Votação com o nome %{name} deve ter menos que 1 opção." + other: "Votação com o nome %{name} deve ter menos que %{count} opções." default_poll_must_have_different_options: "Votação deve ter opções diferentes." named_poll_must_have_different_options: "Votação com o nome %{name} deve ter opções diferentes." default_poll_with_multiple_choices_has_invalid_parameters: "Votação com escolha múltipla tem parâmetros inválidos." @@ -31,3 +35,5 @@ pt: poll_must_be_open_to_vote: "Votação tem que estar aberta para votar." topic_must_be_open_to_toggle_status: "O tópico tem que estar aberto para alternar o estado." only_staff_or_op_can_toggle_status: "Apenas um membro do pessoal ou o autor original pode alternar o estado da votação." + email: + link_to_poll: "Clique para ver a votação." diff --git a/plugins/poll/config/locales/server.pt_BR.yml b/plugins/poll/config/locales/server.pt_BR.yml index 1c9e3a4574d..a943219fe03 100644 --- a/plugins/poll/config/locales/server.pt_BR.yml +++ b/plugins/poll/config/locales/server.pt_BR.yml @@ -14,17 +14,26 @@ pt_BR: multiple_polls_with_same_name: "Existem várias enquetes com o mesmo nome: %{name}. Use o atributo 'name' para identificar suas enquetes." default_poll_must_have_at_least_2_options: "Enquetes devem ter ao mínimo 2 opções." named_poll_must_have_at_least_2_options: "A enquete de nome %{name} deve ter ao menos 2 opções." - default_poll_must_have_less_options: "A enquete deve ter menos de %{máximo} opções." - named_poll_must_have_less_options: "A enquete de nome %{nome} deve ter menos de %{máximo} opções." + default_poll_must_have_less_options: + one: "Enquetes devem ter pelo menos 1 opção." + other: "Enquetes devem ter pelo menos %{count} opções." + named_poll_must_have_less_options: + one: "Enquete chamada %{name} deve ter menos do que 1 opção." + other: "Enquete chamada %{name} deve ter menos do que %{count} opções." default_poll_must_have_different_options: "A votação deve ter opções diferentes." named_poll_must_have_different_options: "A enquete de nome %{nome} deve ter opções diferentes." + default_poll_with_multiple_choices_has_invalid_parameters: "Enquete com múltiplas opções tem parâmetros inválidos." + named_poll_with_multiple_choices_has_invalid_parameters: "Enquete chamada %{name} com múltiplas escolhas tem parâmetros inválidos." requires_at_least_1_valid_option: "Você deve selecionar pelo menos 1 opção válida." cannot_change_polls_after_5_minutes: "Você não pode adicionar, remover ou renomear enquetes depois dos primeiros 5 minutos." op_cannot_edit_options_after_5_minutes: "Você não pode adicionar ou remover opções das enquetes depois dos primeiros 5 minutos. Por favor contate um moderador se você precisar editar uma opção da enquete." staff_cannot_add_or_remove_options_after_5_minutes: "Você não pode adicionar ou remover opções das enquetes depois dos primeiros 5 minutos. Você deve fechar este tópico e criar um novo." no_polls_associated_with_this_post: "Não há votações associadas com este post." no_poll_with_this_name: "Nenhuma enquete com o nome %{nome} associada com este post." + post_is_deleted: "Não pode agir numa mensagem apagada." topic_must_be_open_to_vote: "O tópico deve ser aperto para votação." poll_must_be_open_to_vote: "A enquete deve estar aberta para votação." topic_must_be_open_to_toggle_status: "O tópico deve estar aberto para mudar o status." only_staff_or_op_can_toggle_status: "Somente um moderador ou o criador do tópico pode mudar o status da enquete." + email: + link_to_poll: "Clique para ver a enquete." diff --git a/plugins/poll/config/locales/server.ro.yml b/plugins/poll/config/locales/server.ro.yml index 31d1c440135..e0ca3634c71 100644 --- a/plugins/poll/config/locales/server.ro.yml +++ b/plugins/poll/config/locales/server.ro.yml @@ -5,4 +5,37 @@ # To work with us on translations, join this project: # https://www.transifex.com/projects/p/discourse-org/ -ro: {} +ro: + site_settings: + poll_enabled: "Permiți utilizatorilor să creeze sondaje?" + poll_maximum_options: "Numărul maxim admis de opțiuni într-un sondaj" + poll: + multiple_polls_without_name: "Există mai multe sondaje fără nume. Folosește atributul 'name' pentru a identifica sondajele proprii" + multiple_polls_with_same_name: "Există mai multe sondaje cu același nume: %{name}. Folosește atributul 'name' pentru a identifica sondajele proprii." + default_poll_must_have_at_least_2_options: "Sondajul trebuie să aibă cel puțin 2 opțiuni." + named_poll_must_have_at_least_2_options: "Sondajul numit %{name} trebuie să aibă cel puțin 2 opțiuni." + default_poll_must_have_less_options: + one: "Sondajul trebuie să aibă mai puțin de 1 opțiune." + few: "Sondajul trebuie să conțină cel mult %{count} opțiuni." + other: "Sondajul trebuie să aibă mai puțin de %{count} opțiuni." + named_poll_must_have_less_options: + one: "Sondajul numit %{name} trebuie să aibă cel mult 1 opțiune." + few: "Sondajul numit %{name} trebuie să aibă mai puțin de %{count} opțiuni." + other: "Sondajul numit %{name} trebuie să aibă cel mult %{count} opțiuni." + default_poll_must_have_different_options: "Sondajul trebuie să aibă opțiuni diferite." + named_poll_must_have_different_options: "Sondajul numit %{name} trebuie să aibă opțiuni diferite." + default_poll_with_multiple_choices_has_invalid_parameters: "Sondajul cu opțiuni multiple are parametri invalizi." + named_poll_with_multiple_choices_has_invalid_parameters: "Sondajul numit %{name} cu opțiuni multiple are parametri invalizi." + requires_at_least_1_valid_option: "Trebuie să selectezi cel puțin 1 valoare validă." + cannot_change_polls_after_5_minutes: "Nu poți adăuga, elimina sau redenumi sondaje după primele 5 minute." + op_cannot_edit_options_after_5_minutes: "Nu poți adăuga sau elimina opțiuni ale unui sondaj după primele 5 minute. Te rugăm contactează un moderator pentru a edita o opțiune din sondaj." + staff_cannot_add_or_remove_options_after_5_minutes: "Nu poți adăuga sau elimina opțiuni ale unui sondaj după primele 5 minute. Ar trebui să închizi discuția și să creezi alta în loc." + no_polls_associated_with_this_post: "Nu există sondaje asociate acestei postări." + no_poll_with_this_name: "Nu există nici un sondaj cu numele %{name} asociat acestei postări." + post_is_deleted: "Postările șterse nu se pot modifica." + topic_must_be_open_to_vote: "Discuția trebuie să fie activă pentru a se putea vota." + poll_must_be_open_to_vote: "Sondajul trebuie să fie deschis pentru a se putea vota." + topic_must_be_open_to_toggle_status: "Discuția trebuie să fie activă pentru a se schimba statutul." + only_staff_or_op_can_toggle_status: "Doar un administrator sau autorul postării inițiale pot schimba statusul unui sondaj." + email: + link_to_poll: "Click pentru afișarea sondajului." diff --git a/plugins/poll/config/locales/server.ru.yml b/plugins/poll/config/locales/server.ru.yml index 8f1059c64ee..ba221acecbb 100644 --- a/plugins/poll/config/locales/server.ru.yml +++ b/plugins/poll/config/locales/server.ru.yml @@ -7,27 +7,37 @@ ru: site_settings: - poll_enabled: "Разрешить содание опросов?" - poll_maximum_options: "Максимальное колличество доступных вариантов в голосовании." + poll_enabled: "Разрешить форумчанам создавать опросы?" + poll_maximum_options: "Максимальное колличество вариантов ответов в одном опросе." poll: - multiple_polls_without_name: "Обнаружено несколько голосований без названия. Искользуйте 'name' для уникализации вашего голосования." - multiple_polls_with_same_name: "Голосование с таким названием: %{name} уже существует. Используйте 'name' для уникализации вашего голосования." - default_poll_must_have_at_least_2_options: "В голосовании должно быть хотябы 2 варианта ответа." - named_poll_must_have_at_least_2_options: "В голосовании %{name} должно быть хотябы 2 варианта ответа." - default_poll_must_have_less_options: "Голосование может содержать максимум %{max} ответов." - named_poll_must_have_less_options: "Голосование %{name} может содержать максимум %{max} ответов." - default_poll_must_have_different_options: "Ответы в голосовании должны быть разными." - named_poll_must_have_different_options: "Ответы в голосовании %{name} должны быть разными." - default_poll_with_multiple_choices_has_invalid_parameters: "Опрос c мультивыбором имеет неверные параметры." - named_poll_with_multiple_choices_has_invalid_parameters: "Опрос с мультивыбором %{name} имеет неверные параметры." - requires_at_least_1_valid_option: "Вы должны выбрать как минимум 1 правильный ответ." - cannot_change_polls_after_5_minutes: "Вы не можете удалить или переименовать опрос в течении первых 5 минут." - op_cannot_edit_options_after_5_minutes: "Вы не можете добавлять и удалять ответы голосования по истечению 5 минут после создания. Свяжитесь с модератором если вам необходимо отредактировать ответы в данном голосовании." - staff_cannot_add_or_remove_options_after_5_minutes: "Вы не можете добавлять и удалять ответы голосования по истечению 5 минут после создания. Вы можете закрыть данную тему и создать новую. " - no_polls_associated_with_this_post: "Нет голосований прикрепленных к данному посту" - no_poll_with_this_name: "Нет голосований %{name} прикрепленных к данному посту." + multiple_polls_without_name: "Обнаружено несколько опросов в одном сообщении. Чтобы система могла их различать между собой, используйте атрибут name' для каждого опроса. Например: [poll name=1]" + multiple_polls_with_same_name: "Обнаружено несколько опросов с одним и тем же названием: %{name}. Чтобы система могла различать опросы между собой, придумайте разные значения для атрибута name' - для каждого опроса своё." + default_poll_must_have_at_least_2_options: "В опросе должно быть хотябы 2 варианта ответа." + named_poll_must_have_at_least_2_options: "В опросе с названием \"%{name}\" должно быть хотябы 2 варианта ответа." + default_poll_must_have_less_options: + one: "В опросе может быть не более 1-го варианта ответа." + few: "В опросе может быть не более %{count} вариантов ответов." + many: "В опросе может быть не более %{count} вариантов ответов." + other: "В опросе может быть не более %{count} вариантов ответов." + named_poll_must_have_less_options: + one: "В опросе под названием \"%{name}\" должно быть не более 1-го варианта ответов." + few: "В опросе под названием \"%{name}\" должно быть не более %{max} вариантов ответов." + many: "В опросе под названием \"%{name}\" должно быть не более %{max} вариантов ответов." + other: "В опросе под названием \"%{name}\" должно быть не более %{max} вариантов ответов." + default_poll_must_have_different_options: "В опросе не должно быть одинаковых вариантов ответов." + named_poll_must_have_different_options: "В опросе %{name} не должно быть одинаковых ответов." + default_poll_with_multiple_choices_has_invalid_parameters: "Опрос с множественным выбором вариантов ответов содержит неправильные параметры." + named_poll_with_multiple_choices_has_invalid_parameters: "Опрос под названием %{name} с множественным выбором вариантов ответов содержит неправильные параметры." + requires_at_least_1_valid_option: "Выберите хотя бы 1 вариант ответа." + cannot_change_polls_after_5_minutes: "Запрещается добавлять, удалять или переименовывать опросы через 5 минут после их создания." + op_cannot_edit_options_after_5_minutes: "Запрещается добавлять или удалять варианты ответов в опросах по истечении 5 минут после их создания. Если необходимо внести изменения в ответы, пожалуйста, свяжитесь с модератором." + staff_cannot_add_or_remove_options_after_5_minutes: "Запрещается добавлять или удалять варианты ответов в опросах по истечении 5 минут после их создания. Если нужно изменить набор ответов, следует закрыть данную тему и создать новую." + no_polls_associated_with_this_post: "В данном сообщении нет опросов." + no_poll_with_this_name: "В данном сообщении нет опроса под названием %{name}." post_is_deleted: "Невозможно совершить действие над удаленным сообщением." - topic_must_be_open_to_vote: "Тема должна быть открыта для голосования." - poll_must_be_open_to_vote: "Опрос должен быть открыт для голосования." - topic_must_be_open_to_toggle_status: "Тема должна быть открыта для изменения статуса." - only_staff_or_op_can_toggle_status: "Только модераторы или автор поста может поменять статус голосования." + topic_must_be_open_to_vote: "Для возможности голосования в опросе, тема должна быть открыта." + poll_must_be_open_to_vote: "Опрос должен быть открыт, чтобы в нем можно было голосовать." + topic_must_be_open_to_toggle_status: "Чтобы изменить статус, тема должна быть открыта." + only_staff_or_op_can_toggle_status: "Только модераторы или сам автор могут поменять статус опроса." + email: + link_to_poll: "Нажмите чтобы открыть опрос." diff --git a/plugins/poll/config/locales/server.sk.yml b/plugins/poll/config/locales/server.sk.yml new file mode 100644 index 00000000000..665bc70c744 --- /dev/null +++ b/plugins/poll/config/locales/server.sk.yml @@ -0,0 +1,41 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +sk: + site_settings: + poll_enabled: "Umožnit používaťeľom vytvárať hlasovania?" + poll_maximum_options: "Maximálny počet povolených možností v hlasovaní." + poll: + multiple_polls_without_name: "Existujú viaceré hlasovania bez mena. Použite atribút 'meno', aby ste hlasovanie jednoznačne rozlíšili." + multiple_polls_with_same_name: "Existujú viaceré hlasovania s rovnakým menom: %{name}. Použite atribút 'meno', aby ste hlasovanie jednoznačne rozlíšili." + default_poll_must_have_at_least_2_options: "Hlasovanie musí mať minimálne 2 možnosti." + named_poll_must_have_at_least_2_options: "Hlasovanie s názvom %{name} musí mať minimálne 2 možnosti." + default_poll_must_have_less_options: + one: "Hlasovanie musí mať menej ako jednu možnosť." + few: "Hlasovanie musí mať menej ako %{count} možnosti." + other: "Hlasovanie musí mať menej ako %{count} možnosti." + named_poll_must_have_less_options: + one: "Hlasovanie s názvom %{name} musí mať menej ako 1 možnost." + few: "Hlasovanie s názvom %{name} musí mať menej ako %{count} možnosti." + other: "Hlasovanie s názvom %{name} musí mať menej ako %{count} možností." + default_poll_must_have_different_options: "Hlasovanie musí mať rôzne možnosti." + named_poll_must_have_different_options: "Hlasovanie s názvom %{name} musí mať rôzne možnosti." + default_poll_with_multiple_choices_has_invalid_parameters: "Hlasovanie s viac možnosťami má nesprávne parametre." + named_poll_with_multiple_choices_has_invalid_parameters: "Hlasovanie s názvom %{name} s viac možnosťami má nesprávne parametre." + requires_at_least_1_valid_option: "Musite vybrať aspoň 1 platnú možnosť." + cannot_change_polls_after_5_minutes: "Po prvých 5 minútach už nemôžete pridať, odstrániť alebo premenovať hlasovanie." + op_cannot_edit_options_after_5_minutes: "Po prvých 5 minútach už nemôžete pridať alebo odstrániť možnosti hlasovania. Ak potrebujete upraviť možnosti hlasovania prosím kontaktujte moderátora." + staff_cannot_add_or_remove_options_after_5_minutes: "Po prvých 5 minútach už nemôžete pridať alebo odstrániť možnosti hlasovania. Miesto toho by ste mali uzavrieť túto tému a miesto nej vytvoriť inú." + no_polls_associated_with_this_post: "S týmto príspevkom nie sú spojené žiadne hlasovania." + no_poll_with_this_name: "S týmto príspevkom nie je spojené žiadne hlasovanie s názvom %{name}." + post_is_deleted: "Na vymazanom príspevku nie je možné vykonať." + topic_must_be_open_to_vote: "Na odovzdanie hlasu téma otvorená." + poll_must_be_open_to_vote: "Na odovzdanie hlasu musí byť hlasovanie otvorené." + topic_must_be_open_to_toggle_status: "Na zmenu stavu musí byť téma otvorená." + only_staff_or_op_can_toggle_status: "Zmeniť stav hlasovania môže iba zamestnanec alebo pôvodný prispievateľ." + email: + link_to_poll: "Kliknite na zobrazenie hlasovania." diff --git a/plugins/poll/config/locales/server.sq.yml b/plugins/poll/config/locales/server.sq.yml index c2c613bcc92..9067ae9e633 100644 --- a/plugins/poll/config/locales/server.sq.yml +++ b/plugins/poll/config/locales/server.sq.yml @@ -14,8 +14,6 @@ sq: multiple_polls_with_same_name: "There are multiple polls with the same name: %{name}. Use the 'name' attribute to uniquely identify your polls." default_poll_must_have_at_least_2_options: "Sondazhi duhet të ketë të paktën 2 opsione. " named_poll_must_have_at_least_2_options: "Poll named %{name} must have at least 2 options." - default_poll_must_have_less_options: "Sondazhi duhet të ketë më pak se %{max} opsione." - named_poll_must_have_less_options: "Poll named %{name} must have less than %{max} options." default_poll_must_have_different_options: "Sondazh duhet të ketë opsione të ndryshme." named_poll_must_have_different_options: "Poll named %{name} must have different options." default_poll_with_multiple_choices_has_invalid_parameters: "Poll with multiple choices has invalid parameters." diff --git a/plugins/poll/config/locales/server.sv.yml b/plugins/poll/config/locales/server.sv.yml index d13c1eee1d9..591d40b3ee6 100644 --- a/plugins/poll/config/locales/server.sv.yml +++ b/plugins/poll/config/locales/server.sv.yml @@ -14,8 +14,12 @@ sv: multiple_polls_with_same_name: "Det finns flera omröstningar med samma namn: %{name}. Använd attributet 'namn' för att unikt identifiera din omröstningar." default_poll_must_have_at_least_2_options: "Omröstningen måste ha minst 2 alternativ." named_poll_must_have_at_least_2_options: "Omröstningen med namnet %{name} måste ha minst 2 alternativ." - default_poll_must_have_less_options: "Omröstningen måste ha mindre än %{max} alternativ." - named_poll_must_have_less_options: "Omröstningen med namnet %{name} måste ha mindre än %{max} alternativ." + default_poll_must_have_less_options: + one: "Omröstningen måste ha mindre än 1 alternativ." + other: "Omröstningen måste ha mindre än %{count} alternativ." + named_poll_must_have_less_options: + one: "Omröstningen med namnet %{name} måste ha mindre än 1 alternativ." + other: "Omröstningen med namnet %{name} måste ha mindre än %{count} alternativ." default_poll_must_have_different_options: "Omröstningen måste ha olika alternativ." named_poll_must_have_different_options: "Omröstning med namnet %{name} måste ha olika alternativ." default_poll_with_multiple_choices_has_invalid_parameters: "Omröstning med flera val har ogiltiga parametrar." @@ -31,3 +35,5 @@ sv: poll_must_be_open_to_vote: "Omröstning måste vara öppen för att kunna rösta." topic_must_be_open_to_toggle_status: "Ämnet måste vara öppet för att kunna växla status." only_staff_or_op_can_toggle_status: "Endast personal eller ursprungsskribenten kan växla status på en omröstning." + email: + link_to_poll: "Klicka här för att se omröstningen." diff --git a/plugins/poll/config/locales/server.tr_TR.yml b/plugins/poll/config/locales/server.tr_TR.yml index 9018c91244a..093c9a965d3 100644 --- a/plugins/poll/config/locales/server.tr_TR.yml +++ b/plugins/poll/config/locales/server.tr_TR.yml @@ -14,8 +14,10 @@ tr_TR: multiple_polls_with_same_name: "Aynı isme sahip birden fazla anket var: %{name}. 'name' atıfını kullanarak anketlerinizi özebir tanımlayabilirsiniz." default_poll_must_have_at_least_2_options: "Ankette en az 2 seçenek olmalı." named_poll_must_have_at_least_2_options: "%{name} isimli ankette en az 2 seçenek olmalı." - default_poll_must_have_less_options: "Anketler en fazla %{max} seçeneğe sahip olabilir." - named_poll_must_have_less_options: "%{name} isimli anket en fazla %{max} seçeneğe sahip olabilir." + default_poll_must_have_less_options: + other: "Ankette en az %{count} seçenek olmalı." + named_poll_must_have_less_options: + other: "%{name} isimli ankette en az %{count} seçenek olmalı." default_poll_must_have_different_options: "Anketin farklı seçenekleri olmalı." named_poll_must_have_different_options: "%{name} isimli anketin farklı seçenekleri olmalı." default_poll_with_multiple_choices_has_invalid_parameters: "Çoklu seçim seçeneği içeren anketinizde hatalar belirlendi." @@ -31,3 +33,5 @@ tr_TR: poll_must_be_open_to_vote: "Anket oylanabilmesi için açık olmalı." topic_must_be_open_to_toggle_status: "Statüsün düzenlenebilmesi için konu açık olmalı." only_staff_or_op_can_toggle_status: "Bir anketin statüsünü sadece o anketin orjinal sahibi ya da bir görevli değiştirebilir." + email: + link_to_poll: "Anketi görüntülemek için tıklayın." diff --git a/plugins/poll/config/locales/server.vi.yml b/plugins/poll/config/locales/server.vi.yml new file mode 100644 index 00000000000..8cd71609a2b --- /dev/null +++ b/plugins/poll/config/locales/server.vi.yml @@ -0,0 +1,37 @@ +# encoding: utf-8 +# +# Never edit this file. It will be overwritten when translations are pulled from Transifex. +# +# To work with us on translations, join this project: +# https://www.transifex.com/projects/p/discourse-org/ + +vi: + site_settings: + poll_enabled: "Cho phép người dùng tạo các cuộc thăm dò?" + poll_maximum_options: "Số lượng tối đa tùy chọn trong một cuộc thăm dò." + poll: + multiple_polls_without_name: "Có nhiều cuộc thăm dò mà không có tên. Sử dụng thuộc tính 'name' để xác định cuộc thăm dò của bạn." + multiple_polls_with_same_name: "Có nhiều cuộc thăm dò có cùng tên: %{name}. Sử dụng thuộc tính 'name' để xác định cuộc thăm dò của bạn." + default_poll_must_have_at_least_2_options: "Thăm dò ý kiến ​​phải có ít nhất 2 lựa chọn." + named_poll_must_have_at_least_2_options: "Thăm dò có tên %{name} phải có ít nhất 2 lựa chọn." + default_poll_must_have_less_options: + other: "Thăm dò phải có ít hơn %{count} lựa chọn." + named_poll_must_have_less_options: + other: "Thăm dò %{name} phải có ít hơn %{count} tùy chọn." + default_poll_must_have_different_options: "Thăm dò ý kiến ​​phải có các tùy chọn khác nhau." + named_poll_must_have_different_options: "Thăm dò %{name} ​​phải có các tùy chọn khác nhau." + default_poll_with_multiple_choices_has_invalid_parameters: "Thăm dò ý kiến ​​với nhiều sự lựa chọn có các tham số không hợp lệ." + named_poll_with_multiple_choices_has_invalid_parameters: "Thăm dò %{name} ​​với nhiều sự lựa chọn có các tham số không hợp lệ. " + requires_at_least_1_valid_option: "Bạn phải chọn ít nhất 1 lựa chọn hợp lệ." + cannot_change_polls_after_5_minutes: "Bạn không thể thêm, xóa hoặc đổi tên các cuộc thăm dò 5 phút đầu tiên." + op_cannot_edit_options_after_5_minutes: "Bạn không thể thêm hoặc loại bỏ các bình chọn sau khi 5 phút đầu tiên. Hãy liên hệ với người điều hành nếu bạn cần chỉnh sửa một bình chọn nào đó." + staff_cannot_add_or_remove_options_after_5_minutes: "Bạn không thể thêm hoặc loại bỏ các bình chọn sau khi 5 phút đầu tiên. Bạn nên đóng chủ đề này và tạo ra một cái mới để thay thế." + no_polls_associated_with_this_post: "Không có cuộc thăm dò được liên kết với bài này." + no_poll_with_this_name: "Không có thăm dò có tên %{name} liên kết với bài viết này." + post_is_deleted: "Không thể thực hiện trên bài viết đã xóa." + topic_must_be_open_to_vote: "Các chủ đề phải được mở để bầu chọn." + poll_must_be_open_to_vote: "Thăm dò ý kiến ​​phải được mở để bầu chọn." + topic_must_be_open_to_toggle_status: "Các chủ đề phải được mở để chuyển trạng thái." + only_staff_or_op_can_toggle_status: "Chỉ có một BQT hoặc các người đăng bài có thể chuyển đổi một trạng thái thăm dò ý kiến" + email: + link_to_poll: "Nhấn để hiển thị." diff --git a/plugins/poll/config/locales/server.zh_CN.yml b/plugins/poll/config/locales/server.zh_CN.yml index af100e3010d..878d6379f8c 100644 --- a/plugins/poll/config/locales/server.zh_CN.yml +++ b/plugins/poll/config/locales/server.zh_CN.yml @@ -14,8 +14,10 @@ zh_CN: multiple_polls_with_same_name: "有多个投票的名字相同:%{name}。使用“name”属性唯一标识投票。" default_poll_must_have_at_least_2_options: "投票至少要有 2 个选项。" named_poll_must_have_at_least_2_options: "投票“%{name}”必须要有 2 个选项。" - default_poll_must_have_less_options: "投票选项必须少于 %{max} 个。" - named_poll_must_have_less_options: "%{name}投票的选项必须少于 %{max} 个。" + default_poll_must_have_less_options: + other: "投票选项必须少于%{count}个。" + named_poll_must_have_less_options: + other: "投票“%{name}”的选项必须少于%{count}个。" default_poll_must_have_different_options: "投票必须有不同的选项。" named_poll_must_have_different_options: "%{name}投票的选项必须有不同的选项。" default_poll_with_multiple_choices_has_invalid_parameters: "多选投票有无效选项。" @@ -31,3 +33,5 @@ zh_CN: poll_must_be_open_to_vote: "投票必须开启。" topic_must_be_open_to_toggle_status: "主题必须开放才能改变状态。" only_staff_or_op_can_toggle_status: "只有职员成员或者发布投票的人才能改变投票状态。" + email: + link_to_poll: "点击查看投票。" diff --git a/plugins/poll/db/migrate/20151016163051_merge_polls_votes.rb b/plugins/poll/db/migrate/20151016163051_merge_polls_votes.rb new file mode 100644 index 00000000000..17e6459e120 --- /dev/null +++ b/plugins/poll/db/migrate/20151016163051_merge_polls_votes.rb @@ -0,0 +1,20 @@ +class MergePollsVotes < ActiveRecord::Migration + + def up + PostCustomField.where(name: "polls").order(:post_id).pluck(:post_id).each do |post_id| + polls_votes = {} + PostCustomField.where(post_id: post_id).where("name LIKE 'polls-votes-%'").find_each do |pcf| + user_id = pcf.name["polls-votes-".size..-1] + polls_votes["#{user_id}"] = ::JSON.parse(pcf.value||"{}") + end + + pcf = PostCustomField.find_or_create_by(name: "polls-votes", post_id: post_id) + pcf.value = ::JSON.parse(pcf.value||"{}").merge(polls_votes).to_json + pcf.save + end + end + + def down + end + +end diff --git a/plugins/poll/db/migrate/20160321164925_close_polls_in_closed_topics.rb b/plugins/poll/db/migrate/20160321164925_close_polls_in_closed_topics.rb new file mode 100644 index 00000000000..5ca969c68dc --- /dev/null +++ b/plugins/poll/db/migrate/20160321164925_close_polls_in_closed_topics.rb @@ -0,0 +1,18 @@ +class ClosePollsInClosedTopics < ActiveRecord::Migration + + def up + PostCustomField.joins(post: :topic) + .where("post_custom_fields.name = 'polls'") + .where("topics.closed") + .find_each do |pcf| + polls = ::JSON.parse(pcf.value || "{}") + polls.values.each { |poll| poll["status"] = "closed" } + pcf.value = polls.to_json + pcf.save + end + end + + def down + end + +end diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb index 0f061e5b5f1..ce251f91a25 100644 --- a/plugins/poll/plugin.rb +++ b/plugins/poll/plugin.rb @@ -22,9 +22,17 @@ DEFAULT_POLL_NAME ||= "poll".freeze after_initialize do - # remove "Vote Now!" & "Show Results" links in emails - Email::Styles.register_plugin_style do |fragment| - fragment.css(".poll a.cast-votes, .poll a.toggle-results").each(&:remove) + # turn polls into a link in emails + Email::Styles.register_plugin_style do |fragment, opts| + post = Post.find_by(id: opts[:post_id]) rescue nil + if post.nil? || post.trashed? + fragment.css(".poll").each(&:remove) + else + post_url = "#{Discourse.base_url}#{post.url}" + fragment.css(".poll").each do |poll| + poll.replace "

    #{I18n.t("poll.email.link_to_poll")}

    " + end + end end module ::DiscoursePoll @@ -46,8 +54,8 @@ after_initialize do raise StandardError.new I18n.t("poll.post_is_deleted") end - # topic must be open - if post.topic.try(:closed) || post.topic.try(:archived) + # topic must not be archived + if post.topic.try(:archived) raise StandardError.new I18n.t("poll.topic_must_be_open_to_vote") end @@ -66,24 +74,25 @@ after_initialize do raise StandardError.new I18n.t("poll.requires_at_least_1_valid_option") if options.empty? - votes = post.custom_fields["#{VOTES_CUSTOM_FIELD}-#{user_id}"] || {} - vote = votes[poll_name] || [] + poll["voters"] = 0 + all_options = Hash.new(0) - # increment counters only when the user hasn't casted a vote yet - poll["voters"] += 1 if vote.size == 0 + post.custom_fields[VOTES_CUSTOM_FIELD] ||= {} + post.custom_fields[VOTES_CUSTOM_FIELD]["#{user_id}"] ||= {} + post.custom_fields[VOTES_CUSTOM_FIELD]["#{user_id}"][poll_name] = options - poll["options"].each do |option| - option["votes"] -= 1 if vote.include?(option["id"]) - option["votes"] += 1 if options.include?(option["id"]) + post.custom_fields[VOTES_CUSTOM_FIELD].each do |_, user_votes| + next unless votes = user_votes[poll_name] + votes.each { |option| all_options[option] += 1 } + poll["voters"] += 1 if (available_options & votes.to_set).size > 0 end - votes[poll_name] = options + poll["options"].each { |o| o["votes"] = all_options[o["id"]] } post.custom_fields[POLLS_CUSTOM_FIELD] = polls - post.custom_fields["#{VOTES_CUSTOM_FIELD}-#{user_id}"] = votes post.save_custom_fields(true) - MessageBus.publish("/polls/#{post_id}", { polls: polls }) + MessageBus.publish("/polls/#{post.topic_id}", { post_id: post_id, polls: polls }) return [poll, options] end @@ -98,8 +107,8 @@ after_initialize do raise StandardError.new I18n.t("poll.post_is_deleted") end - # topic must be open - if post.topic.try(:closed) || post.topic.try(:archived) + # topic must not be archived + if post.topic.try(:archived) raise StandardError.new I18n.t("poll.topic_must_be_open_to_toggle_status") end @@ -119,7 +128,7 @@ after_initialize do post.save_custom_fields(true) - MessageBus.publish("/polls/#{post_id}", { polls: polls }) + MessageBus.publish("/polls/#{post.topic_id}", {post_id: post.id, polls: polls }) polls[poll_name] end @@ -257,8 +266,8 @@ after_initialize do # maximum # of options if poll["options"].size > SiteSetting.poll_maximum_options poll["name"] == DEFAULT_POLL_NAME ? - self.errors.add(:base, I18n.t("poll.default_poll_must_have_less_options", max: SiteSetting.poll_maximum_options)) : - self.errors.add(:base, I18n.t("poll.named_poll_must_have_less_options", name: poll["name"], max: SiteSetting.poll_maximum_options)) + self.errors.add(:base, I18n.t("poll.default_poll_must_have_less_options", count: SiteSetting.poll_maximum_options)) : + self.errors.add(:base, I18n.t("poll.named_poll_must_have_less_options", name: poll["name"], count: SiteSetting.poll_maximum_options)) return end @@ -293,8 +302,10 @@ after_initialize do # are the polls different? if polls.keys != previous_polls.keys || current_options != previous_options + has_votes = previous_polls.keys.map { |p| previous_polls[p]["voters"].to_i }.sum > 0 + # outside of the 5-minute edit window? - if post.created_at < 5.minutes.ago + if post.created_at < 5.minutes.ago && has_votes # cannot add/remove/rename polls if polls.keys.sort != previous_polls.keys.sort post.errors.add(:base, I18n.t("poll.cannot_change_polls_after_5_minutes")) @@ -305,7 +316,7 @@ after_initialize do if User.staff.pluck(:id).include?(post.last_editor_id) # staff can only edit options polls.each_key do |poll_name| - if polls[poll_name]["options"].size != previous_polls[poll_name]["options"].size + if polls[poll_name]["options"].size != previous_polls[poll_name]["options"].size && previous_polls[poll_name]["voters"].to_i > 0 post.errors.add(:base, I18n.t("poll.staff_cannot_add_or_remove_options_after_5_minutes")) return end @@ -323,9 +334,7 @@ after_initialize do # when the # of options has changed, reset all the votes if polls[poll_name]["options"].size != previous_polls[poll_name]["options"].size - PostCustomField.where(post_id: post.id) - .where("name LIKE '#{VOTES_CUSTOM_FIELD}-%'") - .destroy_all + PostCustomField.where(post_id: post.id, name: VOTES_CUSTOM_FIELD).destroy_all post.clear_custom_fields next end @@ -341,7 +350,7 @@ after_initialize do post.save_custom_fields(true) # publish the changes - MessageBus.publish("/polls/#{post.id}", { polls: polls }) + MessageBus.publish("/polls/#{post.topic_id}", { post_id: post.id, polls: polls }) end end else @@ -352,23 +361,28 @@ after_initialize do end Post.register_custom_field_type(POLLS_CUSTOM_FIELD, :json) - Post.register_custom_field_type("#{VOTES_CUSTOM_FIELD}-*", :json) + Post.register_custom_field_type(VOTES_CUSTOM_FIELD, :json) TopicView.add_post_custom_fields_whitelister do |user| - whitelisted = [POLLS_CUSTOM_FIELD] - whitelisted << "#{VOTES_CUSTOM_FIELD}-#{user.id}" if user - whitelisted + user ? [POLLS_CUSTOM_FIELD, VOTES_CUSTOM_FIELD] : [POLLS_CUSTOM_FIELD] end # tells the front-end we have a poll for that post on(:post_created) do |post| next if post.is_first_post? || post.custom_fields[POLLS_CUSTOM_FIELD].blank? - MessageBus.publish("/polls", { post_id: post.id }) + MessageBus.publish("/polls/#{post.topic_id}", { + post_id: post.id, + polls: post.custom_fields[POLLS_CUSTOM_FIELD]}) end add_to_serializer(:post, :polls, false) { post_custom_fields[POLLS_CUSTOM_FIELD] } add_to_serializer(:post, :include_polls?) { post_custom_fields.present? && post_custom_fields[POLLS_CUSTOM_FIELD].present? } - add_to_serializer(:post, :polls_votes, false) { post_custom_fields["#{VOTES_CUSTOM_FIELD}-#{scope.user.id}"] } - add_to_serializer(:post, :include_polls_votes?) { scope.user && post_custom_fields.present? && post_custom_fields["#{VOTES_CUSTOM_FIELD}-#{scope.user.id}"].present? } + add_to_serializer(:post, :polls_votes, false) { post_custom_fields[VOTES_CUSTOM_FIELD]["#{scope.user.id}"] } + add_to_serializer(:post, :include_polls_votes?) do + return unless scope.user + return unless post_custom_fields.present? + return unless post_custom_fields[VOTES_CUSTOM_FIELD].present? + post_custom_fields[VOTES_CUSTOM_FIELD].has_key?("#{scope.user.id}") + end end diff --git a/plugins/poll/spec/controllers/polls_controller_spec.rb b/plugins/poll/spec/controllers/polls_controller_spec.rb index bcac39c71f1..b1679d7d6ee 100644 --- a/plugins/poll/spec/controllers/polls_controller_spec.rb +++ b/plugins/poll/spec/controllers/polls_controller_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe ::DiscoursePoll::PollsController do routes { ::DiscoursePoll::Engine.routes } @@ -41,12 +41,10 @@ describe ::DiscoursePoll::PollsController do expect(json["poll"]["options"][1]["votes"]).to eq(1) end - it "ensures topic is not closed" do + it "works even if topic is closed" do topic.update_attribute(:closed, true) - xhr :put, :vote, { post_id: poll.id, poll_name: "poll", options: ["A"] } - expect(response).not_to be_success - json = ::JSON.parse(response.body) - expect(json["errors"][0]).to eq(I18n.t("poll.topic_must_be_open_to_vote")) + xhr :put, :vote, { post_id: poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] } + expect(response).to be_success end it "ensures topic is not archived" do diff --git a/plugins/poll/spec/controllers/posts_controller_spec.rb b/plugins/poll/spec/controllers/posts_controller_spec.rb index a47d7def267..bc86459637f 100644 --- a/plugins/poll/spec/controllers/posts_controller_spec.rb +++ b/plugins/poll/spec/controllers/posts_controller_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe PostsController do let!(:user) { log_in } @@ -50,7 +50,7 @@ describe PostsController do expect(response).not_to be_success json = ::JSON.parse(response.body) - expect(json["errors"][0]).to eq(I18n.t("poll.default_poll_must_have_less_options", max: SiteSetting.poll_maximum_options)) + expect(json["errors"][0]).to eq(I18n.t("poll.default_poll_must_have_less_options", count: SiteSetting.poll_maximum_options)) end it "should have valid parameters" do @@ -126,26 +126,30 @@ describe PostsController do end end - it "OP cannot change the options" do - xhr :put, :update, { id: post_id, post: { raw: new_option } } - expect(response).not_to be_success - json = ::JSON.parse(response.body) - expect(json["errors"][0]).to eq(I18n.t("poll.op_cannot_edit_options_after_5_minutes")) - end + describe "with no vote" do - it "staff can change the options" do - log_in_user(Fabricate(:moderator)) - xhr :put, :update, { id: post_id, post: { raw: new_option } } - expect(response).to be_success - json = ::JSON.parse(response.body) - expect(json["post"]["polls"]["poll"]["options"][1]["html"]).to eq("C") - end + it "OP can change the options" do + xhr :put, :update, { id: post_id, post: { raw: new_option } } + expect(response).to be_success + json = ::JSON.parse(response.body) + expect(json["post"]["polls"]["poll"]["options"][1]["html"]).to eq("C") + end + + it "staff can change the options" do + log_in_user(Fabricate(:moderator)) + xhr :put, :update, { id: post_id, post: { raw: new_option } } + expect(response).to be_success + json = ::JSON.parse(response.body) + expect(json["post"]["polls"]["poll"]["options"][1]["html"]).to eq("C") + end + + it "support changes on the post" do + xhr :put, :update, { id: post_id, post: { raw: updated } } + expect(response).to be_success + json = ::JSON.parse(response.body) + expect(json["post"]["cooked"]).to match("before") + end - it "support changes on the post" do - xhr :put, :update, { id: post_id, post: { raw: updated } } - expect(response).to be_success - json = ::JSON.parse(response.body) - expect(json["post"]["cooked"]).to match("before") end describe "with at least one vote" do @@ -154,6 +158,21 @@ describe PostsController do DiscoursePoll::Poll.vote(post_id, "poll", ["5c24fc1df56d764b550ceae1b9319125"], user.id) end + it "OP cannot change the options" do + xhr :put, :update, { id: post_id, post: { raw: new_option } } + expect(response).not_to be_success + json = ::JSON.parse(response.body) + expect(json["errors"][0]).to eq(I18n.t("poll.op_cannot_edit_options_after_5_minutes")) + end + + it "staff can change the options" do + log_in_user(Fabricate(:moderator)) + xhr :put, :update, { id: post_id, post: { raw: new_option } } + expect(response).to be_success + json = ::JSON.parse(response.body) + expect(json["post"]["polls"]["poll"]["options"][1]["html"]).to eq("C") + end + it "support changes on the post" do xhr :put, :update, { id: post_id, post: { raw: updated } } expect(response).to be_success diff --git a/public/403.ar.html b/public/403.ar.html index 12d30120a46..96bd196b8f9 100644 --- a/public/403.ar.html +++ b/public/403.ar.html @@ -18,9 +18,9 @@

    403

    -

    لا يمكنك عرض المحتوى!

    +

    لا يمكنك عرض هذا المصدر !

    -

    سيتم تبديل الصفحة الحالية بصفحة ديسكورس 403 مخصصة.

    +

    سيتم استبدال الصفحة الحالية بصفحة ديسكورس 403 مخصصة.

    diff --git a/public/403.gl.html b/public/403.gl.html new file mode 100644 index 00000000000..4a2ac9508de --- /dev/null +++ b/public/403.gl.html @@ -0,0 +1,26 @@ + + +Non podes facer iso (403) + + + + +
    +

    403

    +

    Non podes ver este recurso.

    + +

    Substituirase pola páxina 403 personalizada de Discourse.

    +
    + + diff --git a/public/403.it.html b/public/403.it.html index 7ed27adc48e..da8e9cba4eb 100644 --- a/public/403.it.html +++ b/public/403.it.html @@ -1,6 +1,6 @@ -Accesso negato (403) +Non puoi farlo (403) + + +
    +

    403

    +

    Nemáte oprávnenie na zobrazenie týchto údajov!

    + +

    Toto bude nahradené vlastnou Discourse 403 stránkou.

    +
    + + diff --git a/public/403.vi.html b/public/403.vi.html new file mode 100644 index 00000000000..20f37705289 --- /dev/null +++ b/public/403.vi.html @@ -0,0 +1,26 @@ + + + Bạn không thể làm được điều đó (403) + + + + +
    +

    403

    +

    Bạn không thể xem tài nguyên đó!

    + +

    Trang này sẽ được thay thế bằng một trang lỗi 403 tùy chỉnh của Discourse.

    +
    + + diff --git a/public/403.zh_CN.html b/public/403.zh_CN.html index 90823fbe79b..3adf6ed2bc7 100644 --- a/public/403.zh_CN.html +++ b/public/403.zh_CN.html @@ -1,6 +1,6 @@ -操作行为禁止(403) +禁止操作行为 (403) + + + +
    +

    Rexeitouse o cambio pretendido.

    +

    Se cadra tentaches cambiar algo ao que non tes acceso.

    +
    + + diff --git a/public/422.sk.html b/public/422.sk.html new file mode 100644 index 00000000000..36e3684c140 --- /dev/null +++ b/public/422.sk.html @@ -0,0 +1,25 @@ + + +Požadovaná zmena bola zamietnutá (422) + + + + + +
    +

    Požadovaná zmena bola zamietnutá.

    +

    Možno ste skúšali zmeniť niečo k čomu nemáte prístup.

    +
    + + diff --git a/public/422.sv.html b/public/422.sv.html index 5a287bf23bb..20682002596 100644 --- a/public/422.sv.html +++ b/public/422.sv.html @@ -18,7 +18,7 @@
    -

    Förändringen du ville göra nekades.

    +

    Ändringen du ville utföra nekades.

    Kanske försökte du ändra något du inte har åtkomst till.

    diff --git a/public/422.vi.html b/public/422.vi.html new file mode 100644 index 00000000000..082a63b385b --- /dev/null +++ b/public/422.vi.html @@ -0,0 +1,25 @@ + + +Thay đổi bạn muốn thực hiện đã bị từ chối (422) + + + + + +
    +

    Thay đổi bạn muốn thực hiện đã bị từ chối.

    +

    Có thể bạn đã cố thay đổi một số tính năng mà bạn không thể truy cập.

    +
    + + diff --git a/public/500.gl.html b/public/500.gl.html new file mode 100644 index 00000000000..998201529d2 --- /dev/null +++ b/public/500.gl.html @@ -0,0 +1,12 @@ + + +Vaites - Erro 500 + + + +

    Vaites!

    +

    O software con que funciona este foro de discusión atopou un problema inesperado. Sentimos as molestias.

    +

    Rexistrouse información detallada do erro e xerouse unha notificación automática. Revisarémolo.

    +

    Non é precisa ningunha outra medida. Con todo, se persisten as condicións do erro, podes subministrar información adicional, incluíndo os pasos para reproducilo, publicando un tema de discusión na metacategoría.

    + + diff --git a/public/500.sk.html b/public/500.sk.html new file mode 100644 index 00000000000..625a96497d3 --- /dev/null +++ b/public/500.sk.html @@ -0,0 +1,12 @@ + + +Oops - Chyba 500 + + + +

    Oops

    +

    V softvéri poháňajúcom toto diskusné fórum došlo k neočakávanej chybe. Ospravedlňujeme sa za spôsobené nepríjemnosti.

    +

    Podrobnosti o chybe boli zaznamenané a vygenerovalo sa automatické upozornenie. Pozrieme sa na to.

    +

    Nie je potrebná žiadna ďalšia akcia. Ak však chyba pretrváva, môžete poskytnúť dodatočné informácie, vrátane krokov vedúcich k navodeniu chyby založením diskusnej témy v meta kategórií.

    + + diff --git a/public/500.vi.html b/public/500.vi.html new file mode 100644 index 00000000000..79b74efd3f2 --- /dev/null +++ b/public/500.vi.html @@ -0,0 +1,12 @@ + + +Ôi - Lỗi 500 + + + +

    Ối

    +

    Phần mềm chạy diễn đàn thảo luận này bất ngờ gặp sự cố không mong muốn. Chúng tôi rất xin lỗi vì sự bất tiện này.

    +

    Thông tin chi tiết về lỗi đã được ghi lại và thông báo tự động đã được tạo. Chúng tôi sẽ xem xét lỗi này.

    +

    Không cần tiến hành bất cứ hành động nào. Tuy nhiên, nếu lỗi này vẫn tiếp tục, bạn có thể cung cấp thêm thông tin chi tiết bao gồm các bước để tái tạo lỗi hoặc tạo một thảo luận trên meta category.

    + + diff --git a/public/500.zh_CN.html b/public/500.zh_CN.html index 94801fa5ac5..1dc3a0faf25 100644 --- a/public/500.zh_CN.html +++ b/public/500.zh_CN.html @@ -1,12 +1,12 @@ -啊哦 - 500 错误 +噢!错误500

    啊哦

    这个论坛的软件遇到了未知问题。抱歉给你带来的不便。

    错误的详情的已经被记录下来,并且自动生成了一个通知给我们,我们会尽快处理。

    -

    暂时不需采取任何操作。然而,如果错误仍然出现,请提供一些额外的详细信息,包括重现这个错误的步骤,发表至站务分类的讨论主题中。

    +

    暂时不需采取任何操作。如果错误仍然出现,请提供一些额外的详细信息,包括重现这个错误的步骤,发表至站务分类的讨论主题中。

    diff --git a/public/503.gl.html b/public/503.gl.html new file mode 100644 index 00000000000..7ffae6239a9 --- /dev/null +++ b/public/503.gl.html @@ -0,0 +1,11 @@ + + +Este sitio está en mantemento - Discourse.org + + + +

    Estamos realizando tarefas planificadas de mantemento

    +

    Por favor, téntao dentro duns minutos.

    +

    Sentimos as molestias.

    + + diff --git a/public/503.ro.html b/public/503.ro.html index e1ecd7c1bb0..2752fc234ed 100644 --- a/public/503.ro.html +++ b/public/503.ro.html @@ -4,7 +4,7 @@ -

    Momentan suntem indisponibili pentru o mentenanţă a site-ului planificată

    +

    Momentan suntem indisponibili pentru o mentenanţă planificată a site-ului

    Te rog verifică din nou în câteva minute.

    Ne cerem scuze pentru inconvenienţă!

    diff --git a/public/503.sk.html b/public/503.sk.html new file mode 100644 index 00000000000..eae9f09226d --- /dev/null +++ b/public/503.sk.html @@ -0,0 +1,11 @@ + + +Na stránke sa práve vykonáva údržba. + + + +

    Stránka je momentálne nedostupná z dôvodu plánovanej údržby

    +

    Skúste prosím znova o niekoľko minút.

    +

    Ospravedlňujeme sa za spôsobené nepríjemnosti.

    + + diff --git a/public/503.vi.html b/public/503.vi.html new file mode 100644 index 00000000000..a952fd3a5a6 --- /dev/null +++ b/public/503.vi.html @@ -0,0 +1,11 @@ + + +Trang đang được bảo trì- Discourse.org + + + +

    Trang tạm dừng dịch vụ để bảo trì dịch vụ

    +

    Vui lòng quay lại sau vài phút.

    +

    Xin lỗi về sự bất tiện này!

    + + diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 25dd82c5c1c..00000000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/images/avatar.png b/public/images/avatar.png new file mode 100644 index 00000000000..c5b3b496914 Binary files /dev/null and b/public/images/avatar.png differ diff --git a/public/images/d-logo-sketch-small.png b/public/images/d-logo-sketch-small.png index b7b8d0a6ab4..c8434cee11f 100644 Binary files a/public/images/d-logo-sketch-small.png and b/public/images/d-logo-sketch-small.png differ diff --git a/public/images/d-logo-sketch.png b/public/images/d-logo-sketch.png index 114121bceec..5783edabeec 100644 Binary files a/public/images/d-logo-sketch.png and b/public/images/d-logo-sketch.png differ diff --git a/public/images/default-apple-touch-icon.png b/public/images/default-apple-touch-icon.png index 132968a873d..4eec351f1f0 100644 Binary files a/public/images/default-apple-touch-icon.png and b/public/images/default-apple-touch-icon.png differ diff --git a/public/images/default-favicon.png b/public/images/default-favicon.png index f28bdd0c723..03c32d0db8f 100644 Binary files a/public/images/default-favicon.png and b/public/images/default-favicon.png differ diff --git a/public/images/emoji/apple/+1.png b/public/images/emoji/apple/+1.png index e1d89aada6a..05beee9a189 100644 Binary files a/public/images/emoji/apple/+1.png and b/public/images/emoji/apple/+1.png differ diff --git a/public/images/emoji/apple/-1.png b/public/images/emoji/apple/-1.png index b67e9e1e145..8bf40ca3156 100644 Binary files a/public/images/emoji/apple/-1.png and b/public/images/emoji/apple/-1.png differ diff --git a/public/images/emoji/apple/100.png b/public/images/emoji/apple/100.png index 225e308772f..7c4c5ca1814 100644 Binary files a/public/images/emoji/apple/100.png and b/public/images/emoji/apple/100.png differ diff --git a/public/images/emoji/apple/1234.png b/public/images/emoji/apple/1234.png index 22e560c1165..e26f00b2c6c 100644 Binary files a/public/images/emoji/apple/1234.png and b/public/images/emoji/apple/1234.png differ diff --git a/public/images/emoji/apple/8ball.png b/public/images/emoji/apple/8ball.png index 8d7bf27a1ee..3fa227a4cad 100644 Binary files a/public/images/emoji/apple/8ball.png and b/public/images/emoji/apple/8ball.png differ diff --git a/public/images/emoji/apple/a.png b/public/images/emoji/apple/a.png index cb9931af4db..f5a7a43ebd4 100644 Binary files a/public/images/emoji/apple/a.png and b/public/images/emoji/apple/a.png differ diff --git a/public/images/emoji/apple/ab.png b/public/images/emoji/apple/ab.png index 5edb24891ed..b517fcafd96 100644 Binary files a/public/images/emoji/apple/ab.png and b/public/images/emoji/apple/ab.png differ diff --git a/public/images/emoji/apple/abc.png b/public/images/emoji/apple/abc.png index be0db0d75ad..01a6f390279 100644 Binary files a/public/images/emoji/apple/abc.png and b/public/images/emoji/apple/abc.png differ diff --git a/public/images/emoji/apple/abcd.png b/public/images/emoji/apple/abcd.png index 72713ba6611..c2ccf4272cf 100644 Binary files a/public/images/emoji/apple/abcd.png and b/public/images/emoji/apple/abcd.png differ diff --git a/public/images/emoji/apple/accept.png b/public/images/emoji/apple/accept.png index 8d7128c825f..3b9235582c5 100644 Binary files a/public/images/emoji/apple/accept.png and b/public/images/emoji/apple/accept.png differ diff --git a/public/images/emoji/apple/aerial_tramway.png b/public/images/emoji/apple/aerial_tramway.png index 2a00e86920d..69b45ba6282 100644 Binary files a/public/images/emoji/apple/aerial_tramway.png and b/public/images/emoji/apple/aerial_tramway.png differ diff --git a/public/images/emoji/apple/airplane.png b/public/images/emoji/apple/airplane.png index 01f79a7e28c..399e9921418 100644 Binary files a/public/images/emoji/apple/airplane.png and b/public/images/emoji/apple/airplane.png differ diff --git a/public/images/emoji/apple/airplane_arriving.png b/public/images/emoji/apple/airplane_arriving.png new file mode 100644 index 00000000000..5b7bfeb8010 Binary files /dev/null and b/public/images/emoji/apple/airplane_arriving.png differ diff --git a/public/images/emoji/apple/airplane_departure.png b/public/images/emoji/apple/airplane_departure.png new file mode 100644 index 00000000000..3d2f9379efa Binary files /dev/null and b/public/images/emoji/apple/airplane_departure.png differ diff --git a/public/images/emoji/apple/airplane_small.png b/public/images/emoji/apple/airplane_small.png new file mode 100644 index 00000000000..a3a07e0f37e Binary files /dev/null and b/public/images/emoji/apple/airplane_small.png differ diff --git a/public/images/emoji/apple/alarm_clock.png b/public/images/emoji/apple/alarm_clock.png index 74b3151e408..d3263269d2e 100644 Binary files a/public/images/emoji/apple/alarm_clock.png and b/public/images/emoji/apple/alarm_clock.png differ diff --git a/public/images/emoji/apple/alembic.png b/public/images/emoji/apple/alembic.png new file mode 100644 index 00000000000..1e47e111a44 Binary files /dev/null and b/public/images/emoji/apple/alembic.png differ diff --git a/public/images/emoji/apple/alien.png b/public/images/emoji/apple/alien.png index 1cc33ff0a78..92955eb830c 100644 Binary files a/public/images/emoji/apple/alien.png and b/public/images/emoji/apple/alien.png differ diff --git a/public/images/emoji/apple/ambulance.png b/public/images/emoji/apple/ambulance.png index 50addc4b40b..25cf2ce04ea 100644 Binary files a/public/images/emoji/apple/ambulance.png and b/public/images/emoji/apple/ambulance.png differ diff --git a/public/images/emoji/apple/amphora.png b/public/images/emoji/apple/amphora.png new file mode 100644 index 00000000000..35f87691441 Binary files /dev/null and b/public/images/emoji/apple/amphora.png differ diff --git a/public/images/emoji/apple/anchor.png b/public/images/emoji/apple/anchor.png index 7761da427b9..085a3fcfd51 100644 Binary files a/public/images/emoji/apple/anchor.png and b/public/images/emoji/apple/anchor.png differ diff --git a/public/images/emoji/apple/angel.png b/public/images/emoji/apple/angel.png index 9f67e6830cc..0ef415698cd 100644 Binary files a/public/images/emoji/apple/angel.png and b/public/images/emoji/apple/angel.png differ diff --git a/public/images/emoji/apple/anger.png b/public/images/emoji/apple/anger.png index a4d5128dfe9..8c7854cdf02 100644 Binary files a/public/images/emoji/apple/anger.png and b/public/images/emoji/apple/anger.png differ diff --git a/public/images/emoji/apple/anger_right.png b/public/images/emoji/apple/anger_right.png new file mode 100644 index 00000000000..bb53b70b071 Binary files /dev/null and b/public/images/emoji/apple/anger_right.png differ diff --git a/public/images/emoji/apple/angry.png b/public/images/emoji/apple/angry.png index d60e7220dca..3942ec357c8 100644 Binary files a/public/images/emoji/apple/angry.png and b/public/images/emoji/apple/angry.png differ diff --git a/public/images/emoji/apple/anguished.png b/public/images/emoji/apple/anguished.png index 470b36572f8..95f0ce18400 100644 Binary files a/public/images/emoji/apple/anguished.png and b/public/images/emoji/apple/anguished.png differ diff --git a/public/images/emoji/apple/ant.png b/public/images/emoji/apple/ant.png index 4d619880a23..f63ba49102e 100644 Binary files a/public/images/emoji/apple/ant.png and b/public/images/emoji/apple/ant.png differ diff --git a/public/images/emoji/apple/apple.png b/public/images/emoji/apple/apple.png index 7e8777802bf..80050b1d6ca 100644 Binary files a/public/images/emoji/apple/apple.png and b/public/images/emoji/apple/apple.png differ diff --git a/public/images/emoji/apple/aquarius.png b/public/images/emoji/apple/aquarius.png index 034fbbd2c4b..87d5c8b3389 100644 Binary files a/public/images/emoji/apple/aquarius.png and b/public/images/emoji/apple/aquarius.png differ diff --git a/public/images/emoji/apple/aries.png b/public/images/emoji/apple/aries.png index eae37f5584d..7295ff24ff6 100644 Binary files a/public/images/emoji/apple/aries.png and b/public/images/emoji/apple/aries.png differ diff --git a/public/images/emoji/apple/arrow_backward.png b/public/images/emoji/apple/arrow_backward.png index 86a99c5290b..c69aa7b1fa2 100644 Binary files a/public/images/emoji/apple/arrow_backward.png and b/public/images/emoji/apple/arrow_backward.png differ diff --git a/public/images/emoji/apple/arrow_double_down.png b/public/images/emoji/apple/arrow_double_down.png index cfb82e6bfc5..9c9f436f846 100644 Binary files a/public/images/emoji/apple/arrow_double_down.png and b/public/images/emoji/apple/arrow_double_down.png differ diff --git a/public/images/emoji/apple/arrow_double_up.png b/public/images/emoji/apple/arrow_double_up.png index 1caa5747425..d1390ea1eb4 100644 Binary files a/public/images/emoji/apple/arrow_double_up.png and b/public/images/emoji/apple/arrow_double_up.png differ diff --git a/public/images/emoji/apple/arrow_down.png b/public/images/emoji/apple/arrow_down.png index 3fd0141fe98..e8892bfa04f 100644 Binary files a/public/images/emoji/apple/arrow_down.png and b/public/images/emoji/apple/arrow_down.png differ diff --git a/public/images/emoji/apple/arrow_down_small.png b/public/images/emoji/apple/arrow_down_small.png index c7886bd9edd..73cd96a241e 100644 Binary files a/public/images/emoji/apple/arrow_down_small.png and b/public/images/emoji/apple/arrow_down_small.png differ diff --git a/public/images/emoji/apple/arrow_forward.png b/public/images/emoji/apple/arrow_forward.png index 5e5b3ee397a..b7ff1e358bf 100644 Binary files a/public/images/emoji/apple/arrow_forward.png and b/public/images/emoji/apple/arrow_forward.png differ diff --git a/public/images/emoji/apple/arrow_heading_down.png b/public/images/emoji/apple/arrow_heading_down.png index bad0e05880e..29130cc9719 100644 Binary files a/public/images/emoji/apple/arrow_heading_down.png and b/public/images/emoji/apple/arrow_heading_down.png differ diff --git a/public/images/emoji/apple/arrow_heading_up.png b/public/images/emoji/apple/arrow_heading_up.png index 66f3e0672ed..e3ff8bfe31b 100644 Binary files a/public/images/emoji/apple/arrow_heading_up.png and b/public/images/emoji/apple/arrow_heading_up.png differ diff --git a/public/images/emoji/apple/arrow_left.png b/public/images/emoji/apple/arrow_left.png index 14698d51430..23e9a915e60 100644 Binary files a/public/images/emoji/apple/arrow_left.png and b/public/images/emoji/apple/arrow_left.png differ diff --git a/public/images/emoji/apple/arrow_lower_left.png b/public/images/emoji/apple/arrow_lower_left.png index 693f882781f..5eb3ecbb26d 100644 Binary files a/public/images/emoji/apple/arrow_lower_left.png and b/public/images/emoji/apple/arrow_lower_left.png differ diff --git a/public/images/emoji/apple/arrow_lower_right.png b/public/images/emoji/apple/arrow_lower_right.png index 84e22ceded1..18cee61f5a8 100644 Binary files a/public/images/emoji/apple/arrow_lower_right.png and b/public/images/emoji/apple/arrow_lower_right.png differ diff --git a/public/images/emoji/apple/arrow_right.png b/public/images/emoji/apple/arrow_right.png index ab3fe368823..88fc5bfae5e 100644 Binary files a/public/images/emoji/apple/arrow_right.png and b/public/images/emoji/apple/arrow_right.png differ diff --git a/public/images/emoji/apple/arrow_right_hook.png b/public/images/emoji/apple/arrow_right_hook.png index 0190f904b87..fa4b0514fd8 100644 Binary files a/public/images/emoji/apple/arrow_right_hook.png and b/public/images/emoji/apple/arrow_right_hook.png differ diff --git a/public/images/emoji/apple/arrow_up.png b/public/images/emoji/apple/arrow_up.png index e462a4f8488..69b614d1f8d 100644 Binary files a/public/images/emoji/apple/arrow_up.png and b/public/images/emoji/apple/arrow_up.png differ diff --git a/public/images/emoji/apple/arrow_up_down.png b/public/images/emoji/apple/arrow_up_down.png index 9b313192f20..945818d5fcf 100644 Binary files a/public/images/emoji/apple/arrow_up_down.png and b/public/images/emoji/apple/arrow_up_down.png differ diff --git a/public/images/emoji/apple/arrow_up_small.png b/public/images/emoji/apple/arrow_up_small.png index 56154249f9e..f1cbf17146c 100644 Binary files a/public/images/emoji/apple/arrow_up_small.png and b/public/images/emoji/apple/arrow_up_small.png differ diff --git a/public/images/emoji/apple/arrow_upper_left.png b/public/images/emoji/apple/arrow_upper_left.png index 5f88e0a4d26..468a0cb2a79 100644 Binary files a/public/images/emoji/apple/arrow_upper_left.png and b/public/images/emoji/apple/arrow_upper_left.png differ diff --git a/public/images/emoji/apple/arrow_upper_right.png b/public/images/emoji/apple/arrow_upper_right.png index cb956fc863d..fe50ee94ba7 100644 Binary files a/public/images/emoji/apple/arrow_upper_right.png and b/public/images/emoji/apple/arrow_upper_right.png differ diff --git a/public/images/emoji/apple/arrows_clockwise.png b/public/images/emoji/apple/arrows_clockwise.png index 6c3608ba864..0e6f65e9d32 100644 Binary files a/public/images/emoji/apple/arrows_clockwise.png and b/public/images/emoji/apple/arrows_clockwise.png differ diff --git a/public/images/emoji/apple/arrows_counterclockwise.png b/public/images/emoji/apple/arrows_counterclockwise.png index f4d55f05214..07ef8acc31b 100644 Binary files a/public/images/emoji/apple/arrows_counterclockwise.png and b/public/images/emoji/apple/arrows_counterclockwise.png differ diff --git a/public/images/emoji/apple/art.png b/public/images/emoji/apple/art.png index e2da2e8db54..f345c87b46a 100644 Binary files a/public/images/emoji/apple/art.png and b/public/images/emoji/apple/art.png differ diff --git a/public/images/emoji/apple/articulated_lorry.png b/public/images/emoji/apple/articulated_lorry.png index c26dd706787..007ec2e0cb6 100644 Binary files a/public/images/emoji/apple/articulated_lorry.png and b/public/images/emoji/apple/articulated_lorry.png differ diff --git a/public/images/emoji/apple/astonished.png b/public/images/emoji/apple/astonished.png index fe80340f4d0..686fa1d80ee 100644 Binary files a/public/images/emoji/apple/astonished.png and b/public/images/emoji/apple/astonished.png differ diff --git a/public/images/emoji/apple/athletic_shoe.png b/public/images/emoji/apple/athletic_shoe.png index 36767601dbe..7b6134e1355 100644 Binary files a/public/images/emoji/apple/athletic_shoe.png and b/public/images/emoji/apple/athletic_shoe.png differ diff --git a/public/images/emoji/apple/atm.png b/public/images/emoji/apple/atm.png index 93e57ac41ac..b64881b61cc 100644 Binary files a/public/images/emoji/apple/atm.png and b/public/images/emoji/apple/atm.png differ diff --git a/public/images/emoji/apple/atom.png b/public/images/emoji/apple/atom.png new file mode 100644 index 00000000000..21841ed3170 Binary files /dev/null and b/public/images/emoji/apple/atom.png differ diff --git a/public/images/emoji/apple/b.png b/public/images/emoji/apple/b.png index d22733d040a..b7197fc9354 100644 Binary files a/public/images/emoji/apple/b.png and b/public/images/emoji/apple/b.png differ diff --git a/public/images/emoji/apple/baby.png b/public/images/emoji/apple/baby.png index f4bb76fe456..0c0c3ae8273 100644 Binary files a/public/images/emoji/apple/baby.png and b/public/images/emoji/apple/baby.png differ diff --git a/public/images/emoji/apple/baby_bottle.png b/public/images/emoji/apple/baby_bottle.png index 351b4775911..97a3df19bfe 100644 Binary files a/public/images/emoji/apple/baby_bottle.png and b/public/images/emoji/apple/baby_bottle.png differ diff --git a/public/images/emoji/apple/baby_chick.png b/public/images/emoji/apple/baby_chick.png index b80a07df370..e87ac1f41c4 100644 Binary files a/public/images/emoji/apple/baby_chick.png and b/public/images/emoji/apple/baby_chick.png differ diff --git a/public/images/emoji/apple/baby_symbol.png b/public/images/emoji/apple/baby_symbol.png index 73cde87a211..f8dc1e60a0f 100644 Binary files a/public/images/emoji/apple/baby_symbol.png and b/public/images/emoji/apple/baby_symbol.png differ diff --git a/public/images/emoji/apple/back.png b/public/images/emoji/apple/back.png index f1e401c540c..5e77f33952a 100644 Binary files a/public/images/emoji/apple/back.png and b/public/images/emoji/apple/back.png differ diff --git a/public/images/emoji/apple/badminton.png b/public/images/emoji/apple/badminton.png new file mode 100644 index 00000000000..47704637424 Binary files /dev/null and b/public/images/emoji/apple/badminton.png differ diff --git a/public/images/emoji/apple/baggage_claim.png b/public/images/emoji/apple/baggage_claim.png index 5fb3bbfee6d..d09348bcdde 100644 Binary files a/public/images/emoji/apple/baggage_claim.png and b/public/images/emoji/apple/baggage_claim.png differ diff --git a/public/images/emoji/apple/balloon.png b/public/images/emoji/apple/balloon.png index b23ace295e5..60dab8acee2 100644 Binary files a/public/images/emoji/apple/balloon.png and b/public/images/emoji/apple/balloon.png differ diff --git a/public/images/emoji/apple/ballot_box.png b/public/images/emoji/apple/ballot_box.png new file mode 100644 index 00000000000..e2ccbccd0b1 Binary files /dev/null and b/public/images/emoji/apple/ballot_box.png differ diff --git a/public/images/emoji/apple/ballot_box_with_check.png b/public/images/emoji/apple/ballot_box_with_check.png index b3cfd720989..b3e3de194ee 100644 Binary files a/public/images/emoji/apple/ballot_box_with_check.png and b/public/images/emoji/apple/ballot_box_with_check.png differ diff --git a/public/images/emoji/apple/bamboo.png b/public/images/emoji/apple/bamboo.png index 34e06476a14..b099cef0265 100644 Binary files a/public/images/emoji/apple/bamboo.png and b/public/images/emoji/apple/bamboo.png differ diff --git a/public/images/emoji/apple/banana.png b/public/images/emoji/apple/banana.png index 0e1fdefab03..413f381fa45 100644 Binary files a/public/images/emoji/apple/banana.png and b/public/images/emoji/apple/banana.png differ diff --git a/public/images/emoji/apple/bangbang.png b/public/images/emoji/apple/bangbang.png index 8a5728d0cfe..befd4d7f1ad 100644 Binary files a/public/images/emoji/apple/bangbang.png and b/public/images/emoji/apple/bangbang.png differ diff --git a/public/images/emoji/apple/bank.png b/public/images/emoji/apple/bank.png index cdf03d1ba46..82ad15fa2d1 100644 Binary files a/public/images/emoji/apple/bank.png and b/public/images/emoji/apple/bank.png differ diff --git a/public/images/emoji/apple/bar_chart.png b/public/images/emoji/apple/bar_chart.png index e3cdecc0e3d..ae99e9edf27 100644 Binary files a/public/images/emoji/apple/bar_chart.png and b/public/images/emoji/apple/bar_chart.png differ diff --git a/public/images/emoji/apple/barber.png b/public/images/emoji/apple/barber.png index cacd2555ecb..07abf74d1a8 100644 Binary files a/public/images/emoji/apple/barber.png and b/public/images/emoji/apple/barber.png differ diff --git a/public/images/emoji/apple/baseball.png b/public/images/emoji/apple/baseball.png index 32c0d6b112e..aecd2012381 100644 Binary files a/public/images/emoji/apple/baseball.png and b/public/images/emoji/apple/baseball.png differ diff --git a/public/images/emoji/apple/basketball.png b/public/images/emoji/apple/basketball.png index 96b575797d0..019695ab281 100644 Binary files a/public/images/emoji/apple/basketball.png and b/public/images/emoji/apple/basketball.png differ diff --git a/public/images/emoji/apple/basketball_player.png b/public/images/emoji/apple/basketball_player.png new file mode 100644 index 00000000000..244f3dd463a Binary files /dev/null and b/public/images/emoji/apple/basketball_player.png differ diff --git a/public/images/emoji/apple/bath.png b/public/images/emoji/apple/bath.png index 2c100a9cc9d..54787b13596 100644 Binary files a/public/images/emoji/apple/bath.png and b/public/images/emoji/apple/bath.png differ diff --git a/public/images/emoji/apple/bathtub.png b/public/images/emoji/apple/bathtub.png index 7e6cef09257..2e521fe5a1b 100644 Binary files a/public/images/emoji/apple/bathtub.png and b/public/images/emoji/apple/bathtub.png differ diff --git a/public/images/emoji/apple/battery.png b/public/images/emoji/apple/battery.png index 1d09b988e86..af5f26a0905 100644 Binary files a/public/images/emoji/apple/battery.png and b/public/images/emoji/apple/battery.png differ diff --git a/public/images/emoji/apple/beach.png b/public/images/emoji/apple/beach.png new file mode 100644 index 00000000000..68014050162 Binary files /dev/null and b/public/images/emoji/apple/beach.png differ diff --git a/public/images/emoji/apple/beach_umbrella.png b/public/images/emoji/apple/beach_umbrella.png new file mode 100644 index 00000000000..8e380d70dab Binary files /dev/null and b/public/images/emoji/apple/beach_umbrella.png differ diff --git a/public/images/emoji/apple/bear.png b/public/images/emoji/apple/bear.png index 4896c9abb46..925b5232864 100644 Binary files a/public/images/emoji/apple/bear.png and b/public/images/emoji/apple/bear.png differ diff --git a/public/images/emoji/apple/bed.png b/public/images/emoji/apple/bed.png new file mode 100644 index 00000000000..94261fa5a7f Binary files /dev/null and b/public/images/emoji/apple/bed.png differ diff --git a/public/images/emoji/apple/bee.png b/public/images/emoji/apple/bee.png index 8ae23dfbcfc..159767fd7f6 100644 Binary files a/public/images/emoji/apple/bee.png and b/public/images/emoji/apple/bee.png differ diff --git a/public/images/emoji/apple/beer.png b/public/images/emoji/apple/beer.png index b5ce16b2e90..702cafa7963 100644 Binary files a/public/images/emoji/apple/beer.png and b/public/images/emoji/apple/beer.png differ diff --git a/public/images/emoji/apple/beers.png b/public/images/emoji/apple/beers.png index 22e5fc51b46..43ed5c9a3ef 100644 Binary files a/public/images/emoji/apple/beers.png and b/public/images/emoji/apple/beers.png differ diff --git a/public/images/emoji/apple/beetle.png b/public/images/emoji/apple/beetle.png index 52bb51f26c7..ef0cd194986 100644 Binary files a/public/images/emoji/apple/beetle.png and b/public/images/emoji/apple/beetle.png differ diff --git a/public/images/emoji/apple/beginner.png b/public/images/emoji/apple/beginner.png index 8813761dc5a..d8dd3b2b6f4 100644 Binary files a/public/images/emoji/apple/beginner.png and b/public/images/emoji/apple/beginner.png differ diff --git a/public/images/emoji/apple/bell.png b/public/images/emoji/apple/bell.png index db9f0e2f572..4802b3031b5 100644 Binary files a/public/images/emoji/apple/bell.png and b/public/images/emoji/apple/bell.png differ diff --git a/public/images/emoji/apple/bellhop.png b/public/images/emoji/apple/bellhop.png new file mode 100644 index 00000000000..77900e72150 Binary files /dev/null and b/public/images/emoji/apple/bellhop.png differ diff --git a/public/images/emoji/apple/bento.png b/public/images/emoji/apple/bento.png index 89236d6f082..870caf2ccc6 100644 Binary files a/public/images/emoji/apple/bento.png and b/public/images/emoji/apple/bento.png differ diff --git a/public/images/emoji/apple/bicyclist.png b/public/images/emoji/apple/bicyclist.png index 5c65e336017..d5ff1d25cad 100644 Binary files a/public/images/emoji/apple/bicyclist.png and b/public/images/emoji/apple/bicyclist.png differ diff --git a/public/images/emoji/apple/bike.png b/public/images/emoji/apple/bike.png index 5d989ee5bdc..15943410084 100644 Binary files a/public/images/emoji/apple/bike.png and b/public/images/emoji/apple/bike.png differ diff --git a/public/images/emoji/apple/bikini.png b/public/images/emoji/apple/bikini.png index ad1ce7ce88d..6566eea744d 100644 Binary files a/public/images/emoji/apple/bikini.png and b/public/images/emoji/apple/bikini.png differ diff --git a/public/images/emoji/apple/biohazard.png b/public/images/emoji/apple/biohazard.png new file mode 100644 index 00000000000..9fae39a8444 Binary files /dev/null and b/public/images/emoji/apple/biohazard.png differ diff --git a/public/images/emoji/apple/bird.png b/public/images/emoji/apple/bird.png index 51a3a36d656..f7e03019c17 100644 Binary files a/public/images/emoji/apple/bird.png and b/public/images/emoji/apple/bird.png differ diff --git a/public/images/emoji/apple/birthday.png b/public/images/emoji/apple/birthday.png index cf40216a085..5ca25183af6 100644 Binary files a/public/images/emoji/apple/birthday.png and b/public/images/emoji/apple/birthday.png differ diff --git a/public/images/emoji/apple/black_circle.png b/public/images/emoji/apple/black_circle.png index 3b929ddf7ab..e5541f80c93 100644 Binary files a/public/images/emoji/apple/black_circle.png and b/public/images/emoji/apple/black_circle.png differ diff --git a/public/images/emoji/apple/black_joker.png b/public/images/emoji/apple/black_joker.png index 1a83d7b97ff..83396364478 100644 Binary files a/public/images/emoji/apple/black_joker.png and b/public/images/emoji/apple/black_joker.png differ diff --git a/public/images/emoji/apple/black_large_square.png b/public/images/emoji/apple/black_large_square.png index d0b82fd684f..31f626e9137 100644 Binary files a/public/images/emoji/apple/black_large_square.png and b/public/images/emoji/apple/black_large_square.png differ diff --git a/public/images/emoji/apple/black_medium_small_square.png b/public/images/emoji/apple/black_medium_small_square.png index bb65f1580dc..a028beea053 100644 Binary files a/public/images/emoji/apple/black_medium_small_square.png and b/public/images/emoji/apple/black_medium_small_square.png differ diff --git a/public/images/emoji/apple/black_medium_square.png b/public/images/emoji/apple/black_medium_square.png index d0b82fd684f..31f626e9137 100644 Binary files a/public/images/emoji/apple/black_medium_square.png and b/public/images/emoji/apple/black_medium_square.png differ diff --git a/public/images/emoji/apple/black_nib.png b/public/images/emoji/apple/black_nib.png index 760e2fafb03..579e3ba5347 100644 Binary files a/public/images/emoji/apple/black_nib.png and b/public/images/emoji/apple/black_nib.png differ diff --git a/public/images/emoji/apple/black_small_square.png b/public/images/emoji/apple/black_small_square.png index 73ad0e6f302..997ae3f0aea 100644 Binary files a/public/images/emoji/apple/black_small_square.png and b/public/images/emoji/apple/black_small_square.png differ diff --git a/public/images/emoji/apple/black_square_button.png b/public/images/emoji/apple/black_square_button.png index 27af757d898..d2d1fc3abee 100644 Binary files a/public/images/emoji/apple/black_square_button.png and b/public/images/emoji/apple/black_square_button.png differ diff --git a/public/images/emoji/apple/blossom.png b/public/images/emoji/apple/blossom.png index 679a61e2243..7f390897503 100644 Binary files a/public/images/emoji/apple/blossom.png and b/public/images/emoji/apple/blossom.png differ diff --git a/public/images/emoji/apple/blowfish.png b/public/images/emoji/apple/blowfish.png index d480416c517..d378bdc031c 100644 Binary files a/public/images/emoji/apple/blowfish.png and b/public/images/emoji/apple/blowfish.png differ diff --git a/public/images/emoji/apple/blue_book.png b/public/images/emoji/apple/blue_book.png index de037bcdd4d..089dd74de13 100644 Binary files a/public/images/emoji/apple/blue_book.png and b/public/images/emoji/apple/blue_book.png differ diff --git a/public/images/emoji/apple/blue_car.png b/public/images/emoji/apple/blue_car.png index a5d2700fc12..e0410f48c6d 100644 Binary files a/public/images/emoji/apple/blue_car.png and b/public/images/emoji/apple/blue_car.png differ diff --git a/public/images/emoji/apple/blue_heart.png b/public/images/emoji/apple/blue_heart.png index 749b639c2ff..73b7709b0de 100644 Binary files a/public/images/emoji/apple/blue_heart.png and b/public/images/emoji/apple/blue_heart.png differ diff --git a/public/images/emoji/apple/blush.png b/public/images/emoji/apple/blush.png index 78953c9fee2..5a831ac9290 100644 Binary files a/public/images/emoji/apple/blush.png and b/public/images/emoji/apple/blush.png differ diff --git a/public/images/emoji/apple/boar.png b/public/images/emoji/apple/boar.png index ce8dc6cb838..2974cecd679 100644 Binary files a/public/images/emoji/apple/boar.png and b/public/images/emoji/apple/boar.png differ diff --git a/public/images/emoji/apple/boat.png b/public/images/emoji/apple/boat.png index a1755990150..eb287c5b6ab 100644 Binary files a/public/images/emoji/apple/boat.png and b/public/images/emoji/apple/boat.png differ diff --git a/public/images/emoji/apple/bomb.png b/public/images/emoji/apple/bomb.png index 9f163f4e7a5..48d02ab0df2 100644 Binary files a/public/images/emoji/apple/bomb.png and b/public/images/emoji/apple/bomb.png differ diff --git a/public/images/emoji/apple/book.png b/public/images/emoji/apple/book.png index 3393a9b3c87..ecb6184aed3 100644 Binary files a/public/images/emoji/apple/book.png and b/public/images/emoji/apple/book.png differ diff --git a/public/images/emoji/apple/bookmark.png b/public/images/emoji/apple/bookmark.png index 6807f58fe92..2f0e8dea901 100644 Binary files a/public/images/emoji/apple/bookmark.png and b/public/images/emoji/apple/bookmark.png differ diff --git a/public/images/emoji/apple/bookmark_tabs.png b/public/images/emoji/apple/bookmark_tabs.png index 3ad3cc803ce..dc534001761 100644 Binary files a/public/images/emoji/apple/bookmark_tabs.png and b/public/images/emoji/apple/bookmark_tabs.png differ diff --git a/public/images/emoji/apple/books.png b/public/images/emoji/apple/books.png index ca7a047da5a..e239d2172d3 100644 Binary files a/public/images/emoji/apple/books.png and b/public/images/emoji/apple/books.png differ diff --git a/public/images/emoji/apple/boom.png b/public/images/emoji/apple/boom.png index c16baf2aecf..99addec4c4b 100644 Binary files a/public/images/emoji/apple/boom.png and b/public/images/emoji/apple/boom.png differ diff --git a/public/images/emoji/apple/boot.png b/public/images/emoji/apple/boot.png index f835a6041ec..aaf8924672b 100644 Binary files a/public/images/emoji/apple/boot.png and b/public/images/emoji/apple/boot.png differ diff --git a/public/images/emoji/apple/bouquet.png b/public/images/emoji/apple/bouquet.png index e2c55468c7d..57fea11af96 100644 Binary files a/public/images/emoji/apple/bouquet.png and b/public/images/emoji/apple/bouquet.png differ diff --git a/public/images/emoji/apple/bow.png b/public/images/emoji/apple/bow.png index 166bab5e87c..43b6207ed8c 100644 Binary files a/public/images/emoji/apple/bow.png and b/public/images/emoji/apple/bow.png differ diff --git a/public/images/emoji/apple/bow_and_arrow.png b/public/images/emoji/apple/bow_and_arrow.png new file mode 100644 index 00000000000..b0c8684ddd2 Binary files /dev/null and b/public/images/emoji/apple/bow_and_arrow.png differ diff --git a/public/images/emoji/apple/bowling.png b/public/images/emoji/apple/bowling.png index 5ebda9d7cff..8b969e1cafd 100644 Binary files a/public/images/emoji/apple/bowling.png and b/public/images/emoji/apple/bowling.png differ diff --git a/public/images/emoji/apple/boy.png b/public/images/emoji/apple/boy.png index 847b1698c2a..fcc54102860 100644 Binary files a/public/images/emoji/apple/boy.png and b/public/images/emoji/apple/boy.png differ diff --git a/public/images/emoji/apple/bread.png b/public/images/emoji/apple/bread.png index 9c3f40d3285..44c918a079b 100644 Binary files a/public/images/emoji/apple/bread.png and b/public/images/emoji/apple/bread.png differ diff --git a/public/images/emoji/apple/bride_with_veil.png b/public/images/emoji/apple/bride_with_veil.png index 5d3e746d863..a1b102b2746 100644 Binary files a/public/images/emoji/apple/bride_with_veil.png and b/public/images/emoji/apple/bride_with_veil.png differ diff --git a/public/images/emoji/apple/bridge_at_night.png b/public/images/emoji/apple/bridge_at_night.png index d9933f50535..7127b29b958 100644 Binary files a/public/images/emoji/apple/bridge_at_night.png and b/public/images/emoji/apple/bridge_at_night.png differ diff --git a/public/images/emoji/apple/briefcase.png b/public/images/emoji/apple/briefcase.png index 11b89c5380e..4426203b226 100644 Binary files a/public/images/emoji/apple/briefcase.png and b/public/images/emoji/apple/briefcase.png differ diff --git a/public/images/emoji/apple/broken_heart.png b/public/images/emoji/apple/broken_heart.png index 0d8d8255296..e6ad962ba0e 100644 Binary files a/public/images/emoji/apple/broken_heart.png and b/public/images/emoji/apple/broken_heart.png differ diff --git a/public/images/emoji/apple/bug.png b/public/images/emoji/apple/bug.png index 14b0d890a50..8a246a24a8c 100644 Binary files a/public/images/emoji/apple/bug.png and b/public/images/emoji/apple/bug.png differ diff --git a/public/images/emoji/apple/bulb.png b/public/images/emoji/apple/bulb.png index abb3d62f1a0..ed48aa202ec 100644 Binary files a/public/images/emoji/apple/bulb.png and b/public/images/emoji/apple/bulb.png differ diff --git a/public/images/emoji/apple/bullettrain_front.png b/public/images/emoji/apple/bullettrain_front.png index 573259ac7f4..7eb8a87ebe8 100644 Binary files a/public/images/emoji/apple/bullettrain_front.png and b/public/images/emoji/apple/bullettrain_front.png differ diff --git a/public/images/emoji/apple/bullettrain_side.png b/public/images/emoji/apple/bullettrain_side.png index cc3a3791d5a..6a55cceeee7 100644 Binary files a/public/images/emoji/apple/bullettrain_side.png and b/public/images/emoji/apple/bullettrain_side.png differ diff --git a/public/images/emoji/apple/burrito.png b/public/images/emoji/apple/burrito.png new file mode 100644 index 00000000000..18f30ae5a63 Binary files /dev/null and b/public/images/emoji/apple/burrito.png differ diff --git a/public/images/emoji/apple/bus.png b/public/images/emoji/apple/bus.png index 44149941e54..239bbada462 100644 Binary files a/public/images/emoji/apple/bus.png and b/public/images/emoji/apple/bus.png differ diff --git a/public/images/emoji/apple/busstop.png b/public/images/emoji/apple/busstop.png index 1b6d9de136d..30f11b5be26 100644 Binary files a/public/images/emoji/apple/busstop.png and b/public/images/emoji/apple/busstop.png differ diff --git a/public/images/emoji/apple/bust_in_silhouette.png b/public/images/emoji/apple/bust_in_silhouette.png index c48af4ab9b5..68135444cbb 100644 Binary files a/public/images/emoji/apple/bust_in_silhouette.png and b/public/images/emoji/apple/bust_in_silhouette.png differ diff --git a/public/images/emoji/apple/busts_in_silhouette.png b/public/images/emoji/apple/busts_in_silhouette.png index 4c70f9365e3..5b76c5b671d 100644 Binary files a/public/images/emoji/apple/busts_in_silhouette.png and b/public/images/emoji/apple/busts_in_silhouette.png differ diff --git a/public/images/emoji/apple/cactus.png b/public/images/emoji/apple/cactus.png index cc8e4b1e9e9..157b09e00ca 100644 Binary files a/public/images/emoji/apple/cactus.png and b/public/images/emoji/apple/cactus.png differ diff --git a/public/images/emoji/apple/cake.png b/public/images/emoji/apple/cake.png index f5396ca0610..cc1d3ebe1a0 100644 Binary files a/public/images/emoji/apple/cake.png and b/public/images/emoji/apple/cake.png differ diff --git a/public/images/emoji/apple/calendar.png b/public/images/emoji/apple/calendar.png index a6ba1537f65..17011ce9762 100644 Binary files a/public/images/emoji/apple/calendar.png and b/public/images/emoji/apple/calendar.png differ diff --git a/public/images/emoji/apple/calendar_spiral.png b/public/images/emoji/apple/calendar_spiral.png new file mode 100644 index 00000000000..9f0d0f20a04 Binary files /dev/null and b/public/images/emoji/apple/calendar_spiral.png differ diff --git a/public/images/emoji/apple/calling.png b/public/images/emoji/apple/calling.png index 773a17cce5b..a54fe1c8a3e 100644 Binary files a/public/images/emoji/apple/calling.png and b/public/images/emoji/apple/calling.png differ diff --git a/public/images/emoji/apple/camel.png b/public/images/emoji/apple/camel.png index b73a80df413..d76fb634d11 100644 Binary files a/public/images/emoji/apple/camel.png and b/public/images/emoji/apple/camel.png differ diff --git a/public/images/emoji/apple/camera.png b/public/images/emoji/apple/camera.png index 2b5ca74a16a..6d6167bd02b 100644 Binary files a/public/images/emoji/apple/camera.png and b/public/images/emoji/apple/camera.png differ diff --git a/public/images/emoji/apple/camera_with_flash.png b/public/images/emoji/apple/camera_with_flash.png new file mode 100644 index 00000000000..1689926e262 Binary files /dev/null and b/public/images/emoji/apple/camera_with_flash.png differ diff --git a/public/images/emoji/apple/camping.png b/public/images/emoji/apple/camping.png new file mode 100644 index 00000000000..463e13d77c2 Binary files /dev/null and b/public/images/emoji/apple/camping.png differ diff --git a/public/images/emoji/apple/cancer.png b/public/images/emoji/apple/cancer.png index 053ccd09968..69861d869d0 100644 Binary files a/public/images/emoji/apple/cancer.png and b/public/images/emoji/apple/cancer.png differ diff --git a/public/images/emoji/apple/candle.png b/public/images/emoji/apple/candle.png new file mode 100644 index 00000000000..db982079ab5 Binary files /dev/null and b/public/images/emoji/apple/candle.png differ diff --git a/public/images/emoji/apple/candy.png b/public/images/emoji/apple/candy.png index 2e5c316b4ae..79e58f148b6 100644 Binary files a/public/images/emoji/apple/candy.png and b/public/images/emoji/apple/candy.png differ diff --git a/public/images/emoji/apple/capital_abcd.png b/public/images/emoji/apple/capital_abcd.png index ba09fb2cf39..3bab75ef344 100644 Binary files a/public/images/emoji/apple/capital_abcd.png and b/public/images/emoji/apple/capital_abcd.png differ diff --git a/public/images/emoji/apple/capricorn.png b/public/images/emoji/apple/capricorn.png index 04b4c6ef71f..a462de1ed06 100644 Binary files a/public/images/emoji/apple/capricorn.png and b/public/images/emoji/apple/capricorn.png differ diff --git a/public/images/emoji/apple/car.png b/public/images/emoji/apple/car.png index b5d86c4defb..071fae4501a 100644 Binary files a/public/images/emoji/apple/car.png and b/public/images/emoji/apple/car.png differ diff --git a/public/images/emoji/apple/card_box.png b/public/images/emoji/apple/card_box.png new file mode 100644 index 00000000000..851c3b2f5ca Binary files /dev/null and b/public/images/emoji/apple/card_box.png differ diff --git a/public/images/emoji/apple/card_index.png b/public/images/emoji/apple/card_index.png index bfaed033e5c..c673bcb17a5 100644 Binary files a/public/images/emoji/apple/card_index.png and b/public/images/emoji/apple/card_index.png differ diff --git a/public/images/emoji/apple/carousel_horse.png b/public/images/emoji/apple/carousel_horse.png index 17b1eb51fb2..9c847f73e92 100644 Binary files a/public/images/emoji/apple/carousel_horse.png and b/public/images/emoji/apple/carousel_horse.png differ diff --git a/public/images/emoji/apple/cat.png b/public/images/emoji/apple/cat.png index 147dad43cf3..9e08fee545a 100644 Binary files a/public/images/emoji/apple/cat.png and b/public/images/emoji/apple/cat.png differ diff --git a/public/images/emoji/apple/cat2.png b/public/images/emoji/apple/cat2.png index 5192f8c56ab..be2665d81f5 100644 Binary files a/public/images/emoji/apple/cat2.png and b/public/images/emoji/apple/cat2.png differ diff --git a/public/images/emoji/apple/cd.png b/public/images/emoji/apple/cd.png index 4efc27dcd55..290d945f838 100644 Binary files a/public/images/emoji/apple/cd.png and b/public/images/emoji/apple/cd.png differ diff --git a/public/images/emoji/apple/chains.png b/public/images/emoji/apple/chains.png new file mode 100644 index 00000000000..dadbfd85e56 Binary files /dev/null and b/public/images/emoji/apple/chains.png differ diff --git a/public/images/emoji/apple/champagne.png b/public/images/emoji/apple/champagne.png new file mode 100644 index 00000000000..21240556f6c Binary files /dev/null and b/public/images/emoji/apple/champagne.png differ diff --git a/public/images/emoji/apple/chart.png b/public/images/emoji/apple/chart.png index ee8e8f81bf0..68a62f3666d 100644 Binary files a/public/images/emoji/apple/chart.png and b/public/images/emoji/apple/chart.png differ diff --git a/public/images/emoji/apple/chart_with_downwards_trend.png b/public/images/emoji/apple/chart_with_downwards_trend.png index 2698a455c33..c4caeef99df 100644 Binary files a/public/images/emoji/apple/chart_with_downwards_trend.png and b/public/images/emoji/apple/chart_with_downwards_trend.png differ diff --git a/public/images/emoji/apple/chart_with_upwards_trend.png b/public/images/emoji/apple/chart_with_upwards_trend.png index cdc80d4b622..80ba49b0d14 100644 Binary files a/public/images/emoji/apple/chart_with_upwards_trend.png and b/public/images/emoji/apple/chart_with_upwards_trend.png differ diff --git a/public/images/emoji/apple/checkered_flag.png b/public/images/emoji/apple/checkered_flag.png index ff10a1d54ea..e1a2d19245a 100644 Binary files a/public/images/emoji/apple/checkered_flag.png and b/public/images/emoji/apple/checkered_flag.png differ diff --git a/public/images/emoji/apple/cheese.png b/public/images/emoji/apple/cheese.png new file mode 100644 index 00000000000..f397292e14c Binary files /dev/null and b/public/images/emoji/apple/cheese.png differ diff --git a/public/images/emoji/apple/cherries.png b/public/images/emoji/apple/cherries.png index 16c48b03234..3a07560758b 100644 Binary files a/public/images/emoji/apple/cherries.png and b/public/images/emoji/apple/cherries.png differ diff --git a/public/images/emoji/apple/cherry_blossom.png b/public/images/emoji/apple/cherry_blossom.png index abb6c3d998a..5ad229a3351 100644 Binary files a/public/images/emoji/apple/cherry_blossom.png and b/public/images/emoji/apple/cherry_blossom.png differ diff --git a/public/images/emoji/apple/chestnut.png b/public/images/emoji/apple/chestnut.png index fc87a879722..2a701177bcf 100644 Binary files a/public/images/emoji/apple/chestnut.png and b/public/images/emoji/apple/chestnut.png differ diff --git a/public/images/emoji/apple/chicken.png b/public/images/emoji/apple/chicken.png index 6243d8d6116..fad2445a745 100644 Binary files a/public/images/emoji/apple/chicken.png and b/public/images/emoji/apple/chicken.png differ diff --git a/public/images/emoji/apple/children_crossing.png b/public/images/emoji/apple/children_crossing.png index c0f34d93d16..edef251fcd7 100644 Binary files a/public/images/emoji/apple/children_crossing.png and b/public/images/emoji/apple/children_crossing.png differ diff --git a/public/images/emoji/apple/chipmunk.png b/public/images/emoji/apple/chipmunk.png new file mode 100644 index 00000000000..e3d61a3810d Binary files /dev/null and b/public/images/emoji/apple/chipmunk.png differ diff --git a/public/images/emoji/apple/chocolate_bar.png b/public/images/emoji/apple/chocolate_bar.png index 3d78c230f37..ebe856e81bf 100644 Binary files a/public/images/emoji/apple/chocolate_bar.png and b/public/images/emoji/apple/chocolate_bar.png differ diff --git a/public/images/emoji/apple/christmas_tree.png b/public/images/emoji/apple/christmas_tree.png index cf58a681e5e..7cb544871ef 100644 Binary files a/public/images/emoji/apple/christmas_tree.png and b/public/images/emoji/apple/christmas_tree.png differ diff --git a/public/images/emoji/apple/church.png b/public/images/emoji/apple/church.png index 99109f9f64f..2297e999d13 100644 Binary files a/public/images/emoji/apple/church.png and b/public/images/emoji/apple/church.png differ diff --git a/public/images/emoji/apple/cinema.png b/public/images/emoji/apple/cinema.png index 0cd0135c9e2..1a54e0626f1 100644 Binary files a/public/images/emoji/apple/cinema.png and b/public/images/emoji/apple/cinema.png differ diff --git a/public/images/emoji/apple/circus_tent.png b/public/images/emoji/apple/circus_tent.png index fe663269e1b..f2b9cb54b0c 100644 Binary files a/public/images/emoji/apple/circus_tent.png and b/public/images/emoji/apple/circus_tent.png differ diff --git a/public/images/emoji/apple/city_dusk.png b/public/images/emoji/apple/city_dusk.png new file mode 100644 index 00000000000..e9841b41484 Binary files /dev/null and b/public/images/emoji/apple/city_dusk.png differ diff --git a/public/images/emoji/apple/city_sunrise.png b/public/images/emoji/apple/city_sunrise.png index ac0380f47f4..1734e0de467 100644 Binary files a/public/images/emoji/apple/city_sunrise.png and b/public/images/emoji/apple/city_sunrise.png differ diff --git a/public/images/emoji/apple/city_sunset.png b/public/images/emoji/apple/city_sunset.png index 2eb5754e1a5..b22139a827f 100644 Binary files a/public/images/emoji/apple/city_sunset.png and b/public/images/emoji/apple/city_sunset.png differ diff --git a/public/images/emoji/apple/cityscape.png b/public/images/emoji/apple/cityscape.png new file mode 100644 index 00000000000..023e1049d7c Binary files /dev/null and b/public/images/emoji/apple/cityscape.png differ diff --git a/public/images/emoji/apple/cl.png b/public/images/emoji/apple/cl.png index 25dc41637fe..556ed6d4eae 100644 Binary files a/public/images/emoji/apple/cl.png and b/public/images/emoji/apple/cl.png differ diff --git a/public/images/emoji/apple/clap.png b/public/images/emoji/apple/clap.png index 44f6d3130fd..bda5909b31e 100644 Binary files a/public/images/emoji/apple/clap.png and b/public/images/emoji/apple/clap.png differ diff --git a/public/images/emoji/apple/clapper.png b/public/images/emoji/apple/clapper.png index 9c793bd9692..7e0182660fc 100644 Binary files a/public/images/emoji/apple/clapper.png and b/public/images/emoji/apple/clapper.png differ diff --git a/public/images/emoji/apple/classical_building.png b/public/images/emoji/apple/classical_building.png new file mode 100644 index 00000000000..dd1bc910e8c Binary files /dev/null and b/public/images/emoji/apple/classical_building.png differ diff --git a/public/images/emoji/apple/clipboard.png b/public/images/emoji/apple/clipboard.png index c01719f86c7..ba5c67b6456 100644 Binary files a/public/images/emoji/apple/clipboard.png and b/public/images/emoji/apple/clipboard.png differ diff --git a/public/images/emoji/apple/clock.png b/public/images/emoji/apple/clock.png new file mode 100644 index 00000000000..03bbdaf3c89 Binary files /dev/null and b/public/images/emoji/apple/clock.png differ diff --git a/public/images/emoji/apple/clock1.png b/public/images/emoji/apple/clock1.png index 1826755cf45..28f660a0758 100644 Binary files a/public/images/emoji/apple/clock1.png and b/public/images/emoji/apple/clock1.png differ diff --git a/public/images/emoji/apple/clock10.png b/public/images/emoji/apple/clock10.png index e7c1c2bf727..2dc44e8d893 100644 Binary files a/public/images/emoji/apple/clock10.png and b/public/images/emoji/apple/clock10.png differ diff --git a/public/images/emoji/apple/clock1030.png b/public/images/emoji/apple/clock1030.png index e39d969b330..94f59501dc6 100644 Binary files a/public/images/emoji/apple/clock1030.png and b/public/images/emoji/apple/clock1030.png differ diff --git a/public/images/emoji/apple/clock11.png b/public/images/emoji/apple/clock11.png index 8dd8ad49e18..faababb8f5b 100644 Binary files a/public/images/emoji/apple/clock11.png and b/public/images/emoji/apple/clock11.png differ diff --git a/public/images/emoji/apple/clock1130.png b/public/images/emoji/apple/clock1130.png index dd1fd36ce16..1b7db339c10 100644 Binary files a/public/images/emoji/apple/clock1130.png and b/public/images/emoji/apple/clock1130.png differ diff --git a/public/images/emoji/apple/clock12.png b/public/images/emoji/apple/clock12.png index 1bf191d5c7f..c09a632d61f 100644 Binary files a/public/images/emoji/apple/clock12.png and b/public/images/emoji/apple/clock12.png differ diff --git a/public/images/emoji/apple/clock1230.png b/public/images/emoji/apple/clock1230.png index ab5262fe7dc..5fc14653dc4 100644 Binary files a/public/images/emoji/apple/clock1230.png and b/public/images/emoji/apple/clock1230.png differ diff --git a/public/images/emoji/apple/clock130.png b/public/images/emoji/apple/clock130.png index 9b0787837cb..2ed88c5a446 100644 Binary files a/public/images/emoji/apple/clock130.png and b/public/images/emoji/apple/clock130.png differ diff --git a/public/images/emoji/apple/clock2.png b/public/images/emoji/apple/clock2.png index c3548f80ba4..5e91548b17b 100644 Binary files a/public/images/emoji/apple/clock2.png and b/public/images/emoji/apple/clock2.png differ diff --git a/public/images/emoji/apple/clock230.png b/public/images/emoji/apple/clock230.png index 537f9677aca..c3d412cb2de 100644 Binary files a/public/images/emoji/apple/clock230.png and b/public/images/emoji/apple/clock230.png differ diff --git a/public/images/emoji/apple/clock3.png b/public/images/emoji/apple/clock3.png index ba5c1f439b5..b297e3a25fb 100644 Binary files a/public/images/emoji/apple/clock3.png and b/public/images/emoji/apple/clock3.png differ diff --git a/public/images/emoji/apple/clock330.png b/public/images/emoji/apple/clock330.png index 13bc5b51452..3690bfcee60 100644 Binary files a/public/images/emoji/apple/clock330.png and b/public/images/emoji/apple/clock330.png differ diff --git a/public/images/emoji/apple/clock4.png b/public/images/emoji/apple/clock4.png index 02a7fe2f1bd..f6082076dc3 100644 Binary files a/public/images/emoji/apple/clock4.png and b/public/images/emoji/apple/clock4.png differ diff --git a/public/images/emoji/apple/clock430.png b/public/images/emoji/apple/clock430.png index e213359a11e..5128b29281f 100644 Binary files a/public/images/emoji/apple/clock430.png and b/public/images/emoji/apple/clock430.png differ diff --git a/public/images/emoji/apple/clock5.png b/public/images/emoji/apple/clock5.png index f6e00cc61b5..d2afd880b03 100644 Binary files a/public/images/emoji/apple/clock5.png and b/public/images/emoji/apple/clock5.png differ diff --git a/public/images/emoji/apple/clock530.png b/public/images/emoji/apple/clock530.png index 7305fc046a8..e88250e7e99 100644 Binary files a/public/images/emoji/apple/clock530.png and b/public/images/emoji/apple/clock530.png differ diff --git a/public/images/emoji/apple/clock6.png b/public/images/emoji/apple/clock6.png index 4fccf99807e..b2b80f982f1 100644 Binary files a/public/images/emoji/apple/clock6.png and b/public/images/emoji/apple/clock6.png differ diff --git a/public/images/emoji/apple/clock630.png b/public/images/emoji/apple/clock630.png index 100736c1fd7..b11d43ab003 100644 Binary files a/public/images/emoji/apple/clock630.png and b/public/images/emoji/apple/clock630.png differ diff --git a/public/images/emoji/apple/clock7.png b/public/images/emoji/apple/clock7.png index 159bfdaa716..2eab5c3b2e9 100644 Binary files a/public/images/emoji/apple/clock7.png and b/public/images/emoji/apple/clock7.png differ diff --git a/public/images/emoji/apple/clock730.png b/public/images/emoji/apple/clock730.png index c7cb99a0f0d..3761cd53120 100644 Binary files a/public/images/emoji/apple/clock730.png and b/public/images/emoji/apple/clock730.png differ diff --git a/public/images/emoji/apple/clock8.png b/public/images/emoji/apple/clock8.png index d481c1c57da..35cf193e5ca 100644 Binary files a/public/images/emoji/apple/clock8.png and b/public/images/emoji/apple/clock8.png differ diff --git a/public/images/emoji/apple/clock830.png b/public/images/emoji/apple/clock830.png index 85ef43d7ef4..f5671ce76f3 100644 Binary files a/public/images/emoji/apple/clock830.png and b/public/images/emoji/apple/clock830.png differ diff --git a/public/images/emoji/apple/clock9.png b/public/images/emoji/apple/clock9.png index d2114ff4b85..9c261938857 100644 Binary files a/public/images/emoji/apple/clock9.png and b/public/images/emoji/apple/clock9.png differ diff --git a/public/images/emoji/apple/clock930.png b/public/images/emoji/apple/clock930.png index 34af13eb603..7fdecf5b9ab 100644 Binary files a/public/images/emoji/apple/clock930.png and b/public/images/emoji/apple/clock930.png differ diff --git a/public/images/emoji/apple/closed_book.png b/public/images/emoji/apple/closed_book.png index a24ad944002..0878f3efa2d 100644 Binary files a/public/images/emoji/apple/closed_book.png and b/public/images/emoji/apple/closed_book.png differ diff --git a/public/images/emoji/apple/closed_lock_with_key.png b/public/images/emoji/apple/closed_lock_with_key.png index 18d3d693c89..a6108835b40 100644 Binary files a/public/images/emoji/apple/closed_lock_with_key.png and b/public/images/emoji/apple/closed_lock_with_key.png differ diff --git a/public/images/emoji/apple/closed_umbrella.png b/public/images/emoji/apple/closed_umbrella.png index 596a31236a0..02519903864 100644 Binary files a/public/images/emoji/apple/closed_umbrella.png and b/public/images/emoji/apple/closed_umbrella.png differ diff --git a/public/images/emoji/apple/cloud.png b/public/images/emoji/apple/cloud.png index 8e51f77254e..dc011b23943 100644 Binary files a/public/images/emoji/apple/cloud.png and b/public/images/emoji/apple/cloud.png differ diff --git a/public/images/emoji/apple/cloud_lightning.png b/public/images/emoji/apple/cloud_lightning.png new file mode 100644 index 00000000000..637f618d065 Binary files /dev/null and b/public/images/emoji/apple/cloud_lightning.png differ diff --git a/public/images/emoji/apple/cloud_rain.png b/public/images/emoji/apple/cloud_rain.png new file mode 100644 index 00000000000..704e3fa822f Binary files /dev/null and b/public/images/emoji/apple/cloud_rain.png differ diff --git a/public/images/emoji/apple/cloud_snow.png b/public/images/emoji/apple/cloud_snow.png new file mode 100644 index 00000000000..a502b63a4b1 Binary files /dev/null and b/public/images/emoji/apple/cloud_snow.png differ diff --git a/public/images/emoji/apple/cloud_tornado.png b/public/images/emoji/apple/cloud_tornado.png new file mode 100644 index 00000000000..df48b70f5db Binary files /dev/null and b/public/images/emoji/apple/cloud_tornado.png differ diff --git a/public/images/emoji/apple/clubs.png b/public/images/emoji/apple/clubs.png index 230d9d032e0..0f977041a4d 100644 Binary files a/public/images/emoji/apple/clubs.png and b/public/images/emoji/apple/clubs.png differ diff --git a/public/images/emoji/apple/cn.png b/public/images/emoji/apple/cn.png index 5a132ac7cb0..4be941fa0b3 100644 Binary files a/public/images/emoji/apple/cn.png and b/public/images/emoji/apple/cn.png differ diff --git a/public/images/emoji/apple/cocktail.png b/public/images/emoji/apple/cocktail.png index 9dcfbce91bd..04538210860 100644 Binary files a/public/images/emoji/apple/cocktail.png and b/public/images/emoji/apple/cocktail.png differ diff --git a/public/images/emoji/apple/coffee.png b/public/images/emoji/apple/coffee.png index d2e343dbb07..125e754387a 100644 Binary files a/public/images/emoji/apple/coffee.png and b/public/images/emoji/apple/coffee.png differ diff --git a/public/images/emoji/apple/coffin.png b/public/images/emoji/apple/coffin.png new file mode 100644 index 00000000000..08b08c3951a Binary files /dev/null and b/public/images/emoji/apple/coffin.png differ diff --git a/public/images/emoji/apple/cold_sweat.png b/public/images/emoji/apple/cold_sweat.png index 0d22e62fa8f..8a51f367411 100644 Binary files a/public/images/emoji/apple/cold_sweat.png and b/public/images/emoji/apple/cold_sweat.png differ diff --git a/public/images/emoji/apple/collision.png b/public/images/emoji/apple/collision.png index c16baf2aecf..2684772a78a 100644 Binary files a/public/images/emoji/apple/collision.png and b/public/images/emoji/apple/collision.png differ diff --git a/public/images/emoji/apple/comet.png b/public/images/emoji/apple/comet.png new file mode 100644 index 00000000000..2e548168097 Binary files /dev/null and b/public/images/emoji/apple/comet.png differ diff --git a/public/images/emoji/apple/compression.png b/public/images/emoji/apple/compression.png new file mode 100644 index 00000000000..281e7b250d6 Binary files /dev/null and b/public/images/emoji/apple/compression.png differ diff --git a/public/images/emoji/apple/computer.png b/public/images/emoji/apple/computer.png index 9f6b8be581a..05fb56d48f1 100644 Binary files a/public/images/emoji/apple/computer.png and b/public/images/emoji/apple/computer.png differ diff --git a/public/images/emoji/apple/confetti_ball.png b/public/images/emoji/apple/confetti_ball.png index 742816ab44a..986d373a7a9 100644 Binary files a/public/images/emoji/apple/confetti_ball.png and b/public/images/emoji/apple/confetti_ball.png differ diff --git a/public/images/emoji/apple/confounded.png b/public/images/emoji/apple/confounded.png index cb45c1c8c63..92251be5311 100644 Binary files a/public/images/emoji/apple/confounded.png and b/public/images/emoji/apple/confounded.png differ diff --git a/public/images/emoji/apple/confused.png b/public/images/emoji/apple/confused.png index ac533670c2e..8436af6f7ae 100644 Binary files a/public/images/emoji/apple/confused.png and b/public/images/emoji/apple/confused.png differ diff --git a/public/images/emoji/apple/congratulations.png b/public/images/emoji/apple/congratulations.png index 41ef1b63d55..76921b93553 100644 Binary files a/public/images/emoji/apple/congratulations.png and b/public/images/emoji/apple/congratulations.png differ diff --git a/public/images/emoji/apple/construction.png b/public/images/emoji/apple/construction.png index a32fbd42338..f755e901815 100644 Binary files a/public/images/emoji/apple/construction.png and b/public/images/emoji/apple/construction.png differ diff --git a/public/images/emoji/apple/construction_site.png b/public/images/emoji/apple/construction_site.png new file mode 100644 index 00000000000..a78635ffec8 Binary files /dev/null and b/public/images/emoji/apple/construction_site.png differ diff --git a/public/images/emoji/apple/construction_worker.png b/public/images/emoji/apple/construction_worker.png index 8768e47de0d..d35c240d086 100644 Binary files a/public/images/emoji/apple/construction_worker.png and b/public/images/emoji/apple/construction_worker.png differ diff --git a/public/images/emoji/apple/control_knobs.png b/public/images/emoji/apple/control_knobs.png new file mode 100644 index 00000000000..9b2a45d0dc1 Binary files /dev/null and b/public/images/emoji/apple/control_knobs.png differ diff --git a/public/images/emoji/apple/convenience_store.png b/public/images/emoji/apple/convenience_store.png index b8fba9aab06..a84e807fa8f 100644 Binary files a/public/images/emoji/apple/convenience_store.png and b/public/images/emoji/apple/convenience_store.png differ diff --git a/public/images/emoji/apple/cookie.png b/public/images/emoji/apple/cookie.png index 2a6feff345c..12992ec091d 100644 Binary files a/public/images/emoji/apple/cookie.png and b/public/images/emoji/apple/cookie.png differ diff --git a/public/images/emoji/apple/cool.png b/public/images/emoji/apple/cool.png index d901fe824cb..8e0cad456a0 100644 Binary files a/public/images/emoji/apple/cool.png and b/public/images/emoji/apple/cool.png differ diff --git a/public/images/emoji/apple/cop.png b/public/images/emoji/apple/cop.png index 88131338ae1..2e3151efd45 100644 Binary files a/public/images/emoji/apple/cop.png and b/public/images/emoji/apple/cop.png differ diff --git a/public/images/emoji/apple/copyright.png b/public/images/emoji/apple/copyright.png index a7578a29b5f..4bcff248fae 100644 Binary files a/public/images/emoji/apple/copyright.png and b/public/images/emoji/apple/copyright.png differ diff --git a/public/images/emoji/apple/corn.png b/public/images/emoji/apple/corn.png index 75825d1d526..40c1196a478 100644 Binary files a/public/images/emoji/apple/corn.png and b/public/images/emoji/apple/corn.png differ diff --git a/public/images/emoji/apple/couch.png b/public/images/emoji/apple/couch.png new file mode 100644 index 00000000000..0fe1d1dc723 Binary files /dev/null and b/public/images/emoji/apple/couch.png differ diff --git a/public/images/emoji/apple/couple.png b/public/images/emoji/apple/couple.png index 442448bb63f..6d598de3b1f 100644 Binary files a/public/images/emoji/apple/couple.png and b/public/images/emoji/apple/couple.png differ diff --git a/public/images/emoji/apple/couple_with_heart.png b/public/images/emoji/apple/couple_with_heart.png index 41490f6d18b..5723e0ad2a6 100644 Binary files a/public/images/emoji/apple/couple_with_heart.png and b/public/images/emoji/apple/couple_with_heart.png differ diff --git a/public/images/emoji/apple/couplekiss.png b/public/images/emoji/apple/couplekiss.png index cc28fa8487e..ef8399a8438 100644 Binary files a/public/images/emoji/apple/couplekiss.png and b/public/images/emoji/apple/couplekiss.png differ diff --git a/public/images/emoji/apple/cow.png b/public/images/emoji/apple/cow.png index 61e0b7d560d..37d6b4518a4 100644 Binary files a/public/images/emoji/apple/cow.png and b/public/images/emoji/apple/cow.png differ diff --git a/public/images/emoji/apple/cow2.png b/public/images/emoji/apple/cow2.png index 2143ba59596..cc488d2a688 100644 Binary files a/public/images/emoji/apple/cow2.png and b/public/images/emoji/apple/cow2.png differ diff --git a/public/images/emoji/apple/crab.png b/public/images/emoji/apple/crab.png new file mode 100644 index 00000000000..fc81d467c7f Binary files /dev/null and b/public/images/emoji/apple/crab.png differ diff --git a/public/images/emoji/apple/crayon.png b/public/images/emoji/apple/crayon.png new file mode 100644 index 00000000000..1527eabeaf0 Binary files /dev/null and b/public/images/emoji/apple/crayon.png differ diff --git a/public/images/emoji/apple/credit_card.png b/public/images/emoji/apple/credit_card.png index cff26e4080a..be0cb8b5ed0 100644 Binary files a/public/images/emoji/apple/credit_card.png and b/public/images/emoji/apple/credit_card.png differ diff --git a/public/images/emoji/apple/crescent_moon.png b/public/images/emoji/apple/crescent_moon.png index f9b393baca7..dcfcc00f9f8 100644 Binary files a/public/images/emoji/apple/crescent_moon.png and b/public/images/emoji/apple/crescent_moon.png differ diff --git a/public/images/emoji/apple/cricket.png b/public/images/emoji/apple/cricket.png new file mode 100644 index 00000000000..fad7fbf328d Binary files /dev/null and b/public/images/emoji/apple/cricket.png differ diff --git a/public/images/emoji/apple/crocodile.png b/public/images/emoji/apple/crocodile.png index 902210255d0..5f8bc51458b 100644 Binary files a/public/images/emoji/apple/crocodile.png and b/public/images/emoji/apple/crocodile.png differ diff --git a/public/images/emoji/apple/cross.png b/public/images/emoji/apple/cross.png new file mode 100644 index 00000000000..605f15122dc Binary files /dev/null and b/public/images/emoji/apple/cross.png differ diff --git a/public/images/emoji/apple/crossed_flags.png b/public/images/emoji/apple/crossed_flags.png index 4d2b611bfb0..12acf39ce19 100644 Binary files a/public/images/emoji/apple/crossed_flags.png and b/public/images/emoji/apple/crossed_flags.png differ diff --git a/public/images/emoji/apple/crossed_swords.png b/public/images/emoji/apple/crossed_swords.png new file mode 100644 index 00000000000..79b38cf12d6 Binary files /dev/null and b/public/images/emoji/apple/crossed_swords.png differ diff --git a/public/images/emoji/apple/crown.png b/public/images/emoji/apple/crown.png index 13f55e78619..ac5bf3507ac 100644 Binary files a/public/images/emoji/apple/crown.png and b/public/images/emoji/apple/crown.png differ diff --git a/public/images/emoji/apple/cruise_ship.png b/public/images/emoji/apple/cruise_ship.png new file mode 100644 index 00000000000..c3db46e31f2 Binary files /dev/null and b/public/images/emoji/apple/cruise_ship.png differ diff --git a/public/images/emoji/apple/cry.png b/public/images/emoji/apple/cry.png index 1718b42ed4e..d139a33088a 100644 Binary files a/public/images/emoji/apple/cry.png and b/public/images/emoji/apple/cry.png differ diff --git a/public/images/emoji/apple/crying_cat_face.png b/public/images/emoji/apple/crying_cat_face.png index 3b3a47159ad..c6ad0c0eee6 100644 Binary files a/public/images/emoji/apple/crying_cat_face.png and b/public/images/emoji/apple/crying_cat_face.png differ diff --git a/public/images/emoji/apple/crystal_ball.png b/public/images/emoji/apple/crystal_ball.png index bee8b57650b..05268238b8d 100644 Binary files a/public/images/emoji/apple/crystal_ball.png and b/public/images/emoji/apple/crystal_ball.png differ diff --git a/public/images/emoji/apple/cupid.png b/public/images/emoji/apple/cupid.png index 468a8cc1c7b..06a842f5061 100644 Binary files a/public/images/emoji/apple/cupid.png and b/public/images/emoji/apple/cupid.png differ diff --git a/public/images/emoji/apple/curly_loop.png b/public/images/emoji/apple/curly_loop.png index e042005ed86..db599bd6ec3 100644 Binary files a/public/images/emoji/apple/curly_loop.png and b/public/images/emoji/apple/curly_loop.png differ diff --git a/public/images/emoji/apple/currency_exchange.png b/public/images/emoji/apple/currency_exchange.png index dbec08ff5cd..6fe3e9ff5ac 100644 Binary files a/public/images/emoji/apple/currency_exchange.png and b/public/images/emoji/apple/currency_exchange.png differ diff --git a/public/images/emoji/apple/curry.png b/public/images/emoji/apple/curry.png index a36875225fd..25c2a8869c1 100644 Binary files a/public/images/emoji/apple/curry.png and b/public/images/emoji/apple/curry.png differ diff --git a/public/images/emoji/apple/custard.png b/public/images/emoji/apple/custard.png index c851e103383..93dee41a21a 100644 Binary files a/public/images/emoji/apple/custard.png and b/public/images/emoji/apple/custard.png differ diff --git a/public/images/emoji/apple/customs.png b/public/images/emoji/apple/customs.png index 71a647d7888..9cf05f363e4 100644 Binary files a/public/images/emoji/apple/customs.png and b/public/images/emoji/apple/customs.png differ diff --git a/public/images/emoji/apple/cyclone.png b/public/images/emoji/apple/cyclone.png index 0aea4feff74..b49c1411b65 100644 Binary files a/public/images/emoji/apple/cyclone.png and b/public/images/emoji/apple/cyclone.png differ diff --git a/public/images/emoji/apple/dagger.png b/public/images/emoji/apple/dagger.png new file mode 100644 index 00000000000..76ecf228032 Binary files /dev/null and b/public/images/emoji/apple/dagger.png differ diff --git a/public/images/emoji/apple/dancer.png b/public/images/emoji/apple/dancer.png index c4ee0d6deee..9cfc3d99258 100644 Binary files a/public/images/emoji/apple/dancer.png and b/public/images/emoji/apple/dancer.png differ diff --git a/public/images/emoji/apple/dancers.png b/public/images/emoji/apple/dancers.png index b3f2be5dba9..4858350a9bc 100644 Binary files a/public/images/emoji/apple/dancers.png and b/public/images/emoji/apple/dancers.png differ diff --git a/public/images/emoji/apple/dango.png b/public/images/emoji/apple/dango.png index 493edaa4d15..ace15a358e9 100644 Binary files a/public/images/emoji/apple/dango.png and b/public/images/emoji/apple/dango.png differ diff --git a/public/images/emoji/apple/dark_sunglasses.png b/public/images/emoji/apple/dark_sunglasses.png new file mode 100644 index 00000000000..3a24fb7fd69 Binary files /dev/null and b/public/images/emoji/apple/dark_sunglasses.png differ diff --git a/public/images/emoji/apple/dart.png b/public/images/emoji/apple/dart.png index d40e0877662..f88f01a77b7 100644 Binary files a/public/images/emoji/apple/dart.png and b/public/images/emoji/apple/dart.png differ diff --git a/public/images/emoji/apple/dash.png b/public/images/emoji/apple/dash.png index bdc0d85a326..1b1e7f61757 100644 Binary files a/public/images/emoji/apple/dash.png and b/public/images/emoji/apple/dash.png differ diff --git a/public/images/emoji/apple/date.png b/public/images/emoji/apple/date.png index cf88ac2bbc2..6ecd3bcca6b 100644 Binary files a/public/images/emoji/apple/date.png and b/public/images/emoji/apple/date.png differ diff --git a/public/images/emoji/apple/de.png b/public/images/emoji/apple/de.png index 28d4a2f142d..1eea32e76a4 100644 Binary files a/public/images/emoji/apple/de.png and b/public/images/emoji/apple/de.png differ diff --git a/public/images/emoji/apple/deciduous_tree.png b/public/images/emoji/apple/deciduous_tree.png index 2dd403043b2..4721d55ec19 100644 Binary files a/public/images/emoji/apple/deciduous_tree.png and b/public/images/emoji/apple/deciduous_tree.png differ diff --git a/public/images/emoji/apple/department_store.png b/public/images/emoji/apple/department_store.png index 024ea83115e..31fddd83150 100644 Binary files a/public/images/emoji/apple/department_store.png and b/public/images/emoji/apple/department_store.png differ diff --git a/public/images/emoji/apple/desert.png b/public/images/emoji/apple/desert.png new file mode 100644 index 00000000000..eed6da83a9e Binary files /dev/null and b/public/images/emoji/apple/desert.png differ diff --git a/public/images/emoji/apple/desktop.png b/public/images/emoji/apple/desktop.png new file mode 100644 index 00000000000..651803e1094 Binary files /dev/null and b/public/images/emoji/apple/desktop.png differ diff --git a/public/images/emoji/apple/diamond_shape_with_a_dot_inside.png b/public/images/emoji/apple/diamond_shape_with_a_dot_inside.png index ca5ac05d2c8..63a068c24c4 100644 Binary files a/public/images/emoji/apple/diamond_shape_with_a_dot_inside.png and b/public/images/emoji/apple/diamond_shape_with_a_dot_inside.png differ diff --git a/public/images/emoji/apple/diamonds.png b/public/images/emoji/apple/diamonds.png index 08ddc3872c2..6546abc0445 100644 Binary files a/public/images/emoji/apple/diamonds.png and b/public/images/emoji/apple/diamonds.png differ diff --git a/public/images/emoji/apple/disappointed.png b/public/images/emoji/apple/disappointed.png index 0d3f52286f9..64035317d2d 100644 Binary files a/public/images/emoji/apple/disappointed.png and b/public/images/emoji/apple/disappointed.png differ diff --git a/public/images/emoji/apple/disappointed_relieved.png b/public/images/emoji/apple/disappointed_relieved.png index 4a7a9fd69d2..39575a149b2 100644 Binary files a/public/images/emoji/apple/disappointed_relieved.png and b/public/images/emoji/apple/disappointed_relieved.png differ diff --git a/public/images/emoji/apple/dividers.png b/public/images/emoji/apple/dividers.png new file mode 100644 index 00000000000..90fdd826d34 Binary files /dev/null and b/public/images/emoji/apple/dividers.png differ diff --git a/public/images/emoji/apple/dizzy.png b/public/images/emoji/apple/dizzy.png index 94314d0d0a6..5a96e609f57 100644 Binary files a/public/images/emoji/apple/dizzy.png and b/public/images/emoji/apple/dizzy.png differ diff --git a/public/images/emoji/apple/dizzy_face.png b/public/images/emoji/apple/dizzy_face.png index 92bb5851c7a..b5460b8fbb4 100644 Binary files a/public/images/emoji/apple/dizzy_face.png and b/public/images/emoji/apple/dizzy_face.png differ diff --git a/public/images/emoji/apple/do_not_litter.png b/public/images/emoji/apple/do_not_litter.png index 87a95f9d800..97297f74b0f 100644 Binary files a/public/images/emoji/apple/do_not_litter.png and b/public/images/emoji/apple/do_not_litter.png differ diff --git a/public/images/emoji/apple/dog.png b/public/images/emoji/apple/dog.png index c83e5ceb169..486a6e6d715 100644 Binary files a/public/images/emoji/apple/dog.png and b/public/images/emoji/apple/dog.png differ diff --git a/public/images/emoji/apple/dog2.png b/public/images/emoji/apple/dog2.png index 6070161781d..1cf5325cb3e 100644 Binary files a/public/images/emoji/apple/dog2.png and b/public/images/emoji/apple/dog2.png differ diff --git a/public/images/emoji/apple/dollar.png b/public/images/emoji/apple/dollar.png index e0029558499..88d0756b495 100644 Binary files a/public/images/emoji/apple/dollar.png and b/public/images/emoji/apple/dollar.png differ diff --git a/public/images/emoji/apple/dolls.png b/public/images/emoji/apple/dolls.png index cbd0f305301..cffb5bafe72 100644 Binary files a/public/images/emoji/apple/dolls.png and b/public/images/emoji/apple/dolls.png differ diff --git a/public/images/emoji/apple/dolphin.png b/public/images/emoji/apple/dolphin.png index 083819034ce..fa492cd888b 100644 Binary files a/public/images/emoji/apple/dolphin.png and b/public/images/emoji/apple/dolphin.png differ diff --git a/public/images/emoji/apple/door.png b/public/images/emoji/apple/door.png index 8e5e6eab4ed..b7734896e40 100644 Binary files a/public/images/emoji/apple/door.png and b/public/images/emoji/apple/door.png differ diff --git a/public/images/emoji/apple/doughnut.png b/public/images/emoji/apple/doughnut.png index 2b6ff68fe8b..165803bbfb9 100644 Binary files a/public/images/emoji/apple/doughnut.png and b/public/images/emoji/apple/doughnut.png differ diff --git a/public/images/emoji/apple/dove.png b/public/images/emoji/apple/dove.png new file mode 100644 index 00000000000..6dc892768bf Binary files /dev/null and b/public/images/emoji/apple/dove.png differ diff --git a/public/images/emoji/apple/dragon.png b/public/images/emoji/apple/dragon.png index b649b76df31..926f0b387fc 100644 Binary files a/public/images/emoji/apple/dragon.png and b/public/images/emoji/apple/dragon.png differ diff --git a/public/images/emoji/apple/dragon_face.png b/public/images/emoji/apple/dragon_face.png index 326898d697f..4a980ff72ec 100644 Binary files a/public/images/emoji/apple/dragon_face.png and b/public/images/emoji/apple/dragon_face.png differ diff --git a/public/images/emoji/apple/dress.png b/public/images/emoji/apple/dress.png index 55a6aa8fb05..fd736a2af5c 100644 Binary files a/public/images/emoji/apple/dress.png and b/public/images/emoji/apple/dress.png differ diff --git a/public/images/emoji/apple/dromedary_camel.png b/public/images/emoji/apple/dromedary_camel.png index 54acbd1c2a3..07f6f484245 100644 Binary files a/public/images/emoji/apple/dromedary_camel.png and b/public/images/emoji/apple/dromedary_camel.png differ diff --git a/public/images/emoji/apple/droplet.png b/public/images/emoji/apple/droplet.png index d28e56aa630..c8a7fbb909e 100644 Binary files a/public/images/emoji/apple/droplet.png and b/public/images/emoji/apple/droplet.png differ diff --git a/public/images/emoji/apple/dvd.png b/public/images/emoji/apple/dvd.png index 28139865558..d339448d1a5 100644 Binary files a/public/images/emoji/apple/dvd.png and b/public/images/emoji/apple/dvd.png differ diff --git a/public/images/emoji/apple/e-mail.png b/public/images/emoji/apple/e-mail.png index 858234e9a33..f03a9a394ac 100644 Binary files a/public/images/emoji/apple/e-mail.png and b/public/images/emoji/apple/e-mail.png differ diff --git a/public/images/emoji/apple/ear.png b/public/images/emoji/apple/ear.png index c8e64b560dd..3f063847548 100644 Binary files a/public/images/emoji/apple/ear.png and b/public/images/emoji/apple/ear.png differ diff --git a/public/images/emoji/apple/ear_of_rice.png b/public/images/emoji/apple/ear_of_rice.png index 3fc2d4cf76f..ab5913e1f97 100644 Binary files a/public/images/emoji/apple/ear_of_rice.png and b/public/images/emoji/apple/ear_of_rice.png differ diff --git a/public/images/emoji/apple/earth_africa.png b/public/images/emoji/apple/earth_africa.png index dbfb2a7ff7e..000c857de73 100644 Binary files a/public/images/emoji/apple/earth_africa.png and b/public/images/emoji/apple/earth_africa.png differ diff --git a/public/images/emoji/apple/earth_americas.png b/public/images/emoji/apple/earth_americas.png index e18944d8920..235b15aaf9a 100644 Binary files a/public/images/emoji/apple/earth_americas.png and b/public/images/emoji/apple/earth_americas.png differ diff --git a/public/images/emoji/apple/earth_asia.png b/public/images/emoji/apple/earth_asia.png index 9edcc3f88d6..ea7d9cd9945 100644 Binary files a/public/images/emoji/apple/earth_asia.png and b/public/images/emoji/apple/earth_asia.png differ diff --git a/public/images/emoji/apple/egg.png b/public/images/emoji/apple/egg.png index af0f846ba79..c3426d73513 100644 Binary files a/public/images/emoji/apple/egg.png and b/public/images/emoji/apple/egg.png differ diff --git a/public/images/emoji/apple/eggplant.png b/public/images/emoji/apple/eggplant.png index 13e3636314b..cd3d9eeaf37 100644 Binary files a/public/images/emoji/apple/eggplant.png and b/public/images/emoji/apple/eggplant.png differ diff --git a/public/images/emoji/apple/eight.png b/public/images/emoji/apple/eight.png index f76e43d1798..cb9b459f7e6 100644 Binary files a/public/images/emoji/apple/eight.png and b/public/images/emoji/apple/eight.png differ diff --git a/public/images/emoji/apple/eight_pointed_black_star.png b/public/images/emoji/apple/eight_pointed_black_star.png index 6f4b4eac98b..11e720fdd27 100644 Binary files a/public/images/emoji/apple/eight_pointed_black_star.png and b/public/images/emoji/apple/eight_pointed_black_star.png differ diff --git a/public/images/emoji/apple/eight_spoked_asterisk.png b/public/images/emoji/apple/eight_spoked_asterisk.png index efb7f02f520..9a8657d7b2f 100644 Binary files a/public/images/emoji/apple/eight_spoked_asterisk.png and b/public/images/emoji/apple/eight_spoked_asterisk.png differ diff --git a/public/images/emoji/apple/electric_plug.png b/public/images/emoji/apple/electric_plug.png index 4262ad05cdf..fe58495d5d9 100644 Binary files a/public/images/emoji/apple/electric_plug.png and b/public/images/emoji/apple/electric_plug.png differ diff --git a/public/images/emoji/apple/elephant.png b/public/images/emoji/apple/elephant.png index 8fe220de84a..c8800eb3a34 100644 Binary files a/public/images/emoji/apple/elephant.png and b/public/images/emoji/apple/elephant.png differ diff --git a/public/images/emoji/apple/email.png b/public/images/emoji/apple/email.png index e843883b5c3..4553070d511 100644 Binary files a/public/images/emoji/apple/email.png and b/public/images/emoji/apple/email.png differ diff --git a/public/images/emoji/apple/end.png b/public/images/emoji/apple/end.png index ae7b020ce91..74675d81f8a 100644 Binary files a/public/images/emoji/apple/end.png and b/public/images/emoji/apple/end.png differ diff --git a/public/images/emoji/apple/envelope.png b/public/images/emoji/apple/envelope.png index e843883b5c3..f47b07cce90 100644 Binary files a/public/images/emoji/apple/envelope.png and b/public/images/emoji/apple/envelope.png differ diff --git a/public/images/emoji/apple/envelope_with_arrow.png b/public/images/emoji/apple/envelope_with_arrow.png index 24a4f008b53..ae5d944d240 100644 Binary files a/public/images/emoji/apple/envelope_with_arrow.png and b/public/images/emoji/apple/envelope_with_arrow.png differ diff --git a/public/images/emoji/apple/es.png b/public/images/emoji/apple/es.png index afcdcf7b402..2e7761c07a5 100644 Binary files a/public/images/emoji/apple/es.png and b/public/images/emoji/apple/es.png differ diff --git a/public/images/emoji/apple/euro.png b/public/images/emoji/apple/euro.png index 17e0d34ace9..c21d2931c4f 100644 Binary files a/public/images/emoji/apple/euro.png and b/public/images/emoji/apple/euro.png differ diff --git a/public/images/emoji/apple/european_castle.png b/public/images/emoji/apple/european_castle.png index 3f513b8a943..9ae8013aea3 100644 Binary files a/public/images/emoji/apple/european_castle.png and b/public/images/emoji/apple/european_castle.png differ diff --git a/public/images/emoji/apple/european_post_office.png b/public/images/emoji/apple/european_post_office.png index 193d6a5b0bf..b8579f36f74 100644 Binary files a/public/images/emoji/apple/european_post_office.png and b/public/images/emoji/apple/european_post_office.png differ diff --git a/public/images/emoji/apple/evergreen_tree.png b/public/images/emoji/apple/evergreen_tree.png index 4710e8861ff..11887a78630 100644 Binary files a/public/images/emoji/apple/evergreen_tree.png and b/public/images/emoji/apple/evergreen_tree.png differ diff --git a/public/images/emoji/apple/exclamation.png b/public/images/emoji/apple/exclamation.png index 43f4583418a..48e8cf9d66d 100644 Binary files a/public/images/emoji/apple/exclamation.png and b/public/images/emoji/apple/exclamation.png differ diff --git a/public/images/emoji/apple/expressionless.png b/public/images/emoji/apple/expressionless.png index 4882027ec90..115f2d80df2 100644 Binary files a/public/images/emoji/apple/expressionless.png and b/public/images/emoji/apple/expressionless.png differ diff --git a/public/images/emoji/apple/eye.png b/public/images/emoji/apple/eye.png new file mode 100644 index 00000000000..2e04514af43 Binary files /dev/null and b/public/images/emoji/apple/eye.png differ diff --git a/public/images/emoji/apple/eyeglasses.png b/public/images/emoji/apple/eyeglasses.png index 9f4e057a7ad..463f9bb7477 100644 Binary files a/public/images/emoji/apple/eyeglasses.png and b/public/images/emoji/apple/eyeglasses.png differ diff --git a/public/images/emoji/apple/eyes.png b/public/images/emoji/apple/eyes.png index f8ed2b2b2de..cf9d03fb18c 100644 Binary files a/public/images/emoji/apple/eyes.png and b/public/images/emoji/apple/eyes.png differ diff --git a/public/images/emoji/apple/facepunch.png b/public/images/emoji/apple/facepunch.png index 3a76b98e783..524739e607f 100644 Binary files a/public/images/emoji/apple/facepunch.png and b/public/images/emoji/apple/facepunch.png differ diff --git a/public/images/emoji/apple/factory.png b/public/images/emoji/apple/factory.png index 5e196b31c5b..f6a552a66b4 100644 Binary files a/public/images/emoji/apple/factory.png and b/public/images/emoji/apple/factory.png differ diff --git a/public/images/emoji/apple/fallen_leaf.png b/public/images/emoji/apple/fallen_leaf.png index 1804751ac35..9c61dda1634 100644 Binary files a/public/images/emoji/apple/fallen_leaf.png and b/public/images/emoji/apple/fallen_leaf.png differ diff --git a/public/images/emoji/apple/family.png b/public/images/emoji/apple/family.png index f4e470e577e..3758ed01dd9 100644 Binary files a/public/images/emoji/apple/family.png and b/public/images/emoji/apple/family.png differ diff --git a/public/images/emoji/apple/fast_forward.png b/public/images/emoji/apple/fast_forward.png index c5636e73a01..f253ed3a6d5 100644 Binary files a/public/images/emoji/apple/fast_forward.png and b/public/images/emoji/apple/fast_forward.png differ diff --git a/public/images/emoji/apple/fax.png b/public/images/emoji/apple/fax.png index ad5def318d8..7a507368074 100644 Binary files a/public/images/emoji/apple/fax.png and b/public/images/emoji/apple/fax.png differ diff --git a/public/images/emoji/apple/fearful.png b/public/images/emoji/apple/fearful.png index 086503a7f6b..37bba2aaa53 100644 Binary files a/public/images/emoji/apple/fearful.png and b/public/images/emoji/apple/fearful.png differ diff --git a/public/images/emoji/apple/feet.png b/public/images/emoji/apple/feet.png index f80ff2e67aa..ee234e91496 100644 Binary files a/public/images/emoji/apple/feet.png and b/public/images/emoji/apple/feet.png differ diff --git a/public/images/emoji/apple/ferris_wheel.png b/public/images/emoji/apple/ferris_wheel.png index 5ae1b8110ae..269347aadcb 100644 Binary files a/public/images/emoji/apple/ferris_wheel.png and b/public/images/emoji/apple/ferris_wheel.png differ diff --git a/public/images/emoji/apple/ferry.png b/public/images/emoji/apple/ferry.png new file mode 100644 index 00000000000..a3a798ec022 Binary files /dev/null and b/public/images/emoji/apple/ferry.png differ diff --git a/public/images/emoji/apple/field_hockey.png b/public/images/emoji/apple/field_hockey.png new file mode 100644 index 00000000000..3c107b28d50 Binary files /dev/null and b/public/images/emoji/apple/field_hockey.png differ diff --git a/public/images/emoji/apple/file_cabinet.png b/public/images/emoji/apple/file_cabinet.png new file mode 100644 index 00000000000..e5a2ed1eeac Binary files /dev/null and b/public/images/emoji/apple/file_cabinet.png differ diff --git a/public/images/emoji/apple/file_folder.png b/public/images/emoji/apple/file_folder.png index da3462be088..f92532bed12 100644 Binary files a/public/images/emoji/apple/file_folder.png and b/public/images/emoji/apple/file_folder.png differ diff --git a/public/images/emoji/apple/film_frames.png b/public/images/emoji/apple/film_frames.png new file mode 100644 index 00000000000..6bd06eb5648 Binary files /dev/null and b/public/images/emoji/apple/film_frames.png differ diff --git a/public/images/emoji/apple/fire.png b/public/images/emoji/apple/fire.png index a819ed95f16..13406d212bf 100644 Binary files a/public/images/emoji/apple/fire.png and b/public/images/emoji/apple/fire.png differ diff --git a/public/images/emoji/apple/fire_engine.png b/public/images/emoji/apple/fire_engine.png index d7df6e86bdc..c71420f0e5c 100644 Binary files a/public/images/emoji/apple/fire_engine.png and b/public/images/emoji/apple/fire_engine.png differ diff --git a/public/images/emoji/apple/fireworks.png b/public/images/emoji/apple/fireworks.png index 809342d4609..15d182be5a0 100644 Binary files a/public/images/emoji/apple/fireworks.png and b/public/images/emoji/apple/fireworks.png differ diff --git a/public/images/emoji/apple/first_quarter_moon.png b/public/images/emoji/apple/first_quarter_moon.png index adaf1d6cff3..7ad10ce4dbb 100644 Binary files a/public/images/emoji/apple/first_quarter_moon.png and b/public/images/emoji/apple/first_quarter_moon.png differ diff --git a/public/images/emoji/apple/first_quarter_moon_with_face.png b/public/images/emoji/apple/first_quarter_moon_with_face.png index c884089df54..f7f0eafa731 100644 Binary files a/public/images/emoji/apple/first_quarter_moon_with_face.png and b/public/images/emoji/apple/first_quarter_moon_with_face.png differ diff --git a/public/images/emoji/apple/fish.png b/public/images/emoji/apple/fish.png index 8a4039ed257..02ec2bf00b7 100644 Binary files a/public/images/emoji/apple/fish.png and b/public/images/emoji/apple/fish.png differ diff --git a/public/images/emoji/apple/fish_cake.png b/public/images/emoji/apple/fish_cake.png index 8a80c2f42f6..13fbe599985 100644 Binary files a/public/images/emoji/apple/fish_cake.png and b/public/images/emoji/apple/fish_cake.png differ diff --git a/public/images/emoji/apple/fishing_pole_and_fish.png b/public/images/emoji/apple/fishing_pole_and_fish.png index ffc61097107..1bfcc7d5bea 100644 Binary files a/public/images/emoji/apple/fishing_pole_and_fish.png and b/public/images/emoji/apple/fishing_pole_and_fish.png differ diff --git a/public/images/emoji/apple/fist.png b/public/images/emoji/apple/fist.png index 6456c7430c8..bcf93e33f6c 100644 Binary files a/public/images/emoji/apple/fist.png and b/public/images/emoji/apple/fist.png differ diff --git a/public/images/emoji/apple/five.png b/public/images/emoji/apple/five.png index 9555767a9f4..4eab16bd7b8 100644 Binary files a/public/images/emoji/apple/five.png and b/public/images/emoji/apple/five.png differ diff --git a/public/images/emoji/apple/flag_black.png b/public/images/emoji/apple/flag_black.png new file mode 100644 index 00000000000..c132e2c23e9 Binary files /dev/null and b/public/images/emoji/apple/flag_black.png differ diff --git a/public/images/emoji/apple/flag_cn.png b/public/images/emoji/apple/flag_cn.png new file mode 100644 index 00000000000..0b265515a9f Binary files /dev/null and b/public/images/emoji/apple/flag_cn.png differ diff --git a/public/images/emoji/apple/flag_de.png b/public/images/emoji/apple/flag_de.png new file mode 100644 index 00000000000..24aa3d0d8b5 Binary files /dev/null and b/public/images/emoji/apple/flag_de.png differ diff --git a/public/images/emoji/apple/flag_es.png b/public/images/emoji/apple/flag_es.png new file mode 100644 index 00000000000..d2cfcef8403 Binary files /dev/null and b/public/images/emoji/apple/flag_es.png differ diff --git a/public/images/emoji/apple/flag_fr.png b/public/images/emoji/apple/flag_fr.png new file mode 100644 index 00000000000..aab8b4737ed Binary files /dev/null and b/public/images/emoji/apple/flag_fr.png differ diff --git a/public/images/emoji/apple/flag_gb.png b/public/images/emoji/apple/flag_gb.png new file mode 100644 index 00000000000..d4ad5e4a9c9 Binary files /dev/null and b/public/images/emoji/apple/flag_gb.png differ diff --git a/public/images/emoji/apple/flag_it.png b/public/images/emoji/apple/flag_it.png new file mode 100644 index 00000000000..e5d64a1db7a Binary files /dev/null and b/public/images/emoji/apple/flag_it.png differ diff --git a/public/images/emoji/apple/flag_jp.png b/public/images/emoji/apple/flag_jp.png new file mode 100644 index 00000000000..6eb4257c869 Binary files /dev/null and b/public/images/emoji/apple/flag_jp.png differ diff --git a/public/images/emoji/apple/flag_kr.png b/public/images/emoji/apple/flag_kr.png new file mode 100644 index 00000000000..57757ef4a9a Binary files /dev/null and b/public/images/emoji/apple/flag_kr.png differ diff --git a/public/images/emoji/apple/flag_ru.png b/public/images/emoji/apple/flag_ru.png new file mode 100644 index 00000000000..77666f357db Binary files /dev/null and b/public/images/emoji/apple/flag_ru.png differ diff --git a/public/images/emoji/apple/flag_us.png b/public/images/emoji/apple/flag_us.png new file mode 100644 index 00000000000..a3f93780868 Binary files /dev/null and b/public/images/emoji/apple/flag_us.png differ diff --git a/public/images/emoji/apple/flag_white.png b/public/images/emoji/apple/flag_white.png new file mode 100644 index 00000000000..6b6becc2531 Binary files /dev/null and b/public/images/emoji/apple/flag_white.png differ diff --git a/public/images/emoji/apple/flags.png b/public/images/emoji/apple/flags.png index 578fa6e5dff..da9f8543d0c 100644 Binary files a/public/images/emoji/apple/flags.png and b/public/images/emoji/apple/flags.png differ diff --git a/public/images/emoji/apple/flashlight.png b/public/images/emoji/apple/flashlight.png index 6f4487471b2..4707c2d10fa 100644 Binary files a/public/images/emoji/apple/flashlight.png and b/public/images/emoji/apple/flashlight.png differ diff --git a/public/images/emoji/apple/fleur-de-lis.png b/public/images/emoji/apple/fleur-de-lis.png new file mode 100644 index 00000000000..5f98df5b2dd Binary files /dev/null and b/public/images/emoji/apple/fleur-de-lis.png differ diff --git a/public/images/emoji/apple/flipper.png b/public/images/emoji/apple/flipper.png index 083819034ce..0c5c41ed69f 100644 Binary files a/public/images/emoji/apple/flipper.png and b/public/images/emoji/apple/flipper.png differ diff --git a/public/images/emoji/apple/floppy_disk.png b/public/images/emoji/apple/floppy_disk.png index f00a8d4e6cc..6203a665fb8 100644 Binary files a/public/images/emoji/apple/floppy_disk.png and b/public/images/emoji/apple/floppy_disk.png differ diff --git a/public/images/emoji/apple/flower_playing_cards.png b/public/images/emoji/apple/flower_playing_cards.png index 8cf87254620..dd1696eb6ea 100644 Binary files a/public/images/emoji/apple/flower_playing_cards.png and b/public/images/emoji/apple/flower_playing_cards.png differ diff --git a/public/images/emoji/apple/flushed.png b/public/images/emoji/apple/flushed.png index e6aad287d06..8fb81dee827 100644 Binary files a/public/images/emoji/apple/flushed.png and b/public/images/emoji/apple/flushed.png differ diff --git a/public/images/emoji/apple/fog.png b/public/images/emoji/apple/fog.png new file mode 100644 index 00000000000..2f2c2080b56 Binary files /dev/null and b/public/images/emoji/apple/fog.png differ diff --git a/public/images/emoji/apple/foggy.png b/public/images/emoji/apple/foggy.png index 794601e1f02..95cf6527d8c 100644 Binary files a/public/images/emoji/apple/foggy.png and b/public/images/emoji/apple/foggy.png differ diff --git a/public/images/emoji/apple/football.png b/public/images/emoji/apple/football.png index 037f7a76e13..343b00ed95c 100644 Binary files a/public/images/emoji/apple/football.png and b/public/images/emoji/apple/football.png differ diff --git a/public/images/emoji/apple/footprints.png b/public/images/emoji/apple/footprints.png index 3dbc1f795cf..f1c3d0cf6f0 100644 Binary files a/public/images/emoji/apple/footprints.png and b/public/images/emoji/apple/footprints.png differ diff --git a/public/images/emoji/apple/fork_and_knife.png b/public/images/emoji/apple/fork_and_knife.png index 2fbad780ba4..70fae6c3da4 100644 Binary files a/public/images/emoji/apple/fork_and_knife.png and b/public/images/emoji/apple/fork_and_knife.png differ diff --git a/public/images/emoji/apple/fork_knife_plate.png b/public/images/emoji/apple/fork_knife_plate.png new file mode 100644 index 00000000000..0abb5afedc4 Binary files /dev/null and b/public/images/emoji/apple/fork_knife_plate.png differ diff --git a/public/images/emoji/apple/fountain.png b/public/images/emoji/apple/fountain.png index 3e64f78fcba..e243a015d01 100644 Binary files a/public/images/emoji/apple/fountain.png and b/public/images/emoji/apple/fountain.png differ diff --git a/public/images/emoji/apple/four.png b/public/images/emoji/apple/four.png index e0bab58f05f..20150cb2e3e 100644 Binary files a/public/images/emoji/apple/four.png and b/public/images/emoji/apple/four.png differ diff --git a/public/images/emoji/apple/four_leaf_clover.png b/public/images/emoji/apple/four_leaf_clover.png index a4e25b1f3e4..33a7e80a647 100644 Binary files a/public/images/emoji/apple/four_leaf_clover.png and b/public/images/emoji/apple/four_leaf_clover.png differ diff --git a/public/images/emoji/apple/fr.png b/public/images/emoji/apple/fr.png index c4ed9301761..1e900b30348 100644 Binary files a/public/images/emoji/apple/fr.png and b/public/images/emoji/apple/fr.png differ diff --git a/public/images/emoji/apple/frame_photo.png b/public/images/emoji/apple/frame_photo.png new file mode 100644 index 00000000000..75b50f2600d Binary files /dev/null and b/public/images/emoji/apple/frame_photo.png differ diff --git a/public/images/emoji/apple/free.png b/public/images/emoji/apple/free.png index 8f7e6d8a490..58b82df2612 100644 Binary files a/public/images/emoji/apple/free.png and b/public/images/emoji/apple/free.png differ diff --git a/public/images/emoji/apple/fried_shrimp.png b/public/images/emoji/apple/fried_shrimp.png index 4b6711a21a5..a135a7e7d38 100644 Binary files a/public/images/emoji/apple/fried_shrimp.png and b/public/images/emoji/apple/fried_shrimp.png differ diff --git a/public/images/emoji/apple/fries.png b/public/images/emoji/apple/fries.png index 38badf5e608..3ddf1524c98 100644 Binary files a/public/images/emoji/apple/fries.png and b/public/images/emoji/apple/fries.png differ diff --git a/public/images/emoji/apple/frog.png b/public/images/emoji/apple/frog.png index 5abb7e2e385..582b01682b7 100644 Binary files a/public/images/emoji/apple/frog.png and b/public/images/emoji/apple/frog.png differ diff --git a/public/images/emoji/apple/frowning.png b/public/images/emoji/apple/frowning.png index e4dc6f0121c..3f997f70268 100644 Binary files a/public/images/emoji/apple/frowning.png and b/public/images/emoji/apple/frowning.png differ diff --git a/public/images/emoji/apple/frowning2.png b/public/images/emoji/apple/frowning2.png new file mode 100644 index 00000000000..917fc06cbcf Binary files /dev/null and b/public/images/emoji/apple/frowning2.png differ diff --git a/public/images/emoji/apple/fuelpump.png b/public/images/emoji/apple/fuelpump.png index 1495737a6b6..b6c8846cc17 100644 Binary files a/public/images/emoji/apple/fuelpump.png and b/public/images/emoji/apple/fuelpump.png differ diff --git a/public/images/emoji/apple/full_moon.png b/public/images/emoji/apple/full_moon.png index 127f2dcdee5..74a84d3aa48 100644 Binary files a/public/images/emoji/apple/full_moon.png and b/public/images/emoji/apple/full_moon.png differ diff --git a/public/images/emoji/apple/full_moon_with_face.png b/public/images/emoji/apple/full_moon_with_face.png index ee30e5a0270..299450956c3 100644 Binary files a/public/images/emoji/apple/full_moon_with_face.png and b/public/images/emoji/apple/full_moon_with_face.png differ diff --git a/public/images/emoji/apple/game_die.png b/public/images/emoji/apple/game_die.png index 02ee30d4ff4..1d5207a9317 100644 Binary files a/public/images/emoji/apple/game_die.png and b/public/images/emoji/apple/game_die.png differ diff --git a/public/images/emoji/apple/gb.png b/public/images/emoji/apple/gb.png index edb2ec76427..1ff35d07152 100644 Binary files a/public/images/emoji/apple/gb.png and b/public/images/emoji/apple/gb.png differ diff --git a/public/images/emoji/apple/gear.png b/public/images/emoji/apple/gear.png new file mode 100644 index 00000000000..465d74e5f61 Binary files /dev/null and b/public/images/emoji/apple/gear.png differ diff --git a/public/images/emoji/apple/gem.png b/public/images/emoji/apple/gem.png index 7122fba5f80..7c16e8cfbce 100644 Binary files a/public/images/emoji/apple/gem.png and b/public/images/emoji/apple/gem.png differ diff --git a/public/images/emoji/apple/gemini.png b/public/images/emoji/apple/gemini.png index b1a40509ea0..455e0e22645 100644 Binary files a/public/images/emoji/apple/gemini.png and b/public/images/emoji/apple/gemini.png differ diff --git a/public/images/emoji/apple/ghost.png b/public/images/emoji/apple/ghost.png index 3aad399bd40..2166ae49f56 100644 Binary files a/public/images/emoji/apple/ghost.png and b/public/images/emoji/apple/ghost.png differ diff --git a/public/images/emoji/apple/gift.png b/public/images/emoji/apple/gift.png index 4d5db2ef755..6ce643a2f02 100644 Binary files a/public/images/emoji/apple/gift.png and b/public/images/emoji/apple/gift.png differ diff --git a/public/images/emoji/apple/gift_heart.png b/public/images/emoji/apple/gift_heart.png index 7715b6c7449..9c083596d8d 100644 Binary files a/public/images/emoji/apple/gift_heart.png and b/public/images/emoji/apple/gift_heart.png differ diff --git a/public/images/emoji/apple/girl.png b/public/images/emoji/apple/girl.png index 0c20fb99030..ab8ebc03944 100644 Binary files a/public/images/emoji/apple/girl.png and b/public/images/emoji/apple/girl.png differ diff --git a/public/images/emoji/apple/globe_with_meridians.png b/public/images/emoji/apple/globe_with_meridians.png index 352316135b0..ad52c398992 100644 Binary files a/public/images/emoji/apple/globe_with_meridians.png and b/public/images/emoji/apple/globe_with_meridians.png differ diff --git a/public/images/emoji/apple/goat.png b/public/images/emoji/apple/goat.png index e3f39c2f794..3f733848b3b 100644 Binary files a/public/images/emoji/apple/goat.png and b/public/images/emoji/apple/goat.png differ diff --git a/public/images/emoji/apple/golf.png b/public/images/emoji/apple/golf.png index 49b743d3c27..80179df6617 100644 Binary files a/public/images/emoji/apple/golf.png and b/public/images/emoji/apple/golf.png differ diff --git a/public/images/emoji/apple/golfer.png b/public/images/emoji/apple/golfer.png new file mode 100644 index 00000000000..ddbe2baefb1 Binary files /dev/null and b/public/images/emoji/apple/golfer.png differ diff --git a/public/images/emoji/apple/grapes.png b/public/images/emoji/apple/grapes.png index 1c72b6ac845..82b06b6bb1a 100644 Binary files a/public/images/emoji/apple/grapes.png and b/public/images/emoji/apple/grapes.png differ diff --git a/public/images/emoji/apple/green_apple.png b/public/images/emoji/apple/green_apple.png index ea4d2f17733..c1be9b656e8 100644 Binary files a/public/images/emoji/apple/green_apple.png and b/public/images/emoji/apple/green_apple.png differ diff --git a/public/images/emoji/apple/green_book.png b/public/images/emoji/apple/green_book.png index d7e53e3941b..70366c17847 100644 Binary files a/public/images/emoji/apple/green_book.png and b/public/images/emoji/apple/green_book.png differ diff --git a/public/images/emoji/apple/green_heart.png b/public/images/emoji/apple/green_heart.png index 6b006eadd80..19688bd2c86 100644 Binary files a/public/images/emoji/apple/green_heart.png and b/public/images/emoji/apple/green_heart.png differ diff --git a/public/images/emoji/apple/grey_exclamation.png b/public/images/emoji/apple/grey_exclamation.png index 02c4c84bdbb..59aba9d09fc 100644 Binary files a/public/images/emoji/apple/grey_exclamation.png and b/public/images/emoji/apple/grey_exclamation.png differ diff --git a/public/images/emoji/apple/grey_question.png b/public/images/emoji/apple/grey_question.png index b36ee2d7d3c..2049ace2499 100644 Binary files a/public/images/emoji/apple/grey_question.png and b/public/images/emoji/apple/grey_question.png differ diff --git a/public/images/emoji/apple/grimacing.png b/public/images/emoji/apple/grimacing.png index cd7f99ee18f..814266fa074 100644 Binary files a/public/images/emoji/apple/grimacing.png and b/public/images/emoji/apple/grimacing.png differ diff --git a/public/images/emoji/apple/grin.png b/public/images/emoji/apple/grin.png index d00c7e66fd7..350c5dbbed0 100644 Binary files a/public/images/emoji/apple/grin.png and b/public/images/emoji/apple/grin.png differ diff --git a/public/images/emoji/apple/grinning.png b/public/images/emoji/apple/grinning.png index 77d0fd081a3..2b9b09bb64e 100644 Binary files a/public/images/emoji/apple/grinning.png and b/public/images/emoji/apple/grinning.png differ diff --git a/public/images/emoji/apple/guardsman.png b/public/images/emoji/apple/guardsman.png index e22e2b40470..92fe86fe960 100644 Binary files a/public/images/emoji/apple/guardsman.png and b/public/images/emoji/apple/guardsman.png differ diff --git a/public/images/emoji/apple/guitar.png b/public/images/emoji/apple/guitar.png index aa92056c09a..9d5b90a17be 100644 Binary files a/public/images/emoji/apple/guitar.png and b/public/images/emoji/apple/guitar.png differ diff --git a/public/images/emoji/apple/gun.png b/public/images/emoji/apple/gun.png index a5a278eb339..f4f717415a4 100644 Binary files a/public/images/emoji/apple/gun.png and b/public/images/emoji/apple/gun.png differ diff --git a/public/images/emoji/apple/haircut.png b/public/images/emoji/apple/haircut.png index 8a2702166f8..5635ced6710 100644 Binary files a/public/images/emoji/apple/haircut.png and b/public/images/emoji/apple/haircut.png differ diff --git a/public/images/emoji/apple/hamburger.png b/public/images/emoji/apple/hamburger.png index 7fbc23ddb11..57370bb6618 100644 Binary files a/public/images/emoji/apple/hamburger.png and b/public/images/emoji/apple/hamburger.png differ diff --git a/public/images/emoji/apple/hammer.png b/public/images/emoji/apple/hammer.png index cb30c5d5e30..b6bf1e115ab 100644 Binary files a/public/images/emoji/apple/hammer.png and b/public/images/emoji/apple/hammer.png differ diff --git a/public/images/emoji/apple/hammer_pick.png b/public/images/emoji/apple/hammer_pick.png new file mode 100644 index 00000000000..d18d84cf96d Binary files /dev/null and b/public/images/emoji/apple/hammer_pick.png differ diff --git a/public/images/emoji/apple/hamster.png b/public/images/emoji/apple/hamster.png index 3c3c509ab62..b15c000eff2 100644 Binary files a/public/images/emoji/apple/hamster.png and b/public/images/emoji/apple/hamster.png differ diff --git a/public/images/emoji/apple/hand.png b/public/images/emoji/apple/hand.png index dea31537583..ee11cca7bde 100644 Binary files a/public/images/emoji/apple/hand.png and b/public/images/emoji/apple/hand.png differ diff --git a/public/images/emoji/apple/hand_splayed.png b/public/images/emoji/apple/hand_splayed.png new file mode 100644 index 00000000000..f26ba2724d7 Binary files /dev/null and b/public/images/emoji/apple/hand_splayed.png differ diff --git a/public/images/emoji/apple/handbag.png b/public/images/emoji/apple/handbag.png index aa0e951ad45..138ae9e263a 100644 Binary files a/public/images/emoji/apple/handbag.png and b/public/images/emoji/apple/handbag.png differ diff --git a/public/images/emoji/apple/hankey.png b/public/images/emoji/apple/hankey.png index 75544655b3f..4806bffbabe 100644 Binary files a/public/images/emoji/apple/hankey.png and b/public/images/emoji/apple/hankey.png differ diff --git a/public/images/emoji/apple/hash.png b/public/images/emoji/apple/hash.png index e1e5923d41f..d80068cdf6c 100644 Binary files a/public/images/emoji/apple/hash.png and b/public/images/emoji/apple/hash.png differ diff --git a/public/images/emoji/apple/hatched_chick.png b/public/images/emoji/apple/hatched_chick.png index 3e6d9bd73ec..cb563512905 100644 Binary files a/public/images/emoji/apple/hatched_chick.png and b/public/images/emoji/apple/hatched_chick.png differ diff --git a/public/images/emoji/apple/hatching_chick.png b/public/images/emoji/apple/hatching_chick.png index 1e11c41520d..0951038f274 100644 Binary files a/public/images/emoji/apple/hatching_chick.png and b/public/images/emoji/apple/hatching_chick.png differ diff --git a/public/images/emoji/apple/head_bandage.png b/public/images/emoji/apple/head_bandage.png new file mode 100644 index 00000000000..f3fb32796fa Binary files /dev/null and b/public/images/emoji/apple/head_bandage.png differ diff --git a/public/images/emoji/apple/headphones.png b/public/images/emoji/apple/headphones.png index 3c1a1240ca2..9b5bde3bc2d 100644 Binary files a/public/images/emoji/apple/headphones.png and b/public/images/emoji/apple/headphones.png differ diff --git a/public/images/emoji/apple/hear_no_evil.png b/public/images/emoji/apple/hear_no_evil.png index 7e8a512825b..3f7ac5c3539 100644 Binary files a/public/images/emoji/apple/hear_no_evil.png and b/public/images/emoji/apple/hear_no_evil.png differ diff --git a/public/images/emoji/apple/heart.png b/public/images/emoji/apple/heart.png index 8e908d53f92..42a0345b9da 100644 Binary files a/public/images/emoji/apple/heart.png and b/public/images/emoji/apple/heart.png differ diff --git a/public/images/emoji/apple/heart_decoration.png b/public/images/emoji/apple/heart_decoration.png index 458a0ca07f4..0d9278ff6a6 100644 Binary files a/public/images/emoji/apple/heart_decoration.png and b/public/images/emoji/apple/heart_decoration.png differ diff --git a/public/images/emoji/apple/heart_exclamation.png b/public/images/emoji/apple/heart_exclamation.png new file mode 100644 index 00000000000..6b4ad655b30 Binary files /dev/null and b/public/images/emoji/apple/heart_exclamation.png differ diff --git a/public/images/emoji/apple/heart_eyes.png b/public/images/emoji/apple/heart_eyes.png index e63dbfda559..13c50ef2055 100644 Binary files a/public/images/emoji/apple/heart_eyes.png and b/public/images/emoji/apple/heart_eyes.png differ diff --git a/public/images/emoji/apple/heart_eyes_cat.png b/public/images/emoji/apple/heart_eyes_cat.png index b978329cbc4..3a4279b965e 100644 Binary files a/public/images/emoji/apple/heart_eyes_cat.png and b/public/images/emoji/apple/heart_eyes_cat.png differ diff --git a/public/images/emoji/apple/heartbeat.png b/public/images/emoji/apple/heartbeat.png index 9f4b41d32af..56ee7c2be4e 100644 Binary files a/public/images/emoji/apple/heartbeat.png and b/public/images/emoji/apple/heartbeat.png differ diff --git a/public/images/emoji/apple/heartpulse.png b/public/images/emoji/apple/heartpulse.png index 6e99d65f5c0..2d6257b63ff 100644 Binary files a/public/images/emoji/apple/heartpulse.png and b/public/images/emoji/apple/heartpulse.png differ diff --git a/public/images/emoji/apple/hearts.png b/public/images/emoji/apple/hearts.png index bd48264b359..6800fca9d27 100644 Binary files a/public/images/emoji/apple/hearts.png and b/public/images/emoji/apple/hearts.png differ diff --git a/public/images/emoji/apple/heavy_check_mark.png b/public/images/emoji/apple/heavy_check_mark.png index 34d8b9729e4..7d83081cfa7 100644 Binary files a/public/images/emoji/apple/heavy_check_mark.png and b/public/images/emoji/apple/heavy_check_mark.png differ diff --git a/public/images/emoji/apple/heavy_division_sign.png b/public/images/emoji/apple/heavy_division_sign.png index 1604f29170e..ee8aae0695a 100644 Binary files a/public/images/emoji/apple/heavy_division_sign.png and b/public/images/emoji/apple/heavy_division_sign.png differ diff --git a/public/images/emoji/apple/heavy_dollar_sign.png b/public/images/emoji/apple/heavy_dollar_sign.png index 103e0a4ce39..117325dc75f 100644 Binary files a/public/images/emoji/apple/heavy_dollar_sign.png and b/public/images/emoji/apple/heavy_dollar_sign.png differ diff --git a/public/images/emoji/apple/heavy_exclamation_mark.png b/public/images/emoji/apple/heavy_exclamation_mark.png index 43f4583418a..3d585df798b 100644 Binary files a/public/images/emoji/apple/heavy_exclamation_mark.png and b/public/images/emoji/apple/heavy_exclamation_mark.png differ diff --git a/public/images/emoji/apple/heavy_minus_sign.png b/public/images/emoji/apple/heavy_minus_sign.png index 6c64405f732..492913aa390 100644 Binary files a/public/images/emoji/apple/heavy_minus_sign.png and b/public/images/emoji/apple/heavy_minus_sign.png differ diff --git a/public/images/emoji/apple/heavy_multiplication_x.png b/public/images/emoji/apple/heavy_multiplication_x.png index eaf9a6392f6..1916e4062a0 100644 Binary files a/public/images/emoji/apple/heavy_multiplication_x.png and b/public/images/emoji/apple/heavy_multiplication_x.png differ diff --git a/public/images/emoji/apple/heavy_plus_sign.png b/public/images/emoji/apple/heavy_plus_sign.png index 07d7b8a9055..b463983c773 100644 Binary files a/public/images/emoji/apple/heavy_plus_sign.png and b/public/images/emoji/apple/heavy_plus_sign.png differ diff --git a/public/images/emoji/apple/helicopter.png b/public/images/emoji/apple/helicopter.png index 1ee25fa3abf..a52cb26db50 100644 Binary files a/public/images/emoji/apple/helicopter.png and b/public/images/emoji/apple/helicopter.png differ diff --git a/public/images/emoji/apple/helmet_with_cross.png b/public/images/emoji/apple/helmet_with_cross.png new file mode 100644 index 00000000000..e93c2897c7f Binary files /dev/null and b/public/images/emoji/apple/helmet_with_cross.png differ diff --git a/public/images/emoji/apple/herb.png b/public/images/emoji/apple/herb.png index 75df4cee059..436fd17d766 100644 Binary files a/public/images/emoji/apple/herb.png and b/public/images/emoji/apple/herb.png differ diff --git a/public/images/emoji/apple/hibiscus.png b/public/images/emoji/apple/hibiscus.png index 567f8cc0270..ac18da8ee96 100644 Binary files a/public/images/emoji/apple/hibiscus.png and b/public/images/emoji/apple/hibiscus.png differ diff --git a/public/images/emoji/apple/high_brightness.png b/public/images/emoji/apple/high_brightness.png index 49bfcfdfe55..f3b9e97816e 100644 Binary files a/public/images/emoji/apple/high_brightness.png and b/public/images/emoji/apple/high_brightness.png differ diff --git a/public/images/emoji/apple/high_heel.png b/public/images/emoji/apple/high_heel.png index 4562be9dab0..845655fbbc5 100644 Binary files a/public/images/emoji/apple/high_heel.png and b/public/images/emoji/apple/high_heel.png differ diff --git a/public/images/emoji/apple/hocho.png b/public/images/emoji/apple/hocho.png index 630397cd392..08195b63127 100644 Binary files a/public/images/emoji/apple/hocho.png and b/public/images/emoji/apple/hocho.png differ diff --git a/public/images/emoji/apple/hockey.png b/public/images/emoji/apple/hockey.png new file mode 100644 index 00000000000..b6fb640c5ce Binary files /dev/null and b/public/images/emoji/apple/hockey.png differ diff --git a/public/images/emoji/apple/hole.png b/public/images/emoji/apple/hole.png new file mode 100644 index 00000000000..dba53ead68f Binary files /dev/null and b/public/images/emoji/apple/hole.png differ diff --git a/public/images/emoji/apple/homes.png b/public/images/emoji/apple/homes.png new file mode 100644 index 00000000000..08f06a1fd2d Binary files /dev/null and b/public/images/emoji/apple/homes.png differ diff --git a/public/images/emoji/apple/honey_pot.png b/public/images/emoji/apple/honey_pot.png index d7fbb7408ff..df03acfbcf5 100644 Binary files a/public/images/emoji/apple/honey_pot.png and b/public/images/emoji/apple/honey_pot.png differ diff --git a/public/images/emoji/apple/honeybee.png b/public/images/emoji/apple/honeybee.png index 8ae23dfbcfc..5f56f6e8789 100644 Binary files a/public/images/emoji/apple/honeybee.png and b/public/images/emoji/apple/honeybee.png differ diff --git a/public/images/emoji/apple/horse.png b/public/images/emoji/apple/horse.png index f8b53487d38..042a1414e49 100644 Binary files a/public/images/emoji/apple/horse.png and b/public/images/emoji/apple/horse.png differ diff --git a/public/images/emoji/apple/horse_racing.png b/public/images/emoji/apple/horse_racing.png index e5cd7f5dfc1..6cc48addee0 100644 Binary files a/public/images/emoji/apple/horse_racing.png and b/public/images/emoji/apple/horse_racing.png differ diff --git a/public/images/emoji/apple/hospital.png b/public/images/emoji/apple/hospital.png index ba7a2a4216f..2106ccc5131 100644 Binary files a/public/images/emoji/apple/hospital.png and b/public/images/emoji/apple/hospital.png differ diff --git a/public/images/emoji/apple/hot_pepper.png b/public/images/emoji/apple/hot_pepper.png new file mode 100644 index 00000000000..70669ca8749 Binary files /dev/null and b/public/images/emoji/apple/hot_pepper.png differ diff --git a/public/images/emoji/apple/hotdog.png b/public/images/emoji/apple/hotdog.png new file mode 100644 index 00000000000..262c1cde79c Binary files /dev/null and b/public/images/emoji/apple/hotdog.png differ diff --git a/public/images/emoji/apple/hotel.png b/public/images/emoji/apple/hotel.png index a37c5940c7a..a76cbd53677 100644 Binary files a/public/images/emoji/apple/hotel.png and b/public/images/emoji/apple/hotel.png differ diff --git a/public/images/emoji/apple/hotsprings.png b/public/images/emoji/apple/hotsprings.png index 7370ceb6024..9e52daf8a88 100644 Binary files a/public/images/emoji/apple/hotsprings.png and b/public/images/emoji/apple/hotsprings.png differ diff --git a/public/images/emoji/apple/hourglass.png b/public/images/emoji/apple/hourglass.png index 37295ff8165..b1e9a8d31ab 100644 Binary files a/public/images/emoji/apple/hourglass.png and b/public/images/emoji/apple/hourglass.png differ diff --git a/public/images/emoji/apple/hourglass_flowing_sand.png b/public/images/emoji/apple/hourglass_flowing_sand.png index 12ce4252be0..b1f8b76fa66 100644 Binary files a/public/images/emoji/apple/hourglass_flowing_sand.png and b/public/images/emoji/apple/hourglass_flowing_sand.png differ diff --git a/public/images/emoji/apple/house.png b/public/images/emoji/apple/house.png index 4e17b37a8b2..c03fa95554a 100644 Binary files a/public/images/emoji/apple/house.png and b/public/images/emoji/apple/house.png differ diff --git a/public/images/emoji/apple/house_abandoned.png b/public/images/emoji/apple/house_abandoned.png new file mode 100644 index 00000000000..91de0770164 Binary files /dev/null and b/public/images/emoji/apple/house_abandoned.png differ diff --git a/public/images/emoji/apple/house_with_garden.png b/public/images/emoji/apple/house_with_garden.png index 0b0ada8f413..a204451bfe6 100644 Binary files a/public/images/emoji/apple/house_with_garden.png and b/public/images/emoji/apple/house_with_garden.png differ diff --git a/public/images/emoji/apple/hugging.png b/public/images/emoji/apple/hugging.png new file mode 100644 index 00000000000..efe205463bd Binary files /dev/null and b/public/images/emoji/apple/hugging.png differ diff --git a/public/images/emoji/apple/hushed.png b/public/images/emoji/apple/hushed.png index d91a51f6346..660a11c813b 100644 Binary files a/public/images/emoji/apple/hushed.png and b/public/images/emoji/apple/hushed.png differ diff --git a/public/images/emoji/apple/ice_cream.png b/public/images/emoji/apple/ice_cream.png index c7290605938..18e395d8915 100644 Binary files a/public/images/emoji/apple/ice_cream.png and b/public/images/emoji/apple/ice_cream.png differ diff --git a/public/images/emoji/apple/ice_skate.png b/public/images/emoji/apple/ice_skate.png new file mode 100644 index 00000000000..ed97c898b5e Binary files /dev/null and b/public/images/emoji/apple/ice_skate.png differ diff --git a/public/images/emoji/apple/icecream.png b/public/images/emoji/apple/icecream.png index 4af3cbbb101..37141ecf6d1 100644 Binary files a/public/images/emoji/apple/icecream.png and b/public/images/emoji/apple/icecream.png differ diff --git a/public/images/emoji/apple/id.png b/public/images/emoji/apple/id.png index 83f4c2bbe10..7ae173c379f 100644 Binary files a/public/images/emoji/apple/id.png and b/public/images/emoji/apple/id.png differ diff --git a/public/images/emoji/apple/ideograph_advantage.png b/public/images/emoji/apple/ideograph_advantage.png index 9287867239c..2e1a1eefcca 100644 Binary files a/public/images/emoji/apple/ideograph_advantage.png and b/public/images/emoji/apple/ideograph_advantage.png differ diff --git a/public/images/emoji/apple/imp.png b/public/images/emoji/apple/imp.png index eb2e9ccad46..c5419d5d8dc 100644 Binary files a/public/images/emoji/apple/imp.png and b/public/images/emoji/apple/imp.png differ diff --git a/public/images/emoji/apple/inbox_tray.png b/public/images/emoji/apple/inbox_tray.png index 2a23106620e..96896d1f18f 100644 Binary files a/public/images/emoji/apple/inbox_tray.png and b/public/images/emoji/apple/inbox_tray.png differ diff --git a/public/images/emoji/apple/incoming_envelope.png b/public/images/emoji/apple/incoming_envelope.png index fb0a4c80413..be1e6ca7cb6 100644 Binary files a/public/images/emoji/apple/incoming_envelope.png and b/public/images/emoji/apple/incoming_envelope.png differ diff --git a/public/images/emoji/apple/information_desk_person.png b/public/images/emoji/apple/information_desk_person.png index 8804a07a3dd..f0f2f06e913 100644 Binary files a/public/images/emoji/apple/information_desk_person.png and b/public/images/emoji/apple/information_desk_person.png differ diff --git a/public/images/emoji/apple/information_source.png b/public/images/emoji/apple/information_source.png index 47ba0cf16b9..f20c5d16837 100644 Binary files a/public/images/emoji/apple/information_source.png and b/public/images/emoji/apple/information_source.png differ diff --git a/public/images/emoji/apple/innocent.png b/public/images/emoji/apple/innocent.png index 04911a92ad4..ac819fd42d9 100644 Binary files a/public/images/emoji/apple/innocent.png and b/public/images/emoji/apple/innocent.png differ diff --git a/public/images/emoji/apple/interrobang.png b/public/images/emoji/apple/interrobang.png index 23dc8549df0..cacb8b89961 100644 Binary files a/public/images/emoji/apple/interrobang.png and b/public/images/emoji/apple/interrobang.png differ diff --git a/public/images/emoji/apple/iphone.png b/public/images/emoji/apple/iphone.png index 615468a4b70..0e2b9ac5c90 100644 Binary files a/public/images/emoji/apple/iphone.png and b/public/images/emoji/apple/iphone.png differ diff --git a/public/images/emoji/apple/island.png b/public/images/emoji/apple/island.png new file mode 100644 index 00000000000..d5957062bf0 Binary files /dev/null and b/public/images/emoji/apple/island.png differ diff --git a/public/images/emoji/apple/it.png b/public/images/emoji/apple/it.png index d1dee29e894..c332890a00d 100644 Binary files a/public/images/emoji/apple/it.png and b/public/images/emoji/apple/it.png differ diff --git a/public/images/emoji/apple/izakaya_lantern.png b/public/images/emoji/apple/izakaya_lantern.png index 6fbe745103b..cd73b3dfc76 100644 Binary files a/public/images/emoji/apple/izakaya_lantern.png and b/public/images/emoji/apple/izakaya_lantern.png differ diff --git a/public/images/emoji/apple/jack_o_lantern.png b/public/images/emoji/apple/jack_o_lantern.png index 1640d67f8ca..a24698fe92b 100644 Binary files a/public/images/emoji/apple/jack_o_lantern.png and b/public/images/emoji/apple/jack_o_lantern.png differ diff --git a/public/images/emoji/apple/japan.png b/public/images/emoji/apple/japan.png index 93e4c082211..e7c7b901e66 100644 Binary files a/public/images/emoji/apple/japan.png and b/public/images/emoji/apple/japan.png differ diff --git a/public/images/emoji/apple/japanese_castle.png b/public/images/emoji/apple/japanese_castle.png index 547d8075e56..73d09382d4b 100644 Binary files a/public/images/emoji/apple/japanese_castle.png and b/public/images/emoji/apple/japanese_castle.png differ diff --git a/public/images/emoji/apple/japanese_goblin.png b/public/images/emoji/apple/japanese_goblin.png index d00f9f3e83d..0478af39088 100644 Binary files a/public/images/emoji/apple/japanese_goblin.png and b/public/images/emoji/apple/japanese_goblin.png differ diff --git a/public/images/emoji/apple/japanese_ogre.png b/public/images/emoji/apple/japanese_ogre.png index 5ad27b97749..8d37eeeae31 100644 Binary files a/public/images/emoji/apple/japanese_ogre.png and b/public/images/emoji/apple/japanese_ogre.png differ diff --git a/public/images/emoji/apple/jeans.png b/public/images/emoji/apple/jeans.png index 46392d282b5..6523fe5747e 100644 Binary files a/public/images/emoji/apple/jeans.png and b/public/images/emoji/apple/jeans.png differ diff --git a/public/images/emoji/apple/joy.png b/public/images/emoji/apple/joy.png index 9264720e705..5592587f49b 100644 Binary files a/public/images/emoji/apple/joy.png and b/public/images/emoji/apple/joy.png differ diff --git a/public/images/emoji/apple/joy_cat.png b/public/images/emoji/apple/joy_cat.png index b5cf7b6ca91..206ebb86557 100644 Binary files a/public/images/emoji/apple/joy_cat.png and b/public/images/emoji/apple/joy_cat.png differ diff --git a/public/images/emoji/apple/joystick.png b/public/images/emoji/apple/joystick.png new file mode 100644 index 00000000000..198d724907d Binary files /dev/null and b/public/images/emoji/apple/joystick.png differ diff --git a/public/images/emoji/apple/jp.png b/public/images/emoji/apple/jp.png index 8487914a71e..beb79a4acea 100644 Binary files a/public/images/emoji/apple/jp.png and b/public/images/emoji/apple/jp.png differ diff --git a/public/images/emoji/apple/kaaba.png b/public/images/emoji/apple/kaaba.png new file mode 100644 index 00000000000..7319c5b0657 Binary files /dev/null and b/public/images/emoji/apple/kaaba.png differ diff --git a/public/images/emoji/apple/key.png b/public/images/emoji/apple/key.png index 65c4521520a..219fb946726 100644 Binary files a/public/images/emoji/apple/key.png and b/public/images/emoji/apple/key.png differ diff --git a/public/images/emoji/apple/key2.png b/public/images/emoji/apple/key2.png new file mode 100644 index 00000000000..0fe04f3d27c Binary files /dev/null and b/public/images/emoji/apple/key2.png differ diff --git a/public/images/emoji/apple/keyboard.png b/public/images/emoji/apple/keyboard.png new file mode 100644 index 00000000000..f4e6fa7ee62 Binary files /dev/null and b/public/images/emoji/apple/keyboard.png differ diff --git a/public/images/emoji/apple/keycap_ten.png b/public/images/emoji/apple/keycap_ten.png index bbdec44dcae..006ccbb90b1 100644 Binary files a/public/images/emoji/apple/keycap_ten.png and b/public/images/emoji/apple/keycap_ten.png differ diff --git a/public/images/emoji/apple/kimono.png b/public/images/emoji/apple/kimono.png index 6fc096bbd3a..41fd0ba14c4 100644 Binary files a/public/images/emoji/apple/kimono.png and b/public/images/emoji/apple/kimono.png differ diff --git a/public/images/emoji/apple/kiss.png b/public/images/emoji/apple/kiss.png index 93e24f30f4a..27440c119fa 100644 Binary files a/public/images/emoji/apple/kiss.png and b/public/images/emoji/apple/kiss.png differ diff --git a/public/images/emoji/apple/kissing.png b/public/images/emoji/apple/kissing.png index 68ff8480e86..1e1de37c461 100644 Binary files a/public/images/emoji/apple/kissing.png and b/public/images/emoji/apple/kissing.png differ diff --git a/public/images/emoji/apple/kissing_cat.png b/public/images/emoji/apple/kissing_cat.png index 1b1d0ca7831..55e67da1cc6 100644 Binary files a/public/images/emoji/apple/kissing_cat.png and b/public/images/emoji/apple/kissing_cat.png differ diff --git a/public/images/emoji/apple/kissing_closed_eyes.png b/public/images/emoji/apple/kissing_closed_eyes.png index be4934b0c36..d922c081e11 100644 Binary files a/public/images/emoji/apple/kissing_closed_eyes.png and b/public/images/emoji/apple/kissing_closed_eyes.png differ diff --git a/public/images/emoji/apple/kissing_heart.png b/public/images/emoji/apple/kissing_heart.png index 1df787f0e9b..d2fe03b9f35 100644 Binary files a/public/images/emoji/apple/kissing_heart.png and b/public/images/emoji/apple/kissing_heart.png differ diff --git a/public/images/emoji/apple/kissing_smiling_eyes.png b/public/images/emoji/apple/kissing_smiling_eyes.png index 3410556c25e..fcf20828518 100644 Binary files a/public/images/emoji/apple/kissing_smiling_eyes.png and b/public/images/emoji/apple/kissing_smiling_eyes.png differ diff --git a/public/images/emoji/apple/knife.png b/public/images/emoji/apple/knife.png index 630397cd392..7cd04b3e0f5 100644 Binary files a/public/images/emoji/apple/knife.png and b/public/images/emoji/apple/knife.png differ diff --git a/public/images/emoji/apple/koala.png b/public/images/emoji/apple/koala.png index 63a4f04256f..17eeba297f3 100644 Binary files a/public/images/emoji/apple/koala.png and b/public/images/emoji/apple/koala.png differ diff --git a/public/images/emoji/apple/koko.png b/public/images/emoji/apple/koko.png index 5f8c3cb90af..215f0a92392 100644 Binary files a/public/images/emoji/apple/koko.png and b/public/images/emoji/apple/koko.png differ diff --git a/public/images/emoji/apple/kr.png b/public/images/emoji/apple/kr.png index 5640546ef45..e9b0b623f70 100644 Binary files a/public/images/emoji/apple/kr.png and b/public/images/emoji/apple/kr.png differ diff --git a/public/images/emoji/apple/label.png b/public/images/emoji/apple/label.png new file mode 100644 index 00000000000..b1d0009545b Binary files /dev/null and b/public/images/emoji/apple/label.png differ diff --git a/public/images/emoji/apple/lantern.png b/public/images/emoji/apple/lantern.png index 6fbe745103b..9c8448acc51 100644 Binary files a/public/images/emoji/apple/lantern.png and b/public/images/emoji/apple/lantern.png differ diff --git a/public/images/emoji/apple/large_blue_circle.png b/public/images/emoji/apple/large_blue_circle.png index 5df409a5b06..ed831d4e515 100644 Binary files a/public/images/emoji/apple/large_blue_circle.png and b/public/images/emoji/apple/large_blue_circle.png differ diff --git a/public/images/emoji/apple/large_blue_diamond.png b/public/images/emoji/apple/large_blue_diamond.png index 70b7eb05d7d..81b53484e43 100644 Binary files a/public/images/emoji/apple/large_blue_diamond.png and b/public/images/emoji/apple/large_blue_diamond.png differ diff --git a/public/images/emoji/apple/large_orange_diamond.png b/public/images/emoji/apple/large_orange_diamond.png index 585da560085..dea9d62e5be 100644 Binary files a/public/images/emoji/apple/large_orange_diamond.png and b/public/images/emoji/apple/large_orange_diamond.png differ diff --git a/public/images/emoji/apple/last_quarter_moon.png b/public/images/emoji/apple/last_quarter_moon.png index 235b715a8bf..2cacb70a5d8 100644 Binary files a/public/images/emoji/apple/last_quarter_moon.png and b/public/images/emoji/apple/last_quarter_moon.png differ diff --git a/public/images/emoji/apple/last_quarter_moon_with_face.png b/public/images/emoji/apple/last_quarter_moon_with_face.png index 2c9f57694c3..6f0a426d561 100644 Binary files a/public/images/emoji/apple/last_quarter_moon_with_face.png and b/public/images/emoji/apple/last_quarter_moon_with_face.png differ diff --git a/public/images/emoji/apple/laughing.png b/public/images/emoji/apple/laughing.png index 85605c7329d..2dc47165e3a 100644 Binary files a/public/images/emoji/apple/laughing.png and b/public/images/emoji/apple/laughing.png differ diff --git a/public/images/emoji/apple/leaves.png b/public/images/emoji/apple/leaves.png index 85bc9d874a2..9b43e5a08a6 100644 Binary files a/public/images/emoji/apple/leaves.png and b/public/images/emoji/apple/leaves.png differ diff --git a/public/images/emoji/apple/ledger.png b/public/images/emoji/apple/ledger.png index 85443655f78..50905acae64 100644 Binary files a/public/images/emoji/apple/ledger.png and b/public/images/emoji/apple/ledger.png differ diff --git a/public/images/emoji/apple/left_luggage.png b/public/images/emoji/apple/left_luggage.png index fa742b16a9b..94b692a1d88 100644 Binary files a/public/images/emoji/apple/left_luggage.png and b/public/images/emoji/apple/left_luggage.png differ diff --git a/public/images/emoji/apple/left_right_arrow.png b/public/images/emoji/apple/left_right_arrow.png index bc198fc7ba3..b5971c8242d 100644 Binary files a/public/images/emoji/apple/left_right_arrow.png and b/public/images/emoji/apple/left_right_arrow.png differ diff --git a/public/images/emoji/apple/leftwards_arrow_with_hook.png b/public/images/emoji/apple/leftwards_arrow_with_hook.png index fb930823128..a5c73faa610 100644 Binary files a/public/images/emoji/apple/leftwards_arrow_with_hook.png and b/public/images/emoji/apple/leftwards_arrow_with_hook.png differ diff --git a/public/images/emoji/apple/lemon.png b/public/images/emoji/apple/lemon.png index e2754e6478c..1acea0f94ed 100644 Binary files a/public/images/emoji/apple/lemon.png and b/public/images/emoji/apple/lemon.png differ diff --git a/public/images/emoji/apple/leo.png b/public/images/emoji/apple/leo.png index 7f615958164..a0ec5e6b337 100644 Binary files a/public/images/emoji/apple/leo.png and b/public/images/emoji/apple/leo.png differ diff --git a/public/images/emoji/apple/leopard.png b/public/images/emoji/apple/leopard.png index 8451b91a3a1..78e98d15c53 100644 Binary files a/public/images/emoji/apple/leopard.png and b/public/images/emoji/apple/leopard.png differ diff --git a/public/images/emoji/apple/level_slider.png b/public/images/emoji/apple/level_slider.png new file mode 100644 index 00000000000..3a1eef0fa8b Binary files /dev/null and b/public/images/emoji/apple/level_slider.png differ diff --git a/public/images/emoji/apple/levitate.png b/public/images/emoji/apple/levitate.png new file mode 100644 index 00000000000..2021cb1ce7d Binary files /dev/null and b/public/images/emoji/apple/levitate.png differ diff --git a/public/images/emoji/apple/libra.png b/public/images/emoji/apple/libra.png index 95b0aa7fe9a..f7c5c06075a 100644 Binary files a/public/images/emoji/apple/libra.png and b/public/images/emoji/apple/libra.png differ diff --git a/public/images/emoji/apple/lifter.png b/public/images/emoji/apple/lifter.png new file mode 100644 index 00000000000..f86ca733358 Binary files /dev/null and b/public/images/emoji/apple/lifter.png differ diff --git a/public/images/emoji/apple/light_rail.png b/public/images/emoji/apple/light_rail.png index 2a4830d3d2d..85d94ff3ec7 100644 Binary files a/public/images/emoji/apple/light_rail.png and b/public/images/emoji/apple/light_rail.png differ diff --git a/public/images/emoji/apple/link.png b/public/images/emoji/apple/link.png index 6519f662013..525fc6bdd6a 100644 Binary files a/public/images/emoji/apple/link.png and b/public/images/emoji/apple/link.png differ diff --git a/public/images/emoji/apple/lion_face.png b/public/images/emoji/apple/lion_face.png new file mode 100644 index 00000000000..0be5ba6dfe8 Binary files /dev/null and b/public/images/emoji/apple/lion_face.png differ diff --git a/public/images/emoji/apple/lips.png b/public/images/emoji/apple/lips.png index a97856b47d6..f64367f1c81 100644 Binary files a/public/images/emoji/apple/lips.png and b/public/images/emoji/apple/lips.png differ diff --git a/public/images/emoji/apple/lipstick.png b/public/images/emoji/apple/lipstick.png index e26b2a801dc..f87a1dfde86 100644 Binary files a/public/images/emoji/apple/lipstick.png and b/public/images/emoji/apple/lipstick.png differ diff --git a/public/images/emoji/apple/lock.png b/public/images/emoji/apple/lock.png index 14c87731152..c64fcb3d1fa 100644 Binary files a/public/images/emoji/apple/lock.png and b/public/images/emoji/apple/lock.png differ diff --git a/public/images/emoji/apple/lock_with_ink_pen.png b/public/images/emoji/apple/lock_with_ink_pen.png index 4490b88983d..84d4dd259c8 100644 Binary files a/public/images/emoji/apple/lock_with_ink_pen.png and b/public/images/emoji/apple/lock_with_ink_pen.png differ diff --git a/public/images/emoji/apple/lollipop.png b/public/images/emoji/apple/lollipop.png index 65c89afc423..71d192b646b 100644 Binary files a/public/images/emoji/apple/lollipop.png and b/public/images/emoji/apple/lollipop.png differ diff --git a/public/images/emoji/apple/loop.png b/public/images/emoji/apple/loop.png index c34cc067af6..9d7104ee602 100644 Binary files a/public/images/emoji/apple/loop.png and b/public/images/emoji/apple/loop.png differ diff --git a/public/images/emoji/apple/loud_sound.png b/public/images/emoji/apple/loud_sound.png index 291444e4021..3a0d5d1ca7f 100644 Binary files a/public/images/emoji/apple/loud_sound.png and b/public/images/emoji/apple/loud_sound.png differ diff --git a/public/images/emoji/apple/loudspeaker.png b/public/images/emoji/apple/loudspeaker.png index 4e5a409fcd1..b3f28359e35 100644 Binary files a/public/images/emoji/apple/loudspeaker.png and b/public/images/emoji/apple/loudspeaker.png differ diff --git a/public/images/emoji/apple/love_hotel.png b/public/images/emoji/apple/love_hotel.png index eea9d5a6e1f..97c184ff4ea 100644 Binary files a/public/images/emoji/apple/love_hotel.png and b/public/images/emoji/apple/love_hotel.png differ diff --git a/public/images/emoji/apple/love_letter.png b/public/images/emoji/apple/love_letter.png index b2a395ac92f..84437f95c40 100644 Binary files a/public/images/emoji/apple/love_letter.png and b/public/images/emoji/apple/love_letter.png differ diff --git a/public/images/emoji/apple/low_brightness.png b/public/images/emoji/apple/low_brightness.png index 7fbe82ae64d..68afb33a05f 100644 Binary files a/public/images/emoji/apple/low_brightness.png and b/public/images/emoji/apple/low_brightness.png differ diff --git a/public/images/emoji/apple/m.png b/public/images/emoji/apple/m.png index 2ac1e8c97bd..1f7adc773ce 100644 Binary files a/public/images/emoji/apple/m.png and b/public/images/emoji/apple/m.png differ diff --git a/public/images/emoji/apple/mag.png b/public/images/emoji/apple/mag.png index e5232968729..2aa16e4b840 100644 Binary files a/public/images/emoji/apple/mag.png and b/public/images/emoji/apple/mag.png differ diff --git a/public/images/emoji/apple/mag_right.png b/public/images/emoji/apple/mag_right.png index 1957b4f2f91..566397542b7 100644 Binary files a/public/images/emoji/apple/mag_right.png and b/public/images/emoji/apple/mag_right.png differ diff --git a/public/images/emoji/apple/mahjong.png b/public/images/emoji/apple/mahjong.png index 3e9a30d4007..ba805c9eded 100644 Binary files a/public/images/emoji/apple/mahjong.png and b/public/images/emoji/apple/mahjong.png differ diff --git a/public/images/emoji/apple/mailbox.png b/public/images/emoji/apple/mailbox.png index 63d1cdc871e..9c10234886d 100644 Binary files a/public/images/emoji/apple/mailbox.png and b/public/images/emoji/apple/mailbox.png differ diff --git a/public/images/emoji/apple/mailbox_closed.png b/public/images/emoji/apple/mailbox_closed.png index fd314b8d3b2..fea4b62f08d 100644 Binary files a/public/images/emoji/apple/mailbox_closed.png and b/public/images/emoji/apple/mailbox_closed.png differ diff --git a/public/images/emoji/apple/mailbox_with_mail.png b/public/images/emoji/apple/mailbox_with_mail.png index 2a4a15c4ed2..8a1ad5bb495 100644 Binary files a/public/images/emoji/apple/mailbox_with_mail.png and b/public/images/emoji/apple/mailbox_with_mail.png differ diff --git a/public/images/emoji/apple/mailbox_with_no_mail.png b/public/images/emoji/apple/mailbox_with_no_mail.png index c4bda7acfcc..5d482d4ac0d 100644 Binary files a/public/images/emoji/apple/mailbox_with_no_mail.png and b/public/images/emoji/apple/mailbox_with_no_mail.png differ diff --git a/public/images/emoji/apple/man.png b/public/images/emoji/apple/man.png index f9f182c891c..be1c672e128 100644 Binary files a/public/images/emoji/apple/man.png and b/public/images/emoji/apple/man.png differ diff --git a/public/images/emoji/apple/man_with_gua_pi_mao.png b/public/images/emoji/apple/man_with_gua_pi_mao.png index 5e256981b18..018dbc1078a 100644 Binary files a/public/images/emoji/apple/man_with_gua_pi_mao.png and b/public/images/emoji/apple/man_with_gua_pi_mao.png differ diff --git a/public/images/emoji/apple/man_with_turban.png b/public/images/emoji/apple/man_with_turban.png index 64f06b0f2f7..0cf4e049f47 100644 Binary files a/public/images/emoji/apple/man_with_turban.png and b/public/images/emoji/apple/man_with_turban.png differ diff --git a/public/images/emoji/apple/mans_shoe.png b/public/images/emoji/apple/mans_shoe.png index e43ce6ee570..e8fefcaf510 100644 Binary files a/public/images/emoji/apple/mans_shoe.png and b/public/images/emoji/apple/mans_shoe.png differ diff --git a/public/images/emoji/apple/map.png b/public/images/emoji/apple/map.png new file mode 100644 index 00000000000..0faacb80f89 Binary files /dev/null and b/public/images/emoji/apple/map.png differ diff --git a/public/images/emoji/apple/maple_leaf.png b/public/images/emoji/apple/maple_leaf.png index 7ac4aaed6fd..9204fefa2c2 100644 Binary files a/public/images/emoji/apple/maple_leaf.png and b/public/images/emoji/apple/maple_leaf.png differ diff --git a/public/images/emoji/apple/mask.png b/public/images/emoji/apple/mask.png index 21edb3c95a0..21e3d4a0e28 100644 Binary files a/public/images/emoji/apple/mask.png and b/public/images/emoji/apple/mask.png differ diff --git a/public/images/emoji/apple/massage.png b/public/images/emoji/apple/massage.png index f6974e76b0f..b20387f97c8 100644 Binary files a/public/images/emoji/apple/massage.png and b/public/images/emoji/apple/massage.png differ diff --git a/public/images/emoji/apple/meat_on_bone.png b/public/images/emoji/apple/meat_on_bone.png index 80050d4d116..20393265133 100644 Binary files a/public/images/emoji/apple/meat_on_bone.png and b/public/images/emoji/apple/meat_on_bone.png differ diff --git a/public/images/emoji/apple/medal.png b/public/images/emoji/apple/medal.png new file mode 100644 index 00000000000..c75dc457c44 Binary files /dev/null and b/public/images/emoji/apple/medal.png differ diff --git a/public/images/emoji/apple/mega.png b/public/images/emoji/apple/mega.png index 250c352748d..a011155e782 100644 Binary files a/public/images/emoji/apple/mega.png and b/public/images/emoji/apple/mega.png differ diff --git a/public/images/emoji/apple/melon.png b/public/images/emoji/apple/melon.png index 1440d828574..a3b1c8ffb21 100644 Binary files a/public/images/emoji/apple/melon.png and b/public/images/emoji/apple/melon.png differ diff --git a/public/images/emoji/apple/memo.png b/public/images/emoji/apple/memo.png index 57abb762d5f..c31c97a38ab 100644 Binary files a/public/images/emoji/apple/memo.png and b/public/images/emoji/apple/memo.png differ diff --git a/public/images/emoji/apple/menorah.png b/public/images/emoji/apple/menorah.png new file mode 100644 index 00000000000..27a8a09c964 Binary files /dev/null and b/public/images/emoji/apple/menorah.png differ diff --git a/public/images/emoji/apple/mens.png b/public/images/emoji/apple/mens.png index 44c9351d03a..710f6be2059 100644 Binary files a/public/images/emoji/apple/mens.png and b/public/images/emoji/apple/mens.png differ diff --git a/public/images/emoji/apple/metal.png b/public/images/emoji/apple/metal.png new file mode 100644 index 00000000000..ef19c2fee1d Binary files /dev/null and b/public/images/emoji/apple/metal.png differ diff --git a/public/images/emoji/apple/metro.png b/public/images/emoji/apple/metro.png index 4f738719699..f0b6c548033 100644 Binary files a/public/images/emoji/apple/metro.png and b/public/images/emoji/apple/metro.png differ diff --git a/public/images/emoji/apple/microphone.png b/public/images/emoji/apple/microphone.png index 31ade85df6c..c58c8c518b0 100644 Binary files a/public/images/emoji/apple/microphone.png and b/public/images/emoji/apple/microphone.png differ diff --git a/public/images/emoji/apple/microphone2.png b/public/images/emoji/apple/microphone2.png new file mode 100644 index 00000000000..1adc026c0c3 Binary files /dev/null and b/public/images/emoji/apple/microphone2.png differ diff --git a/public/images/emoji/apple/microscope.png b/public/images/emoji/apple/microscope.png index ea527e78389..ddae65676db 100644 Binary files a/public/images/emoji/apple/microscope.png and b/public/images/emoji/apple/microscope.png differ diff --git a/public/images/emoji/apple/middle_finger.png b/public/images/emoji/apple/middle_finger.png new file mode 100644 index 00000000000..3159f7b7655 Binary files /dev/null and b/public/images/emoji/apple/middle_finger.png differ diff --git a/public/images/emoji/apple/military_medal.png b/public/images/emoji/apple/military_medal.png new file mode 100644 index 00000000000..552eabc99b8 Binary files /dev/null and b/public/images/emoji/apple/military_medal.png differ diff --git a/public/images/emoji/apple/milky_way.png b/public/images/emoji/apple/milky_way.png index fe0eaa6455c..c97e68cea71 100644 Binary files a/public/images/emoji/apple/milky_way.png and b/public/images/emoji/apple/milky_way.png differ diff --git a/public/images/emoji/apple/minibus.png b/public/images/emoji/apple/minibus.png index e6a17b0f899..227db34a5e0 100644 Binary files a/public/images/emoji/apple/minibus.png and b/public/images/emoji/apple/minibus.png differ diff --git a/public/images/emoji/apple/minidisc.png b/public/images/emoji/apple/minidisc.png index 56af53b27f1..57f35425559 100644 Binary files a/public/images/emoji/apple/minidisc.png and b/public/images/emoji/apple/minidisc.png differ diff --git a/public/images/emoji/apple/mobile_phone_off.png b/public/images/emoji/apple/mobile_phone_off.png index 23a78d00d8f..c10047e7388 100644 Binary files a/public/images/emoji/apple/mobile_phone_off.png and b/public/images/emoji/apple/mobile_phone_off.png differ diff --git a/public/images/emoji/apple/money_mouth.png b/public/images/emoji/apple/money_mouth.png new file mode 100644 index 00000000000..7942cbe6c76 Binary files /dev/null and b/public/images/emoji/apple/money_mouth.png differ diff --git a/public/images/emoji/apple/money_with_wings.png b/public/images/emoji/apple/money_with_wings.png index 2940d1798a3..127c0b9737f 100644 Binary files a/public/images/emoji/apple/money_with_wings.png and b/public/images/emoji/apple/money_with_wings.png differ diff --git a/public/images/emoji/apple/moneybag.png b/public/images/emoji/apple/moneybag.png index 382fa2adc7a..51915de730b 100644 Binary files a/public/images/emoji/apple/moneybag.png and b/public/images/emoji/apple/moneybag.png differ diff --git a/public/images/emoji/apple/monkey.png b/public/images/emoji/apple/monkey.png index f90ef1317cf..92bf5e367c4 100644 Binary files a/public/images/emoji/apple/monkey.png and b/public/images/emoji/apple/monkey.png differ diff --git a/public/images/emoji/apple/monkey_face.png b/public/images/emoji/apple/monkey_face.png index 341e376bbf8..93666ab2a86 100644 Binary files a/public/images/emoji/apple/monkey_face.png and b/public/images/emoji/apple/monkey_face.png differ diff --git a/public/images/emoji/apple/monorail.png b/public/images/emoji/apple/monorail.png index b5d44f8e9df..f02d088454d 100644 Binary files a/public/images/emoji/apple/monorail.png and b/public/images/emoji/apple/monorail.png differ diff --git a/public/images/emoji/apple/moon.png b/public/images/emoji/apple/moon.png index 03e9b3dabaf..c5fce3fac66 100644 Binary files a/public/images/emoji/apple/moon.png and b/public/images/emoji/apple/moon.png differ diff --git a/public/images/emoji/apple/mortar_board.png b/public/images/emoji/apple/mortar_board.png index d17e8cf074f..ad91b47ba41 100644 Binary files a/public/images/emoji/apple/mortar_board.png and b/public/images/emoji/apple/mortar_board.png differ diff --git a/public/images/emoji/apple/mosque.png b/public/images/emoji/apple/mosque.png new file mode 100644 index 00000000000..2b3126dfd2b Binary files /dev/null and b/public/images/emoji/apple/mosque.png differ diff --git a/public/images/emoji/apple/motorboat.png b/public/images/emoji/apple/motorboat.png new file mode 100644 index 00000000000..2e2a7ac7188 Binary files /dev/null and b/public/images/emoji/apple/motorboat.png differ diff --git a/public/images/emoji/apple/motorcycle.png b/public/images/emoji/apple/motorcycle.png new file mode 100644 index 00000000000..2db9d397cd3 Binary files /dev/null and b/public/images/emoji/apple/motorcycle.png differ diff --git a/public/images/emoji/apple/motorway.png b/public/images/emoji/apple/motorway.png new file mode 100644 index 00000000000..d2cdd05982d Binary files /dev/null and b/public/images/emoji/apple/motorway.png differ diff --git a/public/images/emoji/apple/mount_fuji.png b/public/images/emoji/apple/mount_fuji.png index 7bc05512f89..0c355167375 100644 Binary files a/public/images/emoji/apple/mount_fuji.png and b/public/images/emoji/apple/mount_fuji.png differ diff --git a/public/images/emoji/apple/mountain.png b/public/images/emoji/apple/mountain.png new file mode 100644 index 00000000000..372fc7e6779 Binary files /dev/null and b/public/images/emoji/apple/mountain.png differ diff --git a/public/images/emoji/apple/mountain_bicyclist.png b/public/images/emoji/apple/mountain_bicyclist.png index 761dde0d9e8..322c779e01b 100644 Binary files a/public/images/emoji/apple/mountain_bicyclist.png and b/public/images/emoji/apple/mountain_bicyclist.png differ diff --git a/public/images/emoji/apple/mountain_cableway.png b/public/images/emoji/apple/mountain_cableway.png index 29ff1b58456..4f54f3fbbb9 100644 Binary files a/public/images/emoji/apple/mountain_cableway.png and b/public/images/emoji/apple/mountain_cableway.png differ diff --git a/public/images/emoji/apple/mountain_railway.png b/public/images/emoji/apple/mountain_railway.png index 41ad0c94fc6..8c5d0a9a3bd 100644 Binary files a/public/images/emoji/apple/mountain_railway.png and b/public/images/emoji/apple/mountain_railway.png differ diff --git a/public/images/emoji/apple/mountain_snow.png b/public/images/emoji/apple/mountain_snow.png new file mode 100644 index 00000000000..eb618233dd9 Binary files /dev/null and b/public/images/emoji/apple/mountain_snow.png differ diff --git a/public/images/emoji/apple/mouse.png b/public/images/emoji/apple/mouse.png index 7cd289d40dd..2584b8bdfe3 100644 Binary files a/public/images/emoji/apple/mouse.png and b/public/images/emoji/apple/mouse.png differ diff --git a/public/images/emoji/apple/mouse2.png b/public/images/emoji/apple/mouse2.png index a6c6816b399..01637029015 100644 Binary files a/public/images/emoji/apple/mouse2.png and b/public/images/emoji/apple/mouse2.png differ diff --git a/public/images/emoji/apple/mouse_three_button.png b/public/images/emoji/apple/mouse_three_button.png new file mode 100644 index 00000000000..15d3480e24a Binary files /dev/null and b/public/images/emoji/apple/mouse_three_button.png differ diff --git a/public/images/emoji/apple/movie_camera.png b/public/images/emoji/apple/movie_camera.png index 86af960c98d..8a77f6f57f7 100644 Binary files a/public/images/emoji/apple/movie_camera.png and b/public/images/emoji/apple/movie_camera.png differ diff --git a/public/images/emoji/apple/moyai.png b/public/images/emoji/apple/moyai.png index 4eb8362da1f..9f82c82da9f 100644 Binary files a/public/images/emoji/apple/moyai.png and b/public/images/emoji/apple/moyai.png differ diff --git a/public/images/emoji/apple/muscle.png b/public/images/emoji/apple/muscle.png index 5778d0df7d8..7375b9673b4 100644 Binary files a/public/images/emoji/apple/muscle.png and b/public/images/emoji/apple/muscle.png differ diff --git a/public/images/emoji/apple/mushroom.png b/public/images/emoji/apple/mushroom.png index 5ed54b62da0..ec928eeb90f 100644 Binary files a/public/images/emoji/apple/mushroom.png and b/public/images/emoji/apple/mushroom.png differ diff --git a/public/images/emoji/apple/musical_keyboard.png b/public/images/emoji/apple/musical_keyboard.png index af01fde7bba..5772bca2575 100644 Binary files a/public/images/emoji/apple/musical_keyboard.png and b/public/images/emoji/apple/musical_keyboard.png differ diff --git a/public/images/emoji/apple/musical_note.png b/public/images/emoji/apple/musical_note.png index 83fc05faf97..7e7ff7e43ad 100644 Binary files a/public/images/emoji/apple/musical_note.png and b/public/images/emoji/apple/musical_note.png differ diff --git a/public/images/emoji/apple/musical_score.png b/public/images/emoji/apple/musical_score.png index 5cf7032ebab..35aac580ca5 100644 Binary files a/public/images/emoji/apple/musical_score.png and b/public/images/emoji/apple/musical_score.png differ diff --git a/public/images/emoji/apple/mute.png b/public/images/emoji/apple/mute.png index 25a413be693..10907c4d38e 100644 Binary files a/public/images/emoji/apple/mute.png and b/public/images/emoji/apple/mute.png differ diff --git a/public/images/emoji/apple/nail_care.png b/public/images/emoji/apple/nail_care.png index 9d25f9f739a..49d041b4823 100644 Binary files a/public/images/emoji/apple/nail_care.png and b/public/images/emoji/apple/nail_care.png differ diff --git a/public/images/emoji/apple/name_badge.png b/public/images/emoji/apple/name_badge.png index 09f397a30df..26ae7bf502e 100644 Binary files a/public/images/emoji/apple/name_badge.png and b/public/images/emoji/apple/name_badge.png differ diff --git a/public/images/emoji/apple/necktie.png b/public/images/emoji/apple/necktie.png index 0097e34e2d6..227c1b144a3 100644 Binary files a/public/images/emoji/apple/necktie.png and b/public/images/emoji/apple/necktie.png differ diff --git a/public/images/emoji/apple/negative_squared_cross_mark.png b/public/images/emoji/apple/negative_squared_cross_mark.png index 75f1c61b654..64146131d59 100644 Binary files a/public/images/emoji/apple/negative_squared_cross_mark.png and b/public/images/emoji/apple/negative_squared_cross_mark.png differ diff --git a/public/images/emoji/apple/nerd.png b/public/images/emoji/apple/nerd.png new file mode 100644 index 00000000000..f7fdc390953 Binary files /dev/null and b/public/images/emoji/apple/nerd.png differ diff --git a/public/images/emoji/apple/neutral_face.png b/public/images/emoji/apple/neutral_face.png index 54d72265014..0d006943bd7 100644 Binary files a/public/images/emoji/apple/neutral_face.png and b/public/images/emoji/apple/neutral_face.png differ diff --git a/public/images/emoji/apple/new.png b/public/images/emoji/apple/new.png index 5831405db53..6482d238b59 100644 Binary files a/public/images/emoji/apple/new.png and b/public/images/emoji/apple/new.png differ diff --git a/public/images/emoji/apple/new_moon.png b/public/images/emoji/apple/new_moon.png index 3009b19fa5d..d90d2189814 100644 Binary files a/public/images/emoji/apple/new_moon.png and b/public/images/emoji/apple/new_moon.png differ diff --git a/public/images/emoji/apple/new_moon_with_face.png b/public/images/emoji/apple/new_moon_with_face.png index e3ed1487b9f..d10a21ddbce 100644 Binary files a/public/images/emoji/apple/new_moon_with_face.png and b/public/images/emoji/apple/new_moon_with_face.png differ diff --git a/public/images/emoji/apple/newspaper.png b/public/images/emoji/apple/newspaper.png index dae3495d3ef..ddcfa7e058f 100644 Binary files a/public/images/emoji/apple/newspaper.png and b/public/images/emoji/apple/newspaper.png differ diff --git a/public/images/emoji/apple/newspaper2.png b/public/images/emoji/apple/newspaper2.png new file mode 100644 index 00000000000..2371b569da2 Binary files /dev/null and b/public/images/emoji/apple/newspaper2.png differ diff --git a/public/images/emoji/apple/ng.png b/public/images/emoji/apple/ng.png index 88db02bb1b5..56c89836ba4 100644 Binary files a/public/images/emoji/apple/ng.png and b/public/images/emoji/apple/ng.png differ diff --git a/public/images/emoji/apple/night_with_stars.png b/public/images/emoji/apple/night_with_stars.png index be505a69279..3e6d7118066 100644 Binary files a/public/images/emoji/apple/night_with_stars.png and b/public/images/emoji/apple/night_with_stars.png differ diff --git a/public/images/emoji/apple/nine.png b/public/images/emoji/apple/nine.png index 99f04160cbc..4030effeb58 100644 Binary files a/public/images/emoji/apple/nine.png and b/public/images/emoji/apple/nine.png differ diff --git a/public/images/emoji/apple/no_bell.png b/public/images/emoji/apple/no_bell.png index 09ba559fb46..b9a9e5e7b20 100644 Binary files a/public/images/emoji/apple/no_bell.png and b/public/images/emoji/apple/no_bell.png differ diff --git a/public/images/emoji/apple/no_bicycles.png b/public/images/emoji/apple/no_bicycles.png index 24a2adad0ce..34b8fd1a8a7 100644 Binary files a/public/images/emoji/apple/no_bicycles.png and b/public/images/emoji/apple/no_bicycles.png differ diff --git a/public/images/emoji/apple/no_entry.png b/public/images/emoji/apple/no_entry.png index c36c84e2887..744d79cd00e 100644 Binary files a/public/images/emoji/apple/no_entry.png and b/public/images/emoji/apple/no_entry.png differ diff --git a/public/images/emoji/apple/no_entry_sign.png b/public/images/emoji/apple/no_entry_sign.png index e84384f49de..b3979257551 100644 Binary files a/public/images/emoji/apple/no_entry_sign.png and b/public/images/emoji/apple/no_entry_sign.png differ diff --git a/public/images/emoji/apple/no_good.png b/public/images/emoji/apple/no_good.png index 883fa8a8470..c2270b6fc67 100644 Binary files a/public/images/emoji/apple/no_good.png and b/public/images/emoji/apple/no_good.png differ diff --git a/public/images/emoji/apple/no_mobile_phones.png b/public/images/emoji/apple/no_mobile_phones.png index 8f6e56574dc..9841ca3552c 100644 Binary files a/public/images/emoji/apple/no_mobile_phones.png and b/public/images/emoji/apple/no_mobile_phones.png differ diff --git a/public/images/emoji/apple/no_mouth.png b/public/images/emoji/apple/no_mouth.png index aa22aac320b..af19b28e34a 100644 Binary files a/public/images/emoji/apple/no_mouth.png and b/public/images/emoji/apple/no_mouth.png differ diff --git a/public/images/emoji/apple/no_pedestrians.png b/public/images/emoji/apple/no_pedestrians.png index 851f55df9e8..0df5ce2aa4c 100644 Binary files a/public/images/emoji/apple/no_pedestrians.png and b/public/images/emoji/apple/no_pedestrians.png differ diff --git a/public/images/emoji/apple/no_smoking.png b/public/images/emoji/apple/no_smoking.png index b6bd6309de8..5fd26f7df62 100644 Binary files a/public/images/emoji/apple/no_smoking.png and b/public/images/emoji/apple/no_smoking.png differ diff --git a/public/images/emoji/apple/non-potable_water.png b/public/images/emoji/apple/non-potable_water.png index 25521b4afb4..319ba0303f8 100644 Binary files a/public/images/emoji/apple/non-potable_water.png and b/public/images/emoji/apple/non-potable_water.png differ diff --git a/public/images/emoji/apple/nose.png b/public/images/emoji/apple/nose.png index 403f6aacae3..0e4a437bab7 100644 Binary files a/public/images/emoji/apple/nose.png and b/public/images/emoji/apple/nose.png differ diff --git a/public/images/emoji/apple/notebook.png b/public/images/emoji/apple/notebook.png index 357871772fa..8fc57351a5e 100644 Binary files a/public/images/emoji/apple/notebook.png and b/public/images/emoji/apple/notebook.png differ diff --git a/public/images/emoji/apple/notebook_with_decorative_cover.png b/public/images/emoji/apple/notebook_with_decorative_cover.png index b9898b224e1..a935655d8bc 100644 Binary files a/public/images/emoji/apple/notebook_with_decorative_cover.png and b/public/images/emoji/apple/notebook_with_decorative_cover.png differ diff --git a/public/images/emoji/apple/notepad_spiral.png b/public/images/emoji/apple/notepad_spiral.png new file mode 100644 index 00000000000..ca00c4e0c92 Binary files /dev/null and b/public/images/emoji/apple/notepad_spiral.png differ diff --git a/public/images/emoji/apple/notes.png b/public/images/emoji/apple/notes.png index e55a56600c1..5876fdad1c3 100644 Binary files a/public/images/emoji/apple/notes.png and b/public/images/emoji/apple/notes.png differ diff --git a/public/images/emoji/apple/nut_and_bolt.png b/public/images/emoji/apple/nut_and_bolt.png index 00dcf8b216e..bcd28d09b6d 100644 Binary files a/public/images/emoji/apple/nut_and_bolt.png and b/public/images/emoji/apple/nut_and_bolt.png differ diff --git a/public/images/emoji/apple/o.png b/public/images/emoji/apple/o.png index fcf887e9604..2161fd6980d 100644 Binary files a/public/images/emoji/apple/o.png and b/public/images/emoji/apple/o.png differ diff --git a/public/images/emoji/apple/o2.png b/public/images/emoji/apple/o2.png index c8ca117ad27..5b51c487fd1 100644 Binary files a/public/images/emoji/apple/o2.png and b/public/images/emoji/apple/o2.png differ diff --git a/public/images/emoji/apple/ocean.png b/public/images/emoji/apple/ocean.png index 35798e4f39f..457dce6708d 100644 Binary files a/public/images/emoji/apple/ocean.png and b/public/images/emoji/apple/ocean.png differ diff --git a/public/images/emoji/apple/octopus.png b/public/images/emoji/apple/octopus.png index 16727ff286e..80086a54501 100644 Binary files a/public/images/emoji/apple/octopus.png and b/public/images/emoji/apple/octopus.png differ diff --git a/public/images/emoji/apple/oden.png b/public/images/emoji/apple/oden.png index 1268494dfcf..a1ba075412d 100644 Binary files a/public/images/emoji/apple/oden.png and b/public/images/emoji/apple/oden.png differ diff --git a/public/images/emoji/apple/office.png b/public/images/emoji/apple/office.png index ea025210a17..5b70d776ce7 100644 Binary files a/public/images/emoji/apple/office.png and b/public/images/emoji/apple/office.png differ diff --git a/public/images/emoji/apple/oil.png b/public/images/emoji/apple/oil.png new file mode 100644 index 00000000000..a0d4f87c179 Binary files /dev/null and b/public/images/emoji/apple/oil.png differ diff --git a/public/images/emoji/apple/ok.png b/public/images/emoji/apple/ok.png index 0377d26da3b..af03dd91c53 100644 Binary files a/public/images/emoji/apple/ok.png and b/public/images/emoji/apple/ok.png differ diff --git a/public/images/emoji/apple/ok_hand.png b/public/images/emoji/apple/ok_hand.png index 53533a42d67..1f54f0629d1 100644 Binary files a/public/images/emoji/apple/ok_hand.png and b/public/images/emoji/apple/ok_hand.png differ diff --git a/public/images/emoji/apple/ok_woman.png b/public/images/emoji/apple/ok_woman.png index ba4a27660c3..af62bca94f4 100644 Binary files a/public/images/emoji/apple/ok_woman.png and b/public/images/emoji/apple/ok_woman.png differ diff --git a/public/images/emoji/apple/older_man.png b/public/images/emoji/apple/older_man.png index e6e295553fa..7003b9b0c3b 100644 Binary files a/public/images/emoji/apple/older_man.png and b/public/images/emoji/apple/older_man.png differ diff --git a/public/images/emoji/apple/older_woman.png b/public/images/emoji/apple/older_woman.png index e57546b3309..232b665b5a9 100644 Binary files a/public/images/emoji/apple/older_woman.png and b/public/images/emoji/apple/older_woman.png differ diff --git a/public/images/emoji/apple/om_symbol.png b/public/images/emoji/apple/om_symbol.png new file mode 100644 index 00000000000..abe320afa73 Binary files /dev/null and b/public/images/emoji/apple/om_symbol.png differ diff --git a/public/images/emoji/apple/on.png b/public/images/emoji/apple/on.png index ad28ba63c20..41845767a7e 100644 Binary files a/public/images/emoji/apple/on.png and b/public/images/emoji/apple/on.png differ diff --git a/public/images/emoji/apple/oncoming_automobile.png b/public/images/emoji/apple/oncoming_automobile.png index 2361bf15379..d44d6cbb143 100644 Binary files a/public/images/emoji/apple/oncoming_automobile.png and b/public/images/emoji/apple/oncoming_automobile.png differ diff --git a/public/images/emoji/apple/oncoming_bus.png b/public/images/emoji/apple/oncoming_bus.png index f74afbbaa1f..8f551e6d0a6 100644 Binary files a/public/images/emoji/apple/oncoming_bus.png and b/public/images/emoji/apple/oncoming_bus.png differ diff --git a/public/images/emoji/apple/oncoming_police_car.png b/public/images/emoji/apple/oncoming_police_car.png index 9daf28ef119..e26856e4af9 100644 Binary files a/public/images/emoji/apple/oncoming_police_car.png and b/public/images/emoji/apple/oncoming_police_car.png differ diff --git a/public/images/emoji/apple/oncoming_taxi.png b/public/images/emoji/apple/oncoming_taxi.png index 944299846e3..6b1f4623d5c 100644 Binary files a/public/images/emoji/apple/oncoming_taxi.png and b/public/images/emoji/apple/oncoming_taxi.png differ diff --git a/public/images/emoji/apple/one.png b/public/images/emoji/apple/one.png index 75f447d75c6..2c2caaafc6d 100644 Binary files a/public/images/emoji/apple/one.png and b/public/images/emoji/apple/one.png differ diff --git a/public/images/emoji/apple/open_book.png b/public/images/emoji/apple/open_book.png index 548c1f4f12d..84d06e7360c 100644 Binary files a/public/images/emoji/apple/open_book.png and b/public/images/emoji/apple/open_book.png differ diff --git a/public/images/emoji/apple/open_file_folder.png b/public/images/emoji/apple/open_file_folder.png index f248186181f..bcdd9357f11 100644 Binary files a/public/images/emoji/apple/open_file_folder.png and b/public/images/emoji/apple/open_file_folder.png differ diff --git a/public/images/emoji/apple/open_hands.png b/public/images/emoji/apple/open_hands.png index e082fc6b001..455dd98a63a 100644 Binary files a/public/images/emoji/apple/open_hands.png and b/public/images/emoji/apple/open_hands.png differ diff --git a/public/images/emoji/apple/open_mouth.png b/public/images/emoji/apple/open_mouth.png index 738b8dfd05d..0fd2e8791c6 100644 Binary files a/public/images/emoji/apple/open_mouth.png and b/public/images/emoji/apple/open_mouth.png differ diff --git a/public/images/emoji/apple/ophiuchus.png b/public/images/emoji/apple/ophiuchus.png index d4e41835c34..9cc348f718a 100644 Binary files a/public/images/emoji/apple/ophiuchus.png and b/public/images/emoji/apple/ophiuchus.png differ diff --git a/public/images/emoji/apple/orange_book.png b/public/images/emoji/apple/orange_book.png index b36771d6d84..4b777aa67d9 100644 Binary files a/public/images/emoji/apple/orange_book.png and b/public/images/emoji/apple/orange_book.png differ diff --git a/public/images/emoji/apple/orthodox_cross.png b/public/images/emoji/apple/orthodox_cross.png new file mode 100644 index 00000000000..510d19c1d05 Binary files /dev/null and b/public/images/emoji/apple/orthodox_cross.png differ diff --git a/public/images/emoji/apple/outbox_tray.png b/public/images/emoji/apple/outbox_tray.png index 39bd5731f24..874c0d45692 100644 Binary files a/public/images/emoji/apple/outbox_tray.png and b/public/images/emoji/apple/outbox_tray.png differ diff --git a/public/images/emoji/apple/ox.png b/public/images/emoji/apple/ox.png index e102a5b9235..a477d47f2fd 100644 Binary files a/public/images/emoji/apple/ox.png and b/public/images/emoji/apple/ox.png differ diff --git a/public/images/emoji/apple/package.png b/public/images/emoji/apple/package.png index 23c1eadb8c5..d20814d795e 100644 Binary files a/public/images/emoji/apple/package.png and b/public/images/emoji/apple/package.png differ diff --git a/public/images/emoji/apple/page_facing_up.png b/public/images/emoji/apple/page_facing_up.png index 89f7b77c99d..1d61a6e003a 100644 Binary files a/public/images/emoji/apple/page_facing_up.png and b/public/images/emoji/apple/page_facing_up.png differ diff --git a/public/images/emoji/apple/page_with_curl.png b/public/images/emoji/apple/page_with_curl.png index bfb32cbdac2..bab19506749 100644 Binary files a/public/images/emoji/apple/page_with_curl.png and b/public/images/emoji/apple/page_with_curl.png differ diff --git a/public/images/emoji/apple/pager.png b/public/images/emoji/apple/pager.png index f2d430749e9..d3957a77e89 100644 Binary files a/public/images/emoji/apple/pager.png and b/public/images/emoji/apple/pager.png differ diff --git a/public/images/emoji/apple/paintbrush.png b/public/images/emoji/apple/paintbrush.png new file mode 100644 index 00000000000..cc4b8ef70df Binary files /dev/null and b/public/images/emoji/apple/paintbrush.png differ diff --git a/public/images/emoji/apple/palm_tree.png b/public/images/emoji/apple/palm_tree.png index 970875c59b6..c521d4d3cee 100644 Binary files a/public/images/emoji/apple/palm_tree.png and b/public/images/emoji/apple/palm_tree.png differ diff --git a/public/images/emoji/apple/panda_face.png b/public/images/emoji/apple/panda_face.png index 55d72b53fae..2c58fa21c9e 100644 Binary files a/public/images/emoji/apple/panda_face.png and b/public/images/emoji/apple/panda_face.png differ diff --git a/public/images/emoji/apple/paperclip.png b/public/images/emoji/apple/paperclip.png index aeeeb73602d..979ce880607 100644 Binary files a/public/images/emoji/apple/paperclip.png and b/public/images/emoji/apple/paperclip.png differ diff --git a/public/images/emoji/apple/paperclips.png b/public/images/emoji/apple/paperclips.png new file mode 100644 index 00000000000..04c736a409b Binary files /dev/null and b/public/images/emoji/apple/paperclips.png differ diff --git a/public/images/emoji/apple/park.png b/public/images/emoji/apple/park.png new file mode 100644 index 00000000000..ebd8a9e9583 Binary files /dev/null and b/public/images/emoji/apple/park.png differ diff --git a/public/images/emoji/apple/parking.png b/public/images/emoji/apple/parking.png index 77702630f49..a007ca6e67f 100644 Binary files a/public/images/emoji/apple/parking.png and b/public/images/emoji/apple/parking.png differ diff --git a/public/images/emoji/apple/part_alternation_mark.png b/public/images/emoji/apple/part_alternation_mark.png index 8bc91217cb3..8461bf0b9b3 100644 Binary files a/public/images/emoji/apple/part_alternation_mark.png and b/public/images/emoji/apple/part_alternation_mark.png differ diff --git a/public/images/emoji/apple/partly_sunny.png b/public/images/emoji/apple/partly_sunny.png index 88844068732..7c22e12b0bd 100644 Binary files a/public/images/emoji/apple/partly_sunny.png and b/public/images/emoji/apple/partly_sunny.png differ diff --git a/public/images/emoji/apple/passport_control.png b/public/images/emoji/apple/passport_control.png index 90a1fdc216b..38a94c5c8ff 100644 Binary files a/public/images/emoji/apple/passport_control.png and b/public/images/emoji/apple/passport_control.png differ diff --git a/public/images/emoji/apple/pause_button.png b/public/images/emoji/apple/pause_button.png new file mode 100644 index 00000000000..aac27c376b3 Binary files /dev/null and b/public/images/emoji/apple/pause_button.png differ diff --git a/public/images/emoji/apple/paw_prints.png b/public/images/emoji/apple/paw_prints.png index f80ff2e67aa..4ca20878514 100644 Binary files a/public/images/emoji/apple/paw_prints.png and b/public/images/emoji/apple/paw_prints.png differ diff --git a/public/images/emoji/apple/peace.png b/public/images/emoji/apple/peace.png new file mode 100644 index 00000000000..7001b6a4e7c Binary files /dev/null and b/public/images/emoji/apple/peace.png differ diff --git a/public/images/emoji/apple/peach.png b/public/images/emoji/apple/peach.png index 5d507ac3002..11e6ab71fa8 100644 Binary files a/public/images/emoji/apple/peach.png and b/public/images/emoji/apple/peach.png differ diff --git a/public/images/emoji/apple/pear.png b/public/images/emoji/apple/pear.png index 45206b156cc..de0ad35b653 100644 Binary files a/public/images/emoji/apple/pear.png and b/public/images/emoji/apple/pear.png differ diff --git a/public/images/emoji/apple/pen_ballpoint.png b/public/images/emoji/apple/pen_ballpoint.png new file mode 100644 index 00000000000..14b06985ebc Binary files /dev/null and b/public/images/emoji/apple/pen_ballpoint.png differ diff --git a/public/images/emoji/apple/pen_fountain.png b/public/images/emoji/apple/pen_fountain.png new file mode 100644 index 00000000000..5e9a10292e3 Binary files /dev/null and b/public/images/emoji/apple/pen_fountain.png differ diff --git a/public/images/emoji/apple/pencil.png b/public/images/emoji/apple/pencil.png index 57abb762d5f..400aada1e4e 100644 Binary files a/public/images/emoji/apple/pencil.png and b/public/images/emoji/apple/pencil.png differ diff --git a/public/images/emoji/apple/pencil2.png b/public/images/emoji/apple/pencil2.png index 2b89e3ae0f1..06173a98c38 100644 Binary files a/public/images/emoji/apple/pencil2.png and b/public/images/emoji/apple/pencil2.png differ diff --git a/public/images/emoji/apple/penguin.png b/public/images/emoji/apple/penguin.png index bcb20f55054..e94f3300221 100644 Binary files a/public/images/emoji/apple/penguin.png and b/public/images/emoji/apple/penguin.png differ diff --git a/public/images/emoji/apple/pensive.png b/public/images/emoji/apple/pensive.png index bd7ddd3b17d..7f9d3afba9b 100644 Binary files a/public/images/emoji/apple/pensive.png and b/public/images/emoji/apple/pensive.png differ diff --git a/public/images/emoji/apple/performing_arts.png b/public/images/emoji/apple/performing_arts.png index ec6058de677..647e7fddcac 100644 Binary files a/public/images/emoji/apple/performing_arts.png and b/public/images/emoji/apple/performing_arts.png differ diff --git a/public/images/emoji/apple/persevere.png b/public/images/emoji/apple/persevere.png index 6914cd67d3f..c2f81743922 100644 Binary files a/public/images/emoji/apple/persevere.png and b/public/images/emoji/apple/persevere.png differ diff --git a/public/images/emoji/apple/person_frowning.png b/public/images/emoji/apple/person_frowning.png index a1425d60a16..0289a6f79e3 100644 Binary files a/public/images/emoji/apple/person_frowning.png and b/public/images/emoji/apple/person_frowning.png differ diff --git a/public/images/emoji/apple/person_with_blond_hair.png b/public/images/emoji/apple/person_with_blond_hair.png index 60e3a00d445..de692688910 100644 Binary files a/public/images/emoji/apple/person_with_blond_hair.png and b/public/images/emoji/apple/person_with_blond_hair.png differ diff --git a/public/images/emoji/apple/person_with_pouting_face.png b/public/images/emoji/apple/person_with_pouting_face.png index 5f1a366801b..981163f261b 100644 Binary files a/public/images/emoji/apple/person_with_pouting_face.png and b/public/images/emoji/apple/person_with_pouting_face.png differ diff --git a/public/images/emoji/apple/phone.png b/public/images/emoji/apple/phone.png index fb1d51cdbcd..6ff9c34c34b 100644 Binary files a/public/images/emoji/apple/phone.png and b/public/images/emoji/apple/phone.png differ diff --git a/public/images/emoji/apple/pick.png b/public/images/emoji/apple/pick.png new file mode 100644 index 00000000000..70ad820ce39 Binary files /dev/null and b/public/images/emoji/apple/pick.png differ diff --git a/public/images/emoji/apple/pig.png b/public/images/emoji/apple/pig.png index adbbff8b85c..00858b9526e 100644 Binary files a/public/images/emoji/apple/pig.png and b/public/images/emoji/apple/pig.png differ diff --git a/public/images/emoji/apple/pig2.png b/public/images/emoji/apple/pig2.png index b88c1555032..b193f98fdb6 100644 Binary files a/public/images/emoji/apple/pig2.png and b/public/images/emoji/apple/pig2.png differ diff --git a/public/images/emoji/apple/pig_nose.png b/public/images/emoji/apple/pig_nose.png index 668e8699231..ca0e8b81dcb 100644 Binary files a/public/images/emoji/apple/pig_nose.png and b/public/images/emoji/apple/pig_nose.png differ diff --git a/public/images/emoji/apple/pill.png b/public/images/emoji/apple/pill.png index d0e1463bf99..14afd7ede48 100644 Binary files a/public/images/emoji/apple/pill.png and b/public/images/emoji/apple/pill.png differ diff --git a/public/images/emoji/apple/pineapple.png b/public/images/emoji/apple/pineapple.png index 054a60e2e96..3c13aafa9c9 100644 Binary files a/public/images/emoji/apple/pineapple.png and b/public/images/emoji/apple/pineapple.png differ diff --git a/public/images/emoji/apple/ping_pong.png b/public/images/emoji/apple/ping_pong.png new file mode 100644 index 00000000000..186e254d75f Binary files /dev/null and b/public/images/emoji/apple/ping_pong.png differ diff --git a/public/images/emoji/apple/pisces.png b/public/images/emoji/apple/pisces.png index 2f56acdb242..8f330f0a5d2 100644 Binary files a/public/images/emoji/apple/pisces.png and b/public/images/emoji/apple/pisces.png differ diff --git a/public/images/emoji/apple/pizza.png b/public/images/emoji/apple/pizza.png index fb17a2b46e9..5e820767167 100644 Binary files a/public/images/emoji/apple/pizza.png and b/public/images/emoji/apple/pizza.png differ diff --git a/public/images/emoji/apple/place_of_worship.png b/public/images/emoji/apple/place_of_worship.png new file mode 100644 index 00000000000..b66a3f0f652 Binary files /dev/null and b/public/images/emoji/apple/place_of_worship.png differ diff --git a/public/images/emoji/apple/play_pause.png b/public/images/emoji/apple/play_pause.png new file mode 100644 index 00000000000..b12ac1f1315 Binary files /dev/null and b/public/images/emoji/apple/play_pause.png differ diff --git a/public/images/emoji/apple/point_down.png b/public/images/emoji/apple/point_down.png index a0187533c00..afc4ab07884 100644 Binary files a/public/images/emoji/apple/point_down.png and b/public/images/emoji/apple/point_down.png differ diff --git a/public/images/emoji/apple/point_left.png b/public/images/emoji/apple/point_left.png index e6a0f0f38e5..73ca7cbf72f 100644 Binary files a/public/images/emoji/apple/point_left.png and b/public/images/emoji/apple/point_left.png differ diff --git a/public/images/emoji/apple/point_right.png b/public/images/emoji/apple/point_right.png index 5d3bb369559..1c03a4af6fd 100644 Binary files a/public/images/emoji/apple/point_right.png and b/public/images/emoji/apple/point_right.png differ diff --git a/public/images/emoji/apple/point_up.png b/public/images/emoji/apple/point_up.png index fe4b03fd38d..a89d5295257 100644 Binary files a/public/images/emoji/apple/point_up.png and b/public/images/emoji/apple/point_up.png differ diff --git a/public/images/emoji/apple/point_up_2.png b/public/images/emoji/apple/point_up_2.png index 531273376ed..53c848f36ea 100644 Binary files a/public/images/emoji/apple/point_up_2.png and b/public/images/emoji/apple/point_up_2.png differ diff --git a/public/images/emoji/apple/police_car.png b/public/images/emoji/apple/police_car.png index 84527e12547..5fbe3fe99c0 100644 Binary files a/public/images/emoji/apple/police_car.png and b/public/images/emoji/apple/police_car.png differ diff --git a/public/images/emoji/apple/poodle.png b/public/images/emoji/apple/poodle.png index 2c750091a09..5c289674fe6 100644 Binary files a/public/images/emoji/apple/poodle.png and b/public/images/emoji/apple/poodle.png differ diff --git a/public/images/emoji/apple/poop.png b/public/images/emoji/apple/poop.png index 75544655b3f..8e62f0e43d3 100644 Binary files a/public/images/emoji/apple/poop.png and b/public/images/emoji/apple/poop.png differ diff --git a/public/images/emoji/apple/popcorn.png b/public/images/emoji/apple/popcorn.png new file mode 100644 index 00000000000..ec9fe13950c Binary files /dev/null and b/public/images/emoji/apple/popcorn.png differ diff --git a/public/images/emoji/apple/post_office.png b/public/images/emoji/apple/post_office.png index 2975788a773..b486e67eba5 100644 Binary files a/public/images/emoji/apple/post_office.png and b/public/images/emoji/apple/post_office.png differ diff --git a/public/images/emoji/apple/postal_horn.png b/public/images/emoji/apple/postal_horn.png index d2dc714deda..6e188535c79 100644 Binary files a/public/images/emoji/apple/postal_horn.png and b/public/images/emoji/apple/postal_horn.png differ diff --git a/public/images/emoji/apple/postbox.png b/public/images/emoji/apple/postbox.png index ddad85cd85a..ae0d0e9cdd9 100644 Binary files a/public/images/emoji/apple/postbox.png and b/public/images/emoji/apple/postbox.png differ diff --git a/public/images/emoji/apple/potable_water.png b/public/images/emoji/apple/potable_water.png index 66c599369c6..4374e6c22c9 100644 Binary files a/public/images/emoji/apple/potable_water.png and b/public/images/emoji/apple/potable_water.png differ diff --git a/public/images/emoji/apple/pouch.png b/public/images/emoji/apple/pouch.png index 765b285fc7f..fbedfcdd4ee 100644 Binary files a/public/images/emoji/apple/pouch.png and b/public/images/emoji/apple/pouch.png differ diff --git a/public/images/emoji/apple/poultry_leg.png b/public/images/emoji/apple/poultry_leg.png index 70251a8e942..b4bb949b612 100644 Binary files a/public/images/emoji/apple/poultry_leg.png and b/public/images/emoji/apple/poultry_leg.png differ diff --git a/public/images/emoji/apple/pound.png b/public/images/emoji/apple/pound.png index a479ce6e46e..2ee07583ace 100644 Binary files a/public/images/emoji/apple/pound.png and b/public/images/emoji/apple/pound.png differ diff --git a/public/images/emoji/apple/pouting_cat.png b/public/images/emoji/apple/pouting_cat.png index 101540cc263..8876fd26943 100644 Binary files a/public/images/emoji/apple/pouting_cat.png and b/public/images/emoji/apple/pouting_cat.png differ diff --git a/public/images/emoji/apple/pray.png b/public/images/emoji/apple/pray.png index 3fefd5ad591..06a00ba4cc3 100644 Binary files a/public/images/emoji/apple/pray.png and b/public/images/emoji/apple/pray.png differ diff --git a/public/images/emoji/apple/prayer_beads.png b/public/images/emoji/apple/prayer_beads.png new file mode 100644 index 00000000000..dee68150bd5 Binary files /dev/null and b/public/images/emoji/apple/prayer_beads.png differ diff --git a/public/images/emoji/apple/princess.png b/public/images/emoji/apple/princess.png index ee0213d1946..4df6692809e 100644 Binary files a/public/images/emoji/apple/princess.png and b/public/images/emoji/apple/princess.png differ diff --git a/public/images/emoji/apple/printer.png b/public/images/emoji/apple/printer.png new file mode 100644 index 00000000000..39a692c648b Binary files /dev/null and b/public/images/emoji/apple/printer.png differ diff --git a/public/images/emoji/apple/projector.png b/public/images/emoji/apple/projector.png new file mode 100644 index 00000000000..e944d739e88 Binary files /dev/null and b/public/images/emoji/apple/projector.png differ diff --git a/public/images/emoji/apple/punch.png b/public/images/emoji/apple/punch.png index 3a76b98e783..5a59d61ce16 100644 Binary files a/public/images/emoji/apple/punch.png and b/public/images/emoji/apple/punch.png differ diff --git a/public/images/emoji/apple/purple_heart.png b/public/images/emoji/apple/purple_heart.png index cc9f2b46868..5d825efd07f 100644 Binary files a/public/images/emoji/apple/purple_heart.png and b/public/images/emoji/apple/purple_heart.png differ diff --git a/public/images/emoji/apple/purse.png b/public/images/emoji/apple/purse.png index 41ab614a12d..47d52fab9bc 100644 Binary files a/public/images/emoji/apple/purse.png and b/public/images/emoji/apple/purse.png differ diff --git a/public/images/emoji/apple/pushpin.png b/public/images/emoji/apple/pushpin.png index cda2c126c2d..1bc5add0343 100644 Binary files a/public/images/emoji/apple/pushpin.png and b/public/images/emoji/apple/pushpin.png differ diff --git a/public/images/emoji/apple/put_litter_in_its_place.png b/public/images/emoji/apple/put_litter_in_its_place.png index 3a2e7caffc8..dd6fe74281e 100644 Binary files a/public/images/emoji/apple/put_litter_in_its_place.png and b/public/images/emoji/apple/put_litter_in_its_place.png differ diff --git a/public/images/emoji/apple/question.png b/public/images/emoji/apple/question.png index 13ebaed7438..4b6f88510a0 100644 Binary files a/public/images/emoji/apple/question.png and b/public/images/emoji/apple/question.png differ diff --git a/public/images/emoji/apple/rabbit.png b/public/images/emoji/apple/rabbit.png index b6838844107..fcd1870dffc 100644 Binary files a/public/images/emoji/apple/rabbit.png and b/public/images/emoji/apple/rabbit.png differ diff --git a/public/images/emoji/apple/rabbit2.png b/public/images/emoji/apple/rabbit2.png index 7e9469f3760..8581974e8db 100644 Binary files a/public/images/emoji/apple/rabbit2.png and b/public/images/emoji/apple/rabbit2.png differ diff --git a/public/images/emoji/apple/race_car.png b/public/images/emoji/apple/race_car.png new file mode 100644 index 00000000000..0b9dc36daff Binary files /dev/null and b/public/images/emoji/apple/race_car.png differ diff --git a/public/images/emoji/apple/racehorse.png b/public/images/emoji/apple/racehorse.png index 5a3e1566f2b..04451ab6053 100644 Binary files a/public/images/emoji/apple/racehorse.png and b/public/images/emoji/apple/racehorse.png differ diff --git a/public/images/emoji/apple/radio.png b/public/images/emoji/apple/radio.png index dcdeeff223a..19764c309eb 100644 Binary files a/public/images/emoji/apple/radio.png and b/public/images/emoji/apple/radio.png differ diff --git a/public/images/emoji/apple/radio_button.png b/public/images/emoji/apple/radio_button.png index 1a9c6722e7e..ecb029d51c6 100644 Binary files a/public/images/emoji/apple/radio_button.png and b/public/images/emoji/apple/radio_button.png differ diff --git a/public/images/emoji/apple/radioactive.png b/public/images/emoji/apple/radioactive.png new file mode 100644 index 00000000000..f9c1d5e8a64 Binary files /dev/null and b/public/images/emoji/apple/radioactive.png differ diff --git a/public/images/emoji/apple/rage.png b/public/images/emoji/apple/rage.png index 84ef537606a..926c343b164 100644 Binary files a/public/images/emoji/apple/rage.png and b/public/images/emoji/apple/rage.png differ diff --git a/public/images/emoji/apple/railway_car.png b/public/images/emoji/apple/railway_car.png index 2464ff0c0de..c024320770e 100644 Binary files a/public/images/emoji/apple/railway_car.png and b/public/images/emoji/apple/railway_car.png differ diff --git a/public/images/emoji/apple/railway_track.png b/public/images/emoji/apple/railway_track.png new file mode 100644 index 00000000000..d6646159016 Binary files /dev/null and b/public/images/emoji/apple/railway_track.png differ diff --git a/public/images/emoji/apple/rainbow.png b/public/images/emoji/apple/rainbow.png index 7bce80f7b97..bde8048bbb1 100644 Binary files a/public/images/emoji/apple/rainbow.png and b/public/images/emoji/apple/rainbow.png differ diff --git a/public/images/emoji/apple/raised_hand.png b/public/images/emoji/apple/raised_hand.png index dea31537583..b4e0659eb27 100644 Binary files a/public/images/emoji/apple/raised_hand.png and b/public/images/emoji/apple/raised_hand.png differ diff --git a/public/images/emoji/apple/raised_hands.png b/public/images/emoji/apple/raised_hands.png index 06d4933ab7d..f65df3d37b3 100644 Binary files a/public/images/emoji/apple/raised_hands.png and b/public/images/emoji/apple/raised_hands.png differ diff --git a/public/images/emoji/apple/raising_hand.png b/public/images/emoji/apple/raising_hand.png index 9ede5836cb1..6143d9f5f69 100644 Binary files a/public/images/emoji/apple/raising_hand.png and b/public/images/emoji/apple/raising_hand.png differ diff --git a/public/images/emoji/apple/ram.png b/public/images/emoji/apple/ram.png index 00eb2e75ddd..7b3eb16b9fc 100644 Binary files a/public/images/emoji/apple/ram.png and b/public/images/emoji/apple/ram.png differ diff --git a/public/images/emoji/apple/ramen.png b/public/images/emoji/apple/ramen.png index 76cafae0159..6c2fcb3cfa1 100644 Binary files a/public/images/emoji/apple/ramen.png and b/public/images/emoji/apple/ramen.png differ diff --git a/public/images/emoji/apple/rat.png b/public/images/emoji/apple/rat.png index 987d30c0a10..133656e47d7 100644 Binary files a/public/images/emoji/apple/rat.png and b/public/images/emoji/apple/rat.png differ diff --git a/public/images/emoji/apple/record_button.png b/public/images/emoji/apple/record_button.png new file mode 100644 index 00000000000..578fc829470 Binary files /dev/null and b/public/images/emoji/apple/record_button.png differ diff --git a/public/images/emoji/apple/recycle.png b/public/images/emoji/apple/recycle.png index a58af6e26de..d2705562aa3 100644 Binary files a/public/images/emoji/apple/recycle.png and b/public/images/emoji/apple/recycle.png differ diff --git a/public/images/emoji/apple/red_car.png b/public/images/emoji/apple/red_car.png index d959c48e60c..3094a986c90 100644 Binary files a/public/images/emoji/apple/red_car.png and b/public/images/emoji/apple/red_car.png differ diff --git a/public/images/emoji/apple/red_circle.png b/public/images/emoji/apple/red_circle.png index 2734885bbd4..437cc89c63e 100644 Binary files a/public/images/emoji/apple/red_circle.png and b/public/images/emoji/apple/red_circle.png differ diff --git a/public/images/emoji/apple/registered.png b/public/images/emoji/apple/registered.png index 258d1dc3ee2..7192a7b6621 100644 Binary files a/public/images/emoji/apple/registered.png and b/public/images/emoji/apple/registered.png differ diff --git a/public/images/emoji/apple/relaxed.png b/public/images/emoji/apple/relaxed.png index ef7aa7e22a2..e5994bc9f1a 100644 Binary files a/public/images/emoji/apple/relaxed.png and b/public/images/emoji/apple/relaxed.png differ diff --git a/public/images/emoji/apple/relieved.png b/public/images/emoji/apple/relieved.png index 4d2fa6d2062..eaf55517fe2 100644 Binary files a/public/images/emoji/apple/relieved.png and b/public/images/emoji/apple/relieved.png differ diff --git a/public/images/emoji/apple/reminder_ribbon.png b/public/images/emoji/apple/reminder_ribbon.png new file mode 100644 index 00000000000..bc905d64548 Binary files /dev/null and b/public/images/emoji/apple/reminder_ribbon.png differ diff --git a/public/images/emoji/apple/repeat.png b/public/images/emoji/apple/repeat.png index a92d559020d..6e6a3753a3b 100644 Binary files a/public/images/emoji/apple/repeat.png and b/public/images/emoji/apple/repeat.png differ diff --git a/public/images/emoji/apple/repeat_one.png b/public/images/emoji/apple/repeat_one.png index 2fa085cc57b..621961796e9 100644 Binary files a/public/images/emoji/apple/repeat_one.png and b/public/images/emoji/apple/repeat_one.png differ diff --git a/public/images/emoji/apple/restroom.png b/public/images/emoji/apple/restroom.png index 2ab7e086922..c651906c095 100644 Binary files a/public/images/emoji/apple/restroom.png and b/public/images/emoji/apple/restroom.png differ diff --git a/public/images/emoji/apple/revolving_hearts.png b/public/images/emoji/apple/revolving_hearts.png index 15a77f5e8eb..e44b206b775 100644 Binary files a/public/images/emoji/apple/revolving_hearts.png and b/public/images/emoji/apple/revolving_hearts.png differ diff --git a/public/images/emoji/apple/rewind.png b/public/images/emoji/apple/rewind.png index 989fa59b230..77e5d648a7e 100644 Binary files a/public/images/emoji/apple/rewind.png and b/public/images/emoji/apple/rewind.png differ diff --git a/public/images/emoji/apple/ribbon.png b/public/images/emoji/apple/ribbon.png index ae261ad25e6..cd8e75a6a23 100644 Binary files a/public/images/emoji/apple/ribbon.png and b/public/images/emoji/apple/ribbon.png differ diff --git a/public/images/emoji/apple/rice.png b/public/images/emoji/apple/rice.png index c8bcbb013a6..c650b01b541 100644 Binary files a/public/images/emoji/apple/rice.png and b/public/images/emoji/apple/rice.png differ diff --git a/public/images/emoji/apple/rice_ball.png b/public/images/emoji/apple/rice_ball.png index eeb9ee68ee5..b4f49d79055 100644 Binary files a/public/images/emoji/apple/rice_ball.png and b/public/images/emoji/apple/rice_ball.png differ diff --git a/public/images/emoji/apple/rice_cracker.png b/public/images/emoji/apple/rice_cracker.png index 1f10e6e3726..3b9ea74a604 100644 Binary files a/public/images/emoji/apple/rice_cracker.png and b/public/images/emoji/apple/rice_cracker.png differ diff --git a/public/images/emoji/apple/rice_scene.png b/public/images/emoji/apple/rice_scene.png index eedbe51531a..da484d45382 100644 Binary files a/public/images/emoji/apple/rice_scene.png and b/public/images/emoji/apple/rice_scene.png differ diff --git a/public/images/emoji/apple/ring.png b/public/images/emoji/apple/ring.png index 18207efff25..5959badc98e 100644 Binary files a/public/images/emoji/apple/ring.png and b/public/images/emoji/apple/ring.png differ diff --git a/public/images/emoji/apple/robot.png b/public/images/emoji/apple/robot.png new file mode 100644 index 00000000000..751776d185d Binary files /dev/null and b/public/images/emoji/apple/robot.png differ diff --git a/public/images/emoji/apple/rocket.png b/public/images/emoji/apple/rocket.png index 465bf55a31a..85962ba1cd3 100644 Binary files a/public/images/emoji/apple/rocket.png and b/public/images/emoji/apple/rocket.png differ diff --git a/public/images/emoji/apple/roller_coaster.png b/public/images/emoji/apple/roller_coaster.png index a578a7f26cc..ddb3202f0a1 100644 Binary files a/public/images/emoji/apple/roller_coaster.png and b/public/images/emoji/apple/roller_coaster.png differ diff --git a/public/images/emoji/apple/rolling_eyes.png b/public/images/emoji/apple/rolling_eyes.png new file mode 100644 index 00000000000..f29bda511ff Binary files /dev/null and b/public/images/emoji/apple/rolling_eyes.png differ diff --git a/public/images/emoji/apple/rooster.png b/public/images/emoji/apple/rooster.png index d9c396d130e..29019652337 100644 Binary files a/public/images/emoji/apple/rooster.png and b/public/images/emoji/apple/rooster.png differ diff --git a/public/images/emoji/apple/rose.png b/public/images/emoji/apple/rose.png index ab83159a9e9..ea2f18071e1 100644 Binary files a/public/images/emoji/apple/rose.png and b/public/images/emoji/apple/rose.png differ diff --git a/public/images/emoji/apple/rosette.png b/public/images/emoji/apple/rosette.png new file mode 100644 index 00000000000..0c47885097d Binary files /dev/null and b/public/images/emoji/apple/rosette.png differ diff --git a/public/images/emoji/apple/rotating_light.png b/public/images/emoji/apple/rotating_light.png index 95c6e5f1db6..f140e83beaa 100644 Binary files a/public/images/emoji/apple/rotating_light.png and b/public/images/emoji/apple/rotating_light.png differ diff --git a/public/images/emoji/apple/round_pushpin.png b/public/images/emoji/apple/round_pushpin.png index 77517be3d0f..2e00ae3a080 100644 Binary files a/public/images/emoji/apple/round_pushpin.png and b/public/images/emoji/apple/round_pushpin.png differ diff --git a/public/images/emoji/apple/rowboat.png b/public/images/emoji/apple/rowboat.png index f9182401fb1..7ecf0fc8b27 100644 Binary files a/public/images/emoji/apple/rowboat.png and b/public/images/emoji/apple/rowboat.png differ diff --git a/public/images/emoji/apple/ru.png b/public/images/emoji/apple/ru.png index 9895c1c0dad..f62d984e4ef 100644 Binary files a/public/images/emoji/apple/ru.png and b/public/images/emoji/apple/ru.png differ diff --git a/public/images/emoji/apple/rugby_football.png b/public/images/emoji/apple/rugby_football.png index 9db7220e795..2b0dba2219b 100644 Binary files a/public/images/emoji/apple/rugby_football.png and b/public/images/emoji/apple/rugby_football.png differ diff --git a/public/images/emoji/apple/runner.png b/public/images/emoji/apple/runner.png index 5aa40befed7..76ab4ea4efb 100644 Binary files a/public/images/emoji/apple/runner.png and b/public/images/emoji/apple/runner.png differ diff --git a/public/images/emoji/apple/running.png b/public/images/emoji/apple/running.png index 5aa40befed7..3dfca8b5ad0 100644 Binary files a/public/images/emoji/apple/running.png and b/public/images/emoji/apple/running.png differ diff --git a/public/images/emoji/apple/running_shirt_with_sash.png b/public/images/emoji/apple/running_shirt_with_sash.png index d75e999a0a8..08542c6b682 100644 Binary files a/public/images/emoji/apple/running_shirt_with_sash.png and b/public/images/emoji/apple/running_shirt_with_sash.png differ diff --git a/public/images/emoji/apple/sa.png b/public/images/emoji/apple/sa.png index e8b67ab9267..3892436ef87 100644 Binary files a/public/images/emoji/apple/sa.png and b/public/images/emoji/apple/sa.png differ diff --git a/public/images/emoji/apple/sagittarius.png b/public/images/emoji/apple/sagittarius.png index 87904cb4d73..736e1efd4b4 100644 Binary files a/public/images/emoji/apple/sagittarius.png and b/public/images/emoji/apple/sagittarius.png differ diff --git a/public/images/emoji/apple/sailboat.png b/public/images/emoji/apple/sailboat.png index a1755990150..200e9657d9e 100644 Binary files a/public/images/emoji/apple/sailboat.png and b/public/images/emoji/apple/sailboat.png differ diff --git a/public/images/emoji/apple/sake.png b/public/images/emoji/apple/sake.png index 955724a116f..d0fefad646d 100644 Binary files a/public/images/emoji/apple/sake.png and b/public/images/emoji/apple/sake.png differ diff --git a/public/images/emoji/apple/sandal.png b/public/images/emoji/apple/sandal.png index 5ec65cda601..ef6e81a6228 100644 Binary files a/public/images/emoji/apple/sandal.png and b/public/images/emoji/apple/sandal.png differ diff --git a/public/images/emoji/apple/santa.png b/public/images/emoji/apple/santa.png index ab5a8db5c0e..9a24043e7d3 100644 Binary files a/public/images/emoji/apple/santa.png and b/public/images/emoji/apple/santa.png differ diff --git a/public/images/emoji/apple/satellite.png b/public/images/emoji/apple/satellite.png index bc140cdda53..4d0887a064e 100644 Binary files a/public/images/emoji/apple/satellite.png and b/public/images/emoji/apple/satellite.png differ diff --git a/public/images/emoji/apple/satellite_orbital.png b/public/images/emoji/apple/satellite_orbital.png new file mode 100644 index 00000000000..1c02e1c78c3 Binary files /dev/null and b/public/images/emoji/apple/satellite_orbital.png differ diff --git a/public/images/emoji/apple/satisfied.png b/public/images/emoji/apple/satisfied.png index 85605c7329d..ed64db6fa02 100644 Binary files a/public/images/emoji/apple/satisfied.png and b/public/images/emoji/apple/satisfied.png differ diff --git a/public/images/emoji/apple/saxophone.png b/public/images/emoji/apple/saxophone.png index 4efc3eaf32f..0c76a11554d 100644 Binary files a/public/images/emoji/apple/saxophone.png and b/public/images/emoji/apple/saxophone.png differ diff --git a/public/images/emoji/apple/scales.png b/public/images/emoji/apple/scales.png new file mode 100644 index 00000000000..11fa8f8ae0f Binary files /dev/null and b/public/images/emoji/apple/scales.png differ diff --git a/public/images/emoji/apple/school.png b/public/images/emoji/apple/school.png index a80f2f7590f..52cd1317cba 100644 Binary files a/public/images/emoji/apple/school.png and b/public/images/emoji/apple/school.png differ diff --git a/public/images/emoji/apple/school_satchel.png b/public/images/emoji/apple/school_satchel.png index 042dc2e9a5c..a49d63b7975 100644 Binary files a/public/images/emoji/apple/school_satchel.png and b/public/images/emoji/apple/school_satchel.png differ diff --git a/public/images/emoji/apple/scissors.png b/public/images/emoji/apple/scissors.png index 5673b36f2ac..efebce27506 100644 Binary files a/public/images/emoji/apple/scissors.png and b/public/images/emoji/apple/scissors.png differ diff --git a/public/images/emoji/apple/scorpion.png b/public/images/emoji/apple/scorpion.png new file mode 100644 index 00000000000..74779cb829b Binary files /dev/null and b/public/images/emoji/apple/scorpion.png differ diff --git a/public/images/emoji/apple/scorpius.png b/public/images/emoji/apple/scorpius.png index 029e51ccc49..feb064d5a62 100644 Binary files a/public/images/emoji/apple/scorpius.png and b/public/images/emoji/apple/scorpius.png differ diff --git a/public/images/emoji/apple/scream.png b/public/images/emoji/apple/scream.png index 225b74bd4bf..e485772907c 100644 Binary files a/public/images/emoji/apple/scream.png and b/public/images/emoji/apple/scream.png differ diff --git a/public/images/emoji/apple/scream_cat.png b/public/images/emoji/apple/scream_cat.png index 2624d8cc1ad..b76a55a67eb 100644 Binary files a/public/images/emoji/apple/scream_cat.png and b/public/images/emoji/apple/scream_cat.png differ diff --git a/public/images/emoji/apple/scroll.png b/public/images/emoji/apple/scroll.png index 79e7f10c817..e53b9a6f249 100644 Binary files a/public/images/emoji/apple/scroll.png and b/public/images/emoji/apple/scroll.png differ diff --git a/public/images/emoji/apple/seat.png b/public/images/emoji/apple/seat.png index dbe5b3d6cd3..fb4df9a3c17 100644 Binary files a/public/images/emoji/apple/seat.png and b/public/images/emoji/apple/seat.png differ diff --git a/public/images/emoji/apple/secret.png b/public/images/emoji/apple/secret.png index 1afd76e6f29..6f7cc11e5be 100644 Binary files a/public/images/emoji/apple/secret.png and b/public/images/emoji/apple/secret.png differ diff --git a/public/images/emoji/apple/see_no_evil.png b/public/images/emoji/apple/see_no_evil.png index 2adaa35e76e..d8a5b9ad064 100644 Binary files a/public/images/emoji/apple/see_no_evil.png and b/public/images/emoji/apple/see_no_evil.png differ diff --git a/public/images/emoji/apple/seedling.png b/public/images/emoji/apple/seedling.png index a3a3c0d533a..9e98f8f24cb 100644 Binary files a/public/images/emoji/apple/seedling.png and b/public/images/emoji/apple/seedling.png differ diff --git a/public/images/emoji/apple/seven.png b/public/images/emoji/apple/seven.png index 2698a004fcc..34ed9cca6c6 100644 Binary files a/public/images/emoji/apple/seven.png and b/public/images/emoji/apple/seven.png differ diff --git a/public/images/emoji/apple/shamrock.png b/public/images/emoji/apple/shamrock.png new file mode 100644 index 00000000000..7a68121349e Binary files /dev/null and b/public/images/emoji/apple/shamrock.png differ diff --git a/public/images/emoji/apple/shaved_ice.png b/public/images/emoji/apple/shaved_ice.png index 05ada7bacc8..4f3664d827a 100644 Binary files a/public/images/emoji/apple/shaved_ice.png and b/public/images/emoji/apple/shaved_ice.png differ diff --git a/public/images/emoji/apple/sheep.png b/public/images/emoji/apple/sheep.png index e7bc2c5e872..614b74473ad 100644 Binary files a/public/images/emoji/apple/sheep.png and b/public/images/emoji/apple/sheep.png differ diff --git a/public/images/emoji/apple/shell.png b/public/images/emoji/apple/shell.png index b1d01023d2e..75502efac2a 100644 Binary files a/public/images/emoji/apple/shell.png and b/public/images/emoji/apple/shell.png differ diff --git a/public/images/emoji/apple/shield.png b/public/images/emoji/apple/shield.png new file mode 100644 index 00000000000..c2146a8e4c1 Binary files /dev/null and b/public/images/emoji/apple/shield.png differ diff --git a/public/images/emoji/apple/shinto_shrine.png b/public/images/emoji/apple/shinto_shrine.png new file mode 100644 index 00000000000..f04a6e4043e Binary files /dev/null and b/public/images/emoji/apple/shinto_shrine.png differ diff --git a/public/images/emoji/apple/ship.png b/public/images/emoji/apple/ship.png index e31478286e3..7868937bf08 100644 Binary files a/public/images/emoji/apple/ship.png and b/public/images/emoji/apple/ship.png differ diff --git a/public/images/emoji/apple/shirt.png b/public/images/emoji/apple/shirt.png index 5ac2001128a..64389eb04bd 100644 Binary files a/public/images/emoji/apple/shirt.png and b/public/images/emoji/apple/shirt.png differ diff --git a/public/images/emoji/apple/shit.png b/public/images/emoji/apple/shit.png index 75544655b3f..8e62f0e43d3 100644 Binary files a/public/images/emoji/apple/shit.png and b/public/images/emoji/apple/shit.png differ diff --git a/public/images/emoji/apple/shoe.png b/public/images/emoji/apple/shoe.png index 710a276ecbb..40154177f16 100644 Binary files a/public/images/emoji/apple/shoe.png and b/public/images/emoji/apple/shoe.png differ diff --git a/public/images/emoji/apple/shopping_bags.png b/public/images/emoji/apple/shopping_bags.png new file mode 100644 index 00000000000..5c1fdae6fe7 Binary files /dev/null and b/public/images/emoji/apple/shopping_bags.png differ diff --git a/public/images/emoji/apple/shower.png b/public/images/emoji/apple/shower.png index 72e0e7586a7..ec08ea103a4 100644 Binary files a/public/images/emoji/apple/shower.png and b/public/images/emoji/apple/shower.png differ diff --git a/public/images/emoji/apple/signal_strength.png b/public/images/emoji/apple/signal_strength.png index 24eaacd1d34..886de173094 100644 Binary files a/public/images/emoji/apple/signal_strength.png and b/public/images/emoji/apple/signal_strength.png differ diff --git a/public/images/emoji/apple/six.png b/public/images/emoji/apple/six.png index d3b01a5ec33..ce9b64cca8a 100644 Binary files a/public/images/emoji/apple/six.png and b/public/images/emoji/apple/six.png differ diff --git a/public/images/emoji/apple/six_pointed_star.png b/public/images/emoji/apple/six_pointed_star.png index 96ad5657db9..6e4480e800e 100644 Binary files a/public/images/emoji/apple/six_pointed_star.png and b/public/images/emoji/apple/six_pointed_star.png differ diff --git a/public/images/emoji/apple/ski.png b/public/images/emoji/apple/ski.png index c1c83ed16ea..90399443c8c 100644 Binary files a/public/images/emoji/apple/ski.png and b/public/images/emoji/apple/ski.png differ diff --git a/public/images/emoji/apple/skier.png b/public/images/emoji/apple/skier.png new file mode 100644 index 00000000000..9f4aaf09cd3 Binary files /dev/null and b/public/images/emoji/apple/skier.png differ diff --git a/public/images/emoji/apple/skull.png b/public/images/emoji/apple/skull.png index 01f7beed22f..6d26b302853 100644 Binary files a/public/images/emoji/apple/skull.png and b/public/images/emoji/apple/skull.png differ diff --git a/public/images/emoji/apple/skull_crossbones.png b/public/images/emoji/apple/skull_crossbones.png new file mode 100644 index 00000000000..27db39049d9 Binary files /dev/null and b/public/images/emoji/apple/skull_crossbones.png differ diff --git a/public/images/emoji/apple/sleeping.png b/public/images/emoji/apple/sleeping.png index c6e61cc947a..ec2c462d7d5 100644 Binary files a/public/images/emoji/apple/sleeping.png and b/public/images/emoji/apple/sleeping.png differ diff --git a/public/images/emoji/apple/sleeping_accommodation.png b/public/images/emoji/apple/sleeping_accommodation.png new file mode 100644 index 00000000000..15d17edc2d7 Binary files /dev/null and b/public/images/emoji/apple/sleeping_accommodation.png differ diff --git a/public/images/emoji/apple/sleepy.png b/public/images/emoji/apple/sleepy.png index 167f1ca4b4f..dbe9c8892fc 100644 Binary files a/public/images/emoji/apple/sleepy.png and b/public/images/emoji/apple/sleepy.png differ diff --git a/public/images/emoji/apple/slight_frown.png b/public/images/emoji/apple/slight_frown.png new file mode 100644 index 00000000000..0c0cb44bb92 Binary files /dev/null and b/public/images/emoji/apple/slight_frown.png differ diff --git a/public/images/emoji/apple/slight_smile.png b/public/images/emoji/apple/slight_smile.png new file mode 100644 index 00000000000..3d3b6e08370 Binary files /dev/null and b/public/images/emoji/apple/slight_smile.png differ diff --git a/public/images/emoji/apple/slightly_smiling.png b/public/images/emoji/apple/slightly_smiling.png new file mode 100644 index 00000000000..e7328dabefa Binary files /dev/null and b/public/images/emoji/apple/slightly_smiling.png differ diff --git a/public/images/emoji/apple/slot_machine.png b/public/images/emoji/apple/slot_machine.png index 92f2284d4d4..3b3967a7687 100644 Binary files a/public/images/emoji/apple/slot_machine.png and b/public/images/emoji/apple/slot_machine.png differ diff --git a/public/images/emoji/apple/small_blue_diamond.png b/public/images/emoji/apple/small_blue_diamond.png index 043f0eb9e2c..47e5c0809b1 100644 Binary files a/public/images/emoji/apple/small_blue_diamond.png and b/public/images/emoji/apple/small_blue_diamond.png differ diff --git a/public/images/emoji/apple/small_orange_diamond.png b/public/images/emoji/apple/small_orange_diamond.png index 289cec54703..15d270c4209 100644 Binary files a/public/images/emoji/apple/small_orange_diamond.png and b/public/images/emoji/apple/small_orange_diamond.png differ diff --git a/public/images/emoji/apple/small_red_triangle.png b/public/images/emoji/apple/small_red_triangle.png index 2a89c9c2e79..456f4025ebc 100644 Binary files a/public/images/emoji/apple/small_red_triangle.png and b/public/images/emoji/apple/small_red_triangle.png differ diff --git a/public/images/emoji/apple/small_red_triangle_down.png b/public/images/emoji/apple/small_red_triangle_down.png index 27720b68e46..3119c464768 100644 Binary files a/public/images/emoji/apple/small_red_triangle_down.png and b/public/images/emoji/apple/small_red_triangle_down.png differ diff --git a/public/images/emoji/apple/smile.png b/public/images/emoji/apple/smile.png index 2818e791193..ea78f967f35 100644 Binary files a/public/images/emoji/apple/smile.png and b/public/images/emoji/apple/smile.png differ diff --git a/public/images/emoji/apple/smile_cat.png b/public/images/emoji/apple/smile_cat.png index f0181741f9d..7090c9cf588 100644 Binary files a/public/images/emoji/apple/smile_cat.png and b/public/images/emoji/apple/smile_cat.png differ diff --git a/public/images/emoji/apple/smiley.png b/public/images/emoji/apple/smiley.png index b4abd8111a5..4d14dd892b5 100644 Binary files a/public/images/emoji/apple/smiley.png and b/public/images/emoji/apple/smiley.png differ diff --git a/public/images/emoji/apple/smiley_cat.png b/public/images/emoji/apple/smiley_cat.png index 0100e20466b..adfe3df7ec9 100644 Binary files a/public/images/emoji/apple/smiley_cat.png and b/public/images/emoji/apple/smiley_cat.png differ diff --git a/public/images/emoji/apple/smiling_imp.png b/public/images/emoji/apple/smiling_imp.png index 504b7463248..b7ec4eb1e55 100644 Binary files a/public/images/emoji/apple/smiling_imp.png and b/public/images/emoji/apple/smiling_imp.png differ diff --git a/public/images/emoji/apple/smirk.png b/public/images/emoji/apple/smirk.png index 94c2a21b69a..27240a4072f 100644 Binary files a/public/images/emoji/apple/smirk.png and b/public/images/emoji/apple/smirk.png differ diff --git a/public/images/emoji/apple/smirk_cat.png b/public/images/emoji/apple/smirk_cat.png index 6644e66bf46..5bee06c8b4e 100644 Binary files a/public/images/emoji/apple/smirk_cat.png and b/public/images/emoji/apple/smirk_cat.png differ diff --git a/public/images/emoji/apple/smoking.png b/public/images/emoji/apple/smoking.png index cc50b385b57..e515f08171c 100644 Binary files a/public/images/emoji/apple/smoking.png and b/public/images/emoji/apple/smoking.png differ diff --git a/public/images/emoji/apple/snail.png b/public/images/emoji/apple/snail.png index 916f02d2063..3bb4ab754b0 100644 Binary files a/public/images/emoji/apple/snail.png and b/public/images/emoji/apple/snail.png differ diff --git a/public/images/emoji/apple/snake.png b/public/images/emoji/apple/snake.png index 1ecc42bbcaa..00f6b60216a 100644 Binary files a/public/images/emoji/apple/snake.png and b/public/images/emoji/apple/snake.png differ diff --git a/public/images/emoji/apple/snowboarder.png b/public/images/emoji/apple/snowboarder.png index 0e723eeaf5f..2b136e90cf4 100644 Binary files a/public/images/emoji/apple/snowboarder.png and b/public/images/emoji/apple/snowboarder.png differ diff --git a/public/images/emoji/apple/snowflake.png b/public/images/emoji/apple/snowflake.png index 116e4c98562..1b2e7dd8d8f 100644 Binary files a/public/images/emoji/apple/snowflake.png and b/public/images/emoji/apple/snowflake.png differ diff --git a/public/images/emoji/apple/snowman.png b/public/images/emoji/apple/snowman.png index 0fc6dd49847..e84800155f0 100644 Binary files a/public/images/emoji/apple/snowman.png and b/public/images/emoji/apple/snowman.png differ diff --git a/public/images/emoji/apple/snowman2.png b/public/images/emoji/apple/snowman2.png new file mode 100644 index 00000000000..89e619f41fc Binary files /dev/null and b/public/images/emoji/apple/snowman2.png differ diff --git a/public/images/emoji/apple/sob.png b/public/images/emoji/apple/sob.png index 6ccdfa9f2d8..09bad2e9e2c 100644 Binary files a/public/images/emoji/apple/sob.png and b/public/images/emoji/apple/sob.png differ diff --git a/public/images/emoji/apple/soccer.png b/public/images/emoji/apple/soccer.png index 168422a0dc1..69b6f33b532 100644 Binary files a/public/images/emoji/apple/soccer.png and b/public/images/emoji/apple/soccer.png differ diff --git a/public/images/emoji/apple/soon.png b/public/images/emoji/apple/soon.png index f5f4c31f97b..625fe51edf9 100644 Binary files a/public/images/emoji/apple/soon.png and b/public/images/emoji/apple/soon.png differ diff --git a/public/images/emoji/apple/sos.png b/public/images/emoji/apple/sos.png index e9ecad91dcd..fa357cfa22a 100644 Binary files a/public/images/emoji/apple/sos.png and b/public/images/emoji/apple/sos.png differ diff --git a/public/images/emoji/apple/sound.png b/public/images/emoji/apple/sound.png index a2bb894f6c4..485ea840ef6 100644 Binary files a/public/images/emoji/apple/sound.png and b/public/images/emoji/apple/sound.png differ diff --git a/public/images/emoji/apple/space_invader.png b/public/images/emoji/apple/space_invader.png index bde1b857545..16639c5b27a 100644 Binary files a/public/images/emoji/apple/space_invader.png and b/public/images/emoji/apple/space_invader.png differ diff --git a/public/images/emoji/apple/spades.png b/public/images/emoji/apple/spades.png index 2551e77ee9d..470573feb0c 100644 Binary files a/public/images/emoji/apple/spades.png and b/public/images/emoji/apple/spades.png differ diff --git a/public/images/emoji/apple/spaghetti.png b/public/images/emoji/apple/spaghetti.png index be166e778cc..0abc2eb8438 100644 Binary files a/public/images/emoji/apple/spaghetti.png and b/public/images/emoji/apple/spaghetti.png differ diff --git a/public/images/emoji/apple/sparkle.png b/public/images/emoji/apple/sparkle.png index 39e29ddf97b..d9d27f69571 100644 Binary files a/public/images/emoji/apple/sparkle.png and b/public/images/emoji/apple/sparkle.png differ diff --git a/public/images/emoji/apple/sparkler.png b/public/images/emoji/apple/sparkler.png index 5c87ad16e41..ed52f96584f 100644 Binary files a/public/images/emoji/apple/sparkler.png and b/public/images/emoji/apple/sparkler.png differ diff --git a/public/images/emoji/apple/sparkles.png b/public/images/emoji/apple/sparkles.png index e86b72a2965..1c5998e58bf 100644 Binary files a/public/images/emoji/apple/sparkles.png and b/public/images/emoji/apple/sparkles.png differ diff --git a/public/images/emoji/apple/sparkling_heart.png b/public/images/emoji/apple/sparkling_heart.png index b6584c20d6c..b05da6153e9 100644 Binary files a/public/images/emoji/apple/sparkling_heart.png and b/public/images/emoji/apple/sparkling_heart.png differ diff --git a/public/images/emoji/apple/speak_no_evil.png b/public/images/emoji/apple/speak_no_evil.png index cedb6892ad7..45aad92291a 100644 Binary files a/public/images/emoji/apple/speak_no_evil.png and b/public/images/emoji/apple/speak_no_evil.png differ diff --git a/public/images/emoji/apple/speaker.png b/public/images/emoji/apple/speaker.png index f9dad6af57d..252b07bc847 100644 Binary files a/public/images/emoji/apple/speaker.png and b/public/images/emoji/apple/speaker.png differ diff --git a/public/images/emoji/apple/speaking_head.png b/public/images/emoji/apple/speaking_head.png new file mode 100644 index 00000000000..b25c49724be Binary files /dev/null and b/public/images/emoji/apple/speaking_head.png differ diff --git a/public/images/emoji/apple/speech_balloon.png b/public/images/emoji/apple/speech_balloon.png index 39821d58a23..62003287230 100644 Binary files a/public/images/emoji/apple/speech_balloon.png and b/public/images/emoji/apple/speech_balloon.png differ diff --git a/public/images/emoji/apple/speedboat.png b/public/images/emoji/apple/speedboat.png index 48f62e8e1cb..f1a05336fb0 100644 Binary files a/public/images/emoji/apple/speedboat.png and b/public/images/emoji/apple/speedboat.png differ diff --git a/public/images/emoji/apple/spider.png b/public/images/emoji/apple/spider.png new file mode 100644 index 00000000000..4df7e8bfeba Binary files /dev/null and b/public/images/emoji/apple/spider.png differ diff --git a/public/images/emoji/apple/spider_web.png b/public/images/emoji/apple/spider_web.png new file mode 100644 index 00000000000..bbb08b0e124 Binary files /dev/null and b/public/images/emoji/apple/spider_web.png differ diff --git a/public/images/emoji/apple/spy.png b/public/images/emoji/apple/spy.png new file mode 100644 index 00000000000..9cd898d6c12 Binary files /dev/null and b/public/images/emoji/apple/spy.png differ diff --git a/public/images/emoji/apple/stadium.png b/public/images/emoji/apple/stadium.png new file mode 100644 index 00000000000..342032abbd4 Binary files /dev/null and b/public/images/emoji/apple/stadium.png differ diff --git a/public/images/emoji/apple/star.png b/public/images/emoji/apple/star.png index ddbfb4ca73e..5a758104777 100644 Binary files a/public/images/emoji/apple/star.png and b/public/images/emoji/apple/star.png differ diff --git a/public/images/emoji/apple/star2.png b/public/images/emoji/apple/star2.png index c76d820460f..ab5b8e621ba 100644 Binary files a/public/images/emoji/apple/star2.png and b/public/images/emoji/apple/star2.png differ diff --git a/public/images/emoji/apple/star_and_crescent.png b/public/images/emoji/apple/star_and_crescent.png new file mode 100644 index 00000000000..77fd9928d9f Binary files /dev/null and b/public/images/emoji/apple/star_and_crescent.png differ diff --git a/public/images/emoji/apple/star_of_david.png b/public/images/emoji/apple/star_of_david.png new file mode 100644 index 00000000000..82bc00d3ffe Binary files /dev/null and b/public/images/emoji/apple/star_of_david.png differ diff --git a/public/images/emoji/apple/stars.png b/public/images/emoji/apple/stars.png index ff8568a158f..96b02d12632 100644 Binary files a/public/images/emoji/apple/stars.png and b/public/images/emoji/apple/stars.png differ diff --git a/public/images/emoji/apple/station.png b/public/images/emoji/apple/station.png index 3bb66d1b73a..f1779ba7bda 100644 Binary files a/public/images/emoji/apple/station.png and b/public/images/emoji/apple/station.png differ diff --git a/public/images/emoji/apple/statue_of_liberty.png b/public/images/emoji/apple/statue_of_liberty.png index f94f3bf0667..bff98abb26e 100644 Binary files a/public/images/emoji/apple/statue_of_liberty.png and b/public/images/emoji/apple/statue_of_liberty.png differ diff --git a/public/images/emoji/apple/steam_locomotive.png b/public/images/emoji/apple/steam_locomotive.png index 9f36c7803d5..64da1bcb0fd 100644 Binary files a/public/images/emoji/apple/steam_locomotive.png and b/public/images/emoji/apple/steam_locomotive.png differ diff --git a/public/images/emoji/apple/stew.png b/public/images/emoji/apple/stew.png index 17c68daddf6..32d11c71354 100644 Binary files a/public/images/emoji/apple/stew.png and b/public/images/emoji/apple/stew.png differ diff --git a/public/images/emoji/apple/stop_button.png b/public/images/emoji/apple/stop_button.png new file mode 100644 index 00000000000..99258e0249a Binary files /dev/null and b/public/images/emoji/apple/stop_button.png differ diff --git a/public/images/emoji/apple/stopwatch.png b/public/images/emoji/apple/stopwatch.png new file mode 100644 index 00000000000..d194a2d99a4 Binary files /dev/null and b/public/images/emoji/apple/stopwatch.png differ diff --git a/public/images/emoji/apple/straight_ruler.png b/public/images/emoji/apple/straight_ruler.png index 64dbdc3ab04..61af005f244 100644 Binary files a/public/images/emoji/apple/straight_ruler.png and b/public/images/emoji/apple/straight_ruler.png differ diff --git a/public/images/emoji/apple/strawberry.png b/public/images/emoji/apple/strawberry.png index 4fcde96c68e..33e0db8934f 100644 Binary files a/public/images/emoji/apple/strawberry.png and b/public/images/emoji/apple/strawberry.png differ diff --git a/public/images/emoji/apple/stuck_out_tongue.png b/public/images/emoji/apple/stuck_out_tongue.png index e3dd39e4d29..a665f8e46df 100644 Binary files a/public/images/emoji/apple/stuck_out_tongue.png and b/public/images/emoji/apple/stuck_out_tongue.png differ diff --git a/public/images/emoji/apple/stuck_out_tongue_closed_eyes.png b/public/images/emoji/apple/stuck_out_tongue_closed_eyes.png index 974eb23b018..2cf589c26ae 100644 Binary files a/public/images/emoji/apple/stuck_out_tongue_closed_eyes.png and b/public/images/emoji/apple/stuck_out_tongue_closed_eyes.png differ diff --git a/public/images/emoji/apple/stuck_out_tongue_winking_eye.png b/public/images/emoji/apple/stuck_out_tongue_winking_eye.png index 6f7b54d7fa7..ecbea59f395 100644 Binary files a/public/images/emoji/apple/stuck_out_tongue_winking_eye.png and b/public/images/emoji/apple/stuck_out_tongue_winking_eye.png differ diff --git a/public/images/emoji/apple/sun_with_face.png b/public/images/emoji/apple/sun_with_face.png index 573963ddf35..3dd10ee34f6 100644 Binary files a/public/images/emoji/apple/sun_with_face.png and b/public/images/emoji/apple/sun_with_face.png differ diff --git a/public/images/emoji/apple/sunflower.png b/public/images/emoji/apple/sunflower.png index cb9445fd525..ef4648cede5 100644 Binary files a/public/images/emoji/apple/sunflower.png and b/public/images/emoji/apple/sunflower.png differ diff --git a/public/images/emoji/apple/sunglasses.png b/public/images/emoji/apple/sunglasses.png index 018e7a9e1bb..e76b4bb91dd 100644 Binary files a/public/images/emoji/apple/sunglasses.png and b/public/images/emoji/apple/sunglasses.png differ diff --git a/public/images/emoji/apple/sunny.png b/public/images/emoji/apple/sunny.png index 8581935a3f9..1d794c56f40 100644 Binary files a/public/images/emoji/apple/sunny.png and b/public/images/emoji/apple/sunny.png differ diff --git a/public/images/emoji/apple/sunrise.png b/public/images/emoji/apple/sunrise.png index 63b1016d838..f2e8e65a2f7 100644 Binary files a/public/images/emoji/apple/sunrise.png and b/public/images/emoji/apple/sunrise.png differ diff --git a/public/images/emoji/apple/sunrise_over_mountains.png b/public/images/emoji/apple/sunrise_over_mountains.png index cf69bee42d0..290604bee49 100644 Binary files a/public/images/emoji/apple/sunrise_over_mountains.png and b/public/images/emoji/apple/sunrise_over_mountains.png differ diff --git a/public/images/emoji/apple/surfer.png b/public/images/emoji/apple/surfer.png index 44d7686a250..579cc0c43e1 100644 Binary files a/public/images/emoji/apple/surfer.png and b/public/images/emoji/apple/surfer.png differ diff --git a/public/images/emoji/apple/sushi.png b/public/images/emoji/apple/sushi.png index 9d9ae824209..98345e368fd 100644 Binary files a/public/images/emoji/apple/sushi.png and b/public/images/emoji/apple/sushi.png differ diff --git a/public/images/emoji/apple/suspension_railway.png b/public/images/emoji/apple/suspension_railway.png index d7bcb9efa04..0797e019aaf 100644 Binary files a/public/images/emoji/apple/suspension_railway.png and b/public/images/emoji/apple/suspension_railway.png differ diff --git a/public/images/emoji/apple/sweat.png b/public/images/emoji/apple/sweat.png index b0aa7aba9e2..6369faaead1 100644 Binary files a/public/images/emoji/apple/sweat.png and b/public/images/emoji/apple/sweat.png differ diff --git a/public/images/emoji/apple/sweat_drops.png b/public/images/emoji/apple/sweat_drops.png index b828bf7d50c..c92fb74197f 100644 Binary files a/public/images/emoji/apple/sweat_drops.png and b/public/images/emoji/apple/sweat_drops.png differ diff --git a/public/images/emoji/apple/sweat_smile.png b/public/images/emoji/apple/sweat_smile.png index d7fe48fdac7..cc0c019637f 100644 Binary files a/public/images/emoji/apple/sweat_smile.png and b/public/images/emoji/apple/sweat_smile.png differ diff --git a/public/images/emoji/apple/sweet_potato.png b/public/images/emoji/apple/sweet_potato.png index 5f74aa2e4f3..42abf4b8e18 100644 Binary files a/public/images/emoji/apple/sweet_potato.png and b/public/images/emoji/apple/sweet_potato.png differ diff --git a/public/images/emoji/apple/swimmer.png b/public/images/emoji/apple/swimmer.png index 72abc88e922..d5ea26f9a07 100644 Binary files a/public/images/emoji/apple/swimmer.png and b/public/images/emoji/apple/swimmer.png differ diff --git a/public/images/emoji/apple/symbols.png b/public/images/emoji/apple/symbols.png index 0b04e4aeaad..980d59d366a 100644 Binary files a/public/images/emoji/apple/symbols.png and b/public/images/emoji/apple/symbols.png differ diff --git a/public/images/emoji/apple/synagogue.png b/public/images/emoji/apple/synagogue.png new file mode 100644 index 00000000000..9aec9500ca6 Binary files /dev/null and b/public/images/emoji/apple/synagogue.png differ diff --git a/public/images/emoji/apple/syringe.png b/public/images/emoji/apple/syringe.png index ee04531dca8..48dc0734e01 100644 Binary files a/public/images/emoji/apple/syringe.png and b/public/images/emoji/apple/syringe.png differ diff --git a/public/images/emoji/apple/taco.png b/public/images/emoji/apple/taco.png new file mode 100644 index 00000000000..a4e8ba4e308 Binary files /dev/null and b/public/images/emoji/apple/taco.png differ diff --git a/public/images/emoji/apple/tada.png b/public/images/emoji/apple/tada.png index c8ad6868514..8faf4cf3b03 100644 Binary files a/public/images/emoji/apple/tada.png and b/public/images/emoji/apple/tada.png differ diff --git a/public/images/emoji/apple/tanabata_tree.png b/public/images/emoji/apple/tanabata_tree.png index 3f0cf9824fc..d1919d5a239 100644 Binary files a/public/images/emoji/apple/tanabata_tree.png and b/public/images/emoji/apple/tanabata_tree.png differ diff --git a/public/images/emoji/apple/tangerine.png b/public/images/emoji/apple/tangerine.png index f14f05f04d8..ae77cd1b89b 100644 Binary files a/public/images/emoji/apple/tangerine.png and b/public/images/emoji/apple/tangerine.png differ diff --git a/public/images/emoji/apple/taurus.png b/public/images/emoji/apple/taurus.png index bcef07381e2..e30609a3f1b 100644 Binary files a/public/images/emoji/apple/taurus.png and b/public/images/emoji/apple/taurus.png differ diff --git a/public/images/emoji/apple/taxi.png b/public/images/emoji/apple/taxi.png index 75bd300570d..287c839d276 100644 Binary files a/public/images/emoji/apple/taxi.png and b/public/images/emoji/apple/taxi.png differ diff --git a/public/images/emoji/apple/tea.png b/public/images/emoji/apple/tea.png index 871be1fb359..e29f0f89aa0 100644 Binary files a/public/images/emoji/apple/tea.png and b/public/images/emoji/apple/tea.png differ diff --git a/public/images/emoji/apple/telephone.png b/public/images/emoji/apple/telephone.png index fb1d51cdbcd..21b8c9a5fa3 100644 Binary files a/public/images/emoji/apple/telephone.png and b/public/images/emoji/apple/telephone.png differ diff --git a/public/images/emoji/apple/telephone_receiver.png b/public/images/emoji/apple/telephone_receiver.png index c1f0d40ddf4..dccd94dd899 100644 Binary files a/public/images/emoji/apple/telephone_receiver.png and b/public/images/emoji/apple/telephone_receiver.png differ diff --git a/public/images/emoji/apple/telescope.png b/public/images/emoji/apple/telescope.png index 10998259a5c..6a20842f719 100644 Binary files a/public/images/emoji/apple/telescope.png and b/public/images/emoji/apple/telescope.png differ diff --git a/public/images/emoji/apple/ten.png b/public/images/emoji/apple/ten.png new file mode 100644 index 00000000000..68ae72c0f7a Binary files /dev/null and b/public/images/emoji/apple/ten.png differ diff --git a/public/images/emoji/apple/tennis.png b/public/images/emoji/apple/tennis.png index b07a7f4d2fb..c6f7b398377 100644 Binary files a/public/images/emoji/apple/tennis.png and b/public/images/emoji/apple/tennis.png differ diff --git a/public/images/emoji/apple/tent.png b/public/images/emoji/apple/tent.png index c87edc4b404..511bbbdbf58 100644 Binary files a/public/images/emoji/apple/tent.png and b/public/images/emoji/apple/tent.png differ diff --git a/public/images/emoji/apple/thermometer.png b/public/images/emoji/apple/thermometer.png new file mode 100644 index 00000000000..94d30503cdf Binary files /dev/null and b/public/images/emoji/apple/thermometer.png differ diff --git a/public/images/emoji/apple/thermometer_face.png b/public/images/emoji/apple/thermometer_face.png new file mode 100644 index 00000000000..462afa0e8ea Binary files /dev/null and b/public/images/emoji/apple/thermometer_face.png differ diff --git a/public/images/emoji/apple/thinking.png b/public/images/emoji/apple/thinking.png new file mode 100644 index 00000000000..471c4a3a4b7 Binary files /dev/null and b/public/images/emoji/apple/thinking.png differ diff --git a/public/images/emoji/apple/thought_balloon.png b/public/images/emoji/apple/thought_balloon.png index 3ddecff6843..6f00e3009a9 100644 Binary files a/public/images/emoji/apple/thought_balloon.png and b/public/images/emoji/apple/thought_balloon.png differ diff --git a/public/images/emoji/apple/three.png b/public/images/emoji/apple/three.png index 8a381d9ce93..32a9df29abc 100644 Binary files a/public/images/emoji/apple/three.png and b/public/images/emoji/apple/three.png differ diff --git a/public/images/emoji/apple/thumbsdown.png b/public/images/emoji/apple/thumbsdown.png index c7fb4c06497..934ce9c23f2 100644 Binary files a/public/images/emoji/apple/thumbsdown.png and b/public/images/emoji/apple/thumbsdown.png differ diff --git a/public/images/emoji/apple/thumbsup.png b/public/images/emoji/apple/thumbsup.png index e1d89aada6a..c59befcc163 100644 Binary files a/public/images/emoji/apple/thumbsup.png and b/public/images/emoji/apple/thumbsup.png differ diff --git a/public/images/emoji/apple/thunder_cloud_rain.png b/public/images/emoji/apple/thunder_cloud_rain.png new file mode 100644 index 00000000000..54d0d491ba2 Binary files /dev/null and b/public/images/emoji/apple/thunder_cloud_rain.png differ diff --git a/public/images/emoji/apple/ticket.png b/public/images/emoji/apple/ticket.png index 0b4cf7eff1c..edb1f23941a 100644 Binary files a/public/images/emoji/apple/ticket.png and b/public/images/emoji/apple/ticket.png differ diff --git a/public/images/emoji/apple/tickets.png b/public/images/emoji/apple/tickets.png new file mode 100644 index 00000000000..d019a6976f4 Binary files /dev/null and b/public/images/emoji/apple/tickets.png differ diff --git a/public/images/emoji/apple/tiger.png b/public/images/emoji/apple/tiger.png index 570abedef5d..31104511842 100644 Binary files a/public/images/emoji/apple/tiger.png and b/public/images/emoji/apple/tiger.png differ diff --git a/public/images/emoji/apple/tiger2.png b/public/images/emoji/apple/tiger2.png index 846aee7b5fb..2b064958d03 100644 Binary files a/public/images/emoji/apple/tiger2.png and b/public/images/emoji/apple/tiger2.png differ diff --git a/public/images/emoji/apple/timer.png b/public/images/emoji/apple/timer.png new file mode 100644 index 00000000000..a900a0599d3 Binary files /dev/null and b/public/images/emoji/apple/timer.png differ diff --git a/public/images/emoji/apple/tired_face.png b/public/images/emoji/apple/tired_face.png index 1b7871819cf..ca89544ab3b 100644 Binary files a/public/images/emoji/apple/tired_face.png and b/public/images/emoji/apple/tired_face.png differ diff --git a/public/images/emoji/apple/tm.png b/public/images/emoji/apple/tm.png index 569a83941be..48a7ebe1d61 100644 Binary files a/public/images/emoji/apple/tm.png and b/public/images/emoji/apple/tm.png differ diff --git a/public/images/emoji/apple/toilet.png b/public/images/emoji/apple/toilet.png index f3cf3524344..9b98049b85a 100644 Binary files a/public/images/emoji/apple/toilet.png and b/public/images/emoji/apple/toilet.png differ diff --git a/public/images/emoji/apple/tokyo_tower.png b/public/images/emoji/apple/tokyo_tower.png index 253dfd5aec1..4f88e850bab 100644 Binary files a/public/images/emoji/apple/tokyo_tower.png and b/public/images/emoji/apple/tokyo_tower.png differ diff --git a/public/images/emoji/apple/tomato.png b/public/images/emoji/apple/tomato.png index a50c40daf52..d839d3866f4 100644 Binary files a/public/images/emoji/apple/tomato.png and b/public/images/emoji/apple/tomato.png differ diff --git a/public/images/emoji/apple/tongue.png b/public/images/emoji/apple/tongue.png index e4b6c286747..72b83563ca5 100644 Binary files a/public/images/emoji/apple/tongue.png and b/public/images/emoji/apple/tongue.png differ diff --git a/public/images/emoji/apple/tools.png b/public/images/emoji/apple/tools.png new file mode 100644 index 00000000000..05671ef41e2 Binary files /dev/null and b/public/images/emoji/apple/tools.png differ diff --git a/public/images/emoji/apple/top.png b/public/images/emoji/apple/top.png index 44bde1c3d24..fac8873b057 100644 Binary files a/public/images/emoji/apple/top.png and b/public/images/emoji/apple/top.png differ diff --git a/public/images/emoji/apple/tophat.png b/public/images/emoji/apple/tophat.png index e6813d9b6f5..0c63dfc7b82 100644 Binary files a/public/images/emoji/apple/tophat.png and b/public/images/emoji/apple/tophat.png differ diff --git a/public/images/emoji/apple/track_next.png b/public/images/emoji/apple/track_next.png new file mode 100644 index 00000000000..6c6638ce884 Binary files /dev/null and b/public/images/emoji/apple/track_next.png differ diff --git a/public/images/emoji/apple/track_previous.png b/public/images/emoji/apple/track_previous.png new file mode 100644 index 00000000000..6bef75ae038 Binary files /dev/null and b/public/images/emoji/apple/track_previous.png differ diff --git a/public/images/emoji/apple/trackball.png b/public/images/emoji/apple/trackball.png new file mode 100644 index 00000000000..26567260c7e Binary files /dev/null and b/public/images/emoji/apple/trackball.png differ diff --git a/public/images/emoji/apple/tractor.png b/public/images/emoji/apple/tractor.png index 5ffb5492306..db2bd093f3b 100644 Binary files a/public/images/emoji/apple/tractor.png and b/public/images/emoji/apple/tractor.png differ diff --git a/public/images/emoji/apple/traffic_light.png b/public/images/emoji/apple/traffic_light.png index e639866cfeb..984d6c9a3fe 100644 Binary files a/public/images/emoji/apple/traffic_light.png and b/public/images/emoji/apple/traffic_light.png differ diff --git a/public/images/emoji/apple/train.png b/public/images/emoji/apple/train.png index 58720cf4ffb..0964527e777 100644 Binary files a/public/images/emoji/apple/train.png and b/public/images/emoji/apple/train.png differ diff --git a/public/images/emoji/apple/train2.png b/public/images/emoji/apple/train2.png index cdb6fdb7a19..ff49d55f902 100644 Binary files a/public/images/emoji/apple/train2.png and b/public/images/emoji/apple/train2.png differ diff --git a/public/images/emoji/apple/tram.png b/public/images/emoji/apple/tram.png index 17824fd52cd..d893fce00a9 100644 Binary files a/public/images/emoji/apple/tram.png and b/public/images/emoji/apple/tram.png differ diff --git a/public/images/emoji/apple/triangular_flag_on_post.png b/public/images/emoji/apple/triangular_flag_on_post.png index d938209f4dc..e42737b27b9 100644 Binary files a/public/images/emoji/apple/triangular_flag_on_post.png and b/public/images/emoji/apple/triangular_flag_on_post.png differ diff --git a/public/images/emoji/apple/triangular_ruler.png b/public/images/emoji/apple/triangular_ruler.png index b3cfa6d238a..8cb5b848c3c 100644 Binary files a/public/images/emoji/apple/triangular_ruler.png and b/public/images/emoji/apple/triangular_ruler.png differ diff --git a/public/images/emoji/apple/trident.png b/public/images/emoji/apple/trident.png index 1f6c82a316e..f53d3406ef7 100644 Binary files a/public/images/emoji/apple/trident.png and b/public/images/emoji/apple/trident.png differ diff --git a/public/images/emoji/apple/triumph.png b/public/images/emoji/apple/triumph.png index da654216ced..0a4ecd953a9 100644 Binary files a/public/images/emoji/apple/triumph.png and b/public/images/emoji/apple/triumph.png differ diff --git a/public/images/emoji/apple/trolleybus.png b/public/images/emoji/apple/trolleybus.png index 7a7d20510ad..8253d6438d5 100644 Binary files a/public/images/emoji/apple/trolleybus.png and b/public/images/emoji/apple/trolleybus.png differ diff --git a/public/images/emoji/apple/trophy.png b/public/images/emoji/apple/trophy.png index 8d9a91dbf11..5d60256c423 100644 Binary files a/public/images/emoji/apple/trophy.png and b/public/images/emoji/apple/trophy.png differ diff --git a/public/images/emoji/apple/tropical_drink.png b/public/images/emoji/apple/tropical_drink.png index 108950ed90e..5e25716adb0 100644 Binary files a/public/images/emoji/apple/tropical_drink.png and b/public/images/emoji/apple/tropical_drink.png differ diff --git a/public/images/emoji/apple/tropical_fish.png b/public/images/emoji/apple/tropical_fish.png index d6604096fa3..74bdb675910 100644 Binary files a/public/images/emoji/apple/tropical_fish.png and b/public/images/emoji/apple/tropical_fish.png differ diff --git a/public/images/emoji/apple/truck.png b/public/images/emoji/apple/truck.png index 62aa3a74293..162527d9e83 100644 Binary files a/public/images/emoji/apple/truck.png and b/public/images/emoji/apple/truck.png differ diff --git a/public/images/emoji/apple/trumpet.png b/public/images/emoji/apple/trumpet.png index e623887d8d0..1a5e60092a1 100644 Binary files a/public/images/emoji/apple/trumpet.png and b/public/images/emoji/apple/trumpet.png differ diff --git a/public/images/emoji/apple/tshirt.png b/public/images/emoji/apple/tshirt.png index 725a4a7a4bd..39abccfb268 100644 Binary files a/public/images/emoji/apple/tshirt.png and b/public/images/emoji/apple/tshirt.png differ diff --git a/public/images/emoji/apple/tulip.png b/public/images/emoji/apple/tulip.png index fe36a905302..7796d7a8ead 100644 Binary files a/public/images/emoji/apple/tulip.png and b/public/images/emoji/apple/tulip.png differ diff --git a/public/images/emoji/apple/turkey.png b/public/images/emoji/apple/turkey.png new file mode 100644 index 00000000000..bb5f1493512 Binary files /dev/null and b/public/images/emoji/apple/turkey.png differ diff --git a/public/images/emoji/apple/turtle.png b/public/images/emoji/apple/turtle.png index 997a19b1bdb..35e417543a8 100644 Binary files a/public/images/emoji/apple/turtle.png and b/public/images/emoji/apple/turtle.png differ diff --git a/public/images/emoji/apple/tv.png b/public/images/emoji/apple/tv.png index 5bb841038b8..6cc8f1e65c1 100644 Binary files a/public/images/emoji/apple/tv.png and b/public/images/emoji/apple/tv.png differ diff --git a/public/images/emoji/apple/twisted_rightwards_arrows.png b/public/images/emoji/apple/twisted_rightwards_arrows.png index 6c1df96d699..35e3c4149ff 100644 Binary files a/public/images/emoji/apple/twisted_rightwards_arrows.png and b/public/images/emoji/apple/twisted_rightwards_arrows.png differ diff --git a/public/images/emoji/apple/two.png b/public/images/emoji/apple/two.png index f7f745f927e..f5130088b19 100644 Binary files a/public/images/emoji/apple/two.png and b/public/images/emoji/apple/two.png differ diff --git a/public/images/emoji/apple/two_hearts.png b/public/images/emoji/apple/two_hearts.png index e3d18215c67..80b7905b90f 100644 Binary files a/public/images/emoji/apple/two_hearts.png and b/public/images/emoji/apple/two_hearts.png differ diff --git a/public/images/emoji/apple/two_men_holding_hands.png b/public/images/emoji/apple/two_men_holding_hands.png index 1fe5d323e19..e140237025f 100644 Binary files a/public/images/emoji/apple/two_men_holding_hands.png and b/public/images/emoji/apple/two_men_holding_hands.png differ diff --git a/public/images/emoji/apple/two_women_holding_hands.png b/public/images/emoji/apple/two_women_holding_hands.png index 7fc9f038a55..6f943aa2245 100644 Binary files a/public/images/emoji/apple/two_women_holding_hands.png and b/public/images/emoji/apple/two_women_holding_hands.png differ diff --git a/public/images/emoji/apple/u5272.png b/public/images/emoji/apple/u5272.png index 619b23dad43..d8c2ca780df 100644 Binary files a/public/images/emoji/apple/u5272.png and b/public/images/emoji/apple/u5272.png differ diff --git a/public/images/emoji/apple/u5408.png b/public/images/emoji/apple/u5408.png index 408a32ba238..d826b72b030 100644 Binary files a/public/images/emoji/apple/u5408.png and b/public/images/emoji/apple/u5408.png differ diff --git a/public/images/emoji/apple/u55b6.png b/public/images/emoji/apple/u55b6.png index 0b25a8d6b99..b073ba7cc22 100644 Binary files a/public/images/emoji/apple/u55b6.png and b/public/images/emoji/apple/u55b6.png differ diff --git a/public/images/emoji/apple/u6307.png b/public/images/emoji/apple/u6307.png index acea4049f3d..25306ed567d 100644 Binary files a/public/images/emoji/apple/u6307.png and b/public/images/emoji/apple/u6307.png differ diff --git a/public/images/emoji/apple/u6708.png b/public/images/emoji/apple/u6708.png index 9c96b1b7f40..dd597f521d0 100644 Binary files a/public/images/emoji/apple/u6708.png and b/public/images/emoji/apple/u6708.png differ diff --git a/public/images/emoji/apple/u6709.png b/public/images/emoji/apple/u6709.png index d792be751f5..9714c94b47b 100644 Binary files a/public/images/emoji/apple/u6709.png and b/public/images/emoji/apple/u6709.png differ diff --git a/public/images/emoji/apple/u6e80.png b/public/images/emoji/apple/u6e80.png index afe620cd4b4..a1d3ee7919e 100644 Binary files a/public/images/emoji/apple/u6e80.png and b/public/images/emoji/apple/u6e80.png differ diff --git a/public/images/emoji/apple/u7121.png b/public/images/emoji/apple/u7121.png index 5f6eacc4554..8e573e4ebb2 100644 Binary files a/public/images/emoji/apple/u7121.png and b/public/images/emoji/apple/u7121.png differ diff --git a/public/images/emoji/apple/u7533.png b/public/images/emoji/apple/u7533.png index d2898eedc95..b76cd6cc292 100644 Binary files a/public/images/emoji/apple/u7533.png and b/public/images/emoji/apple/u7533.png differ diff --git a/public/images/emoji/apple/u7981.png b/public/images/emoji/apple/u7981.png index daab0c2ebb6..d9ae5a3fa99 100644 Binary files a/public/images/emoji/apple/u7981.png and b/public/images/emoji/apple/u7981.png differ diff --git a/public/images/emoji/apple/u7a7a.png b/public/images/emoji/apple/u7a7a.png index 2b94c1804a3..407bb2a84db 100644 Binary files a/public/images/emoji/apple/u7a7a.png and b/public/images/emoji/apple/u7a7a.png differ diff --git a/public/images/emoji/apple/uk.png b/public/images/emoji/apple/uk.png index 6baa662eb8b..824e2ff2b48 100644 Binary files a/public/images/emoji/apple/uk.png and b/public/images/emoji/apple/uk.png differ diff --git a/public/images/emoji/apple/umbrella.png b/public/images/emoji/apple/umbrella.png index 690e5f20bf3..3cdedc012ca 100644 Binary files a/public/images/emoji/apple/umbrella.png and b/public/images/emoji/apple/umbrella.png differ diff --git a/public/images/emoji/apple/umbrella2.png b/public/images/emoji/apple/umbrella2.png new file mode 100644 index 00000000000..541849c8bb9 Binary files /dev/null and b/public/images/emoji/apple/umbrella2.png differ diff --git a/public/images/emoji/apple/unamused.png b/public/images/emoji/apple/unamused.png index 9d4e1592e41..0bc87849599 100644 Binary files a/public/images/emoji/apple/unamused.png and b/public/images/emoji/apple/unamused.png differ diff --git a/public/images/emoji/apple/underage.png b/public/images/emoji/apple/underage.png index 79a3bdb4ef1..99fa959c154 100644 Binary files a/public/images/emoji/apple/underage.png and b/public/images/emoji/apple/underage.png differ diff --git a/public/images/emoji/apple/unicorn.png b/public/images/emoji/apple/unicorn.png new file mode 100644 index 00000000000..6fe83ed344f Binary files /dev/null and b/public/images/emoji/apple/unicorn.png differ diff --git a/public/images/emoji/apple/unlock.png b/public/images/emoji/apple/unlock.png index cc1e9a20f28..0ff56233884 100644 Binary files a/public/images/emoji/apple/unlock.png and b/public/images/emoji/apple/unlock.png differ diff --git a/public/images/emoji/apple/up.png b/public/images/emoji/apple/up.png index 18b903b3b96..0e8b98343a7 100644 Binary files a/public/images/emoji/apple/up.png and b/public/images/emoji/apple/up.png differ diff --git a/public/images/emoji/apple/upside_down.png b/public/images/emoji/apple/upside_down.png new file mode 100644 index 00000000000..34b6fec2582 Binary files /dev/null and b/public/images/emoji/apple/upside_down.png differ diff --git a/public/images/emoji/apple/urn.png b/public/images/emoji/apple/urn.png new file mode 100644 index 00000000000..1a71bd1f84b Binary files /dev/null and b/public/images/emoji/apple/urn.png differ diff --git a/public/images/emoji/apple/us.png b/public/images/emoji/apple/us.png index 6c09be9b38e..72a949d087d 100644 Binary files a/public/images/emoji/apple/us.png and b/public/images/emoji/apple/us.png differ diff --git a/public/images/emoji/apple/v.png b/public/images/emoji/apple/v.png index 03ce0681a51..521b5173279 100644 Binary files a/public/images/emoji/apple/v.png and b/public/images/emoji/apple/v.png differ diff --git a/public/images/emoji/apple/vertical_traffic_light.png b/public/images/emoji/apple/vertical_traffic_light.png index 62b6f793edf..8bcd5c1ae37 100644 Binary files a/public/images/emoji/apple/vertical_traffic_light.png and b/public/images/emoji/apple/vertical_traffic_light.png differ diff --git a/public/images/emoji/apple/vhs.png b/public/images/emoji/apple/vhs.png index 134989b4ddb..4b7bc17e4b7 100644 Binary files a/public/images/emoji/apple/vhs.png and b/public/images/emoji/apple/vhs.png differ diff --git a/public/images/emoji/apple/vibration_mode.png b/public/images/emoji/apple/vibration_mode.png index c9966afd490..764d5fb8c8e 100644 Binary files a/public/images/emoji/apple/vibration_mode.png and b/public/images/emoji/apple/vibration_mode.png differ diff --git a/public/images/emoji/apple/video_camera.png b/public/images/emoji/apple/video_camera.png index 974872c3065..1871b0579e6 100644 Binary files a/public/images/emoji/apple/video_camera.png and b/public/images/emoji/apple/video_camera.png differ diff --git a/public/images/emoji/apple/video_game.png b/public/images/emoji/apple/video_game.png index 0742cee8422..5e8eb00513a 100644 Binary files a/public/images/emoji/apple/video_game.png and b/public/images/emoji/apple/video_game.png differ diff --git a/public/images/emoji/apple/violin.png b/public/images/emoji/apple/violin.png index 6a1cf6cdbd4..bd91e0a9250 100644 Binary files a/public/images/emoji/apple/violin.png and b/public/images/emoji/apple/violin.png differ diff --git a/public/images/emoji/apple/virgo.png b/public/images/emoji/apple/virgo.png index 65e7514201b..02ef97a346b 100644 Binary files a/public/images/emoji/apple/virgo.png and b/public/images/emoji/apple/virgo.png differ diff --git a/public/images/emoji/apple/volcano.png b/public/images/emoji/apple/volcano.png index 2768967a9a8..dfdac21fd26 100644 Binary files a/public/images/emoji/apple/volcano.png and b/public/images/emoji/apple/volcano.png differ diff --git a/public/images/emoji/apple/volleyball.png b/public/images/emoji/apple/volleyball.png new file mode 100644 index 00000000000..50db05cd43f Binary files /dev/null and b/public/images/emoji/apple/volleyball.png differ diff --git a/public/images/emoji/apple/vs.png b/public/images/emoji/apple/vs.png index 07ce4b5dbe7..cd5e2dcda4d 100644 Binary files a/public/images/emoji/apple/vs.png and b/public/images/emoji/apple/vs.png differ diff --git a/public/images/emoji/apple/vulcan.png b/public/images/emoji/apple/vulcan.png new file mode 100644 index 00000000000..9f1006c0fd5 Binary files /dev/null and b/public/images/emoji/apple/vulcan.png differ diff --git a/public/images/emoji/apple/walking.png b/public/images/emoji/apple/walking.png index 25d9635e3e4..d814272cf8e 100644 Binary files a/public/images/emoji/apple/walking.png and b/public/images/emoji/apple/walking.png differ diff --git a/public/images/emoji/apple/waning_crescent_moon.png b/public/images/emoji/apple/waning_crescent_moon.png index d6873a6653d..e8a1e7151eb 100644 Binary files a/public/images/emoji/apple/waning_crescent_moon.png and b/public/images/emoji/apple/waning_crescent_moon.png differ diff --git a/public/images/emoji/apple/waning_gibbous_moon.png b/public/images/emoji/apple/waning_gibbous_moon.png index 1ae88a5e926..5a4f769f1c8 100644 Binary files a/public/images/emoji/apple/waning_gibbous_moon.png and b/public/images/emoji/apple/waning_gibbous_moon.png differ diff --git a/public/images/emoji/apple/warning.png b/public/images/emoji/apple/warning.png index 9e51d2b78bf..81318820bf5 100644 Binary files a/public/images/emoji/apple/warning.png and b/public/images/emoji/apple/warning.png differ diff --git a/public/images/emoji/apple/wastebasket.png b/public/images/emoji/apple/wastebasket.png new file mode 100644 index 00000000000..2288fcaf860 Binary files /dev/null and b/public/images/emoji/apple/wastebasket.png differ diff --git a/public/images/emoji/apple/watch.png b/public/images/emoji/apple/watch.png index a8e60eee749..b95bef19716 100644 Binary files a/public/images/emoji/apple/watch.png and b/public/images/emoji/apple/watch.png differ diff --git a/public/images/emoji/apple/water_buffalo.png b/public/images/emoji/apple/water_buffalo.png index 0f67aff6b4c..f806db83a5b 100644 Binary files a/public/images/emoji/apple/water_buffalo.png and b/public/images/emoji/apple/water_buffalo.png differ diff --git a/public/images/emoji/apple/watermelon.png b/public/images/emoji/apple/watermelon.png index dd60d2de381..9e94817135c 100644 Binary files a/public/images/emoji/apple/watermelon.png and b/public/images/emoji/apple/watermelon.png differ diff --git a/public/images/emoji/apple/wave.png b/public/images/emoji/apple/wave.png index cb4a618f561..525f3fb4b6a 100644 Binary files a/public/images/emoji/apple/wave.png and b/public/images/emoji/apple/wave.png differ diff --git a/public/images/emoji/apple/wavy_dash.png b/public/images/emoji/apple/wavy_dash.png index 0908acbc3bd..1fe7ae51334 100644 Binary files a/public/images/emoji/apple/wavy_dash.png and b/public/images/emoji/apple/wavy_dash.png differ diff --git a/public/images/emoji/apple/waxing_crescent_moon.png b/public/images/emoji/apple/waxing_crescent_moon.png index 11c43fba428..7d5b0bfb549 100644 Binary files a/public/images/emoji/apple/waxing_crescent_moon.png and b/public/images/emoji/apple/waxing_crescent_moon.png differ diff --git a/public/images/emoji/apple/waxing_gibbous_moon.png b/public/images/emoji/apple/waxing_gibbous_moon.png index 03e9b3dabaf..246e3545281 100644 Binary files a/public/images/emoji/apple/waxing_gibbous_moon.png and b/public/images/emoji/apple/waxing_gibbous_moon.png differ diff --git a/public/images/emoji/apple/wc.png b/public/images/emoji/apple/wc.png index 8ddf680c1d6..dbbff440dcd 100644 Binary files a/public/images/emoji/apple/wc.png and b/public/images/emoji/apple/wc.png differ diff --git a/public/images/emoji/apple/weary.png b/public/images/emoji/apple/weary.png index 51f4cebb55f..52548e90517 100644 Binary files a/public/images/emoji/apple/weary.png and b/public/images/emoji/apple/weary.png differ diff --git a/public/images/emoji/apple/wedding.png b/public/images/emoji/apple/wedding.png index b104a68c346..5428cb198c1 100644 Binary files a/public/images/emoji/apple/wedding.png and b/public/images/emoji/apple/wedding.png differ diff --git a/public/images/emoji/apple/whale.png b/public/images/emoji/apple/whale.png index 45ed0a77058..ce6ebeee736 100644 Binary files a/public/images/emoji/apple/whale.png and b/public/images/emoji/apple/whale.png differ diff --git a/public/images/emoji/apple/whale2.png b/public/images/emoji/apple/whale2.png index b25d44c2096..283201a4d63 100644 Binary files a/public/images/emoji/apple/whale2.png and b/public/images/emoji/apple/whale2.png differ diff --git a/public/images/emoji/apple/wheel_of_dharma.png b/public/images/emoji/apple/wheel_of_dharma.png new file mode 100644 index 00000000000..90ca228b388 Binary files /dev/null and b/public/images/emoji/apple/wheel_of_dharma.png differ diff --git a/public/images/emoji/apple/wheelchair.png b/public/images/emoji/apple/wheelchair.png index 4091fd27475..2f01cbf2e51 100644 Binary files a/public/images/emoji/apple/wheelchair.png and b/public/images/emoji/apple/wheelchair.png differ diff --git a/public/images/emoji/apple/white_check_mark.png b/public/images/emoji/apple/white_check_mark.png index 30d5b01ab0a..738a8214bac 100644 Binary files a/public/images/emoji/apple/white_check_mark.png and b/public/images/emoji/apple/white_check_mark.png differ diff --git a/public/images/emoji/apple/white_circle.png b/public/images/emoji/apple/white_circle.png index ac1a3908e3e..2c91c945035 100644 Binary files a/public/images/emoji/apple/white_circle.png and b/public/images/emoji/apple/white_circle.png differ diff --git a/public/images/emoji/apple/white_flower.png b/public/images/emoji/apple/white_flower.png index 0687f0835ef..7a453f50357 100644 Binary files a/public/images/emoji/apple/white_flower.png and b/public/images/emoji/apple/white_flower.png differ diff --git a/public/images/emoji/apple/white_large_square.png b/public/images/emoji/apple/white_large_square.png index c9b6916a289..9b32f43f521 100644 Binary files a/public/images/emoji/apple/white_large_square.png and b/public/images/emoji/apple/white_large_square.png differ diff --git a/public/images/emoji/apple/white_medium_small_square.png b/public/images/emoji/apple/white_medium_small_square.png index ce959faecd9..f345db121da 100644 Binary files a/public/images/emoji/apple/white_medium_small_square.png and b/public/images/emoji/apple/white_medium_small_square.png differ diff --git a/public/images/emoji/apple/white_medium_square.png b/public/images/emoji/apple/white_medium_square.png index 11d576bd994..3c3ffe08360 100644 Binary files a/public/images/emoji/apple/white_medium_square.png and b/public/images/emoji/apple/white_medium_square.png differ diff --git a/public/images/emoji/apple/white_small_square.png b/public/images/emoji/apple/white_small_square.png index 8f5b2fb3665..46bc09f109d 100644 Binary files a/public/images/emoji/apple/white_small_square.png and b/public/images/emoji/apple/white_small_square.png differ diff --git a/public/images/emoji/apple/white_square_button.png b/public/images/emoji/apple/white_square_button.png index 3500c14be46..b53607c3895 100644 Binary files a/public/images/emoji/apple/white_square_button.png and b/public/images/emoji/apple/white_square_button.png differ diff --git a/public/images/emoji/apple/white_sun_cloud.png b/public/images/emoji/apple/white_sun_cloud.png new file mode 100644 index 00000000000..ecdd80a3650 Binary files /dev/null and b/public/images/emoji/apple/white_sun_cloud.png differ diff --git a/public/images/emoji/apple/white_sun_rain_cloud.png b/public/images/emoji/apple/white_sun_rain_cloud.png new file mode 100644 index 00000000000..6235af0b93a Binary files /dev/null and b/public/images/emoji/apple/white_sun_rain_cloud.png differ diff --git a/public/images/emoji/apple/white_sun_small_cloud.png b/public/images/emoji/apple/white_sun_small_cloud.png new file mode 100644 index 00000000000..af664c7f25b Binary files /dev/null and b/public/images/emoji/apple/white_sun_small_cloud.png differ diff --git a/public/images/emoji/apple/wind_blowing_face.png b/public/images/emoji/apple/wind_blowing_face.png new file mode 100644 index 00000000000..785159cf3d4 Binary files /dev/null and b/public/images/emoji/apple/wind_blowing_face.png differ diff --git a/public/images/emoji/apple/wind_chime.png b/public/images/emoji/apple/wind_chime.png index 856f00ed0d1..9bf76c657a7 100644 Binary files a/public/images/emoji/apple/wind_chime.png and b/public/images/emoji/apple/wind_chime.png differ diff --git a/public/images/emoji/apple/wine_glass.png b/public/images/emoji/apple/wine_glass.png index 1b890898bd2..939e27f2025 100644 Binary files a/public/images/emoji/apple/wine_glass.png and b/public/images/emoji/apple/wine_glass.png differ diff --git a/public/images/emoji/apple/wink.png b/public/images/emoji/apple/wink.png index 1f092b9cf97..8beeb421bd2 100644 Binary files a/public/images/emoji/apple/wink.png and b/public/images/emoji/apple/wink.png differ diff --git a/public/images/emoji/apple/wolf.png b/public/images/emoji/apple/wolf.png index c7953eed91c..aeeda88abd9 100644 Binary files a/public/images/emoji/apple/wolf.png and b/public/images/emoji/apple/wolf.png differ diff --git a/public/images/emoji/apple/woman.png b/public/images/emoji/apple/woman.png index dc6434a6730..242b73437b1 100644 Binary files a/public/images/emoji/apple/woman.png and b/public/images/emoji/apple/woman.png differ diff --git a/public/images/emoji/apple/womans_clothes.png b/public/images/emoji/apple/womans_clothes.png index f4250ecbe7b..e7e75154fee 100644 Binary files a/public/images/emoji/apple/womans_clothes.png and b/public/images/emoji/apple/womans_clothes.png differ diff --git a/public/images/emoji/apple/womans_hat.png b/public/images/emoji/apple/womans_hat.png index f5a1e8f747e..15670fbac80 100644 Binary files a/public/images/emoji/apple/womans_hat.png and b/public/images/emoji/apple/womans_hat.png differ diff --git a/public/images/emoji/apple/womens.png b/public/images/emoji/apple/womens.png index 3843da3807b..fc7c1406688 100644 Binary files a/public/images/emoji/apple/womens.png and b/public/images/emoji/apple/womens.png differ diff --git a/public/images/emoji/apple/worried.png b/public/images/emoji/apple/worried.png index f5f1b598ed6..206ac9874ea 100644 Binary files a/public/images/emoji/apple/worried.png and b/public/images/emoji/apple/worried.png differ diff --git a/public/images/emoji/apple/wrench.png b/public/images/emoji/apple/wrench.png index 838d39f32d5..0435cbef62a 100644 Binary files a/public/images/emoji/apple/wrench.png and b/public/images/emoji/apple/wrench.png differ diff --git a/public/images/emoji/apple/writing_hand.png b/public/images/emoji/apple/writing_hand.png new file mode 100644 index 00000000000..83421711b15 Binary files /dev/null and b/public/images/emoji/apple/writing_hand.png differ diff --git a/public/images/emoji/apple/x.png b/public/images/emoji/apple/x.png index 14df4723aa8..d624d0b4501 100644 Binary files a/public/images/emoji/apple/x.png and b/public/images/emoji/apple/x.png differ diff --git a/public/images/emoji/apple/yellow_heart.png b/public/images/emoji/apple/yellow_heart.png index ed7f153cd76..0eb5be53bc4 100644 Binary files a/public/images/emoji/apple/yellow_heart.png and b/public/images/emoji/apple/yellow_heart.png differ diff --git a/public/images/emoji/apple/yen.png b/public/images/emoji/apple/yen.png index c695a78ecdc..2dc5fc64d5e 100644 Binary files a/public/images/emoji/apple/yen.png and b/public/images/emoji/apple/yen.png differ diff --git a/public/images/emoji/apple/yin_yang.png b/public/images/emoji/apple/yin_yang.png new file mode 100644 index 00000000000..8fb121fcdae Binary files /dev/null and b/public/images/emoji/apple/yin_yang.png differ diff --git a/public/images/emoji/apple/yum.png b/public/images/emoji/apple/yum.png index b7de2fe729a..b2d830d3861 100644 Binary files a/public/images/emoji/apple/yum.png and b/public/images/emoji/apple/yum.png differ diff --git a/public/images/emoji/apple/zap.png b/public/images/emoji/apple/zap.png index 3b894b345d3..ad614279376 100644 Binary files a/public/images/emoji/apple/zap.png and b/public/images/emoji/apple/zap.png differ diff --git a/public/images/emoji/apple/zero.png b/public/images/emoji/apple/zero.png index 34445165dee..51c031477bf 100644 Binary files a/public/images/emoji/apple/zero.png and b/public/images/emoji/apple/zero.png differ diff --git a/public/images/emoji/apple/zipper_mouth.png b/public/images/emoji/apple/zipper_mouth.png new file mode 100644 index 00000000000..c5d1323c5ce Binary files /dev/null and b/public/images/emoji/apple/zipper_mouth.png differ diff --git a/public/images/emoji/apple/zzz.png b/public/images/emoji/apple/zzz.png index 32bfe76cf8e..a60a0799951 100644 Binary files a/public/images/emoji/apple/zzz.png and b/public/images/emoji/apple/zzz.png differ diff --git a/public/images/emoji/emoji_one/+1.png b/public/images/emoji/emoji_one/+1.png index 0eca450d597..1cf53385fc9 100644 Binary files a/public/images/emoji/emoji_one/+1.png and b/public/images/emoji/emoji_one/+1.png differ diff --git a/public/images/emoji/emoji_one/-1.png b/public/images/emoji/emoji_one/-1.png index 9b6d251b543..ea63ba981ca 100644 Binary files a/public/images/emoji/emoji_one/-1.png and b/public/images/emoji/emoji_one/-1.png differ diff --git a/public/images/emoji/emoji_one/100.png b/public/images/emoji/emoji_one/100.png index 443b163ee04..bd2878b1b8f 100644 Binary files a/public/images/emoji/emoji_one/100.png and b/public/images/emoji/emoji_one/100.png differ diff --git a/public/images/emoji/emoji_one/1234.png b/public/images/emoji/emoji_one/1234.png index af756e561fe..ea9f70d4eb6 100644 Binary files a/public/images/emoji/emoji_one/1234.png and b/public/images/emoji/emoji_one/1234.png differ diff --git a/public/images/emoji/emoji_one/8ball.png b/public/images/emoji/emoji_one/8ball.png index f713ad25231..4515c60a3da 100644 Binary files a/public/images/emoji/emoji_one/8ball.png and b/public/images/emoji/emoji_one/8ball.png differ diff --git a/public/images/emoji/emoji_one/a.png b/public/images/emoji/emoji_one/a.png index 92e42f6310c..e6bb566c18d 100644 Binary files a/public/images/emoji/emoji_one/a.png and b/public/images/emoji/emoji_one/a.png differ diff --git a/public/images/emoji/emoji_one/ab.png b/public/images/emoji/emoji_one/ab.png index b18b5d05974..c20d6e8972d 100644 Binary files a/public/images/emoji/emoji_one/ab.png and b/public/images/emoji/emoji_one/ab.png differ diff --git a/public/images/emoji/emoji_one/abc.png b/public/images/emoji/emoji_one/abc.png index 3834df5f54e..92f600867dc 100644 Binary files a/public/images/emoji/emoji_one/abc.png and b/public/images/emoji/emoji_one/abc.png differ diff --git a/public/images/emoji/emoji_one/abcd.png b/public/images/emoji/emoji_one/abcd.png index 2af477d3b69..ef467755ecf 100644 Binary files a/public/images/emoji/emoji_one/abcd.png and b/public/images/emoji/emoji_one/abcd.png differ diff --git a/public/images/emoji/emoji_one/accept.png b/public/images/emoji/emoji_one/accept.png index 80ccc814ff5..2fe9b670aeb 100644 Binary files a/public/images/emoji/emoji_one/accept.png and b/public/images/emoji/emoji_one/accept.png differ diff --git a/public/images/emoji/emoji_one/aerial_tramway.png b/public/images/emoji/emoji_one/aerial_tramway.png index 01d277bda7d..fd2911254c7 100644 Binary files a/public/images/emoji/emoji_one/aerial_tramway.png and b/public/images/emoji/emoji_one/aerial_tramway.png differ diff --git a/public/images/emoji/emoji_one/airplane.png b/public/images/emoji/emoji_one/airplane.png index bf178671760..b9d82013ef3 100644 Binary files a/public/images/emoji/emoji_one/airplane.png and b/public/images/emoji/emoji_one/airplane.png differ diff --git a/public/images/emoji/emoji_one/airplane_arriving.png b/public/images/emoji/emoji_one/airplane_arriving.png new file mode 100644 index 00000000000..5358f5d98c3 Binary files /dev/null and b/public/images/emoji/emoji_one/airplane_arriving.png differ diff --git a/public/images/emoji/emoji_one/airplane_departure.png b/public/images/emoji/emoji_one/airplane_departure.png new file mode 100644 index 00000000000..94e455bf4e8 Binary files /dev/null and b/public/images/emoji/emoji_one/airplane_departure.png differ diff --git a/public/images/emoji/emoji_one/airplane_small.png b/public/images/emoji/emoji_one/airplane_small.png new file mode 100644 index 00000000000..2328135495b Binary files /dev/null and b/public/images/emoji/emoji_one/airplane_small.png differ diff --git a/public/images/emoji/emoji_one/alarm_clock.png b/public/images/emoji/emoji_one/alarm_clock.png index 3f466f3a7be..2ebfb044995 100644 Binary files a/public/images/emoji/emoji_one/alarm_clock.png and b/public/images/emoji/emoji_one/alarm_clock.png differ diff --git a/public/images/emoji/emoji_one/alembic.png b/public/images/emoji/emoji_one/alembic.png new file mode 100644 index 00000000000..82b4e962932 Binary files /dev/null and b/public/images/emoji/emoji_one/alembic.png differ diff --git a/public/images/emoji/emoji_one/alien.png b/public/images/emoji/emoji_one/alien.png index b3c1e4d4bfd..9270cdda2e5 100644 Binary files a/public/images/emoji/emoji_one/alien.png and b/public/images/emoji/emoji_one/alien.png differ diff --git a/public/images/emoji/emoji_one/ambulance.png b/public/images/emoji/emoji_one/ambulance.png index 9df138d9cda..725c8b152ba 100644 Binary files a/public/images/emoji/emoji_one/ambulance.png and b/public/images/emoji/emoji_one/ambulance.png differ diff --git a/public/images/emoji/emoji_one/amphora.png b/public/images/emoji/emoji_one/amphora.png new file mode 100644 index 00000000000..9e0b5a18f20 Binary files /dev/null and b/public/images/emoji/emoji_one/amphora.png differ diff --git a/public/images/emoji/emoji_one/anchor.png b/public/images/emoji/emoji_one/anchor.png index f2a8200f0fe..3c6f0ea5c75 100644 Binary files a/public/images/emoji/emoji_one/anchor.png and b/public/images/emoji/emoji_one/anchor.png differ diff --git a/public/images/emoji/emoji_one/angel.png b/public/images/emoji/emoji_one/angel.png index 9a56a9e84d7..f7c6715312e 100644 Binary files a/public/images/emoji/emoji_one/angel.png and b/public/images/emoji/emoji_one/angel.png differ diff --git a/public/images/emoji/emoji_one/anger.png b/public/images/emoji/emoji_one/anger.png index bf623d9fc98..ca8c3f4b0e1 100644 Binary files a/public/images/emoji/emoji_one/anger.png and b/public/images/emoji/emoji_one/anger.png differ diff --git a/public/images/emoji/emoji_one/anger_right.png b/public/images/emoji/emoji_one/anger_right.png new file mode 100644 index 00000000000..d711e6d31fc Binary files /dev/null and b/public/images/emoji/emoji_one/anger_right.png differ diff --git a/public/images/emoji/emoji_one/angry.png b/public/images/emoji/emoji_one/angry.png index a2e9201427b..b329d11fc59 100644 Binary files a/public/images/emoji/emoji_one/angry.png and b/public/images/emoji/emoji_one/angry.png differ diff --git a/public/images/emoji/emoji_one/anguished.png b/public/images/emoji/emoji_one/anguished.png index 08c558ef122..369f91828d7 100644 Binary files a/public/images/emoji/emoji_one/anguished.png and b/public/images/emoji/emoji_one/anguished.png differ diff --git a/public/images/emoji/emoji_one/ant.png b/public/images/emoji/emoji_one/ant.png index 1b6ba80c0e0..44c94ac1868 100644 Binary files a/public/images/emoji/emoji_one/ant.png and b/public/images/emoji/emoji_one/ant.png differ diff --git a/public/images/emoji/emoji_one/apple.png b/public/images/emoji/emoji_one/apple.png index bcc5c94aa20..4ed4679f32d 100644 Binary files a/public/images/emoji/emoji_one/apple.png and b/public/images/emoji/emoji_one/apple.png differ diff --git a/public/images/emoji/emoji_one/aquarius.png b/public/images/emoji/emoji_one/aquarius.png index d5d8380befa..68fed14e929 100644 Binary files a/public/images/emoji/emoji_one/aquarius.png and b/public/images/emoji/emoji_one/aquarius.png differ diff --git a/public/images/emoji/emoji_one/aries.png b/public/images/emoji/emoji_one/aries.png index 3c63b0102db..e9766d2d22f 100644 Binary files a/public/images/emoji/emoji_one/aries.png and b/public/images/emoji/emoji_one/aries.png differ diff --git a/public/images/emoji/emoji_one/arrow_backward.png b/public/images/emoji/emoji_one/arrow_backward.png index afd5f1076ce..2a3829cb962 100644 Binary files a/public/images/emoji/emoji_one/arrow_backward.png and b/public/images/emoji/emoji_one/arrow_backward.png differ diff --git a/public/images/emoji/emoji_one/arrow_double_down.png b/public/images/emoji/emoji_one/arrow_double_down.png index 5cc2a9faa29..3da228948f4 100644 Binary files a/public/images/emoji/emoji_one/arrow_double_down.png and b/public/images/emoji/emoji_one/arrow_double_down.png differ diff --git a/public/images/emoji/emoji_one/arrow_double_up.png b/public/images/emoji/emoji_one/arrow_double_up.png index 897f028d63b..f83a68982e5 100644 Binary files a/public/images/emoji/emoji_one/arrow_double_up.png and b/public/images/emoji/emoji_one/arrow_double_up.png differ diff --git a/public/images/emoji/emoji_one/arrow_down.png b/public/images/emoji/emoji_one/arrow_down.png index dc030c6327e..924cd40844c 100644 Binary files a/public/images/emoji/emoji_one/arrow_down.png and b/public/images/emoji/emoji_one/arrow_down.png differ diff --git a/public/images/emoji/emoji_one/arrow_down_small.png b/public/images/emoji/emoji_one/arrow_down_small.png index 98ebcb06e14..9b0c7dbe108 100644 Binary files a/public/images/emoji/emoji_one/arrow_down_small.png and b/public/images/emoji/emoji_one/arrow_down_small.png differ diff --git a/public/images/emoji/emoji_one/arrow_forward.png b/public/images/emoji/emoji_one/arrow_forward.png index 22a50786e17..d8b89ffcf5f 100644 Binary files a/public/images/emoji/emoji_one/arrow_forward.png and b/public/images/emoji/emoji_one/arrow_forward.png differ diff --git a/public/images/emoji/emoji_one/arrow_heading_down.png b/public/images/emoji/emoji_one/arrow_heading_down.png index bde867702f9..32e9a6eff97 100644 Binary files a/public/images/emoji/emoji_one/arrow_heading_down.png and b/public/images/emoji/emoji_one/arrow_heading_down.png differ diff --git a/public/images/emoji/emoji_one/arrow_heading_up.png b/public/images/emoji/emoji_one/arrow_heading_up.png index 11afe80d26d..af827aa6044 100644 Binary files a/public/images/emoji/emoji_one/arrow_heading_up.png and b/public/images/emoji/emoji_one/arrow_heading_up.png differ diff --git a/public/images/emoji/emoji_one/arrow_left.png b/public/images/emoji/emoji_one/arrow_left.png index 5213afc79c3..7a0da299a30 100644 Binary files a/public/images/emoji/emoji_one/arrow_left.png and b/public/images/emoji/emoji_one/arrow_left.png differ diff --git a/public/images/emoji/emoji_one/arrow_lower_left.png b/public/images/emoji/emoji_one/arrow_lower_left.png index 25db5d971c4..1436d03db21 100644 Binary files a/public/images/emoji/emoji_one/arrow_lower_left.png and b/public/images/emoji/emoji_one/arrow_lower_left.png differ diff --git a/public/images/emoji/emoji_one/arrow_lower_right.png b/public/images/emoji/emoji_one/arrow_lower_right.png index 2ff483fed86..c585c809758 100644 Binary files a/public/images/emoji/emoji_one/arrow_lower_right.png and b/public/images/emoji/emoji_one/arrow_lower_right.png differ diff --git a/public/images/emoji/emoji_one/arrow_right.png b/public/images/emoji/emoji_one/arrow_right.png index 6c5318defa4..ced227555e0 100644 Binary files a/public/images/emoji/emoji_one/arrow_right.png and b/public/images/emoji/emoji_one/arrow_right.png differ diff --git a/public/images/emoji/emoji_one/arrow_right_hook.png b/public/images/emoji/emoji_one/arrow_right_hook.png index ccf2a2183c7..bb802ebe9af 100644 Binary files a/public/images/emoji/emoji_one/arrow_right_hook.png and b/public/images/emoji/emoji_one/arrow_right_hook.png differ diff --git a/public/images/emoji/emoji_one/arrow_up.png b/public/images/emoji/emoji_one/arrow_up.png index 4220d45f1c4..73f7bee689e 100644 Binary files a/public/images/emoji/emoji_one/arrow_up.png and b/public/images/emoji/emoji_one/arrow_up.png differ diff --git a/public/images/emoji/emoji_one/arrow_up_down.png b/public/images/emoji/emoji_one/arrow_up_down.png index a420d6ed383..71ef3f30c27 100644 Binary files a/public/images/emoji/emoji_one/arrow_up_down.png and b/public/images/emoji/emoji_one/arrow_up_down.png differ diff --git a/public/images/emoji/emoji_one/arrow_up_small.png b/public/images/emoji/emoji_one/arrow_up_small.png index 37a768ed913..21fd9d4d52d 100644 Binary files a/public/images/emoji/emoji_one/arrow_up_small.png and b/public/images/emoji/emoji_one/arrow_up_small.png differ diff --git a/public/images/emoji/emoji_one/arrow_upper_left.png b/public/images/emoji/emoji_one/arrow_upper_left.png index 7425c8db1bd..461721d169c 100644 Binary files a/public/images/emoji/emoji_one/arrow_upper_left.png and b/public/images/emoji/emoji_one/arrow_upper_left.png differ diff --git a/public/images/emoji/emoji_one/arrow_upper_right.png b/public/images/emoji/emoji_one/arrow_upper_right.png index faccd5353e9..40263fbf522 100644 Binary files a/public/images/emoji/emoji_one/arrow_upper_right.png and b/public/images/emoji/emoji_one/arrow_upper_right.png differ diff --git a/public/images/emoji/emoji_one/arrows_clockwise.png b/public/images/emoji/emoji_one/arrows_clockwise.png index fe708aca101..89c079780cb 100644 Binary files a/public/images/emoji/emoji_one/arrows_clockwise.png and b/public/images/emoji/emoji_one/arrows_clockwise.png differ diff --git a/public/images/emoji/emoji_one/arrows_counterclockwise.png b/public/images/emoji/emoji_one/arrows_counterclockwise.png index f89672b4176..1dc0b9e3873 100644 Binary files a/public/images/emoji/emoji_one/arrows_counterclockwise.png and b/public/images/emoji/emoji_one/arrows_counterclockwise.png differ diff --git a/public/images/emoji/emoji_one/art.png b/public/images/emoji/emoji_one/art.png index a9499e692b4..ec44be614e8 100644 Binary files a/public/images/emoji/emoji_one/art.png and b/public/images/emoji/emoji_one/art.png differ diff --git a/public/images/emoji/emoji_one/articulated_lorry.png b/public/images/emoji/emoji_one/articulated_lorry.png index 4447dcfb52d..6ad5fa93cd1 100644 Binary files a/public/images/emoji/emoji_one/articulated_lorry.png and b/public/images/emoji/emoji_one/articulated_lorry.png differ diff --git a/public/images/emoji/emoji_one/astonished.png b/public/images/emoji/emoji_one/astonished.png index a1ffe4c28a4..f8a514aaa4e 100644 Binary files a/public/images/emoji/emoji_one/astonished.png and b/public/images/emoji/emoji_one/astonished.png differ diff --git a/public/images/emoji/emoji_one/athletic_shoe.png b/public/images/emoji/emoji_one/athletic_shoe.png index e2cd2d3d469..b95bd012db4 100644 Binary files a/public/images/emoji/emoji_one/athletic_shoe.png and b/public/images/emoji/emoji_one/athletic_shoe.png differ diff --git a/public/images/emoji/emoji_one/atm.png b/public/images/emoji/emoji_one/atm.png index 904fef4683d..76a8c9e0d13 100644 Binary files a/public/images/emoji/emoji_one/atm.png and b/public/images/emoji/emoji_one/atm.png differ diff --git a/public/images/emoji/emoji_one/atom.png b/public/images/emoji/emoji_one/atom.png new file mode 100644 index 00000000000..05ad819496e Binary files /dev/null and b/public/images/emoji/emoji_one/atom.png differ diff --git a/public/images/emoji/emoji_one/b.png b/public/images/emoji/emoji_one/b.png index 2b5bfa11aed..fe4d5542bc5 100644 Binary files a/public/images/emoji/emoji_one/b.png and b/public/images/emoji/emoji_one/b.png differ diff --git a/public/images/emoji/emoji_one/baby.png b/public/images/emoji/emoji_one/baby.png index 077d76dce96..e9a9869bfd4 100644 Binary files a/public/images/emoji/emoji_one/baby.png and b/public/images/emoji/emoji_one/baby.png differ diff --git a/public/images/emoji/emoji_one/baby_bottle.png b/public/images/emoji/emoji_one/baby_bottle.png index 64e9edee3f3..430b7f20457 100644 Binary files a/public/images/emoji/emoji_one/baby_bottle.png and b/public/images/emoji/emoji_one/baby_bottle.png differ diff --git a/public/images/emoji/emoji_one/baby_chick.png b/public/images/emoji/emoji_one/baby_chick.png index 66785c88016..471ddf1a585 100644 Binary files a/public/images/emoji/emoji_one/baby_chick.png and b/public/images/emoji/emoji_one/baby_chick.png differ diff --git a/public/images/emoji/emoji_one/baby_symbol.png b/public/images/emoji/emoji_one/baby_symbol.png index 7e9ea963003..5ff6cf75984 100644 Binary files a/public/images/emoji/emoji_one/baby_symbol.png and b/public/images/emoji/emoji_one/baby_symbol.png differ diff --git a/public/images/emoji/emoji_one/back.png b/public/images/emoji/emoji_one/back.png index ee67604c745..a75aca54a86 100644 Binary files a/public/images/emoji/emoji_one/back.png and b/public/images/emoji/emoji_one/back.png differ diff --git a/public/images/emoji/emoji_one/badminton.png b/public/images/emoji/emoji_one/badminton.png new file mode 100644 index 00000000000..19737e99bec Binary files /dev/null and b/public/images/emoji/emoji_one/badminton.png differ diff --git a/public/images/emoji/emoji_one/baggage_claim.png b/public/images/emoji/emoji_one/baggage_claim.png index a81efc8b84d..d700184b0da 100644 Binary files a/public/images/emoji/emoji_one/baggage_claim.png and b/public/images/emoji/emoji_one/baggage_claim.png differ diff --git a/public/images/emoji/emoji_one/balloon.png b/public/images/emoji/emoji_one/balloon.png index 3cea35eba45..1f4d56def91 100644 Binary files a/public/images/emoji/emoji_one/balloon.png and b/public/images/emoji/emoji_one/balloon.png differ diff --git a/public/images/emoji/emoji_one/ballot_box.png b/public/images/emoji/emoji_one/ballot_box.png new file mode 100644 index 00000000000..7effe6710e0 Binary files /dev/null and b/public/images/emoji/emoji_one/ballot_box.png differ diff --git a/public/images/emoji/emoji_one/ballot_box_with_check.png b/public/images/emoji/emoji_one/ballot_box_with_check.png index 3a3763f4923..1a15b3adc73 100644 Binary files a/public/images/emoji/emoji_one/ballot_box_with_check.png and b/public/images/emoji/emoji_one/ballot_box_with_check.png differ diff --git a/public/images/emoji/emoji_one/bamboo.png b/public/images/emoji/emoji_one/bamboo.png index a03cc8c4bf2..1ed3ae46312 100644 Binary files a/public/images/emoji/emoji_one/bamboo.png and b/public/images/emoji/emoji_one/bamboo.png differ diff --git a/public/images/emoji/emoji_one/banana.png b/public/images/emoji/emoji_one/banana.png index 5e68af7706f..cdb4378c59e 100644 Binary files a/public/images/emoji/emoji_one/banana.png and b/public/images/emoji/emoji_one/banana.png differ diff --git a/public/images/emoji/emoji_one/bangbang.png b/public/images/emoji/emoji_one/bangbang.png index 1fd0186af2d..3c7700d8323 100644 Binary files a/public/images/emoji/emoji_one/bangbang.png and b/public/images/emoji/emoji_one/bangbang.png differ diff --git a/public/images/emoji/emoji_one/bank.png b/public/images/emoji/emoji_one/bank.png index c324cc9696b..4747a6ccdf4 100644 Binary files a/public/images/emoji/emoji_one/bank.png and b/public/images/emoji/emoji_one/bank.png differ diff --git a/public/images/emoji/emoji_one/bar_chart.png b/public/images/emoji/emoji_one/bar_chart.png index 024b5c6e7a4..51dd829f63a 100644 Binary files a/public/images/emoji/emoji_one/bar_chart.png and b/public/images/emoji/emoji_one/bar_chart.png differ diff --git a/public/images/emoji/emoji_one/barber.png b/public/images/emoji/emoji_one/barber.png index e2267ff8f53..558e87b67ae 100644 Binary files a/public/images/emoji/emoji_one/barber.png and b/public/images/emoji/emoji_one/barber.png differ diff --git a/public/images/emoji/emoji_one/baseball.png b/public/images/emoji/emoji_one/baseball.png index f4c8cdea459..ba17e773367 100644 Binary files a/public/images/emoji/emoji_one/baseball.png and b/public/images/emoji/emoji_one/baseball.png differ diff --git a/public/images/emoji/emoji_one/basketball.png b/public/images/emoji/emoji_one/basketball.png index d0b5a7186c5..1b75608f27c 100644 Binary files a/public/images/emoji/emoji_one/basketball.png and b/public/images/emoji/emoji_one/basketball.png differ diff --git a/public/images/emoji/emoji_one/basketball_player.png b/public/images/emoji/emoji_one/basketball_player.png new file mode 100644 index 00000000000..19a60cb845f Binary files /dev/null and b/public/images/emoji/emoji_one/basketball_player.png differ diff --git a/public/images/emoji/emoji_one/bath.png b/public/images/emoji/emoji_one/bath.png index 49c81b5fcc0..afb45029f4b 100644 Binary files a/public/images/emoji/emoji_one/bath.png and b/public/images/emoji/emoji_one/bath.png differ diff --git a/public/images/emoji/emoji_one/bathtub.png b/public/images/emoji/emoji_one/bathtub.png index 86b2a262960..6ad83335611 100644 Binary files a/public/images/emoji/emoji_one/bathtub.png and b/public/images/emoji/emoji_one/bathtub.png differ diff --git a/public/images/emoji/emoji_one/battery.png b/public/images/emoji/emoji_one/battery.png index afbf11eef7b..04ddcc7dc30 100644 Binary files a/public/images/emoji/emoji_one/battery.png and b/public/images/emoji/emoji_one/battery.png differ diff --git a/public/images/emoji/emoji_one/beach.png b/public/images/emoji/emoji_one/beach.png new file mode 100644 index 00000000000..e4066df5d59 Binary files /dev/null and b/public/images/emoji/emoji_one/beach.png differ diff --git a/public/images/emoji/emoji_one/beach_umbrella.png b/public/images/emoji/emoji_one/beach_umbrella.png new file mode 100644 index 00000000000..f1f55d8ca9e Binary files /dev/null and b/public/images/emoji/emoji_one/beach_umbrella.png differ diff --git a/public/images/emoji/emoji_one/bear.png b/public/images/emoji/emoji_one/bear.png index 32387186f03..14da118345f 100644 Binary files a/public/images/emoji/emoji_one/bear.png and b/public/images/emoji/emoji_one/bear.png differ diff --git a/public/images/emoji/emoji_one/bed.png b/public/images/emoji/emoji_one/bed.png new file mode 100644 index 00000000000..3a859bbf93e Binary files /dev/null and b/public/images/emoji/emoji_one/bed.png differ diff --git a/public/images/emoji/emoji_one/bee.png b/public/images/emoji/emoji_one/bee.png index e67b7703bff..007b2052e2a 100644 Binary files a/public/images/emoji/emoji_one/bee.png and b/public/images/emoji/emoji_one/bee.png differ diff --git a/public/images/emoji/emoji_one/beer.png b/public/images/emoji/emoji_one/beer.png index de0c3ddd9d2..1fcc98fbfd2 100644 Binary files a/public/images/emoji/emoji_one/beer.png and b/public/images/emoji/emoji_one/beer.png differ diff --git a/public/images/emoji/emoji_one/beers.png b/public/images/emoji/emoji_one/beers.png index 04ba4d9f463..23615303685 100644 Binary files a/public/images/emoji/emoji_one/beers.png and b/public/images/emoji/emoji_one/beers.png differ diff --git a/public/images/emoji/emoji_one/beetle.png b/public/images/emoji/emoji_one/beetle.png index c35380926e6..1864cccd0ac 100644 Binary files a/public/images/emoji/emoji_one/beetle.png and b/public/images/emoji/emoji_one/beetle.png differ diff --git a/public/images/emoji/emoji_one/beginner.png b/public/images/emoji/emoji_one/beginner.png index 1d9cb259b18..136e60380ef 100644 Binary files a/public/images/emoji/emoji_one/beginner.png and b/public/images/emoji/emoji_one/beginner.png differ diff --git a/public/images/emoji/emoji_one/bell.png b/public/images/emoji/emoji_one/bell.png index d1473557ea2..9dcb8aa34f5 100644 Binary files a/public/images/emoji/emoji_one/bell.png and b/public/images/emoji/emoji_one/bell.png differ diff --git a/public/images/emoji/emoji_one/bellhop.png b/public/images/emoji/emoji_one/bellhop.png new file mode 100644 index 00000000000..fc7301104cb Binary files /dev/null and b/public/images/emoji/emoji_one/bellhop.png differ diff --git a/public/images/emoji/emoji_one/bento.png b/public/images/emoji/emoji_one/bento.png index c129f412226..e605ead1121 100644 Binary files a/public/images/emoji/emoji_one/bento.png and b/public/images/emoji/emoji_one/bento.png differ diff --git a/public/images/emoji/emoji_one/bicyclist.png b/public/images/emoji/emoji_one/bicyclist.png index 6f96b2c4396..9fa26f2d215 100644 Binary files a/public/images/emoji/emoji_one/bicyclist.png and b/public/images/emoji/emoji_one/bicyclist.png differ diff --git a/public/images/emoji/emoji_one/bike.png b/public/images/emoji/emoji_one/bike.png index a37d6020720..ec27b50734f 100644 Binary files a/public/images/emoji/emoji_one/bike.png and b/public/images/emoji/emoji_one/bike.png differ diff --git a/public/images/emoji/emoji_one/bikini.png b/public/images/emoji/emoji_one/bikini.png index 62d142f311d..17c0ec334bf 100644 Binary files a/public/images/emoji/emoji_one/bikini.png and b/public/images/emoji/emoji_one/bikini.png differ diff --git a/public/images/emoji/emoji_one/biohazard.png b/public/images/emoji/emoji_one/biohazard.png new file mode 100644 index 00000000000..9c3e4e989e4 Binary files /dev/null and b/public/images/emoji/emoji_one/biohazard.png differ diff --git a/public/images/emoji/emoji_one/bird.png b/public/images/emoji/emoji_one/bird.png index 077178a421f..78da88af959 100644 Binary files a/public/images/emoji/emoji_one/bird.png and b/public/images/emoji/emoji_one/bird.png differ diff --git a/public/images/emoji/emoji_one/birthday.png b/public/images/emoji/emoji_one/birthday.png index c5253b09985..491b0988f4a 100644 Binary files a/public/images/emoji/emoji_one/birthday.png and b/public/images/emoji/emoji_one/birthday.png differ diff --git a/public/images/emoji/emoji_one/black_circle.png b/public/images/emoji/emoji_one/black_circle.png index f1cd7189b56..97f36b32248 100644 Binary files a/public/images/emoji/emoji_one/black_circle.png and b/public/images/emoji/emoji_one/black_circle.png differ diff --git a/public/images/emoji/emoji_one/black_joker.png b/public/images/emoji/emoji_one/black_joker.png index 5c770fb2787..f986d67a8fe 100644 Binary files a/public/images/emoji/emoji_one/black_joker.png and b/public/images/emoji/emoji_one/black_joker.png differ diff --git a/public/images/emoji/emoji_one/black_large_square.png b/public/images/emoji/emoji_one/black_large_square.png index 1fcdd9e75af..04947c7be6b 100644 Binary files a/public/images/emoji/emoji_one/black_large_square.png and b/public/images/emoji/emoji_one/black_large_square.png differ diff --git a/public/images/emoji/emoji_one/black_medium_small_square.png b/public/images/emoji/emoji_one/black_medium_small_square.png index 34035f92e19..83ff53fab38 100644 Binary files a/public/images/emoji/emoji_one/black_medium_small_square.png and b/public/images/emoji/emoji_one/black_medium_small_square.png differ diff --git a/public/images/emoji/emoji_one/black_medium_square.png b/public/images/emoji/emoji_one/black_medium_square.png index 41686da1347..769f50f6380 100644 Binary files a/public/images/emoji/emoji_one/black_medium_square.png and b/public/images/emoji/emoji_one/black_medium_square.png differ diff --git a/public/images/emoji/emoji_one/black_nib.png b/public/images/emoji/emoji_one/black_nib.png index 6f1a76cde5c..7fe40ba430b 100644 Binary files a/public/images/emoji/emoji_one/black_nib.png and b/public/images/emoji/emoji_one/black_nib.png differ diff --git a/public/images/emoji/emoji_one/black_small_square.png b/public/images/emoji/emoji_one/black_small_square.png index 1c5a354d56e..918cb53ed34 100644 Binary files a/public/images/emoji/emoji_one/black_small_square.png and b/public/images/emoji/emoji_one/black_small_square.png differ diff --git a/public/images/emoji/emoji_one/black_square_button.png b/public/images/emoji/emoji_one/black_square_button.png index dfad369f531..a3099d0e2de 100644 Binary files a/public/images/emoji/emoji_one/black_square_button.png and b/public/images/emoji/emoji_one/black_square_button.png differ diff --git a/public/images/emoji/emoji_one/blossom.png b/public/images/emoji/emoji_one/blossom.png index ffc25f25237..45d1d29d103 100644 Binary files a/public/images/emoji/emoji_one/blossom.png and b/public/images/emoji/emoji_one/blossom.png differ diff --git a/public/images/emoji/emoji_one/blowfish.png b/public/images/emoji/emoji_one/blowfish.png index 7529feff75c..d6af8a9e30b 100644 Binary files a/public/images/emoji/emoji_one/blowfish.png and b/public/images/emoji/emoji_one/blowfish.png differ diff --git a/public/images/emoji/emoji_one/blue_book.png b/public/images/emoji/emoji_one/blue_book.png index bf13d1cd619..d1925bb8553 100644 Binary files a/public/images/emoji/emoji_one/blue_book.png and b/public/images/emoji/emoji_one/blue_book.png differ diff --git a/public/images/emoji/emoji_one/blue_car.png b/public/images/emoji/emoji_one/blue_car.png index 0c2e833fffb..7fdb6df1e2b 100644 Binary files a/public/images/emoji/emoji_one/blue_car.png and b/public/images/emoji/emoji_one/blue_car.png differ diff --git a/public/images/emoji/emoji_one/blue_heart.png b/public/images/emoji/emoji_one/blue_heart.png index 697819a8100..851f3086942 100644 Binary files a/public/images/emoji/emoji_one/blue_heart.png and b/public/images/emoji/emoji_one/blue_heart.png differ diff --git a/public/images/emoji/emoji_one/blush.png b/public/images/emoji/emoji_one/blush.png index 5aecc2948c7..93a0d325089 100644 Binary files a/public/images/emoji/emoji_one/blush.png and b/public/images/emoji/emoji_one/blush.png differ diff --git a/public/images/emoji/emoji_one/boar.png b/public/images/emoji/emoji_one/boar.png index 2ccb92fd157..6bb68f1a220 100644 Binary files a/public/images/emoji/emoji_one/boar.png and b/public/images/emoji/emoji_one/boar.png differ diff --git a/public/images/emoji/emoji_one/boat.png b/public/images/emoji/emoji_one/boat.png index 9e862f831f6..f50e3fb1ae6 100644 Binary files a/public/images/emoji/emoji_one/boat.png and b/public/images/emoji/emoji_one/boat.png differ diff --git a/public/images/emoji/emoji_one/bomb.png b/public/images/emoji/emoji_one/bomb.png index 774c5c91e04..09836f942b7 100644 Binary files a/public/images/emoji/emoji_one/bomb.png and b/public/images/emoji/emoji_one/bomb.png differ diff --git a/public/images/emoji/emoji_one/book.png b/public/images/emoji/emoji_one/book.png index 158ba4965d9..7c64a5ab9b2 100644 Binary files a/public/images/emoji/emoji_one/book.png and b/public/images/emoji/emoji_one/book.png differ diff --git a/public/images/emoji/emoji_one/bookmark.png b/public/images/emoji/emoji_one/bookmark.png index 5ccb5ed0bef..6cd022d95c9 100644 Binary files a/public/images/emoji/emoji_one/bookmark.png and b/public/images/emoji/emoji_one/bookmark.png differ diff --git a/public/images/emoji/emoji_one/bookmark_tabs.png b/public/images/emoji/emoji_one/bookmark_tabs.png index b6532cda520..f16d455c6fa 100644 Binary files a/public/images/emoji/emoji_one/bookmark_tabs.png and b/public/images/emoji/emoji_one/bookmark_tabs.png differ diff --git a/public/images/emoji/emoji_one/books.png b/public/images/emoji/emoji_one/books.png index f69bfad763a..89137e10d27 100644 Binary files a/public/images/emoji/emoji_one/books.png and b/public/images/emoji/emoji_one/books.png differ diff --git a/public/images/emoji/emoji_one/boom.png b/public/images/emoji/emoji_one/boom.png index 4480b19814c..c738cf5ec83 100644 Binary files a/public/images/emoji/emoji_one/boom.png and b/public/images/emoji/emoji_one/boom.png differ diff --git a/public/images/emoji/emoji_one/boot.png b/public/images/emoji/emoji_one/boot.png index 856256d5be0..aab63052fa2 100644 Binary files a/public/images/emoji/emoji_one/boot.png and b/public/images/emoji/emoji_one/boot.png differ diff --git a/public/images/emoji/emoji_one/bouquet.png b/public/images/emoji/emoji_one/bouquet.png index e42118f7ff1..30e00773e84 100644 Binary files a/public/images/emoji/emoji_one/bouquet.png and b/public/images/emoji/emoji_one/bouquet.png differ diff --git a/public/images/emoji/emoji_one/bow.png b/public/images/emoji/emoji_one/bow.png index 1674427e90c..46d91754aa3 100644 Binary files a/public/images/emoji/emoji_one/bow.png and b/public/images/emoji/emoji_one/bow.png differ diff --git a/public/images/emoji/emoji_one/bow_and_arrow.png b/public/images/emoji/emoji_one/bow_and_arrow.png new file mode 100644 index 00000000000..6a8fa6984e4 Binary files /dev/null and b/public/images/emoji/emoji_one/bow_and_arrow.png differ diff --git a/public/images/emoji/emoji_one/bowling.png b/public/images/emoji/emoji_one/bowling.png index e41edfbdbe6..a060f86cb85 100644 Binary files a/public/images/emoji/emoji_one/bowling.png and b/public/images/emoji/emoji_one/bowling.png differ diff --git a/public/images/emoji/emoji_one/boy.png b/public/images/emoji/emoji_one/boy.png index 0bc48972209..340a74562e7 100644 Binary files a/public/images/emoji/emoji_one/boy.png and b/public/images/emoji/emoji_one/boy.png differ diff --git a/public/images/emoji/emoji_one/bread.png b/public/images/emoji/emoji_one/bread.png index 3ca73ebc788..2e272574073 100644 Binary files a/public/images/emoji/emoji_one/bread.png and b/public/images/emoji/emoji_one/bread.png differ diff --git a/public/images/emoji/emoji_one/bride_with_veil.png b/public/images/emoji/emoji_one/bride_with_veil.png index 9ec5867e10a..e922f7c4775 100644 Binary files a/public/images/emoji/emoji_one/bride_with_veil.png and b/public/images/emoji/emoji_one/bride_with_veil.png differ diff --git a/public/images/emoji/emoji_one/bridge_at_night.png b/public/images/emoji/emoji_one/bridge_at_night.png index 32d4a53c7da..69e0cf446a5 100644 Binary files a/public/images/emoji/emoji_one/bridge_at_night.png and b/public/images/emoji/emoji_one/bridge_at_night.png differ diff --git a/public/images/emoji/emoji_one/briefcase.png b/public/images/emoji/emoji_one/briefcase.png index a7df5ea5aaa..a423b57c4fa 100644 Binary files a/public/images/emoji/emoji_one/briefcase.png and b/public/images/emoji/emoji_one/briefcase.png differ diff --git a/public/images/emoji/emoji_one/broken_heart.png b/public/images/emoji/emoji_one/broken_heart.png index f24c2b08897..6c5677c89bd 100644 Binary files a/public/images/emoji/emoji_one/broken_heart.png and b/public/images/emoji/emoji_one/broken_heart.png differ diff --git a/public/images/emoji/emoji_one/bug.png b/public/images/emoji/emoji_one/bug.png index 06b35cf5a85..73fa8868a9a 100644 Binary files a/public/images/emoji/emoji_one/bug.png and b/public/images/emoji/emoji_one/bug.png differ diff --git a/public/images/emoji/emoji_one/bulb.png b/public/images/emoji/emoji_one/bulb.png index 7596c82a707..2c32c9cf66a 100644 Binary files a/public/images/emoji/emoji_one/bulb.png and b/public/images/emoji/emoji_one/bulb.png differ diff --git a/public/images/emoji/emoji_one/bullettrain_front.png b/public/images/emoji/emoji_one/bullettrain_front.png index 4d35e5e4bea..f70a90300fb 100644 Binary files a/public/images/emoji/emoji_one/bullettrain_front.png and b/public/images/emoji/emoji_one/bullettrain_front.png differ diff --git a/public/images/emoji/emoji_one/bullettrain_side.png b/public/images/emoji/emoji_one/bullettrain_side.png index af64d86f055..3c7ea78627f 100644 Binary files a/public/images/emoji/emoji_one/bullettrain_side.png and b/public/images/emoji/emoji_one/bullettrain_side.png differ diff --git a/public/images/emoji/emoji_one/burrito.png b/public/images/emoji/emoji_one/burrito.png new file mode 100644 index 00000000000..ec7bd0cd2a4 Binary files /dev/null and b/public/images/emoji/emoji_one/burrito.png differ diff --git a/public/images/emoji/emoji_one/bus.png b/public/images/emoji/emoji_one/bus.png index 1457a84df37..1d0c5f6ae97 100644 Binary files a/public/images/emoji/emoji_one/bus.png and b/public/images/emoji/emoji_one/bus.png differ diff --git a/public/images/emoji/emoji_one/busstop.png b/public/images/emoji/emoji_one/busstop.png index 3e14a30b689..07d40c3ec31 100644 Binary files a/public/images/emoji/emoji_one/busstop.png and b/public/images/emoji/emoji_one/busstop.png differ diff --git a/public/images/emoji/emoji_one/bust_in_silhouette.png b/public/images/emoji/emoji_one/bust_in_silhouette.png index 6398291cbb5..4acdcee1fe7 100644 Binary files a/public/images/emoji/emoji_one/bust_in_silhouette.png and b/public/images/emoji/emoji_one/bust_in_silhouette.png differ diff --git a/public/images/emoji/emoji_one/busts_in_silhouette.png b/public/images/emoji/emoji_one/busts_in_silhouette.png index 24751b2e23f..3841d70dead 100644 Binary files a/public/images/emoji/emoji_one/busts_in_silhouette.png and b/public/images/emoji/emoji_one/busts_in_silhouette.png differ diff --git a/public/images/emoji/emoji_one/cactus.png b/public/images/emoji/emoji_one/cactus.png index 0204fd3436d..78bf7711387 100644 Binary files a/public/images/emoji/emoji_one/cactus.png and b/public/images/emoji/emoji_one/cactus.png differ diff --git a/public/images/emoji/emoji_one/cake.png b/public/images/emoji/emoji_one/cake.png index 0be915e5bdb..2ef7d701d8a 100644 Binary files a/public/images/emoji/emoji_one/cake.png and b/public/images/emoji/emoji_one/cake.png differ diff --git a/public/images/emoji/emoji_one/calendar.png b/public/images/emoji/emoji_one/calendar.png index 2f0fb41c4da..a2cc2338e3e 100644 Binary files a/public/images/emoji/emoji_one/calendar.png and b/public/images/emoji/emoji_one/calendar.png differ diff --git a/public/images/emoji/emoji_one/calendar_spiral.png b/public/images/emoji/emoji_one/calendar_spiral.png new file mode 100644 index 00000000000..d9c5f699d26 Binary files /dev/null and b/public/images/emoji/emoji_one/calendar_spiral.png differ diff --git a/public/images/emoji/emoji_one/calling.png b/public/images/emoji/emoji_one/calling.png index 5544405c10b..0715d2c0807 100644 Binary files a/public/images/emoji/emoji_one/calling.png and b/public/images/emoji/emoji_one/calling.png differ diff --git a/public/images/emoji/emoji_one/camel.png b/public/images/emoji/emoji_one/camel.png index f332bf33353..1a9b601ca8a 100644 Binary files a/public/images/emoji/emoji_one/camel.png and b/public/images/emoji/emoji_one/camel.png differ diff --git a/public/images/emoji/emoji_one/camera.png b/public/images/emoji/emoji_one/camera.png index 7f8c588baf4..f3f6f129602 100644 Binary files a/public/images/emoji/emoji_one/camera.png and b/public/images/emoji/emoji_one/camera.png differ diff --git a/public/images/emoji/emoji_one/camera_with_flash.png b/public/images/emoji/emoji_one/camera_with_flash.png new file mode 100644 index 00000000000..6ea04f77195 Binary files /dev/null and b/public/images/emoji/emoji_one/camera_with_flash.png differ diff --git a/public/images/emoji/emoji_one/camping.png b/public/images/emoji/emoji_one/camping.png new file mode 100644 index 00000000000..943c8fc7d08 Binary files /dev/null and b/public/images/emoji/emoji_one/camping.png differ diff --git a/public/images/emoji/emoji_one/cancer.png b/public/images/emoji/emoji_one/cancer.png index 6e6d2ca75a6..3b862a904b3 100644 Binary files a/public/images/emoji/emoji_one/cancer.png and b/public/images/emoji/emoji_one/cancer.png differ diff --git a/public/images/emoji/emoji_one/candle.png b/public/images/emoji/emoji_one/candle.png new file mode 100644 index 00000000000..11bc7387012 Binary files /dev/null and b/public/images/emoji/emoji_one/candle.png differ diff --git a/public/images/emoji/emoji_one/candy.png b/public/images/emoji/emoji_one/candy.png index c067807c110..a6b5569b27c 100644 Binary files a/public/images/emoji/emoji_one/candy.png and b/public/images/emoji/emoji_one/candy.png differ diff --git a/public/images/emoji/emoji_one/capital_abcd.png b/public/images/emoji/emoji_one/capital_abcd.png index 53243beb338..9a02ad284c0 100644 Binary files a/public/images/emoji/emoji_one/capital_abcd.png and b/public/images/emoji/emoji_one/capital_abcd.png differ diff --git a/public/images/emoji/emoji_one/capricorn.png b/public/images/emoji/emoji_one/capricorn.png index a814e7f8434..be3deea197d 100644 Binary files a/public/images/emoji/emoji_one/capricorn.png and b/public/images/emoji/emoji_one/capricorn.png differ diff --git a/public/images/emoji/emoji_one/car.png b/public/images/emoji/emoji_one/car.png index e266bd21e5b..639a6c6bbae 100644 Binary files a/public/images/emoji/emoji_one/car.png and b/public/images/emoji/emoji_one/car.png differ diff --git a/public/images/emoji/emoji_one/card_box.png b/public/images/emoji/emoji_one/card_box.png new file mode 100644 index 00000000000..3fd527452d4 Binary files /dev/null and b/public/images/emoji/emoji_one/card_box.png differ diff --git a/public/images/emoji/emoji_one/card_index.png b/public/images/emoji/emoji_one/card_index.png index daafd9917f6..2d2fc9295f9 100644 Binary files a/public/images/emoji/emoji_one/card_index.png and b/public/images/emoji/emoji_one/card_index.png differ diff --git a/public/images/emoji/emoji_one/carousel_horse.png b/public/images/emoji/emoji_one/carousel_horse.png index 9c735112aae..a65e6cfa469 100644 Binary files a/public/images/emoji/emoji_one/carousel_horse.png and b/public/images/emoji/emoji_one/carousel_horse.png differ diff --git a/public/images/emoji/emoji_one/cat.png b/public/images/emoji/emoji_one/cat.png index 126d2ef79d3..868ac29ea0c 100644 Binary files a/public/images/emoji/emoji_one/cat.png and b/public/images/emoji/emoji_one/cat.png differ diff --git a/public/images/emoji/emoji_one/cat2.png b/public/images/emoji/emoji_one/cat2.png index 79f06af4838..27bd4c8d5da 100644 Binary files a/public/images/emoji/emoji_one/cat2.png and b/public/images/emoji/emoji_one/cat2.png differ diff --git a/public/images/emoji/emoji_one/cd.png b/public/images/emoji/emoji_one/cd.png index 2998423964c..fe1f36eec84 100644 Binary files a/public/images/emoji/emoji_one/cd.png and b/public/images/emoji/emoji_one/cd.png differ diff --git a/public/images/emoji/emoji_one/chains.png b/public/images/emoji/emoji_one/chains.png new file mode 100644 index 00000000000..d743480f982 Binary files /dev/null and b/public/images/emoji/emoji_one/chains.png differ diff --git a/public/images/emoji/emoji_one/champagne.png b/public/images/emoji/emoji_one/champagne.png new file mode 100644 index 00000000000..56e394220c4 Binary files /dev/null and b/public/images/emoji/emoji_one/champagne.png differ diff --git a/public/images/emoji/emoji_one/chart.png b/public/images/emoji/emoji_one/chart.png index 4a31138f55a..801d8ba4a1f 100644 Binary files a/public/images/emoji/emoji_one/chart.png and b/public/images/emoji/emoji_one/chart.png differ diff --git a/public/images/emoji/emoji_one/chart_with_downwards_trend.png b/public/images/emoji/emoji_one/chart_with_downwards_trend.png index 2c1d69e7c39..6af7067ea5f 100644 Binary files a/public/images/emoji/emoji_one/chart_with_downwards_trend.png and b/public/images/emoji/emoji_one/chart_with_downwards_trend.png differ diff --git a/public/images/emoji/emoji_one/chart_with_upwards_trend.png b/public/images/emoji/emoji_one/chart_with_upwards_trend.png index 20293a17cb7..eb01ae6f540 100644 Binary files a/public/images/emoji/emoji_one/chart_with_upwards_trend.png and b/public/images/emoji/emoji_one/chart_with_upwards_trend.png differ diff --git a/public/images/emoji/emoji_one/checkered_flag.png b/public/images/emoji/emoji_one/checkered_flag.png index 9f1d564f66b..4103c292a8f 100644 Binary files a/public/images/emoji/emoji_one/checkered_flag.png and b/public/images/emoji/emoji_one/checkered_flag.png differ diff --git a/public/images/emoji/emoji_one/cheese.png b/public/images/emoji/emoji_one/cheese.png new file mode 100644 index 00000000000..a9ed4b2e0d8 Binary files /dev/null and b/public/images/emoji/emoji_one/cheese.png differ diff --git a/public/images/emoji/emoji_one/cherries.png b/public/images/emoji/emoji_one/cherries.png index 982292e959e..3629422cba2 100644 Binary files a/public/images/emoji/emoji_one/cherries.png and b/public/images/emoji/emoji_one/cherries.png differ diff --git a/public/images/emoji/emoji_one/cherry_blossom.png b/public/images/emoji/emoji_one/cherry_blossom.png index 7cd8a22e78a..347f375ae3a 100644 Binary files a/public/images/emoji/emoji_one/cherry_blossom.png and b/public/images/emoji/emoji_one/cherry_blossom.png differ diff --git a/public/images/emoji/emoji_one/chestnut.png b/public/images/emoji/emoji_one/chestnut.png index e8503615103..ae2e9e145f7 100644 Binary files a/public/images/emoji/emoji_one/chestnut.png and b/public/images/emoji/emoji_one/chestnut.png differ diff --git a/public/images/emoji/emoji_one/chicken.png b/public/images/emoji/emoji_one/chicken.png index 182ffb343f4..507295f5a12 100644 Binary files a/public/images/emoji/emoji_one/chicken.png and b/public/images/emoji/emoji_one/chicken.png differ diff --git a/public/images/emoji/emoji_one/children_crossing.png b/public/images/emoji/emoji_one/children_crossing.png index 4bc75ab7bdc..415550d9ae7 100644 Binary files a/public/images/emoji/emoji_one/children_crossing.png and b/public/images/emoji/emoji_one/children_crossing.png differ diff --git a/public/images/emoji/emoji_one/chipmunk.png b/public/images/emoji/emoji_one/chipmunk.png new file mode 100644 index 00000000000..3c809f36a06 Binary files /dev/null and b/public/images/emoji/emoji_one/chipmunk.png differ diff --git a/public/images/emoji/emoji_one/chocolate_bar.png b/public/images/emoji/emoji_one/chocolate_bar.png index f76d0902ed6..654b29a5cf8 100644 Binary files a/public/images/emoji/emoji_one/chocolate_bar.png and b/public/images/emoji/emoji_one/chocolate_bar.png differ diff --git a/public/images/emoji/emoji_one/christmas_tree.png b/public/images/emoji/emoji_one/christmas_tree.png index da5fdf85a30..816148741c5 100644 Binary files a/public/images/emoji/emoji_one/christmas_tree.png and b/public/images/emoji/emoji_one/christmas_tree.png differ diff --git a/public/images/emoji/emoji_one/church.png b/public/images/emoji/emoji_one/church.png index e1f25e25a7a..a4745af2d12 100644 Binary files a/public/images/emoji/emoji_one/church.png and b/public/images/emoji/emoji_one/church.png differ diff --git a/public/images/emoji/emoji_one/cinema.png b/public/images/emoji/emoji_one/cinema.png index 768f1991abb..77a4cf5ee7c 100644 Binary files a/public/images/emoji/emoji_one/cinema.png and b/public/images/emoji/emoji_one/cinema.png differ diff --git a/public/images/emoji/emoji_one/circus_tent.png b/public/images/emoji/emoji_one/circus_tent.png index 713b4f085de..56af495b026 100644 Binary files a/public/images/emoji/emoji_one/circus_tent.png and b/public/images/emoji/emoji_one/circus_tent.png differ diff --git a/public/images/emoji/emoji_one/city_dusk.png b/public/images/emoji/emoji_one/city_dusk.png new file mode 100644 index 00000000000..27ef7c850de Binary files /dev/null and b/public/images/emoji/emoji_one/city_dusk.png differ diff --git a/public/images/emoji/emoji_one/city_sunrise.png b/public/images/emoji/emoji_one/city_sunrise.png index 1e05afbb2fd..5ef52c29b76 100644 Binary files a/public/images/emoji/emoji_one/city_sunrise.png and b/public/images/emoji/emoji_one/city_sunrise.png differ diff --git a/public/images/emoji/emoji_one/city_sunset.png b/public/images/emoji/emoji_one/city_sunset.png index ed0694d4420..3c799226c85 100644 Binary files a/public/images/emoji/emoji_one/city_sunset.png and b/public/images/emoji/emoji_one/city_sunset.png differ diff --git a/public/images/emoji/emoji_one/cityscape.png b/public/images/emoji/emoji_one/cityscape.png new file mode 100644 index 00000000000..f5e3089acb3 Binary files /dev/null and b/public/images/emoji/emoji_one/cityscape.png differ diff --git a/public/images/emoji/emoji_one/cl.png b/public/images/emoji/emoji_one/cl.png index cf6682ee4b6..4787e710063 100644 Binary files a/public/images/emoji/emoji_one/cl.png and b/public/images/emoji/emoji_one/cl.png differ diff --git a/public/images/emoji/emoji_one/clap.png b/public/images/emoji/emoji_one/clap.png index ccb725e96cd..3921c685f87 100644 Binary files a/public/images/emoji/emoji_one/clap.png and b/public/images/emoji/emoji_one/clap.png differ diff --git a/public/images/emoji/emoji_one/clapper.png b/public/images/emoji/emoji_one/clapper.png index 54bbba8098b..5e917dac425 100644 Binary files a/public/images/emoji/emoji_one/clapper.png and b/public/images/emoji/emoji_one/clapper.png differ diff --git a/public/images/emoji/emoji_one/classical_building.png b/public/images/emoji/emoji_one/classical_building.png new file mode 100644 index 00000000000..1950bec0355 Binary files /dev/null and b/public/images/emoji/emoji_one/classical_building.png differ diff --git a/public/images/emoji/emoji_one/clipboard.png b/public/images/emoji/emoji_one/clipboard.png index 6120c84dc61..8075c04a4be 100644 Binary files a/public/images/emoji/emoji_one/clipboard.png and b/public/images/emoji/emoji_one/clipboard.png differ diff --git a/public/images/emoji/emoji_one/clock.png b/public/images/emoji/emoji_one/clock.png new file mode 100644 index 00000000000..a65722fd413 Binary files /dev/null and b/public/images/emoji/emoji_one/clock.png differ diff --git a/public/images/emoji/emoji_one/clock1.png b/public/images/emoji/emoji_one/clock1.png index 520c461e9e8..c3f631dc81e 100644 Binary files a/public/images/emoji/emoji_one/clock1.png and b/public/images/emoji/emoji_one/clock1.png differ diff --git a/public/images/emoji/emoji_one/clock10.png b/public/images/emoji/emoji_one/clock10.png index 895ab567566..5cbe32fe19e 100644 Binary files a/public/images/emoji/emoji_one/clock10.png and b/public/images/emoji/emoji_one/clock10.png differ diff --git a/public/images/emoji/emoji_one/clock1030.png b/public/images/emoji/emoji_one/clock1030.png index 0e4c55319e7..9e1bc285df9 100644 Binary files a/public/images/emoji/emoji_one/clock1030.png and b/public/images/emoji/emoji_one/clock1030.png differ diff --git a/public/images/emoji/emoji_one/clock11.png b/public/images/emoji/emoji_one/clock11.png index 692c60bf4f4..b54118a31f8 100644 Binary files a/public/images/emoji/emoji_one/clock11.png and b/public/images/emoji/emoji_one/clock11.png differ diff --git a/public/images/emoji/emoji_one/clock1130.png b/public/images/emoji/emoji_one/clock1130.png index 8ae2bb3632d..d1ab951dfd7 100644 Binary files a/public/images/emoji/emoji_one/clock1130.png and b/public/images/emoji/emoji_one/clock1130.png differ diff --git a/public/images/emoji/emoji_one/clock12.png b/public/images/emoji/emoji_one/clock12.png index 45407cede54..f28bd74a29f 100644 Binary files a/public/images/emoji/emoji_one/clock12.png and b/public/images/emoji/emoji_one/clock12.png differ diff --git a/public/images/emoji/emoji_one/clock1230.png b/public/images/emoji/emoji_one/clock1230.png index fce2ad61953..ce9028a2372 100644 Binary files a/public/images/emoji/emoji_one/clock1230.png and b/public/images/emoji/emoji_one/clock1230.png differ diff --git a/public/images/emoji/emoji_one/clock130.png b/public/images/emoji/emoji_one/clock130.png index d0ae7cb16c2..ccac49b0d9a 100644 Binary files a/public/images/emoji/emoji_one/clock130.png and b/public/images/emoji/emoji_one/clock130.png differ diff --git a/public/images/emoji/emoji_one/clock2.png b/public/images/emoji/emoji_one/clock2.png index e8f5884edcf..6d27a7e6db0 100644 Binary files a/public/images/emoji/emoji_one/clock2.png and b/public/images/emoji/emoji_one/clock2.png differ diff --git a/public/images/emoji/emoji_one/clock230.png b/public/images/emoji/emoji_one/clock230.png index 05217180aee..b95b3aec0e7 100644 Binary files a/public/images/emoji/emoji_one/clock230.png and b/public/images/emoji/emoji_one/clock230.png differ diff --git a/public/images/emoji/emoji_one/clock3.png b/public/images/emoji/emoji_one/clock3.png index a124fedefcf..faf5aa6682f 100644 Binary files a/public/images/emoji/emoji_one/clock3.png and b/public/images/emoji/emoji_one/clock3.png differ diff --git a/public/images/emoji/emoji_one/clock330.png b/public/images/emoji/emoji_one/clock330.png index 50a9a6cc0d3..bf43ffbea2e 100644 Binary files a/public/images/emoji/emoji_one/clock330.png and b/public/images/emoji/emoji_one/clock330.png differ diff --git a/public/images/emoji/emoji_one/clock4.png b/public/images/emoji/emoji_one/clock4.png index 59d5af5291f..f7f7474bdba 100644 Binary files a/public/images/emoji/emoji_one/clock4.png and b/public/images/emoji/emoji_one/clock4.png differ diff --git a/public/images/emoji/emoji_one/clock430.png b/public/images/emoji/emoji_one/clock430.png index 904266c85b8..b83b76f86b3 100644 Binary files a/public/images/emoji/emoji_one/clock430.png and b/public/images/emoji/emoji_one/clock430.png differ diff --git a/public/images/emoji/emoji_one/clock5.png b/public/images/emoji/emoji_one/clock5.png index dea07610e34..6fe3fad2ec1 100644 Binary files a/public/images/emoji/emoji_one/clock5.png and b/public/images/emoji/emoji_one/clock5.png differ diff --git a/public/images/emoji/emoji_one/clock530.png b/public/images/emoji/emoji_one/clock530.png index a278a9fb0b5..3a7f14d379f 100644 Binary files a/public/images/emoji/emoji_one/clock530.png and b/public/images/emoji/emoji_one/clock530.png differ diff --git a/public/images/emoji/emoji_one/clock6.png b/public/images/emoji/emoji_one/clock6.png index e978093553e..7a3b1be3da7 100644 Binary files a/public/images/emoji/emoji_one/clock6.png and b/public/images/emoji/emoji_one/clock6.png differ diff --git a/public/images/emoji/emoji_one/clock630.png b/public/images/emoji/emoji_one/clock630.png index a1f98a9f33b..b63b828a6fc 100644 Binary files a/public/images/emoji/emoji_one/clock630.png and b/public/images/emoji/emoji_one/clock630.png differ diff --git a/public/images/emoji/emoji_one/clock7.png b/public/images/emoji/emoji_one/clock7.png index 93ef6c92c0b..9bd9586feaf 100644 Binary files a/public/images/emoji/emoji_one/clock7.png and b/public/images/emoji/emoji_one/clock7.png differ diff --git a/public/images/emoji/emoji_one/clock730.png b/public/images/emoji/emoji_one/clock730.png index 373bac8b5d2..569a8b81f91 100644 Binary files a/public/images/emoji/emoji_one/clock730.png and b/public/images/emoji/emoji_one/clock730.png differ diff --git a/public/images/emoji/emoji_one/clock8.png b/public/images/emoji/emoji_one/clock8.png index 4faacac336e..7622fb8fdf7 100644 Binary files a/public/images/emoji/emoji_one/clock8.png and b/public/images/emoji/emoji_one/clock8.png differ diff --git a/public/images/emoji/emoji_one/clock830.png b/public/images/emoji/emoji_one/clock830.png index e33946fc90a..4ef83934463 100644 Binary files a/public/images/emoji/emoji_one/clock830.png and b/public/images/emoji/emoji_one/clock830.png differ diff --git a/public/images/emoji/emoji_one/clock9.png b/public/images/emoji/emoji_one/clock9.png index ee94562b069..7a3576d6dc9 100644 Binary files a/public/images/emoji/emoji_one/clock9.png and b/public/images/emoji/emoji_one/clock9.png differ diff --git a/public/images/emoji/emoji_one/clock930.png b/public/images/emoji/emoji_one/clock930.png index 9934e99ee74..c56a1740223 100644 Binary files a/public/images/emoji/emoji_one/clock930.png and b/public/images/emoji/emoji_one/clock930.png differ diff --git a/public/images/emoji/emoji_one/closed_book.png b/public/images/emoji/emoji_one/closed_book.png index 63912b3f5bc..7b7cc75f8e1 100644 Binary files a/public/images/emoji/emoji_one/closed_book.png and b/public/images/emoji/emoji_one/closed_book.png differ diff --git a/public/images/emoji/emoji_one/closed_lock_with_key.png b/public/images/emoji/emoji_one/closed_lock_with_key.png index bdffbda8706..6aed7d0bed0 100644 Binary files a/public/images/emoji/emoji_one/closed_lock_with_key.png and b/public/images/emoji/emoji_one/closed_lock_with_key.png differ diff --git a/public/images/emoji/emoji_one/closed_umbrella.png b/public/images/emoji/emoji_one/closed_umbrella.png index 00afbfb4090..b7595a1195e 100644 Binary files a/public/images/emoji/emoji_one/closed_umbrella.png and b/public/images/emoji/emoji_one/closed_umbrella.png differ diff --git a/public/images/emoji/emoji_one/cloud.png b/public/images/emoji/emoji_one/cloud.png index 559c52f7604..8984458e035 100644 Binary files a/public/images/emoji/emoji_one/cloud.png and b/public/images/emoji/emoji_one/cloud.png differ diff --git a/public/images/emoji/emoji_one/cloud_lightning.png b/public/images/emoji/emoji_one/cloud_lightning.png new file mode 100644 index 00000000000..a199f6e8836 Binary files /dev/null and b/public/images/emoji/emoji_one/cloud_lightning.png differ diff --git a/public/images/emoji/emoji_one/cloud_rain.png b/public/images/emoji/emoji_one/cloud_rain.png new file mode 100644 index 00000000000..d285e3f759d Binary files /dev/null and b/public/images/emoji/emoji_one/cloud_rain.png differ diff --git a/public/images/emoji/emoji_one/cloud_snow.png b/public/images/emoji/emoji_one/cloud_snow.png new file mode 100644 index 00000000000..e0cc8c4acbc Binary files /dev/null and b/public/images/emoji/emoji_one/cloud_snow.png differ diff --git a/public/images/emoji/emoji_one/cloud_tornado.png b/public/images/emoji/emoji_one/cloud_tornado.png new file mode 100644 index 00000000000..00bb97ae09a Binary files /dev/null and b/public/images/emoji/emoji_one/cloud_tornado.png differ diff --git a/public/images/emoji/emoji_one/clubs.png b/public/images/emoji/emoji_one/clubs.png index 6e812252a64..8483d9d2056 100644 Binary files a/public/images/emoji/emoji_one/clubs.png and b/public/images/emoji/emoji_one/clubs.png differ diff --git a/public/images/emoji/emoji_one/cn.png b/public/images/emoji/emoji_one/cn.png index 0151923f351..e09fcb9b442 100644 Binary files a/public/images/emoji/emoji_one/cn.png and b/public/images/emoji/emoji_one/cn.png differ diff --git a/public/images/emoji/emoji_one/cocktail.png b/public/images/emoji/emoji_one/cocktail.png index d03b174fa8e..dfcae146070 100644 Binary files a/public/images/emoji/emoji_one/cocktail.png and b/public/images/emoji/emoji_one/cocktail.png differ diff --git a/public/images/emoji/emoji_one/coffee.png b/public/images/emoji/emoji_one/coffee.png index 6f5a85282aa..3f70a674175 100644 Binary files a/public/images/emoji/emoji_one/coffee.png and b/public/images/emoji/emoji_one/coffee.png differ diff --git a/public/images/emoji/emoji_one/coffin.png b/public/images/emoji/emoji_one/coffin.png new file mode 100644 index 00000000000..f38c07847e7 Binary files /dev/null and b/public/images/emoji/emoji_one/coffin.png differ diff --git a/public/images/emoji/emoji_one/cold_sweat.png b/public/images/emoji/emoji_one/cold_sweat.png index 286f494a353..90a05e87ec6 100644 Binary files a/public/images/emoji/emoji_one/cold_sweat.png and b/public/images/emoji/emoji_one/cold_sweat.png differ diff --git a/public/images/emoji/emoji_one/collision.png b/public/images/emoji/emoji_one/collision.png index 4480b19814c..771b8ef8990 100644 Binary files a/public/images/emoji/emoji_one/collision.png and b/public/images/emoji/emoji_one/collision.png differ diff --git a/public/images/emoji/emoji_one/comet.png b/public/images/emoji/emoji_one/comet.png new file mode 100644 index 00000000000..6d27243697d Binary files /dev/null and b/public/images/emoji/emoji_one/comet.png differ diff --git a/public/images/emoji/emoji_one/compression.png b/public/images/emoji/emoji_one/compression.png new file mode 100644 index 00000000000..86f93629234 Binary files /dev/null and b/public/images/emoji/emoji_one/compression.png differ diff --git a/public/images/emoji/emoji_one/computer.png b/public/images/emoji/emoji_one/computer.png index 24ae29886e5..80b1cfd9a3d 100644 Binary files a/public/images/emoji/emoji_one/computer.png and b/public/images/emoji/emoji_one/computer.png differ diff --git a/public/images/emoji/emoji_one/confetti_ball.png b/public/images/emoji/emoji_one/confetti_ball.png index 74c61e43443..2f3578f9bec 100644 Binary files a/public/images/emoji/emoji_one/confetti_ball.png and b/public/images/emoji/emoji_one/confetti_ball.png differ diff --git a/public/images/emoji/emoji_one/confounded.png b/public/images/emoji/emoji_one/confounded.png index d64e2a534d9..278c1c65951 100644 Binary files a/public/images/emoji/emoji_one/confounded.png and b/public/images/emoji/emoji_one/confounded.png differ diff --git a/public/images/emoji/emoji_one/confused.png b/public/images/emoji/emoji_one/confused.png index d3a23eb8bb8..e7cdf121df9 100644 Binary files a/public/images/emoji/emoji_one/confused.png and b/public/images/emoji/emoji_one/confused.png differ diff --git a/public/images/emoji/emoji_one/congratulations.png b/public/images/emoji/emoji_one/congratulations.png index 687b65ce5c7..58ea4b2458a 100644 Binary files a/public/images/emoji/emoji_one/congratulations.png and b/public/images/emoji/emoji_one/congratulations.png differ diff --git a/public/images/emoji/emoji_one/construction.png b/public/images/emoji/emoji_one/construction.png index 917317b4625..70d74538507 100644 Binary files a/public/images/emoji/emoji_one/construction.png and b/public/images/emoji/emoji_one/construction.png differ diff --git a/public/images/emoji/emoji_one/construction_site.png b/public/images/emoji/emoji_one/construction_site.png new file mode 100644 index 00000000000..04d111a6f48 Binary files /dev/null and b/public/images/emoji/emoji_one/construction_site.png differ diff --git a/public/images/emoji/emoji_one/construction_worker.png b/public/images/emoji/emoji_one/construction_worker.png index f772004ca5d..e2135020ab0 100644 Binary files a/public/images/emoji/emoji_one/construction_worker.png and b/public/images/emoji/emoji_one/construction_worker.png differ diff --git a/public/images/emoji/emoji_one/control_knobs.png b/public/images/emoji/emoji_one/control_knobs.png new file mode 100644 index 00000000000..1a3ae01fb7f Binary files /dev/null and b/public/images/emoji/emoji_one/control_knobs.png differ diff --git a/public/images/emoji/emoji_one/convenience_store.png b/public/images/emoji/emoji_one/convenience_store.png index 675c233dfda..26b680428f2 100644 Binary files a/public/images/emoji/emoji_one/convenience_store.png and b/public/images/emoji/emoji_one/convenience_store.png differ diff --git a/public/images/emoji/emoji_one/cookie.png b/public/images/emoji/emoji_one/cookie.png index 8eb640e8d9a..5e591ac16fe 100644 Binary files a/public/images/emoji/emoji_one/cookie.png and b/public/images/emoji/emoji_one/cookie.png differ diff --git a/public/images/emoji/emoji_one/cool.png b/public/images/emoji/emoji_one/cool.png index aaf3c164590..c5377c5bfe6 100644 Binary files a/public/images/emoji/emoji_one/cool.png and b/public/images/emoji/emoji_one/cool.png differ diff --git a/public/images/emoji/emoji_one/cop.png b/public/images/emoji/emoji_one/cop.png index be1b553cf2c..b795e956da2 100644 Binary files a/public/images/emoji/emoji_one/cop.png and b/public/images/emoji/emoji_one/cop.png differ diff --git a/public/images/emoji/emoji_one/copyright.png b/public/images/emoji/emoji_one/copyright.png index 7b1844b28ae..9872c5b7e2f 100644 Binary files a/public/images/emoji/emoji_one/copyright.png and b/public/images/emoji/emoji_one/copyright.png differ diff --git a/public/images/emoji/emoji_one/corn.png b/public/images/emoji/emoji_one/corn.png index e5f2304bd24..14e681f6f19 100644 Binary files a/public/images/emoji/emoji_one/corn.png and b/public/images/emoji/emoji_one/corn.png differ diff --git a/public/images/emoji/emoji_one/couch.png b/public/images/emoji/emoji_one/couch.png new file mode 100644 index 00000000000..95676c09e83 Binary files /dev/null and b/public/images/emoji/emoji_one/couch.png differ diff --git a/public/images/emoji/emoji_one/couple.png b/public/images/emoji/emoji_one/couple.png index 877fe39014f..3805633c96f 100644 Binary files a/public/images/emoji/emoji_one/couple.png and b/public/images/emoji/emoji_one/couple.png differ diff --git a/public/images/emoji/emoji_one/couple_with_heart.png b/public/images/emoji/emoji_one/couple_with_heart.png index 88bd694a850..92fc7412aba 100644 Binary files a/public/images/emoji/emoji_one/couple_with_heart.png and b/public/images/emoji/emoji_one/couple_with_heart.png differ diff --git a/public/images/emoji/emoji_one/couplekiss.png b/public/images/emoji/emoji_one/couplekiss.png index 505398e983e..34c0f721470 100644 Binary files a/public/images/emoji/emoji_one/couplekiss.png and b/public/images/emoji/emoji_one/couplekiss.png differ diff --git a/public/images/emoji/emoji_one/cow.png b/public/images/emoji/emoji_one/cow.png index 49513b99456..4f3d69799fc 100644 Binary files a/public/images/emoji/emoji_one/cow.png and b/public/images/emoji/emoji_one/cow.png differ diff --git a/public/images/emoji/emoji_one/cow2.png b/public/images/emoji/emoji_one/cow2.png index 984b786befb..edb172f6abe 100644 Binary files a/public/images/emoji/emoji_one/cow2.png and b/public/images/emoji/emoji_one/cow2.png differ diff --git a/public/images/emoji/emoji_one/crab.png b/public/images/emoji/emoji_one/crab.png new file mode 100644 index 00000000000..04374656af5 Binary files /dev/null and b/public/images/emoji/emoji_one/crab.png differ diff --git a/public/images/emoji/emoji_one/crayon.png b/public/images/emoji/emoji_one/crayon.png new file mode 100644 index 00000000000..67043e2a21b Binary files /dev/null and b/public/images/emoji/emoji_one/crayon.png differ diff --git a/public/images/emoji/emoji_one/credit_card.png b/public/images/emoji/emoji_one/credit_card.png index 7037fdb29b3..1f67ade551b 100644 Binary files a/public/images/emoji/emoji_one/credit_card.png and b/public/images/emoji/emoji_one/credit_card.png differ diff --git a/public/images/emoji/emoji_one/crescent_moon.png b/public/images/emoji/emoji_one/crescent_moon.png index 75f7ed56d95..fa09e12ad42 100644 Binary files a/public/images/emoji/emoji_one/crescent_moon.png and b/public/images/emoji/emoji_one/crescent_moon.png differ diff --git a/public/images/emoji/emoji_one/cricket.png b/public/images/emoji/emoji_one/cricket.png new file mode 100644 index 00000000000..2e20bfcd034 Binary files /dev/null and b/public/images/emoji/emoji_one/cricket.png differ diff --git a/public/images/emoji/emoji_one/crocodile.png b/public/images/emoji/emoji_one/crocodile.png index 3b53cacf8ae..5da8a61756b 100644 Binary files a/public/images/emoji/emoji_one/crocodile.png and b/public/images/emoji/emoji_one/crocodile.png differ diff --git a/public/images/emoji/emoji_one/cross.png b/public/images/emoji/emoji_one/cross.png new file mode 100644 index 00000000000..02a0842181a Binary files /dev/null and b/public/images/emoji/emoji_one/cross.png differ diff --git a/public/images/emoji/emoji_one/crossed_flags.png b/public/images/emoji/emoji_one/crossed_flags.png index 5d88b0ad0e7..c1ad42dab41 100644 Binary files a/public/images/emoji/emoji_one/crossed_flags.png and b/public/images/emoji/emoji_one/crossed_flags.png differ diff --git a/public/images/emoji/emoji_one/crossed_swords.png b/public/images/emoji/emoji_one/crossed_swords.png new file mode 100644 index 00000000000..7e992fa3c39 Binary files /dev/null and b/public/images/emoji/emoji_one/crossed_swords.png differ diff --git a/public/images/emoji/emoji_one/crown.png b/public/images/emoji/emoji_one/crown.png index 54ca7998cfc..860ebe2c982 100644 Binary files a/public/images/emoji/emoji_one/crown.png and b/public/images/emoji/emoji_one/crown.png differ diff --git a/public/images/emoji/emoji_one/cruise_ship.png b/public/images/emoji/emoji_one/cruise_ship.png new file mode 100644 index 00000000000..74271367796 Binary files /dev/null and b/public/images/emoji/emoji_one/cruise_ship.png differ diff --git a/public/images/emoji/emoji_one/cry.png b/public/images/emoji/emoji_one/cry.png index dd3f9028fa9..da8f1f04513 100644 Binary files a/public/images/emoji/emoji_one/cry.png and b/public/images/emoji/emoji_one/cry.png differ diff --git a/public/images/emoji/emoji_one/crying_cat_face.png b/public/images/emoji/emoji_one/crying_cat_face.png index 58979048e12..4a0c8d76fed 100644 Binary files a/public/images/emoji/emoji_one/crying_cat_face.png and b/public/images/emoji/emoji_one/crying_cat_face.png differ diff --git a/public/images/emoji/emoji_one/crystal_ball.png b/public/images/emoji/emoji_one/crystal_ball.png index d9ee3b4f36c..c0bcce68f4a 100644 Binary files a/public/images/emoji/emoji_one/crystal_ball.png and b/public/images/emoji/emoji_one/crystal_ball.png differ diff --git a/public/images/emoji/emoji_one/cupid.png b/public/images/emoji/emoji_one/cupid.png index 49260219c70..12312e312f2 100644 Binary files a/public/images/emoji/emoji_one/cupid.png and b/public/images/emoji/emoji_one/cupid.png differ diff --git a/public/images/emoji/emoji_one/curly_loop.png b/public/images/emoji/emoji_one/curly_loop.png index 2446540e73a..98a3b813008 100644 Binary files a/public/images/emoji/emoji_one/curly_loop.png and b/public/images/emoji/emoji_one/curly_loop.png differ diff --git a/public/images/emoji/emoji_one/currency_exchange.png b/public/images/emoji/emoji_one/currency_exchange.png index 76a814ee2d3..96acbe5452e 100644 Binary files a/public/images/emoji/emoji_one/currency_exchange.png and b/public/images/emoji/emoji_one/currency_exchange.png differ diff --git a/public/images/emoji/emoji_one/curry.png b/public/images/emoji/emoji_one/curry.png index f97d0e0f9e9..c7f2c54eb84 100644 Binary files a/public/images/emoji/emoji_one/curry.png and b/public/images/emoji/emoji_one/curry.png differ diff --git a/public/images/emoji/emoji_one/custard.png b/public/images/emoji/emoji_one/custard.png index 44af92a57d3..e520199499b 100644 Binary files a/public/images/emoji/emoji_one/custard.png and b/public/images/emoji/emoji_one/custard.png differ diff --git a/public/images/emoji/emoji_one/customs.png b/public/images/emoji/emoji_one/customs.png index c0b596b074e..97a5ee7bfd9 100644 Binary files a/public/images/emoji/emoji_one/customs.png and b/public/images/emoji/emoji_one/customs.png differ diff --git a/public/images/emoji/emoji_one/cyclone.png b/public/images/emoji/emoji_one/cyclone.png index b245f841729..947a49be710 100644 Binary files a/public/images/emoji/emoji_one/cyclone.png and b/public/images/emoji/emoji_one/cyclone.png differ diff --git a/public/images/emoji/emoji_one/dagger.png b/public/images/emoji/emoji_one/dagger.png new file mode 100644 index 00000000000..4093ea9fce3 Binary files /dev/null and b/public/images/emoji/emoji_one/dagger.png differ diff --git a/public/images/emoji/emoji_one/dancer.png b/public/images/emoji/emoji_one/dancer.png index 705ecf100c8..b84a053f61d 100644 Binary files a/public/images/emoji/emoji_one/dancer.png and b/public/images/emoji/emoji_one/dancer.png differ diff --git a/public/images/emoji/emoji_one/dancers.png b/public/images/emoji/emoji_one/dancers.png index 498d83d9720..47000b9dc32 100644 Binary files a/public/images/emoji/emoji_one/dancers.png and b/public/images/emoji/emoji_one/dancers.png differ diff --git a/public/images/emoji/emoji_one/dango.png b/public/images/emoji/emoji_one/dango.png index d679ebc0231..dc8af040ab0 100644 Binary files a/public/images/emoji/emoji_one/dango.png and b/public/images/emoji/emoji_one/dango.png differ diff --git a/public/images/emoji/emoji_one/dark_sunglasses.png b/public/images/emoji/emoji_one/dark_sunglasses.png new file mode 100644 index 00000000000..cd95402d6e2 Binary files /dev/null and b/public/images/emoji/emoji_one/dark_sunglasses.png differ diff --git a/public/images/emoji/emoji_one/dart.png b/public/images/emoji/emoji_one/dart.png index 527b6a94e01..9b14223202e 100644 Binary files a/public/images/emoji/emoji_one/dart.png and b/public/images/emoji/emoji_one/dart.png differ diff --git a/public/images/emoji/emoji_one/dash.png b/public/images/emoji/emoji_one/dash.png index d58c2228150..88525c48c7c 100644 Binary files a/public/images/emoji/emoji_one/dash.png and b/public/images/emoji/emoji_one/dash.png differ diff --git a/public/images/emoji/emoji_one/date.png b/public/images/emoji/emoji_one/date.png index b6ddf24e372..dbc2ebd44ca 100644 Binary files a/public/images/emoji/emoji_one/date.png and b/public/images/emoji/emoji_one/date.png differ diff --git a/public/images/emoji/emoji_one/de.png b/public/images/emoji/emoji_one/de.png index 36b3290dc0e..b246395ad34 100644 Binary files a/public/images/emoji/emoji_one/de.png and b/public/images/emoji/emoji_one/de.png differ diff --git a/public/images/emoji/emoji_one/deciduous_tree.png b/public/images/emoji/emoji_one/deciduous_tree.png index 1a54ec34b03..6a62f8333cd 100644 Binary files a/public/images/emoji/emoji_one/deciduous_tree.png and b/public/images/emoji/emoji_one/deciduous_tree.png differ diff --git a/public/images/emoji/emoji_one/department_store.png b/public/images/emoji/emoji_one/department_store.png index 6433ed1549f..c0a4baa218b 100644 Binary files a/public/images/emoji/emoji_one/department_store.png and b/public/images/emoji/emoji_one/department_store.png differ diff --git a/public/images/emoji/emoji_one/desert.png b/public/images/emoji/emoji_one/desert.png new file mode 100644 index 00000000000..a548ec13c08 Binary files /dev/null and b/public/images/emoji/emoji_one/desert.png differ diff --git a/public/images/emoji/emoji_one/desktop.png b/public/images/emoji/emoji_one/desktop.png new file mode 100644 index 00000000000..0bb0db87944 Binary files /dev/null and b/public/images/emoji/emoji_one/desktop.png differ diff --git a/public/images/emoji/emoji_one/diamond_shape_with_a_dot_inside.png b/public/images/emoji/emoji_one/diamond_shape_with_a_dot_inside.png index 6aec6cb1920..ec8a4e06767 100644 Binary files a/public/images/emoji/emoji_one/diamond_shape_with_a_dot_inside.png and b/public/images/emoji/emoji_one/diamond_shape_with_a_dot_inside.png differ diff --git a/public/images/emoji/emoji_one/diamonds.png b/public/images/emoji/emoji_one/diamonds.png index 892d8bd24be..38ca65e1242 100644 Binary files a/public/images/emoji/emoji_one/diamonds.png and b/public/images/emoji/emoji_one/diamonds.png differ diff --git a/public/images/emoji/emoji_one/disappointed.png b/public/images/emoji/emoji_one/disappointed.png index 807e4698eb2..ba12f75e108 100644 Binary files a/public/images/emoji/emoji_one/disappointed.png and b/public/images/emoji/emoji_one/disappointed.png differ diff --git a/public/images/emoji/emoji_one/disappointed_relieved.png b/public/images/emoji/emoji_one/disappointed_relieved.png index aac3db94ce6..5e309621acf 100644 Binary files a/public/images/emoji/emoji_one/disappointed_relieved.png and b/public/images/emoji/emoji_one/disappointed_relieved.png differ diff --git a/public/images/emoji/emoji_one/dividers.png b/public/images/emoji/emoji_one/dividers.png new file mode 100644 index 00000000000..8f162232c1f Binary files /dev/null and b/public/images/emoji/emoji_one/dividers.png differ diff --git a/public/images/emoji/emoji_one/dizzy.png b/public/images/emoji/emoji_one/dizzy.png index b6972196c25..c11aeb2c4f1 100644 Binary files a/public/images/emoji/emoji_one/dizzy.png and b/public/images/emoji/emoji_one/dizzy.png differ diff --git a/public/images/emoji/emoji_one/dizzy_face.png b/public/images/emoji/emoji_one/dizzy_face.png index 6f7caabcb64..1b7f821a86d 100644 Binary files a/public/images/emoji/emoji_one/dizzy_face.png and b/public/images/emoji/emoji_one/dizzy_face.png differ diff --git a/public/images/emoji/emoji_one/do_not_litter.png b/public/images/emoji/emoji_one/do_not_litter.png index 66e692d41ef..f2d0d438d28 100644 Binary files a/public/images/emoji/emoji_one/do_not_litter.png and b/public/images/emoji/emoji_one/do_not_litter.png differ diff --git a/public/images/emoji/emoji_one/dog.png b/public/images/emoji/emoji_one/dog.png index 3c107deb40c..de79fbecca0 100644 Binary files a/public/images/emoji/emoji_one/dog.png and b/public/images/emoji/emoji_one/dog.png differ diff --git a/public/images/emoji/emoji_one/dog2.png b/public/images/emoji/emoji_one/dog2.png index 7057ffe6600..be0e3089d8a 100644 Binary files a/public/images/emoji/emoji_one/dog2.png and b/public/images/emoji/emoji_one/dog2.png differ diff --git a/public/images/emoji/emoji_one/dollar.png b/public/images/emoji/emoji_one/dollar.png index 04ebccf74d4..4073d0bd3c8 100644 Binary files a/public/images/emoji/emoji_one/dollar.png and b/public/images/emoji/emoji_one/dollar.png differ diff --git a/public/images/emoji/emoji_one/dolls.png b/public/images/emoji/emoji_one/dolls.png index dcd7b938522..0acd1666b87 100644 Binary files a/public/images/emoji/emoji_one/dolls.png and b/public/images/emoji/emoji_one/dolls.png differ diff --git a/public/images/emoji/emoji_one/dolphin.png b/public/images/emoji/emoji_one/dolphin.png index 4dde4cc134e..e952c24fbe3 100644 Binary files a/public/images/emoji/emoji_one/dolphin.png and b/public/images/emoji/emoji_one/dolphin.png differ diff --git a/public/images/emoji/emoji_one/door.png b/public/images/emoji/emoji_one/door.png index 1d717b76c80..c3dc86e5b56 100644 Binary files a/public/images/emoji/emoji_one/door.png and b/public/images/emoji/emoji_one/door.png differ diff --git a/public/images/emoji/emoji_one/doughnut.png b/public/images/emoji/emoji_one/doughnut.png index b415c96bcff..e65074841dd 100644 Binary files a/public/images/emoji/emoji_one/doughnut.png and b/public/images/emoji/emoji_one/doughnut.png differ diff --git a/public/images/emoji/emoji_one/dove.png b/public/images/emoji/emoji_one/dove.png new file mode 100644 index 00000000000..88ddff7a6c5 Binary files /dev/null and b/public/images/emoji/emoji_one/dove.png differ diff --git a/public/images/emoji/emoji_one/dragon.png b/public/images/emoji/emoji_one/dragon.png index b5b6357705d..ac2de4ba46e 100644 Binary files a/public/images/emoji/emoji_one/dragon.png and b/public/images/emoji/emoji_one/dragon.png differ diff --git a/public/images/emoji/emoji_one/dragon_face.png b/public/images/emoji/emoji_one/dragon_face.png index aba3bd4715f..c8a71384bea 100644 Binary files a/public/images/emoji/emoji_one/dragon_face.png and b/public/images/emoji/emoji_one/dragon_face.png differ diff --git a/public/images/emoji/emoji_one/dress.png b/public/images/emoji/emoji_one/dress.png index 512fe8bfeb8..01ae22aab58 100644 Binary files a/public/images/emoji/emoji_one/dress.png and b/public/images/emoji/emoji_one/dress.png differ diff --git a/public/images/emoji/emoji_one/dromedary_camel.png b/public/images/emoji/emoji_one/dromedary_camel.png index e881a8b5f41..ed8875d64db 100644 Binary files a/public/images/emoji/emoji_one/dromedary_camel.png and b/public/images/emoji/emoji_one/dromedary_camel.png differ diff --git a/public/images/emoji/emoji_one/droplet.png b/public/images/emoji/emoji_one/droplet.png index 12ea46c1969..c15d006d9ff 100644 Binary files a/public/images/emoji/emoji_one/droplet.png and b/public/images/emoji/emoji_one/droplet.png differ diff --git a/public/images/emoji/emoji_one/dvd.png b/public/images/emoji/emoji_one/dvd.png index 294b9140863..5ca53835ce2 100644 Binary files a/public/images/emoji/emoji_one/dvd.png and b/public/images/emoji/emoji_one/dvd.png differ diff --git a/public/images/emoji/emoji_one/e-mail.png b/public/images/emoji/emoji_one/e-mail.png index 52a0022f881..46a3c4d1789 100644 Binary files a/public/images/emoji/emoji_one/e-mail.png and b/public/images/emoji/emoji_one/e-mail.png differ diff --git a/public/images/emoji/emoji_one/ear.png b/public/images/emoji/emoji_one/ear.png index 84053622b11..16fbe47e70f 100644 Binary files a/public/images/emoji/emoji_one/ear.png and b/public/images/emoji/emoji_one/ear.png differ diff --git a/public/images/emoji/emoji_one/ear_of_rice.png b/public/images/emoji/emoji_one/ear_of_rice.png index 9d3f454f86a..eb3e75b4642 100644 Binary files a/public/images/emoji/emoji_one/ear_of_rice.png and b/public/images/emoji/emoji_one/ear_of_rice.png differ diff --git a/public/images/emoji/emoji_one/earth_africa.png b/public/images/emoji/emoji_one/earth_africa.png index a4bbace5493..e387799a10f 100644 Binary files a/public/images/emoji/emoji_one/earth_africa.png and b/public/images/emoji/emoji_one/earth_africa.png differ diff --git a/public/images/emoji/emoji_one/earth_americas.png b/public/images/emoji/emoji_one/earth_americas.png index 13a307f3c36..327c26805ed 100644 Binary files a/public/images/emoji/emoji_one/earth_americas.png and b/public/images/emoji/emoji_one/earth_americas.png differ diff --git a/public/images/emoji/emoji_one/earth_asia.png b/public/images/emoji/emoji_one/earth_asia.png index e8fcb563f77..fdee507fa3a 100644 Binary files a/public/images/emoji/emoji_one/earth_asia.png and b/public/images/emoji/emoji_one/earth_asia.png differ diff --git a/public/images/emoji/emoji_one/egg.png b/public/images/emoji/emoji_one/egg.png index b5c090a17fa..0989cf6d541 100644 Binary files a/public/images/emoji/emoji_one/egg.png and b/public/images/emoji/emoji_one/egg.png differ diff --git a/public/images/emoji/emoji_one/eggplant.png b/public/images/emoji/emoji_one/eggplant.png index 75c902569ed..6eb3d0f5aaf 100644 Binary files a/public/images/emoji/emoji_one/eggplant.png and b/public/images/emoji/emoji_one/eggplant.png differ diff --git a/public/images/emoji/emoji_one/eight.png b/public/images/emoji/emoji_one/eight.png index 05078116065..aed172e2622 100644 Binary files a/public/images/emoji/emoji_one/eight.png and b/public/images/emoji/emoji_one/eight.png differ diff --git a/public/images/emoji/emoji_one/eight_pointed_black_star.png b/public/images/emoji/emoji_one/eight_pointed_black_star.png index 7dcb6b338c1..b8e96dc69c0 100644 Binary files a/public/images/emoji/emoji_one/eight_pointed_black_star.png and b/public/images/emoji/emoji_one/eight_pointed_black_star.png differ diff --git a/public/images/emoji/emoji_one/eight_spoked_asterisk.png b/public/images/emoji/emoji_one/eight_spoked_asterisk.png index 1d3717b994a..07546794eef 100644 Binary files a/public/images/emoji/emoji_one/eight_spoked_asterisk.png and b/public/images/emoji/emoji_one/eight_spoked_asterisk.png differ diff --git a/public/images/emoji/emoji_one/electric_plug.png b/public/images/emoji/emoji_one/electric_plug.png index 402745ea463..446a7d2b44b 100644 Binary files a/public/images/emoji/emoji_one/electric_plug.png and b/public/images/emoji/emoji_one/electric_plug.png differ diff --git a/public/images/emoji/emoji_one/elephant.png b/public/images/emoji/emoji_one/elephant.png index af079ec4db7..a3599f5e0bb 100644 Binary files a/public/images/emoji/emoji_one/elephant.png and b/public/images/emoji/emoji_one/elephant.png differ diff --git a/public/images/emoji/emoji_one/email.png b/public/images/emoji/emoji_one/email.png index 41260282c5d..3751286f73c 100644 Binary files a/public/images/emoji/emoji_one/email.png and b/public/images/emoji/emoji_one/email.png differ diff --git a/public/images/emoji/emoji_one/end.png b/public/images/emoji/emoji_one/end.png index a0cfda28b94..702f2182aa8 100644 Binary files a/public/images/emoji/emoji_one/end.png and b/public/images/emoji/emoji_one/end.png differ diff --git a/public/images/emoji/emoji_one/envelope.png b/public/images/emoji/emoji_one/envelope.png index b512f6d6a77..f7680981232 100644 Binary files a/public/images/emoji/emoji_one/envelope.png and b/public/images/emoji/emoji_one/envelope.png differ diff --git a/public/images/emoji/emoji_one/envelope_with_arrow.png b/public/images/emoji/emoji_one/envelope_with_arrow.png index 373cd8f0f5f..bb94734671a 100644 Binary files a/public/images/emoji/emoji_one/envelope_with_arrow.png and b/public/images/emoji/emoji_one/envelope_with_arrow.png differ diff --git a/public/images/emoji/emoji_one/es.png b/public/images/emoji/emoji_one/es.png index b47b1de8349..875d68a75c9 100644 Binary files a/public/images/emoji/emoji_one/es.png and b/public/images/emoji/emoji_one/es.png differ diff --git a/public/images/emoji/emoji_one/euro.png b/public/images/emoji/emoji_one/euro.png index 2c71bbde8f7..ddc7744afba 100644 Binary files a/public/images/emoji/emoji_one/euro.png and b/public/images/emoji/emoji_one/euro.png differ diff --git a/public/images/emoji/emoji_one/european_castle.png b/public/images/emoji/emoji_one/european_castle.png index 1af59a5b67e..d2fea0ce04e 100644 Binary files a/public/images/emoji/emoji_one/european_castle.png and b/public/images/emoji/emoji_one/european_castle.png differ diff --git a/public/images/emoji/emoji_one/european_post_office.png b/public/images/emoji/emoji_one/european_post_office.png index efc6617c571..fc851d01241 100644 Binary files a/public/images/emoji/emoji_one/european_post_office.png and b/public/images/emoji/emoji_one/european_post_office.png differ diff --git a/public/images/emoji/emoji_one/evergreen_tree.png b/public/images/emoji/emoji_one/evergreen_tree.png index 605e9a167cc..fc3c56a683b 100644 Binary files a/public/images/emoji/emoji_one/evergreen_tree.png and b/public/images/emoji/emoji_one/evergreen_tree.png differ diff --git a/public/images/emoji/emoji_one/exclamation.png b/public/images/emoji/emoji_one/exclamation.png index 6f9147ac0d8..bde695c1d06 100644 Binary files a/public/images/emoji/emoji_one/exclamation.png and b/public/images/emoji/emoji_one/exclamation.png differ diff --git a/public/images/emoji/emoji_one/expressionless.png b/public/images/emoji/emoji_one/expressionless.png index 5b7eb95a6a5..a9a8fbf7e6c 100644 Binary files a/public/images/emoji/emoji_one/expressionless.png and b/public/images/emoji/emoji_one/expressionless.png differ diff --git a/public/images/emoji/emoji_one/eye.png b/public/images/emoji/emoji_one/eye.png new file mode 100644 index 00000000000..9a71b467002 Binary files /dev/null and b/public/images/emoji/emoji_one/eye.png differ diff --git a/public/images/emoji/emoji_one/eyeglasses.png b/public/images/emoji/emoji_one/eyeglasses.png index f1f4612ba2a..86521fd203f 100644 Binary files a/public/images/emoji/emoji_one/eyeglasses.png and b/public/images/emoji/emoji_one/eyeglasses.png differ diff --git a/public/images/emoji/emoji_one/eyes.png b/public/images/emoji/emoji_one/eyes.png index d9a6163f434..06bbab49330 100644 Binary files a/public/images/emoji/emoji_one/eyes.png and b/public/images/emoji/emoji_one/eyes.png differ diff --git a/public/images/emoji/emoji_one/facepunch.png b/public/images/emoji/emoji_one/facepunch.png index a616ffee193..dc01d1a074e 100644 Binary files a/public/images/emoji/emoji_one/facepunch.png and b/public/images/emoji/emoji_one/facepunch.png differ diff --git a/public/images/emoji/emoji_one/factory.png b/public/images/emoji/emoji_one/factory.png index ba04537b7c0..72eadc92e79 100644 Binary files a/public/images/emoji/emoji_one/factory.png and b/public/images/emoji/emoji_one/factory.png differ diff --git a/public/images/emoji/emoji_one/fallen_leaf.png b/public/images/emoji/emoji_one/fallen_leaf.png index 430ac029701..49a3e69f695 100644 Binary files a/public/images/emoji/emoji_one/fallen_leaf.png and b/public/images/emoji/emoji_one/fallen_leaf.png differ diff --git a/public/images/emoji/emoji_one/family.png b/public/images/emoji/emoji_one/family.png index 93b4bcccbd8..c74fe74190d 100644 Binary files a/public/images/emoji/emoji_one/family.png and b/public/images/emoji/emoji_one/family.png differ diff --git a/public/images/emoji/emoji_one/fast_forward.png b/public/images/emoji/emoji_one/fast_forward.png index c810d4039ca..43a84e66bba 100644 Binary files a/public/images/emoji/emoji_one/fast_forward.png and b/public/images/emoji/emoji_one/fast_forward.png differ diff --git a/public/images/emoji/emoji_one/fax.png b/public/images/emoji/emoji_one/fax.png index 471d88a2ac6..aad3adb803a 100644 Binary files a/public/images/emoji/emoji_one/fax.png and b/public/images/emoji/emoji_one/fax.png differ diff --git a/public/images/emoji/emoji_one/fearful.png b/public/images/emoji/emoji_one/fearful.png index 194824206c4..a97f36bf4e8 100644 Binary files a/public/images/emoji/emoji_one/fearful.png and b/public/images/emoji/emoji_one/fearful.png differ diff --git a/public/images/emoji/emoji_one/feet.png b/public/images/emoji/emoji_one/feet.png index 970366ce19a..b059c1422d7 100644 Binary files a/public/images/emoji/emoji_one/feet.png and b/public/images/emoji/emoji_one/feet.png differ diff --git a/public/images/emoji/emoji_one/ferris_wheel.png b/public/images/emoji/emoji_one/ferris_wheel.png index 5f1f8c15894..779459a739c 100644 Binary files a/public/images/emoji/emoji_one/ferris_wheel.png and b/public/images/emoji/emoji_one/ferris_wheel.png differ diff --git a/public/images/emoji/emoji_one/ferry.png b/public/images/emoji/emoji_one/ferry.png new file mode 100644 index 00000000000..a4a8793c9bb Binary files /dev/null and b/public/images/emoji/emoji_one/ferry.png differ diff --git a/public/images/emoji/emoji_one/field_hockey.png b/public/images/emoji/emoji_one/field_hockey.png new file mode 100644 index 00000000000..f4f80660096 Binary files /dev/null and b/public/images/emoji/emoji_one/field_hockey.png differ diff --git a/public/images/emoji/emoji_one/file_cabinet.png b/public/images/emoji/emoji_one/file_cabinet.png new file mode 100644 index 00000000000..c26b487c00a Binary files /dev/null and b/public/images/emoji/emoji_one/file_cabinet.png differ diff --git a/public/images/emoji/emoji_one/file_folder.png b/public/images/emoji/emoji_one/file_folder.png index 244d70720bd..121a99dfff9 100644 Binary files a/public/images/emoji/emoji_one/file_folder.png and b/public/images/emoji/emoji_one/file_folder.png differ diff --git a/public/images/emoji/emoji_one/film_frames.png b/public/images/emoji/emoji_one/film_frames.png new file mode 100644 index 00000000000..6d4307f187e Binary files /dev/null and b/public/images/emoji/emoji_one/film_frames.png differ diff --git a/public/images/emoji/emoji_one/fire.png b/public/images/emoji/emoji_one/fire.png index 3149ed67581..f1a43327c06 100644 Binary files a/public/images/emoji/emoji_one/fire.png and b/public/images/emoji/emoji_one/fire.png differ diff --git a/public/images/emoji/emoji_one/fire_engine.png b/public/images/emoji/emoji_one/fire_engine.png index 0336bfdf5c4..6ea0f873a33 100644 Binary files a/public/images/emoji/emoji_one/fire_engine.png and b/public/images/emoji/emoji_one/fire_engine.png differ diff --git a/public/images/emoji/emoji_one/fireworks.png b/public/images/emoji/emoji_one/fireworks.png index 6c67a0e15f5..6654ee3fa2a 100644 Binary files a/public/images/emoji/emoji_one/fireworks.png and b/public/images/emoji/emoji_one/fireworks.png differ diff --git a/public/images/emoji/emoji_one/first_quarter_moon.png b/public/images/emoji/emoji_one/first_quarter_moon.png index 14734a42c4a..991a84e5e5e 100644 Binary files a/public/images/emoji/emoji_one/first_quarter_moon.png and b/public/images/emoji/emoji_one/first_quarter_moon.png differ diff --git a/public/images/emoji/emoji_one/first_quarter_moon_with_face.png b/public/images/emoji/emoji_one/first_quarter_moon_with_face.png index 5f39296e285..4e44744330b 100644 Binary files a/public/images/emoji/emoji_one/first_quarter_moon_with_face.png and b/public/images/emoji/emoji_one/first_quarter_moon_with_face.png differ diff --git a/public/images/emoji/emoji_one/fish.png b/public/images/emoji/emoji_one/fish.png index cb7b896d6d8..e971874ff8b 100644 Binary files a/public/images/emoji/emoji_one/fish.png and b/public/images/emoji/emoji_one/fish.png differ diff --git a/public/images/emoji/emoji_one/fish_cake.png b/public/images/emoji/emoji_one/fish_cake.png index 6ff94bc36aa..1109b8e7a15 100644 Binary files a/public/images/emoji/emoji_one/fish_cake.png and b/public/images/emoji/emoji_one/fish_cake.png differ diff --git a/public/images/emoji/emoji_one/fishing_pole_and_fish.png b/public/images/emoji/emoji_one/fishing_pole_and_fish.png index 270a011dd60..8561ca9b8b9 100644 Binary files a/public/images/emoji/emoji_one/fishing_pole_and_fish.png and b/public/images/emoji/emoji_one/fishing_pole_and_fish.png differ diff --git a/public/images/emoji/emoji_one/fist.png b/public/images/emoji/emoji_one/fist.png index 1206ebecde5..fc54ea22117 100644 Binary files a/public/images/emoji/emoji_one/fist.png and b/public/images/emoji/emoji_one/fist.png differ diff --git a/public/images/emoji/emoji_one/five.png b/public/images/emoji/emoji_one/five.png index 8d8d6614658..9b868a70ccc 100644 Binary files a/public/images/emoji/emoji_one/five.png and b/public/images/emoji/emoji_one/five.png differ diff --git a/public/images/emoji/emoji_one/flag_black.png b/public/images/emoji/emoji_one/flag_black.png new file mode 100644 index 00000000000..22df4375bef Binary files /dev/null and b/public/images/emoji/emoji_one/flag_black.png differ diff --git a/public/images/emoji/emoji_one/flag_cn.png b/public/images/emoji/emoji_one/flag_cn.png new file mode 100644 index 00000000000..98ecf053cf9 Binary files /dev/null and b/public/images/emoji/emoji_one/flag_cn.png differ diff --git a/public/images/emoji/emoji_one/flag_de.png b/public/images/emoji/emoji_one/flag_de.png new file mode 100644 index 00000000000..3991db99bda Binary files /dev/null and b/public/images/emoji/emoji_one/flag_de.png differ diff --git a/public/images/emoji/emoji_one/flag_es.png b/public/images/emoji/emoji_one/flag_es.png new file mode 100644 index 00000000000..00a7ac17cb6 Binary files /dev/null and b/public/images/emoji/emoji_one/flag_es.png differ diff --git a/public/images/emoji/emoji_one/flag_fr.png b/public/images/emoji/emoji_one/flag_fr.png new file mode 100644 index 00000000000..58ae8bb0ce1 Binary files /dev/null and b/public/images/emoji/emoji_one/flag_fr.png differ diff --git a/public/images/emoji/emoji_one/flag_gb.png b/public/images/emoji/emoji_one/flag_gb.png new file mode 100644 index 00000000000..594fda36ae5 Binary files /dev/null and b/public/images/emoji/emoji_one/flag_gb.png differ diff --git a/public/images/emoji/emoji_one/flag_it.png b/public/images/emoji/emoji_one/flag_it.png new file mode 100644 index 00000000000..4f55dfdc767 Binary files /dev/null and b/public/images/emoji/emoji_one/flag_it.png differ diff --git a/public/images/emoji/emoji_one/flag_jp.png b/public/images/emoji/emoji_one/flag_jp.png new file mode 100644 index 00000000000..1860a8644e5 Binary files /dev/null and b/public/images/emoji/emoji_one/flag_jp.png differ diff --git a/public/images/emoji/emoji_one/flag_kr.png b/public/images/emoji/emoji_one/flag_kr.png new file mode 100644 index 00000000000..3dc0748e7f2 Binary files /dev/null and b/public/images/emoji/emoji_one/flag_kr.png differ diff --git a/public/images/emoji/emoji_one/flag_ru.png b/public/images/emoji/emoji_one/flag_ru.png new file mode 100644 index 00000000000..472ba846d84 Binary files /dev/null and b/public/images/emoji/emoji_one/flag_ru.png differ diff --git a/public/images/emoji/emoji_one/flag_us.png b/public/images/emoji/emoji_one/flag_us.png new file mode 100644 index 00000000000..4c41fbbaa6a Binary files /dev/null and b/public/images/emoji/emoji_one/flag_us.png differ diff --git a/public/images/emoji/emoji_one/flag_white.png b/public/images/emoji/emoji_one/flag_white.png new file mode 100644 index 00000000000..a6b355cf747 Binary files /dev/null and b/public/images/emoji/emoji_one/flag_white.png differ diff --git a/public/images/emoji/emoji_one/flags.png b/public/images/emoji/emoji_one/flags.png index a6bbd0ea3ca..2c664bad236 100644 Binary files a/public/images/emoji/emoji_one/flags.png and b/public/images/emoji/emoji_one/flags.png differ diff --git a/public/images/emoji/emoji_one/flashlight.png b/public/images/emoji/emoji_one/flashlight.png index 8c7781e9a9e..d96fceb5f43 100644 Binary files a/public/images/emoji/emoji_one/flashlight.png and b/public/images/emoji/emoji_one/flashlight.png differ diff --git a/public/images/emoji/emoji_one/fleur-de-lis.png b/public/images/emoji/emoji_one/fleur-de-lis.png new file mode 100644 index 00000000000..d802f1d5823 Binary files /dev/null and b/public/images/emoji/emoji_one/fleur-de-lis.png differ diff --git a/public/images/emoji/emoji_one/flipper.png b/public/images/emoji/emoji_one/flipper.png index 4dde4cc134e..958bca71b1a 100644 Binary files a/public/images/emoji/emoji_one/flipper.png and b/public/images/emoji/emoji_one/flipper.png differ diff --git a/public/images/emoji/emoji_one/floppy_disk.png b/public/images/emoji/emoji_one/floppy_disk.png index d0cab34ceee..af23e91a5e6 100644 Binary files a/public/images/emoji/emoji_one/floppy_disk.png and b/public/images/emoji/emoji_one/floppy_disk.png differ diff --git a/public/images/emoji/emoji_one/flower_playing_cards.png b/public/images/emoji/emoji_one/flower_playing_cards.png index 62a910aa5e2..196293da4b7 100644 Binary files a/public/images/emoji/emoji_one/flower_playing_cards.png and b/public/images/emoji/emoji_one/flower_playing_cards.png differ diff --git a/public/images/emoji/emoji_one/flushed.png b/public/images/emoji/emoji_one/flushed.png index 77487a9f593..96f62ece37c 100644 Binary files a/public/images/emoji/emoji_one/flushed.png and b/public/images/emoji/emoji_one/flushed.png differ diff --git a/public/images/emoji/emoji_one/fog.png b/public/images/emoji/emoji_one/fog.png new file mode 100644 index 00000000000..7bd54ed1ddc Binary files /dev/null and b/public/images/emoji/emoji_one/fog.png differ diff --git a/public/images/emoji/emoji_one/foggy.png b/public/images/emoji/emoji_one/foggy.png index 5686be4c1a1..b86073c48f9 100644 Binary files a/public/images/emoji/emoji_one/foggy.png and b/public/images/emoji/emoji_one/foggy.png differ diff --git a/public/images/emoji/emoji_one/football.png b/public/images/emoji/emoji_one/football.png index 77614589c74..b14feaaf4b6 100644 Binary files a/public/images/emoji/emoji_one/football.png and b/public/images/emoji/emoji_one/football.png differ diff --git a/public/images/emoji/emoji_one/footprints.png b/public/images/emoji/emoji_one/footprints.png index 95c26fc9dab..5d03a0b8523 100644 Binary files a/public/images/emoji/emoji_one/footprints.png and b/public/images/emoji/emoji_one/footprints.png differ diff --git a/public/images/emoji/emoji_one/fork_and_knife.png b/public/images/emoji/emoji_one/fork_and_knife.png index 35c29628819..5066255c5ec 100644 Binary files a/public/images/emoji/emoji_one/fork_and_knife.png and b/public/images/emoji/emoji_one/fork_and_knife.png differ diff --git a/public/images/emoji/emoji_one/fork_knife_plate.png b/public/images/emoji/emoji_one/fork_knife_plate.png new file mode 100644 index 00000000000..4174200d939 Binary files /dev/null and b/public/images/emoji/emoji_one/fork_knife_plate.png differ diff --git a/public/images/emoji/emoji_one/fountain.png b/public/images/emoji/emoji_one/fountain.png index 6c01c0c907a..cc52cb1d0cb 100644 Binary files a/public/images/emoji/emoji_one/fountain.png and b/public/images/emoji/emoji_one/fountain.png differ diff --git a/public/images/emoji/emoji_one/four.png b/public/images/emoji/emoji_one/four.png index 0dd89cae2fc..7aa4f7a1ea9 100644 Binary files a/public/images/emoji/emoji_one/four.png and b/public/images/emoji/emoji_one/four.png differ diff --git a/public/images/emoji/emoji_one/four_leaf_clover.png b/public/images/emoji/emoji_one/four_leaf_clover.png index 4e034da3079..81edbca1259 100644 Binary files a/public/images/emoji/emoji_one/four_leaf_clover.png and b/public/images/emoji/emoji_one/four_leaf_clover.png differ diff --git a/public/images/emoji/emoji_one/fr.png b/public/images/emoji/emoji_one/fr.png index 14271f059db..24383c46e14 100644 Binary files a/public/images/emoji/emoji_one/fr.png and b/public/images/emoji/emoji_one/fr.png differ diff --git a/public/images/emoji/emoji_one/frame_photo.png b/public/images/emoji/emoji_one/frame_photo.png new file mode 100644 index 00000000000..508116dfcb7 Binary files /dev/null and b/public/images/emoji/emoji_one/frame_photo.png differ diff --git a/public/images/emoji/emoji_one/free.png b/public/images/emoji/emoji_one/free.png index 2c1c8f3869f..61fbabd976c 100644 Binary files a/public/images/emoji/emoji_one/free.png and b/public/images/emoji/emoji_one/free.png differ diff --git a/public/images/emoji/emoji_one/fried_shrimp.png b/public/images/emoji/emoji_one/fried_shrimp.png index 30c165438a9..f0474211f70 100644 Binary files a/public/images/emoji/emoji_one/fried_shrimp.png and b/public/images/emoji/emoji_one/fried_shrimp.png differ diff --git a/public/images/emoji/emoji_one/fries.png b/public/images/emoji/emoji_one/fries.png index 0e9f1a2eb5c..528a5c3a5ae 100644 Binary files a/public/images/emoji/emoji_one/fries.png and b/public/images/emoji/emoji_one/fries.png differ diff --git a/public/images/emoji/emoji_one/frog.png b/public/images/emoji/emoji_one/frog.png index 726d0280b27..a3eaea3474a 100644 Binary files a/public/images/emoji/emoji_one/frog.png and b/public/images/emoji/emoji_one/frog.png differ diff --git a/public/images/emoji/emoji_one/frowning.png b/public/images/emoji/emoji_one/frowning.png index 15f09138480..562b248f496 100644 Binary files a/public/images/emoji/emoji_one/frowning.png and b/public/images/emoji/emoji_one/frowning.png differ diff --git a/public/images/emoji/emoji_one/frowning2.png b/public/images/emoji/emoji_one/frowning2.png new file mode 100644 index 00000000000..353b28360ea Binary files /dev/null and b/public/images/emoji/emoji_one/frowning2.png differ diff --git a/public/images/emoji/emoji_one/fuelpump.png b/public/images/emoji/emoji_one/fuelpump.png index 13be7153017..5281fde507b 100644 Binary files a/public/images/emoji/emoji_one/fuelpump.png and b/public/images/emoji/emoji_one/fuelpump.png differ diff --git a/public/images/emoji/emoji_one/full_moon.png b/public/images/emoji/emoji_one/full_moon.png index 649e7a9f0ba..9c439573b37 100644 Binary files a/public/images/emoji/emoji_one/full_moon.png and b/public/images/emoji/emoji_one/full_moon.png differ diff --git a/public/images/emoji/emoji_one/full_moon_with_face.png b/public/images/emoji/emoji_one/full_moon_with_face.png index adb3479d9c4..7b9f23024dd 100644 Binary files a/public/images/emoji/emoji_one/full_moon_with_face.png and b/public/images/emoji/emoji_one/full_moon_with_face.png differ diff --git a/public/images/emoji/emoji_one/game_die.png b/public/images/emoji/emoji_one/game_die.png index 7723d290b7d..547670e1eff 100644 Binary files a/public/images/emoji/emoji_one/game_die.png and b/public/images/emoji/emoji_one/game_die.png differ diff --git a/public/images/emoji/emoji_one/gb.png b/public/images/emoji/emoji_one/gb.png index 61c03f759fd..00843f11937 100644 Binary files a/public/images/emoji/emoji_one/gb.png and b/public/images/emoji/emoji_one/gb.png differ diff --git a/public/images/emoji/emoji_one/gear.png b/public/images/emoji/emoji_one/gear.png new file mode 100644 index 00000000000..fede124a4ae Binary files /dev/null and b/public/images/emoji/emoji_one/gear.png differ diff --git a/public/images/emoji/emoji_one/gem.png b/public/images/emoji/emoji_one/gem.png index a24a082a788..97fd9b1a175 100644 Binary files a/public/images/emoji/emoji_one/gem.png and b/public/images/emoji/emoji_one/gem.png differ diff --git a/public/images/emoji/emoji_one/gemini.png b/public/images/emoji/emoji_one/gemini.png index 9c53145caea..e58d5e28360 100644 Binary files a/public/images/emoji/emoji_one/gemini.png and b/public/images/emoji/emoji_one/gemini.png differ diff --git a/public/images/emoji/emoji_one/ghost.png b/public/images/emoji/emoji_one/ghost.png index 69839699278..b0833104f1e 100644 Binary files a/public/images/emoji/emoji_one/ghost.png and b/public/images/emoji/emoji_one/ghost.png differ diff --git a/public/images/emoji/emoji_one/gift.png b/public/images/emoji/emoji_one/gift.png index bde801b5593..4c699ff84cd 100644 Binary files a/public/images/emoji/emoji_one/gift.png and b/public/images/emoji/emoji_one/gift.png differ diff --git a/public/images/emoji/emoji_one/gift_heart.png b/public/images/emoji/emoji_one/gift_heart.png index eb0292da0ca..6158ba13625 100644 Binary files a/public/images/emoji/emoji_one/gift_heart.png and b/public/images/emoji/emoji_one/gift_heart.png differ diff --git a/public/images/emoji/emoji_one/girl.png b/public/images/emoji/emoji_one/girl.png index 987e5e057a1..854b8d0f5fc 100644 Binary files a/public/images/emoji/emoji_one/girl.png and b/public/images/emoji/emoji_one/girl.png differ diff --git a/public/images/emoji/emoji_one/globe_with_meridians.png b/public/images/emoji/emoji_one/globe_with_meridians.png index a7af2cb1c9b..bceb1572741 100644 Binary files a/public/images/emoji/emoji_one/globe_with_meridians.png and b/public/images/emoji/emoji_one/globe_with_meridians.png differ diff --git a/public/images/emoji/emoji_one/goat.png b/public/images/emoji/emoji_one/goat.png index 41210e5fae9..17cf4360c20 100644 Binary files a/public/images/emoji/emoji_one/goat.png and b/public/images/emoji/emoji_one/goat.png differ diff --git a/public/images/emoji/emoji_one/golf.png b/public/images/emoji/emoji_one/golf.png index c03f8091749..a462edbc8d7 100644 Binary files a/public/images/emoji/emoji_one/golf.png and b/public/images/emoji/emoji_one/golf.png differ diff --git a/public/images/emoji/emoji_one/golfer.png b/public/images/emoji/emoji_one/golfer.png new file mode 100644 index 00000000000..54d2c8aa87a Binary files /dev/null and b/public/images/emoji/emoji_one/golfer.png differ diff --git a/public/images/emoji/emoji_one/grapes.png b/public/images/emoji/emoji_one/grapes.png index 20b09713195..99016bb91ce 100644 Binary files a/public/images/emoji/emoji_one/grapes.png and b/public/images/emoji/emoji_one/grapes.png differ diff --git a/public/images/emoji/emoji_one/green_apple.png b/public/images/emoji/emoji_one/green_apple.png index e3751477310..6cbfc2d9bbd 100644 Binary files a/public/images/emoji/emoji_one/green_apple.png and b/public/images/emoji/emoji_one/green_apple.png differ diff --git a/public/images/emoji/emoji_one/green_book.png b/public/images/emoji/emoji_one/green_book.png index e5e0a6b31e2..10c4daa002b 100644 Binary files a/public/images/emoji/emoji_one/green_book.png and b/public/images/emoji/emoji_one/green_book.png differ diff --git a/public/images/emoji/emoji_one/green_heart.png b/public/images/emoji/emoji_one/green_heart.png index 7735a394233..13d38ed2927 100644 Binary files a/public/images/emoji/emoji_one/green_heart.png and b/public/images/emoji/emoji_one/green_heart.png differ diff --git a/public/images/emoji/emoji_one/grey_exclamation.png b/public/images/emoji/emoji_one/grey_exclamation.png index bed5d887d76..1009d2f5a8f 100644 Binary files a/public/images/emoji/emoji_one/grey_exclamation.png and b/public/images/emoji/emoji_one/grey_exclamation.png differ diff --git a/public/images/emoji/emoji_one/grey_question.png b/public/images/emoji/emoji_one/grey_question.png index f4884404f0f..87b9820fd10 100644 Binary files a/public/images/emoji/emoji_one/grey_question.png and b/public/images/emoji/emoji_one/grey_question.png differ diff --git a/public/images/emoji/emoji_one/grimacing.png b/public/images/emoji/emoji_one/grimacing.png index 7b2944ec2af..f065c6ee8c4 100644 Binary files a/public/images/emoji/emoji_one/grimacing.png and b/public/images/emoji/emoji_one/grimacing.png differ diff --git a/public/images/emoji/emoji_one/grin.png b/public/images/emoji/emoji_one/grin.png index d7e7bd7206b..6754a578824 100644 Binary files a/public/images/emoji/emoji_one/grin.png and b/public/images/emoji/emoji_one/grin.png differ diff --git a/public/images/emoji/emoji_one/grinning.png b/public/images/emoji/emoji_one/grinning.png index 70aba64425d..1b2a11800ce 100644 Binary files a/public/images/emoji/emoji_one/grinning.png and b/public/images/emoji/emoji_one/grinning.png differ diff --git a/public/images/emoji/emoji_one/guardsman.png b/public/images/emoji/emoji_one/guardsman.png index 766ee30fa5e..25d701a65fb 100644 Binary files a/public/images/emoji/emoji_one/guardsman.png and b/public/images/emoji/emoji_one/guardsman.png differ diff --git a/public/images/emoji/emoji_one/guitar.png b/public/images/emoji/emoji_one/guitar.png index ab62a7fbb77..70e1539da4c 100644 Binary files a/public/images/emoji/emoji_one/guitar.png and b/public/images/emoji/emoji_one/guitar.png differ diff --git a/public/images/emoji/emoji_one/gun.png b/public/images/emoji/emoji_one/gun.png index f0e6b8fab77..931c803c676 100644 Binary files a/public/images/emoji/emoji_one/gun.png and b/public/images/emoji/emoji_one/gun.png differ diff --git a/public/images/emoji/emoji_one/haircut.png b/public/images/emoji/emoji_one/haircut.png index 191c5036b16..1671e1ae5ea 100644 Binary files a/public/images/emoji/emoji_one/haircut.png and b/public/images/emoji/emoji_one/haircut.png differ diff --git a/public/images/emoji/emoji_one/hamburger.png b/public/images/emoji/emoji_one/hamburger.png index b18121930cc..dbd7afe87b5 100644 Binary files a/public/images/emoji/emoji_one/hamburger.png and b/public/images/emoji/emoji_one/hamburger.png differ diff --git a/public/images/emoji/emoji_one/hammer.png b/public/images/emoji/emoji_one/hammer.png index 6011c3a7cfd..e5548f80a19 100644 Binary files a/public/images/emoji/emoji_one/hammer.png and b/public/images/emoji/emoji_one/hammer.png differ diff --git a/public/images/emoji/emoji_one/hammer_pick.png b/public/images/emoji/emoji_one/hammer_pick.png new file mode 100644 index 00000000000..3b7bb9dbe03 Binary files /dev/null and b/public/images/emoji/emoji_one/hammer_pick.png differ diff --git a/public/images/emoji/emoji_one/hamster.png b/public/images/emoji/emoji_one/hamster.png index b19be373845..5b901a64e0b 100644 Binary files a/public/images/emoji/emoji_one/hamster.png and b/public/images/emoji/emoji_one/hamster.png differ diff --git a/public/images/emoji/emoji_one/hand.png b/public/images/emoji/emoji_one/hand.png index 4f1fce256e0..0b0a75fa597 100644 Binary files a/public/images/emoji/emoji_one/hand.png and b/public/images/emoji/emoji_one/hand.png differ diff --git a/public/images/emoji/emoji_one/hand_splayed.png b/public/images/emoji/emoji_one/hand_splayed.png new file mode 100644 index 00000000000..c08b63bf043 Binary files /dev/null and b/public/images/emoji/emoji_one/hand_splayed.png differ diff --git a/public/images/emoji/emoji_one/handbag.png b/public/images/emoji/emoji_one/handbag.png index 5566887879c..f89f5a97750 100644 Binary files a/public/images/emoji/emoji_one/handbag.png and b/public/images/emoji/emoji_one/handbag.png differ diff --git a/public/images/emoji/emoji_one/hankey.png b/public/images/emoji/emoji_one/hankey.png index 0c237a78811..999b3d7d5f8 100644 Binary files a/public/images/emoji/emoji_one/hankey.png and b/public/images/emoji/emoji_one/hankey.png differ diff --git a/public/images/emoji/emoji_one/hash.png b/public/images/emoji/emoji_one/hash.png index 46d5f7d87a4..83073fc4525 100644 Binary files a/public/images/emoji/emoji_one/hash.png and b/public/images/emoji/emoji_one/hash.png differ diff --git a/public/images/emoji/emoji_one/hatched_chick.png b/public/images/emoji/emoji_one/hatched_chick.png index de82199dcfe..3f4097c9375 100644 Binary files a/public/images/emoji/emoji_one/hatched_chick.png and b/public/images/emoji/emoji_one/hatched_chick.png differ diff --git a/public/images/emoji/emoji_one/hatching_chick.png b/public/images/emoji/emoji_one/hatching_chick.png index 1e688c22840..26970da8490 100644 Binary files a/public/images/emoji/emoji_one/hatching_chick.png and b/public/images/emoji/emoji_one/hatching_chick.png differ diff --git a/public/images/emoji/emoji_one/head_bandage.png b/public/images/emoji/emoji_one/head_bandage.png new file mode 100644 index 00000000000..b249b127681 Binary files /dev/null and b/public/images/emoji/emoji_one/head_bandage.png differ diff --git a/public/images/emoji/emoji_one/headphones.png b/public/images/emoji/emoji_one/headphones.png index 3335d406008..f3f8a917fa1 100644 Binary files a/public/images/emoji/emoji_one/headphones.png and b/public/images/emoji/emoji_one/headphones.png differ diff --git a/public/images/emoji/emoji_one/hear_no_evil.png b/public/images/emoji/emoji_one/hear_no_evil.png index e909ebf246c..1ca16a4f53c 100644 Binary files a/public/images/emoji/emoji_one/hear_no_evil.png and b/public/images/emoji/emoji_one/hear_no_evil.png differ diff --git a/public/images/emoji/emoji_one/heart.png b/public/images/emoji/emoji_one/heart.png index 5890add644f..df67f254095 100644 Binary files a/public/images/emoji/emoji_one/heart.png and b/public/images/emoji/emoji_one/heart.png differ diff --git a/public/images/emoji/emoji_one/heart_decoration.png b/public/images/emoji/emoji_one/heart_decoration.png index 37c7c6f1846..e854b44ae60 100644 Binary files a/public/images/emoji/emoji_one/heart_decoration.png and b/public/images/emoji/emoji_one/heart_decoration.png differ diff --git a/public/images/emoji/emoji_one/heart_exclamation.png b/public/images/emoji/emoji_one/heart_exclamation.png new file mode 100644 index 00000000000..be54295cc85 Binary files /dev/null and b/public/images/emoji/emoji_one/heart_exclamation.png differ diff --git a/public/images/emoji/emoji_one/heart_eyes.png b/public/images/emoji/emoji_one/heart_eyes.png index 56aa60e8df3..16ebb628d89 100644 Binary files a/public/images/emoji/emoji_one/heart_eyes.png and b/public/images/emoji/emoji_one/heart_eyes.png differ diff --git a/public/images/emoji/emoji_one/heart_eyes_cat.png b/public/images/emoji/emoji_one/heart_eyes_cat.png index 7bdd5964175..59c46ffb2ee 100644 Binary files a/public/images/emoji/emoji_one/heart_eyes_cat.png and b/public/images/emoji/emoji_one/heart_eyes_cat.png differ diff --git a/public/images/emoji/emoji_one/heartbeat.png b/public/images/emoji/emoji_one/heartbeat.png index 43a365e95f0..226dc0b5589 100644 Binary files a/public/images/emoji/emoji_one/heartbeat.png and b/public/images/emoji/emoji_one/heartbeat.png differ diff --git a/public/images/emoji/emoji_one/heartpulse.png b/public/images/emoji/emoji_one/heartpulse.png index b3d5da2e39c..50436c5cb11 100644 Binary files a/public/images/emoji/emoji_one/heartpulse.png and b/public/images/emoji/emoji_one/heartpulse.png differ diff --git a/public/images/emoji/emoji_one/hearts.png b/public/images/emoji/emoji_one/hearts.png index f8615483536..32e2bfad06e 100644 Binary files a/public/images/emoji/emoji_one/hearts.png and b/public/images/emoji/emoji_one/hearts.png differ diff --git a/public/images/emoji/emoji_one/heavy_check_mark.png b/public/images/emoji/emoji_one/heavy_check_mark.png index ad0bb06c011..8479116e7fb 100644 Binary files a/public/images/emoji/emoji_one/heavy_check_mark.png and b/public/images/emoji/emoji_one/heavy_check_mark.png differ diff --git a/public/images/emoji/emoji_one/heavy_division_sign.png b/public/images/emoji/emoji_one/heavy_division_sign.png index 56b457e61b9..3d5307a0312 100644 Binary files a/public/images/emoji/emoji_one/heavy_division_sign.png and b/public/images/emoji/emoji_one/heavy_division_sign.png differ diff --git a/public/images/emoji/emoji_one/heavy_dollar_sign.png b/public/images/emoji/emoji_one/heavy_dollar_sign.png index 4bad879bd9d..ddd8e02b21d 100644 Binary files a/public/images/emoji/emoji_one/heavy_dollar_sign.png and b/public/images/emoji/emoji_one/heavy_dollar_sign.png differ diff --git a/public/images/emoji/emoji_one/heavy_exclamation_mark.png b/public/images/emoji/emoji_one/heavy_exclamation_mark.png index 6f9147ac0d8..fb1fc289a22 100644 Binary files a/public/images/emoji/emoji_one/heavy_exclamation_mark.png and b/public/images/emoji/emoji_one/heavy_exclamation_mark.png differ diff --git a/public/images/emoji/emoji_one/heavy_minus_sign.png b/public/images/emoji/emoji_one/heavy_minus_sign.png index 6a930366a71..2933e7925f7 100644 Binary files a/public/images/emoji/emoji_one/heavy_minus_sign.png and b/public/images/emoji/emoji_one/heavy_minus_sign.png differ diff --git a/public/images/emoji/emoji_one/heavy_multiplication_x.png b/public/images/emoji/emoji_one/heavy_multiplication_x.png index 89792472502..445ab328a35 100644 Binary files a/public/images/emoji/emoji_one/heavy_multiplication_x.png and b/public/images/emoji/emoji_one/heavy_multiplication_x.png differ diff --git a/public/images/emoji/emoji_one/heavy_plus_sign.png b/public/images/emoji/emoji_one/heavy_plus_sign.png index 4c55cd9dca5..c6ca170d4b9 100644 Binary files a/public/images/emoji/emoji_one/heavy_plus_sign.png and b/public/images/emoji/emoji_one/heavy_plus_sign.png differ diff --git a/public/images/emoji/emoji_one/helicopter.png b/public/images/emoji/emoji_one/helicopter.png index 838acddc743..72088fb73ec 100644 Binary files a/public/images/emoji/emoji_one/helicopter.png and b/public/images/emoji/emoji_one/helicopter.png differ diff --git a/public/images/emoji/emoji_one/helmet_with_cross.png b/public/images/emoji/emoji_one/helmet_with_cross.png new file mode 100644 index 00000000000..22efa363c90 Binary files /dev/null and b/public/images/emoji/emoji_one/helmet_with_cross.png differ diff --git a/public/images/emoji/emoji_one/herb.png b/public/images/emoji/emoji_one/herb.png index cb5f8f73533..c8f8b00a4ef 100644 Binary files a/public/images/emoji/emoji_one/herb.png and b/public/images/emoji/emoji_one/herb.png differ diff --git a/public/images/emoji/emoji_one/hibiscus.png b/public/images/emoji/emoji_one/hibiscus.png index e0fd12c95d0..3b24cc224a9 100644 Binary files a/public/images/emoji/emoji_one/hibiscus.png and b/public/images/emoji/emoji_one/hibiscus.png differ diff --git a/public/images/emoji/emoji_one/high_brightness.png b/public/images/emoji/emoji_one/high_brightness.png index 7fd0d11c6ab..3f53e04a034 100644 Binary files a/public/images/emoji/emoji_one/high_brightness.png and b/public/images/emoji/emoji_one/high_brightness.png differ diff --git a/public/images/emoji/emoji_one/high_heel.png b/public/images/emoji/emoji_one/high_heel.png index 36bdb748413..be02404512b 100644 Binary files a/public/images/emoji/emoji_one/high_heel.png and b/public/images/emoji/emoji_one/high_heel.png differ diff --git a/public/images/emoji/emoji_one/hocho.png b/public/images/emoji/emoji_one/hocho.png index 43249ba9427..21146711dad 100644 Binary files a/public/images/emoji/emoji_one/hocho.png and b/public/images/emoji/emoji_one/hocho.png differ diff --git a/public/images/emoji/emoji_one/hockey.png b/public/images/emoji/emoji_one/hockey.png new file mode 100644 index 00000000000..464a11003ae Binary files /dev/null and b/public/images/emoji/emoji_one/hockey.png differ diff --git a/public/images/emoji/emoji_one/hole.png b/public/images/emoji/emoji_one/hole.png new file mode 100644 index 00000000000..19e228f6622 Binary files /dev/null and b/public/images/emoji/emoji_one/hole.png differ diff --git a/public/images/emoji/emoji_one/homes.png b/public/images/emoji/emoji_one/homes.png new file mode 100644 index 00000000000..77fd2f37f17 Binary files /dev/null and b/public/images/emoji/emoji_one/homes.png differ diff --git a/public/images/emoji/emoji_one/honey_pot.png b/public/images/emoji/emoji_one/honey_pot.png index a563f59c7c1..2221d41d1b8 100644 Binary files a/public/images/emoji/emoji_one/honey_pot.png and b/public/images/emoji/emoji_one/honey_pot.png differ diff --git a/public/images/emoji/emoji_one/honeybee.png b/public/images/emoji/emoji_one/honeybee.png index e67b7703bff..a8c24255847 100644 Binary files a/public/images/emoji/emoji_one/honeybee.png and b/public/images/emoji/emoji_one/honeybee.png differ diff --git a/public/images/emoji/emoji_one/horse.png b/public/images/emoji/emoji_one/horse.png index 90b95550647..c4f1d85c10d 100644 Binary files a/public/images/emoji/emoji_one/horse.png and b/public/images/emoji/emoji_one/horse.png differ diff --git a/public/images/emoji/emoji_one/horse_racing.png b/public/images/emoji/emoji_one/horse_racing.png index 57133e8b7a1..15a22ec6a0a 100644 Binary files a/public/images/emoji/emoji_one/horse_racing.png and b/public/images/emoji/emoji_one/horse_racing.png differ diff --git a/public/images/emoji/emoji_one/hospital.png b/public/images/emoji/emoji_one/hospital.png index 80f87bfbe0a..7f9476f7a5d 100644 Binary files a/public/images/emoji/emoji_one/hospital.png and b/public/images/emoji/emoji_one/hospital.png differ diff --git a/public/images/emoji/emoji_one/hot_pepper.png b/public/images/emoji/emoji_one/hot_pepper.png new file mode 100644 index 00000000000..e8c0fa86218 Binary files /dev/null and b/public/images/emoji/emoji_one/hot_pepper.png differ diff --git a/public/images/emoji/emoji_one/hotdog.png b/public/images/emoji/emoji_one/hotdog.png new file mode 100644 index 00000000000..224b69ae2f4 Binary files /dev/null and b/public/images/emoji/emoji_one/hotdog.png differ diff --git a/public/images/emoji/emoji_one/hotel.png b/public/images/emoji/emoji_one/hotel.png index 121b93b0fb8..7cdde04bb71 100644 Binary files a/public/images/emoji/emoji_one/hotel.png and b/public/images/emoji/emoji_one/hotel.png differ diff --git a/public/images/emoji/emoji_one/hotsprings.png b/public/images/emoji/emoji_one/hotsprings.png index dbe158292b5..ed441994505 100644 Binary files a/public/images/emoji/emoji_one/hotsprings.png and b/public/images/emoji/emoji_one/hotsprings.png differ diff --git a/public/images/emoji/emoji_one/hourglass.png b/public/images/emoji/emoji_one/hourglass.png index 06799f8c51e..c2a68fe2f2e 100644 Binary files a/public/images/emoji/emoji_one/hourglass.png and b/public/images/emoji/emoji_one/hourglass.png differ diff --git a/public/images/emoji/emoji_one/hourglass_flowing_sand.png b/public/images/emoji/emoji_one/hourglass_flowing_sand.png index bb0bbd8f706..93aa680bcee 100644 Binary files a/public/images/emoji/emoji_one/hourglass_flowing_sand.png and b/public/images/emoji/emoji_one/hourglass_flowing_sand.png differ diff --git a/public/images/emoji/emoji_one/house.png b/public/images/emoji/emoji_one/house.png index 90551d82350..b3ddbf23732 100644 Binary files a/public/images/emoji/emoji_one/house.png and b/public/images/emoji/emoji_one/house.png differ diff --git a/public/images/emoji/emoji_one/house_abandoned.png b/public/images/emoji/emoji_one/house_abandoned.png new file mode 100644 index 00000000000..0a10ee267e1 Binary files /dev/null and b/public/images/emoji/emoji_one/house_abandoned.png differ diff --git a/public/images/emoji/emoji_one/house_with_garden.png b/public/images/emoji/emoji_one/house_with_garden.png index b00186c463b..b69fc807005 100644 Binary files a/public/images/emoji/emoji_one/house_with_garden.png and b/public/images/emoji/emoji_one/house_with_garden.png differ diff --git a/public/images/emoji/emoji_one/hugging.png b/public/images/emoji/emoji_one/hugging.png new file mode 100644 index 00000000000..d1a7725abf3 Binary files /dev/null and b/public/images/emoji/emoji_one/hugging.png differ diff --git a/public/images/emoji/emoji_one/hushed.png b/public/images/emoji/emoji_one/hushed.png index e1a2b43ec91..90efd61b74b 100644 Binary files a/public/images/emoji/emoji_one/hushed.png and b/public/images/emoji/emoji_one/hushed.png differ diff --git a/public/images/emoji/emoji_one/ice_cream.png b/public/images/emoji/emoji_one/ice_cream.png index ffcad18b4ec..26d02f73beb 100644 Binary files a/public/images/emoji/emoji_one/ice_cream.png and b/public/images/emoji/emoji_one/ice_cream.png differ diff --git a/public/images/emoji/emoji_one/ice_skate.png b/public/images/emoji/emoji_one/ice_skate.png new file mode 100644 index 00000000000..40e307241ad Binary files /dev/null and b/public/images/emoji/emoji_one/ice_skate.png differ diff --git a/public/images/emoji/emoji_one/icecream.png b/public/images/emoji/emoji_one/icecream.png index 39c2e6a8f95..d79853fea93 100644 Binary files a/public/images/emoji/emoji_one/icecream.png and b/public/images/emoji/emoji_one/icecream.png differ diff --git a/public/images/emoji/emoji_one/id.png b/public/images/emoji/emoji_one/id.png index 470686fec1e..8ab3f9a1184 100644 Binary files a/public/images/emoji/emoji_one/id.png and b/public/images/emoji/emoji_one/id.png differ diff --git a/public/images/emoji/emoji_one/ideograph_advantage.png b/public/images/emoji/emoji_one/ideograph_advantage.png index 8df529c4aeb..8dcbdc71068 100644 Binary files a/public/images/emoji/emoji_one/ideograph_advantage.png and b/public/images/emoji/emoji_one/ideograph_advantage.png differ diff --git a/public/images/emoji/emoji_one/imp.png b/public/images/emoji/emoji_one/imp.png index f5e6059dab1..5fe256d2837 100644 Binary files a/public/images/emoji/emoji_one/imp.png and b/public/images/emoji/emoji_one/imp.png differ diff --git a/public/images/emoji/emoji_one/inbox_tray.png b/public/images/emoji/emoji_one/inbox_tray.png index 89073464d58..1a28192a2b5 100644 Binary files a/public/images/emoji/emoji_one/inbox_tray.png and b/public/images/emoji/emoji_one/inbox_tray.png differ diff --git a/public/images/emoji/emoji_one/incoming_envelope.png b/public/images/emoji/emoji_one/incoming_envelope.png index 346421eccac..0b7be37d556 100644 Binary files a/public/images/emoji/emoji_one/incoming_envelope.png and b/public/images/emoji/emoji_one/incoming_envelope.png differ diff --git a/public/images/emoji/emoji_one/information_desk_person.png b/public/images/emoji/emoji_one/information_desk_person.png index 13d1ed00534..c074b7b8ee6 100644 Binary files a/public/images/emoji/emoji_one/information_desk_person.png and b/public/images/emoji/emoji_one/information_desk_person.png differ diff --git a/public/images/emoji/emoji_one/information_source.png b/public/images/emoji/emoji_one/information_source.png index 2db63c3548c..3ce9e5d6799 100644 Binary files a/public/images/emoji/emoji_one/information_source.png and b/public/images/emoji/emoji_one/information_source.png differ diff --git a/public/images/emoji/emoji_one/innocent.png b/public/images/emoji/emoji_one/innocent.png index 1633f48d360..96e28562755 100644 Binary files a/public/images/emoji/emoji_one/innocent.png and b/public/images/emoji/emoji_one/innocent.png differ diff --git a/public/images/emoji/emoji_one/interrobang.png b/public/images/emoji/emoji_one/interrobang.png index 2d182dec7ea..21a7abb5cb2 100644 Binary files a/public/images/emoji/emoji_one/interrobang.png and b/public/images/emoji/emoji_one/interrobang.png differ diff --git a/public/images/emoji/emoji_one/iphone.png b/public/images/emoji/emoji_one/iphone.png index eea83475b24..e3ed839b0d6 100644 Binary files a/public/images/emoji/emoji_one/iphone.png and b/public/images/emoji/emoji_one/iphone.png differ diff --git a/public/images/emoji/emoji_one/island.png b/public/images/emoji/emoji_one/island.png new file mode 100644 index 00000000000..bbb88f6e265 Binary files /dev/null and b/public/images/emoji/emoji_one/island.png differ diff --git a/public/images/emoji/emoji_one/izakaya_lantern.png b/public/images/emoji/emoji_one/izakaya_lantern.png index acdca08909e..e9e2fbcbcca 100644 Binary files a/public/images/emoji/emoji_one/izakaya_lantern.png and b/public/images/emoji/emoji_one/izakaya_lantern.png differ diff --git a/public/images/emoji/emoji_one/jack_o_lantern.png b/public/images/emoji/emoji_one/jack_o_lantern.png index 6471e1d824d..1ba654df21a 100644 Binary files a/public/images/emoji/emoji_one/jack_o_lantern.png and b/public/images/emoji/emoji_one/jack_o_lantern.png differ diff --git a/public/images/emoji/emoji_one/japan.png b/public/images/emoji/emoji_one/japan.png index 3e21b14db39..975a9f91425 100644 Binary files a/public/images/emoji/emoji_one/japan.png and b/public/images/emoji/emoji_one/japan.png differ diff --git a/public/images/emoji/emoji_one/japanese_castle.png b/public/images/emoji/emoji_one/japanese_castle.png index e01ba40adf5..0819dd1cca8 100644 Binary files a/public/images/emoji/emoji_one/japanese_castle.png and b/public/images/emoji/emoji_one/japanese_castle.png differ diff --git a/public/images/emoji/emoji_one/japanese_goblin.png b/public/images/emoji/emoji_one/japanese_goblin.png index 20e1b4eb541..be990d82a6a 100644 Binary files a/public/images/emoji/emoji_one/japanese_goblin.png and b/public/images/emoji/emoji_one/japanese_goblin.png differ diff --git a/public/images/emoji/emoji_one/japanese_ogre.png b/public/images/emoji/emoji_one/japanese_ogre.png index fd1cab65f84..0a0219f4778 100644 Binary files a/public/images/emoji/emoji_one/japanese_ogre.png and b/public/images/emoji/emoji_one/japanese_ogre.png differ diff --git a/public/images/emoji/emoji_one/jeans.png b/public/images/emoji/emoji_one/jeans.png index 713ccbcecf9..ff89c906ae0 100644 Binary files a/public/images/emoji/emoji_one/jeans.png and b/public/images/emoji/emoji_one/jeans.png differ diff --git a/public/images/emoji/emoji_one/joy.png b/public/images/emoji/emoji_one/joy.png index eef42396a86..b42c03d8924 100644 Binary files a/public/images/emoji/emoji_one/joy.png and b/public/images/emoji/emoji_one/joy.png differ diff --git a/public/images/emoji/emoji_one/joy_cat.png b/public/images/emoji/emoji_one/joy_cat.png index a9ec1862507..30556e85929 100644 Binary files a/public/images/emoji/emoji_one/joy_cat.png and b/public/images/emoji/emoji_one/joy_cat.png differ diff --git a/public/images/emoji/emoji_one/joystick.png b/public/images/emoji/emoji_one/joystick.png new file mode 100644 index 00000000000..3d2e5b8f430 Binary files /dev/null and b/public/images/emoji/emoji_one/joystick.png differ diff --git a/public/images/emoji/emoji_one/jp.png b/public/images/emoji/emoji_one/jp.png index 5f779898b28..d1ac231dff3 100644 Binary files a/public/images/emoji/emoji_one/jp.png and b/public/images/emoji/emoji_one/jp.png differ diff --git a/public/images/emoji/emoji_one/kaaba.png b/public/images/emoji/emoji_one/kaaba.png new file mode 100644 index 00000000000..47ee22a82bb Binary files /dev/null and b/public/images/emoji/emoji_one/kaaba.png differ diff --git a/public/images/emoji/emoji_one/key.png b/public/images/emoji/emoji_one/key.png index d5182ccff1f..128f23e5b9b 100644 Binary files a/public/images/emoji/emoji_one/key.png and b/public/images/emoji/emoji_one/key.png differ diff --git a/public/images/emoji/emoji_one/key2.png b/public/images/emoji/emoji_one/key2.png new file mode 100644 index 00000000000..7dc9ba58e45 Binary files /dev/null and b/public/images/emoji/emoji_one/key2.png differ diff --git a/public/images/emoji/emoji_one/keyboard.png b/public/images/emoji/emoji_one/keyboard.png new file mode 100644 index 00000000000..38ac5cb3f5d Binary files /dev/null and b/public/images/emoji/emoji_one/keyboard.png differ diff --git a/public/images/emoji/emoji_one/keycap_ten.png b/public/images/emoji/emoji_one/keycap_ten.png index 7caf26665a6..4399ced42f8 100644 Binary files a/public/images/emoji/emoji_one/keycap_ten.png and b/public/images/emoji/emoji_one/keycap_ten.png differ diff --git a/public/images/emoji/emoji_one/kimono.png b/public/images/emoji/emoji_one/kimono.png index 1cbdea0b17d..02114ffa3a0 100644 Binary files a/public/images/emoji/emoji_one/kimono.png and b/public/images/emoji/emoji_one/kimono.png differ diff --git a/public/images/emoji/emoji_one/kiss.png b/public/images/emoji/emoji_one/kiss.png index bc4c8f73a31..3d58129ab4a 100644 Binary files a/public/images/emoji/emoji_one/kiss.png and b/public/images/emoji/emoji_one/kiss.png differ diff --git a/public/images/emoji/emoji_one/kissing.png b/public/images/emoji/emoji_one/kissing.png index beae104a699..6314d4c4f4c 100644 Binary files a/public/images/emoji/emoji_one/kissing.png and b/public/images/emoji/emoji_one/kissing.png differ diff --git a/public/images/emoji/emoji_one/kissing_cat.png b/public/images/emoji/emoji_one/kissing_cat.png index 3a58d5cfa72..6aaf8af8be1 100644 Binary files a/public/images/emoji/emoji_one/kissing_cat.png and b/public/images/emoji/emoji_one/kissing_cat.png differ diff --git a/public/images/emoji/emoji_one/kissing_closed_eyes.png b/public/images/emoji/emoji_one/kissing_closed_eyes.png index d27a678e7a3..4f9378b66f5 100644 Binary files a/public/images/emoji/emoji_one/kissing_closed_eyes.png and b/public/images/emoji/emoji_one/kissing_closed_eyes.png differ diff --git a/public/images/emoji/emoji_one/kissing_heart.png b/public/images/emoji/emoji_one/kissing_heart.png index e4ca8e05d0c..891aaf1731e 100644 Binary files a/public/images/emoji/emoji_one/kissing_heart.png and b/public/images/emoji/emoji_one/kissing_heart.png differ diff --git a/public/images/emoji/emoji_one/kissing_smiling_eyes.png b/public/images/emoji/emoji_one/kissing_smiling_eyes.png index 732671be63d..aa76ccd2f36 100644 Binary files a/public/images/emoji/emoji_one/kissing_smiling_eyes.png and b/public/images/emoji/emoji_one/kissing_smiling_eyes.png differ diff --git a/public/images/emoji/emoji_one/knife.png b/public/images/emoji/emoji_one/knife.png index 43249ba9427..7c1f1419e96 100644 Binary files a/public/images/emoji/emoji_one/knife.png and b/public/images/emoji/emoji_one/knife.png differ diff --git a/public/images/emoji/emoji_one/koala.png b/public/images/emoji/emoji_one/koala.png index 92814390555..4ea4ac1cbd8 100644 Binary files a/public/images/emoji/emoji_one/koala.png and b/public/images/emoji/emoji_one/koala.png differ diff --git a/public/images/emoji/emoji_one/koko.png b/public/images/emoji/emoji_one/koko.png index c95a69a620c..cdad31907f6 100644 Binary files a/public/images/emoji/emoji_one/koko.png and b/public/images/emoji/emoji_one/koko.png differ diff --git a/public/images/emoji/emoji_one/kr.png b/public/images/emoji/emoji_one/kr.png index f4f14acc0f3..538cfae7b6b 100644 Binary files a/public/images/emoji/emoji_one/kr.png and b/public/images/emoji/emoji_one/kr.png differ diff --git a/public/images/emoji/emoji_one/label.png b/public/images/emoji/emoji_one/label.png new file mode 100644 index 00000000000..16efa7a6f58 Binary files /dev/null and b/public/images/emoji/emoji_one/label.png differ diff --git a/public/images/emoji/emoji_one/lantern.png b/public/images/emoji/emoji_one/lantern.png index acdca08909e..85126b8bd9d 100644 Binary files a/public/images/emoji/emoji_one/lantern.png and b/public/images/emoji/emoji_one/lantern.png differ diff --git a/public/images/emoji/emoji_one/large_blue_circle.png b/public/images/emoji/emoji_one/large_blue_circle.png index ea80b06cb2c..4188a1b1f8a 100644 Binary files a/public/images/emoji/emoji_one/large_blue_circle.png and b/public/images/emoji/emoji_one/large_blue_circle.png differ diff --git a/public/images/emoji/emoji_one/large_blue_diamond.png b/public/images/emoji/emoji_one/large_blue_diamond.png index 266529e075a..ee5282afb79 100644 Binary files a/public/images/emoji/emoji_one/large_blue_diamond.png and b/public/images/emoji/emoji_one/large_blue_diamond.png differ diff --git a/public/images/emoji/emoji_one/large_orange_diamond.png b/public/images/emoji/emoji_one/large_orange_diamond.png index b7d46226f6d..f666b6eefc8 100644 Binary files a/public/images/emoji/emoji_one/large_orange_diamond.png and b/public/images/emoji/emoji_one/large_orange_diamond.png differ diff --git a/public/images/emoji/emoji_one/last_quarter_moon.png b/public/images/emoji/emoji_one/last_quarter_moon.png index 85e0df65a80..8db5dc4dec2 100644 Binary files a/public/images/emoji/emoji_one/last_quarter_moon.png and b/public/images/emoji/emoji_one/last_quarter_moon.png differ diff --git a/public/images/emoji/emoji_one/last_quarter_moon_with_face.png b/public/images/emoji/emoji_one/last_quarter_moon_with_face.png index 37ecabbc7dc..fa73fb68f93 100644 Binary files a/public/images/emoji/emoji_one/last_quarter_moon_with_face.png and b/public/images/emoji/emoji_one/last_quarter_moon_with_face.png differ diff --git a/public/images/emoji/emoji_one/laughing.png b/public/images/emoji/emoji_one/laughing.png index 06adb559cdf..3288d746eac 100644 Binary files a/public/images/emoji/emoji_one/laughing.png and b/public/images/emoji/emoji_one/laughing.png differ diff --git a/public/images/emoji/emoji_one/leaves.png b/public/images/emoji/emoji_one/leaves.png index 569a66fac22..a372191be5e 100644 Binary files a/public/images/emoji/emoji_one/leaves.png and b/public/images/emoji/emoji_one/leaves.png differ diff --git a/public/images/emoji/emoji_one/ledger.png b/public/images/emoji/emoji_one/ledger.png index 04e7930af20..2644074435d 100644 Binary files a/public/images/emoji/emoji_one/ledger.png and b/public/images/emoji/emoji_one/ledger.png differ diff --git a/public/images/emoji/emoji_one/left_luggage.png b/public/images/emoji/emoji_one/left_luggage.png index e8645bc2ea3..bc450cbe3f6 100644 Binary files a/public/images/emoji/emoji_one/left_luggage.png and b/public/images/emoji/emoji_one/left_luggage.png differ diff --git a/public/images/emoji/emoji_one/left_right_arrow.png b/public/images/emoji/emoji_one/left_right_arrow.png index 77a9e88d3cb..4c43289e13d 100644 Binary files a/public/images/emoji/emoji_one/left_right_arrow.png and b/public/images/emoji/emoji_one/left_right_arrow.png differ diff --git a/public/images/emoji/emoji_one/leftwards_arrow_with_hook.png b/public/images/emoji/emoji_one/leftwards_arrow_with_hook.png index f5fb9718a5d..f804641fb9d 100644 Binary files a/public/images/emoji/emoji_one/leftwards_arrow_with_hook.png and b/public/images/emoji/emoji_one/leftwards_arrow_with_hook.png differ diff --git a/public/images/emoji/emoji_one/lemon.png b/public/images/emoji/emoji_one/lemon.png index fa5e87b0302..e3157b9a073 100644 Binary files a/public/images/emoji/emoji_one/lemon.png and b/public/images/emoji/emoji_one/lemon.png differ diff --git a/public/images/emoji/emoji_one/leo.png b/public/images/emoji/emoji_one/leo.png index 8891081ff1b..d96d8c6aaa1 100644 Binary files a/public/images/emoji/emoji_one/leo.png and b/public/images/emoji/emoji_one/leo.png differ diff --git a/public/images/emoji/emoji_one/leopard.png b/public/images/emoji/emoji_one/leopard.png index eb16aa9c621..787051edb8f 100644 Binary files a/public/images/emoji/emoji_one/leopard.png and b/public/images/emoji/emoji_one/leopard.png differ diff --git a/public/images/emoji/emoji_one/level_slider.png b/public/images/emoji/emoji_one/level_slider.png new file mode 100644 index 00000000000..b436f729734 Binary files /dev/null and b/public/images/emoji/emoji_one/level_slider.png differ diff --git a/public/images/emoji/emoji_one/levitate.png b/public/images/emoji/emoji_one/levitate.png new file mode 100644 index 00000000000..7c2517d75a2 Binary files /dev/null and b/public/images/emoji/emoji_one/levitate.png differ diff --git a/public/images/emoji/emoji_one/libra.png b/public/images/emoji/emoji_one/libra.png index d601047945e..78cec1c1e5c 100644 Binary files a/public/images/emoji/emoji_one/libra.png and b/public/images/emoji/emoji_one/libra.png differ diff --git a/public/images/emoji/emoji_one/lifter.png b/public/images/emoji/emoji_one/lifter.png new file mode 100644 index 00000000000..3e52cf7e3ee Binary files /dev/null and b/public/images/emoji/emoji_one/lifter.png differ diff --git a/public/images/emoji/emoji_one/light_rail.png b/public/images/emoji/emoji_one/light_rail.png index 51bf05e278a..a4d79a404cb 100644 Binary files a/public/images/emoji/emoji_one/light_rail.png and b/public/images/emoji/emoji_one/light_rail.png differ diff --git a/public/images/emoji/emoji_one/link.png b/public/images/emoji/emoji_one/link.png index 0954f494a9a..ccb98b3075b 100644 Binary files a/public/images/emoji/emoji_one/link.png and b/public/images/emoji/emoji_one/link.png differ diff --git a/public/images/emoji/emoji_one/lion_face.png b/public/images/emoji/emoji_one/lion_face.png new file mode 100644 index 00000000000..fc03a057db1 Binary files /dev/null and b/public/images/emoji/emoji_one/lion_face.png differ diff --git a/public/images/emoji/emoji_one/lips.png b/public/images/emoji/emoji_one/lips.png index a106ccef785..0923d8323b7 100644 Binary files a/public/images/emoji/emoji_one/lips.png and b/public/images/emoji/emoji_one/lips.png differ diff --git a/public/images/emoji/emoji_one/lipstick.png b/public/images/emoji/emoji_one/lipstick.png index ddf0baad765..4f3f0d24a52 100644 Binary files a/public/images/emoji/emoji_one/lipstick.png and b/public/images/emoji/emoji_one/lipstick.png differ diff --git a/public/images/emoji/emoji_one/lock.png b/public/images/emoji/emoji_one/lock.png index 417050d0a88..649e0fa81bd 100644 Binary files a/public/images/emoji/emoji_one/lock.png and b/public/images/emoji/emoji_one/lock.png differ diff --git a/public/images/emoji/emoji_one/lock_with_ink_pen.png b/public/images/emoji/emoji_one/lock_with_ink_pen.png index 621fe24c2bd..209edafeb08 100644 Binary files a/public/images/emoji/emoji_one/lock_with_ink_pen.png and b/public/images/emoji/emoji_one/lock_with_ink_pen.png differ diff --git a/public/images/emoji/emoji_one/lollipop.png b/public/images/emoji/emoji_one/lollipop.png index 2c6a0ed4c3c..e744656ccb3 100644 Binary files a/public/images/emoji/emoji_one/lollipop.png and b/public/images/emoji/emoji_one/lollipop.png differ diff --git a/public/images/emoji/emoji_one/loop.png b/public/images/emoji/emoji_one/loop.png index 3b6f4933dfd..87dc982198c 100644 Binary files a/public/images/emoji/emoji_one/loop.png and b/public/images/emoji/emoji_one/loop.png differ diff --git a/public/images/emoji/emoji_one/loud_sound.png b/public/images/emoji/emoji_one/loud_sound.png index e84702e56db..90bdd2e8aea 100644 Binary files a/public/images/emoji/emoji_one/loud_sound.png and b/public/images/emoji/emoji_one/loud_sound.png differ diff --git a/public/images/emoji/emoji_one/loudspeaker.png b/public/images/emoji/emoji_one/loudspeaker.png index aaf588cd7b1..d6185f434f4 100644 Binary files a/public/images/emoji/emoji_one/loudspeaker.png and b/public/images/emoji/emoji_one/loudspeaker.png differ diff --git a/public/images/emoji/emoji_one/love_hotel.png b/public/images/emoji/emoji_one/love_hotel.png index d057d46ca2a..d3b8e9c604f 100644 Binary files a/public/images/emoji/emoji_one/love_hotel.png and b/public/images/emoji/emoji_one/love_hotel.png differ diff --git a/public/images/emoji/emoji_one/love_letter.png b/public/images/emoji/emoji_one/love_letter.png index e75e217da27..a76dad87e67 100644 Binary files a/public/images/emoji/emoji_one/love_letter.png and b/public/images/emoji/emoji_one/love_letter.png differ diff --git a/public/images/emoji/emoji_one/low_brightness.png b/public/images/emoji/emoji_one/low_brightness.png index 8566d0381bf..ec18ee037ee 100644 Binary files a/public/images/emoji/emoji_one/low_brightness.png and b/public/images/emoji/emoji_one/low_brightness.png differ diff --git a/public/images/emoji/emoji_one/m.png b/public/images/emoji/emoji_one/m.png index 2c72d4696d4..f4b210a855a 100644 Binary files a/public/images/emoji/emoji_one/m.png and b/public/images/emoji/emoji_one/m.png differ diff --git a/public/images/emoji/emoji_one/mag.png b/public/images/emoji/emoji_one/mag.png index 99982fbecfa..701d85afa71 100644 Binary files a/public/images/emoji/emoji_one/mag.png and b/public/images/emoji/emoji_one/mag.png differ diff --git a/public/images/emoji/emoji_one/mag_right.png b/public/images/emoji/emoji_one/mag_right.png index 95d12da0eea..9984d623fbe 100644 Binary files a/public/images/emoji/emoji_one/mag_right.png and b/public/images/emoji/emoji_one/mag_right.png differ diff --git a/public/images/emoji/emoji_one/mahjong.png b/public/images/emoji/emoji_one/mahjong.png index e13c9d1bc8c..1d247b4564d 100644 Binary files a/public/images/emoji/emoji_one/mahjong.png and b/public/images/emoji/emoji_one/mahjong.png differ diff --git a/public/images/emoji/emoji_one/mailbox.png b/public/images/emoji/emoji_one/mailbox.png index 2f805d4d7c6..fc7c6c2ce89 100644 Binary files a/public/images/emoji/emoji_one/mailbox.png and b/public/images/emoji/emoji_one/mailbox.png differ diff --git a/public/images/emoji/emoji_one/mailbox_closed.png b/public/images/emoji/emoji_one/mailbox_closed.png index b289ca6e0d5..c4903e0f500 100644 Binary files a/public/images/emoji/emoji_one/mailbox_closed.png and b/public/images/emoji/emoji_one/mailbox_closed.png differ diff --git a/public/images/emoji/emoji_one/mailbox_with_mail.png b/public/images/emoji/emoji_one/mailbox_with_mail.png index 8803e087b6b..474b443c57c 100644 Binary files a/public/images/emoji/emoji_one/mailbox_with_mail.png and b/public/images/emoji/emoji_one/mailbox_with_mail.png differ diff --git a/public/images/emoji/emoji_one/mailbox_with_no_mail.png b/public/images/emoji/emoji_one/mailbox_with_no_mail.png index 99fa22600ac..36a3b05b575 100644 Binary files a/public/images/emoji/emoji_one/mailbox_with_no_mail.png and b/public/images/emoji/emoji_one/mailbox_with_no_mail.png differ diff --git a/public/images/emoji/emoji_one/man.png b/public/images/emoji/emoji_one/man.png index cc67805ebaf..80a9b53aa11 100644 Binary files a/public/images/emoji/emoji_one/man.png and b/public/images/emoji/emoji_one/man.png differ diff --git a/public/images/emoji/emoji_one/man_with_gua_pi_mao.png b/public/images/emoji/emoji_one/man_with_gua_pi_mao.png index feeca141c8f..981753732d3 100644 Binary files a/public/images/emoji/emoji_one/man_with_gua_pi_mao.png and b/public/images/emoji/emoji_one/man_with_gua_pi_mao.png differ diff --git a/public/images/emoji/emoji_one/man_with_turban.png b/public/images/emoji/emoji_one/man_with_turban.png index 1ea734de7bc..20442ec2595 100644 Binary files a/public/images/emoji/emoji_one/man_with_turban.png and b/public/images/emoji/emoji_one/man_with_turban.png differ diff --git a/public/images/emoji/emoji_one/mans_shoe.png b/public/images/emoji/emoji_one/mans_shoe.png index 8d8a9feeb26..2243a23f1c2 100644 Binary files a/public/images/emoji/emoji_one/mans_shoe.png and b/public/images/emoji/emoji_one/mans_shoe.png differ diff --git a/public/images/emoji/emoji_one/map.png b/public/images/emoji/emoji_one/map.png new file mode 100644 index 00000000000..fe9c43d924f Binary files /dev/null and b/public/images/emoji/emoji_one/map.png differ diff --git a/public/images/emoji/emoji_one/maple_leaf.png b/public/images/emoji/emoji_one/maple_leaf.png index 2756537f1a4..321dab4af22 100644 Binary files a/public/images/emoji/emoji_one/maple_leaf.png and b/public/images/emoji/emoji_one/maple_leaf.png differ diff --git a/public/images/emoji/emoji_one/mask.png b/public/images/emoji/emoji_one/mask.png index bfcfad6cf0a..ffa4a2ab48a 100644 Binary files a/public/images/emoji/emoji_one/mask.png and b/public/images/emoji/emoji_one/mask.png differ diff --git a/public/images/emoji/emoji_one/massage.png b/public/images/emoji/emoji_one/massage.png index 11ca3b5b66b..23d7b37c6d8 100644 Binary files a/public/images/emoji/emoji_one/massage.png and b/public/images/emoji/emoji_one/massage.png differ diff --git a/public/images/emoji/emoji_one/meat_on_bone.png b/public/images/emoji/emoji_one/meat_on_bone.png index e9697fef171..501e8d46f52 100644 Binary files a/public/images/emoji/emoji_one/meat_on_bone.png and b/public/images/emoji/emoji_one/meat_on_bone.png differ diff --git a/public/images/emoji/emoji_one/medal.png b/public/images/emoji/emoji_one/medal.png new file mode 100644 index 00000000000..280bc07a915 Binary files /dev/null and b/public/images/emoji/emoji_one/medal.png differ diff --git a/public/images/emoji/emoji_one/mega.png b/public/images/emoji/emoji_one/mega.png index 66f741a8313..ba29171f8d5 100644 Binary files a/public/images/emoji/emoji_one/mega.png and b/public/images/emoji/emoji_one/mega.png differ diff --git a/public/images/emoji/emoji_one/melon.png b/public/images/emoji/emoji_one/melon.png index b27f00d254f..fc386346a98 100644 Binary files a/public/images/emoji/emoji_one/melon.png and b/public/images/emoji/emoji_one/melon.png differ diff --git a/public/images/emoji/emoji_one/memo.png b/public/images/emoji/emoji_one/memo.png index fd8f2860912..7e8459b4118 100644 Binary files a/public/images/emoji/emoji_one/memo.png and b/public/images/emoji/emoji_one/memo.png differ diff --git a/public/images/emoji/emoji_one/menorah.png b/public/images/emoji/emoji_one/menorah.png new file mode 100644 index 00000000000..b6a5b0b59e1 Binary files /dev/null and b/public/images/emoji/emoji_one/menorah.png differ diff --git a/public/images/emoji/emoji_one/mens.png b/public/images/emoji/emoji_one/mens.png index 086526c2080..4750a1b1195 100644 Binary files a/public/images/emoji/emoji_one/mens.png and b/public/images/emoji/emoji_one/mens.png differ diff --git a/public/images/emoji/emoji_one/metal.png b/public/images/emoji/emoji_one/metal.png new file mode 100644 index 00000000000..a653d619048 Binary files /dev/null and b/public/images/emoji/emoji_one/metal.png differ diff --git a/public/images/emoji/emoji_one/metro.png b/public/images/emoji/emoji_one/metro.png index 8900ba57409..d51de4fb6fb 100644 Binary files a/public/images/emoji/emoji_one/metro.png and b/public/images/emoji/emoji_one/metro.png differ diff --git a/public/images/emoji/emoji_one/microphone.png b/public/images/emoji/emoji_one/microphone.png index 346b8967c99..20bf0ff917a 100644 Binary files a/public/images/emoji/emoji_one/microphone.png and b/public/images/emoji/emoji_one/microphone.png differ diff --git a/public/images/emoji/emoji_one/microphone2.png b/public/images/emoji/emoji_one/microphone2.png new file mode 100644 index 00000000000..99489964419 Binary files /dev/null and b/public/images/emoji/emoji_one/microphone2.png differ diff --git a/public/images/emoji/emoji_one/microscope.png b/public/images/emoji/emoji_one/microscope.png index 944293d1ef0..186d82e25a0 100644 Binary files a/public/images/emoji/emoji_one/microscope.png and b/public/images/emoji/emoji_one/microscope.png differ diff --git a/public/images/emoji/emoji_one/middle_finger.png b/public/images/emoji/emoji_one/middle_finger.png new file mode 100644 index 00000000000..014e172555b Binary files /dev/null and b/public/images/emoji/emoji_one/middle_finger.png differ diff --git a/public/images/emoji/emoji_one/military_medal.png b/public/images/emoji/emoji_one/military_medal.png new file mode 100644 index 00000000000..a42f53c56c9 Binary files /dev/null and b/public/images/emoji/emoji_one/military_medal.png differ diff --git a/public/images/emoji/emoji_one/milky_way.png b/public/images/emoji/emoji_one/milky_way.png index 2d95b969027..afaf493b8b4 100644 Binary files a/public/images/emoji/emoji_one/milky_way.png and b/public/images/emoji/emoji_one/milky_way.png differ diff --git a/public/images/emoji/emoji_one/minibus.png b/public/images/emoji/emoji_one/minibus.png index 462d0a3487c..59759638a2a 100644 Binary files a/public/images/emoji/emoji_one/minibus.png and b/public/images/emoji/emoji_one/minibus.png differ diff --git a/public/images/emoji/emoji_one/minidisc.png b/public/images/emoji/emoji_one/minidisc.png index ec1b9b858b3..46de9eb2fac 100644 Binary files a/public/images/emoji/emoji_one/minidisc.png and b/public/images/emoji/emoji_one/minidisc.png differ diff --git a/public/images/emoji/emoji_one/mobile_phone_off.png b/public/images/emoji/emoji_one/mobile_phone_off.png index c62ea827fed..8d8747acae3 100644 Binary files a/public/images/emoji/emoji_one/mobile_phone_off.png and b/public/images/emoji/emoji_one/mobile_phone_off.png differ diff --git a/public/images/emoji/emoji_one/money_mouth.png b/public/images/emoji/emoji_one/money_mouth.png new file mode 100644 index 00000000000..e2b81259a68 Binary files /dev/null and b/public/images/emoji/emoji_one/money_mouth.png differ diff --git a/public/images/emoji/emoji_one/money_with_wings.png b/public/images/emoji/emoji_one/money_with_wings.png index 46591e443d5..33b3ce46d9b 100644 Binary files a/public/images/emoji/emoji_one/money_with_wings.png and b/public/images/emoji/emoji_one/money_with_wings.png differ diff --git a/public/images/emoji/emoji_one/moneybag.png b/public/images/emoji/emoji_one/moneybag.png index a44896ab0f3..3d5c37593c1 100644 Binary files a/public/images/emoji/emoji_one/moneybag.png and b/public/images/emoji/emoji_one/moneybag.png differ diff --git a/public/images/emoji/emoji_one/monkey.png b/public/images/emoji/emoji_one/monkey.png index 33e542ba678..1a661bd545b 100644 Binary files a/public/images/emoji/emoji_one/monkey.png and b/public/images/emoji/emoji_one/monkey.png differ diff --git a/public/images/emoji/emoji_one/monkey_face.png b/public/images/emoji/emoji_one/monkey_face.png index a753bae1c9d..abebe46c125 100644 Binary files a/public/images/emoji/emoji_one/monkey_face.png and b/public/images/emoji/emoji_one/monkey_face.png differ diff --git a/public/images/emoji/emoji_one/monorail.png b/public/images/emoji/emoji_one/monorail.png index 3adeb964c48..585f43a7bab 100644 Binary files a/public/images/emoji/emoji_one/monorail.png and b/public/images/emoji/emoji_one/monorail.png differ diff --git a/public/images/emoji/emoji_one/moon.png b/public/images/emoji/emoji_one/moon.png index b53fd42886f..a46b0a92d49 100644 Binary files a/public/images/emoji/emoji_one/moon.png and b/public/images/emoji/emoji_one/moon.png differ diff --git a/public/images/emoji/emoji_one/mortar_board.png b/public/images/emoji/emoji_one/mortar_board.png index 4d5744f60d4..2c55b6b9309 100644 Binary files a/public/images/emoji/emoji_one/mortar_board.png and b/public/images/emoji/emoji_one/mortar_board.png differ diff --git a/public/images/emoji/emoji_one/mosque.png b/public/images/emoji/emoji_one/mosque.png new file mode 100644 index 00000000000..4e3dd287c5c Binary files /dev/null and b/public/images/emoji/emoji_one/mosque.png differ diff --git a/public/images/emoji/emoji_one/motorboat.png b/public/images/emoji/emoji_one/motorboat.png new file mode 100644 index 00000000000..12a63b3f681 Binary files /dev/null and b/public/images/emoji/emoji_one/motorboat.png differ diff --git a/public/images/emoji/emoji_one/motorcycle.png b/public/images/emoji/emoji_one/motorcycle.png new file mode 100644 index 00000000000..45c7567a41f Binary files /dev/null and b/public/images/emoji/emoji_one/motorcycle.png differ diff --git a/public/images/emoji/emoji_one/motorway.png b/public/images/emoji/emoji_one/motorway.png new file mode 100644 index 00000000000..4b54f99ee2d Binary files /dev/null and b/public/images/emoji/emoji_one/motorway.png differ diff --git a/public/images/emoji/emoji_one/mount_fuji.png b/public/images/emoji/emoji_one/mount_fuji.png index 91eec3bae77..15296ffdee8 100644 Binary files a/public/images/emoji/emoji_one/mount_fuji.png and b/public/images/emoji/emoji_one/mount_fuji.png differ diff --git a/public/images/emoji/emoji_one/mountain.png b/public/images/emoji/emoji_one/mountain.png new file mode 100644 index 00000000000..fc1ca084b7d Binary files /dev/null and b/public/images/emoji/emoji_one/mountain.png differ diff --git a/public/images/emoji/emoji_one/mountain_bicyclist.png b/public/images/emoji/emoji_one/mountain_bicyclist.png index 3645a6d83e9..c25b6a8fbb0 100644 Binary files a/public/images/emoji/emoji_one/mountain_bicyclist.png and b/public/images/emoji/emoji_one/mountain_bicyclist.png differ diff --git a/public/images/emoji/emoji_one/mountain_cableway.png b/public/images/emoji/emoji_one/mountain_cableway.png index 6dbd7307e6b..e615ee6b7a1 100644 Binary files a/public/images/emoji/emoji_one/mountain_cableway.png and b/public/images/emoji/emoji_one/mountain_cableway.png differ diff --git a/public/images/emoji/emoji_one/mountain_railway.png b/public/images/emoji/emoji_one/mountain_railway.png index c69df1f8f57..7f5866d79e0 100644 Binary files a/public/images/emoji/emoji_one/mountain_railway.png and b/public/images/emoji/emoji_one/mountain_railway.png differ diff --git a/public/images/emoji/emoji_one/mountain_snow.png b/public/images/emoji/emoji_one/mountain_snow.png new file mode 100644 index 00000000000..0684e4ce6d0 Binary files /dev/null and b/public/images/emoji/emoji_one/mountain_snow.png differ diff --git a/public/images/emoji/emoji_one/mouse.png b/public/images/emoji/emoji_one/mouse.png index a8e5eb73fda..e030a8d0bb9 100644 Binary files a/public/images/emoji/emoji_one/mouse.png and b/public/images/emoji/emoji_one/mouse.png differ diff --git a/public/images/emoji/emoji_one/mouse2.png b/public/images/emoji/emoji_one/mouse2.png index 5b1b1137fe9..a48270e2c5c 100644 Binary files a/public/images/emoji/emoji_one/mouse2.png and b/public/images/emoji/emoji_one/mouse2.png differ diff --git a/public/images/emoji/emoji_one/mouse_three_button.png b/public/images/emoji/emoji_one/mouse_three_button.png new file mode 100644 index 00000000000..5eb22b18a8c Binary files /dev/null and b/public/images/emoji/emoji_one/mouse_three_button.png differ diff --git a/public/images/emoji/emoji_one/movie_camera.png b/public/images/emoji/emoji_one/movie_camera.png index 55f9b27538b..ca2fc8c2ba6 100644 Binary files a/public/images/emoji/emoji_one/movie_camera.png and b/public/images/emoji/emoji_one/movie_camera.png differ diff --git a/public/images/emoji/emoji_one/moyai.png b/public/images/emoji/emoji_one/moyai.png index 247d34e258f..47fd83dcca2 100644 Binary files a/public/images/emoji/emoji_one/moyai.png and b/public/images/emoji/emoji_one/moyai.png differ diff --git a/public/images/emoji/emoji_one/muscle.png b/public/images/emoji/emoji_one/muscle.png index 9913c3684ab..deca35f0fdd 100644 Binary files a/public/images/emoji/emoji_one/muscle.png and b/public/images/emoji/emoji_one/muscle.png differ diff --git a/public/images/emoji/emoji_one/mushroom.png b/public/images/emoji/emoji_one/mushroom.png index b1673df26ce..10c7320ef2b 100644 Binary files a/public/images/emoji/emoji_one/mushroom.png and b/public/images/emoji/emoji_one/mushroom.png differ diff --git a/public/images/emoji/emoji_one/musical_keyboard.png b/public/images/emoji/emoji_one/musical_keyboard.png index 88bb970f876..6a9ff452446 100644 Binary files a/public/images/emoji/emoji_one/musical_keyboard.png and b/public/images/emoji/emoji_one/musical_keyboard.png differ diff --git a/public/images/emoji/emoji_one/musical_note.png b/public/images/emoji/emoji_one/musical_note.png index 9a4606df014..9a1f62759c0 100644 Binary files a/public/images/emoji/emoji_one/musical_note.png and b/public/images/emoji/emoji_one/musical_note.png differ diff --git a/public/images/emoji/emoji_one/musical_score.png b/public/images/emoji/emoji_one/musical_score.png index 700bc6223d6..bc57bd0d7ac 100644 Binary files a/public/images/emoji/emoji_one/musical_score.png and b/public/images/emoji/emoji_one/musical_score.png differ diff --git a/public/images/emoji/emoji_one/mute.png b/public/images/emoji/emoji_one/mute.png index ae7a757725c..4e042944fbc 100644 Binary files a/public/images/emoji/emoji_one/mute.png and b/public/images/emoji/emoji_one/mute.png differ diff --git a/public/images/emoji/emoji_one/nail_care.png b/public/images/emoji/emoji_one/nail_care.png index 279881c2694..40b5db25015 100644 Binary files a/public/images/emoji/emoji_one/nail_care.png and b/public/images/emoji/emoji_one/nail_care.png differ diff --git a/public/images/emoji/emoji_one/name_badge.png b/public/images/emoji/emoji_one/name_badge.png index 7e023acb2c5..b9aed7e9ad4 100644 Binary files a/public/images/emoji/emoji_one/name_badge.png and b/public/images/emoji/emoji_one/name_badge.png differ diff --git a/public/images/emoji/emoji_one/necktie.png b/public/images/emoji/emoji_one/necktie.png index 3ed0339bfd9..daa9943f5b8 100644 Binary files a/public/images/emoji/emoji_one/necktie.png and b/public/images/emoji/emoji_one/necktie.png differ diff --git a/public/images/emoji/emoji_one/negative_squared_cross_mark.png b/public/images/emoji/emoji_one/negative_squared_cross_mark.png index 2aba98954c3..086ce34ce6d 100644 Binary files a/public/images/emoji/emoji_one/negative_squared_cross_mark.png and b/public/images/emoji/emoji_one/negative_squared_cross_mark.png differ diff --git a/public/images/emoji/emoji_one/nerd.png b/public/images/emoji/emoji_one/nerd.png new file mode 100644 index 00000000000..0861d21f60c Binary files /dev/null and b/public/images/emoji/emoji_one/nerd.png differ diff --git a/public/images/emoji/emoji_one/neutral_face.png b/public/images/emoji/emoji_one/neutral_face.png index 929ef11a0bf..88e63b537fc 100644 Binary files a/public/images/emoji/emoji_one/neutral_face.png and b/public/images/emoji/emoji_one/neutral_face.png differ diff --git a/public/images/emoji/emoji_one/new.png b/public/images/emoji/emoji_one/new.png index 22dab436b26..052a3ca3541 100644 Binary files a/public/images/emoji/emoji_one/new.png and b/public/images/emoji/emoji_one/new.png differ diff --git a/public/images/emoji/emoji_one/new_moon.png b/public/images/emoji/emoji_one/new_moon.png index 06e5e67f20d..00f36471da1 100644 Binary files a/public/images/emoji/emoji_one/new_moon.png and b/public/images/emoji/emoji_one/new_moon.png differ diff --git a/public/images/emoji/emoji_one/new_moon_with_face.png b/public/images/emoji/emoji_one/new_moon_with_face.png index c7b2e8011ac..d41e9590a88 100644 Binary files a/public/images/emoji/emoji_one/new_moon_with_face.png and b/public/images/emoji/emoji_one/new_moon_with_face.png differ diff --git a/public/images/emoji/emoji_one/newspaper.png b/public/images/emoji/emoji_one/newspaper.png index ae5e314945c..1dd3a82a012 100644 Binary files a/public/images/emoji/emoji_one/newspaper.png and b/public/images/emoji/emoji_one/newspaper.png differ diff --git a/public/images/emoji/emoji_one/newspaper2.png b/public/images/emoji/emoji_one/newspaper2.png new file mode 100644 index 00000000000..ef62361f06b Binary files /dev/null and b/public/images/emoji/emoji_one/newspaper2.png differ diff --git a/public/images/emoji/emoji_one/ng.png b/public/images/emoji/emoji_one/ng.png index 2925a559a6d..818e81ad796 100644 Binary files a/public/images/emoji/emoji_one/ng.png and b/public/images/emoji/emoji_one/ng.png differ diff --git a/public/images/emoji/emoji_one/night_with_stars.png b/public/images/emoji/emoji_one/night_with_stars.png index bf9a44ab6c9..54520839ef3 100644 Binary files a/public/images/emoji/emoji_one/night_with_stars.png and b/public/images/emoji/emoji_one/night_with_stars.png differ diff --git a/public/images/emoji/emoji_one/nine.png b/public/images/emoji/emoji_one/nine.png index 5ae453155bc..12a5598ea56 100644 Binary files a/public/images/emoji/emoji_one/nine.png and b/public/images/emoji/emoji_one/nine.png differ diff --git a/public/images/emoji/emoji_one/no_bell.png b/public/images/emoji/emoji_one/no_bell.png index 30e8858aaf7..bb59f47df85 100644 Binary files a/public/images/emoji/emoji_one/no_bell.png and b/public/images/emoji/emoji_one/no_bell.png differ diff --git a/public/images/emoji/emoji_one/no_bicycles.png b/public/images/emoji/emoji_one/no_bicycles.png index 222ab031d5c..062383da0ac 100644 Binary files a/public/images/emoji/emoji_one/no_bicycles.png and b/public/images/emoji/emoji_one/no_bicycles.png differ diff --git a/public/images/emoji/emoji_one/no_entry.png b/public/images/emoji/emoji_one/no_entry.png index 2c49af1c563..8483893835b 100644 Binary files a/public/images/emoji/emoji_one/no_entry.png and b/public/images/emoji/emoji_one/no_entry.png differ diff --git a/public/images/emoji/emoji_one/no_entry_sign.png b/public/images/emoji/emoji_one/no_entry_sign.png index 6577a1058f8..b36c270c308 100644 Binary files a/public/images/emoji/emoji_one/no_entry_sign.png and b/public/images/emoji/emoji_one/no_entry_sign.png differ diff --git a/public/images/emoji/emoji_one/no_good.png b/public/images/emoji/emoji_one/no_good.png index e6463ef8472..7e9b81530ab 100644 Binary files a/public/images/emoji/emoji_one/no_good.png and b/public/images/emoji/emoji_one/no_good.png differ diff --git a/public/images/emoji/emoji_one/no_mobile_phones.png b/public/images/emoji/emoji_one/no_mobile_phones.png index 8d1496a1861..f0839c43023 100644 Binary files a/public/images/emoji/emoji_one/no_mobile_phones.png and b/public/images/emoji/emoji_one/no_mobile_phones.png differ diff --git a/public/images/emoji/emoji_one/no_mouth.png b/public/images/emoji/emoji_one/no_mouth.png index 2ac7ab19b7b..6a9ea3a1d46 100644 Binary files a/public/images/emoji/emoji_one/no_mouth.png and b/public/images/emoji/emoji_one/no_mouth.png differ diff --git a/public/images/emoji/emoji_one/no_pedestrians.png b/public/images/emoji/emoji_one/no_pedestrians.png index 9337d8f31ab..a78205856dc 100644 Binary files a/public/images/emoji/emoji_one/no_pedestrians.png and b/public/images/emoji/emoji_one/no_pedestrians.png differ diff --git a/public/images/emoji/emoji_one/no_smoking.png b/public/images/emoji/emoji_one/no_smoking.png index 1f70c8fa66f..8b09310c7bb 100644 Binary files a/public/images/emoji/emoji_one/no_smoking.png and b/public/images/emoji/emoji_one/no_smoking.png differ diff --git a/public/images/emoji/emoji_one/non-potable_water.png b/public/images/emoji/emoji_one/non-potable_water.png index 45c12a545d8..92feee40d58 100644 Binary files a/public/images/emoji/emoji_one/non-potable_water.png and b/public/images/emoji/emoji_one/non-potable_water.png differ diff --git a/public/images/emoji/emoji_one/nose.png b/public/images/emoji/emoji_one/nose.png index 729535807c4..711dfc95e11 100644 Binary files a/public/images/emoji/emoji_one/nose.png and b/public/images/emoji/emoji_one/nose.png differ diff --git a/public/images/emoji/emoji_one/notebook.png b/public/images/emoji/emoji_one/notebook.png index 6ab5257a8cd..47ca64b67f0 100644 Binary files a/public/images/emoji/emoji_one/notebook.png and b/public/images/emoji/emoji_one/notebook.png differ diff --git a/public/images/emoji/emoji_one/notebook_with_decorative_cover.png b/public/images/emoji/emoji_one/notebook_with_decorative_cover.png index 8cc7fe68ffe..18a52677a38 100644 Binary files a/public/images/emoji/emoji_one/notebook_with_decorative_cover.png and b/public/images/emoji/emoji_one/notebook_with_decorative_cover.png differ diff --git a/public/images/emoji/emoji_one/notepad_spiral.png b/public/images/emoji/emoji_one/notepad_spiral.png new file mode 100644 index 00000000000..4d29c1ec0fe Binary files /dev/null and b/public/images/emoji/emoji_one/notepad_spiral.png differ diff --git a/public/images/emoji/emoji_one/notes.png b/public/images/emoji/emoji_one/notes.png index 68f5fb7a982..98bfd65bf38 100644 Binary files a/public/images/emoji/emoji_one/notes.png and b/public/images/emoji/emoji_one/notes.png differ diff --git a/public/images/emoji/emoji_one/nut_and_bolt.png b/public/images/emoji/emoji_one/nut_and_bolt.png index 7b0024e06f5..aeaafa489a7 100644 Binary files a/public/images/emoji/emoji_one/nut_and_bolt.png and b/public/images/emoji/emoji_one/nut_and_bolt.png differ diff --git a/public/images/emoji/emoji_one/o.png b/public/images/emoji/emoji_one/o.png index f141dc45292..9fc2f080286 100644 Binary files a/public/images/emoji/emoji_one/o.png and b/public/images/emoji/emoji_one/o.png differ diff --git a/public/images/emoji/emoji_one/o2.png b/public/images/emoji/emoji_one/o2.png index 0537a9ad0f6..4254d31caaf 100644 Binary files a/public/images/emoji/emoji_one/o2.png and b/public/images/emoji/emoji_one/o2.png differ diff --git a/public/images/emoji/emoji_one/ocean.png b/public/images/emoji/emoji_one/ocean.png index 172dfffdfb0..25a6966d1b3 100644 Binary files a/public/images/emoji/emoji_one/ocean.png and b/public/images/emoji/emoji_one/ocean.png differ diff --git a/public/images/emoji/emoji_one/octopus.png b/public/images/emoji/emoji_one/octopus.png index 8add7143ebb..2214cbd8193 100644 Binary files a/public/images/emoji/emoji_one/octopus.png and b/public/images/emoji/emoji_one/octopus.png differ diff --git a/public/images/emoji/emoji_one/oden.png b/public/images/emoji/emoji_one/oden.png index 8ac803517b7..ef2dd2511e6 100644 Binary files a/public/images/emoji/emoji_one/oden.png and b/public/images/emoji/emoji_one/oden.png differ diff --git a/public/images/emoji/emoji_one/office.png b/public/images/emoji/emoji_one/office.png index 9b06c86facc..650434ee04a 100644 Binary files a/public/images/emoji/emoji_one/office.png and b/public/images/emoji/emoji_one/office.png differ diff --git a/public/images/emoji/emoji_one/oil.png b/public/images/emoji/emoji_one/oil.png new file mode 100644 index 00000000000..8c00bde7330 Binary files /dev/null and b/public/images/emoji/emoji_one/oil.png differ diff --git a/public/images/emoji/emoji_one/ok.png b/public/images/emoji/emoji_one/ok.png index 8acef8cce96..b8ce8542408 100644 Binary files a/public/images/emoji/emoji_one/ok.png and b/public/images/emoji/emoji_one/ok.png differ diff --git a/public/images/emoji/emoji_one/ok_hand.png b/public/images/emoji/emoji_one/ok_hand.png index 0a83015e223..c7c7a012ef2 100644 Binary files a/public/images/emoji/emoji_one/ok_hand.png and b/public/images/emoji/emoji_one/ok_hand.png differ diff --git a/public/images/emoji/emoji_one/ok_woman.png b/public/images/emoji/emoji_one/ok_woman.png index 4bb5176c543..1f3c1c51ef0 100644 Binary files a/public/images/emoji/emoji_one/ok_woman.png and b/public/images/emoji/emoji_one/ok_woman.png differ diff --git a/public/images/emoji/emoji_one/older_man.png b/public/images/emoji/emoji_one/older_man.png index 66fd194007b..bdb4bf01d33 100644 Binary files a/public/images/emoji/emoji_one/older_man.png and b/public/images/emoji/emoji_one/older_man.png differ diff --git a/public/images/emoji/emoji_one/older_woman.png b/public/images/emoji/emoji_one/older_woman.png index e2c5bc72f4f..b68ae464121 100644 Binary files a/public/images/emoji/emoji_one/older_woman.png and b/public/images/emoji/emoji_one/older_woman.png differ diff --git a/public/images/emoji/emoji_one/om_symbol.png b/public/images/emoji/emoji_one/om_symbol.png new file mode 100644 index 00000000000..badf010f078 Binary files /dev/null and b/public/images/emoji/emoji_one/om_symbol.png differ diff --git a/public/images/emoji/emoji_one/on.png b/public/images/emoji/emoji_one/on.png index bdb75220dee..7ef4f5dc98f 100644 Binary files a/public/images/emoji/emoji_one/on.png and b/public/images/emoji/emoji_one/on.png differ diff --git a/public/images/emoji/emoji_one/oncoming_automobile.png b/public/images/emoji/emoji_one/oncoming_automobile.png index b9b0dafbf58..38713e61668 100644 Binary files a/public/images/emoji/emoji_one/oncoming_automobile.png and b/public/images/emoji/emoji_one/oncoming_automobile.png differ diff --git a/public/images/emoji/emoji_one/oncoming_bus.png b/public/images/emoji/emoji_one/oncoming_bus.png index 89381abf96d..bc11c586a20 100644 Binary files a/public/images/emoji/emoji_one/oncoming_bus.png and b/public/images/emoji/emoji_one/oncoming_bus.png differ diff --git a/public/images/emoji/emoji_one/oncoming_police_car.png b/public/images/emoji/emoji_one/oncoming_police_car.png index 2ab9c3302ef..1cf693a3860 100644 Binary files a/public/images/emoji/emoji_one/oncoming_police_car.png and b/public/images/emoji/emoji_one/oncoming_police_car.png differ diff --git a/public/images/emoji/emoji_one/oncoming_taxi.png b/public/images/emoji/emoji_one/oncoming_taxi.png index 806e3958f87..e4f616099e6 100644 Binary files a/public/images/emoji/emoji_one/oncoming_taxi.png and b/public/images/emoji/emoji_one/oncoming_taxi.png differ diff --git a/public/images/emoji/emoji_one/one.png b/public/images/emoji/emoji_one/one.png index cbf8c7450f4..9ddab3b31d5 100644 Binary files a/public/images/emoji/emoji_one/one.png and b/public/images/emoji/emoji_one/one.png differ diff --git a/public/images/emoji/emoji_one/open_book.png b/public/images/emoji/emoji_one/open_book.png index 158ba4965d9..ba3cc456b24 100644 Binary files a/public/images/emoji/emoji_one/open_book.png and b/public/images/emoji/emoji_one/open_book.png differ diff --git a/public/images/emoji/emoji_one/open_file_folder.png b/public/images/emoji/emoji_one/open_file_folder.png index 073afe5fe61..c4745df4017 100644 Binary files a/public/images/emoji/emoji_one/open_file_folder.png and b/public/images/emoji/emoji_one/open_file_folder.png differ diff --git a/public/images/emoji/emoji_one/open_hands.png b/public/images/emoji/emoji_one/open_hands.png index c8eb0bab520..35f79ca093b 100644 Binary files a/public/images/emoji/emoji_one/open_hands.png and b/public/images/emoji/emoji_one/open_hands.png differ diff --git a/public/images/emoji/emoji_one/open_mouth.png b/public/images/emoji/emoji_one/open_mouth.png index f1759e11469..fbcf3a1077e 100644 Binary files a/public/images/emoji/emoji_one/open_mouth.png and b/public/images/emoji/emoji_one/open_mouth.png differ diff --git a/public/images/emoji/emoji_one/ophiuchus.png b/public/images/emoji/emoji_one/ophiuchus.png index 5c349335191..954b50e2465 100644 Binary files a/public/images/emoji/emoji_one/ophiuchus.png and b/public/images/emoji/emoji_one/ophiuchus.png differ diff --git a/public/images/emoji/emoji_one/orange_book.png b/public/images/emoji/emoji_one/orange_book.png index 3b5fc46e591..e3d4f434472 100644 Binary files a/public/images/emoji/emoji_one/orange_book.png and b/public/images/emoji/emoji_one/orange_book.png differ diff --git a/public/images/emoji/emoji_one/orthodox_cross.png b/public/images/emoji/emoji_one/orthodox_cross.png new file mode 100644 index 00000000000..79e13464ab7 Binary files /dev/null and b/public/images/emoji/emoji_one/orthodox_cross.png differ diff --git a/public/images/emoji/emoji_one/outbox_tray.png b/public/images/emoji/emoji_one/outbox_tray.png index c5e55e33efb..dbd61118131 100644 Binary files a/public/images/emoji/emoji_one/outbox_tray.png and b/public/images/emoji/emoji_one/outbox_tray.png differ diff --git a/public/images/emoji/emoji_one/ox.png b/public/images/emoji/emoji_one/ox.png index e1688630c42..a461d694d53 100644 Binary files a/public/images/emoji/emoji_one/ox.png and b/public/images/emoji/emoji_one/ox.png differ diff --git a/public/images/emoji/emoji_one/package.png b/public/images/emoji/emoji_one/package.png index 424c4fd193e..7fddf8d8ae4 100644 Binary files a/public/images/emoji/emoji_one/package.png and b/public/images/emoji/emoji_one/package.png differ diff --git a/public/images/emoji/emoji_one/page_facing_up.png b/public/images/emoji/emoji_one/page_facing_up.png index 674077a2247..2046c275422 100644 Binary files a/public/images/emoji/emoji_one/page_facing_up.png and b/public/images/emoji/emoji_one/page_facing_up.png differ diff --git a/public/images/emoji/emoji_one/page_with_curl.png b/public/images/emoji/emoji_one/page_with_curl.png index ae40b423cb2..037fa1d207c 100644 Binary files a/public/images/emoji/emoji_one/page_with_curl.png and b/public/images/emoji/emoji_one/page_with_curl.png differ diff --git a/public/images/emoji/emoji_one/pager.png b/public/images/emoji/emoji_one/pager.png index eba5f9f1670..73934512619 100644 Binary files a/public/images/emoji/emoji_one/pager.png and b/public/images/emoji/emoji_one/pager.png differ diff --git a/public/images/emoji/emoji_one/paintbrush.png b/public/images/emoji/emoji_one/paintbrush.png new file mode 100644 index 00000000000..7f8ae7efd77 Binary files /dev/null and b/public/images/emoji/emoji_one/paintbrush.png differ diff --git a/public/images/emoji/emoji_one/palm_tree.png b/public/images/emoji/emoji_one/palm_tree.png index b18cffc9432..f921f40d7ce 100644 Binary files a/public/images/emoji/emoji_one/palm_tree.png and b/public/images/emoji/emoji_one/palm_tree.png differ diff --git a/public/images/emoji/emoji_one/panda_face.png b/public/images/emoji/emoji_one/panda_face.png index c10d77c23fe..3d1940a2a59 100644 Binary files a/public/images/emoji/emoji_one/panda_face.png and b/public/images/emoji/emoji_one/panda_face.png differ diff --git a/public/images/emoji/emoji_one/paperclip.png b/public/images/emoji/emoji_one/paperclip.png index 9b5af1de6b8..e235e322538 100644 Binary files a/public/images/emoji/emoji_one/paperclip.png and b/public/images/emoji/emoji_one/paperclip.png differ diff --git a/public/images/emoji/emoji_one/paperclips.png b/public/images/emoji/emoji_one/paperclips.png new file mode 100644 index 00000000000..3c086978d34 Binary files /dev/null and b/public/images/emoji/emoji_one/paperclips.png differ diff --git a/public/images/emoji/emoji_one/park.png b/public/images/emoji/emoji_one/park.png new file mode 100644 index 00000000000..f2c8362c397 Binary files /dev/null and b/public/images/emoji/emoji_one/park.png differ diff --git a/public/images/emoji/emoji_one/parking.png b/public/images/emoji/emoji_one/parking.png index 1fe845971f6..6f23c06efec 100644 Binary files a/public/images/emoji/emoji_one/parking.png and b/public/images/emoji/emoji_one/parking.png differ diff --git a/public/images/emoji/emoji_one/part_alternation_mark.png b/public/images/emoji/emoji_one/part_alternation_mark.png index e348a58d1ef..a6f50330a24 100644 Binary files a/public/images/emoji/emoji_one/part_alternation_mark.png and b/public/images/emoji/emoji_one/part_alternation_mark.png differ diff --git a/public/images/emoji/emoji_one/partly_sunny.png b/public/images/emoji/emoji_one/partly_sunny.png index a5c8d31b84b..d58a9ec170f 100644 Binary files a/public/images/emoji/emoji_one/partly_sunny.png and b/public/images/emoji/emoji_one/partly_sunny.png differ diff --git a/public/images/emoji/emoji_one/passport_control.png b/public/images/emoji/emoji_one/passport_control.png index 8a72a80ad06..ae510c1d5d7 100644 Binary files a/public/images/emoji/emoji_one/passport_control.png and b/public/images/emoji/emoji_one/passport_control.png differ diff --git a/public/images/emoji/emoji_one/pause_button.png b/public/images/emoji/emoji_one/pause_button.png new file mode 100644 index 00000000000..b66c56af7b5 Binary files /dev/null and b/public/images/emoji/emoji_one/pause_button.png differ diff --git a/public/images/emoji/emoji_one/paw_prints.png b/public/images/emoji/emoji_one/paw_prints.png index 970366ce19a..7aa222412b3 100644 Binary files a/public/images/emoji/emoji_one/paw_prints.png and b/public/images/emoji/emoji_one/paw_prints.png differ diff --git a/public/images/emoji/emoji_one/peace.png b/public/images/emoji/emoji_one/peace.png new file mode 100644 index 00000000000..556d48acaac Binary files /dev/null and b/public/images/emoji/emoji_one/peace.png differ diff --git a/public/images/emoji/emoji_one/peach.png b/public/images/emoji/emoji_one/peach.png index b7250fed91a..f1d8e57d242 100644 Binary files a/public/images/emoji/emoji_one/peach.png and b/public/images/emoji/emoji_one/peach.png differ diff --git a/public/images/emoji/emoji_one/pear.png b/public/images/emoji/emoji_one/pear.png index 7f6d05ee616..7d8c5a6216e 100644 Binary files a/public/images/emoji/emoji_one/pear.png and b/public/images/emoji/emoji_one/pear.png differ diff --git a/public/images/emoji/emoji_one/pen_ballpoint.png b/public/images/emoji/emoji_one/pen_ballpoint.png new file mode 100644 index 00000000000..c6d87b9fb27 Binary files /dev/null and b/public/images/emoji/emoji_one/pen_ballpoint.png differ diff --git a/public/images/emoji/emoji_one/pen_fountain.png b/public/images/emoji/emoji_one/pen_fountain.png new file mode 100644 index 00000000000..0b11b69de7a Binary files /dev/null and b/public/images/emoji/emoji_one/pen_fountain.png differ diff --git a/public/images/emoji/emoji_one/pencil.png b/public/images/emoji/emoji_one/pencil.png index fd8f2860912..50564b4aeb9 100644 Binary files a/public/images/emoji/emoji_one/pencil.png and b/public/images/emoji/emoji_one/pencil.png differ diff --git a/public/images/emoji/emoji_one/pencil2.png b/public/images/emoji/emoji_one/pencil2.png index 693ee8429ff..1e074e03161 100644 Binary files a/public/images/emoji/emoji_one/pencil2.png and b/public/images/emoji/emoji_one/pencil2.png differ diff --git a/public/images/emoji/emoji_one/penguin.png b/public/images/emoji/emoji_one/penguin.png index 1789bf22225..23233151ed9 100644 Binary files a/public/images/emoji/emoji_one/penguin.png and b/public/images/emoji/emoji_one/penguin.png differ diff --git a/public/images/emoji/emoji_one/pensive.png b/public/images/emoji/emoji_one/pensive.png index 60add1c1d09..23d9fbf81fd 100644 Binary files a/public/images/emoji/emoji_one/pensive.png and b/public/images/emoji/emoji_one/pensive.png differ diff --git a/public/images/emoji/emoji_one/performing_arts.png b/public/images/emoji/emoji_one/performing_arts.png index 97a5bb7feaf..4b05be4a22f 100644 Binary files a/public/images/emoji/emoji_one/performing_arts.png and b/public/images/emoji/emoji_one/performing_arts.png differ diff --git a/public/images/emoji/emoji_one/persevere.png b/public/images/emoji/emoji_one/persevere.png index 83b08ba35b6..a186a80d4e6 100644 Binary files a/public/images/emoji/emoji_one/persevere.png and b/public/images/emoji/emoji_one/persevere.png differ diff --git a/public/images/emoji/emoji_one/person_frowning.png b/public/images/emoji/emoji_one/person_frowning.png index 19377e9eb61..e77b97bd64f 100644 Binary files a/public/images/emoji/emoji_one/person_frowning.png and b/public/images/emoji/emoji_one/person_frowning.png differ diff --git a/public/images/emoji/emoji_one/person_with_blond_hair.png b/public/images/emoji/emoji_one/person_with_blond_hair.png index eff188afa48..9a0a1cc90f6 100644 Binary files a/public/images/emoji/emoji_one/person_with_blond_hair.png and b/public/images/emoji/emoji_one/person_with_blond_hair.png differ diff --git a/public/images/emoji/emoji_one/person_with_pouting_face.png b/public/images/emoji/emoji_one/person_with_pouting_face.png index 92ea6a97a84..c30c9903334 100644 Binary files a/public/images/emoji/emoji_one/person_with_pouting_face.png and b/public/images/emoji/emoji_one/person_with_pouting_face.png differ diff --git a/public/images/emoji/emoji_one/phone.png b/public/images/emoji/emoji_one/phone.png index 6a14f1bfe91..20dcecf24a5 100644 Binary files a/public/images/emoji/emoji_one/phone.png and b/public/images/emoji/emoji_one/phone.png differ diff --git a/public/images/emoji/emoji_one/pick.png b/public/images/emoji/emoji_one/pick.png new file mode 100644 index 00000000000..c7f116e236f Binary files /dev/null and b/public/images/emoji/emoji_one/pick.png differ diff --git a/public/images/emoji/emoji_one/pig.png b/public/images/emoji/emoji_one/pig.png index e2ef71cc01c..9ebd6b97c5f 100644 Binary files a/public/images/emoji/emoji_one/pig.png and b/public/images/emoji/emoji_one/pig.png differ diff --git a/public/images/emoji/emoji_one/pig2.png b/public/images/emoji/emoji_one/pig2.png index de1147954f0..c1d3c447f66 100644 Binary files a/public/images/emoji/emoji_one/pig2.png and b/public/images/emoji/emoji_one/pig2.png differ diff --git a/public/images/emoji/emoji_one/pig_nose.png b/public/images/emoji/emoji_one/pig_nose.png index 84500633ea1..5f5b86f0f2e 100644 Binary files a/public/images/emoji/emoji_one/pig_nose.png and b/public/images/emoji/emoji_one/pig_nose.png differ diff --git a/public/images/emoji/emoji_one/pill.png b/public/images/emoji/emoji_one/pill.png index 5db2699c478..aac47a01ae6 100644 Binary files a/public/images/emoji/emoji_one/pill.png and b/public/images/emoji/emoji_one/pill.png differ diff --git a/public/images/emoji/emoji_one/pineapple.png b/public/images/emoji/emoji_one/pineapple.png index b9b9f8827ae..4f214fb15fd 100644 Binary files a/public/images/emoji/emoji_one/pineapple.png and b/public/images/emoji/emoji_one/pineapple.png differ diff --git a/public/images/emoji/emoji_one/ping_pong.png b/public/images/emoji/emoji_one/ping_pong.png new file mode 100644 index 00000000000..5bb1f058bea Binary files /dev/null and b/public/images/emoji/emoji_one/ping_pong.png differ diff --git a/public/images/emoji/emoji_one/pisces.png b/public/images/emoji/emoji_one/pisces.png index 57625379074..410629d763b 100644 Binary files a/public/images/emoji/emoji_one/pisces.png and b/public/images/emoji/emoji_one/pisces.png differ diff --git a/public/images/emoji/emoji_one/pizza.png b/public/images/emoji/emoji_one/pizza.png index 2e3ff79895f..ab2ca3fd13b 100644 Binary files a/public/images/emoji/emoji_one/pizza.png and b/public/images/emoji/emoji_one/pizza.png differ diff --git a/public/images/emoji/emoji_one/place_of_worship.png b/public/images/emoji/emoji_one/place_of_worship.png new file mode 100644 index 00000000000..6ae5d822a6b Binary files /dev/null and b/public/images/emoji/emoji_one/place_of_worship.png differ diff --git a/public/images/emoji/emoji_one/play_pause.png b/public/images/emoji/emoji_one/play_pause.png new file mode 100644 index 00000000000..617619659c5 Binary files /dev/null and b/public/images/emoji/emoji_one/play_pause.png differ diff --git a/public/images/emoji/emoji_one/point_down.png b/public/images/emoji/emoji_one/point_down.png index bbd564336c9..c5384d04f07 100644 Binary files a/public/images/emoji/emoji_one/point_down.png and b/public/images/emoji/emoji_one/point_down.png differ diff --git a/public/images/emoji/emoji_one/point_left.png b/public/images/emoji/emoji_one/point_left.png index 9503416b0e7..1235e07507e 100644 Binary files a/public/images/emoji/emoji_one/point_left.png and b/public/images/emoji/emoji_one/point_left.png differ diff --git a/public/images/emoji/emoji_one/point_right.png b/public/images/emoji/emoji_one/point_right.png index 1d7e704a5f2..41151727acc 100644 Binary files a/public/images/emoji/emoji_one/point_right.png and b/public/images/emoji/emoji_one/point_right.png differ diff --git a/public/images/emoji/emoji_one/point_up.png b/public/images/emoji/emoji_one/point_up.png index 71ca2425790..42524ce0667 100644 Binary files a/public/images/emoji/emoji_one/point_up.png and b/public/images/emoji/emoji_one/point_up.png differ diff --git a/public/images/emoji/emoji_one/point_up_2.png b/public/images/emoji/emoji_one/point_up_2.png index b85e5aab3ea..558c6970048 100644 Binary files a/public/images/emoji/emoji_one/point_up_2.png and b/public/images/emoji/emoji_one/point_up_2.png differ diff --git a/public/images/emoji/emoji_one/police_car.png b/public/images/emoji/emoji_one/police_car.png index 4281ed3bb5f..dde1bc204c8 100644 Binary files a/public/images/emoji/emoji_one/police_car.png and b/public/images/emoji/emoji_one/police_car.png differ diff --git a/public/images/emoji/emoji_one/poodle.png b/public/images/emoji/emoji_one/poodle.png index a69f6388d2d..db2db9622a8 100644 Binary files a/public/images/emoji/emoji_one/poodle.png and b/public/images/emoji/emoji_one/poodle.png differ diff --git a/public/images/emoji/emoji_one/poop.png b/public/images/emoji/emoji_one/poop.png index 0c237a78811..e9afe47b0d8 100644 Binary files a/public/images/emoji/emoji_one/poop.png and b/public/images/emoji/emoji_one/poop.png differ diff --git a/public/images/emoji/emoji_one/popcorn.png b/public/images/emoji/emoji_one/popcorn.png new file mode 100644 index 00000000000..d0e482bcc4f Binary files /dev/null and b/public/images/emoji/emoji_one/popcorn.png differ diff --git a/public/images/emoji/emoji_one/post_office.png b/public/images/emoji/emoji_one/post_office.png index f819dac896f..9e3b6cf9207 100644 Binary files a/public/images/emoji/emoji_one/post_office.png and b/public/images/emoji/emoji_one/post_office.png differ diff --git a/public/images/emoji/emoji_one/postal_horn.png b/public/images/emoji/emoji_one/postal_horn.png index 2313eeb4529..975ce2d692f 100644 Binary files a/public/images/emoji/emoji_one/postal_horn.png and b/public/images/emoji/emoji_one/postal_horn.png differ diff --git a/public/images/emoji/emoji_one/postbox.png b/public/images/emoji/emoji_one/postbox.png index 4921a9f87c1..ae96ed1433a 100644 Binary files a/public/images/emoji/emoji_one/postbox.png and b/public/images/emoji/emoji_one/postbox.png differ diff --git a/public/images/emoji/emoji_one/potable_water.png b/public/images/emoji/emoji_one/potable_water.png index 08ee1b50803..29df7bb5590 100644 Binary files a/public/images/emoji/emoji_one/potable_water.png and b/public/images/emoji/emoji_one/potable_water.png differ diff --git a/public/images/emoji/emoji_one/pouch.png b/public/images/emoji/emoji_one/pouch.png index d8e54dd7c9b..75c84298224 100644 Binary files a/public/images/emoji/emoji_one/pouch.png and b/public/images/emoji/emoji_one/pouch.png differ diff --git a/public/images/emoji/emoji_one/poultry_leg.png b/public/images/emoji/emoji_one/poultry_leg.png index eafba9a3e36..6c9c8923a10 100644 Binary files a/public/images/emoji/emoji_one/poultry_leg.png and b/public/images/emoji/emoji_one/poultry_leg.png differ diff --git a/public/images/emoji/emoji_one/pound.png b/public/images/emoji/emoji_one/pound.png index 3ac812ff40e..04114b7089e 100644 Binary files a/public/images/emoji/emoji_one/pound.png and b/public/images/emoji/emoji_one/pound.png differ diff --git a/public/images/emoji/emoji_one/pouting_cat.png b/public/images/emoji/emoji_one/pouting_cat.png index 342a1198bbf..3efb85a594c 100644 Binary files a/public/images/emoji/emoji_one/pouting_cat.png and b/public/images/emoji/emoji_one/pouting_cat.png differ diff --git a/public/images/emoji/emoji_one/pray.png b/public/images/emoji/emoji_one/pray.png index faf1944768e..078d1c6274d 100644 Binary files a/public/images/emoji/emoji_one/pray.png and b/public/images/emoji/emoji_one/pray.png differ diff --git a/public/images/emoji/emoji_one/prayer_beads.png b/public/images/emoji/emoji_one/prayer_beads.png new file mode 100644 index 00000000000..40da4878b7e Binary files /dev/null and b/public/images/emoji/emoji_one/prayer_beads.png differ diff --git a/public/images/emoji/emoji_one/princess.png b/public/images/emoji/emoji_one/princess.png index 360d75eb90f..c79430cb413 100644 Binary files a/public/images/emoji/emoji_one/princess.png and b/public/images/emoji/emoji_one/princess.png differ diff --git a/public/images/emoji/emoji_one/printer.png b/public/images/emoji/emoji_one/printer.png new file mode 100644 index 00000000000..a314326739e Binary files /dev/null and b/public/images/emoji/emoji_one/printer.png differ diff --git a/public/images/emoji/emoji_one/projector.png b/public/images/emoji/emoji_one/projector.png new file mode 100644 index 00000000000..fa46ba0a29a Binary files /dev/null and b/public/images/emoji/emoji_one/projector.png differ diff --git a/public/images/emoji/emoji_one/punch.png b/public/images/emoji/emoji_one/punch.png index a616ffee193..9d0a9623661 100644 Binary files a/public/images/emoji/emoji_one/punch.png and b/public/images/emoji/emoji_one/punch.png differ diff --git a/public/images/emoji/emoji_one/purple_heart.png b/public/images/emoji/emoji_one/purple_heart.png index f1ff877eea2..8ce4c7d79f3 100644 Binary files a/public/images/emoji/emoji_one/purple_heart.png and b/public/images/emoji/emoji_one/purple_heart.png differ diff --git a/public/images/emoji/emoji_one/purse.png b/public/images/emoji/emoji_one/purse.png index da09a41a3e8..8b56826a162 100644 Binary files a/public/images/emoji/emoji_one/purse.png and b/public/images/emoji/emoji_one/purse.png differ diff --git a/public/images/emoji/emoji_one/pushpin.png b/public/images/emoji/emoji_one/pushpin.png index 557ac45f0c8..2840e49371c 100644 Binary files a/public/images/emoji/emoji_one/pushpin.png and b/public/images/emoji/emoji_one/pushpin.png differ diff --git a/public/images/emoji/emoji_one/put_litter_in_its_place.png b/public/images/emoji/emoji_one/put_litter_in_its_place.png index 19267a1de29..ec1bea4b144 100644 Binary files a/public/images/emoji/emoji_one/put_litter_in_its_place.png and b/public/images/emoji/emoji_one/put_litter_in_its_place.png differ diff --git a/public/images/emoji/emoji_one/question.png b/public/images/emoji/emoji_one/question.png index 716261e996f..b0828c28b1e 100644 Binary files a/public/images/emoji/emoji_one/question.png and b/public/images/emoji/emoji_one/question.png differ diff --git a/public/images/emoji/emoji_one/rabbit.png b/public/images/emoji/emoji_one/rabbit.png index e6203c05230..dfa609cc703 100644 Binary files a/public/images/emoji/emoji_one/rabbit.png and b/public/images/emoji/emoji_one/rabbit.png differ diff --git a/public/images/emoji/emoji_one/rabbit2.png b/public/images/emoji/emoji_one/rabbit2.png index ab2fae0fc72..111f3f877a0 100644 Binary files a/public/images/emoji/emoji_one/rabbit2.png and b/public/images/emoji/emoji_one/rabbit2.png differ diff --git a/public/images/emoji/emoji_one/race_car.png b/public/images/emoji/emoji_one/race_car.png new file mode 100644 index 00000000000..4b094c2660d Binary files /dev/null and b/public/images/emoji/emoji_one/race_car.png differ diff --git a/public/images/emoji/emoji_one/racehorse.png b/public/images/emoji/emoji_one/racehorse.png index fadf8f2bf06..9b8e9b4f748 100644 Binary files a/public/images/emoji/emoji_one/racehorse.png and b/public/images/emoji/emoji_one/racehorse.png differ diff --git a/public/images/emoji/emoji_one/radio.png b/public/images/emoji/emoji_one/radio.png index dedc50fe9b4..9b0f207f563 100644 Binary files a/public/images/emoji/emoji_one/radio.png and b/public/images/emoji/emoji_one/radio.png differ diff --git a/public/images/emoji/emoji_one/radio_button.png b/public/images/emoji/emoji_one/radio_button.png index 22baecc2802..8cb71a832f1 100644 Binary files a/public/images/emoji/emoji_one/radio_button.png and b/public/images/emoji/emoji_one/radio_button.png differ diff --git a/public/images/emoji/emoji_one/radioactive.png b/public/images/emoji/emoji_one/radioactive.png new file mode 100644 index 00000000000..cac4064d436 Binary files /dev/null and b/public/images/emoji/emoji_one/radioactive.png differ diff --git a/public/images/emoji/emoji_one/rage.png b/public/images/emoji/emoji_one/rage.png index f62d48c4949..96aff9b1330 100644 Binary files a/public/images/emoji/emoji_one/rage.png and b/public/images/emoji/emoji_one/rage.png differ diff --git a/public/images/emoji/emoji_one/railway_car.png b/public/images/emoji/emoji_one/railway_car.png index 82d80886652..95a4b83bf2c 100644 Binary files a/public/images/emoji/emoji_one/railway_car.png and b/public/images/emoji/emoji_one/railway_car.png differ diff --git a/public/images/emoji/emoji_one/railway_track.png b/public/images/emoji/emoji_one/railway_track.png new file mode 100644 index 00000000000..641cbe2cba4 Binary files /dev/null and b/public/images/emoji/emoji_one/railway_track.png differ diff --git a/public/images/emoji/emoji_one/rainbow.png b/public/images/emoji/emoji_one/rainbow.png index eb539c5bed1..7d624a6d87c 100644 Binary files a/public/images/emoji/emoji_one/rainbow.png and b/public/images/emoji/emoji_one/rainbow.png differ diff --git a/public/images/emoji/emoji_one/raised_hand.png b/public/images/emoji/emoji_one/raised_hand.png index 4f1fce256e0..aa39a2b2827 100644 Binary files a/public/images/emoji/emoji_one/raised_hand.png and b/public/images/emoji/emoji_one/raised_hand.png differ diff --git a/public/images/emoji/emoji_one/raised_hands.png b/public/images/emoji/emoji_one/raised_hands.png index 8dbc25f830d..5a01a8bc340 100644 Binary files a/public/images/emoji/emoji_one/raised_hands.png and b/public/images/emoji/emoji_one/raised_hands.png differ diff --git a/public/images/emoji/emoji_one/raising_hand.png b/public/images/emoji/emoji_one/raising_hand.png index 9d98b8d9c53..a6c1e4252b9 100644 Binary files a/public/images/emoji/emoji_one/raising_hand.png and b/public/images/emoji/emoji_one/raising_hand.png differ diff --git a/public/images/emoji/emoji_one/ram.png b/public/images/emoji/emoji_one/ram.png index 17af1b9a581..97b2457c490 100644 Binary files a/public/images/emoji/emoji_one/ram.png and b/public/images/emoji/emoji_one/ram.png differ diff --git a/public/images/emoji/emoji_one/ramen.png b/public/images/emoji/emoji_one/ramen.png index 78782756653..e7f7ac5aaa3 100644 Binary files a/public/images/emoji/emoji_one/ramen.png and b/public/images/emoji/emoji_one/ramen.png differ diff --git a/public/images/emoji/emoji_one/rat.png b/public/images/emoji/emoji_one/rat.png index 58c2d79d886..b80c03a55c4 100644 Binary files a/public/images/emoji/emoji_one/rat.png and b/public/images/emoji/emoji_one/rat.png differ diff --git a/public/images/emoji/emoji_one/record_button.png b/public/images/emoji/emoji_one/record_button.png new file mode 100644 index 00000000000..b62b87170e8 Binary files /dev/null and b/public/images/emoji/emoji_one/record_button.png differ diff --git a/public/images/emoji/emoji_one/recycle.png b/public/images/emoji/emoji_one/recycle.png index 181391e861b..df4aedc6771 100644 Binary files a/public/images/emoji/emoji_one/recycle.png and b/public/images/emoji/emoji_one/recycle.png differ diff --git a/public/images/emoji/emoji_one/red_car.png b/public/images/emoji/emoji_one/red_car.png index e266bd21e5b..9c1c7c4c21e 100644 Binary files a/public/images/emoji/emoji_one/red_car.png and b/public/images/emoji/emoji_one/red_car.png differ diff --git a/public/images/emoji/emoji_one/red_circle.png b/public/images/emoji/emoji_one/red_circle.png index bf181cc5676..d37651dcc5c 100644 Binary files a/public/images/emoji/emoji_one/red_circle.png and b/public/images/emoji/emoji_one/red_circle.png differ diff --git a/public/images/emoji/emoji_one/registered.png b/public/images/emoji/emoji_one/registered.png index 9776d66f85d..f81fa436323 100644 Binary files a/public/images/emoji/emoji_one/registered.png and b/public/images/emoji/emoji_one/registered.png differ diff --git a/public/images/emoji/emoji_one/relaxed.png b/public/images/emoji/emoji_one/relaxed.png index ec920984997..398aa941675 100644 Binary files a/public/images/emoji/emoji_one/relaxed.png and b/public/images/emoji/emoji_one/relaxed.png differ diff --git a/public/images/emoji/emoji_one/relieved.png b/public/images/emoji/emoji_one/relieved.png index c011b974dd1..6f597ecec8c 100644 Binary files a/public/images/emoji/emoji_one/relieved.png and b/public/images/emoji/emoji_one/relieved.png differ diff --git a/public/images/emoji/emoji_one/reminder_ribbon.png b/public/images/emoji/emoji_one/reminder_ribbon.png new file mode 100644 index 00000000000..c9267457ff4 Binary files /dev/null and b/public/images/emoji/emoji_one/reminder_ribbon.png differ diff --git a/public/images/emoji/emoji_one/repeat.png b/public/images/emoji/emoji_one/repeat.png index edd87a8b207..5f52fe6dbd6 100644 Binary files a/public/images/emoji/emoji_one/repeat.png and b/public/images/emoji/emoji_one/repeat.png differ diff --git a/public/images/emoji/emoji_one/repeat_one.png b/public/images/emoji/emoji_one/repeat_one.png index 50199808787..c2703781dc2 100644 Binary files a/public/images/emoji/emoji_one/repeat_one.png and b/public/images/emoji/emoji_one/repeat_one.png differ diff --git a/public/images/emoji/emoji_one/restroom.png b/public/images/emoji/emoji_one/restroom.png index c8b338688ad..79715936ffb 100644 Binary files a/public/images/emoji/emoji_one/restroom.png and b/public/images/emoji/emoji_one/restroom.png differ diff --git a/public/images/emoji/emoji_one/revolving_hearts.png b/public/images/emoji/emoji_one/revolving_hearts.png index 0602d03c110..25fbd423c58 100644 Binary files a/public/images/emoji/emoji_one/revolving_hearts.png and b/public/images/emoji/emoji_one/revolving_hearts.png differ diff --git a/public/images/emoji/emoji_one/rewind.png b/public/images/emoji/emoji_one/rewind.png index 18aae0affcb..5b12c0e3b80 100644 Binary files a/public/images/emoji/emoji_one/rewind.png and b/public/images/emoji/emoji_one/rewind.png differ diff --git a/public/images/emoji/emoji_one/ribbon.png b/public/images/emoji/emoji_one/ribbon.png index 0cb50b38cae..c6287617e89 100644 Binary files a/public/images/emoji/emoji_one/ribbon.png and b/public/images/emoji/emoji_one/ribbon.png differ diff --git a/public/images/emoji/emoji_one/rice.png b/public/images/emoji/emoji_one/rice.png index 15358ae0217..a7b8f741b5c 100644 Binary files a/public/images/emoji/emoji_one/rice.png and b/public/images/emoji/emoji_one/rice.png differ diff --git a/public/images/emoji/emoji_one/rice_ball.png b/public/images/emoji/emoji_one/rice_ball.png index 4a24a91e28c..fbc76c3fa3e 100644 Binary files a/public/images/emoji/emoji_one/rice_ball.png and b/public/images/emoji/emoji_one/rice_ball.png differ diff --git a/public/images/emoji/emoji_one/rice_cracker.png b/public/images/emoji/emoji_one/rice_cracker.png index 974d205ed87..d4654784a0b 100644 Binary files a/public/images/emoji/emoji_one/rice_cracker.png and b/public/images/emoji/emoji_one/rice_cracker.png differ diff --git a/public/images/emoji/emoji_one/rice_scene.png b/public/images/emoji/emoji_one/rice_scene.png index d68d294f0ba..dd49095b8cb 100644 Binary files a/public/images/emoji/emoji_one/rice_scene.png and b/public/images/emoji/emoji_one/rice_scene.png differ diff --git a/public/images/emoji/emoji_one/ring.png b/public/images/emoji/emoji_one/ring.png index f033d7941cb..0fee7d4d919 100644 Binary files a/public/images/emoji/emoji_one/ring.png and b/public/images/emoji/emoji_one/ring.png differ diff --git a/public/images/emoji/emoji_one/robot.png b/public/images/emoji/emoji_one/robot.png new file mode 100644 index 00000000000..cdbad6d12db Binary files /dev/null and b/public/images/emoji/emoji_one/robot.png differ diff --git a/public/images/emoji/emoji_one/rocket.png b/public/images/emoji/emoji_one/rocket.png index 0ca6d5fed25..e95d9bd7632 100644 Binary files a/public/images/emoji/emoji_one/rocket.png and b/public/images/emoji/emoji_one/rocket.png differ diff --git a/public/images/emoji/emoji_one/roller_coaster.png b/public/images/emoji/emoji_one/roller_coaster.png index 84922986372..10b53c882dd 100644 Binary files a/public/images/emoji/emoji_one/roller_coaster.png and b/public/images/emoji/emoji_one/roller_coaster.png differ diff --git a/public/images/emoji/emoji_one/rolling_eyes.png b/public/images/emoji/emoji_one/rolling_eyes.png new file mode 100644 index 00000000000..da716bbca16 Binary files /dev/null and b/public/images/emoji/emoji_one/rolling_eyes.png differ diff --git a/public/images/emoji/emoji_one/rooster.png b/public/images/emoji/emoji_one/rooster.png index 798542a0ea6..ef54e5432e5 100644 Binary files a/public/images/emoji/emoji_one/rooster.png and b/public/images/emoji/emoji_one/rooster.png differ diff --git a/public/images/emoji/emoji_one/rose.png b/public/images/emoji/emoji_one/rose.png index 2a9d77598c0..825235d7583 100644 Binary files a/public/images/emoji/emoji_one/rose.png and b/public/images/emoji/emoji_one/rose.png differ diff --git a/public/images/emoji/emoji_one/rosette.png b/public/images/emoji/emoji_one/rosette.png new file mode 100644 index 00000000000..9180c9d4dde Binary files /dev/null and b/public/images/emoji/emoji_one/rosette.png differ diff --git a/public/images/emoji/emoji_one/rotating_light.png b/public/images/emoji/emoji_one/rotating_light.png index e286febd4b1..a048838e688 100644 Binary files a/public/images/emoji/emoji_one/rotating_light.png and b/public/images/emoji/emoji_one/rotating_light.png differ diff --git a/public/images/emoji/emoji_one/round_pushpin.png b/public/images/emoji/emoji_one/round_pushpin.png index b16e5c41a97..8d105ac88a9 100644 Binary files a/public/images/emoji/emoji_one/round_pushpin.png and b/public/images/emoji/emoji_one/round_pushpin.png differ diff --git a/public/images/emoji/emoji_one/rowboat.png b/public/images/emoji/emoji_one/rowboat.png index c554e28f205..df338b28616 100644 Binary files a/public/images/emoji/emoji_one/rowboat.png and b/public/images/emoji/emoji_one/rowboat.png differ diff --git a/public/images/emoji/emoji_one/ru.png b/public/images/emoji/emoji_one/ru.png index 2b3c9d915f5..921b13d3735 100644 Binary files a/public/images/emoji/emoji_one/ru.png and b/public/images/emoji/emoji_one/ru.png differ diff --git a/public/images/emoji/emoji_one/rugby_football.png b/public/images/emoji/emoji_one/rugby_football.png index e32b362221a..69ebe52ae90 100644 Binary files a/public/images/emoji/emoji_one/rugby_football.png and b/public/images/emoji/emoji_one/rugby_football.png differ diff --git a/public/images/emoji/emoji_one/runner.png b/public/images/emoji/emoji_one/runner.png index 0ca1f27cd56..c2ae07c0b57 100644 Binary files a/public/images/emoji/emoji_one/runner.png and b/public/images/emoji/emoji_one/runner.png differ diff --git a/public/images/emoji/emoji_one/running.png b/public/images/emoji/emoji_one/running.png index 0ca1f27cd56..7db0dbb1a05 100644 Binary files a/public/images/emoji/emoji_one/running.png and b/public/images/emoji/emoji_one/running.png differ diff --git a/public/images/emoji/emoji_one/running_shirt_with_sash.png b/public/images/emoji/emoji_one/running_shirt_with_sash.png index e49632dadfd..c97808f5b8c 100644 Binary files a/public/images/emoji/emoji_one/running_shirt_with_sash.png and b/public/images/emoji/emoji_one/running_shirt_with_sash.png differ diff --git a/public/images/emoji/emoji_one/sa.png b/public/images/emoji/emoji_one/sa.png index 033348515e0..870a9652ed5 100644 Binary files a/public/images/emoji/emoji_one/sa.png and b/public/images/emoji/emoji_one/sa.png differ diff --git a/public/images/emoji/emoji_one/sagittarius.png b/public/images/emoji/emoji_one/sagittarius.png index 533c7772ada..fe914400ef3 100644 Binary files a/public/images/emoji/emoji_one/sagittarius.png and b/public/images/emoji/emoji_one/sagittarius.png differ diff --git a/public/images/emoji/emoji_one/sailboat.png b/public/images/emoji/emoji_one/sailboat.png index 9e862f831f6..bdcd4bda048 100644 Binary files a/public/images/emoji/emoji_one/sailboat.png and b/public/images/emoji/emoji_one/sailboat.png differ diff --git a/public/images/emoji/emoji_one/sake.png b/public/images/emoji/emoji_one/sake.png index 40a158bfe35..6dd6a54bb76 100644 Binary files a/public/images/emoji/emoji_one/sake.png and b/public/images/emoji/emoji_one/sake.png differ diff --git a/public/images/emoji/emoji_one/sandal.png b/public/images/emoji/emoji_one/sandal.png index 1db7005bb73..3bb2e93dcbd 100644 Binary files a/public/images/emoji/emoji_one/sandal.png and b/public/images/emoji/emoji_one/sandal.png differ diff --git a/public/images/emoji/emoji_one/santa.png b/public/images/emoji/emoji_one/santa.png index 29d63fd9121..4ddc0f7c950 100644 Binary files a/public/images/emoji/emoji_one/santa.png and b/public/images/emoji/emoji_one/santa.png differ diff --git a/public/images/emoji/emoji_one/satellite.png b/public/images/emoji/emoji_one/satellite.png index 7411b9235a2..c535e0974d4 100644 Binary files a/public/images/emoji/emoji_one/satellite.png and b/public/images/emoji/emoji_one/satellite.png differ diff --git a/public/images/emoji/emoji_one/satellite_orbital.png b/public/images/emoji/emoji_one/satellite_orbital.png new file mode 100644 index 00000000000..a0d81278533 Binary files /dev/null and b/public/images/emoji/emoji_one/satellite_orbital.png differ diff --git a/public/images/emoji/emoji_one/satisfied.png b/public/images/emoji/emoji_one/satisfied.png index 06adb559cdf..836d7074ae6 100644 Binary files a/public/images/emoji/emoji_one/satisfied.png and b/public/images/emoji/emoji_one/satisfied.png differ diff --git a/public/images/emoji/emoji_one/saxophone.png b/public/images/emoji/emoji_one/saxophone.png index 63446652f02..5cbb2c44e43 100644 Binary files a/public/images/emoji/emoji_one/saxophone.png and b/public/images/emoji/emoji_one/saxophone.png differ diff --git a/public/images/emoji/emoji_one/scales.png b/public/images/emoji/emoji_one/scales.png new file mode 100644 index 00000000000..3c88977da89 Binary files /dev/null and b/public/images/emoji/emoji_one/scales.png differ diff --git a/public/images/emoji/emoji_one/school.png b/public/images/emoji/emoji_one/school.png index 7bc84c877b1..4fbfbfb9cd5 100644 Binary files a/public/images/emoji/emoji_one/school.png and b/public/images/emoji/emoji_one/school.png differ diff --git a/public/images/emoji/emoji_one/school_satchel.png b/public/images/emoji/emoji_one/school_satchel.png index 79d4ff844a1..4516bd7e2b5 100644 Binary files a/public/images/emoji/emoji_one/school_satchel.png and b/public/images/emoji/emoji_one/school_satchel.png differ diff --git a/public/images/emoji/emoji_one/scissors.png b/public/images/emoji/emoji_one/scissors.png index 0a2d1b07f93..2e6dc5cf746 100644 Binary files a/public/images/emoji/emoji_one/scissors.png and b/public/images/emoji/emoji_one/scissors.png differ diff --git a/public/images/emoji/emoji_one/scorpion.png b/public/images/emoji/emoji_one/scorpion.png new file mode 100644 index 00000000000..a8fec65a5b5 Binary files /dev/null and b/public/images/emoji/emoji_one/scorpion.png differ diff --git a/public/images/emoji/emoji_one/scorpius.png b/public/images/emoji/emoji_one/scorpius.png index 458c843d2b3..45392dcc573 100644 Binary files a/public/images/emoji/emoji_one/scorpius.png and b/public/images/emoji/emoji_one/scorpius.png differ diff --git a/public/images/emoji/emoji_one/scream.png b/public/images/emoji/emoji_one/scream.png index 3929adaf026..5d475317173 100644 Binary files a/public/images/emoji/emoji_one/scream.png and b/public/images/emoji/emoji_one/scream.png differ diff --git a/public/images/emoji/emoji_one/scream_cat.png b/public/images/emoji/emoji_one/scream_cat.png index b82c3b1b3e2..1629dfdd0b4 100644 Binary files a/public/images/emoji/emoji_one/scream_cat.png and b/public/images/emoji/emoji_one/scream_cat.png differ diff --git a/public/images/emoji/emoji_one/scroll.png b/public/images/emoji/emoji_one/scroll.png index 2505dbf59fc..8aceaa6db2e 100644 Binary files a/public/images/emoji/emoji_one/scroll.png and b/public/images/emoji/emoji_one/scroll.png differ diff --git a/public/images/emoji/emoji_one/seat.png b/public/images/emoji/emoji_one/seat.png index 1ec8166b6e1..7881c2ca91f 100644 Binary files a/public/images/emoji/emoji_one/seat.png and b/public/images/emoji/emoji_one/seat.png differ diff --git a/public/images/emoji/emoji_one/secret.png b/public/images/emoji/emoji_one/secret.png index c5f8644393d..70cdf8e1629 100644 Binary files a/public/images/emoji/emoji_one/secret.png and b/public/images/emoji/emoji_one/secret.png differ diff --git a/public/images/emoji/emoji_one/see_no_evil.png b/public/images/emoji/emoji_one/see_no_evil.png index df1fb6607f3..855f90d0903 100644 Binary files a/public/images/emoji/emoji_one/see_no_evil.png and b/public/images/emoji/emoji_one/see_no_evil.png differ diff --git a/public/images/emoji/emoji_one/seedling.png b/public/images/emoji/emoji_one/seedling.png index eae79d27465..000d34d0b2e 100644 Binary files a/public/images/emoji/emoji_one/seedling.png and b/public/images/emoji/emoji_one/seedling.png differ diff --git a/public/images/emoji/emoji_one/seven.png b/public/images/emoji/emoji_one/seven.png index 3f5e9fa9e52..2c0afc56e30 100644 Binary files a/public/images/emoji/emoji_one/seven.png and b/public/images/emoji/emoji_one/seven.png differ diff --git a/public/images/emoji/emoji_one/shamrock.png b/public/images/emoji/emoji_one/shamrock.png new file mode 100644 index 00000000000..a14f158f7fc Binary files /dev/null and b/public/images/emoji/emoji_one/shamrock.png differ diff --git a/public/images/emoji/emoji_one/shaved_ice.png b/public/images/emoji/emoji_one/shaved_ice.png index a14f0f4ec26..3a3898e4ac1 100644 Binary files a/public/images/emoji/emoji_one/shaved_ice.png and b/public/images/emoji/emoji_one/shaved_ice.png differ diff --git a/public/images/emoji/emoji_one/sheep.png b/public/images/emoji/emoji_one/sheep.png index e47d6eda894..48858f1b0c4 100644 Binary files a/public/images/emoji/emoji_one/sheep.png and b/public/images/emoji/emoji_one/sheep.png differ diff --git a/public/images/emoji/emoji_one/shell.png b/public/images/emoji/emoji_one/shell.png index aa3599cf9eb..e4f63169634 100644 Binary files a/public/images/emoji/emoji_one/shell.png and b/public/images/emoji/emoji_one/shell.png differ diff --git a/public/images/emoji/emoji_one/shield.png b/public/images/emoji/emoji_one/shield.png new file mode 100644 index 00000000000..caa71afde7f Binary files /dev/null and b/public/images/emoji/emoji_one/shield.png differ diff --git a/public/images/emoji/emoji_one/shinto_shrine.png b/public/images/emoji/emoji_one/shinto_shrine.png new file mode 100644 index 00000000000..25366b5c5c3 Binary files /dev/null and b/public/images/emoji/emoji_one/shinto_shrine.png differ diff --git a/public/images/emoji/emoji_one/ship.png b/public/images/emoji/emoji_one/ship.png index 9c24f0d3ac1..1303695a970 100644 Binary files a/public/images/emoji/emoji_one/ship.png and b/public/images/emoji/emoji_one/ship.png differ diff --git a/public/images/emoji/emoji_one/shirt.png b/public/images/emoji/emoji_one/shirt.png index 556efde26e9..4836cd37d91 100644 Binary files a/public/images/emoji/emoji_one/shirt.png and b/public/images/emoji/emoji_one/shirt.png differ diff --git a/public/images/emoji/emoji_one/shit.png b/public/images/emoji/emoji_one/shit.png index 0c237a78811..e9afe47b0d8 100644 Binary files a/public/images/emoji/emoji_one/shit.png and b/public/images/emoji/emoji_one/shit.png differ diff --git a/public/images/emoji/emoji_one/shoe.png b/public/images/emoji/emoji_one/shoe.png index 8d8a9feeb26..cbcc998e648 100644 Binary files a/public/images/emoji/emoji_one/shoe.png and b/public/images/emoji/emoji_one/shoe.png differ diff --git a/public/images/emoji/emoji_one/shopping_bags.png b/public/images/emoji/emoji_one/shopping_bags.png new file mode 100644 index 00000000000..08c37ca9071 Binary files /dev/null and b/public/images/emoji/emoji_one/shopping_bags.png differ diff --git a/public/images/emoji/emoji_one/shower.png b/public/images/emoji/emoji_one/shower.png index c794f7765ce..fc908831033 100644 Binary files a/public/images/emoji/emoji_one/shower.png and b/public/images/emoji/emoji_one/shower.png differ diff --git a/public/images/emoji/emoji_one/signal_strength.png b/public/images/emoji/emoji_one/signal_strength.png index b905562cd80..387d383cb74 100644 Binary files a/public/images/emoji/emoji_one/signal_strength.png and b/public/images/emoji/emoji_one/signal_strength.png differ diff --git a/public/images/emoji/emoji_one/six.png b/public/images/emoji/emoji_one/six.png index bf001a11c66..ef292da3b4b 100644 Binary files a/public/images/emoji/emoji_one/six.png and b/public/images/emoji/emoji_one/six.png differ diff --git a/public/images/emoji/emoji_one/six_pointed_star.png b/public/images/emoji/emoji_one/six_pointed_star.png index 2078e2fe0d4..31caba504fa 100644 Binary files a/public/images/emoji/emoji_one/six_pointed_star.png and b/public/images/emoji/emoji_one/six_pointed_star.png differ diff --git a/public/images/emoji/emoji_one/ski.png b/public/images/emoji/emoji_one/ski.png index ac815161916..3ea1bc6e420 100644 Binary files a/public/images/emoji/emoji_one/ski.png and b/public/images/emoji/emoji_one/ski.png differ diff --git a/public/images/emoji/emoji_one/skier.png b/public/images/emoji/emoji_one/skier.png new file mode 100644 index 00000000000..9000b55db4b Binary files /dev/null and b/public/images/emoji/emoji_one/skier.png differ diff --git a/public/images/emoji/emoji_one/skull.png b/public/images/emoji/emoji_one/skull.png index ee66d714726..3527336ec9f 100644 Binary files a/public/images/emoji/emoji_one/skull.png and b/public/images/emoji/emoji_one/skull.png differ diff --git a/public/images/emoji/emoji_one/skull_crossbones.png b/public/images/emoji/emoji_one/skull_crossbones.png new file mode 100644 index 00000000000..08105bf1cc7 Binary files /dev/null and b/public/images/emoji/emoji_one/skull_crossbones.png differ diff --git a/public/images/emoji/emoji_one/sleeping.png b/public/images/emoji/emoji_one/sleeping.png index 68a67595e48..6d1af4f41de 100644 Binary files a/public/images/emoji/emoji_one/sleeping.png and b/public/images/emoji/emoji_one/sleeping.png differ diff --git a/public/images/emoji/emoji_one/sleeping_accommodation.png b/public/images/emoji/emoji_one/sleeping_accommodation.png new file mode 100644 index 00000000000..cd5399bf1e5 Binary files /dev/null and b/public/images/emoji/emoji_one/sleeping_accommodation.png differ diff --git a/public/images/emoji/emoji_one/sleepy.png b/public/images/emoji/emoji_one/sleepy.png index 4e3f47c8f5a..c0fe626fff6 100644 Binary files a/public/images/emoji/emoji_one/sleepy.png and b/public/images/emoji/emoji_one/sleepy.png differ diff --git a/public/images/emoji/emoji_one/slight_frown.png b/public/images/emoji/emoji_one/slight_frown.png new file mode 100644 index 00000000000..0325955e3c6 Binary files /dev/null and b/public/images/emoji/emoji_one/slight_frown.png differ diff --git a/public/images/emoji/emoji_one/slight_smile.png b/public/images/emoji/emoji_one/slight_smile.png new file mode 100644 index 00000000000..0417e8db995 Binary files /dev/null and b/public/images/emoji/emoji_one/slight_smile.png differ diff --git a/public/images/emoji/emoji_one/slightly_smiling.png b/public/images/emoji/emoji_one/slightly_smiling.png new file mode 100644 index 00000000000..5256da45c41 Binary files /dev/null and b/public/images/emoji/emoji_one/slightly_smiling.png differ diff --git a/public/images/emoji/emoji_one/slot_machine.png b/public/images/emoji/emoji_one/slot_machine.png index 81db7b1c0e0..3b14062d9fe 100644 Binary files a/public/images/emoji/emoji_one/slot_machine.png and b/public/images/emoji/emoji_one/slot_machine.png differ diff --git a/public/images/emoji/emoji_one/small_blue_diamond.png b/public/images/emoji/emoji_one/small_blue_diamond.png index 006243c1034..f43bd6b6545 100644 Binary files a/public/images/emoji/emoji_one/small_blue_diamond.png and b/public/images/emoji/emoji_one/small_blue_diamond.png differ diff --git a/public/images/emoji/emoji_one/small_orange_diamond.png b/public/images/emoji/emoji_one/small_orange_diamond.png index cf5fd945976..74a6b8f2e4a 100644 Binary files a/public/images/emoji/emoji_one/small_orange_diamond.png and b/public/images/emoji/emoji_one/small_orange_diamond.png differ diff --git a/public/images/emoji/emoji_one/small_red_triangle.png b/public/images/emoji/emoji_one/small_red_triangle.png index f9864d1238d..87987805169 100644 Binary files a/public/images/emoji/emoji_one/small_red_triangle.png and b/public/images/emoji/emoji_one/small_red_triangle.png differ diff --git a/public/images/emoji/emoji_one/small_red_triangle_down.png b/public/images/emoji/emoji_one/small_red_triangle_down.png index 7a8ebd19bfe..64c4a88ab78 100644 Binary files a/public/images/emoji/emoji_one/small_red_triangle_down.png and b/public/images/emoji/emoji_one/small_red_triangle_down.png differ diff --git a/public/images/emoji/emoji_one/smile.png b/public/images/emoji/emoji_one/smile.png index 05873ba728d..8787803c0c5 100644 Binary files a/public/images/emoji/emoji_one/smile.png and b/public/images/emoji/emoji_one/smile.png differ diff --git a/public/images/emoji/emoji_one/smile_cat.png b/public/images/emoji/emoji_one/smile_cat.png index 8db58061ad5..9578494a9a0 100644 Binary files a/public/images/emoji/emoji_one/smile_cat.png and b/public/images/emoji/emoji_one/smile_cat.png differ diff --git a/public/images/emoji/emoji_one/smiley.png b/public/images/emoji/emoji_one/smiley.png index a33fbf9f92c..c2f5b5fe973 100644 Binary files a/public/images/emoji/emoji_one/smiley.png and b/public/images/emoji/emoji_one/smiley.png differ diff --git a/public/images/emoji/emoji_one/smiley_cat.png b/public/images/emoji/emoji_one/smiley_cat.png index 1610dcfd31c..366d9646920 100644 Binary files a/public/images/emoji/emoji_one/smiley_cat.png and b/public/images/emoji/emoji_one/smiley_cat.png differ diff --git a/public/images/emoji/emoji_one/smiling_imp.png b/public/images/emoji/emoji_one/smiling_imp.png index 594d8f25db9..6af324ca740 100644 Binary files a/public/images/emoji/emoji_one/smiling_imp.png and b/public/images/emoji/emoji_one/smiling_imp.png differ diff --git a/public/images/emoji/emoji_one/smirk.png b/public/images/emoji/emoji_one/smirk.png index 69c37acd7bd..5d639c011c1 100644 Binary files a/public/images/emoji/emoji_one/smirk.png and b/public/images/emoji/emoji_one/smirk.png differ diff --git a/public/images/emoji/emoji_one/smirk_cat.png b/public/images/emoji/emoji_one/smirk_cat.png index 9fe3cd72fd3..4fa7be6f392 100644 Binary files a/public/images/emoji/emoji_one/smirk_cat.png and b/public/images/emoji/emoji_one/smirk_cat.png differ diff --git a/public/images/emoji/emoji_one/smoking.png b/public/images/emoji/emoji_one/smoking.png index c5ff8000232..e0f07b9ae39 100644 Binary files a/public/images/emoji/emoji_one/smoking.png and b/public/images/emoji/emoji_one/smoking.png differ diff --git a/public/images/emoji/emoji_one/snail.png b/public/images/emoji/emoji_one/snail.png index 97f67fb2d37..8214ce46f1a 100644 Binary files a/public/images/emoji/emoji_one/snail.png and b/public/images/emoji/emoji_one/snail.png differ diff --git a/public/images/emoji/emoji_one/snake.png b/public/images/emoji/emoji_one/snake.png index dae731e2204..ba553eaedb1 100644 Binary files a/public/images/emoji/emoji_one/snake.png and b/public/images/emoji/emoji_one/snake.png differ diff --git a/public/images/emoji/emoji_one/snowboarder.png b/public/images/emoji/emoji_one/snowboarder.png index 076c48889c5..12618442c60 100644 Binary files a/public/images/emoji/emoji_one/snowboarder.png and b/public/images/emoji/emoji_one/snowboarder.png differ diff --git a/public/images/emoji/emoji_one/snowflake.png b/public/images/emoji/emoji_one/snowflake.png index e62a5b29e3e..f471d557c72 100644 Binary files a/public/images/emoji/emoji_one/snowflake.png and b/public/images/emoji/emoji_one/snowflake.png differ diff --git a/public/images/emoji/emoji_one/snowman.png b/public/images/emoji/emoji_one/snowman.png index 5cfd23ec02c..a4b99340b58 100644 Binary files a/public/images/emoji/emoji_one/snowman.png and b/public/images/emoji/emoji_one/snowman.png differ diff --git a/public/images/emoji/emoji_one/snowman2.png b/public/images/emoji/emoji_one/snowman2.png new file mode 100644 index 00000000000..d4a0c9e0d99 Binary files /dev/null and b/public/images/emoji/emoji_one/snowman2.png differ diff --git a/public/images/emoji/emoji_one/sob.png b/public/images/emoji/emoji_one/sob.png index 39b85e7ff90..ccf3a606ac6 100644 Binary files a/public/images/emoji/emoji_one/sob.png and b/public/images/emoji/emoji_one/sob.png differ diff --git a/public/images/emoji/emoji_one/soccer.png b/public/images/emoji/emoji_one/soccer.png index 3c285fa6cfc..da456f65df6 100644 Binary files a/public/images/emoji/emoji_one/soccer.png and b/public/images/emoji/emoji_one/soccer.png differ diff --git a/public/images/emoji/emoji_one/soon.png b/public/images/emoji/emoji_one/soon.png index 069beb8e22b..c9acbf0d009 100644 Binary files a/public/images/emoji/emoji_one/soon.png and b/public/images/emoji/emoji_one/soon.png differ diff --git a/public/images/emoji/emoji_one/sos.png b/public/images/emoji/emoji_one/sos.png index 83b011ebc36..8d591e6f5d2 100644 Binary files a/public/images/emoji/emoji_one/sos.png and b/public/images/emoji/emoji_one/sos.png differ diff --git a/public/images/emoji/emoji_one/sound.png b/public/images/emoji/emoji_one/sound.png index 0d7011bcb20..e06a1339f2c 100644 Binary files a/public/images/emoji/emoji_one/sound.png and b/public/images/emoji/emoji_one/sound.png differ diff --git a/public/images/emoji/emoji_one/space_invader.png b/public/images/emoji/emoji_one/space_invader.png index 88554d9656c..1a3ed20fc94 100644 Binary files a/public/images/emoji/emoji_one/space_invader.png and b/public/images/emoji/emoji_one/space_invader.png differ diff --git a/public/images/emoji/emoji_one/spades.png b/public/images/emoji/emoji_one/spades.png index 99cc688573d..848790c2ce6 100644 Binary files a/public/images/emoji/emoji_one/spades.png and b/public/images/emoji/emoji_one/spades.png differ diff --git a/public/images/emoji/emoji_one/spaghetti.png b/public/images/emoji/emoji_one/spaghetti.png index ff15e877a96..380bfd4be19 100644 Binary files a/public/images/emoji/emoji_one/spaghetti.png and b/public/images/emoji/emoji_one/spaghetti.png differ diff --git a/public/images/emoji/emoji_one/sparkle.png b/public/images/emoji/emoji_one/sparkle.png index 73ae3ee69db..58ddbeab49b 100644 Binary files a/public/images/emoji/emoji_one/sparkle.png and b/public/images/emoji/emoji_one/sparkle.png differ diff --git a/public/images/emoji/emoji_one/sparkler.png b/public/images/emoji/emoji_one/sparkler.png index 265e3283387..8080a5708b2 100644 Binary files a/public/images/emoji/emoji_one/sparkler.png and b/public/images/emoji/emoji_one/sparkler.png differ diff --git a/public/images/emoji/emoji_one/sparkles.png b/public/images/emoji/emoji_one/sparkles.png index aa574e0255f..f9b809a71f2 100644 Binary files a/public/images/emoji/emoji_one/sparkles.png and b/public/images/emoji/emoji_one/sparkles.png differ diff --git a/public/images/emoji/emoji_one/sparkling_heart.png b/public/images/emoji/emoji_one/sparkling_heart.png index 0bfffc4ca76..0d3893e293d 100644 Binary files a/public/images/emoji/emoji_one/sparkling_heart.png and b/public/images/emoji/emoji_one/sparkling_heart.png differ diff --git a/public/images/emoji/emoji_one/speak_no_evil.png b/public/images/emoji/emoji_one/speak_no_evil.png index c6f76937f2d..54152b7a0e0 100644 Binary files a/public/images/emoji/emoji_one/speak_no_evil.png and b/public/images/emoji/emoji_one/speak_no_evil.png differ diff --git a/public/images/emoji/emoji_one/speaker.png b/public/images/emoji/emoji_one/speaker.png index 38d5ee391f0..4ea25c4ce14 100644 Binary files a/public/images/emoji/emoji_one/speaker.png and b/public/images/emoji/emoji_one/speaker.png differ diff --git a/public/images/emoji/emoji_one/speaking_head.png b/public/images/emoji/emoji_one/speaking_head.png new file mode 100644 index 00000000000..6fe847e3a2c Binary files /dev/null and b/public/images/emoji/emoji_one/speaking_head.png differ diff --git a/public/images/emoji/emoji_one/speech_balloon.png b/public/images/emoji/emoji_one/speech_balloon.png index 902004e92b2..3d8979725ab 100644 Binary files a/public/images/emoji/emoji_one/speech_balloon.png and b/public/images/emoji/emoji_one/speech_balloon.png differ diff --git a/public/images/emoji/emoji_one/speedboat.png b/public/images/emoji/emoji_one/speedboat.png index 474b052c0d7..0be3f13745e 100644 Binary files a/public/images/emoji/emoji_one/speedboat.png and b/public/images/emoji/emoji_one/speedboat.png differ diff --git a/public/images/emoji/emoji_one/spider.png b/public/images/emoji/emoji_one/spider.png new file mode 100644 index 00000000000..3dc4af311dc Binary files /dev/null and b/public/images/emoji/emoji_one/spider.png differ diff --git a/public/images/emoji/emoji_one/spider_web.png b/public/images/emoji/emoji_one/spider_web.png new file mode 100644 index 00000000000..9eaa5dcddb9 Binary files /dev/null and b/public/images/emoji/emoji_one/spider_web.png differ diff --git a/public/images/emoji/emoji_one/spy.png b/public/images/emoji/emoji_one/spy.png new file mode 100644 index 00000000000..057a54743e4 Binary files /dev/null and b/public/images/emoji/emoji_one/spy.png differ diff --git a/public/images/emoji/emoji_one/stadium.png b/public/images/emoji/emoji_one/stadium.png new file mode 100644 index 00000000000..e1c2547420f Binary files /dev/null and b/public/images/emoji/emoji_one/stadium.png differ diff --git a/public/images/emoji/emoji_one/star.png b/public/images/emoji/emoji_one/star.png index 2c1198caaed..664e4ef2921 100644 Binary files a/public/images/emoji/emoji_one/star.png and b/public/images/emoji/emoji_one/star.png differ diff --git a/public/images/emoji/emoji_one/star2.png b/public/images/emoji/emoji_one/star2.png index 6399b9335b4..914a7556f04 100644 Binary files a/public/images/emoji/emoji_one/star2.png and b/public/images/emoji/emoji_one/star2.png differ diff --git a/public/images/emoji/emoji_one/star_and_crescent.png b/public/images/emoji/emoji_one/star_and_crescent.png new file mode 100644 index 00000000000..c5f8c7cd069 Binary files /dev/null and b/public/images/emoji/emoji_one/star_and_crescent.png differ diff --git a/public/images/emoji/emoji_one/star_of_david.png b/public/images/emoji/emoji_one/star_of_david.png new file mode 100644 index 00000000000..73d3f921cb9 Binary files /dev/null and b/public/images/emoji/emoji_one/star_of_david.png differ diff --git a/public/images/emoji/emoji_one/stars.png b/public/images/emoji/emoji_one/stars.png index 5d2b19ebd9d..e54dc95c3ad 100644 Binary files a/public/images/emoji/emoji_one/stars.png and b/public/images/emoji/emoji_one/stars.png differ diff --git a/public/images/emoji/emoji_one/station.png b/public/images/emoji/emoji_one/station.png index 970d2799d95..a1adf63ca8b 100644 Binary files a/public/images/emoji/emoji_one/station.png and b/public/images/emoji/emoji_one/station.png differ diff --git a/public/images/emoji/emoji_one/statue_of_liberty.png b/public/images/emoji/emoji_one/statue_of_liberty.png index 3ab4414c681..50029e49778 100644 Binary files a/public/images/emoji/emoji_one/statue_of_liberty.png and b/public/images/emoji/emoji_one/statue_of_liberty.png differ diff --git a/public/images/emoji/emoji_one/steam_locomotive.png b/public/images/emoji/emoji_one/steam_locomotive.png index f7c52db713a..75ee6126358 100644 Binary files a/public/images/emoji/emoji_one/steam_locomotive.png and b/public/images/emoji/emoji_one/steam_locomotive.png differ diff --git a/public/images/emoji/emoji_one/stew.png b/public/images/emoji/emoji_one/stew.png index 6f83053386a..b0b44e62cfa 100644 Binary files a/public/images/emoji/emoji_one/stew.png and b/public/images/emoji/emoji_one/stew.png differ diff --git a/public/images/emoji/emoji_one/stop_button.png b/public/images/emoji/emoji_one/stop_button.png new file mode 100644 index 00000000000..66a89743235 Binary files /dev/null and b/public/images/emoji/emoji_one/stop_button.png differ diff --git a/public/images/emoji/emoji_one/stopwatch.png b/public/images/emoji/emoji_one/stopwatch.png new file mode 100644 index 00000000000..4d755287446 Binary files /dev/null and b/public/images/emoji/emoji_one/stopwatch.png differ diff --git a/public/images/emoji/emoji_one/straight_ruler.png b/public/images/emoji/emoji_one/straight_ruler.png index 42e7ac39cfa..4594f768035 100644 Binary files a/public/images/emoji/emoji_one/straight_ruler.png and b/public/images/emoji/emoji_one/straight_ruler.png differ diff --git a/public/images/emoji/emoji_one/strawberry.png b/public/images/emoji/emoji_one/strawberry.png index b28837732e1..ec42484ced6 100644 Binary files a/public/images/emoji/emoji_one/strawberry.png and b/public/images/emoji/emoji_one/strawberry.png differ diff --git a/public/images/emoji/emoji_one/stuck_out_tongue.png b/public/images/emoji/emoji_one/stuck_out_tongue.png index 3b25a869a3d..89a7a57c0a6 100644 Binary files a/public/images/emoji/emoji_one/stuck_out_tongue.png and b/public/images/emoji/emoji_one/stuck_out_tongue.png differ diff --git a/public/images/emoji/emoji_one/stuck_out_tongue_closed_eyes.png b/public/images/emoji/emoji_one/stuck_out_tongue_closed_eyes.png index e4733765902..6bb1df0d710 100644 Binary files a/public/images/emoji/emoji_one/stuck_out_tongue_closed_eyes.png and b/public/images/emoji/emoji_one/stuck_out_tongue_closed_eyes.png differ diff --git a/public/images/emoji/emoji_one/stuck_out_tongue_winking_eye.png b/public/images/emoji/emoji_one/stuck_out_tongue_winking_eye.png index fdae18df7dd..023614486da 100644 Binary files a/public/images/emoji/emoji_one/stuck_out_tongue_winking_eye.png and b/public/images/emoji/emoji_one/stuck_out_tongue_winking_eye.png differ diff --git a/public/images/emoji/emoji_one/sun_with_face.png b/public/images/emoji/emoji_one/sun_with_face.png index 7ee45e4dd14..4254ff4d48c 100644 Binary files a/public/images/emoji/emoji_one/sun_with_face.png and b/public/images/emoji/emoji_one/sun_with_face.png differ diff --git a/public/images/emoji/emoji_one/sunflower.png b/public/images/emoji/emoji_one/sunflower.png index b7cfbf82b41..42eb11dc3e9 100644 Binary files a/public/images/emoji/emoji_one/sunflower.png and b/public/images/emoji/emoji_one/sunflower.png differ diff --git a/public/images/emoji/emoji_one/sunglasses.png b/public/images/emoji/emoji_one/sunglasses.png index 4d622376600..ac9a13a43d5 100644 Binary files a/public/images/emoji/emoji_one/sunglasses.png and b/public/images/emoji/emoji_one/sunglasses.png differ diff --git a/public/images/emoji/emoji_one/sunny.png b/public/images/emoji/emoji_one/sunny.png index d857f703a6e..9aeee22318b 100644 Binary files a/public/images/emoji/emoji_one/sunny.png and b/public/images/emoji/emoji_one/sunny.png differ diff --git a/public/images/emoji/emoji_one/sunrise.png b/public/images/emoji/emoji_one/sunrise.png index 3d17e794a53..fdc6d9046f6 100644 Binary files a/public/images/emoji/emoji_one/sunrise.png and b/public/images/emoji/emoji_one/sunrise.png differ diff --git a/public/images/emoji/emoji_one/sunrise_over_mountains.png b/public/images/emoji/emoji_one/sunrise_over_mountains.png index c1c30134d96..704ae046512 100644 Binary files a/public/images/emoji/emoji_one/sunrise_over_mountains.png and b/public/images/emoji/emoji_one/sunrise_over_mountains.png differ diff --git a/public/images/emoji/emoji_one/surfer.png b/public/images/emoji/emoji_one/surfer.png index 85cf23a6e74..601a6dfa58f 100644 Binary files a/public/images/emoji/emoji_one/surfer.png and b/public/images/emoji/emoji_one/surfer.png differ diff --git a/public/images/emoji/emoji_one/sushi.png b/public/images/emoji/emoji_one/sushi.png index 8c2f6826e05..396e1af4abf 100644 Binary files a/public/images/emoji/emoji_one/sushi.png and b/public/images/emoji/emoji_one/sushi.png differ diff --git a/public/images/emoji/emoji_one/suspension_railway.png b/public/images/emoji/emoji_one/suspension_railway.png index 2c5ff64a16b..ad32876e81b 100644 Binary files a/public/images/emoji/emoji_one/suspension_railway.png and b/public/images/emoji/emoji_one/suspension_railway.png differ diff --git a/public/images/emoji/emoji_one/sweat.png b/public/images/emoji/emoji_one/sweat.png index 1aee2558cfe..5aca2e3a6bf 100644 Binary files a/public/images/emoji/emoji_one/sweat.png and b/public/images/emoji/emoji_one/sweat.png differ diff --git a/public/images/emoji/emoji_one/sweat_drops.png b/public/images/emoji/emoji_one/sweat_drops.png index 3a48a0a7fc2..8023fbd68f2 100644 Binary files a/public/images/emoji/emoji_one/sweat_drops.png and b/public/images/emoji/emoji_one/sweat_drops.png differ diff --git a/public/images/emoji/emoji_one/sweat_smile.png b/public/images/emoji/emoji_one/sweat_smile.png index 09e8bf7fc6d..e73ccb9db0f 100644 Binary files a/public/images/emoji/emoji_one/sweat_smile.png and b/public/images/emoji/emoji_one/sweat_smile.png differ diff --git a/public/images/emoji/emoji_one/sweet_potato.png b/public/images/emoji/emoji_one/sweet_potato.png index 7c60e76cbe0..e4c5129777e 100644 Binary files a/public/images/emoji/emoji_one/sweet_potato.png and b/public/images/emoji/emoji_one/sweet_potato.png differ diff --git a/public/images/emoji/emoji_one/swimmer.png b/public/images/emoji/emoji_one/swimmer.png index ed2b641ab2e..4d6fce737ec 100644 Binary files a/public/images/emoji/emoji_one/swimmer.png and b/public/images/emoji/emoji_one/swimmer.png differ diff --git a/public/images/emoji/emoji_one/symbols.png b/public/images/emoji/emoji_one/symbols.png index 4958f104e63..28c5b0cc455 100644 Binary files a/public/images/emoji/emoji_one/symbols.png and b/public/images/emoji/emoji_one/symbols.png differ diff --git a/public/images/emoji/emoji_one/synagogue.png b/public/images/emoji/emoji_one/synagogue.png new file mode 100644 index 00000000000..5b092e01743 Binary files /dev/null and b/public/images/emoji/emoji_one/synagogue.png differ diff --git a/public/images/emoji/emoji_one/syringe.png b/public/images/emoji/emoji_one/syringe.png index 73eed8cde9a..99b6bad8dd7 100644 Binary files a/public/images/emoji/emoji_one/syringe.png and b/public/images/emoji/emoji_one/syringe.png differ diff --git a/public/images/emoji/emoji_one/taco.png b/public/images/emoji/emoji_one/taco.png new file mode 100644 index 00000000000..b3a126a781d Binary files /dev/null and b/public/images/emoji/emoji_one/taco.png differ diff --git a/public/images/emoji/emoji_one/tada.png b/public/images/emoji/emoji_one/tada.png index 003a669964f..2e1835f56dc 100644 Binary files a/public/images/emoji/emoji_one/tada.png and b/public/images/emoji/emoji_one/tada.png differ diff --git a/public/images/emoji/emoji_one/tanabata_tree.png b/public/images/emoji/emoji_one/tanabata_tree.png index ec7d8cc229e..b8f38660ddb 100644 Binary files a/public/images/emoji/emoji_one/tanabata_tree.png and b/public/images/emoji/emoji_one/tanabata_tree.png differ diff --git a/public/images/emoji/emoji_one/tangerine.png b/public/images/emoji/emoji_one/tangerine.png index 7cb15fcf79e..0bc5b984b7c 100644 Binary files a/public/images/emoji/emoji_one/tangerine.png and b/public/images/emoji/emoji_one/tangerine.png differ diff --git a/public/images/emoji/emoji_one/taurus.png b/public/images/emoji/emoji_one/taurus.png index 10426ef7467..8664f28944e 100644 Binary files a/public/images/emoji/emoji_one/taurus.png and b/public/images/emoji/emoji_one/taurus.png differ diff --git a/public/images/emoji/emoji_one/taxi.png b/public/images/emoji/emoji_one/taxi.png index 8652b1f294e..96284b10f6e 100644 Binary files a/public/images/emoji/emoji_one/taxi.png and b/public/images/emoji/emoji_one/taxi.png differ diff --git a/public/images/emoji/emoji_one/tea.png b/public/images/emoji/emoji_one/tea.png index 898815bb5fa..7eb3b69b332 100644 Binary files a/public/images/emoji/emoji_one/tea.png and b/public/images/emoji/emoji_one/tea.png differ diff --git a/public/images/emoji/emoji_one/telephone.png b/public/images/emoji/emoji_one/telephone.png index 6a14f1bfe91..0372a9c5029 100644 Binary files a/public/images/emoji/emoji_one/telephone.png and b/public/images/emoji/emoji_one/telephone.png differ diff --git a/public/images/emoji/emoji_one/telephone_receiver.png b/public/images/emoji/emoji_one/telephone_receiver.png index 6a8259cb7c1..5ad26a12953 100644 Binary files a/public/images/emoji/emoji_one/telephone_receiver.png and b/public/images/emoji/emoji_one/telephone_receiver.png differ diff --git a/public/images/emoji/emoji_one/telescope.png b/public/images/emoji/emoji_one/telescope.png index 8fc07d50fef..679fe397fd4 100644 Binary files a/public/images/emoji/emoji_one/telescope.png and b/public/images/emoji/emoji_one/telescope.png differ diff --git a/public/images/emoji/emoji_one/ten.png b/public/images/emoji/emoji_one/ten.png new file mode 100644 index 00000000000..ea9109e26a9 Binary files /dev/null and b/public/images/emoji/emoji_one/ten.png differ diff --git a/public/images/emoji/emoji_one/tennis.png b/public/images/emoji/emoji_one/tennis.png index 26288eb2384..8ee3c3b8393 100644 Binary files a/public/images/emoji/emoji_one/tennis.png and b/public/images/emoji/emoji_one/tennis.png differ diff --git a/public/images/emoji/emoji_one/tent.png b/public/images/emoji/emoji_one/tent.png index d1c4fe63dc3..adb12c0f05e 100644 Binary files a/public/images/emoji/emoji_one/tent.png and b/public/images/emoji/emoji_one/tent.png differ diff --git a/public/images/emoji/emoji_one/thermometer.png b/public/images/emoji/emoji_one/thermometer.png new file mode 100644 index 00000000000..b5568957add Binary files /dev/null and b/public/images/emoji/emoji_one/thermometer.png differ diff --git a/public/images/emoji/emoji_one/thermometer_face.png b/public/images/emoji/emoji_one/thermometer_face.png new file mode 100644 index 00000000000..0047a145601 Binary files /dev/null and b/public/images/emoji/emoji_one/thermometer_face.png differ diff --git a/public/images/emoji/emoji_one/thinking.png b/public/images/emoji/emoji_one/thinking.png new file mode 100644 index 00000000000..588362c8740 Binary files /dev/null and b/public/images/emoji/emoji_one/thinking.png differ diff --git a/public/images/emoji/emoji_one/thought_balloon.png b/public/images/emoji/emoji_one/thought_balloon.png index 5a436d9e847..e3c08348d66 100644 Binary files a/public/images/emoji/emoji_one/thought_balloon.png and b/public/images/emoji/emoji_one/thought_balloon.png differ diff --git a/public/images/emoji/emoji_one/three.png b/public/images/emoji/emoji_one/three.png index d50fa340678..c295886f407 100644 Binary files a/public/images/emoji/emoji_one/three.png and b/public/images/emoji/emoji_one/three.png differ diff --git a/public/images/emoji/emoji_one/thumbsdown.png b/public/images/emoji/emoji_one/thumbsdown.png index 9b6d251b543..b3327789a6d 100644 Binary files a/public/images/emoji/emoji_one/thumbsdown.png and b/public/images/emoji/emoji_one/thumbsdown.png differ diff --git a/public/images/emoji/emoji_one/thumbsup.png b/public/images/emoji/emoji_one/thumbsup.png index 0eca450d597..4fd63b22d4e 100644 Binary files a/public/images/emoji/emoji_one/thumbsup.png and b/public/images/emoji/emoji_one/thumbsup.png differ diff --git a/public/images/emoji/emoji_one/thunder_cloud_rain.png b/public/images/emoji/emoji_one/thunder_cloud_rain.png new file mode 100644 index 00000000000..ba43488b8ee Binary files /dev/null and b/public/images/emoji/emoji_one/thunder_cloud_rain.png differ diff --git a/public/images/emoji/emoji_one/ticket.png b/public/images/emoji/emoji_one/ticket.png index 460cb44c3ff..22a1376ee0b 100644 Binary files a/public/images/emoji/emoji_one/ticket.png and b/public/images/emoji/emoji_one/ticket.png differ diff --git a/public/images/emoji/emoji_one/tickets.png b/public/images/emoji/emoji_one/tickets.png new file mode 100644 index 00000000000..61866239d80 Binary files /dev/null and b/public/images/emoji/emoji_one/tickets.png differ diff --git a/public/images/emoji/emoji_one/tiger.png b/public/images/emoji/emoji_one/tiger.png index 64a19cd61e5..14855d661af 100644 Binary files a/public/images/emoji/emoji_one/tiger.png and b/public/images/emoji/emoji_one/tiger.png differ diff --git a/public/images/emoji/emoji_one/tiger2.png b/public/images/emoji/emoji_one/tiger2.png index c7910315e5c..60fce595fd8 100644 Binary files a/public/images/emoji/emoji_one/tiger2.png and b/public/images/emoji/emoji_one/tiger2.png differ diff --git a/public/images/emoji/emoji_one/timer.png b/public/images/emoji/emoji_one/timer.png new file mode 100644 index 00000000000..584922da25d Binary files /dev/null and b/public/images/emoji/emoji_one/timer.png differ diff --git a/public/images/emoji/emoji_one/tired_face.png b/public/images/emoji/emoji_one/tired_face.png index 641d8d83380..29b47345545 100644 Binary files a/public/images/emoji/emoji_one/tired_face.png and b/public/images/emoji/emoji_one/tired_face.png differ diff --git a/public/images/emoji/emoji_one/tm.png b/public/images/emoji/emoji_one/tm.png index 8b379296833..51e7be5bd3b 100644 Binary files a/public/images/emoji/emoji_one/tm.png and b/public/images/emoji/emoji_one/tm.png differ diff --git a/public/images/emoji/emoji_one/toilet.png b/public/images/emoji/emoji_one/toilet.png index ab811075fdf..e6fd35e0ee4 100644 Binary files a/public/images/emoji/emoji_one/toilet.png and b/public/images/emoji/emoji_one/toilet.png differ diff --git a/public/images/emoji/emoji_one/tokyo_tower.png b/public/images/emoji/emoji_one/tokyo_tower.png index 22abea95fbc..eab230fbb62 100644 Binary files a/public/images/emoji/emoji_one/tokyo_tower.png and b/public/images/emoji/emoji_one/tokyo_tower.png differ diff --git a/public/images/emoji/emoji_one/tomato.png b/public/images/emoji/emoji_one/tomato.png index 4114c35ffb4..eb0f4f48553 100644 Binary files a/public/images/emoji/emoji_one/tomato.png and b/public/images/emoji/emoji_one/tomato.png differ diff --git a/public/images/emoji/emoji_one/tongue.png b/public/images/emoji/emoji_one/tongue.png index aaf1e0b2945..7ae527b0d41 100644 Binary files a/public/images/emoji/emoji_one/tongue.png and b/public/images/emoji/emoji_one/tongue.png differ diff --git a/public/images/emoji/emoji_one/tools.png b/public/images/emoji/emoji_one/tools.png new file mode 100644 index 00000000000..dfb667419d8 Binary files /dev/null and b/public/images/emoji/emoji_one/tools.png differ diff --git a/public/images/emoji/emoji_one/top.png b/public/images/emoji/emoji_one/top.png index e744f94e730..1d91f9ec11e 100644 Binary files a/public/images/emoji/emoji_one/top.png and b/public/images/emoji/emoji_one/top.png differ diff --git a/public/images/emoji/emoji_one/tophat.png b/public/images/emoji/emoji_one/tophat.png index 70c972bd284..b1b9f6b28c5 100644 Binary files a/public/images/emoji/emoji_one/tophat.png and b/public/images/emoji/emoji_one/tophat.png differ diff --git a/public/images/emoji/emoji_one/track_next.png b/public/images/emoji/emoji_one/track_next.png new file mode 100644 index 00000000000..9bf5647f7f0 Binary files /dev/null and b/public/images/emoji/emoji_one/track_next.png differ diff --git a/public/images/emoji/emoji_one/track_previous.png b/public/images/emoji/emoji_one/track_previous.png new file mode 100644 index 00000000000..1fd22e0f70e Binary files /dev/null and b/public/images/emoji/emoji_one/track_previous.png differ diff --git a/public/images/emoji/emoji_one/trackball.png b/public/images/emoji/emoji_one/trackball.png new file mode 100644 index 00000000000..a5d82442417 Binary files /dev/null and b/public/images/emoji/emoji_one/trackball.png differ diff --git a/public/images/emoji/emoji_one/tractor.png b/public/images/emoji/emoji_one/tractor.png index fcd4000c56c..78615d7acd8 100644 Binary files a/public/images/emoji/emoji_one/tractor.png and b/public/images/emoji/emoji_one/tractor.png differ diff --git a/public/images/emoji/emoji_one/traffic_light.png b/public/images/emoji/emoji_one/traffic_light.png index 9add0f5bb6d..c3dde0cfedd 100644 Binary files a/public/images/emoji/emoji_one/traffic_light.png and b/public/images/emoji/emoji_one/traffic_light.png differ diff --git a/public/images/emoji/emoji_one/train.png b/public/images/emoji/emoji_one/train.png index fc015d4c3b7..f85fcffe068 100644 Binary files a/public/images/emoji/emoji_one/train.png and b/public/images/emoji/emoji_one/train.png differ diff --git a/public/images/emoji/emoji_one/train2.png b/public/images/emoji/emoji_one/train2.png index 22d8433022b..ba3ca63aba7 100644 Binary files a/public/images/emoji/emoji_one/train2.png and b/public/images/emoji/emoji_one/train2.png differ diff --git a/public/images/emoji/emoji_one/tram.png b/public/images/emoji/emoji_one/tram.png index 851cf182741..d57ac3d5bb8 100644 Binary files a/public/images/emoji/emoji_one/tram.png and b/public/images/emoji/emoji_one/tram.png differ diff --git a/public/images/emoji/emoji_one/triangular_flag_on_post.png b/public/images/emoji/emoji_one/triangular_flag_on_post.png index 180d6cf278b..bad7c4ed08a 100644 Binary files a/public/images/emoji/emoji_one/triangular_flag_on_post.png and b/public/images/emoji/emoji_one/triangular_flag_on_post.png differ diff --git a/public/images/emoji/emoji_one/triangular_ruler.png b/public/images/emoji/emoji_one/triangular_ruler.png index 1dec6a2d4f0..6416c3f5d92 100644 Binary files a/public/images/emoji/emoji_one/triangular_ruler.png and b/public/images/emoji/emoji_one/triangular_ruler.png differ diff --git a/public/images/emoji/emoji_one/trident.png b/public/images/emoji/emoji_one/trident.png index ae1e0bc8839..665005272be 100644 Binary files a/public/images/emoji/emoji_one/trident.png and b/public/images/emoji/emoji_one/trident.png differ diff --git a/public/images/emoji/emoji_one/triumph.png b/public/images/emoji/emoji_one/triumph.png index ba927f8c1ed..19f3c32ec21 100644 Binary files a/public/images/emoji/emoji_one/triumph.png and b/public/images/emoji/emoji_one/triumph.png differ diff --git a/public/images/emoji/emoji_one/trolleybus.png b/public/images/emoji/emoji_one/trolleybus.png index 5207d82da81..236a745c662 100644 Binary files a/public/images/emoji/emoji_one/trolleybus.png and b/public/images/emoji/emoji_one/trolleybus.png differ diff --git a/public/images/emoji/emoji_one/trophy.png b/public/images/emoji/emoji_one/trophy.png index 38429fe197f..e380c355b82 100644 Binary files a/public/images/emoji/emoji_one/trophy.png and b/public/images/emoji/emoji_one/trophy.png differ diff --git a/public/images/emoji/emoji_one/tropical_drink.png b/public/images/emoji/emoji_one/tropical_drink.png index aa0f2ee7eaf..01e6e63407a 100644 Binary files a/public/images/emoji/emoji_one/tropical_drink.png and b/public/images/emoji/emoji_one/tropical_drink.png differ diff --git a/public/images/emoji/emoji_one/tropical_fish.png b/public/images/emoji/emoji_one/tropical_fish.png index 1904f61be27..78cc3ae41bc 100644 Binary files a/public/images/emoji/emoji_one/tropical_fish.png and b/public/images/emoji/emoji_one/tropical_fish.png differ diff --git a/public/images/emoji/emoji_one/truck.png b/public/images/emoji/emoji_one/truck.png index ef99f12fb29..c3a88e135ad 100644 Binary files a/public/images/emoji/emoji_one/truck.png and b/public/images/emoji/emoji_one/truck.png differ diff --git a/public/images/emoji/emoji_one/trumpet.png b/public/images/emoji/emoji_one/trumpet.png index c2270ccbfc1..9d99109be62 100644 Binary files a/public/images/emoji/emoji_one/trumpet.png and b/public/images/emoji/emoji_one/trumpet.png differ diff --git a/public/images/emoji/emoji_one/tshirt.png b/public/images/emoji/emoji_one/tshirt.png index 556efde26e9..06550d9228a 100644 Binary files a/public/images/emoji/emoji_one/tshirt.png and b/public/images/emoji/emoji_one/tshirt.png differ diff --git a/public/images/emoji/emoji_one/tulip.png b/public/images/emoji/emoji_one/tulip.png index a05a51edfa0..b3431abd164 100644 Binary files a/public/images/emoji/emoji_one/tulip.png and b/public/images/emoji/emoji_one/tulip.png differ diff --git a/public/images/emoji/emoji_one/turkey.png b/public/images/emoji/emoji_one/turkey.png new file mode 100644 index 00000000000..2a47cf2d1e3 Binary files /dev/null and b/public/images/emoji/emoji_one/turkey.png differ diff --git a/public/images/emoji/emoji_one/turtle.png b/public/images/emoji/emoji_one/turtle.png index c3a628c0a81..af1fb8fb2c1 100644 Binary files a/public/images/emoji/emoji_one/turtle.png and b/public/images/emoji/emoji_one/turtle.png differ diff --git a/public/images/emoji/emoji_one/tv.png b/public/images/emoji/emoji_one/tv.png index 5318e2dc86a..4e5e70ac5d5 100644 Binary files a/public/images/emoji/emoji_one/tv.png and b/public/images/emoji/emoji_one/tv.png differ diff --git a/public/images/emoji/emoji_one/twisted_rightwards_arrows.png b/public/images/emoji/emoji_one/twisted_rightwards_arrows.png index 8ddb38cb5a3..4b75d061c8a 100644 Binary files a/public/images/emoji/emoji_one/twisted_rightwards_arrows.png and b/public/images/emoji/emoji_one/twisted_rightwards_arrows.png differ diff --git a/public/images/emoji/emoji_one/two.png b/public/images/emoji/emoji_one/two.png index 2a5423968b9..84f604a62b6 100644 Binary files a/public/images/emoji/emoji_one/two.png and b/public/images/emoji/emoji_one/two.png differ diff --git a/public/images/emoji/emoji_one/two_hearts.png b/public/images/emoji/emoji_one/two_hearts.png index 818a3932c97..85ef52e25c1 100644 Binary files a/public/images/emoji/emoji_one/two_hearts.png and b/public/images/emoji/emoji_one/two_hearts.png differ diff --git a/public/images/emoji/emoji_one/two_men_holding_hands.png b/public/images/emoji/emoji_one/two_men_holding_hands.png index a9328449f0b..919b1afc802 100644 Binary files a/public/images/emoji/emoji_one/two_men_holding_hands.png and b/public/images/emoji/emoji_one/two_men_holding_hands.png differ diff --git a/public/images/emoji/emoji_one/two_women_holding_hands.png b/public/images/emoji/emoji_one/two_women_holding_hands.png index 5c28e28d2ec..75aeb31daa1 100644 Binary files a/public/images/emoji/emoji_one/two_women_holding_hands.png and b/public/images/emoji/emoji_one/two_women_holding_hands.png differ diff --git a/public/images/emoji/emoji_one/u5272.png b/public/images/emoji/emoji_one/u5272.png index 9961a4c322a..de8cdf53ccf 100644 Binary files a/public/images/emoji/emoji_one/u5272.png and b/public/images/emoji/emoji_one/u5272.png differ diff --git a/public/images/emoji/emoji_one/u5408.png b/public/images/emoji/emoji_one/u5408.png index 77883fdb2df..3b006eb00f7 100644 Binary files a/public/images/emoji/emoji_one/u5408.png and b/public/images/emoji/emoji_one/u5408.png differ diff --git a/public/images/emoji/emoji_one/u55b6.png b/public/images/emoji/emoji_one/u55b6.png index 53e786b8ab9..c9c4543a77b 100644 Binary files a/public/images/emoji/emoji_one/u55b6.png and b/public/images/emoji/emoji_one/u55b6.png differ diff --git a/public/images/emoji/emoji_one/u6307.png b/public/images/emoji/emoji_one/u6307.png index 85af968abcc..edcc78e6dc8 100644 Binary files a/public/images/emoji/emoji_one/u6307.png and b/public/images/emoji/emoji_one/u6307.png differ diff --git a/public/images/emoji/emoji_one/u6708.png b/public/images/emoji/emoji_one/u6708.png index 8d21aeccfcd..42b50a98a1b 100644 Binary files a/public/images/emoji/emoji_one/u6708.png and b/public/images/emoji/emoji_one/u6708.png differ diff --git a/public/images/emoji/emoji_one/u6709.png b/public/images/emoji/emoji_one/u6709.png index 002991d631f..63519dbcc77 100644 Binary files a/public/images/emoji/emoji_one/u6709.png and b/public/images/emoji/emoji_one/u6709.png differ diff --git a/public/images/emoji/emoji_one/u6e80.png b/public/images/emoji/emoji_one/u6e80.png index d2c2a9f8606..5e502c94469 100644 Binary files a/public/images/emoji/emoji_one/u6e80.png and b/public/images/emoji/emoji_one/u6e80.png differ diff --git a/public/images/emoji/emoji_one/u7121.png b/public/images/emoji/emoji_one/u7121.png index 1ae53d1a7ce..4d8cbfac3a9 100644 Binary files a/public/images/emoji/emoji_one/u7121.png and b/public/images/emoji/emoji_one/u7121.png differ diff --git a/public/images/emoji/emoji_one/u7533.png b/public/images/emoji/emoji_one/u7533.png index ce57dede38e..fe1c44dfc2b 100644 Binary files a/public/images/emoji/emoji_one/u7533.png and b/public/images/emoji/emoji_one/u7533.png differ diff --git a/public/images/emoji/emoji_one/u7981.png b/public/images/emoji/emoji_one/u7981.png index 2162850e95b..a8a8e956d45 100644 Binary files a/public/images/emoji/emoji_one/u7981.png and b/public/images/emoji/emoji_one/u7981.png differ diff --git a/public/images/emoji/emoji_one/u7a7a.png b/public/images/emoji/emoji_one/u7a7a.png index 8237cfa303e..d80b6c88a5b 100644 Binary files a/public/images/emoji/emoji_one/u7a7a.png and b/public/images/emoji/emoji_one/u7a7a.png differ diff --git a/public/images/emoji/emoji_one/uk.png b/public/images/emoji/emoji_one/uk.png index 61c03f759fd..00843f11937 100644 Binary files a/public/images/emoji/emoji_one/uk.png and b/public/images/emoji/emoji_one/uk.png differ diff --git a/public/images/emoji/emoji_one/umbrella.png b/public/images/emoji/emoji_one/umbrella.png index 7a172a4e6bb..67683e7a4e9 100644 Binary files a/public/images/emoji/emoji_one/umbrella.png and b/public/images/emoji/emoji_one/umbrella.png differ diff --git a/public/images/emoji/emoji_one/umbrella2.png b/public/images/emoji/emoji_one/umbrella2.png new file mode 100644 index 00000000000..e1857c1fd79 Binary files /dev/null and b/public/images/emoji/emoji_one/umbrella2.png differ diff --git a/public/images/emoji/emoji_one/unamused.png b/public/images/emoji/emoji_one/unamused.png index 83a7e92ece1..99dc06770ac 100644 Binary files a/public/images/emoji/emoji_one/unamused.png and b/public/images/emoji/emoji_one/unamused.png differ diff --git a/public/images/emoji/emoji_one/underage.png b/public/images/emoji/emoji_one/underage.png index 603ce57eae9..ce253e50bc5 100644 Binary files a/public/images/emoji/emoji_one/underage.png and b/public/images/emoji/emoji_one/underage.png differ diff --git a/public/images/emoji/emoji_one/unicorn.png b/public/images/emoji/emoji_one/unicorn.png new file mode 100644 index 00000000000..dca45abbd50 Binary files /dev/null and b/public/images/emoji/emoji_one/unicorn.png differ diff --git a/public/images/emoji/emoji_one/unlock.png b/public/images/emoji/emoji_one/unlock.png index f2f46d93492..99451d98d0a 100644 Binary files a/public/images/emoji/emoji_one/unlock.png and b/public/images/emoji/emoji_one/unlock.png differ diff --git a/public/images/emoji/emoji_one/up.png b/public/images/emoji/emoji_one/up.png index 1dc334a6bb3..7883e0ef8bd 100644 Binary files a/public/images/emoji/emoji_one/up.png and b/public/images/emoji/emoji_one/up.png differ diff --git a/public/images/emoji/emoji_one/upside_down.png b/public/images/emoji/emoji_one/upside_down.png new file mode 100644 index 00000000000..d097e4f97d5 Binary files /dev/null and b/public/images/emoji/emoji_one/upside_down.png differ diff --git a/public/images/emoji/emoji_one/urn.png b/public/images/emoji/emoji_one/urn.png new file mode 100644 index 00000000000..9d934bad0cd Binary files /dev/null and b/public/images/emoji/emoji_one/urn.png differ diff --git a/public/images/emoji/emoji_one/us.png b/public/images/emoji/emoji_one/us.png index 51c1e8477e0..facfafd625d 100644 Binary files a/public/images/emoji/emoji_one/us.png and b/public/images/emoji/emoji_one/us.png differ diff --git a/public/images/emoji/emoji_one/v.png b/public/images/emoji/emoji_one/v.png index f534f8a0b7d..d462d938905 100644 Binary files a/public/images/emoji/emoji_one/v.png and b/public/images/emoji/emoji_one/v.png differ diff --git a/public/images/emoji/emoji_one/vertical_traffic_light.png b/public/images/emoji/emoji_one/vertical_traffic_light.png index 113c78fa63c..82e7533c3b9 100644 Binary files a/public/images/emoji/emoji_one/vertical_traffic_light.png and b/public/images/emoji/emoji_one/vertical_traffic_light.png differ diff --git a/public/images/emoji/emoji_one/vhs.png b/public/images/emoji/emoji_one/vhs.png index cbc657b7567..6bd49dd5a2a 100644 Binary files a/public/images/emoji/emoji_one/vhs.png and b/public/images/emoji/emoji_one/vhs.png differ diff --git a/public/images/emoji/emoji_one/vibration_mode.png b/public/images/emoji/emoji_one/vibration_mode.png index 1a772ac1556..a8a42cb0fcc 100644 Binary files a/public/images/emoji/emoji_one/vibration_mode.png and b/public/images/emoji/emoji_one/vibration_mode.png differ diff --git a/public/images/emoji/emoji_one/video_camera.png b/public/images/emoji/emoji_one/video_camera.png index 0d64766e296..61b17889949 100644 Binary files a/public/images/emoji/emoji_one/video_camera.png and b/public/images/emoji/emoji_one/video_camera.png differ diff --git a/public/images/emoji/emoji_one/video_game.png b/public/images/emoji/emoji_one/video_game.png index 702832e99d3..23e1ef1babf 100644 Binary files a/public/images/emoji/emoji_one/video_game.png and b/public/images/emoji/emoji_one/video_game.png differ diff --git a/public/images/emoji/emoji_one/violin.png b/public/images/emoji/emoji_one/violin.png index 0bb8e0a10fd..7d7a45dea30 100644 Binary files a/public/images/emoji/emoji_one/violin.png and b/public/images/emoji/emoji_one/violin.png differ diff --git a/public/images/emoji/emoji_one/virgo.png b/public/images/emoji/emoji_one/virgo.png index 322502928c9..d4dd07d5148 100644 Binary files a/public/images/emoji/emoji_one/virgo.png and b/public/images/emoji/emoji_one/virgo.png differ diff --git a/public/images/emoji/emoji_one/volcano.png b/public/images/emoji/emoji_one/volcano.png index 5f2c292f020..a13aeda91d0 100644 Binary files a/public/images/emoji/emoji_one/volcano.png and b/public/images/emoji/emoji_one/volcano.png differ diff --git a/public/images/emoji/emoji_one/volleyball.png b/public/images/emoji/emoji_one/volleyball.png new file mode 100644 index 00000000000..f93768a3788 Binary files /dev/null and b/public/images/emoji/emoji_one/volleyball.png differ diff --git a/public/images/emoji/emoji_one/vs.png b/public/images/emoji/emoji_one/vs.png index 4c4bd41e844..07d73de0348 100644 Binary files a/public/images/emoji/emoji_one/vs.png and b/public/images/emoji/emoji_one/vs.png differ diff --git a/public/images/emoji/emoji_one/vulcan.png b/public/images/emoji/emoji_one/vulcan.png new file mode 100644 index 00000000000..21beed5b608 Binary files /dev/null and b/public/images/emoji/emoji_one/vulcan.png differ diff --git a/public/images/emoji/emoji_one/walking.png b/public/images/emoji/emoji_one/walking.png index 780df9f4759..5fde426f126 100644 Binary files a/public/images/emoji/emoji_one/walking.png and b/public/images/emoji/emoji_one/walking.png differ diff --git a/public/images/emoji/emoji_one/waning_crescent_moon.png b/public/images/emoji/emoji_one/waning_crescent_moon.png index f9ab41111e9..444525c65dd 100644 Binary files a/public/images/emoji/emoji_one/waning_crescent_moon.png and b/public/images/emoji/emoji_one/waning_crescent_moon.png differ diff --git a/public/images/emoji/emoji_one/waning_gibbous_moon.png b/public/images/emoji/emoji_one/waning_gibbous_moon.png index 3b9240298ef..7341413c725 100644 Binary files a/public/images/emoji/emoji_one/waning_gibbous_moon.png and b/public/images/emoji/emoji_one/waning_gibbous_moon.png differ diff --git a/public/images/emoji/emoji_one/warning.png b/public/images/emoji/emoji_one/warning.png index da0bfd5402c..c29bce44a70 100644 Binary files a/public/images/emoji/emoji_one/warning.png and b/public/images/emoji/emoji_one/warning.png differ diff --git a/public/images/emoji/emoji_one/wastebasket.png b/public/images/emoji/emoji_one/wastebasket.png new file mode 100644 index 00000000000..952d9a962d1 Binary files /dev/null and b/public/images/emoji/emoji_one/wastebasket.png differ diff --git a/public/images/emoji/emoji_one/watch.png b/public/images/emoji/emoji_one/watch.png index 50f16588a1c..d48ca108363 100644 Binary files a/public/images/emoji/emoji_one/watch.png and b/public/images/emoji/emoji_one/watch.png differ diff --git a/public/images/emoji/emoji_one/water_buffalo.png b/public/images/emoji/emoji_one/water_buffalo.png index 2c8fa68e8c4..844f69d47af 100644 Binary files a/public/images/emoji/emoji_one/water_buffalo.png and b/public/images/emoji/emoji_one/water_buffalo.png differ diff --git a/public/images/emoji/emoji_one/watermelon.png b/public/images/emoji/emoji_one/watermelon.png index 5125aea3e3d..0617269d5d9 100644 Binary files a/public/images/emoji/emoji_one/watermelon.png and b/public/images/emoji/emoji_one/watermelon.png differ diff --git a/public/images/emoji/emoji_one/wave.png b/public/images/emoji/emoji_one/wave.png index 8a7086bd0fa..4bb63b68a61 100644 Binary files a/public/images/emoji/emoji_one/wave.png and b/public/images/emoji/emoji_one/wave.png differ diff --git a/public/images/emoji/emoji_one/wavy_dash.png b/public/images/emoji/emoji_one/wavy_dash.png index de20687bdd5..621f8607bef 100644 Binary files a/public/images/emoji/emoji_one/wavy_dash.png and b/public/images/emoji/emoji_one/wavy_dash.png differ diff --git a/public/images/emoji/emoji_one/waxing_crescent_moon.png b/public/images/emoji/emoji_one/waxing_crescent_moon.png index 7d4b5a056e4..747e0e4efdf 100644 Binary files a/public/images/emoji/emoji_one/waxing_crescent_moon.png and b/public/images/emoji/emoji_one/waxing_crescent_moon.png differ diff --git a/public/images/emoji/emoji_one/waxing_gibbous_moon.png b/public/images/emoji/emoji_one/waxing_gibbous_moon.png index b53fd42886f..cc1716b1e1a 100644 Binary files a/public/images/emoji/emoji_one/waxing_gibbous_moon.png and b/public/images/emoji/emoji_one/waxing_gibbous_moon.png differ diff --git a/public/images/emoji/emoji_one/wc.png b/public/images/emoji/emoji_one/wc.png index 92399227fd0..a696e4e47c2 100644 Binary files a/public/images/emoji/emoji_one/wc.png and b/public/images/emoji/emoji_one/wc.png differ diff --git a/public/images/emoji/emoji_one/weary.png b/public/images/emoji/emoji_one/weary.png index 09301ab69b3..36a55aec4e8 100644 Binary files a/public/images/emoji/emoji_one/weary.png and b/public/images/emoji/emoji_one/weary.png differ diff --git a/public/images/emoji/emoji_one/wedding.png b/public/images/emoji/emoji_one/wedding.png index dda4a140f4a..96713fdbf54 100644 Binary files a/public/images/emoji/emoji_one/wedding.png and b/public/images/emoji/emoji_one/wedding.png differ diff --git a/public/images/emoji/emoji_one/whale.png b/public/images/emoji/emoji_one/whale.png index cf1ecee86f4..ca541251c1b 100644 Binary files a/public/images/emoji/emoji_one/whale.png and b/public/images/emoji/emoji_one/whale.png differ diff --git a/public/images/emoji/emoji_one/whale2.png b/public/images/emoji/emoji_one/whale2.png index 18186053028..7885f8791c6 100644 Binary files a/public/images/emoji/emoji_one/whale2.png and b/public/images/emoji/emoji_one/whale2.png differ diff --git a/public/images/emoji/emoji_one/wheel_of_dharma.png b/public/images/emoji/emoji_one/wheel_of_dharma.png new file mode 100644 index 00000000000..d6569d3a5e1 Binary files /dev/null and b/public/images/emoji/emoji_one/wheel_of_dharma.png differ diff --git a/public/images/emoji/emoji_one/wheelchair.png b/public/images/emoji/emoji_one/wheelchair.png index 492324ee061..3c41b6d22ff 100644 Binary files a/public/images/emoji/emoji_one/wheelchair.png and b/public/images/emoji/emoji_one/wheelchair.png differ diff --git a/public/images/emoji/emoji_one/white_check_mark.png b/public/images/emoji/emoji_one/white_check_mark.png index 2f35a6fa804..4700639a4d6 100644 Binary files a/public/images/emoji/emoji_one/white_check_mark.png and b/public/images/emoji/emoji_one/white_check_mark.png differ diff --git a/public/images/emoji/emoji_one/white_circle.png b/public/images/emoji/emoji_one/white_circle.png index ba9611efe25..c7e81117e57 100644 Binary files a/public/images/emoji/emoji_one/white_circle.png and b/public/images/emoji/emoji_one/white_circle.png differ diff --git a/public/images/emoji/emoji_one/white_flower.png b/public/images/emoji/emoji_one/white_flower.png index decda76acd2..d2c4e8f807f 100644 Binary files a/public/images/emoji/emoji_one/white_flower.png and b/public/images/emoji/emoji_one/white_flower.png differ diff --git a/public/images/emoji/emoji_one/white_large_square.png b/public/images/emoji/emoji_one/white_large_square.png index 2ee54cd9a4f..73f9cb7daab 100644 Binary files a/public/images/emoji/emoji_one/white_large_square.png and b/public/images/emoji/emoji_one/white_large_square.png differ diff --git a/public/images/emoji/emoji_one/white_medium_small_square.png b/public/images/emoji/emoji_one/white_medium_small_square.png index bfa35d08471..f21616028c0 100644 Binary files a/public/images/emoji/emoji_one/white_medium_small_square.png and b/public/images/emoji/emoji_one/white_medium_small_square.png differ diff --git a/public/images/emoji/emoji_one/white_medium_square.png b/public/images/emoji/emoji_one/white_medium_square.png index 5ced58002e1..36d8dd1a9d6 100644 Binary files a/public/images/emoji/emoji_one/white_medium_square.png and b/public/images/emoji/emoji_one/white_medium_square.png differ diff --git a/public/images/emoji/emoji_one/white_small_square.png b/public/images/emoji/emoji_one/white_small_square.png index c458a1b20b4..7863a445485 100644 Binary files a/public/images/emoji/emoji_one/white_small_square.png and b/public/images/emoji/emoji_one/white_small_square.png differ diff --git a/public/images/emoji/emoji_one/white_square_button.png b/public/images/emoji/emoji_one/white_square_button.png index a55fcd0e2a1..b3a0b0f733e 100644 Binary files a/public/images/emoji/emoji_one/white_square_button.png and b/public/images/emoji/emoji_one/white_square_button.png differ diff --git a/public/images/emoji/emoji_one/white_sun_cloud.png b/public/images/emoji/emoji_one/white_sun_cloud.png new file mode 100644 index 00000000000..461a1f85bab Binary files /dev/null and b/public/images/emoji/emoji_one/white_sun_cloud.png differ diff --git a/public/images/emoji/emoji_one/white_sun_rain_cloud.png b/public/images/emoji/emoji_one/white_sun_rain_cloud.png new file mode 100644 index 00000000000..0d8475bbd0f Binary files /dev/null and b/public/images/emoji/emoji_one/white_sun_rain_cloud.png differ diff --git a/public/images/emoji/emoji_one/white_sun_small_cloud.png b/public/images/emoji/emoji_one/white_sun_small_cloud.png new file mode 100644 index 00000000000..403550e9501 Binary files /dev/null and b/public/images/emoji/emoji_one/white_sun_small_cloud.png differ diff --git a/public/images/emoji/emoji_one/wind_blowing_face.png b/public/images/emoji/emoji_one/wind_blowing_face.png new file mode 100644 index 00000000000..6b933af8e7e Binary files /dev/null and b/public/images/emoji/emoji_one/wind_blowing_face.png differ diff --git a/public/images/emoji/emoji_one/wind_chime.png b/public/images/emoji/emoji_one/wind_chime.png index 8aee0e8bda6..54e7d9e2b18 100644 Binary files a/public/images/emoji/emoji_one/wind_chime.png and b/public/images/emoji/emoji_one/wind_chime.png differ diff --git a/public/images/emoji/emoji_one/wine_glass.png b/public/images/emoji/emoji_one/wine_glass.png index 5854305f434..eb55d7f7685 100644 Binary files a/public/images/emoji/emoji_one/wine_glass.png and b/public/images/emoji/emoji_one/wine_glass.png differ diff --git a/public/images/emoji/emoji_one/wink.png b/public/images/emoji/emoji_one/wink.png index 7b060cd3933..aeb3167b5a7 100644 Binary files a/public/images/emoji/emoji_one/wink.png and b/public/images/emoji/emoji_one/wink.png differ diff --git a/public/images/emoji/emoji_one/wolf.png b/public/images/emoji/emoji_one/wolf.png index 46f054c6259..b744bb03668 100644 Binary files a/public/images/emoji/emoji_one/wolf.png and b/public/images/emoji/emoji_one/wolf.png differ diff --git a/public/images/emoji/emoji_one/woman.png b/public/images/emoji/emoji_one/woman.png index 286dce5b5a7..4feb81529e7 100644 Binary files a/public/images/emoji/emoji_one/woman.png and b/public/images/emoji/emoji_one/woman.png differ diff --git a/public/images/emoji/emoji_one/womans_clothes.png b/public/images/emoji/emoji_one/womans_clothes.png index 1a54942671e..b9fae4c78d3 100644 Binary files a/public/images/emoji/emoji_one/womans_clothes.png and b/public/images/emoji/emoji_one/womans_clothes.png differ diff --git a/public/images/emoji/emoji_one/womans_hat.png b/public/images/emoji/emoji_one/womans_hat.png index 33af561b337..7428b33d168 100644 Binary files a/public/images/emoji/emoji_one/womans_hat.png and b/public/images/emoji/emoji_one/womans_hat.png differ diff --git a/public/images/emoji/emoji_one/womens.png b/public/images/emoji/emoji_one/womens.png index 7e231f009d9..1a2922b8823 100644 Binary files a/public/images/emoji/emoji_one/womens.png and b/public/images/emoji/emoji_one/womens.png differ diff --git a/public/images/emoji/emoji_one/worried.png b/public/images/emoji/emoji_one/worried.png index 8809c790a02..5bc485dc93b 100644 Binary files a/public/images/emoji/emoji_one/worried.png and b/public/images/emoji/emoji_one/worried.png differ diff --git a/public/images/emoji/emoji_one/wrench.png b/public/images/emoji/emoji_one/wrench.png index 64a0d6a7654..3f256a8da60 100644 Binary files a/public/images/emoji/emoji_one/wrench.png and b/public/images/emoji/emoji_one/wrench.png differ diff --git a/public/images/emoji/emoji_one/writing_hand.png b/public/images/emoji/emoji_one/writing_hand.png new file mode 100644 index 00000000000..c49c6987de8 Binary files /dev/null and b/public/images/emoji/emoji_one/writing_hand.png differ diff --git a/public/images/emoji/emoji_one/x.png b/public/images/emoji/emoji_one/x.png index 18de9309024..feba43271d3 100644 Binary files a/public/images/emoji/emoji_one/x.png and b/public/images/emoji/emoji_one/x.png differ diff --git a/public/images/emoji/emoji_one/yellow_heart.png b/public/images/emoji/emoji_one/yellow_heart.png index 40314009eab..c65ef9914d7 100644 Binary files a/public/images/emoji/emoji_one/yellow_heart.png and b/public/images/emoji/emoji_one/yellow_heart.png differ diff --git a/public/images/emoji/emoji_one/yen.png b/public/images/emoji/emoji_one/yen.png index 7585eaa75a4..b3ab2093037 100644 Binary files a/public/images/emoji/emoji_one/yen.png and b/public/images/emoji/emoji_one/yen.png differ diff --git a/public/images/emoji/emoji_one/yin_yang.png b/public/images/emoji/emoji_one/yin_yang.png new file mode 100644 index 00000000000..e8769c4c40e Binary files /dev/null and b/public/images/emoji/emoji_one/yin_yang.png differ diff --git a/public/images/emoji/emoji_one/yum.png b/public/images/emoji/emoji_one/yum.png index 3cf0c60b310..ecb1be12b09 100644 Binary files a/public/images/emoji/emoji_one/yum.png and b/public/images/emoji/emoji_one/yum.png differ diff --git a/public/images/emoji/emoji_one/zap.png b/public/images/emoji/emoji_one/zap.png index 97e8cd8e4af..bbda60b862f 100644 Binary files a/public/images/emoji/emoji_one/zap.png and b/public/images/emoji/emoji_one/zap.png differ diff --git a/public/images/emoji/emoji_one/zero.png b/public/images/emoji/emoji_one/zero.png index 8de44baeb3b..25e3049461a 100644 Binary files a/public/images/emoji/emoji_one/zero.png and b/public/images/emoji/emoji_one/zero.png differ diff --git a/public/images/emoji/emoji_one/zipper_mouth.png b/public/images/emoji/emoji_one/zipper_mouth.png new file mode 100644 index 00000000000..2ddaf45491d Binary files /dev/null and b/public/images/emoji/emoji_one/zipper_mouth.png differ diff --git a/public/images/emoji/emoji_one/zzz.png b/public/images/emoji/emoji_one/zzz.png index cf024a55b05..3a757d85dad 100644 Binary files a/public/images/emoji/emoji_one/zzz.png and b/public/images/emoji/emoji_one/zzz.png differ diff --git a/public/images/emoji/google/+1.png b/public/images/emoji/google/+1.png index b997ff3e9f9..c95e34f58c0 100644 Binary files a/public/images/emoji/google/+1.png and b/public/images/emoji/google/+1.png differ diff --git a/public/images/emoji/google/-1.png b/public/images/emoji/google/-1.png index bd9730bfa4a..3af4fdd1ee7 100644 Binary files a/public/images/emoji/google/-1.png and b/public/images/emoji/google/-1.png differ diff --git a/public/images/emoji/google/100.png b/public/images/emoji/google/100.png index 75fd130b23e..65c60c38ffd 100644 Binary files a/public/images/emoji/google/100.png and b/public/images/emoji/google/100.png differ diff --git a/public/images/emoji/google/1234.png b/public/images/emoji/google/1234.png index 1f2781eed98..a419d260e54 100644 Binary files a/public/images/emoji/google/1234.png and b/public/images/emoji/google/1234.png differ diff --git a/public/images/emoji/google/8ball.png b/public/images/emoji/google/8ball.png index b9c77c88e55..b91c9f72870 100644 Binary files a/public/images/emoji/google/8ball.png and b/public/images/emoji/google/8ball.png differ diff --git a/public/images/emoji/google/a.png b/public/images/emoji/google/a.png index 5cd18366102..26f18ccc86a 100644 Binary files a/public/images/emoji/google/a.png and b/public/images/emoji/google/a.png differ diff --git a/public/images/emoji/google/ab.png b/public/images/emoji/google/ab.png index 8b8c9f60f3d..002398a6c7c 100644 Binary files a/public/images/emoji/google/ab.png and b/public/images/emoji/google/ab.png differ diff --git a/public/images/emoji/google/abc.png b/public/images/emoji/google/abc.png index 90be89447d6..934c23e46ec 100644 Binary files a/public/images/emoji/google/abc.png and b/public/images/emoji/google/abc.png differ diff --git a/public/images/emoji/google/abcd.png b/public/images/emoji/google/abcd.png index 0ddc39ad5ae..cc601b1cbb6 100644 Binary files a/public/images/emoji/google/abcd.png and b/public/images/emoji/google/abcd.png differ diff --git a/public/images/emoji/google/accept.png b/public/images/emoji/google/accept.png index 31b6890f8c1..cc109f468d7 100644 Binary files a/public/images/emoji/google/accept.png and b/public/images/emoji/google/accept.png differ diff --git a/public/images/emoji/google/aerial_tramway.png b/public/images/emoji/google/aerial_tramway.png index adf58bbe989..07871e4ca63 100644 Binary files a/public/images/emoji/google/aerial_tramway.png and b/public/images/emoji/google/aerial_tramway.png differ diff --git a/public/images/emoji/google/airplane.png b/public/images/emoji/google/airplane.png index 7fdbca09e63..590bbb55e95 100644 Binary files a/public/images/emoji/google/airplane.png and b/public/images/emoji/google/airplane.png differ diff --git a/public/images/emoji/google/airplane_arriving.png b/public/images/emoji/google/airplane_arriving.png new file mode 100644 index 00000000000..a385ba00709 Binary files /dev/null and b/public/images/emoji/google/airplane_arriving.png differ diff --git a/public/images/emoji/google/airplane_departure.png b/public/images/emoji/google/airplane_departure.png new file mode 100644 index 00000000000..30dd2054cac Binary files /dev/null and b/public/images/emoji/google/airplane_departure.png differ diff --git a/public/images/emoji/google/airplane_small.png b/public/images/emoji/google/airplane_small.png new file mode 100644 index 00000000000..4f97922d5dd Binary files /dev/null and b/public/images/emoji/google/airplane_small.png differ diff --git a/public/images/emoji/google/alarm_clock.png b/public/images/emoji/google/alarm_clock.png index 90fd1620ade..632b0424eaf 100644 Binary files a/public/images/emoji/google/alarm_clock.png and b/public/images/emoji/google/alarm_clock.png differ diff --git a/public/images/emoji/google/alembic.png b/public/images/emoji/google/alembic.png new file mode 100644 index 00000000000..553d1ceefcb Binary files /dev/null and b/public/images/emoji/google/alembic.png differ diff --git a/public/images/emoji/google/alien.png b/public/images/emoji/google/alien.png index 15552a1a145..60bb9bea487 100644 Binary files a/public/images/emoji/google/alien.png and b/public/images/emoji/google/alien.png differ diff --git a/public/images/emoji/google/ambulance.png b/public/images/emoji/google/ambulance.png index e79610e6fac..68991eeae3b 100644 Binary files a/public/images/emoji/google/ambulance.png and b/public/images/emoji/google/ambulance.png differ diff --git a/public/images/emoji/google/amphora.png b/public/images/emoji/google/amphora.png new file mode 100644 index 00000000000..58998b83d31 Binary files /dev/null and b/public/images/emoji/google/amphora.png differ diff --git a/public/images/emoji/google/anchor.png b/public/images/emoji/google/anchor.png index 78f95afd765..2bd235886e3 100644 Binary files a/public/images/emoji/google/anchor.png and b/public/images/emoji/google/anchor.png differ diff --git a/public/images/emoji/google/angel.png b/public/images/emoji/google/angel.png index a894d6ccbfd..5d8a17049e3 100644 Binary files a/public/images/emoji/google/angel.png and b/public/images/emoji/google/angel.png differ diff --git a/public/images/emoji/google/anger.png b/public/images/emoji/google/anger.png index ecd55a67f2d..a2d05d4d085 100644 Binary files a/public/images/emoji/google/anger.png and b/public/images/emoji/google/anger.png differ diff --git a/public/images/emoji/google/anger_right.png b/public/images/emoji/google/anger_right.png new file mode 100644 index 00000000000..fed984143e3 Binary files /dev/null and b/public/images/emoji/google/anger_right.png differ diff --git a/public/images/emoji/google/angry.png b/public/images/emoji/google/angry.png index 5bbd6c23952..808bfa883e5 100644 Binary files a/public/images/emoji/google/angry.png and b/public/images/emoji/google/angry.png differ diff --git a/public/images/emoji/google/anguished.png b/public/images/emoji/google/anguished.png index 3d2727e4403..6b0d286ac3e 100644 Binary files a/public/images/emoji/google/anguished.png and b/public/images/emoji/google/anguished.png differ diff --git a/public/images/emoji/google/ant.png b/public/images/emoji/google/ant.png index dc92a8025ca..3ca2872f570 100644 Binary files a/public/images/emoji/google/ant.png and b/public/images/emoji/google/ant.png differ diff --git a/public/images/emoji/google/apple.png b/public/images/emoji/google/apple.png index fe2db38113a..7f004c550a1 100644 Binary files a/public/images/emoji/google/apple.png and b/public/images/emoji/google/apple.png differ diff --git a/public/images/emoji/google/aquarius.png b/public/images/emoji/google/aquarius.png index 3d76e553811..a1a67191c09 100644 Binary files a/public/images/emoji/google/aquarius.png and b/public/images/emoji/google/aquarius.png differ diff --git a/public/images/emoji/google/aries.png b/public/images/emoji/google/aries.png index 44762b66a34..dc433cdaefc 100644 Binary files a/public/images/emoji/google/aries.png and b/public/images/emoji/google/aries.png differ diff --git a/public/images/emoji/google/arrow_backward.png b/public/images/emoji/google/arrow_backward.png index 76ad8621372..64f02f4d76e 100644 Binary files a/public/images/emoji/google/arrow_backward.png and b/public/images/emoji/google/arrow_backward.png differ diff --git a/public/images/emoji/google/arrow_double_down.png b/public/images/emoji/google/arrow_double_down.png index 241355de28c..5810ec2b11e 100644 Binary files a/public/images/emoji/google/arrow_double_down.png and b/public/images/emoji/google/arrow_double_down.png differ diff --git a/public/images/emoji/google/arrow_double_up.png b/public/images/emoji/google/arrow_double_up.png index 516383d82c1..becf04cb72f 100644 Binary files a/public/images/emoji/google/arrow_double_up.png and b/public/images/emoji/google/arrow_double_up.png differ diff --git a/public/images/emoji/google/arrow_down.png b/public/images/emoji/google/arrow_down.png index fa55f985b7d..987b8233bc8 100644 Binary files a/public/images/emoji/google/arrow_down.png and b/public/images/emoji/google/arrow_down.png differ diff --git a/public/images/emoji/google/arrow_down_small.png b/public/images/emoji/google/arrow_down_small.png index 1f3fac3d10b..6ee59cfe280 100644 Binary files a/public/images/emoji/google/arrow_down_small.png and b/public/images/emoji/google/arrow_down_small.png differ diff --git a/public/images/emoji/google/arrow_forward.png b/public/images/emoji/google/arrow_forward.png index 4766f1e092f..9688e72163c 100644 Binary files a/public/images/emoji/google/arrow_forward.png and b/public/images/emoji/google/arrow_forward.png differ diff --git a/public/images/emoji/google/arrow_heading_down.png b/public/images/emoji/google/arrow_heading_down.png index de7e9c1a4ac..5f68e573572 100644 Binary files a/public/images/emoji/google/arrow_heading_down.png and b/public/images/emoji/google/arrow_heading_down.png differ diff --git a/public/images/emoji/google/arrow_heading_up.png b/public/images/emoji/google/arrow_heading_up.png index d8356bedb2f..4c3dc2dc6ea 100644 Binary files a/public/images/emoji/google/arrow_heading_up.png and b/public/images/emoji/google/arrow_heading_up.png differ diff --git a/public/images/emoji/google/arrow_left.png b/public/images/emoji/google/arrow_left.png index 0abbb306daf..5d409737971 100644 Binary files a/public/images/emoji/google/arrow_left.png and b/public/images/emoji/google/arrow_left.png differ diff --git a/public/images/emoji/google/arrow_lower_left.png b/public/images/emoji/google/arrow_lower_left.png index 6e2f3707127..7375a23ec67 100644 Binary files a/public/images/emoji/google/arrow_lower_left.png and b/public/images/emoji/google/arrow_lower_left.png differ diff --git a/public/images/emoji/google/arrow_lower_right.png b/public/images/emoji/google/arrow_lower_right.png index 7949e5fbba4..38375b1c616 100644 Binary files a/public/images/emoji/google/arrow_lower_right.png and b/public/images/emoji/google/arrow_lower_right.png differ diff --git a/public/images/emoji/google/arrow_right.png b/public/images/emoji/google/arrow_right.png index 41bc3f68a63..2bd204836a3 100644 Binary files a/public/images/emoji/google/arrow_right.png and b/public/images/emoji/google/arrow_right.png differ diff --git a/public/images/emoji/google/arrow_right_hook.png b/public/images/emoji/google/arrow_right_hook.png index 448cdb39925..0d5f99b6354 100644 Binary files a/public/images/emoji/google/arrow_right_hook.png and b/public/images/emoji/google/arrow_right_hook.png differ diff --git a/public/images/emoji/google/arrow_up.png b/public/images/emoji/google/arrow_up.png index c39e326cae9..2c6d34d3408 100644 Binary files a/public/images/emoji/google/arrow_up.png and b/public/images/emoji/google/arrow_up.png differ diff --git a/public/images/emoji/google/arrow_up_down.png b/public/images/emoji/google/arrow_up_down.png index a3f4c1bfe92..af690e2cc39 100644 Binary files a/public/images/emoji/google/arrow_up_down.png and b/public/images/emoji/google/arrow_up_down.png differ diff --git a/public/images/emoji/google/arrow_up_small.png b/public/images/emoji/google/arrow_up_small.png index 4c880fc9679..d6a29ff7800 100644 Binary files a/public/images/emoji/google/arrow_up_small.png and b/public/images/emoji/google/arrow_up_small.png differ diff --git a/public/images/emoji/google/arrow_upper_left.png b/public/images/emoji/google/arrow_upper_left.png index 91f50bdcd4f..f8f15e75697 100644 Binary files a/public/images/emoji/google/arrow_upper_left.png and b/public/images/emoji/google/arrow_upper_left.png differ diff --git a/public/images/emoji/google/arrow_upper_right.png b/public/images/emoji/google/arrow_upper_right.png index 9ffce9c00cb..ca054bfcdd2 100644 Binary files a/public/images/emoji/google/arrow_upper_right.png and b/public/images/emoji/google/arrow_upper_right.png differ diff --git a/public/images/emoji/google/arrows_clockwise.png b/public/images/emoji/google/arrows_clockwise.png index b9991d29b3b..bdfc3f2b7ff 100644 Binary files a/public/images/emoji/google/arrows_clockwise.png and b/public/images/emoji/google/arrows_clockwise.png differ diff --git a/public/images/emoji/google/arrows_counterclockwise.png b/public/images/emoji/google/arrows_counterclockwise.png index b2011d32d87..cb0b629e206 100644 Binary files a/public/images/emoji/google/arrows_counterclockwise.png and b/public/images/emoji/google/arrows_counterclockwise.png differ diff --git a/public/images/emoji/google/art.png b/public/images/emoji/google/art.png index bbb7f9a33e4..c9bb008b49e 100644 Binary files a/public/images/emoji/google/art.png and b/public/images/emoji/google/art.png differ diff --git a/public/images/emoji/google/articulated_lorry.png b/public/images/emoji/google/articulated_lorry.png index 0cf4f204a7a..10e9f77ab33 100644 Binary files a/public/images/emoji/google/articulated_lorry.png and b/public/images/emoji/google/articulated_lorry.png differ diff --git a/public/images/emoji/google/astonished.png b/public/images/emoji/google/astonished.png index fe2354561f2..e5030a80087 100644 Binary files a/public/images/emoji/google/astonished.png and b/public/images/emoji/google/astonished.png differ diff --git a/public/images/emoji/google/athletic_shoe.png b/public/images/emoji/google/athletic_shoe.png index 194dd323d41..7feed258ce5 100644 Binary files a/public/images/emoji/google/athletic_shoe.png and b/public/images/emoji/google/athletic_shoe.png differ diff --git a/public/images/emoji/google/atm.png b/public/images/emoji/google/atm.png index aa712b55bef..cadafadde84 100644 Binary files a/public/images/emoji/google/atm.png and b/public/images/emoji/google/atm.png differ diff --git a/public/images/emoji/google/atom.png b/public/images/emoji/google/atom.png new file mode 100644 index 00000000000..7b2e8e2de86 Binary files /dev/null and b/public/images/emoji/google/atom.png differ diff --git a/public/images/emoji/google/b.png b/public/images/emoji/google/b.png index daf24fee43c..4755a5468a5 100644 Binary files a/public/images/emoji/google/b.png and b/public/images/emoji/google/b.png differ diff --git a/public/images/emoji/google/baby.png b/public/images/emoji/google/baby.png index fb32a0f4d37..aa78d030eda 100644 Binary files a/public/images/emoji/google/baby.png and b/public/images/emoji/google/baby.png differ diff --git a/public/images/emoji/google/baby_bottle.png b/public/images/emoji/google/baby_bottle.png index fc65ec3ad6c..5c10cbd6af2 100644 Binary files a/public/images/emoji/google/baby_bottle.png and b/public/images/emoji/google/baby_bottle.png differ diff --git a/public/images/emoji/google/baby_chick.png b/public/images/emoji/google/baby_chick.png index 55730e4e94d..70bb2b084f3 100644 Binary files a/public/images/emoji/google/baby_chick.png and b/public/images/emoji/google/baby_chick.png differ diff --git a/public/images/emoji/google/baby_symbol.png b/public/images/emoji/google/baby_symbol.png index 85a20b6a7d4..c4bdf075337 100644 Binary files a/public/images/emoji/google/baby_symbol.png and b/public/images/emoji/google/baby_symbol.png differ diff --git a/public/images/emoji/google/back.png b/public/images/emoji/google/back.png index 49a9449d285..8794b675c91 100644 Binary files a/public/images/emoji/google/back.png and b/public/images/emoji/google/back.png differ diff --git a/public/images/emoji/google/badminton.png b/public/images/emoji/google/badminton.png new file mode 100644 index 00000000000..30d0a702124 Binary files /dev/null and b/public/images/emoji/google/badminton.png differ diff --git a/public/images/emoji/google/baggage_claim.png b/public/images/emoji/google/baggage_claim.png index 1a9441a40d9..91080aed99f 100644 Binary files a/public/images/emoji/google/baggage_claim.png and b/public/images/emoji/google/baggage_claim.png differ diff --git a/public/images/emoji/google/balloon.png b/public/images/emoji/google/balloon.png index 1cfc5be9f53..9f4b4ff5ef1 100644 Binary files a/public/images/emoji/google/balloon.png and b/public/images/emoji/google/balloon.png differ diff --git a/public/images/emoji/google/ballot_box.png b/public/images/emoji/google/ballot_box.png new file mode 100644 index 00000000000..1b2a590b0fb Binary files /dev/null and b/public/images/emoji/google/ballot_box.png differ diff --git a/public/images/emoji/google/ballot_box_with_check.png b/public/images/emoji/google/ballot_box_with_check.png index 1610e6e103d..1ec06c13dd9 100644 Binary files a/public/images/emoji/google/ballot_box_with_check.png and b/public/images/emoji/google/ballot_box_with_check.png differ diff --git a/public/images/emoji/google/bamboo.png b/public/images/emoji/google/bamboo.png index 1b1423823ec..a5135837483 100644 Binary files a/public/images/emoji/google/bamboo.png and b/public/images/emoji/google/bamboo.png differ diff --git a/public/images/emoji/google/banana.png b/public/images/emoji/google/banana.png index 84cca0dba49..32099917939 100644 Binary files a/public/images/emoji/google/banana.png and b/public/images/emoji/google/banana.png differ diff --git a/public/images/emoji/google/bangbang.png b/public/images/emoji/google/bangbang.png index 8bb3afd93f7..a1403b45253 100644 Binary files a/public/images/emoji/google/bangbang.png and b/public/images/emoji/google/bangbang.png differ diff --git a/public/images/emoji/google/bank.png b/public/images/emoji/google/bank.png index a2d23873314..4ce4e876f75 100644 Binary files a/public/images/emoji/google/bank.png and b/public/images/emoji/google/bank.png differ diff --git a/public/images/emoji/google/bar_chart.png b/public/images/emoji/google/bar_chart.png index bb2c08eb49e..bc5baf20b37 100644 Binary files a/public/images/emoji/google/bar_chart.png and b/public/images/emoji/google/bar_chart.png differ diff --git a/public/images/emoji/google/barber.png b/public/images/emoji/google/barber.png index 0034df6031c..c4af50c159f 100644 Binary files a/public/images/emoji/google/barber.png and b/public/images/emoji/google/barber.png differ diff --git a/public/images/emoji/google/baseball.png b/public/images/emoji/google/baseball.png index 1eab7d9e9b6..b703d1e25cb 100644 Binary files a/public/images/emoji/google/baseball.png and b/public/images/emoji/google/baseball.png differ diff --git a/public/images/emoji/google/basketball.png b/public/images/emoji/google/basketball.png index cb52921e305..2b45f671142 100644 Binary files a/public/images/emoji/google/basketball.png and b/public/images/emoji/google/basketball.png differ diff --git a/public/images/emoji/google/basketball_player.png b/public/images/emoji/google/basketball_player.png new file mode 100644 index 00000000000..17d02ddbdb7 Binary files /dev/null and b/public/images/emoji/google/basketball_player.png differ diff --git a/public/images/emoji/google/bath.png b/public/images/emoji/google/bath.png index a91da05e535..e2e60ffa7f7 100644 Binary files a/public/images/emoji/google/bath.png and b/public/images/emoji/google/bath.png differ diff --git a/public/images/emoji/google/bathtub.png b/public/images/emoji/google/bathtub.png index ca11175ffb6..8ad673e4227 100644 Binary files a/public/images/emoji/google/bathtub.png and b/public/images/emoji/google/bathtub.png differ diff --git a/public/images/emoji/google/battery.png b/public/images/emoji/google/battery.png index 2a010860e45..958edf0e375 100644 Binary files a/public/images/emoji/google/battery.png and b/public/images/emoji/google/battery.png differ diff --git a/public/images/emoji/google/beach.png b/public/images/emoji/google/beach.png new file mode 100644 index 00000000000..9bb4009a4ac Binary files /dev/null and b/public/images/emoji/google/beach.png differ diff --git a/public/images/emoji/google/beach_umbrella.png b/public/images/emoji/google/beach_umbrella.png new file mode 100644 index 00000000000..4e54263e139 Binary files /dev/null and b/public/images/emoji/google/beach_umbrella.png differ diff --git a/public/images/emoji/google/bear.png b/public/images/emoji/google/bear.png index 1a167eff48d..30ad901828d 100644 Binary files a/public/images/emoji/google/bear.png and b/public/images/emoji/google/bear.png differ diff --git a/public/images/emoji/google/bed.png b/public/images/emoji/google/bed.png new file mode 100644 index 00000000000..20fcedb2a61 Binary files /dev/null and b/public/images/emoji/google/bed.png differ diff --git a/public/images/emoji/google/bee.png b/public/images/emoji/google/bee.png index 20a86eb54b7..085e17362b5 100644 Binary files a/public/images/emoji/google/bee.png and b/public/images/emoji/google/bee.png differ diff --git a/public/images/emoji/google/beer.png b/public/images/emoji/google/beer.png index 5c4c4002d7f..cd9c413ac9d 100644 Binary files a/public/images/emoji/google/beer.png and b/public/images/emoji/google/beer.png differ diff --git a/public/images/emoji/google/beers.png b/public/images/emoji/google/beers.png index 2767b1a6267..25c23ed6ff7 100644 Binary files a/public/images/emoji/google/beers.png and b/public/images/emoji/google/beers.png differ diff --git a/public/images/emoji/google/beetle.png b/public/images/emoji/google/beetle.png index d8d410788f9..ed6a46efa98 100644 Binary files a/public/images/emoji/google/beetle.png and b/public/images/emoji/google/beetle.png differ diff --git a/public/images/emoji/google/beginner.png b/public/images/emoji/google/beginner.png index c8fbbadad42..b58346eb9d3 100644 Binary files a/public/images/emoji/google/beginner.png and b/public/images/emoji/google/beginner.png differ diff --git a/public/images/emoji/google/bell.png b/public/images/emoji/google/bell.png index 4dce6ef261b..2c625afed9b 100644 Binary files a/public/images/emoji/google/bell.png and b/public/images/emoji/google/bell.png differ diff --git a/public/images/emoji/google/bellhop.png b/public/images/emoji/google/bellhop.png new file mode 100644 index 00000000000..b9b876ebd90 Binary files /dev/null and b/public/images/emoji/google/bellhop.png differ diff --git a/public/images/emoji/google/bento.png b/public/images/emoji/google/bento.png index 7fce1490fa3..02dddedade9 100644 Binary files a/public/images/emoji/google/bento.png and b/public/images/emoji/google/bento.png differ diff --git a/public/images/emoji/google/bicyclist.png b/public/images/emoji/google/bicyclist.png index 11faa4e0669..3aa9093488b 100644 Binary files a/public/images/emoji/google/bicyclist.png and b/public/images/emoji/google/bicyclist.png differ diff --git a/public/images/emoji/google/bike.png b/public/images/emoji/google/bike.png index 30e59c9099f..665034511ae 100644 Binary files a/public/images/emoji/google/bike.png and b/public/images/emoji/google/bike.png differ diff --git a/public/images/emoji/google/bikini.png b/public/images/emoji/google/bikini.png index 8e4c392f722..a7d73e1c973 100644 Binary files a/public/images/emoji/google/bikini.png and b/public/images/emoji/google/bikini.png differ diff --git a/public/images/emoji/google/biohazard.png b/public/images/emoji/google/biohazard.png new file mode 100644 index 00000000000..deae4dd8a0b Binary files /dev/null and b/public/images/emoji/google/biohazard.png differ diff --git a/public/images/emoji/google/bird.png b/public/images/emoji/google/bird.png index 5755a25acbc..9ed01a6d952 100644 Binary files a/public/images/emoji/google/bird.png and b/public/images/emoji/google/bird.png differ diff --git a/public/images/emoji/google/birthday.png b/public/images/emoji/google/birthday.png index 9b931537878..f049edaf947 100644 Binary files a/public/images/emoji/google/birthday.png and b/public/images/emoji/google/birthday.png differ diff --git a/public/images/emoji/google/black_circle.png b/public/images/emoji/google/black_circle.png index 6706b3023c9..726b2217917 100644 Binary files a/public/images/emoji/google/black_circle.png and b/public/images/emoji/google/black_circle.png differ diff --git a/public/images/emoji/google/black_joker.png b/public/images/emoji/google/black_joker.png index 10673f6aa5e..2435a43021e 100644 Binary files a/public/images/emoji/google/black_joker.png and b/public/images/emoji/google/black_joker.png differ diff --git a/public/images/emoji/google/black_large_square.png b/public/images/emoji/google/black_large_square.png index 42da2c7f2c2..e7d99e7c3c6 100644 Binary files a/public/images/emoji/google/black_large_square.png and b/public/images/emoji/google/black_large_square.png differ diff --git a/public/images/emoji/google/black_medium_square.png b/public/images/emoji/google/black_medium_square.png index bdb623aa66b..5b56cfa028e 100644 Binary files a/public/images/emoji/google/black_medium_square.png and b/public/images/emoji/google/black_medium_square.png differ diff --git a/public/images/emoji/google/black_nib.png b/public/images/emoji/google/black_nib.png index 4aff9f87834..019c29a6b03 100644 Binary files a/public/images/emoji/google/black_nib.png and b/public/images/emoji/google/black_nib.png differ diff --git a/public/images/emoji/google/black_square_button.png b/public/images/emoji/google/black_square_button.png index 420b94b3130..382fdda1542 100644 Binary files a/public/images/emoji/google/black_square_button.png and b/public/images/emoji/google/black_square_button.png differ diff --git a/public/images/emoji/google/blossom.png b/public/images/emoji/google/blossom.png index 1633b977213..41b3a095c3d 100644 Binary files a/public/images/emoji/google/blossom.png and b/public/images/emoji/google/blossom.png differ diff --git a/public/images/emoji/google/blowfish.png b/public/images/emoji/google/blowfish.png index ca260c5db00..118e975bde8 100644 Binary files a/public/images/emoji/google/blowfish.png and b/public/images/emoji/google/blowfish.png differ diff --git a/public/images/emoji/google/blue_book.png b/public/images/emoji/google/blue_book.png index f964968ee4b..88a796bf024 100644 Binary files a/public/images/emoji/google/blue_book.png and b/public/images/emoji/google/blue_book.png differ diff --git a/public/images/emoji/google/blue_car.png b/public/images/emoji/google/blue_car.png index d7e12ace439..5b9937ba37f 100644 Binary files a/public/images/emoji/google/blue_car.png and b/public/images/emoji/google/blue_car.png differ diff --git a/public/images/emoji/google/blue_heart.png b/public/images/emoji/google/blue_heart.png index d9b316b3072..644534cbdcd 100644 Binary files a/public/images/emoji/google/blue_heart.png and b/public/images/emoji/google/blue_heart.png differ diff --git a/public/images/emoji/google/blush.png b/public/images/emoji/google/blush.png index 9d6c9718ca7..c72711d3915 100644 Binary files a/public/images/emoji/google/blush.png and b/public/images/emoji/google/blush.png differ diff --git a/public/images/emoji/google/boar.png b/public/images/emoji/google/boar.png index cf0feaa9691..ea874cd62e0 100644 Binary files a/public/images/emoji/google/boar.png and b/public/images/emoji/google/boar.png differ diff --git a/public/images/emoji/google/boat.png b/public/images/emoji/google/boat.png index 2e61e60267a..2369ef06493 100644 Binary files a/public/images/emoji/google/boat.png and b/public/images/emoji/google/boat.png differ diff --git a/public/images/emoji/google/bomb.png b/public/images/emoji/google/bomb.png index c0be032dfab..684b01f2068 100644 Binary files a/public/images/emoji/google/bomb.png and b/public/images/emoji/google/bomb.png differ diff --git a/public/images/emoji/google/book.png b/public/images/emoji/google/book.png index 77ee57a1089..e72d5010849 100644 Binary files a/public/images/emoji/google/book.png and b/public/images/emoji/google/book.png differ diff --git a/public/images/emoji/google/bookmark.png b/public/images/emoji/google/bookmark.png index e576cd8fd2d..2a5b37d3c3a 100644 Binary files a/public/images/emoji/google/bookmark.png and b/public/images/emoji/google/bookmark.png differ diff --git a/public/images/emoji/google/bookmark_tabs.png b/public/images/emoji/google/bookmark_tabs.png index 85894a86168..824d820fd08 100644 Binary files a/public/images/emoji/google/bookmark_tabs.png and b/public/images/emoji/google/bookmark_tabs.png differ diff --git a/public/images/emoji/google/books.png b/public/images/emoji/google/books.png index 689dacf7bb8..865981a6c31 100644 Binary files a/public/images/emoji/google/books.png and b/public/images/emoji/google/books.png differ diff --git a/public/images/emoji/google/boom.png b/public/images/emoji/google/boom.png index ae9722a56cd..dbce2a6e4c8 100644 Binary files a/public/images/emoji/google/boom.png and b/public/images/emoji/google/boom.png differ diff --git a/public/images/emoji/google/boot.png b/public/images/emoji/google/boot.png index c09d55389f2..f2e643a290d 100644 Binary files a/public/images/emoji/google/boot.png and b/public/images/emoji/google/boot.png differ diff --git a/public/images/emoji/google/bouquet.png b/public/images/emoji/google/bouquet.png index 6d0d6f9e674..c4df65f7fc1 100644 Binary files a/public/images/emoji/google/bouquet.png and b/public/images/emoji/google/bouquet.png differ diff --git a/public/images/emoji/google/bow.png b/public/images/emoji/google/bow.png index ce17dd28158..5790ce30a5b 100644 Binary files a/public/images/emoji/google/bow.png and b/public/images/emoji/google/bow.png differ diff --git a/public/images/emoji/google/bow_and_arrow.png b/public/images/emoji/google/bow_and_arrow.png new file mode 100644 index 00000000000..d49fc2cd538 Binary files /dev/null and b/public/images/emoji/google/bow_and_arrow.png differ diff --git a/public/images/emoji/google/bowling.png b/public/images/emoji/google/bowling.png index 63856291e79..5ec51fc510e 100644 Binary files a/public/images/emoji/google/bowling.png and b/public/images/emoji/google/bowling.png differ diff --git a/public/images/emoji/google/boy.png b/public/images/emoji/google/boy.png index 6e66a700ed8..c5e7078de74 100644 Binary files a/public/images/emoji/google/boy.png and b/public/images/emoji/google/boy.png differ diff --git a/public/images/emoji/google/bread.png b/public/images/emoji/google/bread.png index 9778f2e0180..5752e97dbe6 100644 Binary files a/public/images/emoji/google/bread.png and b/public/images/emoji/google/bread.png differ diff --git a/public/images/emoji/google/bride_with_veil.png b/public/images/emoji/google/bride_with_veil.png index 204f8ab2ae8..96510b046a2 100644 Binary files a/public/images/emoji/google/bride_with_veil.png and b/public/images/emoji/google/bride_with_veil.png differ diff --git a/public/images/emoji/google/bridge_at_night.png b/public/images/emoji/google/bridge_at_night.png index b708eafe8bf..982c03a5111 100644 Binary files a/public/images/emoji/google/bridge_at_night.png and b/public/images/emoji/google/bridge_at_night.png differ diff --git a/public/images/emoji/google/briefcase.png b/public/images/emoji/google/briefcase.png index c2051afc866..5d70aa841bb 100644 Binary files a/public/images/emoji/google/briefcase.png and b/public/images/emoji/google/briefcase.png differ diff --git a/public/images/emoji/google/broken_heart.png b/public/images/emoji/google/broken_heart.png index 3d2f386047d..d7b4f27f405 100644 Binary files a/public/images/emoji/google/broken_heart.png and b/public/images/emoji/google/broken_heart.png differ diff --git a/public/images/emoji/google/bug.png b/public/images/emoji/google/bug.png index 2785722e531..0670a643e53 100644 Binary files a/public/images/emoji/google/bug.png and b/public/images/emoji/google/bug.png differ diff --git a/public/images/emoji/google/bulb.png b/public/images/emoji/google/bulb.png index 8be12e3a915..fca03c562c5 100644 Binary files a/public/images/emoji/google/bulb.png and b/public/images/emoji/google/bulb.png differ diff --git a/public/images/emoji/google/bullettrain_front.png b/public/images/emoji/google/bullettrain_front.png index 96b42367d1c..6a386fdfc6d 100644 Binary files a/public/images/emoji/google/bullettrain_front.png and b/public/images/emoji/google/bullettrain_front.png differ diff --git a/public/images/emoji/google/bullettrain_side.png b/public/images/emoji/google/bullettrain_side.png index 4ac1ceadf43..b3b4a5e6345 100644 Binary files a/public/images/emoji/google/bullettrain_side.png and b/public/images/emoji/google/bullettrain_side.png differ diff --git a/public/images/emoji/google/burrito.png b/public/images/emoji/google/burrito.png new file mode 100644 index 00000000000..844a16b1c32 Binary files /dev/null and b/public/images/emoji/google/burrito.png differ diff --git a/public/images/emoji/google/bus.png b/public/images/emoji/google/bus.png index c16cae9a45d..243d07c85c5 100644 Binary files a/public/images/emoji/google/bus.png and b/public/images/emoji/google/bus.png differ diff --git a/public/images/emoji/google/busstop.png b/public/images/emoji/google/busstop.png index c411b70aea5..1f775a19c97 100644 Binary files a/public/images/emoji/google/busstop.png and b/public/images/emoji/google/busstop.png differ diff --git a/public/images/emoji/google/bust_in_silhouette.png b/public/images/emoji/google/bust_in_silhouette.png index 57ef62dd735..60d13b7a3b8 100644 Binary files a/public/images/emoji/google/bust_in_silhouette.png and b/public/images/emoji/google/bust_in_silhouette.png differ diff --git a/public/images/emoji/google/busts_in_silhouette.png b/public/images/emoji/google/busts_in_silhouette.png index c2f0c35342f..afe7f6e3861 100644 Binary files a/public/images/emoji/google/busts_in_silhouette.png and b/public/images/emoji/google/busts_in_silhouette.png differ diff --git a/public/images/emoji/google/cactus.png b/public/images/emoji/google/cactus.png index 9d654ef0353..201af2257cc 100644 Binary files a/public/images/emoji/google/cactus.png and b/public/images/emoji/google/cactus.png differ diff --git a/public/images/emoji/google/cake.png b/public/images/emoji/google/cake.png index f97c84e044b..66e74863f78 100644 Binary files a/public/images/emoji/google/cake.png and b/public/images/emoji/google/cake.png differ diff --git a/public/images/emoji/google/calendar.png b/public/images/emoji/google/calendar.png index 6d04ca74d80..bada128f174 100644 Binary files a/public/images/emoji/google/calendar.png and b/public/images/emoji/google/calendar.png differ diff --git a/public/images/emoji/google/calendar_spiral.png b/public/images/emoji/google/calendar_spiral.png new file mode 100644 index 00000000000..bd6dd7125e4 Binary files /dev/null and b/public/images/emoji/google/calendar_spiral.png differ diff --git a/public/images/emoji/google/calling.png b/public/images/emoji/google/calling.png index 16a9320bfca..283c2f275e1 100644 Binary files a/public/images/emoji/google/calling.png and b/public/images/emoji/google/calling.png differ diff --git a/public/images/emoji/google/camel.png b/public/images/emoji/google/camel.png index 6396e59bae8..1925d5aa484 100644 Binary files a/public/images/emoji/google/camel.png and b/public/images/emoji/google/camel.png differ diff --git a/public/images/emoji/google/camera.png b/public/images/emoji/google/camera.png index a91232b652f..35b181811e4 100644 Binary files a/public/images/emoji/google/camera.png and b/public/images/emoji/google/camera.png differ diff --git a/public/images/emoji/google/camera_with_flash.png b/public/images/emoji/google/camera_with_flash.png new file mode 100644 index 00000000000..6530f83f23e Binary files /dev/null and b/public/images/emoji/google/camera_with_flash.png differ diff --git a/public/images/emoji/google/camping.png b/public/images/emoji/google/camping.png new file mode 100644 index 00000000000..93415ad3c58 Binary files /dev/null and b/public/images/emoji/google/camping.png differ diff --git a/public/images/emoji/google/cancer.png b/public/images/emoji/google/cancer.png index c4c83af8a66..7cf4ecf427f 100644 Binary files a/public/images/emoji/google/cancer.png and b/public/images/emoji/google/cancer.png differ diff --git a/public/images/emoji/google/candle.png b/public/images/emoji/google/candle.png new file mode 100644 index 00000000000..d39a7329717 Binary files /dev/null and b/public/images/emoji/google/candle.png differ diff --git a/public/images/emoji/google/candy.png b/public/images/emoji/google/candy.png index d06237f5ffe..5042d719c8f 100644 Binary files a/public/images/emoji/google/candy.png and b/public/images/emoji/google/candy.png differ diff --git a/public/images/emoji/google/capital_abcd.png b/public/images/emoji/google/capital_abcd.png index 2d9706c46c4..c9e93a2b94c 100644 Binary files a/public/images/emoji/google/capital_abcd.png and b/public/images/emoji/google/capital_abcd.png differ diff --git a/public/images/emoji/google/capricorn.png b/public/images/emoji/google/capricorn.png index 2c48fa50f78..dba8530a7fa 100644 Binary files a/public/images/emoji/google/capricorn.png and b/public/images/emoji/google/capricorn.png differ diff --git a/public/images/emoji/google/car.png b/public/images/emoji/google/car.png index f1be3d95ae5..e71c81d3813 100644 Binary files a/public/images/emoji/google/car.png and b/public/images/emoji/google/car.png differ diff --git a/public/images/emoji/google/card_box.png b/public/images/emoji/google/card_box.png new file mode 100644 index 00000000000..99e43b255fa Binary files /dev/null and b/public/images/emoji/google/card_box.png differ diff --git a/public/images/emoji/google/card_index.png b/public/images/emoji/google/card_index.png index b1c6e85cd9c..4988f3aa682 100644 Binary files a/public/images/emoji/google/card_index.png and b/public/images/emoji/google/card_index.png differ diff --git a/public/images/emoji/google/carousel_horse.png b/public/images/emoji/google/carousel_horse.png index 4a6aed313e1..c1dc86895a1 100644 Binary files a/public/images/emoji/google/carousel_horse.png and b/public/images/emoji/google/carousel_horse.png differ diff --git a/public/images/emoji/google/cat.png b/public/images/emoji/google/cat.png index 10723a98356..bc5f33259b8 100644 Binary files a/public/images/emoji/google/cat.png and b/public/images/emoji/google/cat.png differ diff --git a/public/images/emoji/google/cat2.png b/public/images/emoji/google/cat2.png index c4db7e61fe5..591a2262c12 100644 Binary files a/public/images/emoji/google/cat2.png and b/public/images/emoji/google/cat2.png differ diff --git a/public/images/emoji/google/cd.png b/public/images/emoji/google/cd.png index a2965af89da..e561f0e79f5 100644 Binary files a/public/images/emoji/google/cd.png and b/public/images/emoji/google/cd.png differ diff --git a/public/images/emoji/google/chains.png b/public/images/emoji/google/chains.png new file mode 100644 index 00000000000..b351a69dd25 Binary files /dev/null and b/public/images/emoji/google/chains.png differ diff --git a/public/images/emoji/google/champagne.png b/public/images/emoji/google/champagne.png new file mode 100644 index 00000000000..e42cfacfe61 Binary files /dev/null and b/public/images/emoji/google/champagne.png differ diff --git a/public/images/emoji/google/chart.png b/public/images/emoji/google/chart.png index 80c3e7355e4..a50dc913eae 100644 Binary files a/public/images/emoji/google/chart.png and b/public/images/emoji/google/chart.png differ diff --git a/public/images/emoji/google/chart_with_downwards_trend.png b/public/images/emoji/google/chart_with_downwards_trend.png index 48b84869d11..e9fb1b90cc0 100644 Binary files a/public/images/emoji/google/chart_with_downwards_trend.png and b/public/images/emoji/google/chart_with_downwards_trend.png differ diff --git a/public/images/emoji/google/chart_with_upwards_trend.png b/public/images/emoji/google/chart_with_upwards_trend.png index 1c952e07566..feb0b31ceea 100644 Binary files a/public/images/emoji/google/chart_with_upwards_trend.png and b/public/images/emoji/google/chart_with_upwards_trend.png differ diff --git a/public/images/emoji/google/checkered_flag.png b/public/images/emoji/google/checkered_flag.png index 6de617fb762..d2007275ae2 100644 Binary files a/public/images/emoji/google/checkered_flag.png and b/public/images/emoji/google/checkered_flag.png differ diff --git a/public/images/emoji/google/cheese.png b/public/images/emoji/google/cheese.png new file mode 100644 index 00000000000..b41475b401e Binary files /dev/null and b/public/images/emoji/google/cheese.png differ diff --git a/public/images/emoji/google/cherries.png b/public/images/emoji/google/cherries.png index 857d3f8a9ef..fdc90b4d48b 100644 Binary files a/public/images/emoji/google/cherries.png and b/public/images/emoji/google/cherries.png differ diff --git a/public/images/emoji/google/cherry_blossom.png b/public/images/emoji/google/cherry_blossom.png index cde001ba456..b3e099ac791 100644 Binary files a/public/images/emoji/google/cherry_blossom.png and b/public/images/emoji/google/cherry_blossom.png differ diff --git a/public/images/emoji/google/chestnut.png b/public/images/emoji/google/chestnut.png index feb11f8e230..c85efeb308e 100644 Binary files a/public/images/emoji/google/chestnut.png and b/public/images/emoji/google/chestnut.png differ diff --git a/public/images/emoji/google/chicken.png b/public/images/emoji/google/chicken.png index 410a89e5602..d00dbfed2c5 100644 Binary files a/public/images/emoji/google/chicken.png and b/public/images/emoji/google/chicken.png differ diff --git a/public/images/emoji/google/children_crossing.png b/public/images/emoji/google/children_crossing.png index e87942b7838..0920af0f0bf 100644 Binary files a/public/images/emoji/google/children_crossing.png and b/public/images/emoji/google/children_crossing.png differ diff --git a/public/images/emoji/google/chipmunk.png b/public/images/emoji/google/chipmunk.png new file mode 100644 index 00000000000..3e582e29d8b Binary files /dev/null and b/public/images/emoji/google/chipmunk.png differ diff --git a/public/images/emoji/google/chocolate_bar.png b/public/images/emoji/google/chocolate_bar.png index ac6f2946da0..f63b907b130 100644 Binary files a/public/images/emoji/google/chocolate_bar.png and b/public/images/emoji/google/chocolate_bar.png differ diff --git a/public/images/emoji/google/christmas_tree.png b/public/images/emoji/google/christmas_tree.png index 26fc2c19cfa..27b037c0e8f 100644 Binary files a/public/images/emoji/google/christmas_tree.png and b/public/images/emoji/google/christmas_tree.png differ diff --git a/public/images/emoji/google/church.png b/public/images/emoji/google/church.png index a1d51b34396..906239b16f1 100644 Binary files a/public/images/emoji/google/church.png and b/public/images/emoji/google/church.png differ diff --git a/public/images/emoji/google/cinema.png b/public/images/emoji/google/cinema.png index b9fcfeb0bb7..483e26ef277 100644 Binary files a/public/images/emoji/google/cinema.png and b/public/images/emoji/google/cinema.png differ diff --git a/public/images/emoji/google/circus_tent.png b/public/images/emoji/google/circus_tent.png index 8fdb99af616..e892050f3c4 100644 Binary files a/public/images/emoji/google/circus_tent.png and b/public/images/emoji/google/circus_tent.png differ diff --git a/public/images/emoji/google/city_dusk.png b/public/images/emoji/google/city_dusk.png new file mode 100644 index 00000000000..1d5e0b932d0 Binary files /dev/null and b/public/images/emoji/google/city_dusk.png differ diff --git a/public/images/emoji/google/city_sunrise.png b/public/images/emoji/google/city_sunrise.png index 6198cb69948..16f81d08f59 100644 Binary files a/public/images/emoji/google/city_sunrise.png and b/public/images/emoji/google/city_sunrise.png differ diff --git a/public/images/emoji/google/city_sunset.png b/public/images/emoji/google/city_sunset.png index 8c1ab36688f..9c88ae2674c 100644 Binary files a/public/images/emoji/google/city_sunset.png and b/public/images/emoji/google/city_sunset.png differ diff --git a/public/images/emoji/google/cityscape.png b/public/images/emoji/google/cityscape.png new file mode 100644 index 00000000000..e42dd1941e4 Binary files /dev/null and b/public/images/emoji/google/cityscape.png differ diff --git a/public/images/emoji/google/cl.png b/public/images/emoji/google/cl.png index d26a9ab19c1..438dfa00644 100644 Binary files a/public/images/emoji/google/cl.png and b/public/images/emoji/google/cl.png differ diff --git a/public/images/emoji/google/clap.png b/public/images/emoji/google/clap.png index 7451fa022bc..86cce9e73c4 100644 Binary files a/public/images/emoji/google/clap.png and b/public/images/emoji/google/clap.png differ diff --git a/public/images/emoji/google/clapper.png b/public/images/emoji/google/clapper.png index 5f3ca478636..6f7e94a2f40 100644 Binary files a/public/images/emoji/google/clapper.png and b/public/images/emoji/google/clapper.png differ diff --git a/public/images/emoji/google/classical_building.png b/public/images/emoji/google/classical_building.png new file mode 100644 index 00000000000..7c52f6c9887 Binary files /dev/null and b/public/images/emoji/google/classical_building.png differ diff --git a/public/images/emoji/google/clipboard.png b/public/images/emoji/google/clipboard.png index 8d7999696e0..3a168e3a77e 100644 Binary files a/public/images/emoji/google/clipboard.png and b/public/images/emoji/google/clipboard.png differ diff --git a/public/images/emoji/google/clock.png b/public/images/emoji/google/clock.png new file mode 100644 index 00000000000..a01e801f2c9 Binary files /dev/null and b/public/images/emoji/google/clock.png differ diff --git a/public/images/emoji/google/clock1.png b/public/images/emoji/google/clock1.png index 99cb83a7978..64e1d54a1de 100644 Binary files a/public/images/emoji/google/clock1.png and b/public/images/emoji/google/clock1.png differ diff --git a/public/images/emoji/google/clock10.png b/public/images/emoji/google/clock10.png index 6608a21774a..4b5f5ec1fa9 100644 Binary files a/public/images/emoji/google/clock10.png and b/public/images/emoji/google/clock10.png differ diff --git a/public/images/emoji/google/clock1030.png b/public/images/emoji/google/clock1030.png index 3b4d7c44e80..8f0ae6a4169 100644 Binary files a/public/images/emoji/google/clock1030.png and b/public/images/emoji/google/clock1030.png differ diff --git a/public/images/emoji/google/clock11.png b/public/images/emoji/google/clock11.png index 640bb37ac16..06f98a3ae4a 100644 Binary files a/public/images/emoji/google/clock11.png and b/public/images/emoji/google/clock11.png differ diff --git a/public/images/emoji/google/clock1130.png b/public/images/emoji/google/clock1130.png index 2d52629fe6a..ab89cee0f64 100644 Binary files a/public/images/emoji/google/clock1130.png and b/public/images/emoji/google/clock1130.png differ diff --git a/public/images/emoji/google/clock12.png b/public/images/emoji/google/clock12.png index adac4677fd5..3dc89db1c1b 100644 Binary files a/public/images/emoji/google/clock12.png and b/public/images/emoji/google/clock12.png differ diff --git a/public/images/emoji/google/clock1230.png b/public/images/emoji/google/clock1230.png index 36a40d1f9e4..4a6bc3aeb2c 100644 Binary files a/public/images/emoji/google/clock1230.png and b/public/images/emoji/google/clock1230.png differ diff --git a/public/images/emoji/google/clock130.png b/public/images/emoji/google/clock130.png index 59db85445f0..de70eca2e20 100644 Binary files a/public/images/emoji/google/clock130.png and b/public/images/emoji/google/clock130.png differ diff --git a/public/images/emoji/google/clock2.png b/public/images/emoji/google/clock2.png index 2f18e809163..10e66683b84 100644 Binary files a/public/images/emoji/google/clock2.png and b/public/images/emoji/google/clock2.png differ diff --git a/public/images/emoji/google/clock230.png b/public/images/emoji/google/clock230.png index 96fc98d4a1f..bd570cdbd50 100644 Binary files a/public/images/emoji/google/clock230.png and b/public/images/emoji/google/clock230.png differ diff --git a/public/images/emoji/google/clock3.png b/public/images/emoji/google/clock3.png index 203e102f112..630c1e59efa 100644 Binary files a/public/images/emoji/google/clock3.png and b/public/images/emoji/google/clock3.png differ diff --git a/public/images/emoji/google/clock330.png b/public/images/emoji/google/clock330.png index 05abb9a6614..908626c4091 100644 Binary files a/public/images/emoji/google/clock330.png and b/public/images/emoji/google/clock330.png differ diff --git a/public/images/emoji/google/clock4.png b/public/images/emoji/google/clock4.png index d0cd9d61ee9..13ca9e4358d 100644 Binary files a/public/images/emoji/google/clock4.png and b/public/images/emoji/google/clock4.png differ diff --git a/public/images/emoji/google/clock430.png b/public/images/emoji/google/clock430.png index fac985a8f3b..4c535207d4a 100644 Binary files a/public/images/emoji/google/clock430.png and b/public/images/emoji/google/clock430.png differ diff --git a/public/images/emoji/google/clock5.png b/public/images/emoji/google/clock5.png index 050efd351ff..7c6abe7f4ea 100644 Binary files a/public/images/emoji/google/clock5.png and b/public/images/emoji/google/clock5.png differ diff --git a/public/images/emoji/google/clock530.png b/public/images/emoji/google/clock530.png index 1a46f7fce63..e353f09a014 100644 Binary files a/public/images/emoji/google/clock530.png and b/public/images/emoji/google/clock530.png differ diff --git a/public/images/emoji/google/clock6.png b/public/images/emoji/google/clock6.png index ee93c676f81..ee236d96b85 100644 Binary files a/public/images/emoji/google/clock6.png and b/public/images/emoji/google/clock6.png differ diff --git a/public/images/emoji/google/clock630.png b/public/images/emoji/google/clock630.png index ea32ddb9e46..d4e78c458ea 100644 Binary files a/public/images/emoji/google/clock630.png and b/public/images/emoji/google/clock630.png differ diff --git a/public/images/emoji/google/clock7.png b/public/images/emoji/google/clock7.png index 2845ebf4842..9674f89101c 100644 Binary files a/public/images/emoji/google/clock7.png and b/public/images/emoji/google/clock7.png differ diff --git a/public/images/emoji/google/clock730.png b/public/images/emoji/google/clock730.png index ea2b0623fa7..6ec4f02ddbb 100644 Binary files a/public/images/emoji/google/clock730.png and b/public/images/emoji/google/clock730.png differ diff --git a/public/images/emoji/google/clock8.png b/public/images/emoji/google/clock8.png index 0f53349daed..cb7fa439d61 100644 Binary files a/public/images/emoji/google/clock8.png and b/public/images/emoji/google/clock8.png differ diff --git a/public/images/emoji/google/clock830.png b/public/images/emoji/google/clock830.png index ba5c4cbe7e6..7eee859910c 100644 Binary files a/public/images/emoji/google/clock830.png and b/public/images/emoji/google/clock830.png differ diff --git a/public/images/emoji/google/clock9.png b/public/images/emoji/google/clock9.png index 86a68a66847..3f328d5b737 100644 Binary files a/public/images/emoji/google/clock9.png and b/public/images/emoji/google/clock9.png differ diff --git a/public/images/emoji/google/clock930.png b/public/images/emoji/google/clock930.png index b90a81e6d02..e89ce6d237e 100644 Binary files a/public/images/emoji/google/clock930.png and b/public/images/emoji/google/clock930.png differ diff --git a/public/images/emoji/google/closed_book.png b/public/images/emoji/google/closed_book.png index fefd465eb4e..9e8f17a7058 100644 Binary files a/public/images/emoji/google/closed_book.png and b/public/images/emoji/google/closed_book.png differ diff --git a/public/images/emoji/google/closed_lock_with_key.png b/public/images/emoji/google/closed_lock_with_key.png index a64c97b8495..9d574d88f28 100644 Binary files a/public/images/emoji/google/closed_lock_with_key.png and b/public/images/emoji/google/closed_lock_with_key.png differ diff --git a/public/images/emoji/google/closed_umbrella.png b/public/images/emoji/google/closed_umbrella.png index 8a5e87da83b..cc98f3fb681 100644 Binary files a/public/images/emoji/google/closed_umbrella.png and b/public/images/emoji/google/closed_umbrella.png differ diff --git a/public/images/emoji/google/cloud.png b/public/images/emoji/google/cloud.png index c2291b5ab9e..ad171cb9355 100644 Binary files a/public/images/emoji/google/cloud.png and b/public/images/emoji/google/cloud.png differ diff --git a/public/images/emoji/google/cloud_lightning.png b/public/images/emoji/google/cloud_lightning.png new file mode 100644 index 00000000000..7928332acf0 Binary files /dev/null and b/public/images/emoji/google/cloud_lightning.png differ diff --git a/public/images/emoji/google/cloud_rain.png b/public/images/emoji/google/cloud_rain.png new file mode 100644 index 00000000000..9c98ad6c661 Binary files /dev/null and b/public/images/emoji/google/cloud_rain.png differ diff --git a/public/images/emoji/google/cloud_snow.png b/public/images/emoji/google/cloud_snow.png new file mode 100644 index 00000000000..06159ea0e78 Binary files /dev/null and b/public/images/emoji/google/cloud_snow.png differ diff --git a/public/images/emoji/google/cloud_tornado.png b/public/images/emoji/google/cloud_tornado.png new file mode 100644 index 00000000000..3cd4cfb5193 Binary files /dev/null and b/public/images/emoji/google/cloud_tornado.png differ diff --git a/public/images/emoji/google/clubs.png b/public/images/emoji/google/clubs.png index 19ebed9ccfa..ff8e6aa9c12 100644 Binary files a/public/images/emoji/google/clubs.png and b/public/images/emoji/google/clubs.png differ diff --git a/public/images/emoji/google/cn.png b/public/images/emoji/google/cn.png index 80b5033cacb..e3d59bb2933 100644 Binary files a/public/images/emoji/google/cn.png and b/public/images/emoji/google/cn.png differ diff --git a/public/images/emoji/google/cocktail.png b/public/images/emoji/google/cocktail.png index 3a4e6a04ba1..23a5920b2cf 100644 Binary files a/public/images/emoji/google/cocktail.png and b/public/images/emoji/google/cocktail.png differ diff --git a/public/images/emoji/google/coffee.png b/public/images/emoji/google/coffee.png index 86a7b6a05b8..1d0b431d98e 100644 Binary files a/public/images/emoji/google/coffee.png and b/public/images/emoji/google/coffee.png differ diff --git a/public/images/emoji/google/coffin.png b/public/images/emoji/google/coffin.png new file mode 100644 index 00000000000..07777d3fd1e Binary files /dev/null and b/public/images/emoji/google/coffin.png differ diff --git a/public/images/emoji/google/cold_sweat.png b/public/images/emoji/google/cold_sweat.png index 8240560f255..fe5af1e2643 100644 Binary files a/public/images/emoji/google/cold_sweat.png and b/public/images/emoji/google/cold_sweat.png differ diff --git a/public/images/emoji/google/collision.png b/public/images/emoji/google/collision.png index a143d6c4058..ceb728289ac 100644 Binary files a/public/images/emoji/google/collision.png and b/public/images/emoji/google/collision.png differ diff --git a/public/images/emoji/google/comet.png b/public/images/emoji/google/comet.png new file mode 100644 index 00000000000..9cad61148d2 Binary files /dev/null and b/public/images/emoji/google/comet.png differ diff --git a/public/images/emoji/google/compression.png b/public/images/emoji/google/compression.png new file mode 100644 index 00000000000..ac7dd4ca768 Binary files /dev/null and b/public/images/emoji/google/compression.png differ diff --git a/public/images/emoji/google/computer.png b/public/images/emoji/google/computer.png index fdfb40b1db3..2a46e89ee92 100644 Binary files a/public/images/emoji/google/computer.png and b/public/images/emoji/google/computer.png differ diff --git a/public/images/emoji/google/confetti_ball.png b/public/images/emoji/google/confetti_ball.png index 476a5c2e0a2..3c43c625cfe 100644 Binary files a/public/images/emoji/google/confetti_ball.png and b/public/images/emoji/google/confetti_ball.png differ diff --git a/public/images/emoji/google/confounded.png b/public/images/emoji/google/confounded.png index 6820199b543..597e08fe786 100644 Binary files a/public/images/emoji/google/confounded.png and b/public/images/emoji/google/confounded.png differ diff --git a/public/images/emoji/google/confused.png b/public/images/emoji/google/confused.png index 0c830e8e136..d870aa4d994 100644 Binary files a/public/images/emoji/google/confused.png and b/public/images/emoji/google/confused.png differ diff --git a/public/images/emoji/google/congratulations.png b/public/images/emoji/google/congratulations.png index 369d1fbe21f..85c40aabf45 100644 Binary files a/public/images/emoji/google/congratulations.png and b/public/images/emoji/google/congratulations.png differ diff --git a/public/images/emoji/google/construction.png b/public/images/emoji/google/construction.png index fe526b558b6..433dc1c65e6 100644 Binary files a/public/images/emoji/google/construction.png and b/public/images/emoji/google/construction.png differ diff --git a/public/images/emoji/google/construction_site.png b/public/images/emoji/google/construction_site.png new file mode 100644 index 00000000000..2b27bfb8960 Binary files /dev/null and b/public/images/emoji/google/construction_site.png differ diff --git a/public/images/emoji/google/construction_worker.png b/public/images/emoji/google/construction_worker.png index e9ac71d9fa2..420d08043c9 100644 Binary files a/public/images/emoji/google/construction_worker.png and b/public/images/emoji/google/construction_worker.png differ diff --git a/public/images/emoji/google/control_knobs.png b/public/images/emoji/google/control_knobs.png new file mode 100644 index 00000000000..01aa45bcfdb Binary files /dev/null and b/public/images/emoji/google/control_knobs.png differ diff --git a/public/images/emoji/google/convenience_store.png b/public/images/emoji/google/convenience_store.png index 1a35206174f..dad0f42352f 100644 Binary files a/public/images/emoji/google/convenience_store.png and b/public/images/emoji/google/convenience_store.png differ diff --git a/public/images/emoji/google/cookie.png b/public/images/emoji/google/cookie.png index ebc0e44ee60..7a0ebc5aaab 100644 Binary files a/public/images/emoji/google/cookie.png and b/public/images/emoji/google/cookie.png differ diff --git a/public/images/emoji/google/cool.png b/public/images/emoji/google/cool.png index ca0ab9ffd3d..4f6889458db 100644 Binary files a/public/images/emoji/google/cool.png and b/public/images/emoji/google/cool.png differ diff --git a/public/images/emoji/google/cop.png b/public/images/emoji/google/cop.png index 58482179d4a..0c4332d98a0 100644 Binary files a/public/images/emoji/google/cop.png and b/public/images/emoji/google/cop.png differ diff --git a/public/images/emoji/google/corn.png b/public/images/emoji/google/corn.png index 227207c3136..fdcce5df6d4 100644 Binary files a/public/images/emoji/google/corn.png and b/public/images/emoji/google/corn.png differ diff --git a/public/images/emoji/google/couch.png b/public/images/emoji/google/couch.png new file mode 100644 index 00000000000..b5628b0201d Binary files /dev/null and b/public/images/emoji/google/couch.png differ diff --git a/public/images/emoji/google/couple.png b/public/images/emoji/google/couple.png index a54ba3f716e..525a95b81fd 100644 Binary files a/public/images/emoji/google/couple.png and b/public/images/emoji/google/couple.png differ diff --git a/public/images/emoji/google/couple_with_heart.png b/public/images/emoji/google/couple_with_heart.png index 2cfe9d3e799..77f57dabe7f 100644 Binary files a/public/images/emoji/google/couple_with_heart.png and b/public/images/emoji/google/couple_with_heart.png differ diff --git a/public/images/emoji/google/couplekiss.png b/public/images/emoji/google/couplekiss.png index 47846113d61..f55fc515c8a 100644 Binary files a/public/images/emoji/google/couplekiss.png and b/public/images/emoji/google/couplekiss.png differ diff --git a/public/images/emoji/google/cow.png b/public/images/emoji/google/cow.png index f477a79cf33..d5948806343 100644 Binary files a/public/images/emoji/google/cow.png and b/public/images/emoji/google/cow.png differ diff --git a/public/images/emoji/google/cow2.png b/public/images/emoji/google/cow2.png index 2ad4f10c086..1fe12b4eec0 100644 Binary files a/public/images/emoji/google/cow2.png and b/public/images/emoji/google/cow2.png differ diff --git a/public/images/emoji/google/crab.png b/public/images/emoji/google/crab.png new file mode 100644 index 00000000000..37b3180429f Binary files /dev/null and b/public/images/emoji/google/crab.png differ diff --git a/public/images/emoji/google/crayon.png b/public/images/emoji/google/crayon.png new file mode 100644 index 00000000000..0096c9c637c Binary files /dev/null and b/public/images/emoji/google/crayon.png differ diff --git a/public/images/emoji/google/credit_card.png b/public/images/emoji/google/credit_card.png index 31e899d9175..cfe301946ef 100644 Binary files a/public/images/emoji/google/credit_card.png and b/public/images/emoji/google/credit_card.png differ diff --git a/public/images/emoji/google/crescent_moon.png b/public/images/emoji/google/crescent_moon.png index a5ad76d3b4f..b9451b81088 100644 Binary files a/public/images/emoji/google/crescent_moon.png and b/public/images/emoji/google/crescent_moon.png differ diff --git a/public/images/emoji/google/cricket.png b/public/images/emoji/google/cricket.png new file mode 100644 index 00000000000..300b76d5765 Binary files /dev/null and b/public/images/emoji/google/cricket.png differ diff --git a/public/images/emoji/google/crocodile.png b/public/images/emoji/google/crocodile.png index ab7ef7966ad..e5164c2c14f 100644 Binary files a/public/images/emoji/google/crocodile.png and b/public/images/emoji/google/crocodile.png differ diff --git a/public/images/emoji/google/cross.png b/public/images/emoji/google/cross.png new file mode 100644 index 00000000000..1529863dfd8 Binary files /dev/null and b/public/images/emoji/google/cross.png differ diff --git a/public/images/emoji/google/crossed_flags.png b/public/images/emoji/google/crossed_flags.png index 39cd886dcfb..cf00a174cb2 100644 Binary files a/public/images/emoji/google/crossed_flags.png and b/public/images/emoji/google/crossed_flags.png differ diff --git a/public/images/emoji/google/crossed_swords.png b/public/images/emoji/google/crossed_swords.png new file mode 100644 index 00000000000..636eb7e8e02 Binary files /dev/null and b/public/images/emoji/google/crossed_swords.png differ diff --git a/public/images/emoji/google/crown.png b/public/images/emoji/google/crown.png index b2f99e1da3a..06cb905256b 100644 Binary files a/public/images/emoji/google/crown.png and b/public/images/emoji/google/crown.png differ diff --git a/public/images/emoji/google/cruise_ship.png b/public/images/emoji/google/cruise_ship.png new file mode 100644 index 00000000000..b9360e8eda4 Binary files /dev/null and b/public/images/emoji/google/cruise_ship.png differ diff --git a/public/images/emoji/google/cry.png b/public/images/emoji/google/cry.png index 5056c8153b5..9e39b4a8b28 100644 Binary files a/public/images/emoji/google/cry.png and b/public/images/emoji/google/cry.png differ diff --git a/public/images/emoji/google/crying_cat_face.png b/public/images/emoji/google/crying_cat_face.png index 2b3f6430e26..971fcd020a1 100644 Binary files a/public/images/emoji/google/crying_cat_face.png and b/public/images/emoji/google/crying_cat_face.png differ diff --git a/public/images/emoji/google/crystal_ball.png b/public/images/emoji/google/crystal_ball.png index 1cbb69a764f..015eb29944f 100644 Binary files a/public/images/emoji/google/crystal_ball.png and b/public/images/emoji/google/crystal_ball.png differ diff --git a/public/images/emoji/google/cupid.png b/public/images/emoji/google/cupid.png index c18d80d32df..ab572072b5e 100644 Binary files a/public/images/emoji/google/cupid.png and b/public/images/emoji/google/cupid.png differ diff --git a/public/images/emoji/google/curly_loop.png b/public/images/emoji/google/curly_loop.png index 3e90be6b60b..af104d9e826 100644 Binary files a/public/images/emoji/google/curly_loop.png and b/public/images/emoji/google/curly_loop.png differ diff --git a/public/images/emoji/google/currency_exchange.png b/public/images/emoji/google/currency_exchange.png index 8e18b38bf75..c3387572e0e 100644 Binary files a/public/images/emoji/google/currency_exchange.png and b/public/images/emoji/google/currency_exchange.png differ diff --git a/public/images/emoji/google/curry.png b/public/images/emoji/google/curry.png index aaa54d256a1..87be46d1de3 100644 Binary files a/public/images/emoji/google/curry.png and b/public/images/emoji/google/curry.png differ diff --git a/public/images/emoji/google/custard.png b/public/images/emoji/google/custard.png index 1fe85bde141..b87a6792490 100644 Binary files a/public/images/emoji/google/custard.png and b/public/images/emoji/google/custard.png differ diff --git a/public/images/emoji/google/customs.png b/public/images/emoji/google/customs.png index e0f48dc9c73..80437fd43a1 100644 Binary files a/public/images/emoji/google/customs.png and b/public/images/emoji/google/customs.png differ diff --git a/public/images/emoji/google/cyclone.png b/public/images/emoji/google/cyclone.png index f63cee1e659..a61ce8cdb40 100644 Binary files a/public/images/emoji/google/cyclone.png and b/public/images/emoji/google/cyclone.png differ diff --git a/public/images/emoji/google/dagger.png b/public/images/emoji/google/dagger.png new file mode 100644 index 00000000000..6a4b31e00fd Binary files /dev/null and b/public/images/emoji/google/dagger.png differ diff --git a/public/images/emoji/google/dancer.png b/public/images/emoji/google/dancer.png index 49e9f30b7b9..91b262526b0 100644 Binary files a/public/images/emoji/google/dancer.png and b/public/images/emoji/google/dancer.png differ diff --git a/public/images/emoji/google/dancers.png b/public/images/emoji/google/dancers.png index 41c71964e3b..88633f21b78 100644 Binary files a/public/images/emoji/google/dancers.png and b/public/images/emoji/google/dancers.png differ diff --git a/public/images/emoji/google/dango.png b/public/images/emoji/google/dango.png index 0bf003e91f9..d1ed6deab82 100644 Binary files a/public/images/emoji/google/dango.png and b/public/images/emoji/google/dango.png differ diff --git a/public/images/emoji/google/dark_sunglasses.png b/public/images/emoji/google/dark_sunglasses.png new file mode 100644 index 00000000000..ded25ea1d94 Binary files /dev/null and b/public/images/emoji/google/dark_sunglasses.png differ diff --git a/public/images/emoji/google/dart.png b/public/images/emoji/google/dart.png index 855d690952f..4f5c794a713 100644 Binary files a/public/images/emoji/google/dart.png and b/public/images/emoji/google/dart.png differ diff --git a/public/images/emoji/google/dash.png b/public/images/emoji/google/dash.png index f60692f458d..1504802ec09 100644 Binary files a/public/images/emoji/google/dash.png and b/public/images/emoji/google/dash.png differ diff --git a/public/images/emoji/google/date.png b/public/images/emoji/google/date.png index d7070ed7c3d..22a90b06e92 100644 Binary files a/public/images/emoji/google/date.png and b/public/images/emoji/google/date.png differ diff --git a/public/images/emoji/google/de.png b/public/images/emoji/google/de.png index fae9552eb3d..b864c83462d 100644 Binary files a/public/images/emoji/google/de.png and b/public/images/emoji/google/de.png differ diff --git a/public/images/emoji/google/deciduous_tree.png b/public/images/emoji/google/deciduous_tree.png index fc846109a73..6ec2c3913fe 100644 Binary files a/public/images/emoji/google/deciduous_tree.png and b/public/images/emoji/google/deciduous_tree.png differ diff --git a/public/images/emoji/google/department_store.png b/public/images/emoji/google/department_store.png index e366e68fbf1..3df6a3f662b 100644 Binary files a/public/images/emoji/google/department_store.png and b/public/images/emoji/google/department_store.png differ diff --git a/public/images/emoji/google/desert.png b/public/images/emoji/google/desert.png new file mode 100644 index 00000000000..beac9e023c7 Binary files /dev/null and b/public/images/emoji/google/desert.png differ diff --git a/public/images/emoji/google/desktop.png b/public/images/emoji/google/desktop.png new file mode 100644 index 00000000000..7aa0819ee46 Binary files /dev/null and b/public/images/emoji/google/desktop.png differ diff --git a/public/images/emoji/google/diamond_shape_with_a_dot_inside.png b/public/images/emoji/google/diamond_shape_with_a_dot_inside.png index f5568550ee0..ec534864c33 100644 Binary files a/public/images/emoji/google/diamond_shape_with_a_dot_inside.png and b/public/images/emoji/google/diamond_shape_with_a_dot_inside.png differ diff --git a/public/images/emoji/google/diamonds.png b/public/images/emoji/google/diamonds.png index 30ac5a770b9..f5cfcc7d399 100644 Binary files a/public/images/emoji/google/diamonds.png and b/public/images/emoji/google/diamonds.png differ diff --git a/public/images/emoji/google/disappointed.png b/public/images/emoji/google/disappointed.png index 95c8477721c..ce2be1ed0fd 100644 Binary files a/public/images/emoji/google/disappointed.png and b/public/images/emoji/google/disappointed.png differ diff --git a/public/images/emoji/google/disappointed_relieved.png b/public/images/emoji/google/disappointed_relieved.png index e1832aba189..1e4811d9792 100644 Binary files a/public/images/emoji/google/disappointed_relieved.png and b/public/images/emoji/google/disappointed_relieved.png differ diff --git a/public/images/emoji/google/dividers.png b/public/images/emoji/google/dividers.png new file mode 100644 index 00000000000..b526d0e34be Binary files /dev/null and b/public/images/emoji/google/dividers.png differ diff --git a/public/images/emoji/google/dizzy.png b/public/images/emoji/google/dizzy.png index a231e44f896..b1c445f4fdc 100644 Binary files a/public/images/emoji/google/dizzy.png and b/public/images/emoji/google/dizzy.png differ diff --git a/public/images/emoji/google/dizzy_face.png b/public/images/emoji/google/dizzy_face.png index b4c4af576c0..4a4185c5956 100644 Binary files a/public/images/emoji/google/dizzy_face.png and b/public/images/emoji/google/dizzy_face.png differ diff --git a/public/images/emoji/google/do_not_litter.png b/public/images/emoji/google/do_not_litter.png index 83defc7b262..30b46752933 100644 Binary files a/public/images/emoji/google/do_not_litter.png and b/public/images/emoji/google/do_not_litter.png differ diff --git a/public/images/emoji/google/dog.png b/public/images/emoji/google/dog.png index f6fa6a6a324..b3f37a1ebd8 100644 Binary files a/public/images/emoji/google/dog.png and b/public/images/emoji/google/dog.png differ diff --git a/public/images/emoji/google/dog2.png b/public/images/emoji/google/dog2.png index e0f12799165..18bf2b7b289 100644 Binary files a/public/images/emoji/google/dog2.png and b/public/images/emoji/google/dog2.png differ diff --git a/public/images/emoji/google/dollar.png b/public/images/emoji/google/dollar.png index 86b0e48160c..e5b0e557422 100644 Binary files a/public/images/emoji/google/dollar.png and b/public/images/emoji/google/dollar.png differ diff --git a/public/images/emoji/google/dolls.png b/public/images/emoji/google/dolls.png index dde5eb148cf..25e61036bb4 100644 Binary files a/public/images/emoji/google/dolls.png and b/public/images/emoji/google/dolls.png differ diff --git a/public/images/emoji/google/dolphin.png b/public/images/emoji/google/dolphin.png index 5a96ea27919..71e5a1e12a6 100644 Binary files a/public/images/emoji/google/dolphin.png and b/public/images/emoji/google/dolphin.png differ diff --git a/public/images/emoji/google/door.png b/public/images/emoji/google/door.png index 3a336f79250..8ddea5b80b7 100644 Binary files a/public/images/emoji/google/door.png and b/public/images/emoji/google/door.png differ diff --git a/public/images/emoji/google/doughnut.png b/public/images/emoji/google/doughnut.png index 30bb26049a6..d5c91b0eb3d 100644 Binary files a/public/images/emoji/google/doughnut.png and b/public/images/emoji/google/doughnut.png differ diff --git a/public/images/emoji/google/dove.png b/public/images/emoji/google/dove.png new file mode 100644 index 00000000000..4095825d745 Binary files /dev/null and b/public/images/emoji/google/dove.png differ diff --git a/public/images/emoji/google/dragon.png b/public/images/emoji/google/dragon.png index e8793c8f1ec..7c91df61521 100644 Binary files a/public/images/emoji/google/dragon.png and b/public/images/emoji/google/dragon.png differ diff --git a/public/images/emoji/google/dragon_face.png b/public/images/emoji/google/dragon_face.png index afaab1dc8a1..2c27cf94a94 100644 Binary files a/public/images/emoji/google/dragon_face.png and b/public/images/emoji/google/dragon_face.png differ diff --git a/public/images/emoji/google/dress.png b/public/images/emoji/google/dress.png index cc44eb65e2a..24db160272f 100644 Binary files a/public/images/emoji/google/dress.png and b/public/images/emoji/google/dress.png differ diff --git a/public/images/emoji/google/dromedary_camel.png b/public/images/emoji/google/dromedary_camel.png index 8e6e4cc700b..1b54b563060 100644 Binary files a/public/images/emoji/google/dromedary_camel.png and b/public/images/emoji/google/dromedary_camel.png differ diff --git a/public/images/emoji/google/droplet.png b/public/images/emoji/google/droplet.png index c0ef9ed226f..5b597b84b5b 100644 Binary files a/public/images/emoji/google/droplet.png and b/public/images/emoji/google/droplet.png differ diff --git a/public/images/emoji/google/dvd.png b/public/images/emoji/google/dvd.png index cf9da9221ac..2fbce4b08c0 100644 Binary files a/public/images/emoji/google/dvd.png and b/public/images/emoji/google/dvd.png differ diff --git a/public/images/emoji/google/e-mail.png b/public/images/emoji/google/e-mail.png index b93ed883e8b..d1126e07637 100644 Binary files a/public/images/emoji/google/e-mail.png and b/public/images/emoji/google/e-mail.png differ diff --git a/public/images/emoji/google/ear.png b/public/images/emoji/google/ear.png index c8cd99bd01b..cf084db03c1 100644 Binary files a/public/images/emoji/google/ear.png and b/public/images/emoji/google/ear.png differ diff --git a/public/images/emoji/google/ear_of_rice.png b/public/images/emoji/google/ear_of_rice.png index db1264dde9d..da2b428e193 100644 Binary files a/public/images/emoji/google/ear_of_rice.png and b/public/images/emoji/google/ear_of_rice.png differ diff --git a/public/images/emoji/google/earth_africa.png b/public/images/emoji/google/earth_africa.png index 404f61947bb..6d3c7e5f380 100644 Binary files a/public/images/emoji/google/earth_africa.png and b/public/images/emoji/google/earth_africa.png differ diff --git a/public/images/emoji/google/earth_americas.png b/public/images/emoji/google/earth_americas.png index 920faacc836..de3ceedebcc 100644 Binary files a/public/images/emoji/google/earth_americas.png and b/public/images/emoji/google/earth_americas.png differ diff --git a/public/images/emoji/google/earth_asia.png b/public/images/emoji/google/earth_asia.png index 18addb45427..9d85f1c7f78 100644 Binary files a/public/images/emoji/google/earth_asia.png and b/public/images/emoji/google/earth_asia.png differ diff --git a/public/images/emoji/google/egg.png b/public/images/emoji/google/egg.png index 948cf1ef213..485549454bc 100644 Binary files a/public/images/emoji/google/egg.png and b/public/images/emoji/google/egg.png differ diff --git a/public/images/emoji/google/eggplant.png b/public/images/emoji/google/eggplant.png index fe7a9e2590f..b6c3bf4b0e6 100644 Binary files a/public/images/emoji/google/eggplant.png and b/public/images/emoji/google/eggplant.png differ diff --git a/public/images/emoji/google/eight.png b/public/images/emoji/google/eight.png index f0be67d9d57..9eb32d7196b 100644 Binary files a/public/images/emoji/google/eight.png and b/public/images/emoji/google/eight.png differ diff --git a/public/images/emoji/google/eight_pointed_black_star.png b/public/images/emoji/google/eight_pointed_black_star.png index bd3dddd9c3f..7a225ae4b8f 100644 Binary files a/public/images/emoji/google/eight_pointed_black_star.png and b/public/images/emoji/google/eight_pointed_black_star.png differ diff --git a/public/images/emoji/google/eight_spoked_asterisk.png b/public/images/emoji/google/eight_spoked_asterisk.png index 919703c263e..9a4b6eab33b 100644 Binary files a/public/images/emoji/google/eight_spoked_asterisk.png and b/public/images/emoji/google/eight_spoked_asterisk.png differ diff --git a/public/images/emoji/google/electric_plug.png b/public/images/emoji/google/electric_plug.png index c7f483fcdcc..40ac792bc23 100644 Binary files a/public/images/emoji/google/electric_plug.png and b/public/images/emoji/google/electric_plug.png differ diff --git a/public/images/emoji/google/elephant.png b/public/images/emoji/google/elephant.png index 39d833c3125..d125a44a714 100644 Binary files a/public/images/emoji/google/elephant.png and b/public/images/emoji/google/elephant.png differ diff --git a/public/images/emoji/google/email.png b/public/images/emoji/google/email.png index 1dd98cc6a6b..79f93798906 100644 Binary files a/public/images/emoji/google/email.png and b/public/images/emoji/google/email.png differ diff --git a/public/images/emoji/google/end.png b/public/images/emoji/google/end.png index 97b98c5be2c..ec2ee2f68e5 100644 Binary files a/public/images/emoji/google/end.png and b/public/images/emoji/google/end.png differ diff --git a/public/images/emoji/google/envelope_with_arrow.png b/public/images/emoji/google/envelope_with_arrow.png index 477a189e9fa..7ea961a583e 100644 Binary files a/public/images/emoji/google/envelope_with_arrow.png and b/public/images/emoji/google/envelope_with_arrow.png differ diff --git a/public/images/emoji/google/es.png b/public/images/emoji/google/es.png index 71c41be537b..bb27b5fca6e 100644 Binary files a/public/images/emoji/google/es.png and b/public/images/emoji/google/es.png differ diff --git a/public/images/emoji/google/euro.png b/public/images/emoji/google/euro.png index 35cdc9aa134..f51f3bb2b14 100644 Binary files a/public/images/emoji/google/euro.png and b/public/images/emoji/google/euro.png differ diff --git a/public/images/emoji/google/european_castle.png b/public/images/emoji/google/european_castle.png index eec7a3109d8..3001aed5fe9 100644 Binary files a/public/images/emoji/google/european_castle.png and b/public/images/emoji/google/european_castle.png differ diff --git a/public/images/emoji/google/european_post_office.png b/public/images/emoji/google/european_post_office.png index 154eebc6ca8..707f240be39 100644 Binary files a/public/images/emoji/google/european_post_office.png and b/public/images/emoji/google/european_post_office.png differ diff --git a/public/images/emoji/google/evergreen_tree.png b/public/images/emoji/google/evergreen_tree.png index 594745ef77f..ee1e89b1ddf 100644 Binary files a/public/images/emoji/google/evergreen_tree.png and b/public/images/emoji/google/evergreen_tree.png differ diff --git a/public/images/emoji/google/exclamation.png b/public/images/emoji/google/exclamation.png index db65e8d05c8..df79bb3bb6e 100644 Binary files a/public/images/emoji/google/exclamation.png and b/public/images/emoji/google/exclamation.png differ diff --git a/public/images/emoji/google/expressionless.png b/public/images/emoji/google/expressionless.png index 7d12ae899d7..ffa0f8b01fe 100644 Binary files a/public/images/emoji/google/expressionless.png and b/public/images/emoji/google/expressionless.png differ diff --git a/public/images/emoji/google/eye.png b/public/images/emoji/google/eye.png new file mode 100644 index 00000000000..61e901e6cda Binary files /dev/null and b/public/images/emoji/google/eye.png differ diff --git a/public/images/emoji/google/eyeglasses.png b/public/images/emoji/google/eyeglasses.png index 48e61fb45f0..f4173f9de98 100644 Binary files a/public/images/emoji/google/eyeglasses.png and b/public/images/emoji/google/eyeglasses.png differ diff --git a/public/images/emoji/google/eyes.png b/public/images/emoji/google/eyes.png index a341f7a3a33..158af01c8f9 100644 Binary files a/public/images/emoji/google/eyes.png and b/public/images/emoji/google/eyes.png differ diff --git a/public/images/emoji/google/facepunch.png b/public/images/emoji/google/facepunch.png index 96672f8da34..45f6d8e99b4 100644 Binary files a/public/images/emoji/google/facepunch.png and b/public/images/emoji/google/facepunch.png differ diff --git a/public/images/emoji/google/factory.png b/public/images/emoji/google/factory.png index 9a980e92f83..6e261a0aab5 100644 Binary files a/public/images/emoji/google/factory.png and b/public/images/emoji/google/factory.png differ diff --git a/public/images/emoji/google/fallen_leaf.png b/public/images/emoji/google/fallen_leaf.png index 0839ada3916..03ac796f03c 100644 Binary files a/public/images/emoji/google/fallen_leaf.png and b/public/images/emoji/google/fallen_leaf.png differ diff --git a/public/images/emoji/google/family.png b/public/images/emoji/google/family.png index c02783f6d75..8dbcb3af086 100644 Binary files a/public/images/emoji/google/family.png and b/public/images/emoji/google/family.png differ diff --git a/public/images/emoji/google/fast_forward.png b/public/images/emoji/google/fast_forward.png index 01f6de32db5..a82c8395705 100644 Binary files a/public/images/emoji/google/fast_forward.png and b/public/images/emoji/google/fast_forward.png differ diff --git a/public/images/emoji/google/fax.png b/public/images/emoji/google/fax.png index 877c37efe59..dee4ae69601 100644 Binary files a/public/images/emoji/google/fax.png and b/public/images/emoji/google/fax.png differ diff --git a/public/images/emoji/google/fearful.png b/public/images/emoji/google/fearful.png index a368a711385..942763960d2 100644 Binary files a/public/images/emoji/google/fearful.png and b/public/images/emoji/google/fearful.png differ diff --git a/public/images/emoji/google/feet.png b/public/images/emoji/google/feet.png index 3f88932e4af..5d61e5a9128 100644 Binary files a/public/images/emoji/google/feet.png and b/public/images/emoji/google/feet.png differ diff --git a/public/images/emoji/google/ferris_wheel.png b/public/images/emoji/google/ferris_wheel.png index 634643f8ce3..a9ea6443d6c 100644 Binary files a/public/images/emoji/google/ferris_wheel.png and b/public/images/emoji/google/ferris_wheel.png differ diff --git a/public/images/emoji/google/ferry.png b/public/images/emoji/google/ferry.png new file mode 100644 index 00000000000..06b9353718f Binary files /dev/null and b/public/images/emoji/google/ferry.png differ diff --git a/public/images/emoji/google/field_hockey.png b/public/images/emoji/google/field_hockey.png new file mode 100644 index 00000000000..7213afedce9 Binary files /dev/null and b/public/images/emoji/google/field_hockey.png differ diff --git a/public/images/emoji/google/file_cabinet.png b/public/images/emoji/google/file_cabinet.png new file mode 100644 index 00000000000..c197648675f Binary files /dev/null and b/public/images/emoji/google/file_cabinet.png differ diff --git a/public/images/emoji/google/file_folder.png b/public/images/emoji/google/file_folder.png index 8a2f54372c5..25911ee75e4 100644 Binary files a/public/images/emoji/google/file_folder.png and b/public/images/emoji/google/file_folder.png differ diff --git a/public/images/emoji/google/film_frames.png b/public/images/emoji/google/film_frames.png new file mode 100644 index 00000000000..d3a79feff7a Binary files /dev/null and b/public/images/emoji/google/film_frames.png differ diff --git a/public/images/emoji/google/fire.png b/public/images/emoji/google/fire.png index a4bc221c6df..86f9a41beef 100644 Binary files a/public/images/emoji/google/fire.png and b/public/images/emoji/google/fire.png differ diff --git a/public/images/emoji/google/fire_engine.png b/public/images/emoji/google/fire_engine.png index e6ec91a9f40..21fd9aa2d91 100644 Binary files a/public/images/emoji/google/fire_engine.png and b/public/images/emoji/google/fire_engine.png differ diff --git a/public/images/emoji/google/fireworks.png b/public/images/emoji/google/fireworks.png index 22e886c7638..32ec3428b07 100644 Binary files a/public/images/emoji/google/fireworks.png and b/public/images/emoji/google/fireworks.png differ diff --git a/public/images/emoji/google/first_quarter_moon.png b/public/images/emoji/google/first_quarter_moon.png index ee32ca7a9a7..4b898f4a865 100644 Binary files a/public/images/emoji/google/first_quarter_moon.png and b/public/images/emoji/google/first_quarter_moon.png differ diff --git a/public/images/emoji/google/first_quarter_moon_with_face.png b/public/images/emoji/google/first_quarter_moon_with_face.png index c2812449283..47ade0f6167 100644 Binary files a/public/images/emoji/google/first_quarter_moon_with_face.png and b/public/images/emoji/google/first_quarter_moon_with_face.png differ diff --git a/public/images/emoji/google/fish.png b/public/images/emoji/google/fish.png index 20d7fcd20b2..51d6c794c9a 100644 Binary files a/public/images/emoji/google/fish.png and b/public/images/emoji/google/fish.png differ diff --git a/public/images/emoji/google/fish_cake.png b/public/images/emoji/google/fish_cake.png index 5d943adc6df..0b843818375 100644 Binary files a/public/images/emoji/google/fish_cake.png and b/public/images/emoji/google/fish_cake.png differ diff --git a/public/images/emoji/google/fishing_pole_and_fish.png b/public/images/emoji/google/fishing_pole_and_fish.png index b5a0c98598d..986c4dffc11 100644 Binary files a/public/images/emoji/google/fishing_pole_and_fish.png and b/public/images/emoji/google/fishing_pole_and_fish.png differ diff --git a/public/images/emoji/google/fist.png b/public/images/emoji/google/fist.png index 03788511284..2d310d45e98 100644 Binary files a/public/images/emoji/google/fist.png and b/public/images/emoji/google/fist.png differ diff --git a/public/images/emoji/google/flag_black.png b/public/images/emoji/google/flag_black.png new file mode 100644 index 00000000000..01ecfa27536 Binary files /dev/null and b/public/images/emoji/google/flag_black.png differ diff --git a/public/images/emoji/google/flag_cn.png b/public/images/emoji/google/flag_cn.png new file mode 100644 index 00000000000..2d9c3dad8d6 Binary files /dev/null and b/public/images/emoji/google/flag_cn.png differ diff --git a/public/images/emoji/google/flag_de.png b/public/images/emoji/google/flag_de.png new file mode 100644 index 00000000000..0baf83652e5 Binary files /dev/null and b/public/images/emoji/google/flag_de.png differ diff --git a/public/images/emoji/google/flag_es.png b/public/images/emoji/google/flag_es.png new file mode 100644 index 00000000000..e04765d6b78 Binary files /dev/null and b/public/images/emoji/google/flag_es.png differ diff --git a/public/images/emoji/google/flag_fr.png b/public/images/emoji/google/flag_fr.png new file mode 100644 index 00000000000..674b50805a8 Binary files /dev/null and b/public/images/emoji/google/flag_fr.png differ diff --git a/public/images/emoji/google/flag_gb.png b/public/images/emoji/google/flag_gb.png new file mode 100644 index 00000000000..c5c919ada6b Binary files /dev/null and b/public/images/emoji/google/flag_gb.png differ diff --git a/public/images/emoji/google/flag_it.png b/public/images/emoji/google/flag_it.png new file mode 100644 index 00000000000..7d98f98011f Binary files /dev/null and b/public/images/emoji/google/flag_it.png differ diff --git a/public/images/emoji/google/flag_jp.png b/public/images/emoji/google/flag_jp.png new file mode 100644 index 00000000000..a04b719f8a0 Binary files /dev/null and b/public/images/emoji/google/flag_jp.png differ diff --git a/public/images/emoji/google/flag_kr.png b/public/images/emoji/google/flag_kr.png new file mode 100644 index 00000000000..12b9ab12574 Binary files /dev/null and b/public/images/emoji/google/flag_kr.png differ diff --git a/public/images/emoji/google/flag_ru.png b/public/images/emoji/google/flag_ru.png new file mode 100644 index 00000000000..5121b0cac4b Binary files /dev/null and b/public/images/emoji/google/flag_ru.png differ diff --git a/public/images/emoji/google/flag_us.png b/public/images/emoji/google/flag_us.png new file mode 100644 index 00000000000..9ad26a6680b Binary files /dev/null and b/public/images/emoji/google/flag_us.png differ diff --git a/public/images/emoji/google/flag_white.png b/public/images/emoji/google/flag_white.png new file mode 100644 index 00000000000..4afc58a157e Binary files /dev/null and b/public/images/emoji/google/flag_white.png differ diff --git a/public/images/emoji/google/flags.png b/public/images/emoji/google/flags.png index c831fdacf66..5da0812896c 100644 Binary files a/public/images/emoji/google/flags.png and b/public/images/emoji/google/flags.png differ diff --git a/public/images/emoji/google/flashlight.png b/public/images/emoji/google/flashlight.png index d6ca0cd5117..b2bb6d0340f 100644 Binary files a/public/images/emoji/google/flashlight.png and b/public/images/emoji/google/flashlight.png differ diff --git a/public/images/emoji/google/fleur-de-lis.png b/public/images/emoji/google/fleur-de-lis.png new file mode 100644 index 00000000000..726a9dbfc63 Binary files /dev/null and b/public/images/emoji/google/fleur-de-lis.png differ diff --git a/public/images/emoji/google/flipper.png b/public/images/emoji/google/flipper.png index 61bf80ae9a9..ce56603cf1f 100644 Binary files a/public/images/emoji/google/flipper.png and b/public/images/emoji/google/flipper.png differ diff --git a/public/images/emoji/google/floppy_disk.png b/public/images/emoji/google/floppy_disk.png index 070b7ce14f4..ec5b90961fd 100644 Binary files a/public/images/emoji/google/floppy_disk.png and b/public/images/emoji/google/floppy_disk.png differ diff --git a/public/images/emoji/google/flower_playing_cards.png b/public/images/emoji/google/flower_playing_cards.png index cbe1cd412b9..803eb64d57a 100644 Binary files a/public/images/emoji/google/flower_playing_cards.png and b/public/images/emoji/google/flower_playing_cards.png differ diff --git a/public/images/emoji/google/flushed.png b/public/images/emoji/google/flushed.png index e1f63b828c1..2d71b31ddf4 100644 Binary files a/public/images/emoji/google/flushed.png and b/public/images/emoji/google/flushed.png differ diff --git a/public/images/emoji/google/fog.png b/public/images/emoji/google/fog.png new file mode 100644 index 00000000000..99c75ed752c Binary files /dev/null and b/public/images/emoji/google/fog.png differ diff --git a/public/images/emoji/google/foggy.png b/public/images/emoji/google/foggy.png index 14ccca19cab..6ba401449db 100644 Binary files a/public/images/emoji/google/foggy.png and b/public/images/emoji/google/foggy.png differ diff --git a/public/images/emoji/google/football.png b/public/images/emoji/google/football.png index 590cf19c912..dc6a6265651 100644 Binary files a/public/images/emoji/google/football.png and b/public/images/emoji/google/football.png differ diff --git a/public/images/emoji/google/footprints.png b/public/images/emoji/google/footprints.png index 9d8a4fb2f3e..f64a2c195f3 100644 Binary files a/public/images/emoji/google/footprints.png and b/public/images/emoji/google/footprints.png differ diff --git a/public/images/emoji/google/fork_and_knife.png b/public/images/emoji/google/fork_and_knife.png index c80d53a6b91..d155de6051c 100644 Binary files a/public/images/emoji/google/fork_and_knife.png and b/public/images/emoji/google/fork_and_knife.png differ diff --git a/public/images/emoji/google/fork_knife_plate.png b/public/images/emoji/google/fork_knife_plate.png new file mode 100644 index 00000000000..7522473180d Binary files /dev/null and b/public/images/emoji/google/fork_knife_plate.png differ diff --git a/public/images/emoji/google/fountain.png b/public/images/emoji/google/fountain.png index a88e6cc9c07..cbfed287abe 100644 Binary files a/public/images/emoji/google/fountain.png and b/public/images/emoji/google/fountain.png differ diff --git a/public/images/emoji/google/four.png b/public/images/emoji/google/four.png index 81367f1b71e..ee489fc2d1c 100644 Binary files a/public/images/emoji/google/four.png and b/public/images/emoji/google/four.png differ diff --git a/public/images/emoji/google/four_leaf_clover.png b/public/images/emoji/google/four_leaf_clover.png index 82b3eaeb0a1..ef78f0f3039 100644 Binary files a/public/images/emoji/google/four_leaf_clover.png and b/public/images/emoji/google/four_leaf_clover.png differ diff --git a/public/images/emoji/google/fr.png b/public/images/emoji/google/fr.png index 0d83f0573bf..ccdfe444835 100644 Binary files a/public/images/emoji/google/fr.png and b/public/images/emoji/google/fr.png differ diff --git a/public/images/emoji/google/frame_photo.png b/public/images/emoji/google/frame_photo.png new file mode 100644 index 00000000000..24724359015 Binary files /dev/null and b/public/images/emoji/google/frame_photo.png differ diff --git a/public/images/emoji/google/free.png b/public/images/emoji/google/free.png index 7bc78dda169..a18e75c65a5 100644 Binary files a/public/images/emoji/google/free.png and b/public/images/emoji/google/free.png differ diff --git a/public/images/emoji/google/fried_shrimp.png b/public/images/emoji/google/fried_shrimp.png index 85a685c497e..ea4a2424b4e 100644 Binary files a/public/images/emoji/google/fried_shrimp.png and b/public/images/emoji/google/fried_shrimp.png differ diff --git a/public/images/emoji/google/fries.png b/public/images/emoji/google/fries.png index 991c4a5cee8..e91910d6536 100644 Binary files a/public/images/emoji/google/fries.png and b/public/images/emoji/google/fries.png differ diff --git a/public/images/emoji/google/frog.png b/public/images/emoji/google/frog.png index 89337e9c9ae..fdf48f45297 100644 Binary files a/public/images/emoji/google/frog.png and b/public/images/emoji/google/frog.png differ diff --git a/public/images/emoji/google/frowning.png b/public/images/emoji/google/frowning.png index 1252be42421..063a5287234 100644 Binary files a/public/images/emoji/google/frowning.png and b/public/images/emoji/google/frowning.png differ diff --git a/public/images/emoji/google/frowning2.png b/public/images/emoji/google/frowning2.png new file mode 100644 index 00000000000..60077a561c1 Binary files /dev/null and b/public/images/emoji/google/frowning2.png differ diff --git a/public/images/emoji/google/fuelpump.png b/public/images/emoji/google/fuelpump.png index f31b6c4b9f2..86bcb3e97c4 100644 Binary files a/public/images/emoji/google/fuelpump.png and b/public/images/emoji/google/fuelpump.png differ diff --git a/public/images/emoji/google/full_moon.png b/public/images/emoji/google/full_moon.png index 51514a42a52..72778cce2d1 100644 Binary files a/public/images/emoji/google/full_moon.png and b/public/images/emoji/google/full_moon.png differ diff --git a/public/images/emoji/google/full_moon_with_face.png b/public/images/emoji/google/full_moon_with_face.png index 620ee9d7146..0a723ef0c48 100644 Binary files a/public/images/emoji/google/full_moon_with_face.png and b/public/images/emoji/google/full_moon_with_face.png differ diff --git a/public/images/emoji/google/game_die.png b/public/images/emoji/google/game_die.png index cc23ef9e6f8..5fb4140aea9 100644 Binary files a/public/images/emoji/google/game_die.png and b/public/images/emoji/google/game_die.png differ diff --git a/public/images/emoji/google/gb.png b/public/images/emoji/google/gb.png index a0f834b4c6c..2d95d264e41 100644 Binary files a/public/images/emoji/google/gb.png and b/public/images/emoji/google/gb.png differ diff --git a/public/images/emoji/google/gear.png b/public/images/emoji/google/gear.png new file mode 100644 index 00000000000..79dd801a128 Binary files /dev/null and b/public/images/emoji/google/gear.png differ diff --git a/public/images/emoji/google/gem.png b/public/images/emoji/google/gem.png index ba0944f9fd9..08a50ae8eaa 100644 Binary files a/public/images/emoji/google/gem.png and b/public/images/emoji/google/gem.png differ diff --git a/public/images/emoji/google/gemini.png b/public/images/emoji/google/gemini.png index f6189014c9d..08c0d1b73a5 100644 Binary files a/public/images/emoji/google/gemini.png and b/public/images/emoji/google/gemini.png differ diff --git a/public/images/emoji/google/ghost.png b/public/images/emoji/google/ghost.png index 02f53de91dd..ec8795bdd99 100644 Binary files a/public/images/emoji/google/ghost.png and b/public/images/emoji/google/ghost.png differ diff --git a/public/images/emoji/google/gift.png b/public/images/emoji/google/gift.png index c2b77b8f0f8..bd21768b033 100644 Binary files a/public/images/emoji/google/gift.png and b/public/images/emoji/google/gift.png differ diff --git a/public/images/emoji/google/gift_heart.png b/public/images/emoji/google/gift_heart.png index ab79751077e..c95882d87c1 100644 Binary files a/public/images/emoji/google/gift_heart.png and b/public/images/emoji/google/gift_heart.png differ diff --git a/public/images/emoji/google/girl.png b/public/images/emoji/google/girl.png index 425e9682e60..657c5d3e6ba 100644 Binary files a/public/images/emoji/google/girl.png and b/public/images/emoji/google/girl.png differ diff --git a/public/images/emoji/google/globe_with_meridians.png b/public/images/emoji/google/globe_with_meridians.png index c622f98b6bd..e62c3b5414b 100644 Binary files a/public/images/emoji/google/globe_with_meridians.png and b/public/images/emoji/google/globe_with_meridians.png differ diff --git a/public/images/emoji/google/goat.png b/public/images/emoji/google/goat.png index 9f9ba8f57a0..0802de0dbf3 100644 Binary files a/public/images/emoji/google/goat.png and b/public/images/emoji/google/goat.png differ diff --git a/public/images/emoji/google/golf.png b/public/images/emoji/google/golf.png index 1c4eef3cdf3..73c0d85af47 100644 Binary files a/public/images/emoji/google/golf.png and b/public/images/emoji/google/golf.png differ diff --git a/public/images/emoji/google/golfer.png b/public/images/emoji/google/golfer.png new file mode 100644 index 00000000000..2aff3e9dc42 Binary files /dev/null and b/public/images/emoji/google/golfer.png differ diff --git a/public/images/emoji/google/grapes.png b/public/images/emoji/google/grapes.png index 1ef015cc324..e59791a898d 100644 Binary files a/public/images/emoji/google/grapes.png and b/public/images/emoji/google/grapes.png differ diff --git a/public/images/emoji/google/green_apple.png b/public/images/emoji/google/green_apple.png index 783790de73a..72fd0753517 100644 Binary files a/public/images/emoji/google/green_apple.png and b/public/images/emoji/google/green_apple.png differ diff --git a/public/images/emoji/google/green_book.png b/public/images/emoji/google/green_book.png index 92406449e44..9f4fbe48992 100644 Binary files a/public/images/emoji/google/green_book.png and b/public/images/emoji/google/green_book.png differ diff --git a/public/images/emoji/google/green_heart.png b/public/images/emoji/google/green_heart.png index 4256f5ef8d4..2f4796895ea 100644 Binary files a/public/images/emoji/google/green_heart.png and b/public/images/emoji/google/green_heart.png differ diff --git a/public/images/emoji/google/grey_exclamation.png b/public/images/emoji/google/grey_exclamation.png index 566da09c3bb..ec8a804ac83 100644 Binary files a/public/images/emoji/google/grey_exclamation.png and b/public/images/emoji/google/grey_exclamation.png differ diff --git a/public/images/emoji/google/grey_question.png b/public/images/emoji/google/grey_question.png index 57f55dcd7a6..77639461f42 100644 Binary files a/public/images/emoji/google/grey_question.png and b/public/images/emoji/google/grey_question.png differ diff --git a/public/images/emoji/google/grimacing.png b/public/images/emoji/google/grimacing.png index a7d5a96f0c7..42739cb5f1e 100644 Binary files a/public/images/emoji/google/grimacing.png and b/public/images/emoji/google/grimacing.png differ diff --git a/public/images/emoji/google/grin.png b/public/images/emoji/google/grin.png index 60dee4453fc..dc9e2f2e826 100644 Binary files a/public/images/emoji/google/grin.png and b/public/images/emoji/google/grin.png differ diff --git a/public/images/emoji/google/grinning.png b/public/images/emoji/google/grinning.png index 879c3f26810..e54bb4a9795 100644 Binary files a/public/images/emoji/google/grinning.png and b/public/images/emoji/google/grinning.png differ diff --git a/public/images/emoji/google/guardsman.png b/public/images/emoji/google/guardsman.png index ad57db05766..a70b2e9d30a 100644 Binary files a/public/images/emoji/google/guardsman.png and b/public/images/emoji/google/guardsman.png differ diff --git a/public/images/emoji/google/guitar.png b/public/images/emoji/google/guitar.png index e5dead90ebd..967fe01398a 100644 Binary files a/public/images/emoji/google/guitar.png and b/public/images/emoji/google/guitar.png differ diff --git a/public/images/emoji/google/gun.png b/public/images/emoji/google/gun.png index 144a52e4ad8..07ec0583edc 100644 Binary files a/public/images/emoji/google/gun.png and b/public/images/emoji/google/gun.png differ diff --git a/public/images/emoji/google/haircut.png b/public/images/emoji/google/haircut.png index af0580979e1..0dc029f37f7 100644 Binary files a/public/images/emoji/google/haircut.png and b/public/images/emoji/google/haircut.png differ diff --git a/public/images/emoji/google/hamburger.png b/public/images/emoji/google/hamburger.png index 8408b75feda..06f26d5552a 100644 Binary files a/public/images/emoji/google/hamburger.png and b/public/images/emoji/google/hamburger.png differ diff --git a/public/images/emoji/google/hammer.png b/public/images/emoji/google/hammer.png index 4183b106751..ecd23351ac5 100644 Binary files a/public/images/emoji/google/hammer.png and b/public/images/emoji/google/hammer.png differ diff --git a/public/images/emoji/google/hammer_pick.png b/public/images/emoji/google/hammer_pick.png new file mode 100644 index 00000000000..58690f4623f Binary files /dev/null and b/public/images/emoji/google/hammer_pick.png differ diff --git a/public/images/emoji/google/hamster.png b/public/images/emoji/google/hamster.png index 328891dbbfb..ac0d08a39fa 100644 Binary files a/public/images/emoji/google/hamster.png and b/public/images/emoji/google/hamster.png differ diff --git a/public/images/emoji/google/hand.png b/public/images/emoji/google/hand.png index 312415894ce..ed4c684b312 100644 Binary files a/public/images/emoji/google/hand.png and b/public/images/emoji/google/hand.png differ diff --git a/public/images/emoji/google/hand_splayed.png b/public/images/emoji/google/hand_splayed.png new file mode 100644 index 00000000000..140e5edf6c3 Binary files /dev/null and b/public/images/emoji/google/hand_splayed.png differ diff --git a/public/images/emoji/google/handbag.png b/public/images/emoji/google/handbag.png index da8faaa8a70..a4c147c5d37 100644 Binary files a/public/images/emoji/google/handbag.png and b/public/images/emoji/google/handbag.png differ diff --git a/public/images/emoji/google/hankey.png b/public/images/emoji/google/hankey.png index aa2424539c1..3912c82cce4 100644 Binary files a/public/images/emoji/google/hankey.png and b/public/images/emoji/google/hankey.png differ diff --git a/public/images/emoji/google/hatched_chick.png b/public/images/emoji/google/hatched_chick.png index f5c6d1c3ba2..1ae0ade06f5 100644 Binary files a/public/images/emoji/google/hatched_chick.png and b/public/images/emoji/google/hatched_chick.png differ diff --git a/public/images/emoji/google/hatching_chick.png b/public/images/emoji/google/hatching_chick.png index 42019c35973..2b7e628fd7a 100644 Binary files a/public/images/emoji/google/hatching_chick.png and b/public/images/emoji/google/hatching_chick.png differ diff --git a/public/images/emoji/google/head_bandage.png b/public/images/emoji/google/head_bandage.png new file mode 100644 index 00000000000..bb6358bd844 Binary files /dev/null and b/public/images/emoji/google/head_bandage.png differ diff --git a/public/images/emoji/google/headphones.png b/public/images/emoji/google/headphones.png index d90a4ffb74b..1a9a10122e8 100644 Binary files a/public/images/emoji/google/headphones.png and b/public/images/emoji/google/headphones.png differ diff --git a/public/images/emoji/google/hear_no_evil.png b/public/images/emoji/google/hear_no_evil.png index abd6edd7e30..8d96c71f2c2 100644 Binary files a/public/images/emoji/google/hear_no_evil.png and b/public/images/emoji/google/hear_no_evil.png differ diff --git a/public/images/emoji/google/heart.png b/public/images/emoji/google/heart.png index 5318c5c9fde..3550fd2472e 100644 Binary files a/public/images/emoji/google/heart.png and b/public/images/emoji/google/heart.png differ diff --git a/public/images/emoji/google/heart_decoration.png b/public/images/emoji/google/heart_decoration.png index a728f60e144..65462f838c0 100644 Binary files a/public/images/emoji/google/heart_decoration.png and b/public/images/emoji/google/heart_decoration.png differ diff --git a/public/images/emoji/google/heart_exclamation.png b/public/images/emoji/google/heart_exclamation.png new file mode 100644 index 00000000000..4bcc0432689 Binary files /dev/null and b/public/images/emoji/google/heart_exclamation.png differ diff --git a/public/images/emoji/google/heart_eyes.png b/public/images/emoji/google/heart_eyes.png index 734f5599fd2..51aa37289f8 100644 Binary files a/public/images/emoji/google/heart_eyes.png and b/public/images/emoji/google/heart_eyes.png differ diff --git a/public/images/emoji/google/heart_eyes_cat.png b/public/images/emoji/google/heart_eyes_cat.png index 2c5a92b47c4..4ab4cea800d 100644 Binary files a/public/images/emoji/google/heart_eyes_cat.png and b/public/images/emoji/google/heart_eyes_cat.png differ diff --git a/public/images/emoji/google/heartbeat.png b/public/images/emoji/google/heartbeat.png index 2c5acc6c499..bd7a37fa894 100644 Binary files a/public/images/emoji/google/heartbeat.png and b/public/images/emoji/google/heartbeat.png differ diff --git a/public/images/emoji/google/heartpulse.png b/public/images/emoji/google/heartpulse.png index d2e706153c6..936e3a4eaed 100644 Binary files a/public/images/emoji/google/heartpulse.png and b/public/images/emoji/google/heartpulse.png differ diff --git a/public/images/emoji/google/hearts.png b/public/images/emoji/google/hearts.png index 1383393cc5d..74b13fd89fd 100644 Binary files a/public/images/emoji/google/hearts.png and b/public/images/emoji/google/hearts.png differ diff --git a/public/images/emoji/google/heavy_check_mark.png b/public/images/emoji/google/heavy_check_mark.png index 45e1749c3c1..6c4e0997a2e 100644 Binary files a/public/images/emoji/google/heavy_check_mark.png and b/public/images/emoji/google/heavy_check_mark.png differ diff --git a/public/images/emoji/google/heavy_division_sign.png b/public/images/emoji/google/heavy_division_sign.png index b4868970f62..68bcaf32b04 100644 Binary files a/public/images/emoji/google/heavy_division_sign.png and b/public/images/emoji/google/heavy_division_sign.png differ diff --git a/public/images/emoji/google/heavy_dollar_sign.png b/public/images/emoji/google/heavy_dollar_sign.png index 0ef1cccd55e..7b112aaf083 100644 Binary files a/public/images/emoji/google/heavy_dollar_sign.png and b/public/images/emoji/google/heavy_dollar_sign.png differ diff --git a/public/images/emoji/google/heavy_exclamation_mark.png b/public/images/emoji/google/heavy_exclamation_mark.png index db65e8d05c8..e90e7435aa4 100644 Binary files a/public/images/emoji/google/heavy_exclamation_mark.png and b/public/images/emoji/google/heavy_exclamation_mark.png differ diff --git a/public/images/emoji/google/heavy_minus_sign.png b/public/images/emoji/google/heavy_minus_sign.png index 4a1236772a9..1b2f6483a01 100644 Binary files a/public/images/emoji/google/heavy_minus_sign.png and b/public/images/emoji/google/heavy_minus_sign.png differ diff --git a/public/images/emoji/google/heavy_multiplication_x.png b/public/images/emoji/google/heavy_multiplication_x.png index 95bdaec6cf5..a80ebeecdc2 100644 Binary files a/public/images/emoji/google/heavy_multiplication_x.png and b/public/images/emoji/google/heavy_multiplication_x.png differ diff --git a/public/images/emoji/google/heavy_plus_sign.png b/public/images/emoji/google/heavy_plus_sign.png index 930b0fffb38..69ad22b6bfc 100644 Binary files a/public/images/emoji/google/heavy_plus_sign.png and b/public/images/emoji/google/heavy_plus_sign.png differ diff --git a/public/images/emoji/google/helicopter.png b/public/images/emoji/google/helicopter.png index 3981eaa43d8..3019369a361 100644 Binary files a/public/images/emoji/google/helicopter.png and b/public/images/emoji/google/helicopter.png differ diff --git a/public/images/emoji/google/helmet_with_cross.png b/public/images/emoji/google/helmet_with_cross.png new file mode 100644 index 00000000000..7b60b84c7d4 Binary files /dev/null and b/public/images/emoji/google/helmet_with_cross.png differ diff --git a/public/images/emoji/google/herb.png b/public/images/emoji/google/herb.png index 84e09672e9d..2583dd74d9d 100644 Binary files a/public/images/emoji/google/herb.png and b/public/images/emoji/google/herb.png differ diff --git a/public/images/emoji/google/hibiscus.png b/public/images/emoji/google/hibiscus.png index eed24d38d78..d9190803a66 100644 Binary files a/public/images/emoji/google/hibiscus.png and b/public/images/emoji/google/hibiscus.png differ diff --git a/public/images/emoji/google/high_brightness.png b/public/images/emoji/google/high_brightness.png index 17fc27997fc..f277c5543b9 100644 Binary files a/public/images/emoji/google/high_brightness.png and b/public/images/emoji/google/high_brightness.png differ diff --git a/public/images/emoji/google/high_heel.png b/public/images/emoji/google/high_heel.png index c790678c5b0..7115e66fde3 100644 Binary files a/public/images/emoji/google/high_heel.png and b/public/images/emoji/google/high_heel.png differ diff --git a/public/images/emoji/google/hocho.png b/public/images/emoji/google/hocho.png index a683b759223..90849d0c21a 100644 Binary files a/public/images/emoji/google/hocho.png and b/public/images/emoji/google/hocho.png differ diff --git a/public/images/emoji/google/hockey.png b/public/images/emoji/google/hockey.png new file mode 100644 index 00000000000..a224a9d862c Binary files /dev/null and b/public/images/emoji/google/hockey.png differ diff --git a/public/images/emoji/google/hole.png b/public/images/emoji/google/hole.png new file mode 100644 index 00000000000..a74093e97c5 Binary files /dev/null and b/public/images/emoji/google/hole.png differ diff --git a/public/images/emoji/google/homes.png b/public/images/emoji/google/homes.png new file mode 100644 index 00000000000..330612a2307 Binary files /dev/null and b/public/images/emoji/google/homes.png differ diff --git a/public/images/emoji/google/honey_pot.png b/public/images/emoji/google/honey_pot.png index eb2403cf576..fda115044f0 100644 Binary files a/public/images/emoji/google/honey_pot.png and b/public/images/emoji/google/honey_pot.png differ diff --git a/public/images/emoji/google/honeybee.png b/public/images/emoji/google/honeybee.png index 20a86eb54b7..2a231acea04 100644 Binary files a/public/images/emoji/google/honeybee.png and b/public/images/emoji/google/honeybee.png differ diff --git a/public/images/emoji/google/horse.png b/public/images/emoji/google/horse.png index edc3358716f..b0b22de6425 100644 Binary files a/public/images/emoji/google/horse.png and b/public/images/emoji/google/horse.png differ diff --git a/public/images/emoji/google/horse_racing.png b/public/images/emoji/google/horse_racing.png index c9272e3a58d..78ec2d3bdd3 100644 Binary files a/public/images/emoji/google/horse_racing.png and b/public/images/emoji/google/horse_racing.png differ diff --git a/public/images/emoji/google/hospital.png b/public/images/emoji/google/hospital.png index 110abed0098..2f897973116 100644 Binary files a/public/images/emoji/google/hospital.png and b/public/images/emoji/google/hospital.png differ diff --git a/public/images/emoji/google/hot_pepper.png b/public/images/emoji/google/hot_pepper.png new file mode 100644 index 00000000000..4b96b89987a Binary files /dev/null and b/public/images/emoji/google/hot_pepper.png differ diff --git a/public/images/emoji/google/hotdog.png b/public/images/emoji/google/hotdog.png new file mode 100644 index 00000000000..9b656e4e6e4 Binary files /dev/null and b/public/images/emoji/google/hotdog.png differ diff --git a/public/images/emoji/google/hotel.png b/public/images/emoji/google/hotel.png index 9c75d63d1fc..14eede3a28d 100644 Binary files a/public/images/emoji/google/hotel.png and b/public/images/emoji/google/hotel.png differ diff --git a/public/images/emoji/google/hotsprings.png b/public/images/emoji/google/hotsprings.png index 5a5cc1fb6c1..23d75c922f7 100644 Binary files a/public/images/emoji/google/hotsprings.png and b/public/images/emoji/google/hotsprings.png differ diff --git a/public/images/emoji/google/hourglass.png b/public/images/emoji/google/hourglass.png index da4733970bb..39c29d4917a 100644 Binary files a/public/images/emoji/google/hourglass.png and b/public/images/emoji/google/hourglass.png differ diff --git a/public/images/emoji/google/hourglass_flowing_sand.png b/public/images/emoji/google/hourglass_flowing_sand.png index 7f8671a0f42..9f5e7e50578 100644 Binary files a/public/images/emoji/google/hourglass_flowing_sand.png and b/public/images/emoji/google/hourglass_flowing_sand.png differ diff --git a/public/images/emoji/google/house.png b/public/images/emoji/google/house.png index bde5870fa7e..a6f3144f1cb 100644 Binary files a/public/images/emoji/google/house.png and b/public/images/emoji/google/house.png differ diff --git a/public/images/emoji/google/house_abandoned.png b/public/images/emoji/google/house_abandoned.png new file mode 100644 index 00000000000..65339656f67 Binary files /dev/null and b/public/images/emoji/google/house_abandoned.png differ diff --git a/public/images/emoji/google/house_with_garden.png b/public/images/emoji/google/house_with_garden.png index d6733cb4b1f..adadb47396e 100644 Binary files a/public/images/emoji/google/house_with_garden.png and b/public/images/emoji/google/house_with_garden.png differ diff --git a/public/images/emoji/google/hugging.png b/public/images/emoji/google/hugging.png new file mode 100644 index 00000000000..f96f020cb19 Binary files /dev/null and b/public/images/emoji/google/hugging.png differ diff --git a/public/images/emoji/google/hushed.png b/public/images/emoji/google/hushed.png index 53d02a0de51..86fdf9fbdc8 100644 Binary files a/public/images/emoji/google/hushed.png and b/public/images/emoji/google/hushed.png differ diff --git a/public/images/emoji/google/ice_cream.png b/public/images/emoji/google/ice_cream.png index a52197c796f..df83a39d556 100644 Binary files a/public/images/emoji/google/ice_cream.png and b/public/images/emoji/google/ice_cream.png differ diff --git a/public/images/emoji/google/ice_skate.png b/public/images/emoji/google/ice_skate.png new file mode 100644 index 00000000000..9c4c849ca90 Binary files /dev/null and b/public/images/emoji/google/ice_skate.png differ diff --git a/public/images/emoji/google/icecream.png b/public/images/emoji/google/icecream.png index e995d400a77..2cd79344e2e 100644 Binary files a/public/images/emoji/google/icecream.png and b/public/images/emoji/google/icecream.png differ diff --git a/public/images/emoji/google/id.png b/public/images/emoji/google/id.png index 8d527b4f8e4..026d3324d0d 100644 Binary files a/public/images/emoji/google/id.png and b/public/images/emoji/google/id.png differ diff --git a/public/images/emoji/google/ideograph_advantage.png b/public/images/emoji/google/ideograph_advantage.png index 4e6694a62f2..229142ea217 100644 Binary files a/public/images/emoji/google/ideograph_advantage.png and b/public/images/emoji/google/ideograph_advantage.png differ diff --git a/public/images/emoji/google/imp.png b/public/images/emoji/google/imp.png index 0530c4bad40..4b697d3dfa6 100644 Binary files a/public/images/emoji/google/imp.png and b/public/images/emoji/google/imp.png differ diff --git a/public/images/emoji/google/inbox_tray.png b/public/images/emoji/google/inbox_tray.png index c95f8e342ee..bebd898876c 100644 Binary files a/public/images/emoji/google/inbox_tray.png and b/public/images/emoji/google/inbox_tray.png differ diff --git a/public/images/emoji/google/incoming_envelope.png b/public/images/emoji/google/incoming_envelope.png index 4a13d297942..19e8ba0fffe 100644 Binary files a/public/images/emoji/google/incoming_envelope.png and b/public/images/emoji/google/incoming_envelope.png differ diff --git a/public/images/emoji/google/information_desk_person.png b/public/images/emoji/google/information_desk_person.png index 85605a45edb..8a4c6670b54 100644 Binary files a/public/images/emoji/google/information_desk_person.png and b/public/images/emoji/google/information_desk_person.png differ diff --git a/public/images/emoji/google/information_source.png b/public/images/emoji/google/information_source.png index 85377331d54..ee134fdf19c 100644 Binary files a/public/images/emoji/google/information_source.png and b/public/images/emoji/google/information_source.png differ diff --git a/public/images/emoji/google/innocent.png b/public/images/emoji/google/innocent.png index 7e33f010ed2..77e7a0196d1 100644 Binary files a/public/images/emoji/google/innocent.png and b/public/images/emoji/google/innocent.png differ diff --git a/public/images/emoji/google/interrobang.png b/public/images/emoji/google/interrobang.png index 8fe3253a73e..b714e671cad 100644 Binary files a/public/images/emoji/google/interrobang.png and b/public/images/emoji/google/interrobang.png differ diff --git a/public/images/emoji/google/iphone.png b/public/images/emoji/google/iphone.png index 815c4ba49a0..437398edb1d 100644 Binary files a/public/images/emoji/google/iphone.png and b/public/images/emoji/google/iphone.png differ diff --git a/public/images/emoji/google/island.png b/public/images/emoji/google/island.png new file mode 100644 index 00000000000..eb33977cf62 Binary files /dev/null and b/public/images/emoji/google/island.png differ diff --git a/public/images/emoji/google/it.png b/public/images/emoji/google/it.png index 6aa2808e735..7520581a80b 100644 Binary files a/public/images/emoji/google/it.png and b/public/images/emoji/google/it.png differ diff --git a/public/images/emoji/google/izakaya_lantern.png b/public/images/emoji/google/izakaya_lantern.png index 372e5a7ff1e..7bd1c654e27 100644 Binary files a/public/images/emoji/google/izakaya_lantern.png and b/public/images/emoji/google/izakaya_lantern.png differ diff --git a/public/images/emoji/google/jack_o_lantern.png b/public/images/emoji/google/jack_o_lantern.png index b7da90c5471..914378740ec 100644 Binary files a/public/images/emoji/google/jack_o_lantern.png and b/public/images/emoji/google/jack_o_lantern.png differ diff --git a/public/images/emoji/google/japan.png b/public/images/emoji/google/japan.png index 2e6274ac269..76230c5632f 100644 Binary files a/public/images/emoji/google/japan.png and b/public/images/emoji/google/japan.png differ diff --git a/public/images/emoji/google/japanese_castle.png b/public/images/emoji/google/japanese_castle.png index 542d54cc4d0..1e102b965ac 100644 Binary files a/public/images/emoji/google/japanese_castle.png and b/public/images/emoji/google/japanese_castle.png differ diff --git a/public/images/emoji/google/japanese_goblin.png b/public/images/emoji/google/japanese_goblin.png index c2294edd21e..bebc1050c1a 100644 Binary files a/public/images/emoji/google/japanese_goblin.png and b/public/images/emoji/google/japanese_goblin.png differ diff --git a/public/images/emoji/google/japanese_ogre.png b/public/images/emoji/google/japanese_ogre.png index 2738475fe85..367e69d5ce3 100644 Binary files a/public/images/emoji/google/japanese_ogre.png and b/public/images/emoji/google/japanese_ogre.png differ diff --git a/public/images/emoji/google/jeans.png b/public/images/emoji/google/jeans.png index cd1e59b8580..49eaf8ce774 100644 Binary files a/public/images/emoji/google/jeans.png and b/public/images/emoji/google/jeans.png differ diff --git a/public/images/emoji/google/joy.png b/public/images/emoji/google/joy.png index d20afd7c83c..7f74024ca71 100644 Binary files a/public/images/emoji/google/joy.png and b/public/images/emoji/google/joy.png differ diff --git a/public/images/emoji/google/joy_cat.png b/public/images/emoji/google/joy_cat.png index 8aaeb6375c7..faad80daadc 100644 Binary files a/public/images/emoji/google/joy_cat.png and b/public/images/emoji/google/joy_cat.png differ diff --git a/public/images/emoji/google/joystick.png b/public/images/emoji/google/joystick.png new file mode 100644 index 00000000000..a2891008d05 Binary files /dev/null and b/public/images/emoji/google/joystick.png differ diff --git a/public/images/emoji/google/jp.png b/public/images/emoji/google/jp.png index 197cac2f6e7..3fcaf876537 100644 Binary files a/public/images/emoji/google/jp.png and b/public/images/emoji/google/jp.png differ diff --git a/public/images/emoji/google/kaaba.png b/public/images/emoji/google/kaaba.png new file mode 100644 index 00000000000..ea2a60b17b5 Binary files /dev/null and b/public/images/emoji/google/kaaba.png differ diff --git a/public/images/emoji/google/key.png b/public/images/emoji/google/key.png index 8bf0af58ed2..08e53f8f343 100644 Binary files a/public/images/emoji/google/key.png and b/public/images/emoji/google/key.png differ diff --git a/public/images/emoji/google/key2.png b/public/images/emoji/google/key2.png new file mode 100644 index 00000000000..37bbcbb7cb6 Binary files /dev/null and b/public/images/emoji/google/key2.png differ diff --git a/public/images/emoji/google/keyboard.png b/public/images/emoji/google/keyboard.png new file mode 100644 index 00000000000..5c7ad214457 Binary files /dev/null and b/public/images/emoji/google/keyboard.png differ diff --git a/public/images/emoji/google/keycap_ten.png b/public/images/emoji/google/keycap_ten.png index 641d9c310a1..0af25100221 100644 Binary files a/public/images/emoji/google/keycap_ten.png and b/public/images/emoji/google/keycap_ten.png differ diff --git a/public/images/emoji/google/kimono.png b/public/images/emoji/google/kimono.png index 910314266fc..9cbc8d3fa17 100644 Binary files a/public/images/emoji/google/kimono.png and b/public/images/emoji/google/kimono.png differ diff --git a/public/images/emoji/google/kiss.png b/public/images/emoji/google/kiss.png index 8339ecedfb1..97acd745026 100644 Binary files a/public/images/emoji/google/kiss.png and b/public/images/emoji/google/kiss.png differ diff --git a/public/images/emoji/google/kissing.png b/public/images/emoji/google/kissing.png index 7abe2640039..daa2507b3e1 100644 Binary files a/public/images/emoji/google/kissing.png and b/public/images/emoji/google/kissing.png differ diff --git a/public/images/emoji/google/kissing_cat.png b/public/images/emoji/google/kissing_cat.png index 8a5daa67651..cd38fd8089f 100644 Binary files a/public/images/emoji/google/kissing_cat.png and b/public/images/emoji/google/kissing_cat.png differ diff --git a/public/images/emoji/google/kissing_closed_eyes.png b/public/images/emoji/google/kissing_closed_eyes.png index 75bf81fa49c..3c59419d397 100644 Binary files a/public/images/emoji/google/kissing_closed_eyes.png and b/public/images/emoji/google/kissing_closed_eyes.png differ diff --git a/public/images/emoji/google/kissing_heart.png b/public/images/emoji/google/kissing_heart.png index 0fe423407b3..b7658004a9a 100644 Binary files a/public/images/emoji/google/kissing_heart.png and b/public/images/emoji/google/kissing_heart.png differ diff --git a/public/images/emoji/google/kissing_smiling_eyes.png b/public/images/emoji/google/kissing_smiling_eyes.png index d7f6437fe59..912f049e67c 100644 Binary files a/public/images/emoji/google/kissing_smiling_eyes.png and b/public/images/emoji/google/kissing_smiling_eyes.png differ diff --git a/public/images/emoji/google/knife.png b/public/images/emoji/google/knife.png index 34460cab6f3..487e32d53e2 100644 Binary files a/public/images/emoji/google/knife.png and b/public/images/emoji/google/knife.png differ diff --git a/public/images/emoji/google/koala.png b/public/images/emoji/google/koala.png index a939772dd1f..c7c56061200 100644 Binary files a/public/images/emoji/google/koala.png and b/public/images/emoji/google/koala.png differ diff --git a/public/images/emoji/google/koko.png b/public/images/emoji/google/koko.png index 9b230b456bc..e7bcc19e956 100644 Binary files a/public/images/emoji/google/koko.png and b/public/images/emoji/google/koko.png differ diff --git a/public/images/emoji/google/kr.png b/public/images/emoji/google/kr.png index 78ea7279ad8..d295bbea958 100644 Binary files a/public/images/emoji/google/kr.png and b/public/images/emoji/google/kr.png differ diff --git a/public/images/emoji/google/label.png b/public/images/emoji/google/label.png new file mode 100644 index 00000000000..61c4f8021dc Binary files /dev/null and b/public/images/emoji/google/label.png differ diff --git a/public/images/emoji/google/lantern.png b/public/images/emoji/google/lantern.png index 0756e34d4f6..a029a5f3e6b 100644 Binary files a/public/images/emoji/google/lantern.png and b/public/images/emoji/google/lantern.png differ diff --git a/public/images/emoji/google/large_blue_circle.png b/public/images/emoji/google/large_blue_circle.png index 95f57715a0e..76a607af79c 100644 Binary files a/public/images/emoji/google/large_blue_circle.png and b/public/images/emoji/google/large_blue_circle.png differ diff --git a/public/images/emoji/google/large_blue_diamond.png b/public/images/emoji/google/large_blue_diamond.png index ceba5508044..cc140296739 100644 Binary files a/public/images/emoji/google/large_blue_diamond.png and b/public/images/emoji/google/large_blue_diamond.png differ diff --git a/public/images/emoji/google/large_orange_diamond.png b/public/images/emoji/google/large_orange_diamond.png index 49205b2f829..c54db095b40 100644 Binary files a/public/images/emoji/google/large_orange_diamond.png and b/public/images/emoji/google/large_orange_diamond.png differ diff --git a/public/images/emoji/google/last_quarter_moon.png b/public/images/emoji/google/last_quarter_moon.png index d36e213b53c..fa4883c2f36 100644 Binary files a/public/images/emoji/google/last_quarter_moon.png and b/public/images/emoji/google/last_quarter_moon.png differ diff --git a/public/images/emoji/google/last_quarter_moon_with_face.png b/public/images/emoji/google/last_quarter_moon_with_face.png index b88abbb4dbb..9157f1ec07e 100644 Binary files a/public/images/emoji/google/last_quarter_moon_with_face.png and b/public/images/emoji/google/last_quarter_moon_with_face.png differ diff --git a/public/images/emoji/google/laughing.png b/public/images/emoji/google/laughing.png index 8265a2e20c3..3322a94d592 100644 Binary files a/public/images/emoji/google/laughing.png and b/public/images/emoji/google/laughing.png differ diff --git a/public/images/emoji/google/leaves.png b/public/images/emoji/google/leaves.png index b59a4b0e6c3..eb7b39a3437 100644 Binary files a/public/images/emoji/google/leaves.png and b/public/images/emoji/google/leaves.png differ diff --git a/public/images/emoji/google/ledger.png b/public/images/emoji/google/ledger.png index 85a9b8458ba..83871873d2b 100644 Binary files a/public/images/emoji/google/ledger.png and b/public/images/emoji/google/ledger.png differ diff --git a/public/images/emoji/google/left_luggage.png b/public/images/emoji/google/left_luggage.png index 3855da52a78..0bc3a87c0d3 100644 Binary files a/public/images/emoji/google/left_luggage.png and b/public/images/emoji/google/left_luggage.png differ diff --git a/public/images/emoji/google/left_right_arrow.png b/public/images/emoji/google/left_right_arrow.png index 5c3e2bb7709..dfbc74289b2 100644 Binary files a/public/images/emoji/google/left_right_arrow.png and b/public/images/emoji/google/left_right_arrow.png differ diff --git a/public/images/emoji/google/leftwards_arrow_with_hook.png b/public/images/emoji/google/leftwards_arrow_with_hook.png index 85981609760..582b558d657 100644 Binary files a/public/images/emoji/google/leftwards_arrow_with_hook.png and b/public/images/emoji/google/leftwards_arrow_with_hook.png differ diff --git a/public/images/emoji/google/lemon.png b/public/images/emoji/google/lemon.png index 87c9614d087..7e3d176d1db 100644 Binary files a/public/images/emoji/google/lemon.png and b/public/images/emoji/google/lemon.png differ diff --git a/public/images/emoji/google/leo.png b/public/images/emoji/google/leo.png index cbdc7f5710b..d3cdae276c0 100644 Binary files a/public/images/emoji/google/leo.png and b/public/images/emoji/google/leo.png differ diff --git a/public/images/emoji/google/leopard.png b/public/images/emoji/google/leopard.png index d01138abfc5..fb4d13fa975 100644 Binary files a/public/images/emoji/google/leopard.png and b/public/images/emoji/google/leopard.png differ diff --git a/public/images/emoji/google/level_slider.png b/public/images/emoji/google/level_slider.png new file mode 100644 index 00000000000..74adedad393 Binary files /dev/null and b/public/images/emoji/google/level_slider.png differ diff --git a/public/images/emoji/google/levitate.png b/public/images/emoji/google/levitate.png new file mode 100644 index 00000000000..b257d1b6529 Binary files /dev/null and b/public/images/emoji/google/levitate.png differ diff --git a/public/images/emoji/google/libra.png b/public/images/emoji/google/libra.png index bc6a1c8af45..7be3dc10312 100644 Binary files a/public/images/emoji/google/libra.png and b/public/images/emoji/google/libra.png differ diff --git a/public/images/emoji/google/lifter.png b/public/images/emoji/google/lifter.png new file mode 100644 index 00000000000..52dd8c972a1 Binary files /dev/null and b/public/images/emoji/google/lifter.png differ diff --git a/public/images/emoji/google/light_rail.png b/public/images/emoji/google/light_rail.png index 9ff5f20ff1a..1fa53d6e8c3 100644 Binary files a/public/images/emoji/google/light_rail.png and b/public/images/emoji/google/light_rail.png differ diff --git a/public/images/emoji/google/link.png b/public/images/emoji/google/link.png index 2be94b5bfa4..214c4a13e67 100644 Binary files a/public/images/emoji/google/link.png and b/public/images/emoji/google/link.png differ diff --git a/public/images/emoji/google/lion_face.png b/public/images/emoji/google/lion_face.png new file mode 100644 index 00000000000..18ec861a2d2 Binary files /dev/null and b/public/images/emoji/google/lion_face.png differ diff --git a/public/images/emoji/google/lips.png b/public/images/emoji/google/lips.png index c37cf47159f..75ecaa09841 100644 Binary files a/public/images/emoji/google/lips.png and b/public/images/emoji/google/lips.png differ diff --git a/public/images/emoji/google/lipstick.png b/public/images/emoji/google/lipstick.png index 871a697a231..5cf284d3b9b 100644 Binary files a/public/images/emoji/google/lipstick.png and b/public/images/emoji/google/lipstick.png differ diff --git a/public/images/emoji/google/lock.png b/public/images/emoji/google/lock.png index f4bb547eaf5..e0ec08eb419 100644 Binary files a/public/images/emoji/google/lock.png and b/public/images/emoji/google/lock.png differ diff --git a/public/images/emoji/google/lock_with_ink_pen.png b/public/images/emoji/google/lock_with_ink_pen.png index 78c3032202e..cb96a0147e4 100644 Binary files a/public/images/emoji/google/lock_with_ink_pen.png and b/public/images/emoji/google/lock_with_ink_pen.png differ diff --git a/public/images/emoji/google/lollipop.png b/public/images/emoji/google/lollipop.png index de011193d28..d854078cfb5 100644 Binary files a/public/images/emoji/google/lollipop.png and b/public/images/emoji/google/lollipop.png differ diff --git a/public/images/emoji/google/loop.png b/public/images/emoji/google/loop.png index c8d62e68a75..8c3af6be15f 100644 Binary files a/public/images/emoji/google/loop.png and b/public/images/emoji/google/loop.png differ diff --git a/public/images/emoji/google/loud_sound.png b/public/images/emoji/google/loud_sound.png index 1424ff834cd..b229fb8d27b 100644 Binary files a/public/images/emoji/google/loud_sound.png and b/public/images/emoji/google/loud_sound.png differ diff --git a/public/images/emoji/google/loudspeaker.png b/public/images/emoji/google/loudspeaker.png index 39d5afa9ddd..e06a687705c 100644 Binary files a/public/images/emoji/google/loudspeaker.png and b/public/images/emoji/google/loudspeaker.png differ diff --git a/public/images/emoji/google/love_hotel.png b/public/images/emoji/google/love_hotel.png index 3e714a2944e..8c08c50af3f 100644 Binary files a/public/images/emoji/google/love_hotel.png and b/public/images/emoji/google/love_hotel.png differ diff --git a/public/images/emoji/google/love_letter.png b/public/images/emoji/google/love_letter.png index c8ea4c7ee87..2afa8a4d71b 100644 Binary files a/public/images/emoji/google/love_letter.png and b/public/images/emoji/google/love_letter.png differ diff --git a/public/images/emoji/google/low_brightness.png b/public/images/emoji/google/low_brightness.png index d6630f805be..9296a5d8c26 100644 Binary files a/public/images/emoji/google/low_brightness.png and b/public/images/emoji/google/low_brightness.png differ diff --git a/public/images/emoji/google/m.png b/public/images/emoji/google/m.png index c6d07b2141b..d1f2c32d592 100644 Binary files a/public/images/emoji/google/m.png and b/public/images/emoji/google/m.png differ diff --git a/public/images/emoji/google/mag.png b/public/images/emoji/google/mag.png index 26914822797..309cb7284a2 100644 Binary files a/public/images/emoji/google/mag.png and b/public/images/emoji/google/mag.png differ diff --git a/public/images/emoji/google/mag_right.png b/public/images/emoji/google/mag_right.png index a7eea48a979..a079fc679fe 100644 Binary files a/public/images/emoji/google/mag_right.png and b/public/images/emoji/google/mag_right.png differ diff --git a/public/images/emoji/google/mahjong.png b/public/images/emoji/google/mahjong.png index 90e33121d01..902c1144847 100644 Binary files a/public/images/emoji/google/mahjong.png and b/public/images/emoji/google/mahjong.png differ diff --git a/public/images/emoji/google/mailbox.png b/public/images/emoji/google/mailbox.png index 96977e23027..f87a2a9e7f5 100644 Binary files a/public/images/emoji/google/mailbox.png and b/public/images/emoji/google/mailbox.png differ diff --git a/public/images/emoji/google/mailbox_closed.png b/public/images/emoji/google/mailbox_closed.png index 02868e7294c..ee036d2059e 100644 Binary files a/public/images/emoji/google/mailbox_closed.png and b/public/images/emoji/google/mailbox_closed.png differ diff --git a/public/images/emoji/google/mailbox_with_mail.png b/public/images/emoji/google/mailbox_with_mail.png index f1efa012b67..2dfada603f3 100644 Binary files a/public/images/emoji/google/mailbox_with_mail.png and b/public/images/emoji/google/mailbox_with_mail.png differ diff --git a/public/images/emoji/google/mailbox_with_no_mail.png b/public/images/emoji/google/mailbox_with_no_mail.png index fb0942a113b..fb074fddf07 100644 Binary files a/public/images/emoji/google/mailbox_with_no_mail.png and b/public/images/emoji/google/mailbox_with_no_mail.png differ diff --git a/public/images/emoji/google/man.png b/public/images/emoji/google/man.png index 620635122a9..4632c7e966b 100644 Binary files a/public/images/emoji/google/man.png and b/public/images/emoji/google/man.png differ diff --git a/public/images/emoji/google/man_with_gua_pi_mao.png b/public/images/emoji/google/man_with_gua_pi_mao.png index 09fba51b5ce..0f08b499170 100644 Binary files a/public/images/emoji/google/man_with_gua_pi_mao.png and b/public/images/emoji/google/man_with_gua_pi_mao.png differ diff --git a/public/images/emoji/google/man_with_turban.png b/public/images/emoji/google/man_with_turban.png index 8e5b9de8b9b..6493923d968 100644 Binary files a/public/images/emoji/google/man_with_turban.png and b/public/images/emoji/google/man_with_turban.png differ diff --git a/public/images/emoji/google/mans_shoe.png b/public/images/emoji/google/mans_shoe.png index 9c811a82bda..a0d8f3baa4c 100644 Binary files a/public/images/emoji/google/mans_shoe.png and b/public/images/emoji/google/mans_shoe.png differ diff --git a/public/images/emoji/google/map.png b/public/images/emoji/google/map.png new file mode 100644 index 00000000000..47a97c65b37 Binary files /dev/null and b/public/images/emoji/google/map.png differ diff --git a/public/images/emoji/google/maple_leaf.png b/public/images/emoji/google/maple_leaf.png index 9c6825ee3a4..83e2cf27428 100644 Binary files a/public/images/emoji/google/maple_leaf.png and b/public/images/emoji/google/maple_leaf.png differ diff --git a/public/images/emoji/google/mask.png b/public/images/emoji/google/mask.png index b724685200a..c6b14221dc5 100644 Binary files a/public/images/emoji/google/mask.png and b/public/images/emoji/google/mask.png differ diff --git a/public/images/emoji/google/massage.png b/public/images/emoji/google/massage.png index df1ba61493f..cf62537bead 100644 Binary files a/public/images/emoji/google/massage.png and b/public/images/emoji/google/massage.png differ diff --git a/public/images/emoji/google/meat_on_bone.png b/public/images/emoji/google/meat_on_bone.png index 8595de4c78d..0ea8452a334 100644 Binary files a/public/images/emoji/google/meat_on_bone.png and b/public/images/emoji/google/meat_on_bone.png differ diff --git a/public/images/emoji/google/medal.png b/public/images/emoji/google/medal.png new file mode 100644 index 00000000000..01f0e9af78d Binary files /dev/null and b/public/images/emoji/google/medal.png differ diff --git a/public/images/emoji/google/mega.png b/public/images/emoji/google/mega.png index c72c2be3579..9b564b0836d 100644 Binary files a/public/images/emoji/google/mega.png and b/public/images/emoji/google/mega.png differ diff --git a/public/images/emoji/google/melon.png b/public/images/emoji/google/melon.png index 077bf80e835..715babd8158 100644 Binary files a/public/images/emoji/google/melon.png and b/public/images/emoji/google/melon.png differ diff --git a/public/images/emoji/google/memo.png b/public/images/emoji/google/memo.png index 6ed3a14147b..2021c6c8e81 100644 Binary files a/public/images/emoji/google/memo.png and b/public/images/emoji/google/memo.png differ diff --git a/public/images/emoji/google/menorah.png b/public/images/emoji/google/menorah.png new file mode 100644 index 00000000000..d618e60f658 Binary files /dev/null and b/public/images/emoji/google/menorah.png differ diff --git a/public/images/emoji/google/mens.png b/public/images/emoji/google/mens.png index 2cba6e063ff..5285eabaa6f 100644 Binary files a/public/images/emoji/google/mens.png and b/public/images/emoji/google/mens.png differ diff --git a/public/images/emoji/google/metal.png b/public/images/emoji/google/metal.png new file mode 100644 index 00000000000..fe5ca6ecb4f Binary files /dev/null and b/public/images/emoji/google/metal.png differ diff --git a/public/images/emoji/google/metro.png b/public/images/emoji/google/metro.png index 4ee633bd5dc..03878c75277 100644 Binary files a/public/images/emoji/google/metro.png and b/public/images/emoji/google/metro.png differ diff --git a/public/images/emoji/google/microphone.png b/public/images/emoji/google/microphone.png index 5bceb3f8cc5..b70134b33af 100644 Binary files a/public/images/emoji/google/microphone.png and b/public/images/emoji/google/microphone.png differ diff --git a/public/images/emoji/google/microphone2.png b/public/images/emoji/google/microphone2.png new file mode 100644 index 00000000000..4a772830df4 Binary files /dev/null and b/public/images/emoji/google/microphone2.png differ diff --git a/public/images/emoji/google/microscope.png b/public/images/emoji/google/microscope.png index 21b5c1f12ce..1ccf2596008 100644 Binary files a/public/images/emoji/google/microscope.png and b/public/images/emoji/google/microscope.png differ diff --git a/public/images/emoji/google/middle_finger.png b/public/images/emoji/google/middle_finger.png new file mode 100644 index 00000000000..7bab9e62d04 Binary files /dev/null and b/public/images/emoji/google/middle_finger.png differ diff --git a/public/images/emoji/google/military_medal.png b/public/images/emoji/google/military_medal.png new file mode 100644 index 00000000000..905a8389249 Binary files /dev/null and b/public/images/emoji/google/military_medal.png differ diff --git a/public/images/emoji/google/milky_way.png b/public/images/emoji/google/milky_way.png index 830ae3f0006..962b92c5e84 100644 Binary files a/public/images/emoji/google/milky_way.png and b/public/images/emoji/google/milky_way.png differ diff --git a/public/images/emoji/google/minibus.png b/public/images/emoji/google/minibus.png index 65b536d1aae..686a1ed47c5 100644 Binary files a/public/images/emoji/google/minibus.png and b/public/images/emoji/google/minibus.png differ diff --git a/public/images/emoji/google/minidisc.png b/public/images/emoji/google/minidisc.png index 6532a4ed7f4..e47e86e4913 100644 Binary files a/public/images/emoji/google/minidisc.png and b/public/images/emoji/google/minidisc.png differ diff --git a/public/images/emoji/google/mobile_phone_off.png b/public/images/emoji/google/mobile_phone_off.png index 3fd9fab04f6..ee7c94e1679 100644 Binary files a/public/images/emoji/google/mobile_phone_off.png and b/public/images/emoji/google/mobile_phone_off.png differ diff --git a/public/images/emoji/google/money_mouth.png b/public/images/emoji/google/money_mouth.png new file mode 100644 index 00000000000..231c21c1611 Binary files /dev/null and b/public/images/emoji/google/money_mouth.png differ diff --git a/public/images/emoji/google/money_with_wings.png b/public/images/emoji/google/money_with_wings.png index 45b6814f319..278d7e89b70 100644 Binary files a/public/images/emoji/google/money_with_wings.png and b/public/images/emoji/google/money_with_wings.png differ diff --git a/public/images/emoji/google/moneybag.png b/public/images/emoji/google/moneybag.png index aebb8d43909..ca5660fd86f 100644 Binary files a/public/images/emoji/google/moneybag.png and b/public/images/emoji/google/moneybag.png differ diff --git a/public/images/emoji/google/monkey.png b/public/images/emoji/google/monkey.png index 2311b2a6777..11a8f7ad020 100644 Binary files a/public/images/emoji/google/monkey.png and b/public/images/emoji/google/monkey.png differ diff --git a/public/images/emoji/google/monkey_face.png b/public/images/emoji/google/monkey_face.png index caea91db35e..ead2954f9c5 100644 Binary files a/public/images/emoji/google/monkey_face.png and b/public/images/emoji/google/monkey_face.png differ diff --git a/public/images/emoji/google/monorail.png b/public/images/emoji/google/monorail.png index e7197d7e872..030f0f00a3c 100644 Binary files a/public/images/emoji/google/monorail.png and b/public/images/emoji/google/monorail.png differ diff --git a/public/images/emoji/google/moon.png b/public/images/emoji/google/moon.png index 4828995c5d0..11df42bd72a 100644 Binary files a/public/images/emoji/google/moon.png and b/public/images/emoji/google/moon.png differ diff --git a/public/images/emoji/google/mortar_board.png b/public/images/emoji/google/mortar_board.png index 8a3720a9fa4..c3b1090f5d1 100644 Binary files a/public/images/emoji/google/mortar_board.png and b/public/images/emoji/google/mortar_board.png differ diff --git a/public/images/emoji/google/mosque.png b/public/images/emoji/google/mosque.png new file mode 100644 index 00000000000..0aee1ca20d1 Binary files /dev/null and b/public/images/emoji/google/mosque.png differ diff --git a/public/images/emoji/google/motorboat.png b/public/images/emoji/google/motorboat.png new file mode 100644 index 00000000000..a735312ec64 Binary files /dev/null and b/public/images/emoji/google/motorboat.png differ diff --git a/public/images/emoji/google/motorcycle.png b/public/images/emoji/google/motorcycle.png new file mode 100644 index 00000000000..26da5995fe6 Binary files /dev/null and b/public/images/emoji/google/motorcycle.png differ diff --git a/public/images/emoji/google/motorway.png b/public/images/emoji/google/motorway.png new file mode 100644 index 00000000000..3fbb18ea255 Binary files /dev/null and b/public/images/emoji/google/motorway.png differ diff --git a/public/images/emoji/google/mount_fuji.png b/public/images/emoji/google/mount_fuji.png index 8ed0604fba4..9549846edbf 100644 Binary files a/public/images/emoji/google/mount_fuji.png and b/public/images/emoji/google/mount_fuji.png differ diff --git a/public/images/emoji/google/mountain.png b/public/images/emoji/google/mountain.png new file mode 100644 index 00000000000..869d358f1fd Binary files /dev/null and b/public/images/emoji/google/mountain.png differ diff --git a/public/images/emoji/google/mountain_bicyclist.png b/public/images/emoji/google/mountain_bicyclist.png index 60aeec8aecc..63709aa05c3 100644 Binary files a/public/images/emoji/google/mountain_bicyclist.png and b/public/images/emoji/google/mountain_bicyclist.png differ diff --git a/public/images/emoji/google/mountain_cableway.png b/public/images/emoji/google/mountain_cableway.png index 6b71d2656d1..aebabbe8685 100644 Binary files a/public/images/emoji/google/mountain_cableway.png and b/public/images/emoji/google/mountain_cableway.png differ diff --git a/public/images/emoji/google/mountain_railway.png b/public/images/emoji/google/mountain_railway.png index 5f460d66b15..7a89d9b1581 100644 Binary files a/public/images/emoji/google/mountain_railway.png and b/public/images/emoji/google/mountain_railway.png differ diff --git a/public/images/emoji/google/mountain_snow.png b/public/images/emoji/google/mountain_snow.png new file mode 100644 index 00000000000..e5c77bfc5ed Binary files /dev/null and b/public/images/emoji/google/mountain_snow.png differ diff --git a/public/images/emoji/google/mouse.png b/public/images/emoji/google/mouse.png index 0c5d9b3b100..e915471e400 100644 Binary files a/public/images/emoji/google/mouse.png and b/public/images/emoji/google/mouse.png differ diff --git a/public/images/emoji/google/mouse2.png b/public/images/emoji/google/mouse2.png index 32089e9d9d8..4310a346de3 100644 Binary files a/public/images/emoji/google/mouse2.png and b/public/images/emoji/google/mouse2.png differ diff --git a/public/images/emoji/google/mouse_three_button.png b/public/images/emoji/google/mouse_three_button.png new file mode 100644 index 00000000000..6ac3b8f8c93 Binary files /dev/null and b/public/images/emoji/google/mouse_three_button.png differ diff --git a/public/images/emoji/google/movie_camera.png b/public/images/emoji/google/movie_camera.png index d8db67d7768..04ecc818c3c 100644 Binary files a/public/images/emoji/google/movie_camera.png and b/public/images/emoji/google/movie_camera.png differ diff --git a/public/images/emoji/google/moyai.png b/public/images/emoji/google/moyai.png index f308131cba1..eeb97a72e9d 100644 Binary files a/public/images/emoji/google/moyai.png and b/public/images/emoji/google/moyai.png differ diff --git a/public/images/emoji/google/muscle.png b/public/images/emoji/google/muscle.png index b446b01c948..ded54ca4d53 100644 Binary files a/public/images/emoji/google/muscle.png and b/public/images/emoji/google/muscle.png differ diff --git a/public/images/emoji/google/mushroom.png b/public/images/emoji/google/mushroom.png index 5701b528cc7..ea3a720f1cb 100644 Binary files a/public/images/emoji/google/mushroom.png and b/public/images/emoji/google/mushroom.png differ diff --git a/public/images/emoji/google/musical_keyboard.png b/public/images/emoji/google/musical_keyboard.png index 398331fc9f7..a739cfbde7e 100644 Binary files a/public/images/emoji/google/musical_keyboard.png and b/public/images/emoji/google/musical_keyboard.png differ diff --git a/public/images/emoji/google/musical_note.png b/public/images/emoji/google/musical_note.png index d15e9644f51..1fbd6993c46 100644 Binary files a/public/images/emoji/google/musical_note.png and b/public/images/emoji/google/musical_note.png differ diff --git a/public/images/emoji/google/musical_score.png b/public/images/emoji/google/musical_score.png index af675be5148..b40e5bceb90 100644 Binary files a/public/images/emoji/google/musical_score.png and b/public/images/emoji/google/musical_score.png differ diff --git a/public/images/emoji/google/mute.png b/public/images/emoji/google/mute.png index ee4cba2b424..9ffee312582 100644 Binary files a/public/images/emoji/google/mute.png and b/public/images/emoji/google/mute.png differ diff --git a/public/images/emoji/google/nail_care.png b/public/images/emoji/google/nail_care.png index 5238de682d3..8f2c4aa2529 100644 Binary files a/public/images/emoji/google/nail_care.png and b/public/images/emoji/google/nail_care.png differ diff --git a/public/images/emoji/google/name_badge.png b/public/images/emoji/google/name_badge.png index 89972980e39..34873df6947 100644 Binary files a/public/images/emoji/google/name_badge.png and b/public/images/emoji/google/name_badge.png differ diff --git a/public/images/emoji/google/necktie.png b/public/images/emoji/google/necktie.png index cca52c8aea6..8f31266abf1 100644 Binary files a/public/images/emoji/google/necktie.png and b/public/images/emoji/google/necktie.png differ diff --git a/public/images/emoji/google/negative_squared_cross_mark.png b/public/images/emoji/google/negative_squared_cross_mark.png index 4a71381ddd7..7e101ff8c27 100644 Binary files a/public/images/emoji/google/negative_squared_cross_mark.png and b/public/images/emoji/google/negative_squared_cross_mark.png differ diff --git a/public/images/emoji/google/nerd.png b/public/images/emoji/google/nerd.png new file mode 100644 index 00000000000..29712d83c92 Binary files /dev/null and b/public/images/emoji/google/nerd.png differ diff --git a/public/images/emoji/google/neutral_face.png b/public/images/emoji/google/neutral_face.png index e9cf28e58eb..e57bd249e0d 100644 Binary files a/public/images/emoji/google/neutral_face.png and b/public/images/emoji/google/neutral_face.png differ diff --git a/public/images/emoji/google/new.png b/public/images/emoji/google/new.png index a794c6928fc..5d9e2d2930b 100644 Binary files a/public/images/emoji/google/new.png and b/public/images/emoji/google/new.png differ diff --git a/public/images/emoji/google/new_moon.png b/public/images/emoji/google/new_moon.png index ae3175c0ef8..8399c9d265e 100644 Binary files a/public/images/emoji/google/new_moon.png and b/public/images/emoji/google/new_moon.png differ diff --git a/public/images/emoji/google/new_moon_with_face.png b/public/images/emoji/google/new_moon_with_face.png index 66e56479404..c010da872b1 100644 Binary files a/public/images/emoji/google/new_moon_with_face.png and b/public/images/emoji/google/new_moon_with_face.png differ diff --git a/public/images/emoji/google/newspaper.png b/public/images/emoji/google/newspaper.png index 3545e4fe977..c4315699ba5 100644 Binary files a/public/images/emoji/google/newspaper.png and b/public/images/emoji/google/newspaper.png differ diff --git a/public/images/emoji/google/newspaper2.png b/public/images/emoji/google/newspaper2.png new file mode 100644 index 00000000000..d8abf1de67c Binary files /dev/null and b/public/images/emoji/google/newspaper2.png differ diff --git a/public/images/emoji/google/ng.png b/public/images/emoji/google/ng.png index 16dd308963f..1bfe4ab339b 100644 Binary files a/public/images/emoji/google/ng.png and b/public/images/emoji/google/ng.png differ diff --git a/public/images/emoji/google/night_with_stars.png b/public/images/emoji/google/night_with_stars.png index 1ac4b9761dc..7e1edd13887 100644 Binary files a/public/images/emoji/google/night_with_stars.png and b/public/images/emoji/google/night_with_stars.png differ diff --git a/public/images/emoji/google/nine.png b/public/images/emoji/google/nine.png index 702e20b9c04..743f036182f 100644 Binary files a/public/images/emoji/google/nine.png and b/public/images/emoji/google/nine.png differ diff --git a/public/images/emoji/google/no_bell.png b/public/images/emoji/google/no_bell.png index 48b2a867d92..7e6d92df4d7 100644 Binary files a/public/images/emoji/google/no_bell.png and b/public/images/emoji/google/no_bell.png differ diff --git a/public/images/emoji/google/no_bicycles.png b/public/images/emoji/google/no_bicycles.png index 9464d12a263..d8379f86d78 100644 Binary files a/public/images/emoji/google/no_bicycles.png and b/public/images/emoji/google/no_bicycles.png differ diff --git a/public/images/emoji/google/no_entry.png b/public/images/emoji/google/no_entry.png index 0820299a733..edd9ec27a48 100644 Binary files a/public/images/emoji/google/no_entry.png and b/public/images/emoji/google/no_entry.png differ diff --git a/public/images/emoji/google/no_entry_sign.png b/public/images/emoji/google/no_entry_sign.png index e7f37677e44..c495501413d 100644 Binary files a/public/images/emoji/google/no_entry_sign.png and b/public/images/emoji/google/no_entry_sign.png differ diff --git a/public/images/emoji/google/no_good.png b/public/images/emoji/google/no_good.png index ac08d335300..63a56a24712 100644 Binary files a/public/images/emoji/google/no_good.png and b/public/images/emoji/google/no_good.png differ diff --git a/public/images/emoji/google/no_mobile_phones.png b/public/images/emoji/google/no_mobile_phones.png index 7bd5edbbee0..7784b26dc74 100644 Binary files a/public/images/emoji/google/no_mobile_phones.png and b/public/images/emoji/google/no_mobile_phones.png differ diff --git a/public/images/emoji/google/no_mouth.png b/public/images/emoji/google/no_mouth.png index c91368ffae9..255c2e67af0 100644 Binary files a/public/images/emoji/google/no_mouth.png and b/public/images/emoji/google/no_mouth.png differ diff --git a/public/images/emoji/google/no_pedestrians.png b/public/images/emoji/google/no_pedestrians.png index 4aaf7e0ea13..7dc65c1d84e 100644 Binary files a/public/images/emoji/google/no_pedestrians.png and b/public/images/emoji/google/no_pedestrians.png differ diff --git a/public/images/emoji/google/no_smoking.png b/public/images/emoji/google/no_smoking.png index 345dcf2c8b1..1f0ec2dc57d 100644 Binary files a/public/images/emoji/google/no_smoking.png and b/public/images/emoji/google/no_smoking.png differ diff --git a/public/images/emoji/google/non-potable_water.png b/public/images/emoji/google/non-potable_water.png index 85267b5920a..f9916668ac0 100644 Binary files a/public/images/emoji/google/non-potable_water.png and b/public/images/emoji/google/non-potable_water.png differ diff --git a/public/images/emoji/google/nose.png b/public/images/emoji/google/nose.png index de3d25a7bc1..465b2de5bea 100644 Binary files a/public/images/emoji/google/nose.png and b/public/images/emoji/google/nose.png differ diff --git a/public/images/emoji/google/notebook.png b/public/images/emoji/google/notebook.png index 68808bbd0d6..5bcd947064e 100644 Binary files a/public/images/emoji/google/notebook.png and b/public/images/emoji/google/notebook.png differ diff --git a/public/images/emoji/google/notebook_with_decorative_cover.png b/public/images/emoji/google/notebook_with_decorative_cover.png index 692508cf201..1f93d9977b7 100644 Binary files a/public/images/emoji/google/notebook_with_decorative_cover.png and b/public/images/emoji/google/notebook_with_decorative_cover.png differ diff --git a/public/images/emoji/google/notepad_spiral.png b/public/images/emoji/google/notepad_spiral.png new file mode 100644 index 00000000000..160c8c2e28b Binary files /dev/null and b/public/images/emoji/google/notepad_spiral.png differ diff --git a/public/images/emoji/google/notes.png b/public/images/emoji/google/notes.png index faf6da3668c..27d9592d91c 100644 Binary files a/public/images/emoji/google/notes.png and b/public/images/emoji/google/notes.png differ diff --git a/public/images/emoji/google/nut_and_bolt.png b/public/images/emoji/google/nut_and_bolt.png index 67f7323f463..b8e8474295c 100644 Binary files a/public/images/emoji/google/nut_and_bolt.png and b/public/images/emoji/google/nut_and_bolt.png differ diff --git a/public/images/emoji/google/o.png b/public/images/emoji/google/o.png index e0d08de45ec..571dd320278 100644 Binary files a/public/images/emoji/google/o.png and b/public/images/emoji/google/o.png differ diff --git a/public/images/emoji/google/o2.png b/public/images/emoji/google/o2.png index 03cf43d5af4..250873e6616 100644 Binary files a/public/images/emoji/google/o2.png and b/public/images/emoji/google/o2.png differ diff --git a/public/images/emoji/google/ocean.png b/public/images/emoji/google/ocean.png index c24ecc65bdb..a8a7a161d45 100644 Binary files a/public/images/emoji/google/ocean.png and b/public/images/emoji/google/ocean.png differ diff --git a/public/images/emoji/google/octopus.png b/public/images/emoji/google/octopus.png index 35875ccdd74..c6331d0a81d 100644 Binary files a/public/images/emoji/google/octopus.png and b/public/images/emoji/google/octopus.png differ diff --git a/public/images/emoji/google/oden.png b/public/images/emoji/google/oden.png index 0f0c1e426be..9362e0469ec 100644 Binary files a/public/images/emoji/google/oden.png and b/public/images/emoji/google/oden.png differ diff --git a/public/images/emoji/google/office.png b/public/images/emoji/google/office.png index 678d6d4b195..4b030941a45 100644 Binary files a/public/images/emoji/google/office.png and b/public/images/emoji/google/office.png differ diff --git a/public/images/emoji/google/oil.png b/public/images/emoji/google/oil.png new file mode 100644 index 00000000000..c7214f90135 Binary files /dev/null and b/public/images/emoji/google/oil.png differ diff --git a/public/images/emoji/google/ok.png b/public/images/emoji/google/ok.png index 5071f9e5ed3..db6d487d4f7 100644 Binary files a/public/images/emoji/google/ok.png and b/public/images/emoji/google/ok.png differ diff --git a/public/images/emoji/google/ok_hand.png b/public/images/emoji/google/ok_hand.png index 1c3eefddac1..1f55a4fa4e6 100644 Binary files a/public/images/emoji/google/ok_hand.png and b/public/images/emoji/google/ok_hand.png differ diff --git a/public/images/emoji/google/ok_woman.png b/public/images/emoji/google/ok_woman.png index edfb0e6f28f..9cc80b37103 100644 Binary files a/public/images/emoji/google/ok_woman.png and b/public/images/emoji/google/ok_woman.png differ diff --git a/public/images/emoji/google/older_man.png b/public/images/emoji/google/older_man.png index 07706ffd865..bb9fd976279 100644 Binary files a/public/images/emoji/google/older_man.png and b/public/images/emoji/google/older_man.png differ diff --git a/public/images/emoji/google/older_woman.png b/public/images/emoji/google/older_woman.png index 51794869126..82412427ded 100644 Binary files a/public/images/emoji/google/older_woman.png and b/public/images/emoji/google/older_woman.png differ diff --git a/public/images/emoji/google/om_symbol.png b/public/images/emoji/google/om_symbol.png new file mode 100644 index 00000000000..df39c8dec05 Binary files /dev/null and b/public/images/emoji/google/om_symbol.png differ diff --git a/public/images/emoji/google/on.png b/public/images/emoji/google/on.png index 7423312480e..70a6f85aa16 100644 Binary files a/public/images/emoji/google/on.png and b/public/images/emoji/google/on.png differ diff --git a/public/images/emoji/google/oncoming_automobile.png b/public/images/emoji/google/oncoming_automobile.png index cac7e1043e3..32d754b1083 100644 Binary files a/public/images/emoji/google/oncoming_automobile.png and b/public/images/emoji/google/oncoming_automobile.png differ diff --git a/public/images/emoji/google/oncoming_bus.png b/public/images/emoji/google/oncoming_bus.png index c96b3e28ba8..1400a4fa480 100644 Binary files a/public/images/emoji/google/oncoming_bus.png and b/public/images/emoji/google/oncoming_bus.png differ diff --git a/public/images/emoji/google/oncoming_police_car.png b/public/images/emoji/google/oncoming_police_car.png index 6b7f10eab70..2512f628f42 100644 Binary files a/public/images/emoji/google/oncoming_police_car.png and b/public/images/emoji/google/oncoming_police_car.png differ diff --git a/public/images/emoji/google/oncoming_taxi.png b/public/images/emoji/google/oncoming_taxi.png index 20a3741a8ab..043ffb49561 100644 Binary files a/public/images/emoji/google/oncoming_taxi.png and b/public/images/emoji/google/oncoming_taxi.png differ diff --git a/public/images/emoji/google/one.png b/public/images/emoji/google/one.png index 771c6a92ef6..b211ba17839 100644 Binary files a/public/images/emoji/google/one.png and b/public/images/emoji/google/one.png differ diff --git a/public/images/emoji/google/open_file_folder.png b/public/images/emoji/google/open_file_folder.png index 48c23a7041b..ea5fef333c7 100644 Binary files a/public/images/emoji/google/open_file_folder.png and b/public/images/emoji/google/open_file_folder.png differ diff --git a/public/images/emoji/google/open_hands.png b/public/images/emoji/google/open_hands.png index 5836c119d02..b3d92e77028 100644 Binary files a/public/images/emoji/google/open_hands.png and b/public/images/emoji/google/open_hands.png differ diff --git a/public/images/emoji/google/open_mouth.png b/public/images/emoji/google/open_mouth.png index b341b368922..eefb143990f 100644 Binary files a/public/images/emoji/google/open_mouth.png and b/public/images/emoji/google/open_mouth.png differ diff --git a/public/images/emoji/google/ophiuchus.png b/public/images/emoji/google/ophiuchus.png index 5b90e663678..aebb3841e3c 100644 Binary files a/public/images/emoji/google/ophiuchus.png and b/public/images/emoji/google/ophiuchus.png differ diff --git a/public/images/emoji/google/orange_book.png b/public/images/emoji/google/orange_book.png index fefef006729..782ebeabddd 100644 Binary files a/public/images/emoji/google/orange_book.png and b/public/images/emoji/google/orange_book.png differ diff --git a/public/images/emoji/google/orthodox_cross.png b/public/images/emoji/google/orthodox_cross.png new file mode 100644 index 00000000000..5355c810f25 Binary files /dev/null and b/public/images/emoji/google/orthodox_cross.png differ diff --git a/public/images/emoji/google/outbox_tray.png b/public/images/emoji/google/outbox_tray.png index b22fd44feaf..5ef9d8791b7 100644 Binary files a/public/images/emoji/google/outbox_tray.png and b/public/images/emoji/google/outbox_tray.png differ diff --git a/public/images/emoji/google/ox.png b/public/images/emoji/google/ox.png index 22df911bf02..8710a80a7e7 100644 Binary files a/public/images/emoji/google/ox.png and b/public/images/emoji/google/ox.png differ diff --git a/public/images/emoji/google/package.png b/public/images/emoji/google/package.png index 22990fe0f0b..2b99d42ffe8 100644 Binary files a/public/images/emoji/google/package.png and b/public/images/emoji/google/package.png differ diff --git a/public/images/emoji/google/page_facing_up.png b/public/images/emoji/google/page_facing_up.png index 3289cc0720d..468abf6e90c 100644 Binary files a/public/images/emoji/google/page_facing_up.png and b/public/images/emoji/google/page_facing_up.png differ diff --git a/public/images/emoji/google/page_with_curl.png b/public/images/emoji/google/page_with_curl.png index cb649547fa9..f5d5cf16a3f 100644 Binary files a/public/images/emoji/google/page_with_curl.png and b/public/images/emoji/google/page_with_curl.png differ diff --git a/public/images/emoji/google/pager.png b/public/images/emoji/google/pager.png index a6d4483f488..2551c82bdf0 100644 Binary files a/public/images/emoji/google/pager.png and b/public/images/emoji/google/pager.png differ diff --git a/public/images/emoji/google/paintbrush.png b/public/images/emoji/google/paintbrush.png new file mode 100644 index 00000000000..e41a4f6b5da Binary files /dev/null and b/public/images/emoji/google/paintbrush.png differ diff --git a/public/images/emoji/google/palm_tree.png b/public/images/emoji/google/palm_tree.png index 0026d5abaed..9ac9f4574f0 100644 Binary files a/public/images/emoji/google/palm_tree.png and b/public/images/emoji/google/palm_tree.png differ diff --git a/public/images/emoji/google/panda_face.png b/public/images/emoji/google/panda_face.png index fdbf57e686f..8663c2148f4 100644 Binary files a/public/images/emoji/google/panda_face.png and b/public/images/emoji/google/panda_face.png differ diff --git a/public/images/emoji/google/paperclip.png b/public/images/emoji/google/paperclip.png index 01eee99b8a2..f3bc82397f3 100644 Binary files a/public/images/emoji/google/paperclip.png and b/public/images/emoji/google/paperclip.png differ diff --git a/public/images/emoji/google/paperclips.png b/public/images/emoji/google/paperclips.png new file mode 100644 index 00000000000..d9d9c5c8a42 Binary files /dev/null and b/public/images/emoji/google/paperclips.png differ diff --git a/public/images/emoji/google/park.png b/public/images/emoji/google/park.png new file mode 100644 index 00000000000..468fd0fb892 Binary files /dev/null and b/public/images/emoji/google/park.png differ diff --git a/public/images/emoji/google/parking.png b/public/images/emoji/google/parking.png index c7f775cef7d..968c0ee9ef1 100644 Binary files a/public/images/emoji/google/parking.png and b/public/images/emoji/google/parking.png differ diff --git a/public/images/emoji/google/part_alternation_mark.png b/public/images/emoji/google/part_alternation_mark.png index cdf5367211b..1a851818817 100644 Binary files a/public/images/emoji/google/part_alternation_mark.png and b/public/images/emoji/google/part_alternation_mark.png differ diff --git a/public/images/emoji/google/partly_sunny.png b/public/images/emoji/google/partly_sunny.png index 09c4a02cc0c..fe3f35f553f 100644 Binary files a/public/images/emoji/google/partly_sunny.png and b/public/images/emoji/google/partly_sunny.png differ diff --git a/public/images/emoji/google/passport_control.png b/public/images/emoji/google/passport_control.png index 7f03c51bdab..c2b116076f1 100644 Binary files a/public/images/emoji/google/passport_control.png and b/public/images/emoji/google/passport_control.png differ diff --git a/public/images/emoji/google/pause_button.png b/public/images/emoji/google/pause_button.png new file mode 100644 index 00000000000..31f4ff52840 Binary files /dev/null and b/public/images/emoji/google/pause_button.png differ diff --git a/public/images/emoji/google/peace.png b/public/images/emoji/google/peace.png new file mode 100644 index 00000000000..d1f1f7a3bfc Binary files /dev/null and b/public/images/emoji/google/peace.png differ diff --git a/public/images/emoji/google/peach.png b/public/images/emoji/google/peach.png index cd84170fb67..2e3fbec7daa 100644 Binary files a/public/images/emoji/google/peach.png and b/public/images/emoji/google/peach.png differ diff --git a/public/images/emoji/google/pear.png b/public/images/emoji/google/pear.png index d865e4a9fb1..91a93107da9 100644 Binary files a/public/images/emoji/google/pear.png and b/public/images/emoji/google/pear.png differ diff --git a/public/images/emoji/google/pen_ballpoint.png b/public/images/emoji/google/pen_ballpoint.png new file mode 100644 index 00000000000..a935dd5eac8 Binary files /dev/null and b/public/images/emoji/google/pen_ballpoint.png differ diff --git a/public/images/emoji/google/pen_fountain.png b/public/images/emoji/google/pen_fountain.png new file mode 100644 index 00000000000..10c36f30c0f Binary files /dev/null and b/public/images/emoji/google/pen_fountain.png differ diff --git a/public/images/emoji/google/pencil.png b/public/images/emoji/google/pencil.png index 068ed18ff80..e63a874d78f 100644 Binary files a/public/images/emoji/google/pencil.png and b/public/images/emoji/google/pencil.png differ diff --git a/public/images/emoji/google/pencil2.png b/public/images/emoji/google/pencil2.png index 3cd7a6b6f10..07efab0e875 100644 Binary files a/public/images/emoji/google/pencil2.png and b/public/images/emoji/google/pencil2.png differ diff --git a/public/images/emoji/google/penguin.png b/public/images/emoji/google/penguin.png index 6e81134705d..7508ca50ad7 100644 Binary files a/public/images/emoji/google/penguin.png and b/public/images/emoji/google/penguin.png differ diff --git a/public/images/emoji/google/pensive.png b/public/images/emoji/google/pensive.png index 0443c84d03e..0986383c32c 100644 Binary files a/public/images/emoji/google/pensive.png and b/public/images/emoji/google/pensive.png differ diff --git a/public/images/emoji/google/performing_arts.png b/public/images/emoji/google/performing_arts.png index d09fe8f5ff4..89608220d8d 100644 Binary files a/public/images/emoji/google/performing_arts.png and b/public/images/emoji/google/performing_arts.png differ diff --git a/public/images/emoji/google/persevere.png b/public/images/emoji/google/persevere.png index 62b1c9541e5..42a47c5a74f 100644 Binary files a/public/images/emoji/google/persevere.png and b/public/images/emoji/google/persevere.png differ diff --git a/public/images/emoji/google/person_frowning.png b/public/images/emoji/google/person_frowning.png index a33e2caf66e..b61a30e462b 100644 Binary files a/public/images/emoji/google/person_frowning.png and b/public/images/emoji/google/person_frowning.png differ diff --git a/public/images/emoji/google/person_with_blond_hair.png b/public/images/emoji/google/person_with_blond_hair.png index 2a2f1493fee..f9b53e69759 100644 Binary files a/public/images/emoji/google/person_with_blond_hair.png and b/public/images/emoji/google/person_with_blond_hair.png differ diff --git a/public/images/emoji/google/person_with_pouting_face.png b/public/images/emoji/google/person_with_pouting_face.png index f7e7280bbda..1579c94f489 100644 Binary files a/public/images/emoji/google/person_with_pouting_face.png and b/public/images/emoji/google/person_with_pouting_face.png differ diff --git a/public/images/emoji/google/phone.png b/public/images/emoji/google/phone.png index 36500f20304..001b39f86bb 100644 Binary files a/public/images/emoji/google/phone.png and b/public/images/emoji/google/phone.png differ diff --git a/public/images/emoji/google/pick.png b/public/images/emoji/google/pick.png new file mode 100644 index 00000000000..8fd6623bb1a Binary files /dev/null and b/public/images/emoji/google/pick.png differ diff --git a/public/images/emoji/google/pig.png b/public/images/emoji/google/pig.png index a95b84730be..66e872e813d 100644 Binary files a/public/images/emoji/google/pig.png and b/public/images/emoji/google/pig.png differ diff --git a/public/images/emoji/google/pig2.png b/public/images/emoji/google/pig2.png index 8e78feae9d0..0ae0ddd1d8e 100644 Binary files a/public/images/emoji/google/pig2.png and b/public/images/emoji/google/pig2.png differ diff --git a/public/images/emoji/google/pig_nose.png b/public/images/emoji/google/pig_nose.png index 5afe033f193..8e4506f1e77 100644 Binary files a/public/images/emoji/google/pig_nose.png and b/public/images/emoji/google/pig_nose.png differ diff --git a/public/images/emoji/google/pill.png b/public/images/emoji/google/pill.png index 7189d2f8e3c..841d2dd4b5e 100644 Binary files a/public/images/emoji/google/pill.png and b/public/images/emoji/google/pill.png differ diff --git a/public/images/emoji/google/pineapple.png b/public/images/emoji/google/pineapple.png index 2417a411a02..c5183efe7ca 100644 Binary files a/public/images/emoji/google/pineapple.png and b/public/images/emoji/google/pineapple.png differ diff --git a/public/images/emoji/google/ping_pong.png b/public/images/emoji/google/ping_pong.png new file mode 100644 index 00000000000..c5547d94caa Binary files /dev/null and b/public/images/emoji/google/ping_pong.png differ diff --git a/public/images/emoji/google/pisces.png b/public/images/emoji/google/pisces.png index bfd44f5d9e2..4379ecb65f0 100644 Binary files a/public/images/emoji/google/pisces.png and b/public/images/emoji/google/pisces.png differ diff --git a/public/images/emoji/google/pizza.png b/public/images/emoji/google/pizza.png index 4d1f51a7286..681189e557a 100644 Binary files a/public/images/emoji/google/pizza.png and b/public/images/emoji/google/pizza.png differ diff --git a/public/images/emoji/google/place_of_worship.png b/public/images/emoji/google/place_of_worship.png new file mode 100644 index 00000000000..dc4b77ccc02 Binary files /dev/null and b/public/images/emoji/google/place_of_worship.png differ diff --git a/public/images/emoji/google/play_pause.png b/public/images/emoji/google/play_pause.png new file mode 100644 index 00000000000..ad2c3639ac9 Binary files /dev/null and b/public/images/emoji/google/play_pause.png differ diff --git a/public/images/emoji/google/point_down.png b/public/images/emoji/google/point_down.png index 3f0342b0a46..b950eada7e2 100644 Binary files a/public/images/emoji/google/point_down.png and b/public/images/emoji/google/point_down.png differ diff --git a/public/images/emoji/google/point_left.png b/public/images/emoji/google/point_left.png index 70036882a58..8c6ba482bc1 100644 Binary files a/public/images/emoji/google/point_left.png and b/public/images/emoji/google/point_left.png differ diff --git a/public/images/emoji/google/point_right.png b/public/images/emoji/google/point_right.png index 594d8b1af3f..afdc5e7757a 100644 Binary files a/public/images/emoji/google/point_right.png and b/public/images/emoji/google/point_right.png differ diff --git a/public/images/emoji/google/point_up.png b/public/images/emoji/google/point_up.png index decda3bd03c..df101422fec 100644 Binary files a/public/images/emoji/google/point_up.png and b/public/images/emoji/google/point_up.png differ diff --git a/public/images/emoji/google/point_up_2.png b/public/images/emoji/google/point_up_2.png index 32a13865429..f8587d22ee6 100644 Binary files a/public/images/emoji/google/point_up_2.png and b/public/images/emoji/google/point_up_2.png differ diff --git a/public/images/emoji/google/police_car.png b/public/images/emoji/google/police_car.png index 1bd7b0acc0b..292df28e832 100644 Binary files a/public/images/emoji/google/police_car.png and b/public/images/emoji/google/police_car.png differ diff --git a/public/images/emoji/google/poodle.png b/public/images/emoji/google/poodle.png index bccec8b5451..dc50fc657ff 100644 Binary files a/public/images/emoji/google/poodle.png and b/public/images/emoji/google/poodle.png differ diff --git a/public/images/emoji/google/poop.png b/public/images/emoji/google/poop.png index 18b0c41e541..a8b5706af55 100644 Binary files a/public/images/emoji/google/poop.png and b/public/images/emoji/google/poop.png differ diff --git a/public/images/emoji/google/popcorn.png b/public/images/emoji/google/popcorn.png new file mode 100644 index 00000000000..f71c7d08f2d Binary files /dev/null and b/public/images/emoji/google/popcorn.png differ diff --git a/public/images/emoji/google/post_office.png b/public/images/emoji/google/post_office.png index e534a046eda..18c94c0e39a 100644 Binary files a/public/images/emoji/google/post_office.png and b/public/images/emoji/google/post_office.png differ diff --git a/public/images/emoji/google/postal_horn.png b/public/images/emoji/google/postal_horn.png index 98ab78b89f8..7b1871c4d0d 100644 Binary files a/public/images/emoji/google/postal_horn.png and b/public/images/emoji/google/postal_horn.png differ diff --git a/public/images/emoji/google/postbox.png b/public/images/emoji/google/postbox.png index 1043a035c24..de74a3cc165 100644 Binary files a/public/images/emoji/google/postbox.png and b/public/images/emoji/google/postbox.png differ diff --git a/public/images/emoji/google/potable_water.png b/public/images/emoji/google/potable_water.png index 286138e798e..fa01100ed76 100644 Binary files a/public/images/emoji/google/potable_water.png and b/public/images/emoji/google/potable_water.png differ diff --git a/public/images/emoji/google/pouch.png b/public/images/emoji/google/pouch.png index f40337403d1..495a6ca2864 100644 Binary files a/public/images/emoji/google/pouch.png and b/public/images/emoji/google/pouch.png differ diff --git a/public/images/emoji/google/poultry_leg.png b/public/images/emoji/google/poultry_leg.png index 05e1307fbdc..f9c58ba772a 100644 Binary files a/public/images/emoji/google/poultry_leg.png and b/public/images/emoji/google/poultry_leg.png differ diff --git a/public/images/emoji/google/pound.png b/public/images/emoji/google/pound.png index fdb0efd1761..3abd0abfd74 100644 Binary files a/public/images/emoji/google/pound.png and b/public/images/emoji/google/pound.png differ diff --git a/public/images/emoji/google/pouting_cat.png b/public/images/emoji/google/pouting_cat.png index 339a872dc88..df744d0f0e6 100644 Binary files a/public/images/emoji/google/pouting_cat.png and b/public/images/emoji/google/pouting_cat.png differ diff --git a/public/images/emoji/google/pray.png b/public/images/emoji/google/pray.png index 2c617f29939..992aa026d74 100644 Binary files a/public/images/emoji/google/pray.png and b/public/images/emoji/google/pray.png differ diff --git a/public/images/emoji/google/prayer_beads.png b/public/images/emoji/google/prayer_beads.png new file mode 100644 index 00000000000..8121c40e8d4 Binary files /dev/null and b/public/images/emoji/google/prayer_beads.png differ diff --git a/public/images/emoji/google/princess.png b/public/images/emoji/google/princess.png index c6991b3e3ad..d50b017f7bf 100644 Binary files a/public/images/emoji/google/princess.png and b/public/images/emoji/google/princess.png differ diff --git a/public/images/emoji/google/printer.png b/public/images/emoji/google/printer.png new file mode 100644 index 00000000000..1bf9570bbaa Binary files /dev/null and b/public/images/emoji/google/printer.png differ diff --git a/public/images/emoji/google/projector.png b/public/images/emoji/google/projector.png new file mode 100644 index 00000000000..cd06f11a210 Binary files /dev/null and b/public/images/emoji/google/projector.png differ diff --git a/public/images/emoji/google/punch.png b/public/images/emoji/google/punch.png index 96672f8da34..5d2a306db6d 100644 Binary files a/public/images/emoji/google/punch.png and b/public/images/emoji/google/punch.png differ diff --git a/public/images/emoji/google/purple_heart.png b/public/images/emoji/google/purple_heart.png index 32206b9ef30..2169654a5d1 100644 Binary files a/public/images/emoji/google/purple_heart.png and b/public/images/emoji/google/purple_heart.png differ diff --git a/public/images/emoji/google/purse.png b/public/images/emoji/google/purse.png index 2546187ccea..377a74f4874 100644 Binary files a/public/images/emoji/google/purse.png and b/public/images/emoji/google/purse.png differ diff --git a/public/images/emoji/google/pushpin.png b/public/images/emoji/google/pushpin.png index 077ab406ea1..cb5f9295ad8 100644 Binary files a/public/images/emoji/google/pushpin.png and b/public/images/emoji/google/pushpin.png differ diff --git a/public/images/emoji/google/put_litter_in_its_place.png b/public/images/emoji/google/put_litter_in_its_place.png index 0b2cb59c2eb..58665b55580 100644 Binary files a/public/images/emoji/google/put_litter_in_its_place.png and b/public/images/emoji/google/put_litter_in_its_place.png differ diff --git a/public/images/emoji/google/question.png b/public/images/emoji/google/question.png index bbcf3deef45..7767a4ee0b9 100644 Binary files a/public/images/emoji/google/question.png and b/public/images/emoji/google/question.png differ diff --git a/public/images/emoji/google/rabbit.png b/public/images/emoji/google/rabbit.png index 49aeb254038..f3e786b56a4 100644 Binary files a/public/images/emoji/google/rabbit.png and b/public/images/emoji/google/rabbit.png differ diff --git a/public/images/emoji/google/rabbit2.png b/public/images/emoji/google/rabbit2.png index 447e4192c92..709796c73f5 100644 Binary files a/public/images/emoji/google/rabbit2.png and b/public/images/emoji/google/rabbit2.png differ diff --git a/public/images/emoji/google/race_car.png b/public/images/emoji/google/race_car.png new file mode 100644 index 00000000000..a751071429a Binary files /dev/null and b/public/images/emoji/google/race_car.png differ diff --git a/public/images/emoji/google/racehorse.png b/public/images/emoji/google/racehorse.png index f3d352d9d52..e6a3eaa9fac 100644 Binary files a/public/images/emoji/google/racehorse.png and b/public/images/emoji/google/racehorse.png differ diff --git a/public/images/emoji/google/radio.png b/public/images/emoji/google/radio.png index e922eb87fd4..f4962bbf819 100644 Binary files a/public/images/emoji/google/radio.png and b/public/images/emoji/google/radio.png differ diff --git a/public/images/emoji/google/radio_button.png b/public/images/emoji/google/radio_button.png index d9cd8e03e56..c292c8e3ac8 100644 Binary files a/public/images/emoji/google/radio_button.png and b/public/images/emoji/google/radio_button.png differ diff --git a/public/images/emoji/google/radioactive.png b/public/images/emoji/google/radioactive.png new file mode 100644 index 00000000000..01e580ddf4f Binary files /dev/null and b/public/images/emoji/google/radioactive.png differ diff --git a/public/images/emoji/google/rage.png b/public/images/emoji/google/rage.png index 0117a490b15..fc37e8e4467 100644 Binary files a/public/images/emoji/google/rage.png and b/public/images/emoji/google/rage.png differ diff --git a/public/images/emoji/google/railway_car.png b/public/images/emoji/google/railway_car.png index 8fdb8a71ad2..664e763a648 100644 Binary files a/public/images/emoji/google/railway_car.png and b/public/images/emoji/google/railway_car.png differ diff --git a/public/images/emoji/google/railway_track.png b/public/images/emoji/google/railway_track.png new file mode 100644 index 00000000000..ceac451e0fc Binary files /dev/null and b/public/images/emoji/google/railway_track.png differ diff --git a/public/images/emoji/google/rainbow.png b/public/images/emoji/google/rainbow.png index 4747144d82a..fe230fdd904 100644 Binary files a/public/images/emoji/google/rainbow.png and b/public/images/emoji/google/rainbow.png differ diff --git a/public/images/emoji/google/raised_hand.png b/public/images/emoji/google/raised_hand.png index e8b03e0c20d..d55e6579395 100644 Binary files a/public/images/emoji/google/raised_hand.png and b/public/images/emoji/google/raised_hand.png differ diff --git a/public/images/emoji/google/raised_hands.png b/public/images/emoji/google/raised_hands.png index 5969b78e656..761ff0d20af 100644 Binary files a/public/images/emoji/google/raised_hands.png and b/public/images/emoji/google/raised_hands.png differ diff --git a/public/images/emoji/google/raising_hand.png b/public/images/emoji/google/raising_hand.png index 94b7cff59ba..cfbf3d44180 100644 Binary files a/public/images/emoji/google/raising_hand.png and b/public/images/emoji/google/raising_hand.png differ diff --git a/public/images/emoji/google/ram.png b/public/images/emoji/google/ram.png index 86a12ecf05a..03fd3184d73 100644 Binary files a/public/images/emoji/google/ram.png and b/public/images/emoji/google/ram.png differ diff --git a/public/images/emoji/google/ramen.png b/public/images/emoji/google/ramen.png index b627e7ac828..818fa389423 100644 Binary files a/public/images/emoji/google/ramen.png and b/public/images/emoji/google/ramen.png differ diff --git a/public/images/emoji/google/rat.png b/public/images/emoji/google/rat.png index a6dda927a95..3f49831891b 100644 Binary files a/public/images/emoji/google/rat.png and b/public/images/emoji/google/rat.png differ diff --git a/public/images/emoji/google/record_button.png b/public/images/emoji/google/record_button.png new file mode 100644 index 00000000000..c532d18d8d6 Binary files /dev/null and b/public/images/emoji/google/record_button.png differ diff --git a/public/images/emoji/google/recycle.png b/public/images/emoji/google/recycle.png index 6be86eaea7d..94770f22f15 100644 Binary files a/public/images/emoji/google/recycle.png and b/public/images/emoji/google/recycle.png differ diff --git a/public/images/emoji/google/red_car.png b/public/images/emoji/google/red_car.png index f1be3d95ae5..219bf9923cb 100644 Binary files a/public/images/emoji/google/red_car.png and b/public/images/emoji/google/red_car.png differ diff --git a/public/images/emoji/google/red_circle.png b/public/images/emoji/google/red_circle.png index 7bce4942381..3293b07fcca 100644 Binary files a/public/images/emoji/google/red_circle.png and b/public/images/emoji/google/red_circle.png differ diff --git a/public/images/emoji/google/relaxed.png b/public/images/emoji/google/relaxed.png index 5f0cec556f1..40709476ef5 100644 Binary files a/public/images/emoji/google/relaxed.png and b/public/images/emoji/google/relaxed.png differ diff --git a/public/images/emoji/google/relieved.png b/public/images/emoji/google/relieved.png index 020b4ed57b4..20a6bcc12c3 100644 Binary files a/public/images/emoji/google/relieved.png and b/public/images/emoji/google/relieved.png differ diff --git a/public/images/emoji/google/reminder_ribbon.png b/public/images/emoji/google/reminder_ribbon.png new file mode 100644 index 00000000000..95930a18586 Binary files /dev/null and b/public/images/emoji/google/reminder_ribbon.png differ diff --git a/public/images/emoji/google/repeat.png b/public/images/emoji/google/repeat.png index c0952f02f34..04e5b555466 100644 Binary files a/public/images/emoji/google/repeat.png and b/public/images/emoji/google/repeat.png differ diff --git a/public/images/emoji/google/repeat_one.png b/public/images/emoji/google/repeat_one.png index a3e0d641502..1cecb3cbaa9 100644 Binary files a/public/images/emoji/google/repeat_one.png and b/public/images/emoji/google/repeat_one.png differ diff --git a/public/images/emoji/google/restroom.png b/public/images/emoji/google/restroom.png index 1166e06aa57..12bdf7c9561 100644 Binary files a/public/images/emoji/google/restroom.png and b/public/images/emoji/google/restroom.png differ diff --git a/public/images/emoji/google/revolving_hearts.png b/public/images/emoji/google/revolving_hearts.png index 9a9f6c1b74b..c2287d36c10 100644 Binary files a/public/images/emoji/google/revolving_hearts.png and b/public/images/emoji/google/revolving_hearts.png differ diff --git a/public/images/emoji/google/rewind.png b/public/images/emoji/google/rewind.png index 6d850b98f9b..7c2130883a3 100644 Binary files a/public/images/emoji/google/rewind.png and b/public/images/emoji/google/rewind.png differ diff --git a/public/images/emoji/google/ribbon.png b/public/images/emoji/google/ribbon.png index cfaa698528e..5fb209fe3ba 100644 Binary files a/public/images/emoji/google/ribbon.png and b/public/images/emoji/google/ribbon.png differ diff --git a/public/images/emoji/google/rice.png b/public/images/emoji/google/rice.png index 3404afb438e..f045e9ae2d5 100644 Binary files a/public/images/emoji/google/rice.png and b/public/images/emoji/google/rice.png differ diff --git a/public/images/emoji/google/rice_ball.png b/public/images/emoji/google/rice_ball.png index 8a92252f294..74546fa940a 100644 Binary files a/public/images/emoji/google/rice_ball.png and b/public/images/emoji/google/rice_ball.png differ diff --git a/public/images/emoji/google/rice_cracker.png b/public/images/emoji/google/rice_cracker.png index 68957de5353..0ca76cd3106 100644 Binary files a/public/images/emoji/google/rice_cracker.png and b/public/images/emoji/google/rice_cracker.png differ diff --git a/public/images/emoji/google/rice_scene.png b/public/images/emoji/google/rice_scene.png index 42b7f321b5b..328016a30b2 100644 Binary files a/public/images/emoji/google/rice_scene.png and b/public/images/emoji/google/rice_scene.png differ diff --git a/public/images/emoji/google/ring.png b/public/images/emoji/google/ring.png index 2047eb036a1..12fdf3be368 100644 Binary files a/public/images/emoji/google/ring.png and b/public/images/emoji/google/ring.png differ diff --git a/public/images/emoji/google/robot.png b/public/images/emoji/google/robot.png new file mode 100644 index 00000000000..e3f67625235 Binary files /dev/null and b/public/images/emoji/google/robot.png differ diff --git a/public/images/emoji/google/rocket.png b/public/images/emoji/google/rocket.png index c0cba9ff8e4..66b437d0af0 100644 Binary files a/public/images/emoji/google/rocket.png and b/public/images/emoji/google/rocket.png differ diff --git a/public/images/emoji/google/roller_coaster.png b/public/images/emoji/google/roller_coaster.png index 1f9d0469916..1fc70843c46 100644 Binary files a/public/images/emoji/google/roller_coaster.png and b/public/images/emoji/google/roller_coaster.png differ diff --git a/public/images/emoji/google/rolling_eyes.png b/public/images/emoji/google/rolling_eyes.png new file mode 100644 index 00000000000..a6660d55aa8 Binary files /dev/null and b/public/images/emoji/google/rolling_eyes.png differ diff --git a/public/images/emoji/google/rooster.png b/public/images/emoji/google/rooster.png index 90754020bc5..8308434678a 100644 Binary files a/public/images/emoji/google/rooster.png and b/public/images/emoji/google/rooster.png differ diff --git a/public/images/emoji/google/rose.png b/public/images/emoji/google/rose.png index e3128385968..89ad0585e14 100644 Binary files a/public/images/emoji/google/rose.png and b/public/images/emoji/google/rose.png differ diff --git a/public/images/emoji/google/rosette.png b/public/images/emoji/google/rosette.png new file mode 100644 index 00000000000..dc5b0ff48c7 Binary files /dev/null and b/public/images/emoji/google/rosette.png differ diff --git a/public/images/emoji/google/rotating_light.png b/public/images/emoji/google/rotating_light.png index 3481fa444fd..aa74d8b4526 100644 Binary files a/public/images/emoji/google/rotating_light.png and b/public/images/emoji/google/rotating_light.png differ diff --git a/public/images/emoji/google/round_pushpin.png b/public/images/emoji/google/round_pushpin.png index 99d774b2dc0..1c44fe11572 100644 Binary files a/public/images/emoji/google/round_pushpin.png and b/public/images/emoji/google/round_pushpin.png differ diff --git a/public/images/emoji/google/rowboat.png b/public/images/emoji/google/rowboat.png index bcef277f1dc..3022bf7c28f 100644 Binary files a/public/images/emoji/google/rowboat.png and b/public/images/emoji/google/rowboat.png differ diff --git a/public/images/emoji/google/ru.png b/public/images/emoji/google/ru.png index d7db8a6d22c..548095e2997 100644 Binary files a/public/images/emoji/google/ru.png and b/public/images/emoji/google/ru.png differ diff --git a/public/images/emoji/google/rugby_football.png b/public/images/emoji/google/rugby_football.png index 5494fc9a7b9..ee135818989 100644 Binary files a/public/images/emoji/google/rugby_football.png and b/public/images/emoji/google/rugby_football.png differ diff --git a/public/images/emoji/google/runner.png b/public/images/emoji/google/runner.png index af6a23e44cd..823d6401a5a 100644 Binary files a/public/images/emoji/google/runner.png and b/public/images/emoji/google/runner.png differ diff --git a/public/images/emoji/google/running.png b/public/images/emoji/google/running.png index af6a23e44cd..363d1e03830 100644 Binary files a/public/images/emoji/google/running.png and b/public/images/emoji/google/running.png differ diff --git a/public/images/emoji/google/running_shirt_with_sash.png b/public/images/emoji/google/running_shirt_with_sash.png index 1c8f965330b..d1abede732e 100644 Binary files a/public/images/emoji/google/running_shirt_with_sash.png and b/public/images/emoji/google/running_shirt_with_sash.png differ diff --git a/public/images/emoji/google/sa.png b/public/images/emoji/google/sa.png index 393ac91d549..71b95b60519 100644 Binary files a/public/images/emoji/google/sa.png and b/public/images/emoji/google/sa.png differ diff --git a/public/images/emoji/google/sagittarius.png b/public/images/emoji/google/sagittarius.png index 3f5adbcfdb2..e29edf425fb 100644 Binary files a/public/images/emoji/google/sagittarius.png and b/public/images/emoji/google/sagittarius.png differ diff --git a/public/images/emoji/google/sailboat.png b/public/images/emoji/google/sailboat.png index 1a34dcba48d..1cfc123705e 100644 Binary files a/public/images/emoji/google/sailboat.png and b/public/images/emoji/google/sailboat.png differ diff --git a/public/images/emoji/google/sake.png b/public/images/emoji/google/sake.png index 259c4a5bc41..95e1f03a3b7 100644 Binary files a/public/images/emoji/google/sake.png and b/public/images/emoji/google/sake.png differ diff --git a/public/images/emoji/google/sandal.png b/public/images/emoji/google/sandal.png index 16548990b2a..9f4cfeba826 100644 Binary files a/public/images/emoji/google/sandal.png and b/public/images/emoji/google/sandal.png differ diff --git a/public/images/emoji/google/santa.png b/public/images/emoji/google/santa.png index 66076b595e3..e6a5e4a7316 100644 Binary files a/public/images/emoji/google/santa.png and b/public/images/emoji/google/santa.png differ diff --git a/public/images/emoji/google/satellite.png b/public/images/emoji/google/satellite.png index 8c7ad353668..84de92d0e6c 100644 Binary files a/public/images/emoji/google/satellite.png and b/public/images/emoji/google/satellite.png differ diff --git a/public/images/emoji/google/satellite_orbital.png b/public/images/emoji/google/satellite_orbital.png new file mode 100644 index 00000000000..a788d48b522 Binary files /dev/null and b/public/images/emoji/google/satellite_orbital.png differ diff --git a/public/images/emoji/google/satisfied.png b/public/images/emoji/google/satisfied.png index 8265a2e20c3..2b103d44587 100644 Binary files a/public/images/emoji/google/satisfied.png and b/public/images/emoji/google/satisfied.png differ diff --git a/public/images/emoji/google/saxophone.png b/public/images/emoji/google/saxophone.png index 688a0e23434..8b26176a5d2 100644 Binary files a/public/images/emoji/google/saxophone.png and b/public/images/emoji/google/saxophone.png differ diff --git a/public/images/emoji/google/scales.png b/public/images/emoji/google/scales.png new file mode 100644 index 00000000000..dea79c41218 Binary files /dev/null and b/public/images/emoji/google/scales.png differ diff --git a/public/images/emoji/google/school.png b/public/images/emoji/google/school.png index 1f1fe610ad1..15eb1d600ea 100644 Binary files a/public/images/emoji/google/school.png and b/public/images/emoji/google/school.png differ diff --git a/public/images/emoji/google/school_satchel.png b/public/images/emoji/google/school_satchel.png index bf4abcb2a15..6812b8816c6 100644 Binary files a/public/images/emoji/google/school_satchel.png and b/public/images/emoji/google/school_satchel.png differ diff --git a/public/images/emoji/google/scissors.png b/public/images/emoji/google/scissors.png index 95659681b7d..d3357076f44 100644 Binary files a/public/images/emoji/google/scissors.png and b/public/images/emoji/google/scissors.png differ diff --git a/public/images/emoji/google/scorpion.png b/public/images/emoji/google/scorpion.png new file mode 100644 index 00000000000..d8ac29bdf97 Binary files /dev/null and b/public/images/emoji/google/scorpion.png differ diff --git a/public/images/emoji/google/scorpius.png b/public/images/emoji/google/scorpius.png index e02f2f99c36..7eee6b0f24e 100644 Binary files a/public/images/emoji/google/scorpius.png and b/public/images/emoji/google/scorpius.png differ diff --git a/public/images/emoji/google/scream.png b/public/images/emoji/google/scream.png index d8f44d95e08..cb6c289f197 100644 Binary files a/public/images/emoji/google/scream.png and b/public/images/emoji/google/scream.png differ diff --git a/public/images/emoji/google/scream_cat.png b/public/images/emoji/google/scream_cat.png index c472c67a7d8..887035958c7 100644 Binary files a/public/images/emoji/google/scream_cat.png and b/public/images/emoji/google/scream_cat.png differ diff --git a/public/images/emoji/google/scroll.png b/public/images/emoji/google/scroll.png index 8c07ec25ec0..6abd6ab9bed 100644 Binary files a/public/images/emoji/google/scroll.png and b/public/images/emoji/google/scroll.png differ diff --git a/public/images/emoji/google/seat.png b/public/images/emoji/google/seat.png index 7248d889d74..0c77cc4ce98 100644 Binary files a/public/images/emoji/google/seat.png and b/public/images/emoji/google/seat.png differ diff --git a/public/images/emoji/google/secret.png b/public/images/emoji/google/secret.png index 71399b9030c..97feace14aa 100644 Binary files a/public/images/emoji/google/secret.png and b/public/images/emoji/google/secret.png differ diff --git a/public/images/emoji/google/see_no_evil.png b/public/images/emoji/google/see_no_evil.png index db583b81ff4..27fe6e1b6d6 100644 Binary files a/public/images/emoji/google/see_no_evil.png and b/public/images/emoji/google/see_no_evil.png differ diff --git a/public/images/emoji/google/seedling.png b/public/images/emoji/google/seedling.png index f349d7ab5b0..742a2558478 100644 Binary files a/public/images/emoji/google/seedling.png and b/public/images/emoji/google/seedling.png differ diff --git a/public/images/emoji/google/seven.png b/public/images/emoji/google/seven.png index b244dbc2918..881f256b001 100644 Binary files a/public/images/emoji/google/seven.png and b/public/images/emoji/google/seven.png differ diff --git a/public/images/emoji/google/shamrock.png b/public/images/emoji/google/shamrock.png new file mode 100644 index 00000000000..e5c458477ed Binary files /dev/null and b/public/images/emoji/google/shamrock.png differ diff --git a/public/images/emoji/google/shaved_ice.png b/public/images/emoji/google/shaved_ice.png index 0aecf2373a5..81a0917f2b3 100644 Binary files a/public/images/emoji/google/shaved_ice.png and b/public/images/emoji/google/shaved_ice.png differ diff --git a/public/images/emoji/google/sheep.png b/public/images/emoji/google/sheep.png index af3e6fd9d4c..d51a3094a6a 100644 Binary files a/public/images/emoji/google/sheep.png and b/public/images/emoji/google/sheep.png differ diff --git a/public/images/emoji/google/shell.png b/public/images/emoji/google/shell.png index 4a253dce59b..2fb016b7b62 100644 Binary files a/public/images/emoji/google/shell.png and b/public/images/emoji/google/shell.png differ diff --git a/public/images/emoji/google/shield.png b/public/images/emoji/google/shield.png new file mode 100644 index 00000000000..8a69eef1369 Binary files /dev/null and b/public/images/emoji/google/shield.png differ diff --git a/public/images/emoji/google/shinto_shrine.png b/public/images/emoji/google/shinto_shrine.png new file mode 100644 index 00000000000..bd55e6fb8a2 Binary files /dev/null and b/public/images/emoji/google/shinto_shrine.png differ diff --git a/public/images/emoji/google/ship.png b/public/images/emoji/google/ship.png index 9bbd3498f32..de974ca63c3 100644 Binary files a/public/images/emoji/google/ship.png and b/public/images/emoji/google/ship.png differ diff --git a/public/images/emoji/google/shirt.png b/public/images/emoji/google/shirt.png index cb0fd1dd087..051cec30679 100644 Binary files a/public/images/emoji/google/shirt.png and b/public/images/emoji/google/shirt.png differ diff --git a/public/images/emoji/google/shit.png b/public/images/emoji/google/shit.png index 61b946b0c3c..0ecd8e2887a 100644 Binary files a/public/images/emoji/google/shit.png and b/public/images/emoji/google/shit.png differ diff --git a/public/images/emoji/google/shoe.png b/public/images/emoji/google/shoe.png index 9c811a82bda..da65794f8ae 100644 Binary files a/public/images/emoji/google/shoe.png and b/public/images/emoji/google/shoe.png differ diff --git a/public/images/emoji/google/shopping_bags.png b/public/images/emoji/google/shopping_bags.png new file mode 100644 index 00000000000..cff8a39cbd2 Binary files /dev/null and b/public/images/emoji/google/shopping_bags.png differ diff --git a/public/images/emoji/google/shower.png b/public/images/emoji/google/shower.png index 339975ab73f..72cf68084a5 100644 Binary files a/public/images/emoji/google/shower.png and b/public/images/emoji/google/shower.png differ diff --git a/public/images/emoji/google/signal_strength.png b/public/images/emoji/google/signal_strength.png index 6b69fbc8cb7..9bc5ef931b8 100644 Binary files a/public/images/emoji/google/signal_strength.png and b/public/images/emoji/google/signal_strength.png differ diff --git a/public/images/emoji/google/six.png b/public/images/emoji/google/six.png index 08c6a283037..5d38067263e 100644 Binary files a/public/images/emoji/google/six.png and b/public/images/emoji/google/six.png differ diff --git a/public/images/emoji/google/six_pointed_star.png b/public/images/emoji/google/six_pointed_star.png index 32e74c8f72c..3e4da5eb89f 100644 Binary files a/public/images/emoji/google/six_pointed_star.png and b/public/images/emoji/google/six_pointed_star.png differ diff --git a/public/images/emoji/google/ski.png b/public/images/emoji/google/ski.png index 47d1fecc7c1..c948531552f 100644 Binary files a/public/images/emoji/google/ski.png and b/public/images/emoji/google/ski.png differ diff --git a/public/images/emoji/google/skier.png b/public/images/emoji/google/skier.png new file mode 100644 index 00000000000..9407ff34972 Binary files /dev/null and b/public/images/emoji/google/skier.png differ diff --git a/public/images/emoji/google/skull.png b/public/images/emoji/google/skull.png index 120d72188f6..f29d8292836 100644 Binary files a/public/images/emoji/google/skull.png and b/public/images/emoji/google/skull.png differ diff --git a/public/images/emoji/google/skull_crossbones.png b/public/images/emoji/google/skull_crossbones.png new file mode 100644 index 00000000000..f3f0d910d8b Binary files /dev/null and b/public/images/emoji/google/skull_crossbones.png differ diff --git a/public/images/emoji/google/sleeping.png b/public/images/emoji/google/sleeping.png index c610c05e818..ac834e3bff0 100644 Binary files a/public/images/emoji/google/sleeping.png and b/public/images/emoji/google/sleeping.png differ diff --git a/public/images/emoji/google/sleeping_accommodation.png b/public/images/emoji/google/sleeping_accommodation.png new file mode 100644 index 00000000000..c6344e1f870 Binary files /dev/null and b/public/images/emoji/google/sleeping_accommodation.png differ diff --git a/public/images/emoji/google/sleepy.png b/public/images/emoji/google/sleepy.png index 3b85d64ad76..8f2cc113af7 100644 Binary files a/public/images/emoji/google/sleepy.png and b/public/images/emoji/google/sleepy.png differ diff --git a/public/images/emoji/google/slight_frown.png b/public/images/emoji/google/slight_frown.png new file mode 100644 index 00000000000..56816d49540 Binary files /dev/null and b/public/images/emoji/google/slight_frown.png differ diff --git a/public/images/emoji/google/slight_smile.png b/public/images/emoji/google/slight_smile.png new file mode 100644 index 00000000000..7fbc5699e52 Binary files /dev/null and b/public/images/emoji/google/slight_smile.png differ diff --git a/public/images/emoji/google/slightly_smiling.png b/public/images/emoji/google/slightly_smiling.png new file mode 100644 index 00000000000..6d60982f555 Binary files /dev/null and b/public/images/emoji/google/slightly_smiling.png differ diff --git a/public/images/emoji/google/slot_machine.png b/public/images/emoji/google/slot_machine.png index 7918b10a877..9ccc3f4454e 100644 Binary files a/public/images/emoji/google/slot_machine.png and b/public/images/emoji/google/slot_machine.png differ diff --git a/public/images/emoji/google/small_blue_diamond.png b/public/images/emoji/google/small_blue_diamond.png index 75aa555d39d..508814dd7c3 100644 Binary files a/public/images/emoji/google/small_blue_diamond.png and b/public/images/emoji/google/small_blue_diamond.png differ diff --git a/public/images/emoji/google/small_orange_diamond.png b/public/images/emoji/google/small_orange_diamond.png index 95a93da54e5..5ca29abfa6f 100644 Binary files a/public/images/emoji/google/small_orange_diamond.png and b/public/images/emoji/google/small_orange_diamond.png differ diff --git a/public/images/emoji/google/small_red_triangle.png b/public/images/emoji/google/small_red_triangle.png index b9b2819103e..d79c7b05541 100644 Binary files a/public/images/emoji/google/small_red_triangle.png and b/public/images/emoji/google/small_red_triangle.png differ diff --git a/public/images/emoji/google/small_red_triangle_down.png b/public/images/emoji/google/small_red_triangle_down.png index 6c039f7f5c1..e7f2bbb56dd 100644 Binary files a/public/images/emoji/google/small_red_triangle_down.png and b/public/images/emoji/google/small_red_triangle_down.png differ diff --git a/public/images/emoji/google/smile.png b/public/images/emoji/google/smile.png index ba9476ed850..72a201593fa 100644 Binary files a/public/images/emoji/google/smile.png and b/public/images/emoji/google/smile.png differ diff --git a/public/images/emoji/google/smile_cat.png b/public/images/emoji/google/smile_cat.png index 8aff6c23643..892b57fa7c6 100644 Binary files a/public/images/emoji/google/smile_cat.png and b/public/images/emoji/google/smile_cat.png differ diff --git a/public/images/emoji/google/smiley.png b/public/images/emoji/google/smiley.png index 68b715e6264..f918220d80d 100644 Binary files a/public/images/emoji/google/smiley.png and b/public/images/emoji/google/smiley.png differ diff --git a/public/images/emoji/google/smiley_cat.png b/public/images/emoji/google/smiley_cat.png index e4a568cb27b..19bd40d9ad7 100644 Binary files a/public/images/emoji/google/smiley_cat.png and b/public/images/emoji/google/smiley_cat.png differ diff --git a/public/images/emoji/google/smiling_imp.png b/public/images/emoji/google/smiling_imp.png index 426ac8713f5..1efd62d661e 100644 Binary files a/public/images/emoji/google/smiling_imp.png and b/public/images/emoji/google/smiling_imp.png differ diff --git a/public/images/emoji/google/smirk.png b/public/images/emoji/google/smirk.png index f4eb5c89861..d5d0cfb98ff 100644 Binary files a/public/images/emoji/google/smirk.png and b/public/images/emoji/google/smirk.png differ diff --git a/public/images/emoji/google/smirk_cat.png b/public/images/emoji/google/smirk_cat.png index fd67cc8f30b..a56009a738a 100644 Binary files a/public/images/emoji/google/smirk_cat.png and b/public/images/emoji/google/smirk_cat.png differ diff --git a/public/images/emoji/google/smoking.png b/public/images/emoji/google/smoking.png index 5a71169dcb3..3f35ba10a4b 100644 Binary files a/public/images/emoji/google/smoking.png and b/public/images/emoji/google/smoking.png differ diff --git a/public/images/emoji/google/snail.png b/public/images/emoji/google/snail.png index a5b877b60db..b150526c3f9 100644 Binary files a/public/images/emoji/google/snail.png and b/public/images/emoji/google/snail.png differ diff --git a/public/images/emoji/google/snake.png b/public/images/emoji/google/snake.png index 91900d3f376..be5116ef39a 100644 Binary files a/public/images/emoji/google/snake.png and b/public/images/emoji/google/snake.png differ diff --git a/public/images/emoji/google/snowboarder.png b/public/images/emoji/google/snowboarder.png index 087134fbeca..e40ed37a85b 100644 Binary files a/public/images/emoji/google/snowboarder.png and b/public/images/emoji/google/snowboarder.png differ diff --git a/public/images/emoji/google/snowflake.png b/public/images/emoji/google/snowflake.png index 750a022686e..a8f49d5d72e 100644 Binary files a/public/images/emoji/google/snowflake.png and b/public/images/emoji/google/snowflake.png differ diff --git a/public/images/emoji/google/snowman.png b/public/images/emoji/google/snowman.png index 5ab294556d4..19d2e872d77 100644 Binary files a/public/images/emoji/google/snowman.png and b/public/images/emoji/google/snowman.png differ diff --git a/public/images/emoji/google/snowman2.png b/public/images/emoji/google/snowman2.png new file mode 100644 index 00000000000..5e1b3c3287b Binary files /dev/null and b/public/images/emoji/google/snowman2.png differ diff --git a/public/images/emoji/google/sob.png b/public/images/emoji/google/sob.png index 818f19f6072..b1c70b329d7 100644 Binary files a/public/images/emoji/google/sob.png and b/public/images/emoji/google/sob.png differ diff --git a/public/images/emoji/google/soccer.png b/public/images/emoji/google/soccer.png index 70c8be05106..0c755e8e262 100644 Binary files a/public/images/emoji/google/soccer.png and b/public/images/emoji/google/soccer.png differ diff --git a/public/images/emoji/google/soon.png b/public/images/emoji/google/soon.png index 12ffedaa28a..ae202f17d8b 100644 Binary files a/public/images/emoji/google/soon.png and b/public/images/emoji/google/soon.png differ diff --git a/public/images/emoji/google/sos.png b/public/images/emoji/google/sos.png index 14b149c44d6..b36ca3af7a9 100644 Binary files a/public/images/emoji/google/sos.png and b/public/images/emoji/google/sos.png differ diff --git a/public/images/emoji/google/sound.png b/public/images/emoji/google/sound.png index 93c2660fabe..29cd8898dfe 100644 Binary files a/public/images/emoji/google/sound.png and b/public/images/emoji/google/sound.png differ diff --git a/public/images/emoji/google/space_invader.png b/public/images/emoji/google/space_invader.png index 76175a55754..1340a639bc1 100644 Binary files a/public/images/emoji/google/space_invader.png and b/public/images/emoji/google/space_invader.png differ diff --git a/public/images/emoji/google/spades.png b/public/images/emoji/google/spades.png index 410d28af684..235a8874020 100644 Binary files a/public/images/emoji/google/spades.png and b/public/images/emoji/google/spades.png differ diff --git a/public/images/emoji/google/spaghetti.png b/public/images/emoji/google/spaghetti.png index 5998902ccca..5c8c7d58291 100644 Binary files a/public/images/emoji/google/spaghetti.png and b/public/images/emoji/google/spaghetti.png differ diff --git a/public/images/emoji/google/sparkle.png b/public/images/emoji/google/sparkle.png index f40a3af355e..5857d961839 100644 Binary files a/public/images/emoji/google/sparkle.png and b/public/images/emoji/google/sparkle.png differ diff --git a/public/images/emoji/google/sparkler.png b/public/images/emoji/google/sparkler.png index b8fcaf8d8cb..6d8ed0835b8 100644 Binary files a/public/images/emoji/google/sparkler.png and b/public/images/emoji/google/sparkler.png differ diff --git a/public/images/emoji/google/sparkles.png b/public/images/emoji/google/sparkles.png index a62c4161e4f..1b232a0c250 100644 Binary files a/public/images/emoji/google/sparkles.png and b/public/images/emoji/google/sparkles.png differ diff --git a/public/images/emoji/google/sparkling_heart.png b/public/images/emoji/google/sparkling_heart.png index e79f23170bc..532a3caa6ce 100644 Binary files a/public/images/emoji/google/sparkling_heart.png and b/public/images/emoji/google/sparkling_heart.png differ diff --git a/public/images/emoji/google/speak_no_evil.png b/public/images/emoji/google/speak_no_evil.png index 7e3e1ec495c..887d3c049dc 100644 Binary files a/public/images/emoji/google/speak_no_evil.png and b/public/images/emoji/google/speak_no_evil.png differ diff --git a/public/images/emoji/google/speaker.png b/public/images/emoji/google/speaker.png index 05c1af37a5c..64667a8f2a0 100644 Binary files a/public/images/emoji/google/speaker.png and b/public/images/emoji/google/speaker.png differ diff --git a/public/images/emoji/google/speaking_head.png b/public/images/emoji/google/speaking_head.png new file mode 100644 index 00000000000..3df8c91a9b4 Binary files /dev/null and b/public/images/emoji/google/speaking_head.png differ diff --git a/public/images/emoji/google/speech_balloon.png b/public/images/emoji/google/speech_balloon.png index 53e4d4ed84d..154f295baaa 100644 Binary files a/public/images/emoji/google/speech_balloon.png and b/public/images/emoji/google/speech_balloon.png differ diff --git a/public/images/emoji/google/speedboat.png b/public/images/emoji/google/speedboat.png index 10f8200d23a..7b0f825774a 100644 Binary files a/public/images/emoji/google/speedboat.png and b/public/images/emoji/google/speedboat.png differ diff --git a/public/images/emoji/google/spider.png b/public/images/emoji/google/spider.png new file mode 100644 index 00000000000..6441b957f17 Binary files /dev/null and b/public/images/emoji/google/spider.png differ diff --git a/public/images/emoji/google/spider_web.png b/public/images/emoji/google/spider_web.png new file mode 100644 index 00000000000..89dff1e576f Binary files /dev/null and b/public/images/emoji/google/spider_web.png differ diff --git a/public/images/emoji/google/spy.png b/public/images/emoji/google/spy.png new file mode 100644 index 00000000000..fc5d8db4a8a Binary files /dev/null and b/public/images/emoji/google/spy.png differ diff --git a/public/images/emoji/google/stadium.png b/public/images/emoji/google/stadium.png new file mode 100644 index 00000000000..55151d4b416 Binary files /dev/null and b/public/images/emoji/google/stadium.png differ diff --git a/public/images/emoji/google/star.png b/public/images/emoji/google/star.png index db351e9c010..24cd3d17e1b 100644 Binary files a/public/images/emoji/google/star.png and b/public/images/emoji/google/star.png differ diff --git a/public/images/emoji/google/star2.png b/public/images/emoji/google/star2.png index b74aaae1d18..80932575b27 100644 Binary files a/public/images/emoji/google/star2.png and b/public/images/emoji/google/star2.png differ diff --git a/public/images/emoji/google/star_and_crescent.png b/public/images/emoji/google/star_and_crescent.png new file mode 100644 index 00000000000..d653df867f2 Binary files /dev/null and b/public/images/emoji/google/star_and_crescent.png differ diff --git a/public/images/emoji/google/star_of_david.png b/public/images/emoji/google/star_of_david.png new file mode 100644 index 00000000000..7109e573ed7 Binary files /dev/null and b/public/images/emoji/google/star_of_david.png differ diff --git a/public/images/emoji/google/stars.png b/public/images/emoji/google/stars.png index 13788ae007d..893c56950f5 100644 Binary files a/public/images/emoji/google/stars.png and b/public/images/emoji/google/stars.png differ diff --git a/public/images/emoji/google/station.png b/public/images/emoji/google/station.png index b0a0f2071f0..706f1609b35 100644 Binary files a/public/images/emoji/google/station.png and b/public/images/emoji/google/station.png differ diff --git a/public/images/emoji/google/statue_of_liberty.png b/public/images/emoji/google/statue_of_liberty.png index f87a30b6722..a381be3c7d2 100644 Binary files a/public/images/emoji/google/statue_of_liberty.png and b/public/images/emoji/google/statue_of_liberty.png differ diff --git a/public/images/emoji/google/steam_locomotive.png b/public/images/emoji/google/steam_locomotive.png index 1d45d39f463..9a4cdb37346 100644 Binary files a/public/images/emoji/google/steam_locomotive.png and b/public/images/emoji/google/steam_locomotive.png differ diff --git a/public/images/emoji/google/stew.png b/public/images/emoji/google/stew.png index 46e5a246681..81fee11ae90 100644 Binary files a/public/images/emoji/google/stew.png and b/public/images/emoji/google/stew.png differ diff --git a/public/images/emoji/google/stop_button.png b/public/images/emoji/google/stop_button.png new file mode 100644 index 00000000000..cd00a6dd939 Binary files /dev/null and b/public/images/emoji/google/stop_button.png differ diff --git a/public/images/emoji/google/stopwatch.png b/public/images/emoji/google/stopwatch.png new file mode 100644 index 00000000000..10e6d920193 Binary files /dev/null and b/public/images/emoji/google/stopwatch.png differ diff --git a/public/images/emoji/google/straight_ruler.png b/public/images/emoji/google/straight_ruler.png index 1c518f9fa6a..7b639013e64 100644 Binary files a/public/images/emoji/google/straight_ruler.png and b/public/images/emoji/google/straight_ruler.png differ diff --git a/public/images/emoji/google/strawberry.png b/public/images/emoji/google/strawberry.png index deec02d51c3..d5719c48213 100644 Binary files a/public/images/emoji/google/strawberry.png and b/public/images/emoji/google/strawberry.png differ diff --git a/public/images/emoji/google/stuck_out_tongue.png b/public/images/emoji/google/stuck_out_tongue.png index 905eedb300e..86ba2f554b8 100644 Binary files a/public/images/emoji/google/stuck_out_tongue.png and b/public/images/emoji/google/stuck_out_tongue.png differ diff --git a/public/images/emoji/google/stuck_out_tongue_closed_eyes.png b/public/images/emoji/google/stuck_out_tongue_closed_eyes.png index 66981bc17eb..387154625f3 100644 Binary files a/public/images/emoji/google/stuck_out_tongue_closed_eyes.png and b/public/images/emoji/google/stuck_out_tongue_closed_eyes.png differ diff --git a/public/images/emoji/google/stuck_out_tongue_winking_eye.png b/public/images/emoji/google/stuck_out_tongue_winking_eye.png index fb2667d3648..079c66f4613 100644 Binary files a/public/images/emoji/google/stuck_out_tongue_winking_eye.png and b/public/images/emoji/google/stuck_out_tongue_winking_eye.png differ diff --git a/public/images/emoji/google/sun_with_face.png b/public/images/emoji/google/sun_with_face.png index 047bf940e12..ac7a4e73169 100644 Binary files a/public/images/emoji/google/sun_with_face.png and b/public/images/emoji/google/sun_with_face.png differ diff --git a/public/images/emoji/google/sunflower.png b/public/images/emoji/google/sunflower.png index 3ae96689b32..a79b25c87d7 100644 Binary files a/public/images/emoji/google/sunflower.png and b/public/images/emoji/google/sunflower.png differ diff --git a/public/images/emoji/google/sunglasses.png b/public/images/emoji/google/sunglasses.png index 2603a2c9d0c..e9724a3a25c 100644 Binary files a/public/images/emoji/google/sunglasses.png and b/public/images/emoji/google/sunglasses.png differ diff --git a/public/images/emoji/google/sunny.png b/public/images/emoji/google/sunny.png index 7976bb50a77..c9effb9bd4f 100644 Binary files a/public/images/emoji/google/sunny.png and b/public/images/emoji/google/sunny.png differ diff --git a/public/images/emoji/google/sunrise.png b/public/images/emoji/google/sunrise.png index d82cbf70c6a..3400b8b12e3 100644 Binary files a/public/images/emoji/google/sunrise.png and b/public/images/emoji/google/sunrise.png differ diff --git a/public/images/emoji/google/sunrise_over_mountains.png b/public/images/emoji/google/sunrise_over_mountains.png index fdfea703e51..b65b7304e36 100644 Binary files a/public/images/emoji/google/sunrise_over_mountains.png and b/public/images/emoji/google/sunrise_over_mountains.png differ diff --git a/public/images/emoji/google/surfer.png b/public/images/emoji/google/surfer.png index af5fbfb251d..dc95d63003d 100644 Binary files a/public/images/emoji/google/surfer.png and b/public/images/emoji/google/surfer.png differ diff --git a/public/images/emoji/google/sushi.png b/public/images/emoji/google/sushi.png index 88a4f1b3cab..6c945b5ed2e 100644 Binary files a/public/images/emoji/google/sushi.png and b/public/images/emoji/google/sushi.png differ diff --git a/public/images/emoji/google/suspension_railway.png b/public/images/emoji/google/suspension_railway.png index b0abb8761d8..2fcab0e0d86 100644 Binary files a/public/images/emoji/google/suspension_railway.png and b/public/images/emoji/google/suspension_railway.png differ diff --git a/public/images/emoji/google/sweat.png b/public/images/emoji/google/sweat.png index f59c14b3d92..4ab69a17e3f 100644 Binary files a/public/images/emoji/google/sweat.png and b/public/images/emoji/google/sweat.png differ diff --git a/public/images/emoji/google/sweat_drops.png b/public/images/emoji/google/sweat_drops.png index b711c631a59..431f430af75 100644 Binary files a/public/images/emoji/google/sweat_drops.png and b/public/images/emoji/google/sweat_drops.png differ diff --git a/public/images/emoji/google/sweat_smile.png b/public/images/emoji/google/sweat_smile.png index f75f054d976..c4b0bc9e68f 100644 Binary files a/public/images/emoji/google/sweat_smile.png and b/public/images/emoji/google/sweat_smile.png differ diff --git a/public/images/emoji/google/sweet_potato.png b/public/images/emoji/google/sweet_potato.png index c55a85a2e3f..a3ebfa33bd7 100644 Binary files a/public/images/emoji/google/sweet_potato.png and b/public/images/emoji/google/sweet_potato.png differ diff --git a/public/images/emoji/google/swimmer.png b/public/images/emoji/google/swimmer.png index 6c02ad04715..c873f8819ef 100644 Binary files a/public/images/emoji/google/swimmer.png and b/public/images/emoji/google/swimmer.png differ diff --git a/public/images/emoji/google/symbols.png b/public/images/emoji/google/symbols.png index 1079a745e88..420ad7e401d 100644 Binary files a/public/images/emoji/google/symbols.png and b/public/images/emoji/google/symbols.png differ diff --git a/public/images/emoji/google/synagogue.png b/public/images/emoji/google/synagogue.png new file mode 100644 index 00000000000..9ab7aac9735 Binary files /dev/null and b/public/images/emoji/google/synagogue.png differ diff --git a/public/images/emoji/google/syringe.png b/public/images/emoji/google/syringe.png index 921249967ed..a396d75dd90 100644 Binary files a/public/images/emoji/google/syringe.png and b/public/images/emoji/google/syringe.png differ diff --git a/public/images/emoji/google/taco.png b/public/images/emoji/google/taco.png new file mode 100644 index 00000000000..880e316f837 Binary files /dev/null and b/public/images/emoji/google/taco.png differ diff --git a/public/images/emoji/google/tada.png b/public/images/emoji/google/tada.png index b2922e39c31..d3351387f49 100644 Binary files a/public/images/emoji/google/tada.png and b/public/images/emoji/google/tada.png differ diff --git a/public/images/emoji/google/tanabata_tree.png b/public/images/emoji/google/tanabata_tree.png index 9b7d1157665..ab7876a7f60 100644 Binary files a/public/images/emoji/google/tanabata_tree.png and b/public/images/emoji/google/tanabata_tree.png differ diff --git a/public/images/emoji/google/tangerine.png b/public/images/emoji/google/tangerine.png index efdacb0598a..ca61f4a1e77 100644 Binary files a/public/images/emoji/google/tangerine.png and b/public/images/emoji/google/tangerine.png differ diff --git a/public/images/emoji/google/taurus.png b/public/images/emoji/google/taurus.png index 1c3f9cfc13b..55b0d8d23ee 100644 Binary files a/public/images/emoji/google/taurus.png and b/public/images/emoji/google/taurus.png differ diff --git a/public/images/emoji/google/taxi.png b/public/images/emoji/google/taxi.png index 13c7dcace7a..8c6394b05b4 100644 Binary files a/public/images/emoji/google/taxi.png and b/public/images/emoji/google/taxi.png differ diff --git a/public/images/emoji/google/tea.png b/public/images/emoji/google/tea.png index bd0cc6ac9f1..e4541114663 100644 Binary files a/public/images/emoji/google/tea.png and b/public/images/emoji/google/tea.png differ diff --git a/public/images/emoji/google/telephone.png b/public/images/emoji/google/telephone.png index a775ccf56f1..f836f52cc8b 100644 Binary files a/public/images/emoji/google/telephone.png and b/public/images/emoji/google/telephone.png differ diff --git a/public/images/emoji/google/telephone_receiver.png b/public/images/emoji/google/telephone_receiver.png index 28d73fd5949..4b686ecd1bd 100644 Binary files a/public/images/emoji/google/telephone_receiver.png and b/public/images/emoji/google/telephone_receiver.png differ diff --git a/public/images/emoji/google/telescope.png b/public/images/emoji/google/telescope.png index dc453d9476c..444f870bff0 100644 Binary files a/public/images/emoji/google/telescope.png and b/public/images/emoji/google/telescope.png differ diff --git a/public/images/emoji/google/ten.png b/public/images/emoji/google/ten.png new file mode 100644 index 00000000000..43c3ab79a36 Binary files /dev/null and b/public/images/emoji/google/ten.png differ diff --git a/public/images/emoji/google/tennis.png b/public/images/emoji/google/tennis.png index f97c711ddf5..29c95e20186 100644 Binary files a/public/images/emoji/google/tennis.png and b/public/images/emoji/google/tennis.png differ diff --git a/public/images/emoji/google/tent.png b/public/images/emoji/google/tent.png index c525883b1b2..dd32e9ccb60 100644 Binary files a/public/images/emoji/google/tent.png and b/public/images/emoji/google/tent.png differ diff --git a/public/images/emoji/google/thermometer.png b/public/images/emoji/google/thermometer.png new file mode 100644 index 00000000000..f5fd7cb0b64 Binary files /dev/null and b/public/images/emoji/google/thermometer.png differ diff --git a/public/images/emoji/google/thermometer_face.png b/public/images/emoji/google/thermometer_face.png new file mode 100644 index 00000000000..c83df33be89 Binary files /dev/null and b/public/images/emoji/google/thermometer_face.png differ diff --git a/public/images/emoji/google/thinking.png b/public/images/emoji/google/thinking.png new file mode 100644 index 00000000000..ffdaf974ae8 Binary files /dev/null and b/public/images/emoji/google/thinking.png differ diff --git a/public/images/emoji/google/thought_balloon.png b/public/images/emoji/google/thought_balloon.png index 07d9bd70cca..e1880329004 100644 Binary files a/public/images/emoji/google/thought_balloon.png and b/public/images/emoji/google/thought_balloon.png differ diff --git a/public/images/emoji/google/thumbsdown.png b/public/images/emoji/google/thumbsdown.png index bd9730bfa4a..de239d21ea3 100644 Binary files a/public/images/emoji/google/thumbsdown.png and b/public/images/emoji/google/thumbsdown.png differ diff --git a/public/images/emoji/google/thunder_cloud_rain.png b/public/images/emoji/google/thunder_cloud_rain.png new file mode 100644 index 00000000000..4bf859a12de Binary files /dev/null and b/public/images/emoji/google/thunder_cloud_rain.png differ diff --git a/public/images/emoji/google/ticket.png b/public/images/emoji/google/ticket.png index 318adbc2c8f..aa02a6f725d 100644 Binary files a/public/images/emoji/google/ticket.png and b/public/images/emoji/google/ticket.png differ diff --git a/public/images/emoji/google/tickets.png b/public/images/emoji/google/tickets.png new file mode 100644 index 00000000000..c61d207c75c Binary files /dev/null and b/public/images/emoji/google/tickets.png differ diff --git a/public/images/emoji/google/tiger.png b/public/images/emoji/google/tiger.png index 64d0947765f..8f1f65c72c8 100644 Binary files a/public/images/emoji/google/tiger.png and b/public/images/emoji/google/tiger.png differ diff --git a/public/images/emoji/google/tiger2.png b/public/images/emoji/google/tiger2.png index d7aaff011fe..b5715daa0bb 100644 Binary files a/public/images/emoji/google/tiger2.png and b/public/images/emoji/google/tiger2.png differ diff --git a/public/images/emoji/google/timer.png b/public/images/emoji/google/timer.png new file mode 100644 index 00000000000..e504759acad Binary files /dev/null and b/public/images/emoji/google/timer.png differ diff --git a/public/images/emoji/google/tired_face.png b/public/images/emoji/google/tired_face.png index bbd28b4c9ee..f581b815429 100644 Binary files a/public/images/emoji/google/tired_face.png and b/public/images/emoji/google/tired_face.png differ diff --git a/public/images/emoji/google/tm.png b/public/images/emoji/google/tm.png index 4aba4b57d45..6fc1eb811b4 100644 Binary files a/public/images/emoji/google/tm.png and b/public/images/emoji/google/tm.png differ diff --git a/public/images/emoji/google/toilet.png b/public/images/emoji/google/toilet.png index fd3782b5b88..8b4b9d218b4 100644 Binary files a/public/images/emoji/google/toilet.png and b/public/images/emoji/google/toilet.png differ diff --git a/public/images/emoji/google/tokyo_tower.png b/public/images/emoji/google/tokyo_tower.png index 28b1c2e5e9b..4c7eaf7c201 100644 Binary files a/public/images/emoji/google/tokyo_tower.png and b/public/images/emoji/google/tokyo_tower.png differ diff --git a/public/images/emoji/google/tomato.png b/public/images/emoji/google/tomato.png index 70d6fc7aac6..fcd18f5b40e 100644 Binary files a/public/images/emoji/google/tomato.png and b/public/images/emoji/google/tomato.png differ diff --git a/public/images/emoji/google/tongue.png b/public/images/emoji/google/tongue.png index e97d3bbb559..1e66c94010c 100644 Binary files a/public/images/emoji/google/tongue.png and b/public/images/emoji/google/tongue.png differ diff --git a/public/images/emoji/google/tools.png b/public/images/emoji/google/tools.png new file mode 100644 index 00000000000..81401c5680b Binary files /dev/null and b/public/images/emoji/google/tools.png differ diff --git a/public/images/emoji/google/top.png b/public/images/emoji/google/top.png index d2797c0d25c..ddcc6d42472 100644 Binary files a/public/images/emoji/google/top.png and b/public/images/emoji/google/top.png differ diff --git a/public/images/emoji/google/tophat.png b/public/images/emoji/google/tophat.png index 208ae3a3f49..1f9279e5781 100644 Binary files a/public/images/emoji/google/tophat.png and b/public/images/emoji/google/tophat.png differ diff --git a/public/images/emoji/google/track_next.png b/public/images/emoji/google/track_next.png new file mode 100644 index 00000000000..904f3b32f4b Binary files /dev/null and b/public/images/emoji/google/track_next.png differ diff --git a/public/images/emoji/google/track_previous.png b/public/images/emoji/google/track_previous.png new file mode 100644 index 00000000000..4b2d3c48a0f Binary files /dev/null and b/public/images/emoji/google/track_previous.png differ diff --git a/public/images/emoji/google/trackball.png b/public/images/emoji/google/trackball.png new file mode 100644 index 00000000000..2de9f53c98b Binary files /dev/null and b/public/images/emoji/google/trackball.png differ diff --git a/public/images/emoji/google/tractor.png b/public/images/emoji/google/tractor.png index d343d8126b7..180d35b87d0 100644 Binary files a/public/images/emoji/google/tractor.png and b/public/images/emoji/google/tractor.png differ diff --git a/public/images/emoji/google/traffic_light.png b/public/images/emoji/google/traffic_light.png index 52a22092c01..442731ac065 100644 Binary files a/public/images/emoji/google/traffic_light.png and b/public/images/emoji/google/traffic_light.png differ diff --git a/public/images/emoji/google/train.png b/public/images/emoji/google/train.png index 3e811714552..ce48b0aaf94 100644 Binary files a/public/images/emoji/google/train.png and b/public/images/emoji/google/train.png differ diff --git a/public/images/emoji/google/train2.png b/public/images/emoji/google/train2.png index 3bacea89f35..3f3f351b8a1 100644 Binary files a/public/images/emoji/google/train2.png and b/public/images/emoji/google/train2.png differ diff --git a/public/images/emoji/google/tram.png b/public/images/emoji/google/tram.png index 318a68d7d74..bbfc78d85db 100644 Binary files a/public/images/emoji/google/tram.png and b/public/images/emoji/google/tram.png differ diff --git a/public/images/emoji/google/triangular_flag_on_post.png b/public/images/emoji/google/triangular_flag_on_post.png index 5c76e1f5a20..bdb0295c243 100644 Binary files a/public/images/emoji/google/triangular_flag_on_post.png and b/public/images/emoji/google/triangular_flag_on_post.png differ diff --git a/public/images/emoji/google/triangular_ruler.png b/public/images/emoji/google/triangular_ruler.png index 813b4025d8c..b71b344c065 100644 Binary files a/public/images/emoji/google/triangular_ruler.png and b/public/images/emoji/google/triangular_ruler.png differ diff --git a/public/images/emoji/google/trident.png b/public/images/emoji/google/trident.png index 48a35be55fd..5fbbc52cc01 100644 Binary files a/public/images/emoji/google/trident.png and b/public/images/emoji/google/trident.png differ diff --git a/public/images/emoji/google/triumph.png b/public/images/emoji/google/triumph.png index 985c466483d..4aa89667e2c 100644 Binary files a/public/images/emoji/google/triumph.png and b/public/images/emoji/google/triumph.png differ diff --git a/public/images/emoji/google/trolleybus.png b/public/images/emoji/google/trolleybus.png index 686482baddc..3db220359d6 100644 Binary files a/public/images/emoji/google/trolleybus.png and b/public/images/emoji/google/trolleybus.png differ diff --git a/public/images/emoji/google/trophy.png b/public/images/emoji/google/trophy.png index 1e09a20fec2..f999e98dc49 100644 Binary files a/public/images/emoji/google/trophy.png and b/public/images/emoji/google/trophy.png differ diff --git a/public/images/emoji/google/tropical_drink.png b/public/images/emoji/google/tropical_drink.png index 37a51dad675..a81538e5bf8 100644 Binary files a/public/images/emoji/google/tropical_drink.png and b/public/images/emoji/google/tropical_drink.png differ diff --git a/public/images/emoji/google/tropical_fish.png b/public/images/emoji/google/tropical_fish.png index e86eb1c2469..f9e264ce473 100644 Binary files a/public/images/emoji/google/tropical_fish.png and b/public/images/emoji/google/tropical_fish.png differ diff --git a/public/images/emoji/google/truck.png b/public/images/emoji/google/truck.png index a765f53a00c..f8d8cb9b151 100644 Binary files a/public/images/emoji/google/truck.png and b/public/images/emoji/google/truck.png differ diff --git a/public/images/emoji/google/trumpet.png b/public/images/emoji/google/trumpet.png index a4240061950..6cd49ce2c65 100644 Binary files a/public/images/emoji/google/trumpet.png and b/public/images/emoji/google/trumpet.png differ diff --git a/public/images/emoji/google/tshirt.png b/public/images/emoji/google/tshirt.png index 004c3ae918d..c2fedf6ba3b 100644 Binary files a/public/images/emoji/google/tshirt.png and b/public/images/emoji/google/tshirt.png differ diff --git a/public/images/emoji/google/tulip.png b/public/images/emoji/google/tulip.png index b51c03e4d35..826415a4734 100644 Binary files a/public/images/emoji/google/tulip.png and b/public/images/emoji/google/tulip.png differ diff --git a/public/images/emoji/google/turkey.png b/public/images/emoji/google/turkey.png new file mode 100644 index 00000000000..ecc3d40b4c1 Binary files /dev/null and b/public/images/emoji/google/turkey.png differ diff --git a/public/images/emoji/google/turtle.png b/public/images/emoji/google/turtle.png index 1ccf443ed3d..89ca3dfa798 100644 Binary files a/public/images/emoji/google/turtle.png and b/public/images/emoji/google/turtle.png differ diff --git a/public/images/emoji/google/tv.png b/public/images/emoji/google/tv.png index 288f1678852..465a9cb2730 100644 Binary files a/public/images/emoji/google/tv.png and b/public/images/emoji/google/tv.png differ diff --git a/public/images/emoji/google/twisted_rightwards_arrows.png b/public/images/emoji/google/twisted_rightwards_arrows.png index e1ea7c6f8cd..cbd60446b7c 100644 Binary files a/public/images/emoji/google/twisted_rightwards_arrows.png and b/public/images/emoji/google/twisted_rightwards_arrows.png differ diff --git a/public/images/emoji/google/two.png b/public/images/emoji/google/two.png index dbe81f63ebc..cfbc11cec9a 100644 Binary files a/public/images/emoji/google/two.png and b/public/images/emoji/google/two.png differ diff --git a/public/images/emoji/google/two_hearts.png b/public/images/emoji/google/two_hearts.png index b636d6508dc..0be47400aec 100644 Binary files a/public/images/emoji/google/two_hearts.png and b/public/images/emoji/google/two_hearts.png differ diff --git a/public/images/emoji/google/two_men_holding_hands.png b/public/images/emoji/google/two_men_holding_hands.png index efc1c64943e..489f0e39b53 100644 Binary files a/public/images/emoji/google/two_men_holding_hands.png and b/public/images/emoji/google/two_men_holding_hands.png differ diff --git a/public/images/emoji/google/two_women_holding_hands.png b/public/images/emoji/google/two_women_holding_hands.png index 1866b86b40b..8b7ebf4280f 100644 Binary files a/public/images/emoji/google/two_women_holding_hands.png and b/public/images/emoji/google/two_women_holding_hands.png differ diff --git a/public/images/emoji/google/u5272.png b/public/images/emoji/google/u5272.png index 9c1c17efc28..b5a119b49c2 100644 Binary files a/public/images/emoji/google/u5272.png and b/public/images/emoji/google/u5272.png differ diff --git a/public/images/emoji/google/u5408.png b/public/images/emoji/google/u5408.png index 5efaab77f9f..26d434c422f 100644 Binary files a/public/images/emoji/google/u5408.png and b/public/images/emoji/google/u5408.png differ diff --git a/public/images/emoji/google/u55b6.png b/public/images/emoji/google/u55b6.png index 313eb5666d4..c306f22cacc 100644 Binary files a/public/images/emoji/google/u55b6.png and b/public/images/emoji/google/u55b6.png differ diff --git a/public/images/emoji/google/u6307.png b/public/images/emoji/google/u6307.png index 3a2e409d5c9..c512a00a049 100644 Binary files a/public/images/emoji/google/u6307.png and b/public/images/emoji/google/u6307.png differ diff --git a/public/images/emoji/google/u6708.png b/public/images/emoji/google/u6708.png index aa1d978bcd6..4c18c85f295 100644 Binary files a/public/images/emoji/google/u6708.png and b/public/images/emoji/google/u6708.png differ diff --git a/public/images/emoji/google/u6709.png b/public/images/emoji/google/u6709.png index 09d14b84903..0533bee7e70 100644 Binary files a/public/images/emoji/google/u6709.png and b/public/images/emoji/google/u6709.png differ diff --git a/public/images/emoji/google/u6e80.png b/public/images/emoji/google/u6e80.png index 48f03773c4d..577fafa86ab 100644 Binary files a/public/images/emoji/google/u6e80.png and b/public/images/emoji/google/u6e80.png differ diff --git a/public/images/emoji/google/u7121.png b/public/images/emoji/google/u7121.png index 6ffa619f434..d20c950ee1a 100644 Binary files a/public/images/emoji/google/u7121.png and b/public/images/emoji/google/u7121.png differ diff --git a/public/images/emoji/google/u7533.png b/public/images/emoji/google/u7533.png index 7b0fec5a3ca..d5f0a04450f 100644 Binary files a/public/images/emoji/google/u7533.png and b/public/images/emoji/google/u7533.png differ diff --git a/public/images/emoji/google/u7981.png b/public/images/emoji/google/u7981.png index 54bd719c373..5fd6054123e 100644 Binary files a/public/images/emoji/google/u7981.png and b/public/images/emoji/google/u7981.png differ diff --git a/public/images/emoji/google/u7a7a.png b/public/images/emoji/google/u7a7a.png index e8168130907..b0c3bcc163a 100644 Binary files a/public/images/emoji/google/u7a7a.png and b/public/images/emoji/google/u7a7a.png differ diff --git a/public/images/emoji/google/umbrella.png b/public/images/emoji/google/umbrella.png index cd669cbc204..1f61ce1088c 100644 Binary files a/public/images/emoji/google/umbrella.png and b/public/images/emoji/google/umbrella.png differ diff --git a/public/images/emoji/google/umbrella2.png b/public/images/emoji/google/umbrella2.png new file mode 100644 index 00000000000..869153d75b4 Binary files /dev/null and b/public/images/emoji/google/umbrella2.png differ diff --git a/public/images/emoji/google/unamused.png b/public/images/emoji/google/unamused.png index f29c569cfc1..07c2363684f 100644 Binary files a/public/images/emoji/google/unamused.png and b/public/images/emoji/google/unamused.png differ diff --git a/public/images/emoji/google/underage.png b/public/images/emoji/google/underage.png index c826df20968..d53f93df18a 100644 Binary files a/public/images/emoji/google/underage.png and b/public/images/emoji/google/underage.png differ diff --git a/public/images/emoji/google/unicorn.png b/public/images/emoji/google/unicorn.png new file mode 100644 index 00000000000..ffcb1839ee8 Binary files /dev/null and b/public/images/emoji/google/unicorn.png differ diff --git a/public/images/emoji/google/unlock.png b/public/images/emoji/google/unlock.png index bbc707999c5..18154a4e7d7 100644 Binary files a/public/images/emoji/google/unlock.png and b/public/images/emoji/google/unlock.png differ diff --git a/public/images/emoji/google/up.png b/public/images/emoji/google/up.png index 3626d6b8a43..5f547944eb5 100644 Binary files a/public/images/emoji/google/up.png and b/public/images/emoji/google/up.png differ diff --git a/public/images/emoji/google/upside_down.png b/public/images/emoji/google/upside_down.png new file mode 100644 index 00000000000..b0bc852137a Binary files /dev/null and b/public/images/emoji/google/upside_down.png differ diff --git a/public/images/emoji/google/urn.png b/public/images/emoji/google/urn.png new file mode 100644 index 00000000000..edc661551bb Binary files /dev/null and b/public/images/emoji/google/urn.png differ diff --git a/public/images/emoji/google/us.png b/public/images/emoji/google/us.png index ab1c5d28de3..949b41bee49 100644 Binary files a/public/images/emoji/google/us.png and b/public/images/emoji/google/us.png differ diff --git a/public/images/emoji/google/v.png b/public/images/emoji/google/v.png index 7bcb2047716..96db7d829aa 100644 Binary files a/public/images/emoji/google/v.png and b/public/images/emoji/google/v.png differ diff --git a/public/images/emoji/google/vertical_traffic_light.png b/public/images/emoji/google/vertical_traffic_light.png index 08f87fb6810..1c46e18fe15 100644 Binary files a/public/images/emoji/google/vertical_traffic_light.png and b/public/images/emoji/google/vertical_traffic_light.png differ diff --git a/public/images/emoji/google/vhs.png b/public/images/emoji/google/vhs.png index 85f80e4aa56..814f41e6cd7 100644 Binary files a/public/images/emoji/google/vhs.png and b/public/images/emoji/google/vhs.png differ diff --git a/public/images/emoji/google/vibration_mode.png b/public/images/emoji/google/vibration_mode.png index e5eb51ddd0d..8230ac8499b 100644 Binary files a/public/images/emoji/google/vibration_mode.png and b/public/images/emoji/google/vibration_mode.png differ diff --git a/public/images/emoji/google/video_camera.png b/public/images/emoji/google/video_camera.png index 133e4f9de20..23b6870e596 100644 Binary files a/public/images/emoji/google/video_camera.png and b/public/images/emoji/google/video_camera.png differ diff --git a/public/images/emoji/google/video_game.png b/public/images/emoji/google/video_game.png index 66697ce495e..289d0a64c15 100644 Binary files a/public/images/emoji/google/video_game.png and b/public/images/emoji/google/video_game.png differ diff --git a/public/images/emoji/google/violin.png b/public/images/emoji/google/violin.png index d1e3f9bc5a2..766a9ba9dbf 100644 Binary files a/public/images/emoji/google/violin.png and b/public/images/emoji/google/violin.png differ diff --git a/public/images/emoji/google/virgo.png b/public/images/emoji/google/virgo.png index 2e24c061fe1..23a810812e9 100644 Binary files a/public/images/emoji/google/virgo.png and b/public/images/emoji/google/virgo.png differ diff --git a/public/images/emoji/google/volcano.png b/public/images/emoji/google/volcano.png index f8f97c90ee4..c4e47a49d63 100644 Binary files a/public/images/emoji/google/volcano.png and b/public/images/emoji/google/volcano.png differ diff --git a/public/images/emoji/google/volleyball.png b/public/images/emoji/google/volleyball.png new file mode 100644 index 00000000000..77d998d3e9c Binary files /dev/null and b/public/images/emoji/google/volleyball.png differ diff --git a/public/images/emoji/google/vs.png b/public/images/emoji/google/vs.png index 977c7db3ec8..10d3090655b 100644 Binary files a/public/images/emoji/google/vs.png and b/public/images/emoji/google/vs.png differ diff --git a/public/images/emoji/google/vulcan.png b/public/images/emoji/google/vulcan.png new file mode 100644 index 00000000000..20cb6f2786c Binary files /dev/null and b/public/images/emoji/google/vulcan.png differ diff --git a/public/images/emoji/google/walking.png b/public/images/emoji/google/walking.png index 7dc8388449d..9331d4acb13 100644 Binary files a/public/images/emoji/google/walking.png and b/public/images/emoji/google/walking.png differ diff --git a/public/images/emoji/google/waning_crescent_moon.png b/public/images/emoji/google/waning_crescent_moon.png index 87472993a22..a47624b3bf4 100644 Binary files a/public/images/emoji/google/waning_crescent_moon.png and b/public/images/emoji/google/waning_crescent_moon.png differ diff --git a/public/images/emoji/google/waning_gibbous_moon.png b/public/images/emoji/google/waning_gibbous_moon.png index 07724889d2b..74f746277ac 100644 Binary files a/public/images/emoji/google/waning_gibbous_moon.png and b/public/images/emoji/google/waning_gibbous_moon.png differ diff --git a/public/images/emoji/google/warning.png b/public/images/emoji/google/warning.png index 15043c5a4a2..a8aae5fd4bf 100644 Binary files a/public/images/emoji/google/warning.png and b/public/images/emoji/google/warning.png differ diff --git a/public/images/emoji/google/wastebasket.png b/public/images/emoji/google/wastebasket.png new file mode 100644 index 00000000000..7064341987b Binary files /dev/null and b/public/images/emoji/google/wastebasket.png differ diff --git a/public/images/emoji/google/watch.png b/public/images/emoji/google/watch.png index 86dc4fc3d8d..cede969ee36 100644 Binary files a/public/images/emoji/google/watch.png and b/public/images/emoji/google/watch.png differ diff --git a/public/images/emoji/google/water_buffalo.png b/public/images/emoji/google/water_buffalo.png index d89bc7129a8..e087967f8eb 100644 Binary files a/public/images/emoji/google/water_buffalo.png and b/public/images/emoji/google/water_buffalo.png differ diff --git a/public/images/emoji/google/watermelon.png b/public/images/emoji/google/watermelon.png index 47d520261bb..5f8a3a607f5 100644 Binary files a/public/images/emoji/google/watermelon.png and b/public/images/emoji/google/watermelon.png differ diff --git a/public/images/emoji/google/wave.png b/public/images/emoji/google/wave.png index 63d03f7ae1b..6affbedda84 100644 Binary files a/public/images/emoji/google/wave.png and b/public/images/emoji/google/wave.png differ diff --git a/public/images/emoji/google/wavy_dash.png b/public/images/emoji/google/wavy_dash.png index ea0f2a1ecf9..5a5a24f803e 100644 Binary files a/public/images/emoji/google/wavy_dash.png and b/public/images/emoji/google/wavy_dash.png differ diff --git a/public/images/emoji/google/waxing_crescent_moon.png b/public/images/emoji/google/waxing_crescent_moon.png index 76c00692943..d9403412d69 100644 Binary files a/public/images/emoji/google/waxing_crescent_moon.png and b/public/images/emoji/google/waxing_crescent_moon.png differ diff --git a/public/images/emoji/google/waxing_gibbous_moon.png b/public/images/emoji/google/waxing_gibbous_moon.png index a8a36e3a986..02bec1ad187 100644 Binary files a/public/images/emoji/google/waxing_gibbous_moon.png and b/public/images/emoji/google/waxing_gibbous_moon.png differ diff --git a/public/images/emoji/google/wc.png b/public/images/emoji/google/wc.png index 65f034fd482..3d387020e15 100644 Binary files a/public/images/emoji/google/wc.png and b/public/images/emoji/google/wc.png differ diff --git a/public/images/emoji/google/weary.png b/public/images/emoji/google/weary.png index 57d4aee3367..7fdb134f87f 100644 Binary files a/public/images/emoji/google/weary.png and b/public/images/emoji/google/weary.png differ diff --git a/public/images/emoji/google/wedding.png b/public/images/emoji/google/wedding.png index 4946a36a0ae..34bb72daf8a 100644 Binary files a/public/images/emoji/google/wedding.png and b/public/images/emoji/google/wedding.png differ diff --git a/public/images/emoji/google/whale.png b/public/images/emoji/google/whale.png index 919a70ccd60..4a87aa2ff89 100644 Binary files a/public/images/emoji/google/whale.png and b/public/images/emoji/google/whale.png differ diff --git a/public/images/emoji/google/whale2.png b/public/images/emoji/google/whale2.png index ee0aa3bda63..91eefa5353f 100644 Binary files a/public/images/emoji/google/whale2.png and b/public/images/emoji/google/whale2.png differ diff --git a/public/images/emoji/google/wheel_of_dharma.png b/public/images/emoji/google/wheel_of_dharma.png new file mode 100644 index 00000000000..c102a50a517 Binary files /dev/null and b/public/images/emoji/google/wheel_of_dharma.png differ diff --git a/public/images/emoji/google/wheelchair.png b/public/images/emoji/google/wheelchair.png index c8623f5c26c..f1afc1539b4 100644 Binary files a/public/images/emoji/google/wheelchair.png and b/public/images/emoji/google/wheelchair.png differ diff --git a/public/images/emoji/google/white_check_mark.png b/public/images/emoji/google/white_check_mark.png index 1b27de2f9a2..305ff10e690 100644 Binary files a/public/images/emoji/google/white_check_mark.png and b/public/images/emoji/google/white_check_mark.png differ diff --git a/public/images/emoji/google/white_circle.png b/public/images/emoji/google/white_circle.png index 35423303859..165270b6f30 100644 Binary files a/public/images/emoji/google/white_circle.png and b/public/images/emoji/google/white_circle.png differ diff --git a/public/images/emoji/google/white_flower.png b/public/images/emoji/google/white_flower.png index dc865632995..316ab66bd5c 100644 Binary files a/public/images/emoji/google/white_flower.png and b/public/images/emoji/google/white_flower.png differ diff --git a/public/images/emoji/google/white_large_square.png b/public/images/emoji/google/white_large_square.png index 3b74c3e35dd..fd5d209b6d7 100644 Binary files a/public/images/emoji/google/white_large_square.png and b/public/images/emoji/google/white_large_square.png differ diff --git a/public/images/emoji/google/white_medium_square.png b/public/images/emoji/google/white_medium_square.png index a90b30d2176..0fbc2da276f 100644 Binary files a/public/images/emoji/google/white_medium_square.png and b/public/images/emoji/google/white_medium_square.png differ diff --git a/public/images/emoji/google/white_square_button.png b/public/images/emoji/google/white_square_button.png index e01000cbe38..565c3e70a13 100644 Binary files a/public/images/emoji/google/white_square_button.png and b/public/images/emoji/google/white_square_button.png differ diff --git a/public/images/emoji/google/white_sun_cloud.png b/public/images/emoji/google/white_sun_cloud.png new file mode 100644 index 00000000000..4ae2fd114a8 Binary files /dev/null and b/public/images/emoji/google/white_sun_cloud.png differ diff --git a/public/images/emoji/google/white_sun_rain_cloud.png b/public/images/emoji/google/white_sun_rain_cloud.png new file mode 100644 index 00000000000..78535070d6a Binary files /dev/null and b/public/images/emoji/google/white_sun_rain_cloud.png differ diff --git a/public/images/emoji/google/white_sun_small_cloud.png b/public/images/emoji/google/white_sun_small_cloud.png new file mode 100644 index 00000000000..1e2117f2479 Binary files /dev/null and b/public/images/emoji/google/white_sun_small_cloud.png differ diff --git a/public/images/emoji/google/wind_blowing_face.png b/public/images/emoji/google/wind_blowing_face.png new file mode 100644 index 00000000000..3db70932808 Binary files /dev/null and b/public/images/emoji/google/wind_blowing_face.png differ diff --git a/public/images/emoji/google/wind_chime.png b/public/images/emoji/google/wind_chime.png index bfc5ffce793..c7e7c74c934 100644 Binary files a/public/images/emoji/google/wind_chime.png and b/public/images/emoji/google/wind_chime.png differ diff --git a/public/images/emoji/google/wine_glass.png b/public/images/emoji/google/wine_glass.png index 7ae47dae80c..0915a028846 100644 Binary files a/public/images/emoji/google/wine_glass.png and b/public/images/emoji/google/wine_glass.png differ diff --git a/public/images/emoji/google/wink.png b/public/images/emoji/google/wink.png index fa82c48e21b..c6c28a2a1f8 100644 Binary files a/public/images/emoji/google/wink.png and b/public/images/emoji/google/wink.png differ diff --git a/public/images/emoji/google/wolf.png b/public/images/emoji/google/wolf.png index aeac39b1215..1d2b41218f6 100644 Binary files a/public/images/emoji/google/wolf.png and b/public/images/emoji/google/wolf.png differ diff --git a/public/images/emoji/google/woman.png b/public/images/emoji/google/woman.png index bcfb1d24230..3c6ef266b23 100644 Binary files a/public/images/emoji/google/woman.png and b/public/images/emoji/google/woman.png differ diff --git a/public/images/emoji/google/womans_clothes.png b/public/images/emoji/google/womans_clothes.png index eff37245309..c3e19d14949 100644 Binary files a/public/images/emoji/google/womans_clothes.png and b/public/images/emoji/google/womans_clothes.png differ diff --git a/public/images/emoji/google/womans_hat.png b/public/images/emoji/google/womans_hat.png index a80039dcc54..f26c7674c6f 100644 Binary files a/public/images/emoji/google/womans_hat.png and b/public/images/emoji/google/womans_hat.png differ diff --git a/public/images/emoji/google/womens.png b/public/images/emoji/google/womens.png index 15977627b6f..3ad6f2e9dd8 100644 Binary files a/public/images/emoji/google/womens.png and b/public/images/emoji/google/womens.png differ diff --git a/public/images/emoji/google/worried.png b/public/images/emoji/google/worried.png index 23356816723..4578afc6ce3 100644 Binary files a/public/images/emoji/google/worried.png and b/public/images/emoji/google/worried.png differ diff --git a/public/images/emoji/google/wrench.png b/public/images/emoji/google/wrench.png index 7933aa8d6a9..8610eab733d 100644 Binary files a/public/images/emoji/google/wrench.png and b/public/images/emoji/google/wrench.png differ diff --git a/public/images/emoji/google/writing_hand.png b/public/images/emoji/google/writing_hand.png new file mode 100644 index 00000000000..b178941f4cb Binary files /dev/null and b/public/images/emoji/google/writing_hand.png differ diff --git a/public/images/emoji/google/x.png b/public/images/emoji/google/x.png index 9532e64fb7b..11302ba0e04 100644 Binary files a/public/images/emoji/google/x.png and b/public/images/emoji/google/x.png differ diff --git a/public/images/emoji/google/yellow_heart.png b/public/images/emoji/google/yellow_heart.png index b108aeb4b7e..af4c809417a 100644 Binary files a/public/images/emoji/google/yellow_heart.png and b/public/images/emoji/google/yellow_heart.png differ diff --git a/public/images/emoji/google/yen.png b/public/images/emoji/google/yen.png index 1164cb561cc..d11d124901c 100644 Binary files a/public/images/emoji/google/yen.png and b/public/images/emoji/google/yen.png differ diff --git a/public/images/emoji/google/yin_yang.png b/public/images/emoji/google/yin_yang.png new file mode 100644 index 00000000000..1e682f0582a Binary files /dev/null and b/public/images/emoji/google/yin_yang.png differ diff --git a/public/images/emoji/google/yum.png b/public/images/emoji/google/yum.png index 11e71c662e3..0c9cd992b7e 100644 Binary files a/public/images/emoji/google/yum.png and b/public/images/emoji/google/yum.png differ diff --git a/public/images/emoji/google/zap.png b/public/images/emoji/google/zap.png index b180e1c6f8a..e0dcd63e975 100644 Binary files a/public/images/emoji/google/zap.png and b/public/images/emoji/google/zap.png differ diff --git a/public/images/emoji/google/zipper_mouth.png b/public/images/emoji/google/zipper_mouth.png new file mode 100644 index 00000000000..de15534fb78 Binary files /dev/null and b/public/images/emoji/google/zipper_mouth.png differ diff --git a/public/images/emoji/google/zzz.png b/public/images/emoji/google/zzz.png index bbb8726591d..2d4b2599fff 100644 Binary files a/public/images/emoji/google/zzz.png and b/public/images/emoji/google/zzz.png differ diff --git a/public/images/emoji/twitter/+1.png b/public/images/emoji/twitter/+1.png index f4bafe3cc19..9e37b14d8ae 100644 Binary files a/public/images/emoji/twitter/+1.png and b/public/images/emoji/twitter/+1.png differ diff --git a/public/images/emoji/twitter/-1.png b/public/images/emoji/twitter/-1.png index 892f5cf1ee5..8a531851600 100644 Binary files a/public/images/emoji/twitter/-1.png and b/public/images/emoji/twitter/-1.png differ diff --git a/public/images/emoji/twitter/100.png b/public/images/emoji/twitter/100.png index 7a9b91830fc..52853d5ddeb 100644 Binary files a/public/images/emoji/twitter/100.png and b/public/images/emoji/twitter/100.png differ diff --git a/public/images/emoji/twitter/1234.png b/public/images/emoji/twitter/1234.png index 076d4526e76..e7c7c363b0b 100644 Binary files a/public/images/emoji/twitter/1234.png and b/public/images/emoji/twitter/1234.png differ diff --git a/public/images/emoji/twitter/8ball.png b/public/images/emoji/twitter/8ball.png index 8f53cd375ed..be2d7a6d6f3 100644 Binary files a/public/images/emoji/twitter/8ball.png and b/public/images/emoji/twitter/8ball.png differ diff --git a/public/images/emoji/twitter/a.png b/public/images/emoji/twitter/a.png index 4910a182891..446cf7c2549 100644 Binary files a/public/images/emoji/twitter/a.png and b/public/images/emoji/twitter/a.png differ diff --git a/public/images/emoji/twitter/ab.png b/public/images/emoji/twitter/ab.png index 629ccf6410e..9e212f3ba23 100644 Binary files a/public/images/emoji/twitter/ab.png and b/public/images/emoji/twitter/ab.png differ diff --git a/public/images/emoji/twitter/abc.png b/public/images/emoji/twitter/abc.png index 54907e5029d..71a3aa84707 100644 Binary files a/public/images/emoji/twitter/abc.png and b/public/images/emoji/twitter/abc.png differ diff --git a/public/images/emoji/twitter/abcd.png b/public/images/emoji/twitter/abcd.png index 9d867149d76..877bdfc85df 100644 Binary files a/public/images/emoji/twitter/abcd.png and b/public/images/emoji/twitter/abcd.png differ diff --git a/public/images/emoji/twitter/accept.png b/public/images/emoji/twitter/accept.png index 90a727b1e11..4ce4b6729c8 100644 Binary files a/public/images/emoji/twitter/accept.png and b/public/images/emoji/twitter/accept.png differ diff --git a/public/images/emoji/twitter/aerial_tramway.png b/public/images/emoji/twitter/aerial_tramway.png index 40d2b1c91ff..93599a170ce 100644 Binary files a/public/images/emoji/twitter/aerial_tramway.png and b/public/images/emoji/twitter/aerial_tramway.png differ diff --git a/public/images/emoji/twitter/airplane.png b/public/images/emoji/twitter/airplane.png index 5d2406ab3c8..cf24c72e494 100644 Binary files a/public/images/emoji/twitter/airplane.png and b/public/images/emoji/twitter/airplane.png differ diff --git a/public/images/emoji/twitter/airplane_arriving.png b/public/images/emoji/twitter/airplane_arriving.png new file mode 100644 index 00000000000..a75656592fa Binary files /dev/null and b/public/images/emoji/twitter/airplane_arriving.png differ diff --git a/public/images/emoji/twitter/airplane_departure.png b/public/images/emoji/twitter/airplane_departure.png new file mode 100644 index 00000000000..dc86670a865 Binary files /dev/null and b/public/images/emoji/twitter/airplane_departure.png differ diff --git a/public/images/emoji/twitter/airplane_small.png b/public/images/emoji/twitter/airplane_small.png new file mode 100644 index 00000000000..6a67b428f9d Binary files /dev/null and b/public/images/emoji/twitter/airplane_small.png differ diff --git a/public/images/emoji/twitter/alarm_clock.png b/public/images/emoji/twitter/alarm_clock.png index 214b12ccd8f..385f0df015a 100644 Binary files a/public/images/emoji/twitter/alarm_clock.png and b/public/images/emoji/twitter/alarm_clock.png differ diff --git a/public/images/emoji/twitter/alembic.png b/public/images/emoji/twitter/alembic.png new file mode 100644 index 00000000000..f450e6da1f9 Binary files /dev/null and b/public/images/emoji/twitter/alembic.png differ diff --git a/public/images/emoji/twitter/alien.png b/public/images/emoji/twitter/alien.png index 704ba0a0786..f1cd2b36f67 100644 Binary files a/public/images/emoji/twitter/alien.png and b/public/images/emoji/twitter/alien.png differ diff --git a/public/images/emoji/twitter/ambulance.png b/public/images/emoji/twitter/ambulance.png index 2c912f03708..80681a180e3 100644 Binary files a/public/images/emoji/twitter/ambulance.png and b/public/images/emoji/twitter/ambulance.png differ diff --git a/public/images/emoji/twitter/amphora.png b/public/images/emoji/twitter/amphora.png new file mode 100644 index 00000000000..550f047067a Binary files /dev/null and b/public/images/emoji/twitter/amphora.png differ diff --git a/public/images/emoji/twitter/anchor.png b/public/images/emoji/twitter/anchor.png index a64e24ed27e..c8e523f1392 100644 Binary files a/public/images/emoji/twitter/anchor.png and b/public/images/emoji/twitter/anchor.png differ diff --git a/public/images/emoji/twitter/angel.png b/public/images/emoji/twitter/angel.png index cdcec5f51a0..a6576bae30e 100644 Binary files a/public/images/emoji/twitter/angel.png and b/public/images/emoji/twitter/angel.png differ diff --git a/public/images/emoji/twitter/anger.png b/public/images/emoji/twitter/anger.png index 14f5a6d970e..4273bed07ba 100644 Binary files a/public/images/emoji/twitter/anger.png and b/public/images/emoji/twitter/anger.png differ diff --git a/public/images/emoji/twitter/anger_right.png b/public/images/emoji/twitter/anger_right.png new file mode 100644 index 00000000000..d6e6ffd8197 Binary files /dev/null and b/public/images/emoji/twitter/anger_right.png differ diff --git a/public/images/emoji/twitter/angry.png b/public/images/emoji/twitter/angry.png index 6c69d9b0d13..60233a0e3ab 100644 Binary files a/public/images/emoji/twitter/angry.png and b/public/images/emoji/twitter/angry.png differ diff --git a/public/images/emoji/twitter/anguished.png b/public/images/emoji/twitter/anguished.png index 70219ed5977..4e2565f91e4 100644 Binary files a/public/images/emoji/twitter/anguished.png and b/public/images/emoji/twitter/anguished.png differ diff --git a/public/images/emoji/twitter/ant.png b/public/images/emoji/twitter/ant.png index 74c43359fe5..0b5a6225754 100644 Binary files a/public/images/emoji/twitter/ant.png and b/public/images/emoji/twitter/ant.png differ diff --git a/public/images/emoji/twitter/apple.png b/public/images/emoji/twitter/apple.png index f1c6758569c..52a2fc7be17 100644 Binary files a/public/images/emoji/twitter/apple.png and b/public/images/emoji/twitter/apple.png differ diff --git a/public/images/emoji/twitter/aquarius.png b/public/images/emoji/twitter/aquarius.png index ccf4bccc66c..0465fad624e 100644 Binary files a/public/images/emoji/twitter/aquarius.png and b/public/images/emoji/twitter/aquarius.png differ diff --git a/public/images/emoji/twitter/aries.png b/public/images/emoji/twitter/aries.png index 53c1b5cb92f..c23b1b60d0e 100644 Binary files a/public/images/emoji/twitter/aries.png and b/public/images/emoji/twitter/aries.png differ diff --git a/public/images/emoji/twitter/arrow_backward.png b/public/images/emoji/twitter/arrow_backward.png index 52cfb55fe83..47b55a75441 100644 Binary files a/public/images/emoji/twitter/arrow_backward.png and b/public/images/emoji/twitter/arrow_backward.png differ diff --git a/public/images/emoji/twitter/arrow_double_down.png b/public/images/emoji/twitter/arrow_double_down.png index a2066604890..8a99dac6ec5 100644 Binary files a/public/images/emoji/twitter/arrow_double_down.png and b/public/images/emoji/twitter/arrow_double_down.png differ diff --git a/public/images/emoji/twitter/arrow_double_up.png b/public/images/emoji/twitter/arrow_double_up.png index a8eaf8886d0..e7e8eadea98 100644 Binary files a/public/images/emoji/twitter/arrow_double_up.png and b/public/images/emoji/twitter/arrow_double_up.png differ diff --git a/public/images/emoji/twitter/arrow_down.png b/public/images/emoji/twitter/arrow_down.png index c8fce77f66e..3060efdec53 100644 Binary files a/public/images/emoji/twitter/arrow_down.png and b/public/images/emoji/twitter/arrow_down.png differ diff --git a/public/images/emoji/twitter/arrow_down_small.png b/public/images/emoji/twitter/arrow_down_small.png index ca171752a0e..eac1cbfacfd 100644 Binary files a/public/images/emoji/twitter/arrow_down_small.png and b/public/images/emoji/twitter/arrow_down_small.png differ diff --git a/public/images/emoji/twitter/arrow_forward.png b/public/images/emoji/twitter/arrow_forward.png index 318fc58f361..9141aaa2d5a 100644 Binary files a/public/images/emoji/twitter/arrow_forward.png and b/public/images/emoji/twitter/arrow_forward.png differ diff --git a/public/images/emoji/twitter/arrow_heading_down.png b/public/images/emoji/twitter/arrow_heading_down.png index 3cc4353e1a0..f6ec17c0ae9 100644 Binary files a/public/images/emoji/twitter/arrow_heading_down.png and b/public/images/emoji/twitter/arrow_heading_down.png differ diff --git a/public/images/emoji/twitter/arrow_heading_up.png b/public/images/emoji/twitter/arrow_heading_up.png index 1980877413d..ae1e836ef85 100644 Binary files a/public/images/emoji/twitter/arrow_heading_up.png and b/public/images/emoji/twitter/arrow_heading_up.png differ diff --git a/public/images/emoji/twitter/arrow_left.png b/public/images/emoji/twitter/arrow_left.png index 163b53501b4..12871e34f98 100644 Binary files a/public/images/emoji/twitter/arrow_left.png and b/public/images/emoji/twitter/arrow_left.png differ diff --git a/public/images/emoji/twitter/arrow_lower_left.png b/public/images/emoji/twitter/arrow_lower_left.png index 30b784363d4..11f7037bf94 100644 Binary files a/public/images/emoji/twitter/arrow_lower_left.png and b/public/images/emoji/twitter/arrow_lower_left.png differ diff --git a/public/images/emoji/twitter/arrow_lower_right.png b/public/images/emoji/twitter/arrow_lower_right.png index 75d2b8ef92a..257e5b8c03e 100644 Binary files a/public/images/emoji/twitter/arrow_lower_right.png and b/public/images/emoji/twitter/arrow_lower_right.png differ diff --git a/public/images/emoji/twitter/arrow_right.png b/public/images/emoji/twitter/arrow_right.png index 8c13e198534..8ef69a31b0d 100644 Binary files a/public/images/emoji/twitter/arrow_right.png and b/public/images/emoji/twitter/arrow_right.png differ diff --git a/public/images/emoji/twitter/arrow_right_hook.png b/public/images/emoji/twitter/arrow_right_hook.png index 586e0d48b78..78863022fd1 100644 Binary files a/public/images/emoji/twitter/arrow_right_hook.png and b/public/images/emoji/twitter/arrow_right_hook.png differ diff --git a/public/images/emoji/twitter/arrow_up.png b/public/images/emoji/twitter/arrow_up.png index 561899cb6e9..a83a26356e2 100644 Binary files a/public/images/emoji/twitter/arrow_up.png and b/public/images/emoji/twitter/arrow_up.png differ diff --git a/public/images/emoji/twitter/arrow_up_down.png b/public/images/emoji/twitter/arrow_up_down.png index 72622939e09..7da82f11936 100644 Binary files a/public/images/emoji/twitter/arrow_up_down.png and b/public/images/emoji/twitter/arrow_up_down.png differ diff --git a/public/images/emoji/twitter/arrow_up_small.png b/public/images/emoji/twitter/arrow_up_small.png index 878ffcfc227..9495c3141d9 100644 Binary files a/public/images/emoji/twitter/arrow_up_small.png and b/public/images/emoji/twitter/arrow_up_small.png differ diff --git a/public/images/emoji/twitter/arrow_upper_left.png b/public/images/emoji/twitter/arrow_upper_left.png index 88a8c8c65ca..14e93fec057 100644 Binary files a/public/images/emoji/twitter/arrow_upper_left.png and b/public/images/emoji/twitter/arrow_upper_left.png differ diff --git a/public/images/emoji/twitter/arrow_upper_right.png b/public/images/emoji/twitter/arrow_upper_right.png index 422fe6c47c3..79829aaf7b2 100644 Binary files a/public/images/emoji/twitter/arrow_upper_right.png and b/public/images/emoji/twitter/arrow_upper_right.png differ diff --git a/public/images/emoji/twitter/arrows_clockwise.png b/public/images/emoji/twitter/arrows_clockwise.png index 79bb1681aca..c5bd6b78732 100644 Binary files a/public/images/emoji/twitter/arrows_clockwise.png and b/public/images/emoji/twitter/arrows_clockwise.png differ diff --git a/public/images/emoji/twitter/arrows_counterclockwise.png b/public/images/emoji/twitter/arrows_counterclockwise.png index 3ebc7315190..5527bec4e94 100644 Binary files a/public/images/emoji/twitter/arrows_counterclockwise.png and b/public/images/emoji/twitter/arrows_counterclockwise.png differ diff --git a/public/images/emoji/twitter/art.png b/public/images/emoji/twitter/art.png index c22a9f342b9..b36f226a813 100644 Binary files a/public/images/emoji/twitter/art.png and b/public/images/emoji/twitter/art.png differ diff --git a/public/images/emoji/twitter/articulated_lorry.png b/public/images/emoji/twitter/articulated_lorry.png index ebc5d3fd7e5..912a01f9b55 100644 Binary files a/public/images/emoji/twitter/articulated_lorry.png and b/public/images/emoji/twitter/articulated_lorry.png differ diff --git a/public/images/emoji/twitter/astonished.png b/public/images/emoji/twitter/astonished.png index 273454344c7..3d3b4047a3c 100644 Binary files a/public/images/emoji/twitter/astonished.png and b/public/images/emoji/twitter/astonished.png differ diff --git a/public/images/emoji/twitter/athletic_shoe.png b/public/images/emoji/twitter/athletic_shoe.png index 302effc6144..5195621ef25 100644 Binary files a/public/images/emoji/twitter/athletic_shoe.png and b/public/images/emoji/twitter/athletic_shoe.png differ diff --git a/public/images/emoji/twitter/atm.png b/public/images/emoji/twitter/atm.png index 02517ef06cd..ce7d89e6421 100644 Binary files a/public/images/emoji/twitter/atm.png and b/public/images/emoji/twitter/atm.png differ diff --git a/public/images/emoji/twitter/atom.png b/public/images/emoji/twitter/atom.png new file mode 100644 index 00000000000..e1203eec7d8 Binary files /dev/null and b/public/images/emoji/twitter/atom.png differ diff --git a/public/images/emoji/twitter/b.png b/public/images/emoji/twitter/b.png index 9ba297423c4..ab5cb258ff3 100644 Binary files a/public/images/emoji/twitter/b.png and b/public/images/emoji/twitter/b.png differ diff --git a/public/images/emoji/twitter/baby.png b/public/images/emoji/twitter/baby.png index 6508b64e5b0..01d9c75f325 100644 Binary files a/public/images/emoji/twitter/baby.png and b/public/images/emoji/twitter/baby.png differ diff --git a/public/images/emoji/twitter/baby_bottle.png b/public/images/emoji/twitter/baby_bottle.png index 16502327307..3c073554000 100644 Binary files a/public/images/emoji/twitter/baby_bottle.png and b/public/images/emoji/twitter/baby_bottle.png differ diff --git a/public/images/emoji/twitter/baby_chick.png b/public/images/emoji/twitter/baby_chick.png index 4e27df54249..ec02e885bea 100644 Binary files a/public/images/emoji/twitter/baby_chick.png and b/public/images/emoji/twitter/baby_chick.png differ diff --git a/public/images/emoji/twitter/baby_symbol.png b/public/images/emoji/twitter/baby_symbol.png index e9e43ccfec0..dbeabaca5d4 100644 Binary files a/public/images/emoji/twitter/baby_symbol.png and b/public/images/emoji/twitter/baby_symbol.png differ diff --git a/public/images/emoji/twitter/back.png b/public/images/emoji/twitter/back.png index 06d2d855472..3cfebbb815c 100644 Binary files a/public/images/emoji/twitter/back.png and b/public/images/emoji/twitter/back.png differ diff --git a/public/images/emoji/twitter/badminton.png b/public/images/emoji/twitter/badminton.png new file mode 100644 index 00000000000..86cf6f14657 Binary files /dev/null and b/public/images/emoji/twitter/badminton.png differ diff --git a/public/images/emoji/twitter/baggage_claim.png b/public/images/emoji/twitter/baggage_claim.png index f83a918a695..2441abbec25 100644 Binary files a/public/images/emoji/twitter/baggage_claim.png and b/public/images/emoji/twitter/baggage_claim.png differ diff --git a/public/images/emoji/twitter/balloon.png b/public/images/emoji/twitter/balloon.png index bb152dc6d7d..0815d100e57 100644 Binary files a/public/images/emoji/twitter/balloon.png and b/public/images/emoji/twitter/balloon.png differ diff --git a/public/images/emoji/twitter/ballot_box.png b/public/images/emoji/twitter/ballot_box.png new file mode 100644 index 00000000000..583ec9c01d2 Binary files /dev/null and b/public/images/emoji/twitter/ballot_box.png differ diff --git a/public/images/emoji/twitter/ballot_box_with_check.png b/public/images/emoji/twitter/ballot_box_with_check.png index 202beb96e1a..26d19bd6cbe 100644 Binary files a/public/images/emoji/twitter/ballot_box_with_check.png and b/public/images/emoji/twitter/ballot_box_with_check.png differ diff --git a/public/images/emoji/twitter/bamboo.png b/public/images/emoji/twitter/bamboo.png index 17595aca587..6d9f75530ef 100644 Binary files a/public/images/emoji/twitter/bamboo.png and b/public/images/emoji/twitter/bamboo.png differ diff --git a/public/images/emoji/twitter/banana.png b/public/images/emoji/twitter/banana.png index d007ebaff55..f67d4cedcdd 100644 Binary files a/public/images/emoji/twitter/banana.png and b/public/images/emoji/twitter/banana.png differ diff --git a/public/images/emoji/twitter/bangbang.png b/public/images/emoji/twitter/bangbang.png index b7c7c51827f..845ff4da8e4 100644 Binary files a/public/images/emoji/twitter/bangbang.png and b/public/images/emoji/twitter/bangbang.png differ diff --git a/public/images/emoji/twitter/bank.png b/public/images/emoji/twitter/bank.png index 6bc054d19b8..5e764766580 100644 Binary files a/public/images/emoji/twitter/bank.png and b/public/images/emoji/twitter/bank.png differ diff --git a/public/images/emoji/twitter/bar_chart.png b/public/images/emoji/twitter/bar_chart.png index 335ba0f3c5a..1c1a9a24b03 100644 Binary files a/public/images/emoji/twitter/bar_chart.png and b/public/images/emoji/twitter/bar_chart.png differ diff --git a/public/images/emoji/twitter/barber.png b/public/images/emoji/twitter/barber.png index 19f432af957..9880e721707 100644 Binary files a/public/images/emoji/twitter/barber.png and b/public/images/emoji/twitter/barber.png differ diff --git a/public/images/emoji/twitter/baseball.png b/public/images/emoji/twitter/baseball.png index 5dbda2836d6..e889b8b0bd9 100644 Binary files a/public/images/emoji/twitter/baseball.png and b/public/images/emoji/twitter/baseball.png differ diff --git a/public/images/emoji/twitter/basketball.png b/public/images/emoji/twitter/basketball.png index 20e25daebf5..c437282c446 100644 Binary files a/public/images/emoji/twitter/basketball.png and b/public/images/emoji/twitter/basketball.png differ diff --git a/public/images/emoji/twitter/basketball_player.png b/public/images/emoji/twitter/basketball_player.png new file mode 100644 index 00000000000..8b98c38994f Binary files /dev/null and b/public/images/emoji/twitter/basketball_player.png differ diff --git a/public/images/emoji/twitter/bath.png b/public/images/emoji/twitter/bath.png index a7dc17b7239..742ce80bf4b 100644 Binary files a/public/images/emoji/twitter/bath.png and b/public/images/emoji/twitter/bath.png differ diff --git a/public/images/emoji/twitter/bathtub.png b/public/images/emoji/twitter/bathtub.png index 0580a6d24b7..579ca796cdf 100644 Binary files a/public/images/emoji/twitter/bathtub.png and b/public/images/emoji/twitter/bathtub.png differ diff --git a/public/images/emoji/twitter/battery.png b/public/images/emoji/twitter/battery.png index 4baada52602..897aecd3c1b 100644 Binary files a/public/images/emoji/twitter/battery.png and b/public/images/emoji/twitter/battery.png differ diff --git a/public/images/emoji/twitter/beach.png b/public/images/emoji/twitter/beach.png new file mode 100644 index 00000000000..16509a7e8dd Binary files /dev/null and b/public/images/emoji/twitter/beach.png differ diff --git a/public/images/emoji/twitter/beach_umbrella.png b/public/images/emoji/twitter/beach_umbrella.png new file mode 100644 index 00000000000..2bb23697b7f Binary files /dev/null and b/public/images/emoji/twitter/beach_umbrella.png differ diff --git a/public/images/emoji/twitter/bear.png b/public/images/emoji/twitter/bear.png index e3321e290fb..8ce3aca8fd2 100644 Binary files a/public/images/emoji/twitter/bear.png and b/public/images/emoji/twitter/bear.png differ diff --git a/public/images/emoji/twitter/bed.png b/public/images/emoji/twitter/bed.png new file mode 100644 index 00000000000..4680571709c Binary files /dev/null and b/public/images/emoji/twitter/bed.png differ diff --git a/public/images/emoji/twitter/bee.png b/public/images/emoji/twitter/bee.png index 5e73fc3687c..0429354f0cb 100644 Binary files a/public/images/emoji/twitter/bee.png and b/public/images/emoji/twitter/bee.png differ diff --git a/public/images/emoji/twitter/beer.png b/public/images/emoji/twitter/beer.png index 3c3e9442601..f11d4b8babc 100644 Binary files a/public/images/emoji/twitter/beer.png and b/public/images/emoji/twitter/beer.png differ diff --git a/public/images/emoji/twitter/beers.png b/public/images/emoji/twitter/beers.png index 723b1cc5c6a..7420158054a 100644 Binary files a/public/images/emoji/twitter/beers.png and b/public/images/emoji/twitter/beers.png differ diff --git a/public/images/emoji/twitter/beetle.png b/public/images/emoji/twitter/beetle.png index 35c8d0d8646..78a02529e57 100644 Binary files a/public/images/emoji/twitter/beetle.png and b/public/images/emoji/twitter/beetle.png differ diff --git a/public/images/emoji/twitter/beginner.png b/public/images/emoji/twitter/beginner.png index 412af52ada9..c767d9d5544 100644 Binary files a/public/images/emoji/twitter/beginner.png and b/public/images/emoji/twitter/beginner.png differ diff --git a/public/images/emoji/twitter/bell.png b/public/images/emoji/twitter/bell.png index 08483cc3c3d..d8fe68b3575 100644 Binary files a/public/images/emoji/twitter/bell.png and b/public/images/emoji/twitter/bell.png differ diff --git a/public/images/emoji/twitter/bellhop.png b/public/images/emoji/twitter/bellhop.png new file mode 100644 index 00000000000..07c6badfdac Binary files /dev/null and b/public/images/emoji/twitter/bellhop.png differ diff --git a/public/images/emoji/twitter/bento.png b/public/images/emoji/twitter/bento.png index b36a703ba90..4889897107d 100644 Binary files a/public/images/emoji/twitter/bento.png and b/public/images/emoji/twitter/bento.png differ diff --git a/public/images/emoji/twitter/bicyclist.png b/public/images/emoji/twitter/bicyclist.png index 80800d3da63..7eb6d93873e 100644 Binary files a/public/images/emoji/twitter/bicyclist.png and b/public/images/emoji/twitter/bicyclist.png differ diff --git a/public/images/emoji/twitter/bike.png b/public/images/emoji/twitter/bike.png index 7128411a504..71db964dedc 100644 Binary files a/public/images/emoji/twitter/bike.png and b/public/images/emoji/twitter/bike.png differ diff --git a/public/images/emoji/twitter/bikini.png b/public/images/emoji/twitter/bikini.png index 79c08d1d712..5d2f6c3f3b5 100644 Binary files a/public/images/emoji/twitter/bikini.png and b/public/images/emoji/twitter/bikini.png differ diff --git a/public/images/emoji/twitter/biohazard.png b/public/images/emoji/twitter/biohazard.png new file mode 100644 index 00000000000..1ef96832a04 Binary files /dev/null and b/public/images/emoji/twitter/biohazard.png differ diff --git a/public/images/emoji/twitter/bird.png b/public/images/emoji/twitter/bird.png index c73fa88a78e..caa87433961 100644 Binary files a/public/images/emoji/twitter/bird.png and b/public/images/emoji/twitter/bird.png differ diff --git a/public/images/emoji/twitter/birthday.png b/public/images/emoji/twitter/birthday.png index 961239034f4..c8484dc3cb0 100644 Binary files a/public/images/emoji/twitter/birthday.png and b/public/images/emoji/twitter/birthday.png differ diff --git a/public/images/emoji/twitter/black_circle.png b/public/images/emoji/twitter/black_circle.png index c763980938c..b46bce14cfc 100644 Binary files a/public/images/emoji/twitter/black_circle.png and b/public/images/emoji/twitter/black_circle.png differ diff --git a/public/images/emoji/twitter/black_joker.png b/public/images/emoji/twitter/black_joker.png index 57c236aa499..12ba87afd15 100644 Binary files a/public/images/emoji/twitter/black_joker.png and b/public/images/emoji/twitter/black_joker.png differ diff --git a/public/images/emoji/twitter/black_large_square.png b/public/images/emoji/twitter/black_large_square.png index 6465bde6148..2b9ed6bc449 100644 Binary files a/public/images/emoji/twitter/black_large_square.png and b/public/images/emoji/twitter/black_large_square.png differ diff --git a/public/images/emoji/twitter/black_medium_small_square.png b/public/images/emoji/twitter/black_medium_small_square.png index 0955daf448f..febceb46e5f 100644 Binary files a/public/images/emoji/twitter/black_medium_small_square.png and b/public/images/emoji/twitter/black_medium_small_square.png differ diff --git a/public/images/emoji/twitter/black_medium_square.png b/public/images/emoji/twitter/black_medium_square.png index 5ce46828ec8..6130ae162a8 100644 Binary files a/public/images/emoji/twitter/black_medium_square.png and b/public/images/emoji/twitter/black_medium_square.png differ diff --git a/public/images/emoji/twitter/black_nib.png b/public/images/emoji/twitter/black_nib.png index 66b2c663d2f..43d1dc69083 100644 Binary files a/public/images/emoji/twitter/black_nib.png and b/public/images/emoji/twitter/black_nib.png differ diff --git a/public/images/emoji/twitter/black_small_square.png b/public/images/emoji/twitter/black_small_square.png index 203ce77c1a2..57df0544da5 100644 Binary files a/public/images/emoji/twitter/black_small_square.png and b/public/images/emoji/twitter/black_small_square.png differ diff --git a/public/images/emoji/twitter/black_square_button.png b/public/images/emoji/twitter/black_square_button.png index 0e7f6888eac..b1f62787817 100644 Binary files a/public/images/emoji/twitter/black_square_button.png and b/public/images/emoji/twitter/black_square_button.png differ diff --git a/public/images/emoji/twitter/blossom.png b/public/images/emoji/twitter/blossom.png index 5bc24065c69..dd39767913d 100644 Binary files a/public/images/emoji/twitter/blossom.png and b/public/images/emoji/twitter/blossom.png differ diff --git a/public/images/emoji/twitter/blowfish.png b/public/images/emoji/twitter/blowfish.png index d77f9f52a32..a02fb899cdd 100644 Binary files a/public/images/emoji/twitter/blowfish.png and b/public/images/emoji/twitter/blowfish.png differ diff --git a/public/images/emoji/twitter/blue_book.png b/public/images/emoji/twitter/blue_book.png index 367697f718a..48d3712bb1d 100644 Binary files a/public/images/emoji/twitter/blue_book.png and b/public/images/emoji/twitter/blue_book.png differ diff --git a/public/images/emoji/twitter/blue_car.png b/public/images/emoji/twitter/blue_car.png index f8320178a11..9548eea9e13 100644 Binary files a/public/images/emoji/twitter/blue_car.png and b/public/images/emoji/twitter/blue_car.png differ diff --git a/public/images/emoji/twitter/blue_heart.png b/public/images/emoji/twitter/blue_heart.png index f58f9bc1378..2ecd7da608e 100644 Binary files a/public/images/emoji/twitter/blue_heart.png and b/public/images/emoji/twitter/blue_heart.png differ diff --git a/public/images/emoji/twitter/blush.png b/public/images/emoji/twitter/blush.png index 6e7bb4be4c6..020191c9f87 100644 Binary files a/public/images/emoji/twitter/blush.png and b/public/images/emoji/twitter/blush.png differ diff --git a/public/images/emoji/twitter/boar.png b/public/images/emoji/twitter/boar.png index fe9ceb0a620..f21409fdd35 100644 Binary files a/public/images/emoji/twitter/boar.png and b/public/images/emoji/twitter/boar.png differ diff --git a/public/images/emoji/twitter/boat.png b/public/images/emoji/twitter/boat.png index 7b4a289ed2d..2062f2896d9 100644 Binary files a/public/images/emoji/twitter/boat.png and b/public/images/emoji/twitter/boat.png differ diff --git a/public/images/emoji/twitter/bomb.png b/public/images/emoji/twitter/bomb.png index 4c833e97531..f4c547c5cbb 100644 Binary files a/public/images/emoji/twitter/bomb.png and b/public/images/emoji/twitter/bomb.png differ diff --git a/public/images/emoji/twitter/book.png b/public/images/emoji/twitter/book.png index e62882acb69..31cbe96905c 100644 Binary files a/public/images/emoji/twitter/book.png and b/public/images/emoji/twitter/book.png differ diff --git a/public/images/emoji/twitter/bookmark.png b/public/images/emoji/twitter/bookmark.png index 19a9fff2e6c..ef10ce4bab8 100644 Binary files a/public/images/emoji/twitter/bookmark.png and b/public/images/emoji/twitter/bookmark.png differ diff --git a/public/images/emoji/twitter/bookmark_tabs.png b/public/images/emoji/twitter/bookmark_tabs.png index 0c8e6848bdc..748655111a1 100644 Binary files a/public/images/emoji/twitter/bookmark_tabs.png and b/public/images/emoji/twitter/bookmark_tabs.png differ diff --git a/public/images/emoji/twitter/books.png b/public/images/emoji/twitter/books.png index d987bf6f872..2c7b3bb9c38 100644 Binary files a/public/images/emoji/twitter/books.png and b/public/images/emoji/twitter/books.png differ diff --git a/public/images/emoji/twitter/boom.png b/public/images/emoji/twitter/boom.png index a7f1e2a5eb6..acd36989547 100644 Binary files a/public/images/emoji/twitter/boom.png and b/public/images/emoji/twitter/boom.png differ diff --git a/public/images/emoji/twitter/boot.png b/public/images/emoji/twitter/boot.png index f2e89fcfdd6..7625bde5a63 100644 Binary files a/public/images/emoji/twitter/boot.png and b/public/images/emoji/twitter/boot.png differ diff --git a/public/images/emoji/twitter/bouquet.png b/public/images/emoji/twitter/bouquet.png index 14d6645c7da..27078e04a29 100644 Binary files a/public/images/emoji/twitter/bouquet.png and b/public/images/emoji/twitter/bouquet.png differ diff --git a/public/images/emoji/twitter/bow.png b/public/images/emoji/twitter/bow.png index 44739d36b1c..1e791d0c0a0 100644 Binary files a/public/images/emoji/twitter/bow.png and b/public/images/emoji/twitter/bow.png differ diff --git a/public/images/emoji/twitter/bow_and_arrow.png b/public/images/emoji/twitter/bow_and_arrow.png new file mode 100644 index 00000000000..f50a1389fef Binary files /dev/null and b/public/images/emoji/twitter/bow_and_arrow.png differ diff --git a/public/images/emoji/twitter/bowling.png b/public/images/emoji/twitter/bowling.png index 19e52cf0dbc..812f0dde2e7 100644 Binary files a/public/images/emoji/twitter/bowling.png and b/public/images/emoji/twitter/bowling.png differ diff --git a/public/images/emoji/twitter/boy.png b/public/images/emoji/twitter/boy.png index ebe4770d048..4608ebdd058 100644 Binary files a/public/images/emoji/twitter/boy.png and b/public/images/emoji/twitter/boy.png differ diff --git a/public/images/emoji/twitter/bread.png b/public/images/emoji/twitter/bread.png index 0e5c0a70a5c..668a89a6a7a 100644 Binary files a/public/images/emoji/twitter/bread.png and b/public/images/emoji/twitter/bread.png differ diff --git a/public/images/emoji/twitter/bride_with_veil.png b/public/images/emoji/twitter/bride_with_veil.png index cf753cdb8a2..8956c9df5d3 100644 Binary files a/public/images/emoji/twitter/bride_with_veil.png and b/public/images/emoji/twitter/bride_with_veil.png differ diff --git a/public/images/emoji/twitter/bridge_at_night.png b/public/images/emoji/twitter/bridge_at_night.png index 48fc34293ff..6f160d0f2f9 100644 Binary files a/public/images/emoji/twitter/bridge_at_night.png and b/public/images/emoji/twitter/bridge_at_night.png differ diff --git a/public/images/emoji/twitter/briefcase.png b/public/images/emoji/twitter/briefcase.png index be6b0777a08..2606250b698 100644 Binary files a/public/images/emoji/twitter/briefcase.png and b/public/images/emoji/twitter/briefcase.png differ diff --git a/public/images/emoji/twitter/broken_heart.png b/public/images/emoji/twitter/broken_heart.png index 9666f048446..52ded7181e8 100644 Binary files a/public/images/emoji/twitter/broken_heart.png and b/public/images/emoji/twitter/broken_heart.png differ diff --git a/public/images/emoji/twitter/bug.png b/public/images/emoji/twitter/bug.png index f37a34af0b2..ebc9db7f1c1 100644 Binary files a/public/images/emoji/twitter/bug.png and b/public/images/emoji/twitter/bug.png differ diff --git a/public/images/emoji/twitter/bulb.png b/public/images/emoji/twitter/bulb.png index 993543ec2fc..1bf108ae48d 100644 Binary files a/public/images/emoji/twitter/bulb.png and b/public/images/emoji/twitter/bulb.png differ diff --git a/public/images/emoji/twitter/bullettrain_front.png b/public/images/emoji/twitter/bullettrain_front.png index 0ddc6ac8bc2..53b6a90302d 100644 Binary files a/public/images/emoji/twitter/bullettrain_front.png and b/public/images/emoji/twitter/bullettrain_front.png differ diff --git a/public/images/emoji/twitter/bullettrain_side.png b/public/images/emoji/twitter/bullettrain_side.png index 6b8be83f3d2..e15146370a4 100644 Binary files a/public/images/emoji/twitter/bullettrain_side.png and b/public/images/emoji/twitter/bullettrain_side.png differ diff --git a/public/images/emoji/twitter/burrito.png b/public/images/emoji/twitter/burrito.png new file mode 100644 index 00000000000..74894241cc2 Binary files /dev/null and b/public/images/emoji/twitter/burrito.png differ diff --git a/public/images/emoji/twitter/bus.png b/public/images/emoji/twitter/bus.png index 49789c073eb..026598eb0c1 100644 Binary files a/public/images/emoji/twitter/bus.png and b/public/images/emoji/twitter/bus.png differ diff --git a/public/images/emoji/twitter/busstop.png b/public/images/emoji/twitter/busstop.png index 6bc1f9fd94a..1855119693d 100644 Binary files a/public/images/emoji/twitter/busstop.png and b/public/images/emoji/twitter/busstop.png differ diff --git a/public/images/emoji/twitter/bust_in_silhouette.png b/public/images/emoji/twitter/bust_in_silhouette.png index 07d1fb4eef0..b557434757a 100644 Binary files a/public/images/emoji/twitter/bust_in_silhouette.png and b/public/images/emoji/twitter/bust_in_silhouette.png differ diff --git a/public/images/emoji/twitter/busts_in_silhouette.png b/public/images/emoji/twitter/busts_in_silhouette.png index 15f824b9ecb..c3dca55c177 100644 Binary files a/public/images/emoji/twitter/busts_in_silhouette.png and b/public/images/emoji/twitter/busts_in_silhouette.png differ diff --git a/public/images/emoji/twitter/cactus.png b/public/images/emoji/twitter/cactus.png index 54f83949ee6..93328d849fd 100644 Binary files a/public/images/emoji/twitter/cactus.png and b/public/images/emoji/twitter/cactus.png differ diff --git a/public/images/emoji/twitter/cake.png b/public/images/emoji/twitter/cake.png index d81f9abb5a9..da9d0a87a4e 100644 Binary files a/public/images/emoji/twitter/cake.png and b/public/images/emoji/twitter/cake.png differ diff --git a/public/images/emoji/twitter/calendar.png b/public/images/emoji/twitter/calendar.png index 185e25a5642..038557af2e8 100644 Binary files a/public/images/emoji/twitter/calendar.png and b/public/images/emoji/twitter/calendar.png differ diff --git a/public/images/emoji/twitter/calendar_spiral.png b/public/images/emoji/twitter/calendar_spiral.png new file mode 100644 index 00000000000..e2edcfeeb3f Binary files /dev/null and b/public/images/emoji/twitter/calendar_spiral.png differ diff --git a/public/images/emoji/twitter/calling.png b/public/images/emoji/twitter/calling.png index 41d26d1b3f7..bcb0d974cd0 100644 Binary files a/public/images/emoji/twitter/calling.png and b/public/images/emoji/twitter/calling.png differ diff --git a/public/images/emoji/twitter/camel.png b/public/images/emoji/twitter/camel.png index 6417a70074d..5a1bd3644df 100644 Binary files a/public/images/emoji/twitter/camel.png and b/public/images/emoji/twitter/camel.png differ diff --git a/public/images/emoji/twitter/camera.png b/public/images/emoji/twitter/camera.png index 4cf79f30908..220e5c80c86 100644 Binary files a/public/images/emoji/twitter/camera.png and b/public/images/emoji/twitter/camera.png differ diff --git a/public/images/emoji/twitter/camera_with_flash.png b/public/images/emoji/twitter/camera_with_flash.png new file mode 100644 index 00000000000..ddb3b744bf9 Binary files /dev/null and b/public/images/emoji/twitter/camera_with_flash.png differ diff --git a/public/images/emoji/twitter/camping.png b/public/images/emoji/twitter/camping.png new file mode 100644 index 00000000000..1bcf75dfd4e Binary files /dev/null and b/public/images/emoji/twitter/camping.png differ diff --git a/public/images/emoji/twitter/cancer.png b/public/images/emoji/twitter/cancer.png index 3d1420a3981..5ed7c80d893 100644 Binary files a/public/images/emoji/twitter/cancer.png and b/public/images/emoji/twitter/cancer.png differ diff --git a/public/images/emoji/twitter/candle.png b/public/images/emoji/twitter/candle.png new file mode 100644 index 00000000000..57a63deca69 Binary files /dev/null and b/public/images/emoji/twitter/candle.png differ diff --git a/public/images/emoji/twitter/candy.png b/public/images/emoji/twitter/candy.png index 2d1d3378d0a..cb059ea1a11 100644 Binary files a/public/images/emoji/twitter/candy.png and b/public/images/emoji/twitter/candy.png differ diff --git a/public/images/emoji/twitter/capital_abcd.png b/public/images/emoji/twitter/capital_abcd.png index d5e843d70c7..9ffd881d575 100644 Binary files a/public/images/emoji/twitter/capital_abcd.png and b/public/images/emoji/twitter/capital_abcd.png differ diff --git a/public/images/emoji/twitter/capricorn.png b/public/images/emoji/twitter/capricorn.png index c3458d236f8..7ad5bccd30b 100644 Binary files a/public/images/emoji/twitter/capricorn.png and b/public/images/emoji/twitter/capricorn.png differ diff --git a/public/images/emoji/twitter/car.png b/public/images/emoji/twitter/car.png index 93610d2c438..ba0d2e7b226 100644 Binary files a/public/images/emoji/twitter/car.png and b/public/images/emoji/twitter/car.png differ diff --git a/public/images/emoji/twitter/card_box.png b/public/images/emoji/twitter/card_box.png new file mode 100644 index 00000000000..9a032fff610 Binary files /dev/null and b/public/images/emoji/twitter/card_box.png differ diff --git a/public/images/emoji/twitter/card_index.png b/public/images/emoji/twitter/card_index.png index 6621717911d..fc6c652e2e1 100644 Binary files a/public/images/emoji/twitter/card_index.png and b/public/images/emoji/twitter/card_index.png differ diff --git a/public/images/emoji/twitter/carousel_horse.png b/public/images/emoji/twitter/carousel_horse.png index df4c93d9b8a..c3222b35b62 100644 Binary files a/public/images/emoji/twitter/carousel_horse.png and b/public/images/emoji/twitter/carousel_horse.png differ diff --git a/public/images/emoji/twitter/cat.png b/public/images/emoji/twitter/cat.png index 131059b4918..831bdaaa3af 100644 Binary files a/public/images/emoji/twitter/cat.png and b/public/images/emoji/twitter/cat.png differ diff --git a/public/images/emoji/twitter/cat2.png b/public/images/emoji/twitter/cat2.png index 9d2b681d7e7..2bb709fedda 100644 Binary files a/public/images/emoji/twitter/cat2.png and b/public/images/emoji/twitter/cat2.png differ diff --git a/public/images/emoji/twitter/cd.png b/public/images/emoji/twitter/cd.png index 29f3a72e78a..939c2dbebec 100644 Binary files a/public/images/emoji/twitter/cd.png and b/public/images/emoji/twitter/cd.png differ diff --git a/public/images/emoji/twitter/chains.png b/public/images/emoji/twitter/chains.png new file mode 100644 index 00000000000..15b22f2e758 Binary files /dev/null and b/public/images/emoji/twitter/chains.png differ diff --git a/public/images/emoji/twitter/champagne.png b/public/images/emoji/twitter/champagne.png new file mode 100644 index 00000000000..f27c9ea1e26 Binary files /dev/null and b/public/images/emoji/twitter/champagne.png differ diff --git a/public/images/emoji/twitter/chart.png b/public/images/emoji/twitter/chart.png index d45ccad87db..b94b21ee4c9 100644 Binary files a/public/images/emoji/twitter/chart.png and b/public/images/emoji/twitter/chart.png differ diff --git a/public/images/emoji/twitter/chart_with_downwards_trend.png b/public/images/emoji/twitter/chart_with_downwards_trend.png index c15b13dcfb4..b31545daf2f 100644 Binary files a/public/images/emoji/twitter/chart_with_downwards_trend.png and b/public/images/emoji/twitter/chart_with_downwards_trend.png differ diff --git a/public/images/emoji/twitter/chart_with_upwards_trend.png b/public/images/emoji/twitter/chart_with_upwards_trend.png index 27eec28511e..8b8e8be4022 100644 Binary files a/public/images/emoji/twitter/chart_with_upwards_trend.png and b/public/images/emoji/twitter/chart_with_upwards_trend.png differ diff --git a/public/images/emoji/twitter/checkered_flag.png b/public/images/emoji/twitter/checkered_flag.png index e9f90e3ffd0..0abec34b60b 100644 Binary files a/public/images/emoji/twitter/checkered_flag.png and b/public/images/emoji/twitter/checkered_flag.png differ diff --git a/public/images/emoji/twitter/cheese.png b/public/images/emoji/twitter/cheese.png new file mode 100644 index 00000000000..8566b2e59b5 Binary files /dev/null and b/public/images/emoji/twitter/cheese.png differ diff --git a/public/images/emoji/twitter/cherries.png b/public/images/emoji/twitter/cherries.png index 7ef46a065d9..a55c87f316a 100644 Binary files a/public/images/emoji/twitter/cherries.png and b/public/images/emoji/twitter/cherries.png differ diff --git a/public/images/emoji/twitter/cherry_blossom.png b/public/images/emoji/twitter/cherry_blossom.png index 423f93d75cd..d8300af3cbe 100644 Binary files a/public/images/emoji/twitter/cherry_blossom.png and b/public/images/emoji/twitter/cherry_blossom.png differ diff --git a/public/images/emoji/twitter/chestnut.png b/public/images/emoji/twitter/chestnut.png index bc6f3189d4d..87712a81db9 100644 Binary files a/public/images/emoji/twitter/chestnut.png and b/public/images/emoji/twitter/chestnut.png differ diff --git a/public/images/emoji/twitter/chicken.png b/public/images/emoji/twitter/chicken.png index 8a11e60698c..f43d7b2ea56 100644 Binary files a/public/images/emoji/twitter/chicken.png and b/public/images/emoji/twitter/chicken.png differ diff --git a/public/images/emoji/twitter/children_crossing.png b/public/images/emoji/twitter/children_crossing.png index 585f42852ee..e9a4a607b02 100644 Binary files a/public/images/emoji/twitter/children_crossing.png and b/public/images/emoji/twitter/children_crossing.png differ diff --git a/public/images/emoji/twitter/chipmunk.png b/public/images/emoji/twitter/chipmunk.png new file mode 100644 index 00000000000..e46b2790d62 Binary files /dev/null and b/public/images/emoji/twitter/chipmunk.png differ diff --git a/public/images/emoji/twitter/chocolate_bar.png b/public/images/emoji/twitter/chocolate_bar.png index 1339a7f3709..d8795d24b49 100644 Binary files a/public/images/emoji/twitter/chocolate_bar.png and b/public/images/emoji/twitter/chocolate_bar.png differ diff --git a/public/images/emoji/twitter/christmas_tree.png b/public/images/emoji/twitter/christmas_tree.png index c8329d1eb0d..4cbc21a58a6 100644 Binary files a/public/images/emoji/twitter/christmas_tree.png and b/public/images/emoji/twitter/christmas_tree.png differ diff --git a/public/images/emoji/twitter/church.png b/public/images/emoji/twitter/church.png index 89cbc84b255..f87d2311e8f 100644 Binary files a/public/images/emoji/twitter/church.png and b/public/images/emoji/twitter/church.png differ diff --git a/public/images/emoji/twitter/cinema.png b/public/images/emoji/twitter/cinema.png index 186f11e0070..2ba12b0eef2 100644 Binary files a/public/images/emoji/twitter/cinema.png and b/public/images/emoji/twitter/cinema.png differ diff --git a/public/images/emoji/twitter/circus_tent.png b/public/images/emoji/twitter/circus_tent.png index 362b8be7308..60b95ec378d 100644 Binary files a/public/images/emoji/twitter/circus_tent.png and b/public/images/emoji/twitter/circus_tent.png differ diff --git a/public/images/emoji/twitter/city_dusk.png b/public/images/emoji/twitter/city_dusk.png new file mode 100644 index 00000000000..2fd9ace38c9 Binary files /dev/null and b/public/images/emoji/twitter/city_dusk.png differ diff --git a/public/images/emoji/twitter/city_sunrise.png b/public/images/emoji/twitter/city_sunrise.png index 5bf1a5a85d7..305b7915ea4 100644 Binary files a/public/images/emoji/twitter/city_sunrise.png and b/public/images/emoji/twitter/city_sunrise.png differ diff --git a/public/images/emoji/twitter/city_sunset.png b/public/images/emoji/twitter/city_sunset.png index 087f9b4eecf..8895045b765 100644 Binary files a/public/images/emoji/twitter/city_sunset.png and b/public/images/emoji/twitter/city_sunset.png differ diff --git a/public/images/emoji/twitter/cityscape.png b/public/images/emoji/twitter/cityscape.png new file mode 100644 index 00000000000..74a0df8a9a0 Binary files /dev/null and b/public/images/emoji/twitter/cityscape.png differ diff --git a/public/images/emoji/twitter/cl.png b/public/images/emoji/twitter/cl.png index c80ff2c21b1..58b666069d3 100644 Binary files a/public/images/emoji/twitter/cl.png and b/public/images/emoji/twitter/cl.png differ diff --git a/public/images/emoji/twitter/clap.png b/public/images/emoji/twitter/clap.png index 5683995f1b9..6e6191a43d3 100644 Binary files a/public/images/emoji/twitter/clap.png and b/public/images/emoji/twitter/clap.png differ diff --git a/public/images/emoji/twitter/clapper.png b/public/images/emoji/twitter/clapper.png index 68b61925a68..d1dc8905396 100644 Binary files a/public/images/emoji/twitter/clapper.png and b/public/images/emoji/twitter/clapper.png differ diff --git a/public/images/emoji/twitter/classical_building.png b/public/images/emoji/twitter/classical_building.png new file mode 100644 index 00000000000..4e9508d6961 Binary files /dev/null and b/public/images/emoji/twitter/classical_building.png differ diff --git a/public/images/emoji/twitter/clipboard.png b/public/images/emoji/twitter/clipboard.png index b04e37a5f2f..3426bcbd6ca 100644 Binary files a/public/images/emoji/twitter/clipboard.png and b/public/images/emoji/twitter/clipboard.png differ diff --git a/public/images/emoji/twitter/clock.png b/public/images/emoji/twitter/clock.png new file mode 100644 index 00000000000..028f514b37a Binary files /dev/null and b/public/images/emoji/twitter/clock.png differ diff --git a/public/images/emoji/twitter/clock1.png b/public/images/emoji/twitter/clock1.png index 766f09a00fe..4b5fb60f5b9 100644 Binary files a/public/images/emoji/twitter/clock1.png and b/public/images/emoji/twitter/clock1.png differ diff --git a/public/images/emoji/twitter/clock10.png b/public/images/emoji/twitter/clock10.png index 6bb74629318..99e1160d68f 100644 Binary files a/public/images/emoji/twitter/clock10.png and b/public/images/emoji/twitter/clock10.png differ diff --git a/public/images/emoji/twitter/clock1030.png b/public/images/emoji/twitter/clock1030.png index 5894b04e67a..cb56d218347 100644 Binary files a/public/images/emoji/twitter/clock1030.png and b/public/images/emoji/twitter/clock1030.png differ diff --git a/public/images/emoji/twitter/clock11.png b/public/images/emoji/twitter/clock11.png index eb17f8ceb7f..a3328388f5e 100644 Binary files a/public/images/emoji/twitter/clock11.png and b/public/images/emoji/twitter/clock11.png differ diff --git a/public/images/emoji/twitter/clock1130.png b/public/images/emoji/twitter/clock1130.png index 946959ae5a4..737710ab8cc 100644 Binary files a/public/images/emoji/twitter/clock1130.png and b/public/images/emoji/twitter/clock1130.png differ diff --git a/public/images/emoji/twitter/clock12.png b/public/images/emoji/twitter/clock12.png index 3eedd9f589f..78fa0a78f2d 100644 Binary files a/public/images/emoji/twitter/clock12.png and b/public/images/emoji/twitter/clock12.png differ diff --git a/public/images/emoji/twitter/clock1230.png b/public/images/emoji/twitter/clock1230.png index 8fa3fc2d4c2..a43eb1c8e9c 100644 Binary files a/public/images/emoji/twitter/clock1230.png and b/public/images/emoji/twitter/clock1230.png differ diff --git a/public/images/emoji/twitter/clock130.png b/public/images/emoji/twitter/clock130.png index fadb2d700a1..194437e6ad7 100644 Binary files a/public/images/emoji/twitter/clock130.png and b/public/images/emoji/twitter/clock130.png differ diff --git a/public/images/emoji/twitter/clock2.png b/public/images/emoji/twitter/clock2.png index 28b580392b9..14dca1d4b85 100644 Binary files a/public/images/emoji/twitter/clock2.png and b/public/images/emoji/twitter/clock2.png differ diff --git a/public/images/emoji/twitter/clock230.png b/public/images/emoji/twitter/clock230.png index 2ea515b453c..61ef308ad38 100644 Binary files a/public/images/emoji/twitter/clock230.png and b/public/images/emoji/twitter/clock230.png differ diff --git a/public/images/emoji/twitter/clock3.png b/public/images/emoji/twitter/clock3.png index b6838e5d9a7..0cd3b410eb1 100644 Binary files a/public/images/emoji/twitter/clock3.png and b/public/images/emoji/twitter/clock3.png differ diff --git a/public/images/emoji/twitter/clock330.png b/public/images/emoji/twitter/clock330.png index 5dd74542688..68edcb9017d 100644 Binary files a/public/images/emoji/twitter/clock330.png and b/public/images/emoji/twitter/clock330.png differ diff --git a/public/images/emoji/twitter/clock4.png b/public/images/emoji/twitter/clock4.png index 40acf8c04d7..ed1884f4bdd 100644 Binary files a/public/images/emoji/twitter/clock4.png and b/public/images/emoji/twitter/clock4.png differ diff --git a/public/images/emoji/twitter/clock430.png b/public/images/emoji/twitter/clock430.png index db6765d4bc3..596aae2f033 100644 Binary files a/public/images/emoji/twitter/clock430.png and b/public/images/emoji/twitter/clock430.png differ diff --git a/public/images/emoji/twitter/clock5.png b/public/images/emoji/twitter/clock5.png index 43b9718de03..f63bb552571 100644 Binary files a/public/images/emoji/twitter/clock5.png and b/public/images/emoji/twitter/clock5.png differ diff --git a/public/images/emoji/twitter/clock530.png b/public/images/emoji/twitter/clock530.png index f7a5b76d3aa..ff4e898b8cd 100644 Binary files a/public/images/emoji/twitter/clock530.png and b/public/images/emoji/twitter/clock530.png differ diff --git a/public/images/emoji/twitter/clock6.png b/public/images/emoji/twitter/clock6.png index c3c1fa85ba7..d4b81c9829a 100644 Binary files a/public/images/emoji/twitter/clock6.png and b/public/images/emoji/twitter/clock6.png differ diff --git a/public/images/emoji/twitter/clock630.png b/public/images/emoji/twitter/clock630.png index 48c5d0a3c80..bcd86cf9ad7 100644 Binary files a/public/images/emoji/twitter/clock630.png and b/public/images/emoji/twitter/clock630.png differ diff --git a/public/images/emoji/twitter/clock7.png b/public/images/emoji/twitter/clock7.png index 5f04fcda122..7b79ac44da0 100644 Binary files a/public/images/emoji/twitter/clock7.png and b/public/images/emoji/twitter/clock7.png differ diff --git a/public/images/emoji/twitter/clock730.png b/public/images/emoji/twitter/clock730.png index dad3fd39c87..05b28847c42 100644 Binary files a/public/images/emoji/twitter/clock730.png and b/public/images/emoji/twitter/clock730.png differ diff --git a/public/images/emoji/twitter/clock8.png b/public/images/emoji/twitter/clock8.png index 446da51fc9f..653d076aa75 100644 Binary files a/public/images/emoji/twitter/clock8.png and b/public/images/emoji/twitter/clock8.png differ diff --git a/public/images/emoji/twitter/clock830.png b/public/images/emoji/twitter/clock830.png index 5ae1273f3c2..b04e87bf079 100644 Binary files a/public/images/emoji/twitter/clock830.png and b/public/images/emoji/twitter/clock830.png differ diff --git a/public/images/emoji/twitter/clock9.png b/public/images/emoji/twitter/clock9.png index c5ff5261ec5..20dc0c0a4df 100644 Binary files a/public/images/emoji/twitter/clock9.png and b/public/images/emoji/twitter/clock9.png differ diff --git a/public/images/emoji/twitter/clock930.png b/public/images/emoji/twitter/clock930.png index 2c726282a2e..618d8ee5b3f 100644 Binary files a/public/images/emoji/twitter/clock930.png and b/public/images/emoji/twitter/clock930.png differ diff --git a/public/images/emoji/twitter/closed_book.png b/public/images/emoji/twitter/closed_book.png index 8436c5ff83f..75ddc431186 100644 Binary files a/public/images/emoji/twitter/closed_book.png and b/public/images/emoji/twitter/closed_book.png differ diff --git a/public/images/emoji/twitter/closed_lock_with_key.png b/public/images/emoji/twitter/closed_lock_with_key.png index 5bd299e00ea..153ae4f1a68 100644 Binary files a/public/images/emoji/twitter/closed_lock_with_key.png and b/public/images/emoji/twitter/closed_lock_with_key.png differ diff --git a/public/images/emoji/twitter/closed_umbrella.png b/public/images/emoji/twitter/closed_umbrella.png index 6baf7e2199c..ac173936fbf 100644 Binary files a/public/images/emoji/twitter/closed_umbrella.png and b/public/images/emoji/twitter/closed_umbrella.png differ diff --git a/public/images/emoji/twitter/cloud.png b/public/images/emoji/twitter/cloud.png index 8cd5827eb4d..e553459c27d 100644 Binary files a/public/images/emoji/twitter/cloud.png and b/public/images/emoji/twitter/cloud.png differ diff --git a/public/images/emoji/twitter/cloud_lightning.png b/public/images/emoji/twitter/cloud_lightning.png new file mode 100644 index 00000000000..032be57a738 Binary files /dev/null and b/public/images/emoji/twitter/cloud_lightning.png differ diff --git a/public/images/emoji/twitter/cloud_rain.png b/public/images/emoji/twitter/cloud_rain.png new file mode 100644 index 00000000000..d7f1c989642 Binary files /dev/null and b/public/images/emoji/twitter/cloud_rain.png differ diff --git a/public/images/emoji/twitter/cloud_snow.png b/public/images/emoji/twitter/cloud_snow.png new file mode 100644 index 00000000000..e7c797ba25a Binary files /dev/null and b/public/images/emoji/twitter/cloud_snow.png differ diff --git a/public/images/emoji/twitter/cloud_tornado.png b/public/images/emoji/twitter/cloud_tornado.png new file mode 100644 index 00000000000..720f7faec96 Binary files /dev/null and b/public/images/emoji/twitter/cloud_tornado.png differ diff --git a/public/images/emoji/twitter/clubs.png b/public/images/emoji/twitter/clubs.png index a6ca677262c..ae7bc0051cd 100644 Binary files a/public/images/emoji/twitter/clubs.png and b/public/images/emoji/twitter/clubs.png differ diff --git a/public/images/emoji/twitter/cn.png b/public/images/emoji/twitter/cn.png index de68ae2a232..56c2dfe2382 100644 Binary files a/public/images/emoji/twitter/cn.png and b/public/images/emoji/twitter/cn.png differ diff --git a/public/images/emoji/twitter/cocktail.png b/public/images/emoji/twitter/cocktail.png index 6cd28f2e6f5..ecad120d407 100644 Binary files a/public/images/emoji/twitter/cocktail.png and b/public/images/emoji/twitter/cocktail.png differ diff --git a/public/images/emoji/twitter/coffee.png b/public/images/emoji/twitter/coffee.png index 831a18d2dcc..ebe28a16f40 100644 Binary files a/public/images/emoji/twitter/coffee.png and b/public/images/emoji/twitter/coffee.png differ diff --git a/public/images/emoji/twitter/coffin.png b/public/images/emoji/twitter/coffin.png new file mode 100644 index 00000000000..c61f4912f4b Binary files /dev/null and b/public/images/emoji/twitter/coffin.png differ diff --git a/public/images/emoji/twitter/cold_sweat.png b/public/images/emoji/twitter/cold_sweat.png index 64bba6550aa..67780294cd1 100644 Binary files a/public/images/emoji/twitter/cold_sweat.png and b/public/images/emoji/twitter/cold_sweat.png differ diff --git a/public/images/emoji/twitter/comet.png b/public/images/emoji/twitter/comet.png new file mode 100644 index 00000000000..4ddea9ad812 Binary files /dev/null and b/public/images/emoji/twitter/comet.png differ diff --git a/public/images/emoji/twitter/compression.png b/public/images/emoji/twitter/compression.png new file mode 100644 index 00000000000..b22237fb7f2 Binary files /dev/null and b/public/images/emoji/twitter/compression.png differ diff --git a/public/images/emoji/twitter/computer.png b/public/images/emoji/twitter/computer.png index 5f1241a227e..43618584b4e 100644 Binary files a/public/images/emoji/twitter/computer.png and b/public/images/emoji/twitter/computer.png differ diff --git a/public/images/emoji/twitter/confetti_ball.png b/public/images/emoji/twitter/confetti_ball.png index cde7370c2ca..62648eb394b 100644 Binary files a/public/images/emoji/twitter/confetti_ball.png and b/public/images/emoji/twitter/confetti_ball.png differ diff --git a/public/images/emoji/twitter/confounded.png b/public/images/emoji/twitter/confounded.png index 391887eb468..62bd8dc0b15 100644 Binary files a/public/images/emoji/twitter/confounded.png and b/public/images/emoji/twitter/confounded.png differ diff --git a/public/images/emoji/twitter/confused.png b/public/images/emoji/twitter/confused.png index b5c5b0752ca..b51470710e4 100644 Binary files a/public/images/emoji/twitter/confused.png and b/public/images/emoji/twitter/confused.png differ diff --git a/public/images/emoji/twitter/congratulations.png b/public/images/emoji/twitter/congratulations.png index 43941cf9603..0dd4c5a4846 100644 Binary files a/public/images/emoji/twitter/congratulations.png and b/public/images/emoji/twitter/congratulations.png differ diff --git a/public/images/emoji/twitter/construction.png b/public/images/emoji/twitter/construction.png index 9ad7eb08037..15770f5ae1b 100644 Binary files a/public/images/emoji/twitter/construction.png and b/public/images/emoji/twitter/construction.png differ diff --git a/public/images/emoji/twitter/construction_site.png b/public/images/emoji/twitter/construction_site.png new file mode 100644 index 00000000000..082a7432656 Binary files /dev/null and b/public/images/emoji/twitter/construction_site.png differ diff --git a/public/images/emoji/twitter/construction_worker.png b/public/images/emoji/twitter/construction_worker.png index 9275fc25564..1ee477f893f 100644 Binary files a/public/images/emoji/twitter/construction_worker.png and b/public/images/emoji/twitter/construction_worker.png differ diff --git a/public/images/emoji/twitter/control_knobs.png b/public/images/emoji/twitter/control_knobs.png new file mode 100644 index 00000000000..336be918781 Binary files /dev/null and b/public/images/emoji/twitter/control_knobs.png differ diff --git a/public/images/emoji/twitter/convenience_store.png b/public/images/emoji/twitter/convenience_store.png index 5384f549831..e3b7a4a120d 100644 Binary files a/public/images/emoji/twitter/convenience_store.png and b/public/images/emoji/twitter/convenience_store.png differ diff --git a/public/images/emoji/twitter/cookie.png b/public/images/emoji/twitter/cookie.png index f558874b029..f0e17ef8533 100644 Binary files a/public/images/emoji/twitter/cookie.png and b/public/images/emoji/twitter/cookie.png differ diff --git a/public/images/emoji/twitter/cool.png b/public/images/emoji/twitter/cool.png index 768286f26fe..8eccf0c8044 100644 Binary files a/public/images/emoji/twitter/cool.png and b/public/images/emoji/twitter/cool.png differ diff --git a/public/images/emoji/twitter/cop.png b/public/images/emoji/twitter/cop.png index 0ee11b9040f..36e81979350 100644 Binary files a/public/images/emoji/twitter/cop.png and b/public/images/emoji/twitter/cop.png differ diff --git a/public/images/emoji/twitter/copyright.png b/public/images/emoji/twitter/copyright.png index 48699b6e462..222a02cd2a2 100644 Binary files a/public/images/emoji/twitter/copyright.png and b/public/images/emoji/twitter/copyright.png differ diff --git a/public/images/emoji/twitter/corn.png b/public/images/emoji/twitter/corn.png index 941a8085a8d..bd39f0bd64f 100644 Binary files a/public/images/emoji/twitter/corn.png and b/public/images/emoji/twitter/corn.png differ diff --git a/public/images/emoji/twitter/couch.png b/public/images/emoji/twitter/couch.png new file mode 100644 index 00000000000..56a8bfa9edb Binary files /dev/null and b/public/images/emoji/twitter/couch.png differ diff --git a/public/images/emoji/twitter/couple.png b/public/images/emoji/twitter/couple.png index 3a7c20a76cd..9eb4d7d8448 100644 Binary files a/public/images/emoji/twitter/couple.png and b/public/images/emoji/twitter/couple.png differ diff --git a/public/images/emoji/twitter/couple_with_heart.png b/public/images/emoji/twitter/couple_with_heart.png index d8a2a1f9472..8abca3bf432 100644 Binary files a/public/images/emoji/twitter/couple_with_heart.png and b/public/images/emoji/twitter/couple_with_heart.png differ diff --git a/public/images/emoji/twitter/couplekiss.png b/public/images/emoji/twitter/couplekiss.png index 2f1bb00cd57..e265ea5f058 100644 Binary files a/public/images/emoji/twitter/couplekiss.png and b/public/images/emoji/twitter/couplekiss.png differ diff --git a/public/images/emoji/twitter/cow.png b/public/images/emoji/twitter/cow.png index 498220c09f7..7dcd6847d46 100644 Binary files a/public/images/emoji/twitter/cow.png and b/public/images/emoji/twitter/cow.png differ diff --git a/public/images/emoji/twitter/cow2.png b/public/images/emoji/twitter/cow2.png index 7f3c3d65fbb..549bcd72ac0 100644 Binary files a/public/images/emoji/twitter/cow2.png and b/public/images/emoji/twitter/cow2.png differ diff --git a/public/images/emoji/twitter/crab.png b/public/images/emoji/twitter/crab.png new file mode 100644 index 00000000000..021356a53d2 Binary files /dev/null and b/public/images/emoji/twitter/crab.png differ diff --git a/public/images/emoji/twitter/crayon.png b/public/images/emoji/twitter/crayon.png new file mode 100644 index 00000000000..d309e3ba3a4 Binary files /dev/null and b/public/images/emoji/twitter/crayon.png differ diff --git a/public/images/emoji/twitter/credit_card.png b/public/images/emoji/twitter/credit_card.png index 80e559e3111..5f8f1229b61 100644 Binary files a/public/images/emoji/twitter/credit_card.png and b/public/images/emoji/twitter/credit_card.png differ diff --git a/public/images/emoji/twitter/crescent_moon.png b/public/images/emoji/twitter/crescent_moon.png index b8eab76ece9..353c19d84e8 100644 Binary files a/public/images/emoji/twitter/crescent_moon.png and b/public/images/emoji/twitter/crescent_moon.png differ diff --git a/public/images/emoji/twitter/cricket.png b/public/images/emoji/twitter/cricket.png new file mode 100644 index 00000000000..128d9efa82f Binary files /dev/null and b/public/images/emoji/twitter/cricket.png differ diff --git a/public/images/emoji/twitter/crocodile.png b/public/images/emoji/twitter/crocodile.png index 37aa7ddd01d..0dee6b8e344 100644 Binary files a/public/images/emoji/twitter/crocodile.png and b/public/images/emoji/twitter/crocodile.png differ diff --git a/public/images/emoji/twitter/cross.png b/public/images/emoji/twitter/cross.png new file mode 100644 index 00000000000..53f8e5cd4b0 Binary files /dev/null and b/public/images/emoji/twitter/cross.png differ diff --git a/public/images/emoji/twitter/crossed_flags.png b/public/images/emoji/twitter/crossed_flags.png index c96898fa681..33fd9fba3cc 100644 Binary files a/public/images/emoji/twitter/crossed_flags.png and b/public/images/emoji/twitter/crossed_flags.png differ diff --git a/public/images/emoji/twitter/crossed_swords.png b/public/images/emoji/twitter/crossed_swords.png new file mode 100644 index 00000000000..ec1da04367b Binary files /dev/null and b/public/images/emoji/twitter/crossed_swords.png differ diff --git a/public/images/emoji/twitter/crown.png b/public/images/emoji/twitter/crown.png index 6fc5359bfed..c54072e8d18 100644 Binary files a/public/images/emoji/twitter/crown.png and b/public/images/emoji/twitter/crown.png differ diff --git a/public/images/emoji/twitter/cruise_ship.png b/public/images/emoji/twitter/cruise_ship.png new file mode 100644 index 00000000000..99ea24ed751 Binary files /dev/null and b/public/images/emoji/twitter/cruise_ship.png differ diff --git a/public/images/emoji/twitter/cry.png b/public/images/emoji/twitter/cry.png index 3cedd100246..2957a058cf4 100644 Binary files a/public/images/emoji/twitter/cry.png and b/public/images/emoji/twitter/cry.png differ diff --git a/public/images/emoji/twitter/crying_cat_face.png b/public/images/emoji/twitter/crying_cat_face.png index 112d9b08d97..a5fe5d14107 100644 Binary files a/public/images/emoji/twitter/crying_cat_face.png and b/public/images/emoji/twitter/crying_cat_face.png differ diff --git a/public/images/emoji/twitter/crystal_ball.png b/public/images/emoji/twitter/crystal_ball.png index bc73165e376..3bc0ce3cd5a 100644 Binary files a/public/images/emoji/twitter/crystal_ball.png and b/public/images/emoji/twitter/crystal_ball.png differ diff --git a/public/images/emoji/twitter/cupid.png b/public/images/emoji/twitter/cupid.png index 635adec9768..e8a56cf2685 100644 Binary files a/public/images/emoji/twitter/cupid.png and b/public/images/emoji/twitter/cupid.png differ diff --git a/public/images/emoji/twitter/curly_loop.png b/public/images/emoji/twitter/curly_loop.png index dfd006b6baa..b189d1bc4f5 100644 Binary files a/public/images/emoji/twitter/curly_loop.png and b/public/images/emoji/twitter/curly_loop.png differ diff --git a/public/images/emoji/twitter/currency_exchange.png b/public/images/emoji/twitter/currency_exchange.png index a6a295083f0..6784ecd8977 100644 Binary files a/public/images/emoji/twitter/currency_exchange.png and b/public/images/emoji/twitter/currency_exchange.png differ diff --git a/public/images/emoji/twitter/curry.png b/public/images/emoji/twitter/curry.png index 6708a387c1d..650602ab586 100644 Binary files a/public/images/emoji/twitter/curry.png and b/public/images/emoji/twitter/curry.png differ diff --git a/public/images/emoji/twitter/custard.png b/public/images/emoji/twitter/custard.png index 3b740c002ab..5edf08274b8 100644 Binary files a/public/images/emoji/twitter/custard.png and b/public/images/emoji/twitter/custard.png differ diff --git a/public/images/emoji/twitter/customs.png b/public/images/emoji/twitter/customs.png index 7f51eac1fa0..fed5923232b 100644 Binary files a/public/images/emoji/twitter/customs.png and b/public/images/emoji/twitter/customs.png differ diff --git a/public/images/emoji/twitter/cyclone.png b/public/images/emoji/twitter/cyclone.png index 81298ee38e4..e9747a509ae 100644 Binary files a/public/images/emoji/twitter/cyclone.png and b/public/images/emoji/twitter/cyclone.png differ diff --git a/public/images/emoji/twitter/dagger.png b/public/images/emoji/twitter/dagger.png new file mode 100644 index 00000000000..85607ff4c04 Binary files /dev/null and b/public/images/emoji/twitter/dagger.png differ diff --git a/public/images/emoji/twitter/dancer.png b/public/images/emoji/twitter/dancer.png index 383a7b7bf88..3d80c20ec33 100644 Binary files a/public/images/emoji/twitter/dancer.png and b/public/images/emoji/twitter/dancer.png differ diff --git a/public/images/emoji/twitter/dancers.png b/public/images/emoji/twitter/dancers.png index 52768b4abe5..368e10d3354 100644 Binary files a/public/images/emoji/twitter/dancers.png and b/public/images/emoji/twitter/dancers.png differ diff --git a/public/images/emoji/twitter/dango.png b/public/images/emoji/twitter/dango.png index 8567a28537c..c1bc99fa29a 100644 Binary files a/public/images/emoji/twitter/dango.png and b/public/images/emoji/twitter/dango.png differ diff --git a/public/images/emoji/twitter/dark_sunglasses.png b/public/images/emoji/twitter/dark_sunglasses.png new file mode 100644 index 00000000000..5e20bb49f5f Binary files /dev/null and b/public/images/emoji/twitter/dark_sunglasses.png differ diff --git a/public/images/emoji/twitter/dart.png b/public/images/emoji/twitter/dart.png index 812f3354218..97d1606dff7 100644 Binary files a/public/images/emoji/twitter/dart.png and b/public/images/emoji/twitter/dart.png differ diff --git a/public/images/emoji/twitter/dash.png b/public/images/emoji/twitter/dash.png index bbcd065b11b..60bf7a57421 100644 Binary files a/public/images/emoji/twitter/dash.png and b/public/images/emoji/twitter/dash.png differ diff --git a/public/images/emoji/twitter/date.png b/public/images/emoji/twitter/date.png index 1f65765e492..830bebb96de 100644 Binary files a/public/images/emoji/twitter/date.png and b/public/images/emoji/twitter/date.png differ diff --git a/public/images/emoji/twitter/de.png b/public/images/emoji/twitter/de.png index 6c989908889..576dcd27b10 100644 Binary files a/public/images/emoji/twitter/de.png and b/public/images/emoji/twitter/de.png differ diff --git a/public/images/emoji/twitter/deciduous_tree.png b/public/images/emoji/twitter/deciduous_tree.png index 34a0a9516f7..97ab7f595ef 100644 Binary files a/public/images/emoji/twitter/deciduous_tree.png and b/public/images/emoji/twitter/deciduous_tree.png differ diff --git a/public/images/emoji/twitter/department_store.png b/public/images/emoji/twitter/department_store.png index 473ac9921eb..c6c2556338e 100644 Binary files a/public/images/emoji/twitter/department_store.png and b/public/images/emoji/twitter/department_store.png differ diff --git a/public/images/emoji/twitter/desert.png b/public/images/emoji/twitter/desert.png new file mode 100644 index 00000000000..3ec8a867b45 Binary files /dev/null and b/public/images/emoji/twitter/desert.png differ diff --git a/public/images/emoji/twitter/desktop.png b/public/images/emoji/twitter/desktop.png new file mode 100644 index 00000000000..ba57371eba4 Binary files /dev/null and b/public/images/emoji/twitter/desktop.png differ diff --git a/public/images/emoji/twitter/diamond_shape_with_a_dot_inside.png b/public/images/emoji/twitter/diamond_shape_with_a_dot_inside.png index ad16b8b899a..43d6967c044 100644 Binary files a/public/images/emoji/twitter/diamond_shape_with_a_dot_inside.png and b/public/images/emoji/twitter/diamond_shape_with_a_dot_inside.png differ diff --git a/public/images/emoji/twitter/diamonds.png b/public/images/emoji/twitter/diamonds.png index b9f3ca876a2..8fd4e2de308 100644 Binary files a/public/images/emoji/twitter/diamonds.png and b/public/images/emoji/twitter/diamonds.png differ diff --git a/public/images/emoji/twitter/disappointed.png b/public/images/emoji/twitter/disappointed.png index 22bf80de004..7bbd57a6da8 100644 Binary files a/public/images/emoji/twitter/disappointed.png and b/public/images/emoji/twitter/disappointed.png differ diff --git a/public/images/emoji/twitter/disappointed_relieved.png b/public/images/emoji/twitter/disappointed_relieved.png index d73d8a31f70..6f2fe9d847a 100644 Binary files a/public/images/emoji/twitter/disappointed_relieved.png and b/public/images/emoji/twitter/disappointed_relieved.png differ diff --git a/public/images/emoji/twitter/dividers.png b/public/images/emoji/twitter/dividers.png new file mode 100644 index 00000000000..fe01846bb50 Binary files /dev/null and b/public/images/emoji/twitter/dividers.png differ diff --git a/public/images/emoji/twitter/dizzy.png b/public/images/emoji/twitter/dizzy.png index f6b9920ab96..8e44e593a1a 100644 Binary files a/public/images/emoji/twitter/dizzy.png and b/public/images/emoji/twitter/dizzy.png differ diff --git a/public/images/emoji/twitter/dizzy_face.png b/public/images/emoji/twitter/dizzy_face.png index 45d3443efc4..a6417859682 100644 Binary files a/public/images/emoji/twitter/dizzy_face.png and b/public/images/emoji/twitter/dizzy_face.png differ diff --git a/public/images/emoji/twitter/do_not_litter.png b/public/images/emoji/twitter/do_not_litter.png index 235ceccc5cf..95cc973a197 100644 Binary files a/public/images/emoji/twitter/do_not_litter.png and b/public/images/emoji/twitter/do_not_litter.png differ diff --git a/public/images/emoji/twitter/dog.png b/public/images/emoji/twitter/dog.png index cb5afae151a..c8b0b70c67b 100644 Binary files a/public/images/emoji/twitter/dog.png and b/public/images/emoji/twitter/dog.png differ diff --git a/public/images/emoji/twitter/dog2.png b/public/images/emoji/twitter/dog2.png index 544b06c57e8..e92f1df08e1 100644 Binary files a/public/images/emoji/twitter/dog2.png and b/public/images/emoji/twitter/dog2.png differ diff --git a/public/images/emoji/twitter/dollar.png b/public/images/emoji/twitter/dollar.png index a6fc28564c4..54c20f7f597 100644 Binary files a/public/images/emoji/twitter/dollar.png and b/public/images/emoji/twitter/dollar.png differ diff --git a/public/images/emoji/twitter/dolls.png b/public/images/emoji/twitter/dolls.png index 2091a47e4b7..61e39c8289b 100644 Binary files a/public/images/emoji/twitter/dolls.png and b/public/images/emoji/twitter/dolls.png differ diff --git a/public/images/emoji/twitter/dolphin.png b/public/images/emoji/twitter/dolphin.png index 38c764d8780..60559867def 100644 Binary files a/public/images/emoji/twitter/dolphin.png and b/public/images/emoji/twitter/dolphin.png differ diff --git a/public/images/emoji/twitter/door.png b/public/images/emoji/twitter/door.png index b812516a8ec..7ec70cfced0 100644 Binary files a/public/images/emoji/twitter/door.png and b/public/images/emoji/twitter/door.png differ diff --git a/public/images/emoji/twitter/doughnut.png b/public/images/emoji/twitter/doughnut.png index 77fbe577013..a11d44e0f1f 100644 Binary files a/public/images/emoji/twitter/doughnut.png and b/public/images/emoji/twitter/doughnut.png differ diff --git a/public/images/emoji/twitter/dove.png b/public/images/emoji/twitter/dove.png new file mode 100644 index 00000000000..c303dda4292 Binary files /dev/null and b/public/images/emoji/twitter/dove.png differ diff --git a/public/images/emoji/twitter/dragon.png b/public/images/emoji/twitter/dragon.png index 328dba4a0d6..0acbdd2037c 100644 Binary files a/public/images/emoji/twitter/dragon.png and b/public/images/emoji/twitter/dragon.png differ diff --git a/public/images/emoji/twitter/dragon_face.png b/public/images/emoji/twitter/dragon_face.png index a082fc59846..e68a469aed1 100644 Binary files a/public/images/emoji/twitter/dragon_face.png and b/public/images/emoji/twitter/dragon_face.png differ diff --git a/public/images/emoji/twitter/dress.png b/public/images/emoji/twitter/dress.png index 2cd3306393c..1ba418f1c1a 100644 Binary files a/public/images/emoji/twitter/dress.png and b/public/images/emoji/twitter/dress.png differ diff --git a/public/images/emoji/twitter/dromedary_camel.png b/public/images/emoji/twitter/dromedary_camel.png index 59b26340bfd..39315e7db60 100644 Binary files a/public/images/emoji/twitter/dromedary_camel.png and b/public/images/emoji/twitter/dromedary_camel.png differ diff --git a/public/images/emoji/twitter/droplet.png b/public/images/emoji/twitter/droplet.png index c880318b290..c1c509dda39 100644 Binary files a/public/images/emoji/twitter/droplet.png and b/public/images/emoji/twitter/droplet.png differ diff --git a/public/images/emoji/twitter/dvd.png b/public/images/emoji/twitter/dvd.png index b2fef5b99e3..dea243dfe34 100644 Binary files a/public/images/emoji/twitter/dvd.png and b/public/images/emoji/twitter/dvd.png differ diff --git a/public/images/emoji/twitter/e-mail.png b/public/images/emoji/twitter/e-mail.png index 7b759b705d0..9a4302c3672 100644 Binary files a/public/images/emoji/twitter/e-mail.png and b/public/images/emoji/twitter/e-mail.png differ diff --git a/public/images/emoji/twitter/ear.png b/public/images/emoji/twitter/ear.png index 327d2ca3cb6..0f0c231326d 100644 Binary files a/public/images/emoji/twitter/ear.png and b/public/images/emoji/twitter/ear.png differ diff --git a/public/images/emoji/twitter/ear_of_rice.png b/public/images/emoji/twitter/ear_of_rice.png index db1c7b998fe..0f0ff9b087d 100644 Binary files a/public/images/emoji/twitter/ear_of_rice.png and b/public/images/emoji/twitter/ear_of_rice.png differ diff --git a/public/images/emoji/twitter/earth_africa.png b/public/images/emoji/twitter/earth_africa.png index 8d0222397cf..625b905eb7f 100644 Binary files a/public/images/emoji/twitter/earth_africa.png and b/public/images/emoji/twitter/earth_africa.png differ diff --git a/public/images/emoji/twitter/earth_americas.png b/public/images/emoji/twitter/earth_americas.png index e3adea79453..205fa892141 100644 Binary files a/public/images/emoji/twitter/earth_americas.png and b/public/images/emoji/twitter/earth_americas.png differ diff --git a/public/images/emoji/twitter/earth_asia.png b/public/images/emoji/twitter/earth_asia.png index 1ef76cd9a3e..e214ff57374 100644 Binary files a/public/images/emoji/twitter/earth_asia.png and b/public/images/emoji/twitter/earth_asia.png differ diff --git a/public/images/emoji/twitter/egg.png b/public/images/emoji/twitter/egg.png index 05d55c39702..77755bf29ac 100644 Binary files a/public/images/emoji/twitter/egg.png and b/public/images/emoji/twitter/egg.png differ diff --git a/public/images/emoji/twitter/eggplant.png b/public/images/emoji/twitter/eggplant.png index f730d0cc59f..37a0f5e12ad 100644 Binary files a/public/images/emoji/twitter/eggplant.png and b/public/images/emoji/twitter/eggplant.png differ diff --git a/public/images/emoji/twitter/eight.png b/public/images/emoji/twitter/eight.png index f8fce1bd81f..1f2e6a49281 100644 Binary files a/public/images/emoji/twitter/eight.png and b/public/images/emoji/twitter/eight.png differ diff --git a/public/images/emoji/twitter/eight_pointed_black_star.png b/public/images/emoji/twitter/eight_pointed_black_star.png index e6272916518..33f39ccb859 100644 Binary files a/public/images/emoji/twitter/eight_pointed_black_star.png and b/public/images/emoji/twitter/eight_pointed_black_star.png differ diff --git a/public/images/emoji/twitter/eight_spoked_asterisk.png b/public/images/emoji/twitter/eight_spoked_asterisk.png index e946641cd6a..559da97fb15 100644 Binary files a/public/images/emoji/twitter/eight_spoked_asterisk.png and b/public/images/emoji/twitter/eight_spoked_asterisk.png differ diff --git a/public/images/emoji/twitter/electric_plug.png b/public/images/emoji/twitter/electric_plug.png index b5cae49a8f2..5d69957f0da 100644 Binary files a/public/images/emoji/twitter/electric_plug.png and b/public/images/emoji/twitter/electric_plug.png differ diff --git a/public/images/emoji/twitter/elephant.png b/public/images/emoji/twitter/elephant.png index f09a72ff368..40d063a46e0 100644 Binary files a/public/images/emoji/twitter/elephant.png and b/public/images/emoji/twitter/elephant.png differ diff --git a/public/images/emoji/twitter/email.png b/public/images/emoji/twitter/email.png index 48f5f907fad..66bb2e2b92a 100644 Binary files a/public/images/emoji/twitter/email.png and b/public/images/emoji/twitter/email.png differ diff --git a/public/images/emoji/twitter/end.png b/public/images/emoji/twitter/end.png index 6f31c3698bd..462a3913ade 100644 Binary files a/public/images/emoji/twitter/end.png and b/public/images/emoji/twitter/end.png differ diff --git a/public/images/emoji/twitter/envelope.png b/public/images/emoji/twitter/envelope.png index 48f5f907fad..68d3a096eae 100644 Binary files a/public/images/emoji/twitter/envelope.png and b/public/images/emoji/twitter/envelope.png differ diff --git a/public/images/emoji/twitter/envelope_with_arrow.png b/public/images/emoji/twitter/envelope_with_arrow.png index 437f2bacfec..101bc8d71f8 100644 Binary files a/public/images/emoji/twitter/envelope_with_arrow.png and b/public/images/emoji/twitter/envelope_with_arrow.png differ diff --git a/public/images/emoji/twitter/es.png b/public/images/emoji/twitter/es.png index f1c9ca864ae..56bf2dd7c8e 100644 Binary files a/public/images/emoji/twitter/es.png and b/public/images/emoji/twitter/es.png differ diff --git a/public/images/emoji/twitter/euro.png b/public/images/emoji/twitter/euro.png index 34b3fdca171..6bec9f0a731 100644 Binary files a/public/images/emoji/twitter/euro.png and b/public/images/emoji/twitter/euro.png differ diff --git a/public/images/emoji/twitter/european_castle.png b/public/images/emoji/twitter/european_castle.png index 3746920b65f..7fb8518bf35 100644 Binary files a/public/images/emoji/twitter/european_castle.png and b/public/images/emoji/twitter/european_castle.png differ diff --git a/public/images/emoji/twitter/european_post_office.png b/public/images/emoji/twitter/european_post_office.png index fc809d143eb..f4f3c9f8235 100644 Binary files a/public/images/emoji/twitter/european_post_office.png and b/public/images/emoji/twitter/european_post_office.png differ diff --git a/public/images/emoji/twitter/evergreen_tree.png b/public/images/emoji/twitter/evergreen_tree.png index a5dc92c2499..77d8c7a11a9 100644 Binary files a/public/images/emoji/twitter/evergreen_tree.png and b/public/images/emoji/twitter/evergreen_tree.png differ diff --git a/public/images/emoji/twitter/exclamation.png b/public/images/emoji/twitter/exclamation.png index 9fdca664aa7..4e58af6e6d4 100644 Binary files a/public/images/emoji/twitter/exclamation.png and b/public/images/emoji/twitter/exclamation.png differ diff --git a/public/images/emoji/twitter/expressionless.png b/public/images/emoji/twitter/expressionless.png index b18262c97ae..31149435437 100644 Binary files a/public/images/emoji/twitter/expressionless.png and b/public/images/emoji/twitter/expressionless.png differ diff --git a/public/images/emoji/twitter/eye.png b/public/images/emoji/twitter/eye.png new file mode 100644 index 00000000000..182e1052304 Binary files /dev/null and b/public/images/emoji/twitter/eye.png differ diff --git a/public/images/emoji/twitter/eyeglasses.png b/public/images/emoji/twitter/eyeglasses.png index 56843572e4b..8cab3a7094a 100644 Binary files a/public/images/emoji/twitter/eyeglasses.png and b/public/images/emoji/twitter/eyeglasses.png differ diff --git a/public/images/emoji/twitter/eyes.png b/public/images/emoji/twitter/eyes.png index 543cd830895..ce47b7dc3f6 100644 Binary files a/public/images/emoji/twitter/eyes.png and b/public/images/emoji/twitter/eyes.png differ diff --git a/public/images/emoji/twitter/facepunch.png b/public/images/emoji/twitter/facepunch.png index b41129276f3..90a28680205 100644 Binary files a/public/images/emoji/twitter/facepunch.png and b/public/images/emoji/twitter/facepunch.png differ diff --git a/public/images/emoji/twitter/factory.png b/public/images/emoji/twitter/factory.png index ae843aa1fdb..428833f9862 100644 Binary files a/public/images/emoji/twitter/factory.png and b/public/images/emoji/twitter/factory.png differ diff --git a/public/images/emoji/twitter/fallen_leaf.png b/public/images/emoji/twitter/fallen_leaf.png index 12fabf89e6d..5c07796015e 100644 Binary files a/public/images/emoji/twitter/fallen_leaf.png and b/public/images/emoji/twitter/fallen_leaf.png differ diff --git a/public/images/emoji/twitter/family.png b/public/images/emoji/twitter/family.png index c51b9c53498..911bb57bc30 100644 Binary files a/public/images/emoji/twitter/family.png and b/public/images/emoji/twitter/family.png differ diff --git a/public/images/emoji/twitter/fast_forward.png b/public/images/emoji/twitter/fast_forward.png index 5e5bf418cea..c7fe17c84a8 100644 Binary files a/public/images/emoji/twitter/fast_forward.png and b/public/images/emoji/twitter/fast_forward.png differ diff --git a/public/images/emoji/twitter/fax.png b/public/images/emoji/twitter/fax.png index cc9c1e8461a..689e0c63317 100644 Binary files a/public/images/emoji/twitter/fax.png and b/public/images/emoji/twitter/fax.png differ diff --git a/public/images/emoji/twitter/fearful.png b/public/images/emoji/twitter/fearful.png index 87fbeafded2..c0eae3060d9 100644 Binary files a/public/images/emoji/twitter/fearful.png and b/public/images/emoji/twitter/fearful.png differ diff --git a/public/images/emoji/twitter/feet.png b/public/images/emoji/twitter/feet.png index 94deaa1e55b..36ca50f9012 100644 Binary files a/public/images/emoji/twitter/feet.png and b/public/images/emoji/twitter/feet.png differ diff --git a/public/images/emoji/twitter/ferris_wheel.png b/public/images/emoji/twitter/ferris_wheel.png index f1fdeeda816..fb25a463a35 100644 Binary files a/public/images/emoji/twitter/ferris_wheel.png and b/public/images/emoji/twitter/ferris_wheel.png differ diff --git a/public/images/emoji/twitter/ferry.png b/public/images/emoji/twitter/ferry.png new file mode 100644 index 00000000000..26633aad4d2 Binary files /dev/null and b/public/images/emoji/twitter/ferry.png differ diff --git a/public/images/emoji/twitter/field_hockey.png b/public/images/emoji/twitter/field_hockey.png new file mode 100644 index 00000000000..10212007776 Binary files /dev/null and b/public/images/emoji/twitter/field_hockey.png differ diff --git a/public/images/emoji/twitter/file_cabinet.png b/public/images/emoji/twitter/file_cabinet.png new file mode 100644 index 00000000000..73162f33053 Binary files /dev/null and b/public/images/emoji/twitter/file_cabinet.png differ diff --git a/public/images/emoji/twitter/file_folder.png b/public/images/emoji/twitter/file_folder.png index d35190876c4..e4f27d582f3 100644 Binary files a/public/images/emoji/twitter/file_folder.png and b/public/images/emoji/twitter/file_folder.png differ diff --git a/public/images/emoji/twitter/film_frames.png b/public/images/emoji/twitter/film_frames.png new file mode 100644 index 00000000000..f0fcd6fc1dc Binary files /dev/null and b/public/images/emoji/twitter/film_frames.png differ diff --git a/public/images/emoji/twitter/fire.png b/public/images/emoji/twitter/fire.png index 6b794c4fcf0..322a9bd51f5 100644 Binary files a/public/images/emoji/twitter/fire.png and b/public/images/emoji/twitter/fire.png differ diff --git a/public/images/emoji/twitter/fire_engine.png b/public/images/emoji/twitter/fire_engine.png index 83018e1b7a4..72403e3f417 100644 Binary files a/public/images/emoji/twitter/fire_engine.png and b/public/images/emoji/twitter/fire_engine.png differ diff --git a/public/images/emoji/twitter/fireworks.png b/public/images/emoji/twitter/fireworks.png index fbfe37a540b..d67a1af002e 100644 Binary files a/public/images/emoji/twitter/fireworks.png and b/public/images/emoji/twitter/fireworks.png differ diff --git a/public/images/emoji/twitter/first_quarter_moon.png b/public/images/emoji/twitter/first_quarter_moon.png index 72aedfe0054..00435a5bd26 100644 Binary files a/public/images/emoji/twitter/first_quarter_moon.png and b/public/images/emoji/twitter/first_quarter_moon.png differ diff --git a/public/images/emoji/twitter/first_quarter_moon_with_face.png b/public/images/emoji/twitter/first_quarter_moon_with_face.png index 3324846ee21..ec2b890e0f3 100644 Binary files a/public/images/emoji/twitter/first_quarter_moon_with_face.png and b/public/images/emoji/twitter/first_quarter_moon_with_face.png differ diff --git a/public/images/emoji/twitter/fish.png b/public/images/emoji/twitter/fish.png index 839e210761f..11d7d0de3ee 100644 Binary files a/public/images/emoji/twitter/fish.png and b/public/images/emoji/twitter/fish.png differ diff --git a/public/images/emoji/twitter/fish_cake.png b/public/images/emoji/twitter/fish_cake.png index b1a00ee4528..e5fce4bb516 100644 Binary files a/public/images/emoji/twitter/fish_cake.png and b/public/images/emoji/twitter/fish_cake.png differ diff --git a/public/images/emoji/twitter/fishing_pole_and_fish.png b/public/images/emoji/twitter/fishing_pole_and_fish.png index eee0257faf5..a16cc44270a 100644 Binary files a/public/images/emoji/twitter/fishing_pole_and_fish.png and b/public/images/emoji/twitter/fishing_pole_and_fish.png differ diff --git a/public/images/emoji/twitter/fist.png b/public/images/emoji/twitter/fist.png index 2374784cae8..63b9268872c 100644 Binary files a/public/images/emoji/twitter/fist.png and b/public/images/emoji/twitter/fist.png differ diff --git a/public/images/emoji/twitter/flag_black.png b/public/images/emoji/twitter/flag_black.png new file mode 100644 index 00000000000..c8d8e24c3a8 Binary files /dev/null and b/public/images/emoji/twitter/flag_black.png differ diff --git a/public/images/emoji/twitter/flag_cn.png b/public/images/emoji/twitter/flag_cn.png new file mode 100644 index 00000000000..3c8867958c2 Binary files /dev/null and b/public/images/emoji/twitter/flag_cn.png differ diff --git a/public/images/emoji/twitter/flag_de.png b/public/images/emoji/twitter/flag_de.png new file mode 100644 index 00000000000..8df6465dfeb Binary files /dev/null and b/public/images/emoji/twitter/flag_de.png differ diff --git a/public/images/emoji/twitter/flag_es.png b/public/images/emoji/twitter/flag_es.png new file mode 100644 index 00000000000..4f5942de649 Binary files /dev/null and b/public/images/emoji/twitter/flag_es.png differ diff --git a/public/images/emoji/twitter/flag_fr.png b/public/images/emoji/twitter/flag_fr.png new file mode 100644 index 00000000000..1818a910e91 Binary files /dev/null and b/public/images/emoji/twitter/flag_fr.png differ diff --git a/public/images/emoji/twitter/flag_gb.png b/public/images/emoji/twitter/flag_gb.png new file mode 100644 index 00000000000..fa1e1d65801 Binary files /dev/null and b/public/images/emoji/twitter/flag_gb.png differ diff --git a/public/images/emoji/twitter/flag_it.png b/public/images/emoji/twitter/flag_it.png new file mode 100644 index 00000000000..556a8df4b20 Binary files /dev/null and b/public/images/emoji/twitter/flag_it.png differ diff --git a/public/images/emoji/twitter/flag_jp.png b/public/images/emoji/twitter/flag_jp.png new file mode 100644 index 00000000000..53fabdb484a Binary files /dev/null and b/public/images/emoji/twitter/flag_jp.png differ diff --git a/public/images/emoji/twitter/flag_kr.png b/public/images/emoji/twitter/flag_kr.png new file mode 100644 index 00000000000..2132a435e36 Binary files /dev/null and b/public/images/emoji/twitter/flag_kr.png differ diff --git a/public/images/emoji/twitter/flag_ru.png b/public/images/emoji/twitter/flag_ru.png new file mode 100644 index 00000000000..79880997513 Binary files /dev/null and b/public/images/emoji/twitter/flag_ru.png differ diff --git a/public/images/emoji/twitter/flag_us.png b/public/images/emoji/twitter/flag_us.png new file mode 100644 index 00000000000..d2d67ab7841 Binary files /dev/null and b/public/images/emoji/twitter/flag_us.png differ diff --git a/public/images/emoji/twitter/flag_white.png b/public/images/emoji/twitter/flag_white.png new file mode 100644 index 00000000000..68543be8f2e Binary files /dev/null and b/public/images/emoji/twitter/flag_white.png differ diff --git a/public/images/emoji/twitter/flags.png b/public/images/emoji/twitter/flags.png index f3a2f3b0e3f..73af7ed5bf4 100644 Binary files a/public/images/emoji/twitter/flags.png and b/public/images/emoji/twitter/flags.png differ diff --git a/public/images/emoji/twitter/flashlight.png b/public/images/emoji/twitter/flashlight.png index de62c7f5f5b..d754b9efa35 100644 Binary files a/public/images/emoji/twitter/flashlight.png and b/public/images/emoji/twitter/flashlight.png differ diff --git a/public/images/emoji/twitter/fleur-de-lis.png b/public/images/emoji/twitter/fleur-de-lis.png new file mode 100644 index 00000000000..eaa91aeb3a2 Binary files /dev/null and b/public/images/emoji/twitter/fleur-de-lis.png differ diff --git a/public/images/emoji/twitter/flipper.png b/public/images/emoji/twitter/flipper.png index 38c764d8780..157c51d3d5a 100644 Binary files a/public/images/emoji/twitter/flipper.png and b/public/images/emoji/twitter/flipper.png differ diff --git a/public/images/emoji/twitter/floppy_disk.png b/public/images/emoji/twitter/floppy_disk.png index 8c93824ee82..29991d01c64 100644 Binary files a/public/images/emoji/twitter/floppy_disk.png and b/public/images/emoji/twitter/floppy_disk.png differ diff --git a/public/images/emoji/twitter/flower_playing_cards.png b/public/images/emoji/twitter/flower_playing_cards.png index ce008314324..8abece28bcb 100644 Binary files a/public/images/emoji/twitter/flower_playing_cards.png and b/public/images/emoji/twitter/flower_playing_cards.png differ diff --git a/public/images/emoji/twitter/flushed.png b/public/images/emoji/twitter/flushed.png index 3957403f5db..26e0338c93e 100644 Binary files a/public/images/emoji/twitter/flushed.png and b/public/images/emoji/twitter/flushed.png differ diff --git a/public/images/emoji/twitter/fog.png b/public/images/emoji/twitter/fog.png new file mode 100644 index 00000000000..f8aee2c7b5e Binary files /dev/null and b/public/images/emoji/twitter/fog.png differ diff --git a/public/images/emoji/twitter/foggy.png b/public/images/emoji/twitter/foggy.png index dedacf36c01..98fe7062c35 100644 Binary files a/public/images/emoji/twitter/foggy.png and b/public/images/emoji/twitter/foggy.png differ diff --git a/public/images/emoji/twitter/football.png b/public/images/emoji/twitter/football.png index 4e87648f1a7..97c5e680adf 100644 Binary files a/public/images/emoji/twitter/football.png and b/public/images/emoji/twitter/football.png differ diff --git a/public/images/emoji/twitter/footprints.png b/public/images/emoji/twitter/footprints.png index e5db6271ed8..ab903d3776d 100644 Binary files a/public/images/emoji/twitter/footprints.png and b/public/images/emoji/twitter/footprints.png differ diff --git a/public/images/emoji/twitter/fork_and_knife.png b/public/images/emoji/twitter/fork_and_knife.png index c13653732d5..305b1fe82ac 100644 Binary files a/public/images/emoji/twitter/fork_and_knife.png and b/public/images/emoji/twitter/fork_and_knife.png differ diff --git a/public/images/emoji/twitter/fork_knife_plate.png b/public/images/emoji/twitter/fork_knife_plate.png new file mode 100644 index 00000000000..693fa161c6a Binary files /dev/null and b/public/images/emoji/twitter/fork_knife_plate.png differ diff --git a/public/images/emoji/twitter/fountain.png b/public/images/emoji/twitter/fountain.png index 01fab36e54a..24287325d18 100644 Binary files a/public/images/emoji/twitter/fountain.png and b/public/images/emoji/twitter/fountain.png differ diff --git a/public/images/emoji/twitter/four_leaf_clover.png b/public/images/emoji/twitter/four_leaf_clover.png index 0339897b720..cc9632ca995 100644 Binary files a/public/images/emoji/twitter/four_leaf_clover.png and b/public/images/emoji/twitter/four_leaf_clover.png differ diff --git a/public/images/emoji/twitter/fr.png b/public/images/emoji/twitter/fr.png index 5db03261273..8a9ec3c50a2 100644 Binary files a/public/images/emoji/twitter/fr.png and b/public/images/emoji/twitter/fr.png differ diff --git a/public/images/emoji/twitter/frame_photo.png b/public/images/emoji/twitter/frame_photo.png new file mode 100644 index 00000000000..c4980524254 Binary files /dev/null and b/public/images/emoji/twitter/frame_photo.png differ diff --git a/public/images/emoji/twitter/free.png b/public/images/emoji/twitter/free.png index 28803e044f7..2c29f6538bb 100644 Binary files a/public/images/emoji/twitter/free.png and b/public/images/emoji/twitter/free.png differ diff --git a/public/images/emoji/twitter/fried_shrimp.png b/public/images/emoji/twitter/fried_shrimp.png index 16726fb6ca5..9bd785b5145 100644 Binary files a/public/images/emoji/twitter/fried_shrimp.png and b/public/images/emoji/twitter/fried_shrimp.png differ diff --git a/public/images/emoji/twitter/fries.png b/public/images/emoji/twitter/fries.png index 976e30d9018..b5ebe812d95 100644 Binary files a/public/images/emoji/twitter/fries.png and b/public/images/emoji/twitter/fries.png differ diff --git a/public/images/emoji/twitter/frog.png b/public/images/emoji/twitter/frog.png index 13678d96e2d..6e90b67d90b 100644 Binary files a/public/images/emoji/twitter/frog.png and b/public/images/emoji/twitter/frog.png differ diff --git a/public/images/emoji/twitter/frowning.png b/public/images/emoji/twitter/frowning.png index 6a6d43d319b..9b537c8ae75 100644 Binary files a/public/images/emoji/twitter/frowning.png and b/public/images/emoji/twitter/frowning.png differ diff --git a/public/images/emoji/twitter/frowning2.png b/public/images/emoji/twitter/frowning2.png new file mode 100644 index 00000000000..0b8335cd570 Binary files /dev/null and b/public/images/emoji/twitter/frowning2.png differ diff --git a/public/images/emoji/twitter/fuelpump.png b/public/images/emoji/twitter/fuelpump.png index 29e29704849..e89361dedc2 100644 Binary files a/public/images/emoji/twitter/fuelpump.png and b/public/images/emoji/twitter/fuelpump.png differ diff --git a/public/images/emoji/twitter/full_moon.png b/public/images/emoji/twitter/full_moon.png index b97fc9bcded..7d6cdea65ea 100644 Binary files a/public/images/emoji/twitter/full_moon.png and b/public/images/emoji/twitter/full_moon.png differ diff --git a/public/images/emoji/twitter/full_moon_with_face.png b/public/images/emoji/twitter/full_moon_with_face.png index ea8b052d1bd..04ea13b6d81 100644 Binary files a/public/images/emoji/twitter/full_moon_with_face.png and b/public/images/emoji/twitter/full_moon_with_face.png differ diff --git a/public/images/emoji/twitter/game_die.png b/public/images/emoji/twitter/game_die.png index 2745754d14e..6251fb05a1b 100644 Binary files a/public/images/emoji/twitter/game_die.png and b/public/images/emoji/twitter/game_die.png differ diff --git a/public/images/emoji/twitter/gb.png b/public/images/emoji/twitter/gb.png index f31e458c1dc..79cadb58eed 100644 Binary files a/public/images/emoji/twitter/gb.png and b/public/images/emoji/twitter/gb.png differ diff --git a/public/images/emoji/twitter/gear.png b/public/images/emoji/twitter/gear.png new file mode 100644 index 00000000000..b85014eca38 Binary files /dev/null and b/public/images/emoji/twitter/gear.png differ diff --git a/public/images/emoji/twitter/gem.png b/public/images/emoji/twitter/gem.png index e455ec978bf..b61b2bd2b67 100644 Binary files a/public/images/emoji/twitter/gem.png and b/public/images/emoji/twitter/gem.png differ diff --git a/public/images/emoji/twitter/gemini.png b/public/images/emoji/twitter/gemini.png index bb1fde5cd7f..bc07ea9a84a 100644 Binary files a/public/images/emoji/twitter/gemini.png and b/public/images/emoji/twitter/gemini.png differ diff --git a/public/images/emoji/twitter/ghost.png b/public/images/emoji/twitter/ghost.png index 43f96c27b83..e90310074cc 100644 Binary files a/public/images/emoji/twitter/ghost.png and b/public/images/emoji/twitter/ghost.png differ diff --git a/public/images/emoji/twitter/gift.png b/public/images/emoji/twitter/gift.png index 054ceb609da..a2b3897bfe2 100644 Binary files a/public/images/emoji/twitter/gift.png and b/public/images/emoji/twitter/gift.png differ diff --git a/public/images/emoji/twitter/gift_heart.png b/public/images/emoji/twitter/gift_heart.png index 9370396f84f..74da290482c 100644 Binary files a/public/images/emoji/twitter/gift_heart.png and b/public/images/emoji/twitter/gift_heart.png differ diff --git a/public/images/emoji/twitter/girl.png b/public/images/emoji/twitter/girl.png index 1414cc64c95..42e21d3bb31 100644 Binary files a/public/images/emoji/twitter/girl.png and b/public/images/emoji/twitter/girl.png differ diff --git a/public/images/emoji/twitter/globe_with_meridians.png b/public/images/emoji/twitter/globe_with_meridians.png index 7875096c3c4..3f095701abd 100644 Binary files a/public/images/emoji/twitter/globe_with_meridians.png and b/public/images/emoji/twitter/globe_with_meridians.png differ diff --git a/public/images/emoji/twitter/goat.png b/public/images/emoji/twitter/goat.png index a6f5479a8d7..383abc1f02d 100644 Binary files a/public/images/emoji/twitter/goat.png and b/public/images/emoji/twitter/goat.png differ diff --git a/public/images/emoji/twitter/golf.png b/public/images/emoji/twitter/golf.png index cf27469ca3b..ad77eac5cd0 100644 Binary files a/public/images/emoji/twitter/golf.png and b/public/images/emoji/twitter/golf.png differ diff --git a/public/images/emoji/twitter/golfer.png b/public/images/emoji/twitter/golfer.png new file mode 100644 index 00000000000..e13b10d9e65 Binary files /dev/null and b/public/images/emoji/twitter/golfer.png differ diff --git a/public/images/emoji/twitter/grapes.png b/public/images/emoji/twitter/grapes.png index 694dd705b06..9e766db966a 100644 Binary files a/public/images/emoji/twitter/grapes.png and b/public/images/emoji/twitter/grapes.png differ diff --git a/public/images/emoji/twitter/green_apple.png b/public/images/emoji/twitter/green_apple.png index 37a3a771d25..5b8a85dcd7a 100644 Binary files a/public/images/emoji/twitter/green_apple.png and b/public/images/emoji/twitter/green_apple.png differ diff --git a/public/images/emoji/twitter/green_book.png b/public/images/emoji/twitter/green_book.png index 3b642510e18..4f82e785a07 100644 Binary files a/public/images/emoji/twitter/green_book.png and b/public/images/emoji/twitter/green_book.png differ diff --git a/public/images/emoji/twitter/green_heart.png b/public/images/emoji/twitter/green_heart.png index e00b740cbe0..1886619806e 100644 Binary files a/public/images/emoji/twitter/green_heart.png and b/public/images/emoji/twitter/green_heart.png differ diff --git a/public/images/emoji/twitter/grey_exclamation.png b/public/images/emoji/twitter/grey_exclamation.png index 938a03f1f5d..a534ffd545b 100644 Binary files a/public/images/emoji/twitter/grey_exclamation.png and b/public/images/emoji/twitter/grey_exclamation.png differ diff --git a/public/images/emoji/twitter/grey_question.png b/public/images/emoji/twitter/grey_question.png index f315475e0e7..a040ccadb1a 100644 Binary files a/public/images/emoji/twitter/grey_question.png and b/public/images/emoji/twitter/grey_question.png differ diff --git a/public/images/emoji/twitter/grimacing.png b/public/images/emoji/twitter/grimacing.png index 00244300ed1..aa09f80da92 100644 Binary files a/public/images/emoji/twitter/grimacing.png and b/public/images/emoji/twitter/grimacing.png differ diff --git a/public/images/emoji/twitter/grin.png b/public/images/emoji/twitter/grin.png index dba5a759b66..bc4a45f2230 100644 Binary files a/public/images/emoji/twitter/grin.png and b/public/images/emoji/twitter/grin.png differ diff --git a/public/images/emoji/twitter/grinning.png b/public/images/emoji/twitter/grinning.png index 34ac223f396..f964def143a 100644 Binary files a/public/images/emoji/twitter/grinning.png and b/public/images/emoji/twitter/grinning.png differ diff --git a/public/images/emoji/twitter/guardsman.png b/public/images/emoji/twitter/guardsman.png index 213b4f2d3de..ffd702fe44c 100644 Binary files a/public/images/emoji/twitter/guardsman.png and b/public/images/emoji/twitter/guardsman.png differ diff --git a/public/images/emoji/twitter/guitar.png b/public/images/emoji/twitter/guitar.png index 94459caa661..f4d4cee26a3 100644 Binary files a/public/images/emoji/twitter/guitar.png and b/public/images/emoji/twitter/guitar.png differ diff --git a/public/images/emoji/twitter/gun.png b/public/images/emoji/twitter/gun.png index 243beb1e2a3..f1ff34a44c7 100644 Binary files a/public/images/emoji/twitter/gun.png and b/public/images/emoji/twitter/gun.png differ diff --git a/public/images/emoji/twitter/haircut.png b/public/images/emoji/twitter/haircut.png index 042cdf54da6..e2763af3932 100644 Binary files a/public/images/emoji/twitter/haircut.png and b/public/images/emoji/twitter/haircut.png differ diff --git a/public/images/emoji/twitter/hamburger.png b/public/images/emoji/twitter/hamburger.png index d720c572087..25d55c4236c 100644 Binary files a/public/images/emoji/twitter/hamburger.png and b/public/images/emoji/twitter/hamburger.png differ diff --git a/public/images/emoji/twitter/hammer.png b/public/images/emoji/twitter/hammer.png index 99f9f88ad1e..aa75835079d 100644 Binary files a/public/images/emoji/twitter/hammer.png and b/public/images/emoji/twitter/hammer.png differ diff --git a/public/images/emoji/twitter/hammer_pick.png b/public/images/emoji/twitter/hammer_pick.png new file mode 100644 index 00000000000..3243f0a4225 Binary files /dev/null and b/public/images/emoji/twitter/hammer_pick.png differ diff --git a/public/images/emoji/twitter/hamster.png b/public/images/emoji/twitter/hamster.png index ac23f411552..20cb6a94c94 100644 Binary files a/public/images/emoji/twitter/hamster.png and b/public/images/emoji/twitter/hamster.png differ diff --git a/public/images/emoji/twitter/hand.png b/public/images/emoji/twitter/hand.png index f7edfd6c3d8..21893fbdda7 100644 Binary files a/public/images/emoji/twitter/hand.png and b/public/images/emoji/twitter/hand.png differ diff --git a/public/images/emoji/twitter/hand_splayed.png b/public/images/emoji/twitter/hand_splayed.png new file mode 100644 index 00000000000..cf2dcda2dc2 Binary files /dev/null and b/public/images/emoji/twitter/hand_splayed.png differ diff --git a/public/images/emoji/twitter/handbag.png b/public/images/emoji/twitter/handbag.png index be89378c793..e154b9e0ddb 100644 Binary files a/public/images/emoji/twitter/handbag.png and b/public/images/emoji/twitter/handbag.png differ diff --git a/public/images/emoji/twitter/hankey.png b/public/images/emoji/twitter/hankey.png index d44f2036460..7194246ee21 100644 Binary files a/public/images/emoji/twitter/hankey.png and b/public/images/emoji/twitter/hankey.png differ diff --git a/public/images/emoji/twitter/hatched_chick.png b/public/images/emoji/twitter/hatched_chick.png index 2593d560f67..53ff80881f5 100644 Binary files a/public/images/emoji/twitter/hatched_chick.png and b/public/images/emoji/twitter/hatched_chick.png differ diff --git a/public/images/emoji/twitter/hatching_chick.png b/public/images/emoji/twitter/hatching_chick.png index 8e5cb2b609a..7a4dc72bc1e 100644 Binary files a/public/images/emoji/twitter/hatching_chick.png and b/public/images/emoji/twitter/hatching_chick.png differ diff --git a/public/images/emoji/twitter/head_bandage.png b/public/images/emoji/twitter/head_bandage.png new file mode 100644 index 00000000000..3be8843a968 Binary files /dev/null and b/public/images/emoji/twitter/head_bandage.png differ diff --git a/public/images/emoji/twitter/headphones.png b/public/images/emoji/twitter/headphones.png index 58c3aabcdc0..1f0c0d32f0e 100644 Binary files a/public/images/emoji/twitter/headphones.png and b/public/images/emoji/twitter/headphones.png differ diff --git a/public/images/emoji/twitter/hear_no_evil.png b/public/images/emoji/twitter/hear_no_evil.png index dc5c4b2a345..432a4c542fe 100644 Binary files a/public/images/emoji/twitter/hear_no_evil.png and b/public/images/emoji/twitter/hear_no_evil.png differ diff --git a/public/images/emoji/twitter/heart.png b/public/images/emoji/twitter/heart.png index add7a5de00c..bcdb71ca1db 100644 Binary files a/public/images/emoji/twitter/heart.png and b/public/images/emoji/twitter/heart.png differ diff --git a/public/images/emoji/twitter/heart_decoration.png b/public/images/emoji/twitter/heart_decoration.png index ca45712fa89..f29ecf36a05 100644 Binary files a/public/images/emoji/twitter/heart_decoration.png and b/public/images/emoji/twitter/heart_decoration.png differ diff --git a/public/images/emoji/twitter/heart_exclamation.png b/public/images/emoji/twitter/heart_exclamation.png new file mode 100644 index 00000000000..adcc6238e04 Binary files /dev/null and b/public/images/emoji/twitter/heart_exclamation.png differ diff --git a/public/images/emoji/twitter/heart_eyes.png b/public/images/emoji/twitter/heart_eyes.png index ecfc26db648..127926f1a2b 100644 Binary files a/public/images/emoji/twitter/heart_eyes.png and b/public/images/emoji/twitter/heart_eyes.png differ diff --git a/public/images/emoji/twitter/heart_eyes_cat.png b/public/images/emoji/twitter/heart_eyes_cat.png index 2de123d16b0..b572edc3085 100644 Binary files a/public/images/emoji/twitter/heart_eyes_cat.png and b/public/images/emoji/twitter/heart_eyes_cat.png differ diff --git a/public/images/emoji/twitter/heartbeat.png b/public/images/emoji/twitter/heartbeat.png index 95416c6f115..e29e8c0aa5d 100644 Binary files a/public/images/emoji/twitter/heartbeat.png and b/public/images/emoji/twitter/heartbeat.png differ diff --git a/public/images/emoji/twitter/heartpulse.png b/public/images/emoji/twitter/heartpulse.png index e6256db2d14..4d9895dfe72 100644 Binary files a/public/images/emoji/twitter/heartpulse.png and b/public/images/emoji/twitter/heartpulse.png differ diff --git a/public/images/emoji/twitter/hearts.png b/public/images/emoji/twitter/hearts.png index 3e56fe0cbfc..52bb4eedead 100644 Binary files a/public/images/emoji/twitter/hearts.png and b/public/images/emoji/twitter/hearts.png differ diff --git a/public/images/emoji/twitter/heavy_check_mark.png b/public/images/emoji/twitter/heavy_check_mark.png index 41a80f3f6e8..5ec19a14759 100644 Binary files a/public/images/emoji/twitter/heavy_check_mark.png and b/public/images/emoji/twitter/heavy_check_mark.png differ diff --git a/public/images/emoji/twitter/heavy_division_sign.png b/public/images/emoji/twitter/heavy_division_sign.png index 5a780b11a96..1cfd64d8caa 100644 Binary files a/public/images/emoji/twitter/heavy_division_sign.png and b/public/images/emoji/twitter/heavy_division_sign.png differ diff --git a/public/images/emoji/twitter/heavy_dollar_sign.png b/public/images/emoji/twitter/heavy_dollar_sign.png index af0ea8d1f23..ebdce176c88 100644 Binary files a/public/images/emoji/twitter/heavy_dollar_sign.png and b/public/images/emoji/twitter/heavy_dollar_sign.png differ diff --git a/public/images/emoji/twitter/heavy_minus_sign.png b/public/images/emoji/twitter/heavy_minus_sign.png index 91e1e27e7ac..43f8c020c41 100644 Binary files a/public/images/emoji/twitter/heavy_minus_sign.png and b/public/images/emoji/twitter/heavy_minus_sign.png differ diff --git a/public/images/emoji/twitter/heavy_multiplication_x.png b/public/images/emoji/twitter/heavy_multiplication_x.png index f497148921a..47f763d9833 100644 Binary files a/public/images/emoji/twitter/heavy_multiplication_x.png and b/public/images/emoji/twitter/heavy_multiplication_x.png differ diff --git a/public/images/emoji/twitter/heavy_plus_sign.png b/public/images/emoji/twitter/heavy_plus_sign.png index 245b1204102..79cb09846ff 100644 Binary files a/public/images/emoji/twitter/heavy_plus_sign.png and b/public/images/emoji/twitter/heavy_plus_sign.png differ diff --git a/public/images/emoji/twitter/helicopter.png b/public/images/emoji/twitter/helicopter.png index 222450010d3..55b92c4f8fc 100644 Binary files a/public/images/emoji/twitter/helicopter.png and b/public/images/emoji/twitter/helicopter.png differ diff --git a/public/images/emoji/twitter/helmet_with_cross.png b/public/images/emoji/twitter/helmet_with_cross.png new file mode 100644 index 00000000000..5d8a20a6b11 Binary files /dev/null and b/public/images/emoji/twitter/helmet_with_cross.png differ diff --git a/public/images/emoji/twitter/herb.png b/public/images/emoji/twitter/herb.png index dfb2cf04235..451d04112e5 100644 Binary files a/public/images/emoji/twitter/herb.png and b/public/images/emoji/twitter/herb.png differ diff --git a/public/images/emoji/twitter/hibiscus.png b/public/images/emoji/twitter/hibiscus.png index eef00681390..4e60b2dc49d 100644 Binary files a/public/images/emoji/twitter/hibiscus.png and b/public/images/emoji/twitter/hibiscus.png differ diff --git a/public/images/emoji/twitter/high_brightness.png b/public/images/emoji/twitter/high_brightness.png index ffd3dee5ebd..53b83a39b16 100644 Binary files a/public/images/emoji/twitter/high_brightness.png and b/public/images/emoji/twitter/high_brightness.png differ diff --git a/public/images/emoji/twitter/high_heel.png b/public/images/emoji/twitter/high_heel.png index ef4e9370738..a2b8097799d 100644 Binary files a/public/images/emoji/twitter/high_heel.png and b/public/images/emoji/twitter/high_heel.png differ diff --git a/public/images/emoji/twitter/hocho.png b/public/images/emoji/twitter/hocho.png index 1aae17f5b56..1dec23fc404 100644 Binary files a/public/images/emoji/twitter/hocho.png and b/public/images/emoji/twitter/hocho.png differ diff --git a/public/images/emoji/twitter/hockey.png b/public/images/emoji/twitter/hockey.png new file mode 100644 index 00000000000..0959352b882 Binary files /dev/null and b/public/images/emoji/twitter/hockey.png differ diff --git a/public/images/emoji/twitter/hole.png b/public/images/emoji/twitter/hole.png new file mode 100644 index 00000000000..0f353402876 Binary files /dev/null and b/public/images/emoji/twitter/hole.png differ diff --git a/public/images/emoji/twitter/homes.png b/public/images/emoji/twitter/homes.png new file mode 100644 index 00000000000..42fdacd954d Binary files /dev/null and b/public/images/emoji/twitter/homes.png differ diff --git a/public/images/emoji/twitter/honey_pot.png b/public/images/emoji/twitter/honey_pot.png index 10cd190a2d5..8dfe65bddc4 100644 Binary files a/public/images/emoji/twitter/honey_pot.png and b/public/images/emoji/twitter/honey_pot.png differ diff --git a/public/images/emoji/twitter/honeybee.png b/public/images/emoji/twitter/honeybee.png index fa15755f912..850ec0d691d 100644 Binary files a/public/images/emoji/twitter/honeybee.png and b/public/images/emoji/twitter/honeybee.png differ diff --git a/public/images/emoji/twitter/horse.png b/public/images/emoji/twitter/horse.png index f7d143166c2..365bf73de82 100644 Binary files a/public/images/emoji/twitter/horse.png and b/public/images/emoji/twitter/horse.png differ diff --git a/public/images/emoji/twitter/horse_racing.png b/public/images/emoji/twitter/horse_racing.png index 026f9db33f9..d84af3e85e0 100644 Binary files a/public/images/emoji/twitter/horse_racing.png and b/public/images/emoji/twitter/horse_racing.png differ diff --git a/public/images/emoji/twitter/hospital.png b/public/images/emoji/twitter/hospital.png index 6fce5dd0b24..d36b423ce26 100644 Binary files a/public/images/emoji/twitter/hospital.png and b/public/images/emoji/twitter/hospital.png differ diff --git a/public/images/emoji/twitter/hot_pepper.png b/public/images/emoji/twitter/hot_pepper.png new file mode 100644 index 00000000000..c0f7d3a8f0c Binary files /dev/null and b/public/images/emoji/twitter/hot_pepper.png differ diff --git a/public/images/emoji/twitter/hotdog.png b/public/images/emoji/twitter/hotdog.png new file mode 100644 index 00000000000..9d5050a3c96 Binary files /dev/null and b/public/images/emoji/twitter/hotdog.png differ diff --git a/public/images/emoji/twitter/hotel.png b/public/images/emoji/twitter/hotel.png index 63f5c5b1f36..5ab3518d3e5 100644 Binary files a/public/images/emoji/twitter/hotel.png and b/public/images/emoji/twitter/hotel.png differ diff --git a/public/images/emoji/twitter/hotsprings.png b/public/images/emoji/twitter/hotsprings.png index e88aa44b315..e63ddb3ce28 100644 Binary files a/public/images/emoji/twitter/hotsprings.png and b/public/images/emoji/twitter/hotsprings.png differ diff --git a/public/images/emoji/twitter/hourglass.png b/public/images/emoji/twitter/hourglass.png index 55d822d0a1a..90e7e4ebc55 100644 Binary files a/public/images/emoji/twitter/hourglass.png and b/public/images/emoji/twitter/hourglass.png differ diff --git a/public/images/emoji/twitter/hourglass_flowing_sand.png b/public/images/emoji/twitter/hourglass_flowing_sand.png index 91bc5ab8322..4c208cdfbab 100644 Binary files a/public/images/emoji/twitter/hourglass_flowing_sand.png and b/public/images/emoji/twitter/hourglass_flowing_sand.png differ diff --git a/public/images/emoji/twitter/house.png b/public/images/emoji/twitter/house.png index ca181c99390..0e322e18a7a 100644 Binary files a/public/images/emoji/twitter/house.png and b/public/images/emoji/twitter/house.png differ diff --git a/public/images/emoji/twitter/house_abandoned.png b/public/images/emoji/twitter/house_abandoned.png new file mode 100644 index 00000000000..4ca92ee5ca4 Binary files /dev/null and b/public/images/emoji/twitter/house_abandoned.png differ diff --git a/public/images/emoji/twitter/house_with_garden.png b/public/images/emoji/twitter/house_with_garden.png index 40e09fb8d0f..23391f96cac 100644 Binary files a/public/images/emoji/twitter/house_with_garden.png and b/public/images/emoji/twitter/house_with_garden.png differ diff --git a/public/images/emoji/twitter/hugging.png b/public/images/emoji/twitter/hugging.png new file mode 100644 index 00000000000..aa07844841f Binary files /dev/null and b/public/images/emoji/twitter/hugging.png differ diff --git a/public/images/emoji/twitter/hushed.png b/public/images/emoji/twitter/hushed.png index 7df76608770..fc3895629d4 100644 Binary files a/public/images/emoji/twitter/hushed.png and b/public/images/emoji/twitter/hushed.png differ diff --git a/public/images/emoji/twitter/ice_cream.png b/public/images/emoji/twitter/ice_cream.png index 93123a28a58..5a9e829214c 100644 Binary files a/public/images/emoji/twitter/ice_cream.png and b/public/images/emoji/twitter/ice_cream.png differ diff --git a/public/images/emoji/twitter/ice_skate.png b/public/images/emoji/twitter/ice_skate.png new file mode 100644 index 00000000000..373137fb1dc Binary files /dev/null and b/public/images/emoji/twitter/ice_skate.png differ diff --git a/public/images/emoji/twitter/icecream.png b/public/images/emoji/twitter/icecream.png index 9554000f007..c84be663f8b 100644 Binary files a/public/images/emoji/twitter/icecream.png and b/public/images/emoji/twitter/icecream.png differ diff --git a/public/images/emoji/twitter/id.png b/public/images/emoji/twitter/id.png index b16bb031fa1..c22ef6ef656 100644 Binary files a/public/images/emoji/twitter/id.png and b/public/images/emoji/twitter/id.png differ diff --git a/public/images/emoji/twitter/ideograph_advantage.png b/public/images/emoji/twitter/ideograph_advantage.png index b29464fc214..3a30167aaf2 100644 Binary files a/public/images/emoji/twitter/ideograph_advantage.png and b/public/images/emoji/twitter/ideograph_advantage.png differ diff --git a/public/images/emoji/twitter/imp.png b/public/images/emoji/twitter/imp.png index 682809ce1a3..c1c2fde0ecf 100644 Binary files a/public/images/emoji/twitter/imp.png and b/public/images/emoji/twitter/imp.png differ diff --git a/public/images/emoji/twitter/inbox_tray.png b/public/images/emoji/twitter/inbox_tray.png index a316547a948..824bd030b6b 100644 Binary files a/public/images/emoji/twitter/inbox_tray.png and b/public/images/emoji/twitter/inbox_tray.png differ diff --git a/public/images/emoji/twitter/incoming_envelope.png b/public/images/emoji/twitter/incoming_envelope.png index b54d6d40f3c..48392c4e3f9 100644 Binary files a/public/images/emoji/twitter/incoming_envelope.png and b/public/images/emoji/twitter/incoming_envelope.png differ diff --git a/public/images/emoji/twitter/information_desk_person.png b/public/images/emoji/twitter/information_desk_person.png index d5a8e98892c..d4038e6b12e 100644 Binary files a/public/images/emoji/twitter/information_desk_person.png and b/public/images/emoji/twitter/information_desk_person.png differ diff --git a/public/images/emoji/twitter/information_source.png b/public/images/emoji/twitter/information_source.png index 18df7aa44e7..9f7e6d599a5 100644 Binary files a/public/images/emoji/twitter/information_source.png and b/public/images/emoji/twitter/information_source.png differ diff --git a/public/images/emoji/twitter/innocent.png b/public/images/emoji/twitter/innocent.png index 76d9bc4265e..af100e7d42b 100644 Binary files a/public/images/emoji/twitter/innocent.png and b/public/images/emoji/twitter/innocent.png differ diff --git a/public/images/emoji/twitter/interrobang.png b/public/images/emoji/twitter/interrobang.png index 99a7e68bc61..06f78f01266 100644 Binary files a/public/images/emoji/twitter/interrobang.png and b/public/images/emoji/twitter/interrobang.png differ diff --git a/public/images/emoji/twitter/iphone.png b/public/images/emoji/twitter/iphone.png index 9e04b16d9ce..0f4c2b5c436 100644 Binary files a/public/images/emoji/twitter/iphone.png and b/public/images/emoji/twitter/iphone.png differ diff --git a/public/images/emoji/twitter/island.png b/public/images/emoji/twitter/island.png new file mode 100644 index 00000000000..8be357d21f9 Binary files /dev/null and b/public/images/emoji/twitter/island.png differ diff --git a/public/images/emoji/twitter/it.png b/public/images/emoji/twitter/it.png index fc876eb18f4..a8927b3eab7 100644 Binary files a/public/images/emoji/twitter/it.png and b/public/images/emoji/twitter/it.png differ diff --git a/public/images/emoji/twitter/izakaya_lantern.png b/public/images/emoji/twitter/izakaya_lantern.png index b0db1cbed63..a045fe8f104 100644 Binary files a/public/images/emoji/twitter/izakaya_lantern.png and b/public/images/emoji/twitter/izakaya_lantern.png differ diff --git a/public/images/emoji/twitter/jack_o_lantern.png b/public/images/emoji/twitter/jack_o_lantern.png index 2c23eaa9ce9..2bb6865db9f 100644 Binary files a/public/images/emoji/twitter/jack_o_lantern.png and b/public/images/emoji/twitter/jack_o_lantern.png differ diff --git a/public/images/emoji/twitter/japan.png b/public/images/emoji/twitter/japan.png index 4a0373975fc..ec89bf22b17 100644 Binary files a/public/images/emoji/twitter/japan.png and b/public/images/emoji/twitter/japan.png differ diff --git a/public/images/emoji/twitter/japanese_castle.png b/public/images/emoji/twitter/japanese_castle.png index 597bd22440a..e71612a5d0c 100644 Binary files a/public/images/emoji/twitter/japanese_castle.png and b/public/images/emoji/twitter/japanese_castle.png differ diff --git a/public/images/emoji/twitter/japanese_goblin.png b/public/images/emoji/twitter/japanese_goblin.png index c5204750bc0..3fb5b7ecbc1 100644 Binary files a/public/images/emoji/twitter/japanese_goblin.png and b/public/images/emoji/twitter/japanese_goblin.png differ diff --git a/public/images/emoji/twitter/japanese_ogre.png b/public/images/emoji/twitter/japanese_ogre.png index 01fae2768ab..4d49bae608b 100644 Binary files a/public/images/emoji/twitter/japanese_ogre.png and b/public/images/emoji/twitter/japanese_ogre.png differ diff --git a/public/images/emoji/twitter/jeans.png b/public/images/emoji/twitter/jeans.png index 2d60a872d9a..81a4bf9f40d 100644 Binary files a/public/images/emoji/twitter/jeans.png and b/public/images/emoji/twitter/jeans.png differ diff --git a/public/images/emoji/twitter/joy.png b/public/images/emoji/twitter/joy.png index b2a2037a0e0..a4e5b2d162a 100644 Binary files a/public/images/emoji/twitter/joy.png and b/public/images/emoji/twitter/joy.png differ diff --git a/public/images/emoji/twitter/joy_cat.png b/public/images/emoji/twitter/joy_cat.png index dbd4f34b75b..6c0b1889ac6 100644 Binary files a/public/images/emoji/twitter/joy_cat.png and b/public/images/emoji/twitter/joy_cat.png differ diff --git a/public/images/emoji/twitter/joystick.png b/public/images/emoji/twitter/joystick.png new file mode 100644 index 00000000000..2cb7d212e2e Binary files /dev/null and b/public/images/emoji/twitter/joystick.png differ diff --git a/public/images/emoji/twitter/jp.png b/public/images/emoji/twitter/jp.png index 64967f96caa..01cc1ccc235 100644 Binary files a/public/images/emoji/twitter/jp.png and b/public/images/emoji/twitter/jp.png differ diff --git a/public/images/emoji/twitter/kaaba.png b/public/images/emoji/twitter/kaaba.png new file mode 100644 index 00000000000..1f4914e706f Binary files /dev/null and b/public/images/emoji/twitter/kaaba.png differ diff --git a/public/images/emoji/twitter/key.png b/public/images/emoji/twitter/key.png index e7be37b6d38..b17d1e8e80f 100644 Binary files a/public/images/emoji/twitter/key.png and b/public/images/emoji/twitter/key.png differ diff --git a/public/images/emoji/twitter/key2.png b/public/images/emoji/twitter/key2.png new file mode 100644 index 00000000000..bb0baeeb6d6 Binary files /dev/null and b/public/images/emoji/twitter/key2.png differ diff --git a/public/images/emoji/twitter/keyboard.png b/public/images/emoji/twitter/keyboard.png new file mode 100644 index 00000000000..35faa872efe Binary files /dev/null and b/public/images/emoji/twitter/keyboard.png differ diff --git a/public/images/emoji/twitter/keycap_ten.png b/public/images/emoji/twitter/keycap_ten.png index 60ef2a92dc4..9cd005d4d66 100644 Binary files a/public/images/emoji/twitter/keycap_ten.png and b/public/images/emoji/twitter/keycap_ten.png differ diff --git a/public/images/emoji/twitter/kimono.png b/public/images/emoji/twitter/kimono.png index fbb9d5d5180..ba0d140dde5 100644 Binary files a/public/images/emoji/twitter/kimono.png and b/public/images/emoji/twitter/kimono.png differ diff --git a/public/images/emoji/twitter/kiss.png b/public/images/emoji/twitter/kiss.png index aff0652a00d..7864eb58104 100644 Binary files a/public/images/emoji/twitter/kiss.png and b/public/images/emoji/twitter/kiss.png differ diff --git a/public/images/emoji/twitter/kissing.png b/public/images/emoji/twitter/kissing.png index 12d18f7c0b5..f4f143dc4cd 100644 Binary files a/public/images/emoji/twitter/kissing.png and b/public/images/emoji/twitter/kissing.png differ diff --git a/public/images/emoji/twitter/kissing_cat.png b/public/images/emoji/twitter/kissing_cat.png index 4ecc4e3fe45..445fb5261ba 100644 Binary files a/public/images/emoji/twitter/kissing_cat.png and b/public/images/emoji/twitter/kissing_cat.png differ diff --git a/public/images/emoji/twitter/kissing_closed_eyes.png b/public/images/emoji/twitter/kissing_closed_eyes.png index 8ebaff085a7..5cabbb2a6e3 100644 Binary files a/public/images/emoji/twitter/kissing_closed_eyes.png and b/public/images/emoji/twitter/kissing_closed_eyes.png differ diff --git a/public/images/emoji/twitter/kissing_heart.png b/public/images/emoji/twitter/kissing_heart.png index ed2db332fd2..10935eadb29 100644 Binary files a/public/images/emoji/twitter/kissing_heart.png and b/public/images/emoji/twitter/kissing_heart.png differ diff --git a/public/images/emoji/twitter/kissing_smiling_eyes.png b/public/images/emoji/twitter/kissing_smiling_eyes.png index 871680f68a7..443aab95cd6 100644 Binary files a/public/images/emoji/twitter/kissing_smiling_eyes.png and b/public/images/emoji/twitter/kissing_smiling_eyes.png differ diff --git a/public/images/emoji/twitter/knife.png b/public/images/emoji/twitter/knife.png index 1aae17f5b56..9f581344558 100644 Binary files a/public/images/emoji/twitter/knife.png and b/public/images/emoji/twitter/knife.png differ diff --git a/public/images/emoji/twitter/koala.png b/public/images/emoji/twitter/koala.png index 7dc6ffc0d8a..3b8dd5592ff 100644 Binary files a/public/images/emoji/twitter/koala.png and b/public/images/emoji/twitter/koala.png differ diff --git a/public/images/emoji/twitter/koko.png b/public/images/emoji/twitter/koko.png index cdfe2da9103..3ea190fbe2b 100644 Binary files a/public/images/emoji/twitter/koko.png and b/public/images/emoji/twitter/koko.png differ diff --git a/public/images/emoji/twitter/kr.png b/public/images/emoji/twitter/kr.png index 95d9d1f8aef..3fd1914c6ef 100644 Binary files a/public/images/emoji/twitter/kr.png and b/public/images/emoji/twitter/kr.png differ diff --git a/public/images/emoji/twitter/label.png b/public/images/emoji/twitter/label.png new file mode 100644 index 00000000000..b455f5684d5 Binary files /dev/null and b/public/images/emoji/twitter/label.png differ diff --git a/public/images/emoji/twitter/lantern.png b/public/images/emoji/twitter/lantern.png index b0db1cbed63..f1eee24fc70 100644 Binary files a/public/images/emoji/twitter/lantern.png and b/public/images/emoji/twitter/lantern.png differ diff --git a/public/images/emoji/twitter/large_blue_circle.png b/public/images/emoji/twitter/large_blue_circle.png index c88d962c76e..53f0ed3a262 100644 Binary files a/public/images/emoji/twitter/large_blue_circle.png and b/public/images/emoji/twitter/large_blue_circle.png differ diff --git a/public/images/emoji/twitter/large_blue_diamond.png b/public/images/emoji/twitter/large_blue_diamond.png index 6132b0ae5e0..53c7561eb44 100644 Binary files a/public/images/emoji/twitter/large_blue_diamond.png and b/public/images/emoji/twitter/large_blue_diamond.png differ diff --git a/public/images/emoji/twitter/large_orange_diamond.png b/public/images/emoji/twitter/large_orange_diamond.png index fe248ded8b6..ecfeac267cb 100644 Binary files a/public/images/emoji/twitter/large_orange_diamond.png and b/public/images/emoji/twitter/large_orange_diamond.png differ diff --git a/public/images/emoji/twitter/last_quarter_moon.png b/public/images/emoji/twitter/last_quarter_moon.png index e8df8a06e4a..b7ddaac49fc 100644 Binary files a/public/images/emoji/twitter/last_quarter_moon.png and b/public/images/emoji/twitter/last_quarter_moon.png differ diff --git a/public/images/emoji/twitter/last_quarter_moon_with_face.png b/public/images/emoji/twitter/last_quarter_moon_with_face.png index 8fd4b780d97..35c5f46ec00 100644 Binary files a/public/images/emoji/twitter/last_quarter_moon_with_face.png and b/public/images/emoji/twitter/last_quarter_moon_with_face.png differ diff --git a/public/images/emoji/twitter/laughing.png b/public/images/emoji/twitter/laughing.png index fa350e829e6..7601f88d77a 100644 Binary files a/public/images/emoji/twitter/laughing.png and b/public/images/emoji/twitter/laughing.png differ diff --git a/public/images/emoji/twitter/leaves.png b/public/images/emoji/twitter/leaves.png index b5d4212569a..f647745e7f1 100644 Binary files a/public/images/emoji/twitter/leaves.png and b/public/images/emoji/twitter/leaves.png differ diff --git a/public/images/emoji/twitter/ledger.png b/public/images/emoji/twitter/ledger.png index 065fd009a27..8b448a4c1fa 100644 Binary files a/public/images/emoji/twitter/ledger.png and b/public/images/emoji/twitter/ledger.png differ diff --git a/public/images/emoji/twitter/left_luggage.png b/public/images/emoji/twitter/left_luggage.png index abb4056828b..ddf472c098b 100644 Binary files a/public/images/emoji/twitter/left_luggage.png and b/public/images/emoji/twitter/left_luggage.png differ diff --git a/public/images/emoji/twitter/left_right_arrow.png b/public/images/emoji/twitter/left_right_arrow.png index 189d061eb27..8830e654493 100644 Binary files a/public/images/emoji/twitter/left_right_arrow.png and b/public/images/emoji/twitter/left_right_arrow.png differ diff --git a/public/images/emoji/twitter/leftwards_arrow_with_hook.png b/public/images/emoji/twitter/leftwards_arrow_with_hook.png index 959519d64f5..3794a11375f 100644 Binary files a/public/images/emoji/twitter/leftwards_arrow_with_hook.png and b/public/images/emoji/twitter/leftwards_arrow_with_hook.png differ diff --git a/public/images/emoji/twitter/lemon.png b/public/images/emoji/twitter/lemon.png index e36b8011915..7c978f6f1a3 100644 Binary files a/public/images/emoji/twitter/lemon.png and b/public/images/emoji/twitter/lemon.png differ diff --git a/public/images/emoji/twitter/leo.png b/public/images/emoji/twitter/leo.png index d2d00b2f6c0..275f8b789c6 100644 Binary files a/public/images/emoji/twitter/leo.png and b/public/images/emoji/twitter/leo.png differ diff --git a/public/images/emoji/twitter/leopard.png b/public/images/emoji/twitter/leopard.png index 61f54b70351..e07948f1031 100644 Binary files a/public/images/emoji/twitter/leopard.png and b/public/images/emoji/twitter/leopard.png differ diff --git a/public/images/emoji/twitter/level_slider.png b/public/images/emoji/twitter/level_slider.png new file mode 100644 index 00000000000..560cb59a09b Binary files /dev/null and b/public/images/emoji/twitter/level_slider.png differ diff --git a/public/images/emoji/twitter/levitate.png b/public/images/emoji/twitter/levitate.png new file mode 100644 index 00000000000..3a3c4b98947 Binary files /dev/null and b/public/images/emoji/twitter/levitate.png differ diff --git a/public/images/emoji/twitter/libra.png b/public/images/emoji/twitter/libra.png index 8033638220c..9787221fc08 100644 Binary files a/public/images/emoji/twitter/libra.png and b/public/images/emoji/twitter/libra.png differ diff --git a/public/images/emoji/twitter/lifter.png b/public/images/emoji/twitter/lifter.png new file mode 100644 index 00000000000..5f43a357761 Binary files /dev/null and b/public/images/emoji/twitter/lifter.png differ diff --git a/public/images/emoji/twitter/light_rail.png b/public/images/emoji/twitter/light_rail.png index 9644a1448ec..79d10c4bf9a 100644 Binary files a/public/images/emoji/twitter/light_rail.png and b/public/images/emoji/twitter/light_rail.png differ diff --git a/public/images/emoji/twitter/link.png b/public/images/emoji/twitter/link.png index aec60045bed..480c00ee9b6 100644 Binary files a/public/images/emoji/twitter/link.png and b/public/images/emoji/twitter/link.png differ diff --git a/public/images/emoji/twitter/lion_face.png b/public/images/emoji/twitter/lion_face.png new file mode 100644 index 00000000000..7e818c2c11a Binary files /dev/null and b/public/images/emoji/twitter/lion_face.png differ diff --git a/public/images/emoji/twitter/lips.png b/public/images/emoji/twitter/lips.png index bf071d34540..23f431fcb2c 100644 Binary files a/public/images/emoji/twitter/lips.png and b/public/images/emoji/twitter/lips.png differ diff --git a/public/images/emoji/twitter/lipstick.png b/public/images/emoji/twitter/lipstick.png index cd66dc73d44..0943584b24b 100644 Binary files a/public/images/emoji/twitter/lipstick.png and b/public/images/emoji/twitter/lipstick.png differ diff --git a/public/images/emoji/twitter/lock.png b/public/images/emoji/twitter/lock.png index 0ca7847e762..846c5d55f25 100644 Binary files a/public/images/emoji/twitter/lock.png and b/public/images/emoji/twitter/lock.png differ diff --git a/public/images/emoji/twitter/lock_with_ink_pen.png b/public/images/emoji/twitter/lock_with_ink_pen.png index 4545d84e6b3..ba5f871e645 100644 Binary files a/public/images/emoji/twitter/lock_with_ink_pen.png and b/public/images/emoji/twitter/lock_with_ink_pen.png differ diff --git a/public/images/emoji/twitter/lollipop.png b/public/images/emoji/twitter/lollipop.png index 8ee842079c9..d31a2e99e26 100644 Binary files a/public/images/emoji/twitter/lollipop.png and b/public/images/emoji/twitter/lollipop.png differ diff --git a/public/images/emoji/twitter/loop.png b/public/images/emoji/twitter/loop.png index 84531b512ee..03520c81d25 100644 Binary files a/public/images/emoji/twitter/loop.png and b/public/images/emoji/twitter/loop.png differ diff --git a/public/images/emoji/twitter/loud_sound.png b/public/images/emoji/twitter/loud_sound.png index 5223a4fdf09..cba0a749ab0 100644 Binary files a/public/images/emoji/twitter/loud_sound.png and b/public/images/emoji/twitter/loud_sound.png differ diff --git a/public/images/emoji/twitter/loudspeaker.png b/public/images/emoji/twitter/loudspeaker.png index 07a48a075b4..dc3c4a347af 100644 Binary files a/public/images/emoji/twitter/loudspeaker.png and b/public/images/emoji/twitter/loudspeaker.png differ diff --git a/public/images/emoji/twitter/love_hotel.png b/public/images/emoji/twitter/love_hotel.png index 361bd8b90a8..165600c9c18 100644 Binary files a/public/images/emoji/twitter/love_hotel.png and b/public/images/emoji/twitter/love_hotel.png differ diff --git a/public/images/emoji/twitter/love_letter.png b/public/images/emoji/twitter/love_letter.png index f21cb7ce09a..92c4f068c67 100644 Binary files a/public/images/emoji/twitter/love_letter.png and b/public/images/emoji/twitter/love_letter.png differ diff --git a/public/images/emoji/twitter/low_brightness.png b/public/images/emoji/twitter/low_brightness.png index 3793de1799d..959f1333b2d 100644 Binary files a/public/images/emoji/twitter/low_brightness.png and b/public/images/emoji/twitter/low_brightness.png differ diff --git a/public/images/emoji/twitter/m.png b/public/images/emoji/twitter/m.png index 194552e9a1e..ba50344aedd 100644 Binary files a/public/images/emoji/twitter/m.png and b/public/images/emoji/twitter/m.png differ diff --git a/public/images/emoji/twitter/mag.png b/public/images/emoji/twitter/mag.png index 7b0029e5787..cc0b35516c0 100644 Binary files a/public/images/emoji/twitter/mag.png and b/public/images/emoji/twitter/mag.png differ diff --git a/public/images/emoji/twitter/mag_right.png b/public/images/emoji/twitter/mag_right.png index 768ea434824..6cf56975d16 100644 Binary files a/public/images/emoji/twitter/mag_right.png and b/public/images/emoji/twitter/mag_right.png differ diff --git a/public/images/emoji/twitter/mahjong.png b/public/images/emoji/twitter/mahjong.png index 0bd4418bb39..71cc0affb67 100644 Binary files a/public/images/emoji/twitter/mahjong.png and b/public/images/emoji/twitter/mahjong.png differ diff --git a/public/images/emoji/twitter/mailbox.png b/public/images/emoji/twitter/mailbox.png index a4971adecb1..f6d85e6196d 100644 Binary files a/public/images/emoji/twitter/mailbox.png and b/public/images/emoji/twitter/mailbox.png differ diff --git a/public/images/emoji/twitter/mailbox_closed.png b/public/images/emoji/twitter/mailbox_closed.png index 4cd28cf556c..649c33a1a79 100644 Binary files a/public/images/emoji/twitter/mailbox_closed.png and b/public/images/emoji/twitter/mailbox_closed.png differ diff --git a/public/images/emoji/twitter/mailbox_with_mail.png b/public/images/emoji/twitter/mailbox_with_mail.png index e2d7887c7ff..52a21f58d33 100644 Binary files a/public/images/emoji/twitter/mailbox_with_mail.png and b/public/images/emoji/twitter/mailbox_with_mail.png differ diff --git a/public/images/emoji/twitter/mailbox_with_no_mail.png b/public/images/emoji/twitter/mailbox_with_no_mail.png index 9fa2c61b618..4a9836da13d 100644 Binary files a/public/images/emoji/twitter/mailbox_with_no_mail.png and b/public/images/emoji/twitter/mailbox_with_no_mail.png differ diff --git a/public/images/emoji/twitter/man.png b/public/images/emoji/twitter/man.png index e10fc1521c1..40fb365247a 100644 Binary files a/public/images/emoji/twitter/man.png and b/public/images/emoji/twitter/man.png differ diff --git a/public/images/emoji/twitter/man_with_gua_pi_mao.png b/public/images/emoji/twitter/man_with_gua_pi_mao.png index fc3a90d2dee..d351ebb31a3 100644 Binary files a/public/images/emoji/twitter/man_with_gua_pi_mao.png and b/public/images/emoji/twitter/man_with_gua_pi_mao.png differ diff --git a/public/images/emoji/twitter/man_with_turban.png b/public/images/emoji/twitter/man_with_turban.png index 22d5ac6b444..2670ca4a0b0 100644 Binary files a/public/images/emoji/twitter/man_with_turban.png and b/public/images/emoji/twitter/man_with_turban.png differ diff --git a/public/images/emoji/twitter/mans_shoe.png b/public/images/emoji/twitter/mans_shoe.png index 71d4be2c33f..57ad408c73f 100644 Binary files a/public/images/emoji/twitter/mans_shoe.png and b/public/images/emoji/twitter/mans_shoe.png differ diff --git a/public/images/emoji/twitter/map.png b/public/images/emoji/twitter/map.png new file mode 100644 index 00000000000..c7a727c28f8 Binary files /dev/null and b/public/images/emoji/twitter/map.png differ diff --git a/public/images/emoji/twitter/maple_leaf.png b/public/images/emoji/twitter/maple_leaf.png index 97faddd01c9..49279388015 100644 Binary files a/public/images/emoji/twitter/maple_leaf.png and b/public/images/emoji/twitter/maple_leaf.png differ diff --git a/public/images/emoji/twitter/mask.png b/public/images/emoji/twitter/mask.png index f10360e5f6f..d879de77af8 100644 Binary files a/public/images/emoji/twitter/mask.png and b/public/images/emoji/twitter/mask.png differ diff --git a/public/images/emoji/twitter/massage.png b/public/images/emoji/twitter/massage.png index 8d72618c54b..1e5c253b47e 100644 Binary files a/public/images/emoji/twitter/massage.png and b/public/images/emoji/twitter/massage.png differ diff --git a/public/images/emoji/twitter/meat_on_bone.png b/public/images/emoji/twitter/meat_on_bone.png index 33a16690a58..23cfcd5ed27 100644 Binary files a/public/images/emoji/twitter/meat_on_bone.png and b/public/images/emoji/twitter/meat_on_bone.png differ diff --git a/public/images/emoji/twitter/medal.png b/public/images/emoji/twitter/medal.png new file mode 100644 index 00000000000..c56f77095f0 Binary files /dev/null and b/public/images/emoji/twitter/medal.png differ diff --git a/public/images/emoji/twitter/mega.png b/public/images/emoji/twitter/mega.png index d77e10cc9f5..e5e3942c11c 100644 Binary files a/public/images/emoji/twitter/mega.png and b/public/images/emoji/twitter/mega.png differ diff --git a/public/images/emoji/twitter/melon.png b/public/images/emoji/twitter/melon.png index d5243e0c9ec..8608115191c 100644 Binary files a/public/images/emoji/twitter/melon.png and b/public/images/emoji/twitter/melon.png differ diff --git a/public/images/emoji/twitter/memo.png b/public/images/emoji/twitter/memo.png index 9bbc624eb01..c2f7d00942f 100644 Binary files a/public/images/emoji/twitter/memo.png and b/public/images/emoji/twitter/memo.png differ diff --git a/public/images/emoji/twitter/menorah.png b/public/images/emoji/twitter/menorah.png new file mode 100644 index 00000000000..f63c13ac9b1 Binary files /dev/null and b/public/images/emoji/twitter/menorah.png differ diff --git a/public/images/emoji/twitter/mens.png b/public/images/emoji/twitter/mens.png index 3b84cf01cbf..d307905f172 100644 Binary files a/public/images/emoji/twitter/mens.png and b/public/images/emoji/twitter/mens.png differ diff --git a/public/images/emoji/twitter/metal.png b/public/images/emoji/twitter/metal.png new file mode 100644 index 00000000000..6107226f130 Binary files /dev/null and b/public/images/emoji/twitter/metal.png differ diff --git a/public/images/emoji/twitter/metro.png b/public/images/emoji/twitter/metro.png index 319b6428d27..c4363d086d6 100644 Binary files a/public/images/emoji/twitter/metro.png and b/public/images/emoji/twitter/metro.png differ diff --git a/public/images/emoji/twitter/microphone.png b/public/images/emoji/twitter/microphone.png index 3e909125b18..796d91dd9d1 100644 Binary files a/public/images/emoji/twitter/microphone.png and b/public/images/emoji/twitter/microphone.png differ diff --git a/public/images/emoji/twitter/microphone2.png b/public/images/emoji/twitter/microphone2.png new file mode 100644 index 00000000000..a256e3d491e Binary files /dev/null and b/public/images/emoji/twitter/microphone2.png differ diff --git a/public/images/emoji/twitter/microscope.png b/public/images/emoji/twitter/microscope.png index d06f145d9f5..9d476cb700d 100644 Binary files a/public/images/emoji/twitter/microscope.png and b/public/images/emoji/twitter/microscope.png differ diff --git a/public/images/emoji/twitter/middle_finger.png b/public/images/emoji/twitter/middle_finger.png new file mode 100644 index 00000000000..ba7dcb95d6d Binary files /dev/null and b/public/images/emoji/twitter/middle_finger.png differ diff --git a/public/images/emoji/twitter/military_medal.png b/public/images/emoji/twitter/military_medal.png new file mode 100644 index 00000000000..afa7ac77e85 Binary files /dev/null and b/public/images/emoji/twitter/military_medal.png differ diff --git a/public/images/emoji/twitter/milky_way.png b/public/images/emoji/twitter/milky_way.png index d8bc86ba7ca..294fc6fceca 100644 Binary files a/public/images/emoji/twitter/milky_way.png and b/public/images/emoji/twitter/milky_way.png differ diff --git a/public/images/emoji/twitter/minibus.png b/public/images/emoji/twitter/minibus.png index 592058cd581..df8fa903531 100644 Binary files a/public/images/emoji/twitter/minibus.png and b/public/images/emoji/twitter/minibus.png differ diff --git a/public/images/emoji/twitter/minidisc.png b/public/images/emoji/twitter/minidisc.png index d7e1bea69ab..844efe377ba 100644 Binary files a/public/images/emoji/twitter/minidisc.png and b/public/images/emoji/twitter/minidisc.png differ diff --git a/public/images/emoji/twitter/mobile_phone_off.png b/public/images/emoji/twitter/mobile_phone_off.png index ae6eddf731f..a902b33683f 100644 Binary files a/public/images/emoji/twitter/mobile_phone_off.png and b/public/images/emoji/twitter/mobile_phone_off.png differ diff --git a/public/images/emoji/twitter/money_mouth.png b/public/images/emoji/twitter/money_mouth.png new file mode 100644 index 00000000000..c1f7dcaa33d Binary files /dev/null and b/public/images/emoji/twitter/money_mouth.png differ diff --git a/public/images/emoji/twitter/money_with_wings.png b/public/images/emoji/twitter/money_with_wings.png index cef4d0d53d2..45798c0525b 100644 Binary files a/public/images/emoji/twitter/money_with_wings.png and b/public/images/emoji/twitter/money_with_wings.png differ diff --git a/public/images/emoji/twitter/moneybag.png b/public/images/emoji/twitter/moneybag.png index 21fd16a1a3d..cf810c29d4f 100644 Binary files a/public/images/emoji/twitter/moneybag.png and b/public/images/emoji/twitter/moneybag.png differ diff --git a/public/images/emoji/twitter/monkey.png b/public/images/emoji/twitter/monkey.png index 47aa8197836..6bd4795e2e9 100644 Binary files a/public/images/emoji/twitter/monkey.png and b/public/images/emoji/twitter/monkey.png differ diff --git a/public/images/emoji/twitter/monkey_face.png b/public/images/emoji/twitter/monkey_face.png index bd19d05d9c6..fa67a7ec45c 100644 Binary files a/public/images/emoji/twitter/monkey_face.png and b/public/images/emoji/twitter/monkey_face.png differ diff --git a/public/images/emoji/twitter/monorail.png b/public/images/emoji/twitter/monorail.png index 1887dd9e7df..3c53b952f05 100644 Binary files a/public/images/emoji/twitter/monorail.png and b/public/images/emoji/twitter/monorail.png differ diff --git a/public/images/emoji/twitter/moon.png b/public/images/emoji/twitter/moon.png index 319561d7109..6a990e2d3e1 100644 Binary files a/public/images/emoji/twitter/moon.png and b/public/images/emoji/twitter/moon.png differ diff --git a/public/images/emoji/twitter/mortar_board.png b/public/images/emoji/twitter/mortar_board.png index f50bb041196..dcd0ab9aa1a 100644 Binary files a/public/images/emoji/twitter/mortar_board.png and b/public/images/emoji/twitter/mortar_board.png differ diff --git a/public/images/emoji/twitter/mosque.png b/public/images/emoji/twitter/mosque.png new file mode 100644 index 00000000000..570f6971c62 Binary files /dev/null and b/public/images/emoji/twitter/mosque.png differ diff --git a/public/images/emoji/twitter/motorboat.png b/public/images/emoji/twitter/motorboat.png new file mode 100644 index 00000000000..a849f0683af Binary files /dev/null and b/public/images/emoji/twitter/motorboat.png differ diff --git a/public/images/emoji/twitter/motorcycle.png b/public/images/emoji/twitter/motorcycle.png new file mode 100644 index 00000000000..89f8265e3fb Binary files /dev/null and b/public/images/emoji/twitter/motorcycle.png differ diff --git a/public/images/emoji/twitter/motorway.png b/public/images/emoji/twitter/motorway.png new file mode 100644 index 00000000000..8bc3caf9510 Binary files /dev/null and b/public/images/emoji/twitter/motorway.png differ diff --git a/public/images/emoji/twitter/mount_fuji.png b/public/images/emoji/twitter/mount_fuji.png index 1a5fe70d2cb..858b10e84ee 100644 Binary files a/public/images/emoji/twitter/mount_fuji.png and b/public/images/emoji/twitter/mount_fuji.png differ diff --git a/public/images/emoji/twitter/mountain.png b/public/images/emoji/twitter/mountain.png new file mode 100644 index 00000000000..01384a0d1eb Binary files /dev/null and b/public/images/emoji/twitter/mountain.png differ diff --git a/public/images/emoji/twitter/mountain_bicyclist.png b/public/images/emoji/twitter/mountain_bicyclist.png index d9bc79c759e..5294de7061f 100644 Binary files a/public/images/emoji/twitter/mountain_bicyclist.png and b/public/images/emoji/twitter/mountain_bicyclist.png differ diff --git a/public/images/emoji/twitter/mountain_cableway.png b/public/images/emoji/twitter/mountain_cableway.png index 0d5fb274c7f..5f5018e126a 100644 Binary files a/public/images/emoji/twitter/mountain_cableway.png and b/public/images/emoji/twitter/mountain_cableway.png differ diff --git a/public/images/emoji/twitter/mountain_railway.png b/public/images/emoji/twitter/mountain_railway.png index 1b3d6b85931..9768330992b 100644 Binary files a/public/images/emoji/twitter/mountain_railway.png and b/public/images/emoji/twitter/mountain_railway.png differ diff --git a/public/images/emoji/twitter/mountain_snow.png b/public/images/emoji/twitter/mountain_snow.png new file mode 100644 index 00000000000..05f51304e91 Binary files /dev/null and b/public/images/emoji/twitter/mountain_snow.png differ diff --git a/public/images/emoji/twitter/mouse.png b/public/images/emoji/twitter/mouse.png index 0c10a90bd1f..5ce0a4c250d 100644 Binary files a/public/images/emoji/twitter/mouse.png and b/public/images/emoji/twitter/mouse.png differ diff --git a/public/images/emoji/twitter/mouse2.png b/public/images/emoji/twitter/mouse2.png index 0f91255e3f0..506da85054a 100644 Binary files a/public/images/emoji/twitter/mouse2.png and b/public/images/emoji/twitter/mouse2.png differ diff --git a/public/images/emoji/twitter/mouse_three_button.png b/public/images/emoji/twitter/mouse_three_button.png new file mode 100644 index 00000000000..08541826f40 Binary files /dev/null and b/public/images/emoji/twitter/mouse_three_button.png differ diff --git a/public/images/emoji/twitter/movie_camera.png b/public/images/emoji/twitter/movie_camera.png index 084e37772ea..f9d5434d5a0 100644 Binary files a/public/images/emoji/twitter/movie_camera.png and b/public/images/emoji/twitter/movie_camera.png differ diff --git a/public/images/emoji/twitter/moyai.png b/public/images/emoji/twitter/moyai.png index 4e711f21521..38d55a829f4 100644 Binary files a/public/images/emoji/twitter/moyai.png and b/public/images/emoji/twitter/moyai.png differ diff --git a/public/images/emoji/twitter/muscle.png b/public/images/emoji/twitter/muscle.png index 34fa6c55385..c1baf8497d0 100644 Binary files a/public/images/emoji/twitter/muscle.png and b/public/images/emoji/twitter/muscle.png differ diff --git a/public/images/emoji/twitter/mushroom.png b/public/images/emoji/twitter/mushroom.png index c5ac4e5338d..fd4da2bb105 100644 Binary files a/public/images/emoji/twitter/mushroom.png and b/public/images/emoji/twitter/mushroom.png differ diff --git a/public/images/emoji/twitter/musical_keyboard.png b/public/images/emoji/twitter/musical_keyboard.png index 2c579cef7b4..7fdfbb07078 100644 Binary files a/public/images/emoji/twitter/musical_keyboard.png and b/public/images/emoji/twitter/musical_keyboard.png differ diff --git a/public/images/emoji/twitter/musical_note.png b/public/images/emoji/twitter/musical_note.png index 16ebcca7d6e..dde6e70271a 100644 Binary files a/public/images/emoji/twitter/musical_note.png and b/public/images/emoji/twitter/musical_note.png differ diff --git a/public/images/emoji/twitter/musical_score.png b/public/images/emoji/twitter/musical_score.png index a381d646a2a..93814151957 100644 Binary files a/public/images/emoji/twitter/musical_score.png and b/public/images/emoji/twitter/musical_score.png differ diff --git a/public/images/emoji/twitter/mute.png b/public/images/emoji/twitter/mute.png index e32805db1ab..2b1f7af89e9 100644 Binary files a/public/images/emoji/twitter/mute.png and b/public/images/emoji/twitter/mute.png differ diff --git a/public/images/emoji/twitter/nail_care.png b/public/images/emoji/twitter/nail_care.png index 26218548ab8..168b7305933 100644 Binary files a/public/images/emoji/twitter/nail_care.png and b/public/images/emoji/twitter/nail_care.png differ diff --git a/public/images/emoji/twitter/name_badge.png b/public/images/emoji/twitter/name_badge.png index d2f06bdfc94..b7371811a8a 100644 Binary files a/public/images/emoji/twitter/name_badge.png and b/public/images/emoji/twitter/name_badge.png differ diff --git a/public/images/emoji/twitter/necktie.png b/public/images/emoji/twitter/necktie.png index c4a1381dd30..1d24cccb4c3 100644 Binary files a/public/images/emoji/twitter/necktie.png and b/public/images/emoji/twitter/necktie.png differ diff --git a/public/images/emoji/twitter/negative_squared_cross_mark.png b/public/images/emoji/twitter/negative_squared_cross_mark.png index 7906549a9da..537f7c9493e 100644 Binary files a/public/images/emoji/twitter/negative_squared_cross_mark.png and b/public/images/emoji/twitter/negative_squared_cross_mark.png differ diff --git a/public/images/emoji/twitter/nerd.png b/public/images/emoji/twitter/nerd.png new file mode 100644 index 00000000000..1d14fc303cb Binary files /dev/null and b/public/images/emoji/twitter/nerd.png differ diff --git a/public/images/emoji/twitter/neutral_face.png b/public/images/emoji/twitter/neutral_face.png index 2cfa8c444f7..4261c23af52 100644 Binary files a/public/images/emoji/twitter/neutral_face.png and b/public/images/emoji/twitter/neutral_face.png differ diff --git a/public/images/emoji/twitter/new.png b/public/images/emoji/twitter/new.png index 276537a3989..c1ebd95b3ba 100644 Binary files a/public/images/emoji/twitter/new.png and b/public/images/emoji/twitter/new.png differ diff --git a/public/images/emoji/twitter/new_moon.png b/public/images/emoji/twitter/new_moon.png index 6d497dc1148..d196481f78c 100644 Binary files a/public/images/emoji/twitter/new_moon.png and b/public/images/emoji/twitter/new_moon.png differ diff --git a/public/images/emoji/twitter/new_moon_with_face.png b/public/images/emoji/twitter/new_moon_with_face.png index ebceb6b1cc8..3d7b15a841d 100644 Binary files a/public/images/emoji/twitter/new_moon_with_face.png and b/public/images/emoji/twitter/new_moon_with_face.png differ diff --git a/public/images/emoji/twitter/newspaper.png b/public/images/emoji/twitter/newspaper.png index 41c5f765e44..40b3d722c1b 100644 Binary files a/public/images/emoji/twitter/newspaper.png and b/public/images/emoji/twitter/newspaper.png differ diff --git a/public/images/emoji/twitter/newspaper2.png b/public/images/emoji/twitter/newspaper2.png new file mode 100644 index 00000000000..bc184c041ed Binary files /dev/null and b/public/images/emoji/twitter/newspaper2.png differ diff --git a/public/images/emoji/twitter/ng.png b/public/images/emoji/twitter/ng.png index f8e409a8673..4979e1d2888 100644 Binary files a/public/images/emoji/twitter/ng.png and b/public/images/emoji/twitter/ng.png differ diff --git a/public/images/emoji/twitter/night_with_stars.png b/public/images/emoji/twitter/night_with_stars.png index 0635fe3d28f..cb19066ac9d 100644 Binary files a/public/images/emoji/twitter/night_with_stars.png and b/public/images/emoji/twitter/night_with_stars.png differ diff --git a/public/images/emoji/twitter/no_bell.png b/public/images/emoji/twitter/no_bell.png index fdb2c84b644..ad89f639810 100644 Binary files a/public/images/emoji/twitter/no_bell.png and b/public/images/emoji/twitter/no_bell.png differ diff --git a/public/images/emoji/twitter/no_bicycles.png b/public/images/emoji/twitter/no_bicycles.png index 84f5ef0d2c1..c5cb70e3550 100644 Binary files a/public/images/emoji/twitter/no_bicycles.png and b/public/images/emoji/twitter/no_bicycles.png differ diff --git a/public/images/emoji/twitter/no_entry.png b/public/images/emoji/twitter/no_entry.png index 2f119b691ad..8274ee05df5 100644 Binary files a/public/images/emoji/twitter/no_entry.png and b/public/images/emoji/twitter/no_entry.png differ diff --git a/public/images/emoji/twitter/no_entry_sign.png b/public/images/emoji/twitter/no_entry_sign.png index 89d8c80b54e..8bd12ca9c85 100644 Binary files a/public/images/emoji/twitter/no_entry_sign.png and b/public/images/emoji/twitter/no_entry_sign.png differ diff --git a/public/images/emoji/twitter/no_good.png b/public/images/emoji/twitter/no_good.png index 9869f61e33e..83c70a8ae2c 100644 Binary files a/public/images/emoji/twitter/no_good.png and b/public/images/emoji/twitter/no_good.png differ diff --git a/public/images/emoji/twitter/no_mobile_phones.png b/public/images/emoji/twitter/no_mobile_phones.png index d9f18020d09..00d21f50660 100644 Binary files a/public/images/emoji/twitter/no_mobile_phones.png and b/public/images/emoji/twitter/no_mobile_phones.png differ diff --git a/public/images/emoji/twitter/no_mouth.png b/public/images/emoji/twitter/no_mouth.png index 1ce9b90a8b2..c2b4f3e0085 100644 Binary files a/public/images/emoji/twitter/no_mouth.png and b/public/images/emoji/twitter/no_mouth.png differ diff --git a/public/images/emoji/twitter/no_pedestrians.png b/public/images/emoji/twitter/no_pedestrians.png index a5b334b508f..52fdb72b15c 100644 Binary files a/public/images/emoji/twitter/no_pedestrians.png and b/public/images/emoji/twitter/no_pedestrians.png differ diff --git a/public/images/emoji/twitter/no_smoking.png b/public/images/emoji/twitter/no_smoking.png index 44deedbac9f..dfa574a2b79 100644 Binary files a/public/images/emoji/twitter/no_smoking.png and b/public/images/emoji/twitter/no_smoking.png differ diff --git a/public/images/emoji/twitter/non-potable_water.png b/public/images/emoji/twitter/non-potable_water.png index 7073d006ee5..25585cd0020 100644 Binary files a/public/images/emoji/twitter/non-potable_water.png and b/public/images/emoji/twitter/non-potable_water.png differ diff --git a/public/images/emoji/twitter/nose.png b/public/images/emoji/twitter/nose.png index 0ebca56495b..fae396ae6be 100644 Binary files a/public/images/emoji/twitter/nose.png and b/public/images/emoji/twitter/nose.png differ diff --git a/public/images/emoji/twitter/notebook.png b/public/images/emoji/twitter/notebook.png index c9a88cbb4e3..4d7110ed80b 100644 Binary files a/public/images/emoji/twitter/notebook.png and b/public/images/emoji/twitter/notebook.png differ diff --git a/public/images/emoji/twitter/notebook_with_decorative_cover.png b/public/images/emoji/twitter/notebook_with_decorative_cover.png index d856c5bbf3c..833cf40dbea 100644 Binary files a/public/images/emoji/twitter/notebook_with_decorative_cover.png and b/public/images/emoji/twitter/notebook_with_decorative_cover.png differ diff --git a/public/images/emoji/twitter/notepad_spiral.png b/public/images/emoji/twitter/notepad_spiral.png new file mode 100644 index 00000000000..b57a95c28a0 Binary files /dev/null and b/public/images/emoji/twitter/notepad_spiral.png differ diff --git a/public/images/emoji/twitter/notes.png b/public/images/emoji/twitter/notes.png index a3cbb555c2c..2cbc951cac6 100644 Binary files a/public/images/emoji/twitter/notes.png and b/public/images/emoji/twitter/notes.png differ diff --git a/public/images/emoji/twitter/nut_and_bolt.png b/public/images/emoji/twitter/nut_and_bolt.png index 18e60933441..31b21dd2ca5 100644 Binary files a/public/images/emoji/twitter/nut_and_bolt.png and b/public/images/emoji/twitter/nut_and_bolt.png differ diff --git a/public/images/emoji/twitter/o.png b/public/images/emoji/twitter/o.png index fc938e887e2..e9964a2fab9 100644 Binary files a/public/images/emoji/twitter/o.png and b/public/images/emoji/twitter/o.png differ diff --git a/public/images/emoji/twitter/o2.png b/public/images/emoji/twitter/o2.png index 9d601e39daa..174f217c92c 100644 Binary files a/public/images/emoji/twitter/o2.png and b/public/images/emoji/twitter/o2.png differ diff --git a/public/images/emoji/twitter/ocean.png b/public/images/emoji/twitter/ocean.png index 8da365de185..c21507673af 100644 Binary files a/public/images/emoji/twitter/ocean.png and b/public/images/emoji/twitter/ocean.png differ diff --git a/public/images/emoji/twitter/octopus.png b/public/images/emoji/twitter/octopus.png index 2ef3384087a..c5798b43185 100644 Binary files a/public/images/emoji/twitter/octopus.png and b/public/images/emoji/twitter/octopus.png differ diff --git a/public/images/emoji/twitter/oden.png b/public/images/emoji/twitter/oden.png index 2859686c062..dd29356a74c 100644 Binary files a/public/images/emoji/twitter/oden.png and b/public/images/emoji/twitter/oden.png differ diff --git a/public/images/emoji/twitter/office.png b/public/images/emoji/twitter/office.png index b991af54dd8..9009632b632 100644 Binary files a/public/images/emoji/twitter/office.png and b/public/images/emoji/twitter/office.png differ diff --git a/public/images/emoji/twitter/oil.png b/public/images/emoji/twitter/oil.png new file mode 100644 index 00000000000..6aab4045d7a Binary files /dev/null and b/public/images/emoji/twitter/oil.png differ diff --git a/public/images/emoji/twitter/ok.png b/public/images/emoji/twitter/ok.png index 0820262bed8..93f62cb4920 100644 Binary files a/public/images/emoji/twitter/ok.png and b/public/images/emoji/twitter/ok.png differ diff --git a/public/images/emoji/twitter/ok_hand.png b/public/images/emoji/twitter/ok_hand.png index fb8ea8e73a0..9efe8a8c885 100644 Binary files a/public/images/emoji/twitter/ok_hand.png and b/public/images/emoji/twitter/ok_hand.png differ diff --git a/public/images/emoji/twitter/ok_woman.png b/public/images/emoji/twitter/ok_woman.png index d072795cd91..c912be42fc7 100644 Binary files a/public/images/emoji/twitter/ok_woman.png and b/public/images/emoji/twitter/ok_woman.png differ diff --git a/public/images/emoji/twitter/older_man.png b/public/images/emoji/twitter/older_man.png index 9ace4c880eb..2fcaf291cdf 100644 Binary files a/public/images/emoji/twitter/older_man.png and b/public/images/emoji/twitter/older_man.png differ diff --git a/public/images/emoji/twitter/older_woman.png b/public/images/emoji/twitter/older_woman.png index 2b2c9f47d30..141dc4ea42d 100644 Binary files a/public/images/emoji/twitter/older_woman.png and b/public/images/emoji/twitter/older_woman.png differ diff --git a/public/images/emoji/twitter/om_symbol.png b/public/images/emoji/twitter/om_symbol.png new file mode 100644 index 00000000000..6b59c980321 Binary files /dev/null and b/public/images/emoji/twitter/om_symbol.png differ diff --git a/public/images/emoji/twitter/on.png b/public/images/emoji/twitter/on.png index 1e1645555db..447ac16af90 100644 Binary files a/public/images/emoji/twitter/on.png and b/public/images/emoji/twitter/on.png differ diff --git a/public/images/emoji/twitter/oncoming_automobile.png b/public/images/emoji/twitter/oncoming_automobile.png index 32c53649559..d6c19c9e5bc 100644 Binary files a/public/images/emoji/twitter/oncoming_automobile.png and b/public/images/emoji/twitter/oncoming_automobile.png differ diff --git a/public/images/emoji/twitter/oncoming_bus.png b/public/images/emoji/twitter/oncoming_bus.png index 6a83467842e..043ef58993c 100644 Binary files a/public/images/emoji/twitter/oncoming_bus.png and b/public/images/emoji/twitter/oncoming_bus.png differ diff --git a/public/images/emoji/twitter/oncoming_police_car.png b/public/images/emoji/twitter/oncoming_police_car.png index 291162ca577..7548baa99df 100644 Binary files a/public/images/emoji/twitter/oncoming_police_car.png and b/public/images/emoji/twitter/oncoming_police_car.png differ diff --git a/public/images/emoji/twitter/oncoming_taxi.png b/public/images/emoji/twitter/oncoming_taxi.png index acb98146929..43e3e150299 100644 Binary files a/public/images/emoji/twitter/oncoming_taxi.png and b/public/images/emoji/twitter/oncoming_taxi.png differ diff --git a/public/images/emoji/twitter/one.png b/public/images/emoji/twitter/one.png index 1155e53a510..e61050b625c 100644 Binary files a/public/images/emoji/twitter/one.png and b/public/images/emoji/twitter/one.png differ diff --git a/public/images/emoji/twitter/open_book.png b/public/images/emoji/twitter/open_book.png index da480828426..c952d6ab398 100644 Binary files a/public/images/emoji/twitter/open_book.png and b/public/images/emoji/twitter/open_book.png differ diff --git a/public/images/emoji/twitter/open_file_folder.png b/public/images/emoji/twitter/open_file_folder.png index cc2d2f3ebad..3f4973e52de 100644 Binary files a/public/images/emoji/twitter/open_file_folder.png and b/public/images/emoji/twitter/open_file_folder.png differ diff --git a/public/images/emoji/twitter/open_hands.png b/public/images/emoji/twitter/open_hands.png index 54ce8e260a4..1312422d96e 100644 Binary files a/public/images/emoji/twitter/open_hands.png and b/public/images/emoji/twitter/open_hands.png differ diff --git a/public/images/emoji/twitter/open_mouth.png b/public/images/emoji/twitter/open_mouth.png index f079cebcbc6..e7a33f5c734 100644 Binary files a/public/images/emoji/twitter/open_mouth.png and b/public/images/emoji/twitter/open_mouth.png differ diff --git a/public/images/emoji/twitter/ophiuchus.png b/public/images/emoji/twitter/ophiuchus.png index 718308fff6a..e8355c92975 100644 Binary files a/public/images/emoji/twitter/ophiuchus.png and b/public/images/emoji/twitter/ophiuchus.png differ diff --git a/public/images/emoji/twitter/orange_book.png b/public/images/emoji/twitter/orange_book.png index 25dc2e153b7..d7096796720 100644 Binary files a/public/images/emoji/twitter/orange_book.png and b/public/images/emoji/twitter/orange_book.png differ diff --git a/public/images/emoji/twitter/orthodox_cross.png b/public/images/emoji/twitter/orthodox_cross.png new file mode 100644 index 00000000000..796b51f9d14 Binary files /dev/null and b/public/images/emoji/twitter/orthodox_cross.png differ diff --git a/public/images/emoji/twitter/outbox_tray.png b/public/images/emoji/twitter/outbox_tray.png index 1243a9c7873..1e5b5986d4f 100644 Binary files a/public/images/emoji/twitter/outbox_tray.png and b/public/images/emoji/twitter/outbox_tray.png differ diff --git a/public/images/emoji/twitter/ox.png b/public/images/emoji/twitter/ox.png index 0404a21d6d8..9f953f848df 100644 Binary files a/public/images/emoji/twitter/ox.png and b/public/images/emoji/twitter/ox.png differ diff --git a/public/images/emoji/twitter/package.png b/public/images/emoji/twitter/package.png index f707f1242bf..39ec969aba0 100644 Binary files a/public/images/emoji/twitter/package.png and b/public/images/emoji/twitter/package.png differ diff --git a/public/images/emoji/twitter/page_facing_up.png b/public/images/emoji/twitter/page_facing_up.png index 4927daf5bdd..dce1f3639c6 100644 Binary files a/public/images/emoji/twitter/page_facing_up.png and b/public/images/emoji/twitter/page_facing_up.png differ diff --git a/public/images/emoji/twitter/page_with_curl.png b/public/images/emoji/twitter/page_with_curl.png index 10e3219b9db..d13d198c6d6 100644 Binary files a/public/images/emoji/twitter/page_with_curl.png and b/public/images/emoji/twitter/page_with_curl.png differ diff --git a/public/images/emoji/twitter/pager.png b/public/images/emoji/twitter/pager.png index f1ae64ce335..7cb248980a5 100644 Binary files a/public/images/emoji/twitter/pager.png and b/public/images/emoji/twitter/pager.png differ diff --git a/public/images/emoji/twitter/paintbrush.png b/public/images/emoji/twitter/paintbrush.png new file mode 100644 index 00000000000..94b575de127 Binary files /dev/null and b/public/images/emoji/twitter/paintbrush.png differ diff --git a/public/images/emoji/twitter/palm_tree.png b/public/images/emoji/twitter/palm_tree.png index 918ed0c4e73..98469a5202f 100644 Binary files a/public/images/emoji/twitter/palm_tree.png and b/public/images/emoji/twitter/palm_tree.png differ diff --git a/public/images/emoji/twitter/panda_face.png b/public/images/emoji/twitter/panda_face.png index 59cdd2a7aea..8b846e852f4 100644 Binary files a/public/images/emoji/twitter/panda_face.png and b/public/images/emoji/twitter/panda_face.png differ diff --git a/public/images/emoji/twitter/paperclip.png b/public/images/emoji/twitter/paperclip.png index 0a92e4219d6..9fcbeca6ec7 100644 Binary files a/public/images/emoji/twitter/paperclip.png and b/public/images/emoji/twitter/paperclip.png differ diff --git a/public/images/emoji/twitter/paperclips.png b/public/images/emoji/twitter/paperclips.png new file mode 100644 index 00000000000..126b4392695 Binary files /dev/null and b/public/images/emoji/twitter/paperclips.png differ diff --git a/public/images/emoji/twitter/park.png b/public/images/emoji/twitter/park.png new file mode 100644 index 00000000000..5dec43509b4 Binary files /dev/null and b/public/images/emoji/twitter/park.png differ diff --git a/public/images/emoji/twitter/parking.png b/public/images/emoji/twitter/parking.png index efbfbebd9fe..3824025e51f 100644 Binary files a/public/images/emoji/twitter/parking.png and b/public/images/emoji/twitter/parking.png differ diff --git a/public/images/emoji/twitter/part_alternation_mark.png b/public/images/emoji/twitter/part_alternation_mark.png index a73ddf77670..2e23f2bade1 100644 Binary files a/public/images/emoji/twitter/part_alternation_mark.png and b/public/images/emoji/twitter/part_alternation_mark.png differ diff --git a/public/images/emoji/twitter/partly_sunny.png b/public/images/emoji/twitter/partly_sunny.png index 0d42818d192..6e06f775e2b 100644 Binary files a/public/images/emoji/twitter/partly_sunny.png and b/public/images/emoji/twitter/partly_sunny.png differ diff --git a/public/images/emoji/twitter/passport_control.png b/public/images/emoji/twitter/passport_control.png index 328551726e4..55d3a9b47f9 100644 Binary files a/public/images/emoji/twitter/passport_control.png and b/public/images/emoji/twitter/passport_control.png differ diff --git a/public/images/emoji/twitter/pause_button.png b/public/images/emoji/twitter/pause_button.png new file mode 100644 index 00000000000..78d4ae8ac92 Binary files /dev/null and b/public/images/emoji/twitter/pause_button.png differ diff --git a/public/images/emoji/twitter/peace.png b/public/images/emoji/twitter/peace.png new file mode 100644 index 00000000000..74e529b1595 Binary files /dev/null and b/public/images/emoji/twitter/peace.png differ diff --git a/public/images/emoji/twitter/peach.png b/public/images/emoji/twitter/peach.png index 92fa321311a..cfee94c1d19 100644 Binary files a/public/images/emoji/twitter/peach.png and b/public/images/emoji/twitter/peach.png differ diff --git a/public/images/emoji/twitter/pear.png b/public/images/emoji/twitter/pear.png index 4a6ad8fc45c..6ebb4d70671 100644 Binary files a/public/images/emoji/twitter/pear.png and b/public/images/emoji/twitter/pear.png differ diff --git a/public/images/emoji/twitter/pen_ballpoint.png b/public/images/emoji/twitter/pen_ballpoint.png new file mode 100644 index 00000000000..6219ae26cc1 Binary files /dev/null and b/public/images/emoji/twitter/pen_ballpoint.png differ diff --git a/public/images/emoji/twitter/pen_fountain.png b/public/images/emoji/twitter/pen_fountain.png new file mode 100644 index 00000000000..f2579410b27 Binary files /dev/null and b/public/images/emoji/twitter/pen_fountain.png differ diff --git a/public/images/emoji/twitter/pencil.png b/public/images/emoji/twitter/pencil.png index 9bbc624eb01..6152d13957a 100644 Binary files a/public/images/emoji/twitter/pencil.png and b/public/images/emoji/twitter/pencil.png differ diff --git a/public/images/emoji/twitter/pencil2.png b/public/images/emoji/twitter/pencil2.png index a469366006c..a6658a52f38 100644 Binary files a/public/images/emoji/twitter/pencil2.png and b/public/images/emoji/twitter/pencil2.png differ diff --git a/public/images/emoji/twitter/penguin.png b/public/images/emoji/twitter/penguin.png index 931349517cf..b7b0ad9ada1 100644 Binary files a/public/images/emoji/twitter/penguin.png and b/public/images/emoji/twitter/penguin.png differ diff --git a/public/images/emoji/twitter/pensive.png b/public/images/emoji/twitter/pensive.png index b43a3de2953..941d6c8c790 100644 Binary files a/public/images/emoji/twitter/pensive.png and b/public/images/emoji/twitter/pensive.png differ diff --git a/public/images/emoji/twitter/performing_arts.png b/public/images/emoji/twitter/performing_arts.png index 08412f86062..f26cee85bd5 100644 Binary files a/public/images/emoji/twitter/performing_arts.png and b/public/images/emoji/twitter/performing_arts.png differ diff --git a/public/images/emoji/twitter/persevere.png b/public/images/emoji/twitter/persevere.png index 2f44a831779..5c99ddbb571 100644 Binary files a/public/images/emoji/twitter/persevere.png and b/public/images/emoji/twitter/persevere.png differ diff --git a/public/images/emoji/twitter/person_frowning.png b/public/images/emoji/twitter/person_frowning.png index 9cc0a968bb4..4f262c3ad40 100644 Binary files a/public/images/emoji/twitter/person_frowning.png and b/public/images/emoji/twitter/person_frowning.png differ diff --git a/public/images/emoji/twitter/person_with_blond_hair.png b/public/images/emoji/twitter/person_with_blond_hair.png index 15dbacbd70a..51bb86986ff 100644 Binary files a/public/images/emoji/twitter/person_with_blond_hair.png and b/public/images/emoji/twitter/person_with_blond_hair.png differ diff --git a/public/images/emoji/twitter/person_with_pouting_face.png b/public/images/emoji/twitter/person_with_pouting_face.png index 6f8b40e3a7f..ec114b7b840 100644 Binary files a/public/images/emoji/twitter/person_with_pouting_face.png and b/public/images/emoji/twitter/person_with_pouting_face.png differ diff --git a/public/images/emoji/twitter/phone.png b/public/images/emoji/twitter/phone.png index 3d636ba8c54..d8626e6e66d 100644 Binary files a/public/images/emoji/twitter/phone.png and b/public/images/emoji/twitter/phone.png differ diff --git a/public/images/emoji/twitter/pick.png b/public/images/emoji/twitter/pick.png new file mode 100644 index 00000000000..696accaff2c Binary files /dev/null and b/public/images/emoji/twitter/pick.png differ diff --git a/public/images/emoji/twitter/pig.png b/public/images/emoji/twitter/pig.png index c57ac4fdb9f..85bc8a3789b 100644 Binary files a/public/images/emoji/twitter/pig.png and b/public/images/emoji/twitter/pig.png differ diff --git a/public/images/emoji/twitter/pig2.png b/public/images/emoji/twitter/pig2.png index 2492c5628fc..51c1dda2d87 100644 Binary files a/public/images/emoji/twitter/pig2.png and b/public/images/emoji/twitter/pig2.png differ diff --git a/public/images/emoji/twitter/pig_nose.png b/public/images/emoji/twitter/pig_nose.png index a78d4e9ee74..9575ae1b55c 100644 Binary files a/public/images/emoji/twitter/pig_nose.png and b/public/images/emoji/twitter/pig_nose.png differ diff --git a/public/images/emoji/twitter/pill.png b/public/images/emoji/twitter/pill.png index a9def2fd03f..fd1873fdfab 100644 Binary files a/public/images/emoji/twitter/pill.png and b/public/images/emoji/twitter/pill.png differ diff --git a/public/images/emoji/twitter/pineapple.png b/public/images/emoji/twitter/pineapple.png index 4e6cf2615ef..b1d8f2ff74d 100644 Binary files a/public/images/emoji/twitter/pineapple.png and b/public/images/emoji/twitter/pineapple.png differ diff --git a/public/images/emoji/twitter/ping_pong.png b/public/images/emoji/twitter/ping_pong.png new file mode 100644 index 00000000000..44de4d9510c Binary files /dev/null and b/public/images/emoji/twitter/ping_pong.png differ diff --git a/public/images/emoji/twitter/pisces.png b/public/images/emoji/twitter/pisces.png index 274daa24afa..a0ff83a0e21 100644 Binary files a/public/images/emoji/twitter/pisces.png and b/public/images/emoji/twitter/pisces.png differ diff --git a/public/images/emoji/twitter/pizza.png b/public/images/emoji/twitter/pizza.png index eaa5f879380..00652465af7 100644 Binary files a/public/images/emoji/twitter/pizza.png and b/public/images/emoji/twitter/pizza.png differ diff --git a/public/images/emoji/twitter/place_of_worship.png b/public/images/emoji/twitter/place_of_worship.png new file mode 100644 index 00000000000..b8e09969559 Binary files /dev/null and b/public/images/emoji/twitter/place_of_worship.png differ diff --git a/public/images/emoji/twitter/play_pause.png b/public/images/emoji/twitter/play_pause.png new file mode 100644 index 00000000000..0839a426ee2 Binary files /dev/null and b/public/images/emoji/twitter/play_pause.png differ diff --git a/public/images/emoji/twitter/point_down.png b/public/images/emoji/twitter/point_down.png index 275970ffce6..3d6fa1dc34f 100644 Binary files a/public/images/emoji/twitter/point_down.png and b/public/images/emoji/twitter/point_down.png differ diff --git a/public/images/emoji/twitter/point_left.png b/public/images/emoji/twitter/point_left.png index fe1c9e2a9b0..de4a4d6ba59 100644 Binary files a/public/images/emoji/twitter/point_left.png and b/public/images/emoji/twitter/point_left.png differ diff --git a/public/images/emoji/twitter/point_right.png b/public/images/emoji/twitter/point_right.png index 54b368ac633..41e8d012a6a 100644 Binary files a/public/images/emoji/twitter/point_right.png and b/public/images/emoji/twitter/point_right.png differ diff --git a/public/images/emoji/twitter/point_up.png b/public/images/emoji/twitter/point_up.png index 8f13a38f169..64f4ba209f6 100644 Binary files a/public/images/emoji/twitter/point_up.png and b/public/images/emoji/twitter/point_up.png differ diff --git a/public/images/emoji/twitter/point_up_2.png b/public/images/emoji/twitter/point_up_2.png index 374c6fb7992..c6cb2afdf5f 100644 Binary files a/public/images/emoji/twitter/point_up_2.png and b/public/images/emoji/twitter/point_up_2.png differ diff --git a/public/images/emoji/twitter/police_car.png b/public/images/emoji/twitter/police_car.png index 7829c801290..7bb763e8273 100644 Binary files a/public/images/emoji/twitter/police_car.png and b/public/images/emoji/twitter/police_car.png differ diff --git a/public/images/emoji/twitter/poodle.png b/public/images/emoji/twitter/poodle.png index 6e77dc3f09c..485d34b0a66 100644 Binary files a/public/images/emoji/twitter/poodle.png and b/public/images/emoji/twitter/poodle.png differ diff --git a/public/images/emoji/twitter/poop.png b/public/images/emoji/twitter/poop.png index 604d2a2d0a3..7284027c6b4 100644 Binary files a/public/images/emoji/twitter/poop.png and b/public/images/emoji/twitter/poop.png differ diff --git a/public/images/emoji/twitter/popcorn.png b/public/images/emoji/twitter/popcorn.png new file mode 100644 index 00000000000..6f4e0f0b6b5 Binary files /dev/null and b/public/images/emoji/twitter/popcorn.png differ diff --git a/public/images/emoji/twitter/post_office.png b/public/images/emoji/twitter/post_office.png index aeecd2f65f6..06385a2c8d2 100644 Binary files a/public/images/emoji/twitter/post_office.png and b/public/images/emoji/twitter/post_office.png differ diff --git a/public/images/emoji/twitter/postal_horn.png b/public/images/emoji/twitter/postal_horn.png index 01008d82838..c0cfacae687 100644 Binary files a/public/images/emoji/twitter/postal_horn.png and b/public/images/emoji/twitter/postal_horn.png differ diff --git a/public/images/emoji/twitter/postbox.png b/public/images/emoji/twitter/postbox.png index fbff07974f2..d2c3f3d4d56 100644 Binary files a/public/images/emoji/twitter/postbox.png and b/public/images/emoji/twitter/postbox.png differ diff --git a/public/images/emoji/twitter/potable_water.png b/public/images/emoji/twitter/potable_water.png index 5d8b61f82d8..5f04b98a993 100644 Binary files a/public/images/emoji/twitter/potable_water.png and b/public/images/emoji/twitter/potable_water.png differ diff --git a/public/images/emoji/twitter/pouch.png b/public/images/emoji/twitter/pouch.png index 926368a8045..43522c9efcc 100644 Binary files a/public/images/emoji/twitter/pouch.png and b/public/images/emoji/twitter/pouch.png differ diff --git a/public/images/emoji/twitter/poultry_leg.png b/public/images/emoji/twitter/poultry_leg.png index e4140ec3935..abcb924ecf5 100644 Binary files a/public/images/emoji/twitter/poultry_leg.png and b/public/images/emoji/twitter/poultry_leg.png differ diff --git a/public/images/emoji/twitter/pound.png b/public/images/emoji/twitter/pound.png index a8156dc4f24..a4d63e8449f 100644 Binary files a/public/images/emoji/twitter/pound.png and b/public/images/emoji/twitter/pound.png differ diff --git a/public/images/emoji/twitter/pouting_cat.png b/public/images/emoji/twitter/pouting_cat.png index 77a4195fdcd..fbc093ffb0a 100644 Binary files a/public/images/emoji/twitter/pouting_cat.png and b/public/images/emoji/twitter/pouting_cat.png differ diff --git a/public/images/emoji/twitter/pray.png b/public/images/emoji/twitter/pray.png index e866b14496b..143dc395e84 100644 Binary files a/public/images/emoji/twitter/pray.png and b/public/images/emoji/twitter/pray.png differ diff --git a/public/images/emoji/twitter/prayer_beads.png b/public/images/emoji/twitter/prayer_beads.png new file mode 100644 index 00000000000..e7709c6cb23 Binary files /dev/null and b/public/images/emoji/twitter/prayer_beads.png differ diff --git a/public/images/emoji/twitter/princess.png b/public/images/emoji/twitter/princess.png index 3830c501e5d..1f410e26b40 100644 Binary files a/public/images/emoji/twitter/princess.png and b/public/images/emoji/twitter/princess.png differ diff --git a/public/images/emoji/twitter/printer.png b/public/images/emoji/twitter/printer.png new file mode 100644 index 00000000000..58961b6b096 Binary files /dev/null and b/public/images/emoji/twitter/printer.png differ diff --git a/public/images/emoji/twitter/projector.png b/public/images/emoji/twitter/projector.png new file mode 100644 index 00000000000..6135a3366c3 Binary files /dev/null and b/public/images/emoji/twitter/projector.png differ diff --git a/public/images/emoji/twitter/purple_heart.png b/public/images/emoji/twitter/purple_heart.png index f63e7273945..c84cce076f6 100644 Binary files a/public/images/emoji/twitter/purple_heart.png and b/public/images/emoji/twitter/purple_heart.png differ diff --git a/public/images/emoji/twitter/purse.png b/public/images/emoji/twitter/purse.png index 76717fbc71a..91b11916e1f 100644 Binary files a/public/images/emoji/twitter/purse.png and b/public/images/emoji/twitter/purse.png differ diff --git a/public/images/emoji/twitter/pushpin.png b/public/images/emoji/twitter/pushpin.png index 5e6faac1df1..ab27d56967c 100644 Binary files a/public/images/emoji/twitter/pushpin.png and b/public/images/emoji/twitter/pushpin.png differ diff --git a/public/images/emoji/twitter/put_litter_in_its_place.png b/public/images/emoji/twitter/put_litter_in_its_place.png index fdf4bb6db91..fc7b6b66975 100644 Binary files a/public/images/emoji/twitter/put_litter_in_its_place.png and b/public/images/emoji/twitter/put_litter_in_its_place.png differ diff --git a/public/images/emoji/twitter/question.png b/public/images/emoji/twitter/question.png index fc0680b3cd8..1e723aea512 100644 Binary files a/public/images/emoji/twitter/question.png and b/public/images/emoji/twitter/question.png differ diff --git a/public/images/emoji/twitter/rabbit.png b/public/images/emoji/twitter/rabbit.png index a75b2758270..8187e7c090a 100644 Binary files a/public/images/emoji/twitter/rabbit.png and b/public/images/emoji/twitter/rabbit.png differ diff --git a/public/images/emoji/twitter/rabbit2.png b/public/images/emoji/twitter/rabbit2.png index 07d14a83f4f..aa11d680151 100644 Binary files a/public/images/emoji/twitter/rabbit2.png and b/public/images/emoji/twitter/rabbit2.png differ diff --git a/public/images/emoji/twitter/race_car.png b/public/images/emoji/twitter/race_car.png new file mode 100644 index 00000000000..894f1b62c24 Binary files /dev/null and b/public/images/emoji/twitter/race_car.png differ diff --git a/public/images/emoji/twitter/racehorse.png b/public/images/emoji/twitter/racehorse.png index 9cff0b935dd..edd7816d859 100644 Binary files a/public/images/emoji/twitter/racehorse.png and b/public/images/emoji/twitter/racehorse.png differ diff --git a/public/images/emoji/twitter/radio.png b/public/images/emoji/twitter/radio.png index 1b54f54e030..36096751755 100644 Binary files a/public/images/emoji/twitter/radio.png and b/public/images/emoji/twitter/radio.png differ diff --git a/public/images/emoji/twitter/radio_button.png b/public/images/emoji/twitter/radio_button.png index 54d091f5c09..39a73ebf0ba 100644 Binary files a/public/images/emoji/twitter/radio_button.png and b/public/images/emoji/twitter/radio_button.png differ diff --git a/public/images/emoji/twitter/radioactive.png b/public/images/emoji/twitter/radioactive.png new file mode 100644 index 00000000000..2c4d0ab5795 Binary files /dev/null and b/public/images/emoji/twitter/radioactive.png differ diff --git a/public/images/emoji/twitter/rage.png b/public/images/emoji/twitter/rage.png index c1ab5d1fd96..7a646ebbfff 100644 Binary files a/public/images/emoji/twitter/rage.png and b/public/images/emoji/twitter/rage.png differ diff --git a/public/images/emoji/twitter/railway_car.png b/public/images/emoji/twitter/railway_car.png index e4dbd4f882b..6d8d459a3d4 100644 Binary files a/public/images/emoji/twitter/railway_car.png and b/public/images/emoji/twitter/railway_car.png differ diff --git a/public/images/emoji/twitter/railway_track.png b/public/images/emoji/twitter/railway_track.png new file mode 100644 index 00000000000..8a09aa1ede9 Binary files /dev/null and b/public/images/emoji/twitter/railway_track.png differ diff --git a/public/images/emoji/twitter/rainbow.png b/public/images/emoji/twitter/rainbow.png index d0aaec8aa29..b9bc2ba5948 100644 Binary files a/public/images/emoji/twitter/rainbow.png and b/public/images/emoji/twitter/rainbow.png differ diff --git a/public/images/emoji/twitter/raised_hands.png b/public/images/emoji/twitter/raised_hands.png index bb0bcd8ad96..c936e1cb0fe 100644 Binary files a/public/images/emoji/twitter/raised_hands.png and b/public/images/emoji/twitter/raised_hands.png differ diff --git a/public/images/emoji/twitter/raising_hand.png b/public/images/emoji/twitter/raising_hand.png index 3d23df88109..279c641590b 100644 Binary files a/public/images/emoji/twitter/raising_hand.png and b/public/images/emoji/twitter/raising_hand.png differ diff --git a/public/images/emoji/twitter/ram.png b/public/images/emoji/twitter/ram.png index 9259b3c35a4..69606572411 100644 Binary files a/public/images/emoji/twitter/ram.png and b/public/images/emoji/twitter/ram.png differ diff --git a/public/images/emoji/twitter/ramen.png b/public/images/emoji/twitter/ramen.png index 577b4a5c04e..dac5de6f2f6 100644 Binary files a/public/images/emoji/twitter/ramen.png and b/public/images/emoji/twitter/ramen.png differ diff --git a/public/images/emoji/twitter/rat.png b/public/images/emoji/twitter/rat.png index 5c577cf5cb6..6e65af5d1c8 100644 Binary files a/public/images/emoji/twitter/rat.png and b/public/images/emoji/twitter/rat.png differ diff --git a/public/images/emoji/twitter/record_button.png b/public/images/emoji/twitter/record_button.png new file mode 100644 index 00000000000..3725e1c215e Binary files /dev/null and b/public/images/emoji/twitter/record_button.png differ diff --git a/public/images/emoji/twitter/recycle.png b/public/images/emoji/twitter/recycle.png index 568b5459a7a..670dd2b5d6f 100644 Binary files a/public/images/emoji/twitter/recycle.png and b/public/images/emoji/twitter/recycle.png differ diff --git a/public/images/emoji/twitter/red_car.png b/public/images/emoji/twitter/red_car.png index 93610d2c438..3dd084f99ac 100644 Binary files a/public/images/emoji/twitter/red_car.png and b/public/images/emoji/twitter/red_car.png differ diff --git a/public/images/emoji/twitter/red_circle.png b/public/images/emoji/twitter/red_circle.png index 90103e1e70c..c44bc094b4c 100644 Binary files a/public/images/emoji/twitter/red_circle.png and b/public/images/emoji/twitter/red_circle.png differ diff --git a/public/images/emoji/twitter/registered.png b/public/images/emoji/twitter/registered.png index 8761856480c..e8ec23f661f 100644 Binary files a/public/images/emoji/twitter/registered.png and b/public/images/emoji/twitter/registered.png differ diff --git a/public/images/emoji/twitter/relaxed.png b/public/images/emoji/twitter/relaxed.png index 5206089b60b..0c030587ff2 100644 Binary files a/public/images/emoji/twitter/relaxed.png and b/public/images/emoji/twitter/relaxed.png differ diff --git a/public/images/emoji/twitter/relieved.png b/public/images/emoji/twitter/relieved.png index d3743ebc2ca..b9ca87e45cb 100644 Binary files a/public/images/emoji/twitter/relieved.png and b/public/images/emoji/twitter/relieved.png differ diff --git a/public/images/emoji/twitter/reminder_ribbon.png b/public/images/emoji/twitter/reminder_ribbon.png new file mode 100644 index 00000000000..09d8d0e3081 Binary files /dev/null and b/public/images/emoji/twitter/reminder_ribbon.png differ diff --git a/public/images/emoji/twitter/repeat.png b/public/images/emoji/twitter/repeat.png index 89fcc1f2326..3b995af9ddd 100644 Binary files a/public/images/emoji/twitter/repeat.png and b/public/images/emoji/twitter/repeat.png differ diff --git a/public/images/emoji/twitter/repeat_one.png b/public/images/emoji/twitter/repeat_one.png index d8cba319cab..10f7bbb75eb 100644 Binary files a/public/images/emoji/twitter/repeat_one.png and b/public/images/emoji/twitter/repeat_one.png differ diff --git a/public/images/emoji/twitter/restroom.png b/public/images/emoji/twitter/restroom.png index df75a32071e..77d411f3e7d 100644 Binary files a/public/images/emoji/twitter/restroom.png and b/public/images/emoji/twitter/restroom.png differ diff --git a/public/images/emoji/twitter/revolving_hearts.png b/public/images/emoji/twitter/revolving_hearts.png index fcfb0c35047..334f2ffbf2f 100644 Binary files a/public/images/emoji/twitter/revolving_hearts.png and b/public/images/emoji/twitter/revolving_hearts.png differ diff --git a/public/images/emoji/twitter/rewind.png b/public/images/emoji/twitter/rewind.png index 09aba5b223c..7a137362755 100644 Binary files a/public/images/emoji/twitter/rewind.png and b/public/images/emoji/twitter/rewind.png differ diff --git a/public/images/emoji/twitter/ribbon.png b/public/images/emoji/twitter/ribbon.png index 530137dbc2a..6836ca115cd 100644 Binary files a/public/images/emoji/twitter/ribbon.png and b/public/images/emoji/twitter/ribbon.png differ diff --git a/public/images/emoji/twitter/rice.png b/public/images/emoji/twitter/rice.png index d4824bfa781..96d33e2104d 100644 Binary files a/public/images/emoji/twitter/rice.png and b/public/images/emoji/twitter/rice.png differ diff --git a/public/images/emoji/twitter/rice_ball.png b/public/images/emoji/twitter/rice_ball.png index b5ad453ebdb..2a1d21ae77b 100644 Binary files a/public/images/emoji/twitter/rice_ball.png and b/public/images/emoji/twitter/rice_ball.png differ diff --git a/public/images/emoji/twitter/rice_cracker.png b/public/images/emoji/twitter/rice_cracker.png index 0be2e5c4812..191ba5aa2e2 100644 Binary files a/public/images/emoji/twitter/rice_cracker.png and b/public/images/emoji/twitter/rice_cracker.png differ diff --git a/public/images/emoji/twitter/rice_scene.png b/public/images/emoji/twitter/rice_scene.png index 56f23076d4c..eb37d84a153 100644 Binary files a/public/images/emoji/twitter/rice_scene.png and b/public/images/emoji/twitter/rice_scene.png differ diff --git a/public/images/emoji/twitter/ring.png b/public/images/emoji/twitter/ring.png index b46e092e540..2bd05ada096 100644 Binary files a/public/images/emoji/twitter/ring.png and b/public/images/emoji/twitter/ring.png differ diff --git a/public/images/emoji/twitter/robot.png b/public/images/emoji/twitter/robot.png new file mode 100644 index 00000000000..03eff68a694 Binary files /dev/null and b/public/images/emoji/twitter/robot.png differ diff --git a/public/images/emoji/twitter/rocket.png b/public/images/emoji/twitter/rocket.png index 041fe598669..2f6633a7c01 100644 Binary files a/public/images/emoji/twitter/rocket.png and b/public/images/emoji/twitter/rocket.png differ diff --git a/public/images/emoji/twitter/roller_coaster.png b/public/images/emoji/twitter/roller_coaster.png index 3f95bab1cf6..82ebb225960 100644 Binary files a/public/images/emoji/twitter/roller_coaster.png and b/public/images/emoji/twitter/roller_coaster.png differ diff --git a/public/images/emoji/twitter/rolling_eyes.png b/public/images/emoji/twitter/rolling_eyes.png new file mode 100644 index 00000000000..e2e047be106 Binary files /dev/null and b/public/images/emoji/twitter/rolling_eyes.png differ diff --git a/public/images/emoji/twitter/rooster.png b/public/images/emoji/twitter/rooster.png index ea5c8564a88..bdc0711c6b1 100644 Binary files a/public/images/emoji/twitter/rooster.png and b/public/images/emoji/twitter/rooster.png differ diff --git a/public/images/emoji/twitter/rose.png b/public/images/emoji/twitter/rose.png index aba7e665168..e780aa72f59 100644 Binary files a/public/images/emoji/twitter/rose.png and b/public/images/emoji/twitter/rose.png differ diff --git a/public/images/emoji/twitter/rosette.png b/public/images/emoji/twitter/rosette.png new file mode 100644 index 00000000000..3ef48e7eb1b Binary files /dev/null and b/public/images/emoji/twitter/rosette.png differ diff --git a/public/images/emoji/twitter/rotating_light.png b/public/images/emoji/twitter/rotating_light.png index 950497413a7..464e8de8aa7 100644 Binary files a/public/images/emoji/twitter/rotating_light.png and b/public/images/emoji/twitter/rotating_light.png differ diff --git a/public/images/emoji/twitter/round_pushpin.png b/public/images/emoji/twitter/round_pushpin.png index 7846f1669b1..e8d12293ffe 100644 Binary files a/public/images/emoji/twitter/round_pushpin.png and b/public/images/emoji/twitter/round_pushpin.png differ diff --git a/public/images/emoji/twitter/rowboat.png b/public/images/emoji/twitter/rowboat.png index 05004b4eefe..1a56f0fdeab 100644 Binary files a/public/images/emoji/twitter/rowboat.png and b/public/images/emoji/twitter/rowboat.png differ diff --git a/public/images/emoji/twitter/ru.png b/public/images/emoji/twitter/ru.png index 021d32f9383..33da99a65b0 100644 Binary files a/public/images/emoji/twitter/ru.png and b/public/images/emoji/twitter/ru.png differ diff --git a/public/images/emoji/twitter/rugby_football.png b/public/images/emoji/twitter/rugby_football.png index 74aaa253750..a2233524caa 100644 Binary files a/public/images/emoji/twitter/rugby_football.png and b/public/images/emoji/twitter/rugby_football.png differ diff --git a/public/images/emoji/twitter/runner.png b/public/images/emoji/twitter/runner.png index 73a678354b8..b9a3bb4a212 100644 Binary files a/public/images/emoji/twitter/runner.png and b/public/images/emoji/twitter/runner.png differ diff --git a/public/images/emoji/twitter/running.png b/public/images/emoji/twitter/running.png index 73a678354b8..cff2b793d8b 100644 Binary files a/public/images/emoji/twitter/running.png and b/public/images/emoji/twitter/running.png differ diff --git a/public/images/emoji/twitter/running_shirt_with_sash.png b/public/images/emoji/twitter/running_shirt_with_sash.png index 1e41d23f899..f44753c9ee9 100644 Binary files a/public/images/emoji/twitter/running_shirt_with_sash.png and b/public/images/emoji/twitter/running_shirt_with_sash.png differ diff --git a/public/images/emoji/twitter/sa.png b/public/images/emoji/twitter/sa.png index 6f981401b1d..c334448c0d4 100644 Binary files a/public/images/emoji/twitter/sa.png and b/public/images/emoji/twitter/sa.png differ diff --git a/public/images/emoji/twitter/sagittarius.png b/public/images/emoji/twitter/sagittarius.png index 68d964ca996..b6f475c8589 100644 Binary files a/public/images/emoji/twitter/sagittarius.png and b/public/images/emoji/twitter/sagittarius.png differ diff --git a/public/images/emoji/twitter/sake.png b/public/images/emoji/twitter/sake.png index c705943afe6..245f59b67be 100644 Binary files a/public/images/emoji/twitter/sake.png and b/public/images/emoji/twitter/sake.png differ diff --git a/public/images/emoji/twitter/sandal.png b/public/images/emoji/twitter/sandal.png index 73bbff56af7..41669e2b250 100644 Binary files a/public/images/emoji/twitter/sandal.png and b/public/images/emoji/twitter/sandal.png differ diff --git a/public/images/emoji/twitter/santa.png b/public/images/emoji/twitter/santa.png index 8d385646292..bb9d04f11fc 100644 Binary files a/public/images/emoji/twitter/santa.png and b/public/images/emoji/twitter/santa.png differ diff --git a/public/images/emoji/twitter/satellite.png b/public/images/emoji/twitter/satellite.png index a83aa3e2596..7c55cb91ab9 100644 Binary files a/public/images/emoji/twitter/satellite.png and b/public/images/emoji/twitter/satellite.png differ diff --git a/public/images/emoji/twitter/satellite_orbital.png b/public/images/emoji/twitter/satellite_orbital.png new file mode 100644 index 00000000000..81715516af6 Binary files /dev/null and b/public/images/emoji/twitter/satellite_orbital.png differ diff --git a/public/images/emoji/twitter/satisfied.png b/public/images/emoji/twitter/satisfied.png index fa350e829e6..fe3876f9f82 100644 Binary files a/public/images/emoji/twitter/satisfied.png and b/public/images/emoji/twitter/satisfied.png differ diff --git a/public/images/emoji/twitter/saxophone.png b/public/images/emoji/twitter/saxophone.png index 4cc798d0f10..e97a2dabe39 100644 Binary files a/public/images/emoji/twitter/saxophone.png and b/public/images/emoji/twitter/saxophone.png differ diff --git a/public/images/emoji/twitter/scales.png b/public/images/emoji/twitter/scales.png new file mode 100644 index 00000000000..1647464628d Binary files /dev/null and b/public/images/emoji/twitter/scales.png differ diff --git a/public/images/emoji/twitter/school.png b/public/images/emoji/twitter/school.png index 78b6ad844b8..a74d1e4c991 100644 Binary files a/public/images/emoji/twitter/school.png and b/public/images/emoji/twitter/school.png differ diff --git a/public/images/emoji/twitter/school_satchel.png b/public/images/emoji/twitter/school_satchel.png index 5f8295fb23e..a173c78b0bf 100644 Binary files a/public/images/emoji/twitter/school_satchel.png and b/public/images/emoji/twitter/school_satchel.png differ diff --git a/public/images/emoji/twitter/scissors.png b/public/images/emoji/twitter/scissors.png index 12d809df3f4..a5636452baa 100644 Binary files a/public/images/emoji/twitter/scissors.png and b/public/images/emoji/twitter/scissors.png differ diff --git a/public/images/emoji/twitter/scorpion.png b/public/images/emoji/twitter/scorpion.png new file mode 100644 index 00000000000..cf0f2e7e1f3 Binary files /dev/null and b/public/images/emoji/twitter/scorpion.png differ diff --git a/public/images/emoji/twitter/scorpius.png b/public/images/emoji/twitter/scorpius.png index 17b213184f1..faf1b3f6263 100644 Binary files a/public/images/emoji/twitter/scorpius.png and b/public/images/emoji/twitter/scorpius.png differ diff --git a/public/images/emoji/twitter/scream.png b/public/images/emoji/twitter/scream.png index 0167a57b726..10a49178481 100644 Binary files a/public/images/emoji/twitter/scream.png and b/public/images/emoji/twitter/scream.png differ diff --git a/public/images/emoji/twitter/scream_cat.png b/public/images/emoji/twitter/scream_cat.png index 6f009c49dfc..d084db0867e 100644 Binary files a/public/images/emoji/twitter/scream_cat.png and b/public/images/emoji/twitter/scream_cat.png differ diff --git a/public/images/emoji/twitter/scroll.png b/public/images/emoji/twitter/scroll.png index c973d3cb989..8b41be4ab39 100644 Binary files a/public/images/emoji/twitter/scroll.png and b/public/images/emoji/twitter/scroll.png differ diff --git a/public/images/emoji/twitter/seat.png b/public/images/emoji/twitter/seat.png index 4f42f6212e8..4e8b8455325 100644 Binary files a/public/images/emoji/twitter/seat.png and b/public/images/emoji/twitter/seat.png differ diff --git a/public/images/emoji/twitter/secret.png b/public/images/emoji/twitter/secret.png index d64ecfabd2d..c7dcf736a5d 100644 Binary files a/public/images/emoji/twitter/secret.png and b/public/images/emoji/twitter/secret.png differ diff --git a/public/images/emoji/twitter/see_no_evil.png b/public/images/emoji/twitter/see_no_evil.png index e3ee674da86..dc3908ceb1b 100644 Binary files a/public/images/emoji/twitter/see_no_evil.png and b/public/images/emoji/twitter/see_no_evil.png differ diff --git a/public/images/emoji/twitter/seedling.png b/public/images/emoji/twitter/seedling.png index e2afd3fc736..2840e70702b 100644 Binary files a/public/images/emoji/twitter/seedling.png and b/public/images/emoji/twitter/seedling.png differ diff --git a/public/images/emoji/twitter/shamrock.png b/public/images/emoji/twitter/shamrock.png new file mode 100644 index 00000000000..275a5059817 Binary files /dev/null and b/public/images/emoji/twitter/shamrock.png differ diff --git a/public/images/emoji/twitter/shaved_ice.png b/public/images/emoji/twitter/shaved_ice.png index 40e7e673aed..5f0924771ee 100644 Binary files a/public/images/emoji/twitter/shaved_ice.png and b/public/images/emoji/twitter/shaved_ice.png differ diff --git a/public/images/emoji/twitter/sheep.png b/public/images/emoji/twitter/sheep.png index 9a02e6b6f49..4ceaab6d134 100644 Binary files a/public/images/emoji/twitter/sheep.png and b/public/images/emoji/twitter/sheep.png differ diff --git a/public/images/emoji/twitter/shell.png b/public/images/emoji/twitter/shell.png index e9efae186e3..da805ef84c8 100644 Binary files a/public/images/emoji/twitter/shell.png and b/public/images/emoji/twitter/shell.png differ diff --git a/public/images/emoji/twitter/shield.png b/public/images/emoji/twitter/shield.png new file mode 100644 index 00000000000..51ce00cd207 Binary files /dev/null and b/public/images/emoji/twitter/shield.png differ diff --git a/public/images/emoji/twitter/shinto_shrine.png b/public/images/emoji/twitter/shinto_shrine.png new file mode 100644 index 00000000000..d5c11c548d5 Binary files /dev/null and b/public/images/emoji/twitter/shinto_shrine.png differ diff --git a/public/images/emoji/twitter/ship.png b/public/images/emoji/twitter/ship.png index bad0411e1fc..c3d7cc094d3 100644 Binary files a/public/images/emoji/twitter/ship.png and b/public/images/emoji/twitter/ship.png differ diff --git a/public/images/emoji/twitter/shirt.png b/public/images/emoji/twitter/shirt.png index bf78d21c060..7efd56ad0d3 100644 Binary files a/public/images/emoji/twitter/shirt.png and b/public/images/emoji/twitter/shirt.png differ diff --git a/public/images/emoji/twitter/shit.png b/public/images/emoji/twitter/shit.png index 604d2a2d0a3..7284027c6b4 100644 Binary files a/public/images/emoji/twitter/shit.png and b/public/images/emoji/twitter/shit.png differ diff --git a/public/images/emoji/twitter/shopping_bags.png b/public/images/emoji/twitter/shopping_bags.png new file mode 100644 index 00000000000..685a70cdcdf Binary files /dev/null and b/public/images/emoji/twitter/shopping_bags.png differ diff --git a/public/images/emoji/twitter/shower.png b/public/images/emoji/twitter/shower.png index 9a448a49057..2fe95989bbb 100644 Binary files a/public/images/emoji/twitter/shower.png and b/public/images/emoji/twitter/shower.png differ diff --git a/public/images/emoji/twitter/signal_strength.png b/public/images/emoji/twitter/signal_strength.png index 7ba93b16571..f99fd0376f0 100644 Binary files a/public/images/emoji/twitter/signal_strength.png and b/public/images/emoji/twitter/signal_strength.png differ diff --git a/public/images/emoji/twitter/six_pointed_star.png b/public/images/emoji/twitter/six_pointed_star.png index 148a7090cd1..96891a116cd 100644 Binary files a/public/images/emoji/twitter/six_pointed_star.png and b/public/images/emoji/twitter/six_pointed_star.png differ diff --git a/public/images/emoji/twitter/ski.png b/public/images/emoji/twitter/ski.png index 84d05c7dee2..24d3ed617a1 100644 Binary files a/public/images/emoji/twitter/ski.png and b/public/images/emoji/twitter/ski.png differ diff --git a/public/images/emoji/twitter/skier.png b/public/images/emoji/twitter/skier.png new file mode 100644 index 00000000000..0a99f58df8c Binary files /dev/null and b/public/images/emoji/twitter/skier.png differ diff --git a/public/images/emoji/twitter/skull.png b/public/images/emoji/twitter/skull.png index 9573b3f73ae..c14227ead34 100644 Binary files a/public/images/emoji/twitter/skull.png and b/public/images/emoji/twitter/skull.png differ diff --git a/public/images/emoji/twitter/skull_crossbones.png b/public/images/emoji/twitter/skull_crossbones.png new file mode 100644 index 00000000000..8aebd69f28d Binary files /dev/null and b/public/images/emoji/twitter/skull_crossbones.png differ diff --git a/public/images/emoji/twitter/sleeping.png b/public/images/emoji/twitter/sleeping.png index f8aca5e443b..0f75f7f65a9 100644 Binary files a/public/images/emoji/twitter/sleeping.png and b/public/images/emoji/twitter/sleeping.png differ diff --git a/public/images/emoji/twitter/sleeping_accommodation.png b/public/images/emoji/twitter/sleeping_accommodation.png new file mode 100644 index 00000000000..aab85aeaa5c Binary files /dev/null and b/public/images/emoji/twitter/sleeping_accommodation.png differ diff --git a/public/images/emoji/twitter/sleepy.png b/public/images/emoji/twitter/sleepy.png index adbe0bc6a7d..2b454fadd87 100644 Binary files a/public/images/emoji/twitter/sleepy.png and b/public/images/emoji/twitter/sleepy.png differ diff --git a/public/images/emoji/twitter/slight_frown.png b/public/images/emoji/twitter/slight_frown.png new file mode 100644 index 00000000000..3f3c9251aab Binary files /dev/null and b/public/images/emoji/twitter/slight_frown.png differ diff --git a/public/images/emoji/twitter/slight_smile.png b/public/images/emoji/twitter/slight_smile.png new file mode 100644 index 00000000000..4360c49ec5b Binary files /dev/null and b/public/images/emoji/twitter/slight_smile.png differ diff --git a/public/images/emoji/twitter/slightly_smiling.png b/public/images/emoji/twitter/slightly_smiling.png new file mode 100644 index 00000000000..6242f5865a2 Binary files /dev/null and b/public/images/emoji/twitter/slightly_smiling.png differ diff --git a/public/images/emoji/twitter/slot_machine.png b/public/images/emoji/twitter/slot_machine.png index cfdc70a0fd8..c090c729874 100644 Binary files a/public/images/emoji/twitter/slot_machine.png and b/public/images/emoji/twitter/slot_machine.png differ diff --git a/public/images/emoji/twitter/small_blue_diamond.png b/public/images/emoji/twitter/small_blue_diamond.png index f7bddb0dff4..811edc4d470 100644 Binary files a/public/images/emoji/twitter/small_blue_diamond.png and b/public/images/emoji/twitter/small_blue_diamond.png differ diff --git a/public/images/emoji/twitter/small_orange_diamond.png b/public/images/emoji/twitter/small_orange_diamond.png index c0770290fde..6a06f956c44 100644 Binary files a/public/images/emoji/twitter/small_orange_diamond.png and b/public/images/emoji/twitter/small_orange_diamond.png differ diff --git a/public/images/emoji/twitter/small_red_triangle.png b/public/images/emoji/twitter/small_red_triangle.png index cbfc5377da6..be4f7bfd631 100644 Binary files a/public/images/emoji/twitter/small_red_triangle.png and b/public/images/emoji/twitter/small_red_triangle.png differ diff --git a/public/images/emoji/twitter/small_red_triangle_down.png b/public/images/emoji/twitter/small_red_triangle_down.png index 3aa3db5f657..62dc1bc55f6 100644 Binary files a/public/images/emoji/twitter/small_red_triangle_down.png and b/public/images/emoji/twitter/small_red_triangle_down.png differ diff --git a/public/images/emoji/twitter/smile.png b/public/images/emoji/twitter/smile.png index 642c90ccbc3..b22bc0c4f15 100644 Binary files a/public/images/emoji/twitter/smile.png and b/public/images/emoji/twitter/smile.png differ diff --git a/public/images/emoji/twitter/smile_cat.png b/public/images/emoji/twitter/smile_cat.png index 0461f8cc01d..fcf381e395e 100644 Binary files a/public/images/emoji/twitter/smile_cat.png and b/public/images/emoji/twitter/smile_cat.png differ diff --git a/public/images/emoji/twitter/smiley.png b/public/images/emoji/twitter/smiley.png index add54338079..276d7e49ad8 100644 Binary files a/public/images/emoji/twitter/smiley.png and b/public/images/emoji/twitter/smiley.png differ diff --git a/public/images/emoji/twitter/smiley_cat.png b/public/images/emoji/twitter/smiley_cat.png index d8d42a8ca2f..0b12667d884 100644 Binary files a/public/images/emoji/twitter/smiley_cat.png and b/public/images/emoji/twitter/smiley_cat.png differ diff --git a/public/images/emoji/twitter/smiling_imp.png b/public/images/emoji/twitter/smiling_imp.png index 66a8653d010..949df8aa784 100644 Binary files a/public/images/emoji/twitter/smiling_imp.png and b/public/images/emoji/twitter/smiling_imp.png differ diff --git a/public/images/emoji/twitter/smirk.png b/public/images/emoji/twitter/smirk.png index 70240ea5bae..5a131b961da 100644 Binary files a/public/images/emoji/twitter/smirk.png and b/public/images/emoji/twitter/smirk.png differ diff --git a/public/images/emoji/twitter/smirk_cat.png b/public/images/emoji/twitter/smirk_cat.png index 24f9337a524..e5ef07c63ad 100644 Binary files a/public/images/emoji/twitter/smirk_cat.png and b/public/images/emoji/twitter/smirk_cat.png differ diff --git a/public/images/emoji/twitter/smoking.png b/public/images/emoji/twitter/smoking.png index 2dd81c268f2..4c874e481dd 100644 Binary files a/public/images/emoji/twitter/smoking.png and b/public/images/emoji/twitter/smoking.png differ diff --git a/public/images/emoji/twitter/snail.png b/public/images/emoji/twitter/snail.png index 95994f978a0..55821215c5e 100644 Binary files a/public/images/emoji/twitter/snail.png and b/public/images/emoji/twitter/snail.png differ diff --git a/public/images/emoji/twitter/snake.png b/public/images/emoji/twitter/snake.png index 511d1ed9ed0..c6425e3fdac 100644 Binary files a/public/images/emoji/twitter/snake.png and b/public/images/emoji/twitter/snake.png differ diff --git a/public/images/emoji/twitter/snowboarder.png b/public/images/emoji/twitter/snowboarder.png index 25d831f3ed4..5dfbfbd2e93 100644 Binary files a/public/images/emoji/twitter/snowboarder.png and b/public/images/emoji/twitter/snowboarder.png differ diff --git a/public/images/emoji/twitter/snowflake.png b/public/images/emoji/twitter/snowflake.png index f028132c84c..987a0ab1b8c 100644 Binary files a/public/images/emoji/twitter/snowflake.png and b/public/images/emoji/twitter/snowflake.png differ diff --git a/public/images/emoji/twitter/snowman.png b/public/images/emoji/twitter/snowman.png index 21be2386676..9cc71367564 100644 Binary files a/public/images/emoji/twitter/snowman.png and b/public/images/emoji/twitter/snowman.png differ diff --git a/public/images/emoji/twitter/snowman2.png b/public/images/emoji/twitter/snowman2.png new file mode 100644 index 00000000000..8d53ae6e2e1 Binary files /dev/null and b/public/images/emoji/twitter/snowman2.png differ diff --git a/public/images/emoji/twitter/sob.png b/public/images/emoji/twitter/sob.png index a6d73884f26..5fd60102f8e 100644 Binary files a/public/images/emoji/twitter/sob.png and b/public/images/emoji/twitter/sob.png differ diff --git a/public/images/emoji/twitter/soccer.png b/public/images/emoji/twitter/soccer.png index c306eced704..5c399e49472 100644 Binary files a/public/images/emoji/twitter/soccer.png and b/public/images/emoji/twitter/soccer.png differ diff --git a/public/images/emoji/twitter/soon.png b/public/images/emoji/twitter/soon.png index eac4c59d95c..247ee1ec9e9 100644 Binary files a/public/images/emoji/twitter/soon.png and b/public/images/emoji/twitter/soon.png differ diff --git a/public/images/emoji/twitter/sos.png b/public/images/emoji/twitter/sos.png index 086755edd49..08dc5ee19d3 100644 Binary files a/public/images/emoji/twitter/sos.png and b/public/images/emoji/twitter/sos.png differ diff --git a/public/images/emoji/twitter/sound.png b/public/images/emoji/twitter/sound.png index e0d7df94b82..bfdba6bdb95 100644 Binary files a/public/images/emoji/twitter/sound.png and b/public/images/emoji/twitter/sound.png differ diff --git a/public/images/emoji/twitter/space_invader.png b/public/images/emoji/twitter/space_invader.png index c714fc28157..56031f3524e 100644 Binary files a/public/images/emoji/twitter/space_invader.png and b/public/images/emoji/twitter/space_invader.png differ diff --git a/public/images/emoji/twitter/spades.png b/public/images/emoji/twitter/spades.png index b8276037eb8..939a04e99eb 100644 Binary files a/public/images/emoji/twitter/spades.png and b/public/images/emoji/twitter/spades.png differ diff --git a/public/images/emoji/twitter/spaghetti.png b/public/images/emoji/twitter/spaghetti.png index d07ed9ec449..324f6be8e9b 100644 Binary files a/public/images/emoji/twitter/spaghetti.png and b/public/images/emoji/twitter/spaghetti.png differ diff --git a/public/images/emoji/twitter/sparkle.png b/public/images/emoji/twitter/sparkle.png index d3e02076415..926e8ff21a5 100644 Binary files a/public/images/emoji/twitter/sparkle.png and b/public/images/emoji/twitter/sparkle.png differ diff --git a/public/images/emoji/twitter/sparkler.png b/public/images/emoji/twitter/sparkler.png index 9c43022b9d3..f7fffca2f7a 100644 Binary files a/public/images/emoji/twitter/sparkler.png and b/public/images/emoji/twitter/sparkler.png differ diff --git a/public/images/emoji/twitter/sparkles.png b/public/images/emoji/twitter/sparkles.png index 514855cf818..1fa5de89195 100644 Binary files a/public/images/emoji/twitter/sparkles.png and b/public/images/emoji/twitter/sparkles.png differ diff --git a/public/images/emoji/twitter/sparkling_heart.png b/public/images/emoji/twitter/sparkling_heart.png index 7221d81d066..433612d799d 100644 Binary files a/public/images/emoji/twitter/sparkling_heart.png and b/public/images/emoji/twitter/sparkling_heart.png differ diff --git a/public/images/emoji/twitter/speak_no_evil.png b/public/images/emoji/twitter/speak_no_evil.png index c2061ce8999..2b8ba38ac68 100644 Binary files a/public/images/emoji/twitter/speak_no_evil.png and b/public/images/emoji/twitter/speak_no_evil.png differ diff --git a/public/images/emoji/twitter/speaker.png b/public/images/emoji/twitter/speaker.png index ed651cc72ef..9bb76c392c4 100644 Binary files a/public/images/emoji/twitter/speaker.png and b/public/images/emoji/twitter/speaker.png differ diff --git a/public/images/emoji/twitter/speaking_head.png b/public/images/emoji/twitter/speaking_head.png new file mode 100644 index 00000000000..56d482de530 Binary files /dev/null and b/public/images/emoji/twitter/speaking_head.png differ diff --git a/public/images/emoji/twitter/speech_balloon.png b/public/images/emoji/twitter/speech_balloon.png index a084cdc80b0..5810381b08d 100644 Binary files a/public/images/emoji/twitter/speech_balloon.png and b/public/images/emoji/twitter/speech_balloon.png differ diff --git a/public/images/emoji/twitter/speedboat.png b/public/images/emoji/twitter/speedboat.png index de945ce10ad..b9e9ef85207 100644 Binary files a/public/images/emoji/twitter/speedboat.png and b/public/images/emoji/twitter/speedboat.png differ diff --git a/public/images/emoji/twitter/spider.png b/public/images/emoji/twitter/spider.png new file mode 100644 index 00000000000..e3e128e5400 Binary files /dev/null and b/public/images/emoji/twitter/spider.png differ diff --git a/public/images/emoji/twitter/spider_web.png b/public/images/emoji/twitter/spider_web.png new file mode 100644 index 00000000000..683a02c906e Binary files /dev/null and b/public/images/emoji/twitter/spider_web.png differ diff --git a/public/images/emoji/twitter/spy.png b/public/images/emoji/twitter/spy.png new file mode 100644 index 00000000000..5dfa1e366b7 Binary files /dev/null and b/public/images/emoji/twitter/spy.png differ diff --git a/public/images/emoji/twitter/stadium.png b/public/images/emoji/twitter/stadium.png new file mode 100644 index 00000000000..6e56ffd85c8 Binary files /dev/null and b/public/images/emoji/twitter/stadium.png differ diff --git a/public/images/emoji/twitter/star.png b/public/images/emoji/twitter/star.png index 6e540555290..0abed9fcfd1 100644 Binary files a/public/images/emoji/twitter/star.png and b/public/images/emoji/twitter/star.png differ diff --git a/public/images/emoji/twitter/star2.png b/public/images/emoji/twitter/star2.png index b3b7f87db70..b69cb782464 100644 Binary files a/public/images/emoji/twitter/star2.png and b/public/images/emoji/twitter/star2.png differ diff --git a/public/images/emoji/twitter/star_and_crescent.png b/public/images/emoji/twitter/star_and_crescent.png new file mode 100644 index 00000000000..ae1f1386913 Binary files /dev/null and b/public/images/emoji/twitter/star_and_crescent.png differ diff --git a/public/images/emoji/twitter/star_of_david.png b/public/images/emoji/twitter/star_of_david.png new file mode 100644 index 00000000000..efe21ecdfe8 Binary files /dev/null and b/public/images/emoji/twitter/star_of_david.png differ diff --git a/public/images/emoji/twitter/stars.png b/public/images/emoji/twitter/stars.png index 61a29072130..8e26865e625 100644 Binary files a/public/images/emoji/twitter/stars.png and b/public/images/emoji/twitter/stars.png differ diff --git a/public/images/emoji/twitter/station.png b/public/images/emoji/twitter/station.png index 5921653cc10..ced5872ef69 100644 Binary files a/public/images/emoji/twitter/station.png and b/public/images/emoji/twitter/station.png differ diff --git a/public/images/emoji/twitter/statue_of_liberty.png b/public/images/emoji/twitter/statue_of_liberty.png index e3006b714c0..33f740e3eb1 100644 Binary files a/public/images/emoji/twitter/statue_of_liberty.png and b/public/images/emoji/twitter/statue_of_liberty.png differ diff --git a/public/images/emoji/twitter/steam_locomotive.png b/public/images/emoji/twitter/steam_locomotive.png index 16f69944f27..cd3f334714b 100644 Binary files a/public/images/emoji/twitter/steam_locomotive.png and b/public/images/emoji/twitter/steam_locomotive.png differ diff --git a/public/images/emoji/twitter/stew.png b/public/images/emoji/twitter/stew.png index 96ab289ffa5..b27bcf962df 100644 Binary files a/public/images/emoji/twitter/stew.png and b/public/images/emoji/twitter/stew.png differ diff --git a/public/images/emoji/twitter/stop_button.png b/public/images/emoji/twitter/stop_button.png new file mode 100644 index 00000000000..8b8953809ac Binary files /dev/null and b/public/images/emoji/twitter/stop_button.png differ diff --git a/public/images/emoji/twitter/stopwatch.png b/public/images/emoji/twitter/stopwatch.png new file mode 100644 index 00000000000..91ee4827ade Binary files /dev/null and b/public/images/emoji/twitter/stopwatch.png differ diff --git a/public/images/emoji/twitter/straight_ruler.png b/public/images/emoji/twitter/straight_ruler.png index ff4dceac958..dc6409e0a5d 100644 Binary files a/public/images/emoji/twitter/straight_ruler.png and b/public/images/emoji/twitter/straight_ruler.png differ diff --git a/public/images/emoji/twitter/strawberry.png b/public/images/emoji/twitter/strawberry.png index 8e01de58bbe..a19bd4a23e5 100644 Binary files a/public/images/emoji/twitter/strawberry.png and b/public/images/emoji/twitter/strawberry.png differ diff --git a/public/images/emoji/twitter/stuck_out_tongue.png b/public/images/emoji/twitter/stuck_out_tongue.png index f036ed35fa0..b1127e5cc75 100644 Binary files a/public/images/emoji/twitter/stuck_out_tongue.png and b/public/images/emoji/twitter/stuck_out_tongue.png differ diff --git a/public/images/emoji/twitter/stuck_out_tongue_closed_eyes.png b/public/images/emoji/twitter/stuck_out_tongue_closed_eyes.png index 05b69618aef..0ea2bdd1454 100644 Binary files a/public/images/emoji/twitter/stuck_out_tongue_closed_eyes.png and b/public/images/emoji/twitter/stuck_out_tongue_closed_eyes.png differ diff --git a/public/images/emoji/twitter/stuck_out_tongue_winking_eye.png b/public/images/emoji/twitter/stuck_out_tongue_winking_eye.png index 00f9976ca9d..1dda4a54d62 100644 Binary files a/public/images/emoji/twitter/stuck_out_tongue_winking_eye.png and b/public/images/emoji/twitter/stuck_out_tongue_winking_eye.png differ diff --git a/public/images/emoji/twitter/sun_with_face.png b/public/images/emoji/twitter/sun_with_face.png index 78297f9fdb4..1445a34eef0 100644 Binary files a/public/images/emoji/twitter/sun_with_face.png and b/public/images/emoji/twitter/sun_with_face.png differ diff --git a/public/images/emoji/twitter/sunflower.png b/public/images/emoji/twitter/sunflower.png index cbe183f49b7..e28bc6fc889 100644 Binary files a/public/images/emoji/twitter/sunflower.png and b/public/images/emoji/twitter/sunflower.png differ diff --git a/public/images/emoji/twitter/sunglasses.png b/public/images/emoji/twitter/sunglasses.png index d11e074d1dd..988e2f1afce 100644 Binary files a/public/images/emoji/twitter/sunglasses.png and b/public/images/emoji/twitter/sunglasses.png differ diff --git a/public/images/emoji/twitter/sunny.png b/public/images/emoji/twitter/sunny.png index ff67294e5fd..14c4db83b41 100644 Binary files a/public/images/emoji/twitter/sunny.png and b/public/images/emoji/twitter/sunny.png differ diff --git a/public/images/emoji/twitter/sunrise.png b/public/images/emoji/twitter/sunrise.png index 0e77ad0cd19..ada8c90e0fd 100644 Binary files a/public/images/emoji/twitter/sunrise.png and b/public/images/emoji/twitter/sunrise.png differ diff --git a/public/images/emoji/twitter/sunrise_over_mountains.png b/public/images/emoji/twitter/sunrise_over_mountains.png index c95776b5270..dd4f94bbf69 100644 Binary files a/public/images/emoji/twitter/sunrise_over_mountains.png and b/public/images/emoji/twitter/sunrise_over_mountains.png differ diff --git a/public/images/emoji/twitter/surfer.png b/public/images/emoji/twitter/surfer.png index 84e76fa4395..852efd417e5 100644 Binary files a/public/images/emoji/twitter/surfer.png and b/public/images/emoji/twitter/surfer.png differ diff --git a/public/images/emoji/twitter/sushi.png b/public/images/emoji/twitter/sushi.png index 53c053f021b..807d0fdda2a 100644 Binary files a/public/images/emoji/twitter/sushi.png and b/public/images/emoji/twitter/sushi.png differ diff --git a/public/images/emoji/twitter/suspension_railway.png b/public/images/emoji/twitter/suspension_railway.png index f357d583a97..8fc402f89d3 100644 Binary files a/public/images/emoji/twitter/suspension_railway.png and b/public/images/emoji/twitter/suspension_railway.png differ diff --git a/public/images/emoji/twitter/sweat.png b/public/images/emoji/twitter/sweat.png index 30f8642b864..bcad0e3f239 100644 Binary files a/public/images/emoji/twitter/sweat.png and b/public/images/emoji/twitter/sweat.png differ diff --git a/public/images/emoji/twitter/sweat_drops.png b/public/images/emoji/twitter/sweat_drops.png index 6b14c111ef7..adae644416a 100644 Binary files a/public/images/emoji/twitter/sweat_drops.png and b/public/images/emoji/twitter/sweat_drops.png differ diff --git a/public/images/emoji/twitter/sweat_smile.png b/public/images/emoji/twitter/sweat_smile.png index 2401acf351a..25e97effc0e 100644 Binary files a/public/images/emoji/twitter/sweat_smile.png and b/public/images/emoji/twitter/sweat_smile.png differ diff --git a/public/images/emoji/twitter/sweet_potato.png b/public/images/emoji/twitter/sweet_potato.png index 014490b42f4..c9449e49963 100644 Binary files a/public/images/emoji/twitter/sweet_potato.png and b/public/images/emoji/twitter/sweet_potato.png differ diff --git a/public/images/emoji/twitter/swimmer.png b/public/images/emoji/twitter/swimmer.png index d15b6cd901a..4aea21a9e14 100644 Binary files a/public/images/emoji/twitter/swimmer.png and b/public/images/emoji/twitter/swimmer.png differ diff --git a/public/images/emoji/twitter/symbols.png b/public/images/emoji/twitter/symbols.png index 21ccc8953b5..7715cd6caf6 100644 Binary files a/public/images/emoji/twitter/symbols.png and b/public/images/emoji/twitter/symbols.png differ diff --git a/public/images/emoji/twitter/synagogue.png b/public/images/emoji/twitter/synagogue.png new file mode 100644 index 00000000000..9dc959850a3 Binary files /dev/null and b/public/images/emoji/twitter/synagogue.png differ diff --git a/public/images/emoji/twitter/syringe.png b/public/images/emoji/twitter/syringe.png index 6f5b363f4b6..b093302452e 100644 Binary files a/public/images/emoji/twitter/syringe.png and b/public/images/emoji/twitter/syringe.png differ diff --git a/public/images/emoji/twitter/taco.png b/public/images/emoji/twitter/taco.png new file mode 100644 index 00000000000..fdb8752e1f1 Binary files /dev/null and b/public/images/emoji/twitter/taco.png differ diff --git a/public/images/emoji/twitter/tada.png b/public/images/emoji/twitter/tada.png index 26b49592cfb..13736cbb639 100644 Binary files a/public/images/emoji/twitter/tada.png and b/public/images/emoji/twitter/tada.png differ diff --git a/public/images/emoji/twitter/tanabata_tree.png b/public/images/emoji/twitter/tanabata_tree.png index 9e583b9e02b..45d5c253aa0 100644 Binary files a/public/images/emoji/twitter/tanabata_tree.png and b/public/images/emoji/twitter/tanabata_tree.png differ diff --git a/public/images/emoji/twitter/tangerine.png b/public/images/emoji/twitter/tangerine.png index 9d7c349b384..1ac523ec416 100644 Binary files a/public/images/emoji/twitter/tangerine.png and b/public/images/emoji/twitter/tangerine.png differ diff --git a/public/images/emoji/twitter/taurus.png b/public/images/emoji/twitter/taurus.png index 413be66bc17..6ea439229c7 100644 Binary files a/public/images/emoji/twitter/taurus.png and b/public/images/emoji/twitter/taurus.png differ diff --git a/public/images/emoji/twitter/taxi.png b/public/images/emoji/twitter/taxi.png index 112a3ad7f5e..5484b2fe0f5 100644 Binary files a/public/images/emoji/twitter/taxi.png and b/public/images/emoji/twitter/taxi.png differ diff --git a/public/images/emoji/twitter/tea.png b/public/images/emoji/twitter/tea.png index 93b986f9e2a..b546aa7302f 100644 Binary files a/public/images/emoji/twitter/tea.png and b/public/images/emoji/twitter/tea.png differ diff --git a/public/images/emoji/twitter/telephone_receiver.png b/public/images/emoji/twitter/telephone_receiver.png index 2c8bd6a58c5..6f796dfde38 100644 Binary files a/public/images/emoji/twitter/telephone_receiver.png and b/public/images/emoji/twitter/telephone_receiver.png differ diff --git a/public/images/emoji/twitter/telescope.png b/public/images/emoji/twitter/telescope.png index dc6ab4a6e7d..86c11762404 100644 Binary files a/public/images/emoji/twitter/telescope.png and b/public/images/emoji/twitter/telescope.png differ diff --git a/public/images/emoji/twitter/ten.png b/public/images/emoji/twitter/ten.png new file mode 100644 index 00000000000..9151e978ce4 Binary files /dev/null and b/public/images/emoji/twitter/ten.png differ diff --git a/public/images/emoji/twitter/tennis.png b/public/images/emoji/twitter/tennis.png index 53749f61f8f..f8120a86ce7 100644 Binary files a/public/images/emoji/twitter/tennis.png and b/public/images/emoji/twitter/tennis.png differ diff --git a/public/images/emoji/twitter/tent.png b/public/images/emoji/twitter/tent.png index 10f87707636..82f8931a438 100644 Binary files a/public/images/emoji/twitter/tent.png and b/public/images/emoji/twitter/tent.png differ diff --git a/public/images/emoji/twitter/thermometer.png b/public/images/emoji/twitter/thermometer.png new file mode 100644 index 00000000000..53746a78bf8 Binary files /dev/null and b/public/images/emoji/twitter/thermometer.png differ diff --git a/public/images/emoji/twitter/thermometer_face.png b/public/images/emoji/twitter/thermometer_face.png new file mode 100644 index 00000000000..c9440239c0d Binary files /dev/null and b/public/images/emoji/twitter/thermometer_face.png differ diff --git a/public/images/emoji/twitter/thinking.png b/public/images/emoji/twitter/thinking.png new file mode 100644 index 00000000000..41be4fd6bc7 Binary files /dev/null and b/public/images/emoji/twitter/thinking.png differ diff --git a/public/images/emoji/twitter/thought_balloon.png b/public/images/emoji/twitter/thought_balloon.png index 65b0129676e..f2f024a2404 100644 Binary files a/public/images/emoji/twitter/thought_balloon.png and b/public/images/emoji/twitter/thought_balloon.png differ diff --git a/public/images/emoji/twitter/thumbsdown.png b/public/images/emoji/twitter/thumbsdown.png index 6a639124ee4..d740aa7b25e 100644 Binary files a/public/images/emoji/twitter/thumbsdown.png and b/public/images/emoji/twitter/thumbsdown.png differ diff --git a/public/images/emoji/twitter/thunder_cloud_rain.png b/public/images/emoji/twitter/thunder_cloud_rain.png new file mode 100644 index 00000000000..71c2af1396b Binary files /dev/null and b/public/images/emoji/twitter/thunder_cloud_rain.png differ diff --git a/public/images/emoji/twitter/ticket.png b/public/images/emoji/twitter/ticket.png index e87e3128ef3..347662a2337 100644 Binary files a/public/images/emoji/twitter/ticket.png and b/public/images/emoji/twitter/ticket.png differ diff --git a/public/images/emoji/twitter/tickets.png b/public/images/emoji/twitter/tickets.png new file mode 100644 index 00000000000..11c88ec8544 Binary files /dev/null and b/public/images/emoji/twitter/tickets.png differ diff --git a/public/images/emoji/twitter/tiger.png b/public/images/emoji/twitter/tiger.png index 871536275f9..ab9a80f3a31 100644 Binary files a/public/images/emoji/twitter/tiger.png and b/public/images/emoji/twitter/tiger.png differ diff --git a/public/images/emoji/twitter/tiger2.png b/public/images/emoji/twitter/tiger2.png index 0b7f0ebb380..8dfdd97eca2 100644 Binary files a/public/images/emoji/twitter/tiger2.png and b/public/images/emoji/twitter/tiger2.png differ diff --git a/public/images/emoji/twitter/timer.png b/public/images/emoji/twitter/timer.png new file mode 100644 index 00000000000..c7f6d21c6c2 Binary files /dev/null and b/public/images/emoji/twitter/timer.png differ diff --git a/public/images/emoji/twitter/tired_face.png b/public/images/emoji/twitter/tired_face.png index b87d4dbeb6f..dc99e21d659 100644 Binary files a/public/images/emoji/twitter/tired_face.png and b/public/images/emoji/twitter/tired_face.png differ diff --git a/public/images/emoji/twitter/tm.png b/public/images/emoji/twitter/tm.png index f70fd4797e8..a46e367eaf1 100644 Binary files a/public/images/emoji/twitter/tm.png and b/public/images/emoji/twitter/tm.png differ diff --git a/public/images/emoji/twitter/toilet.png b/public/images/emoji/twitter/toilet.png index 7b7468b1be1..fe173f23f72 100644 Binary files a/public/images/emoji/twitter/toilet.png and b/public/images/emoji/twitter/toilet.png differ diff --git a/public/images/emoji/twitter/tokyo_tower.png b/public/images/emoji/twitter/tokyo_tower.png index 88c8d71c749..a139ecd615a 100644 Binary files a/public/images/emoji/twitter/tokyo_tower.png and b/public/images/emoji/twitter/tokyo_tower.png differ diff --git a/public/images/emoji/twitter/tomato.png b/public/images/emoji/twitter/tomato.png index 95d9acba96e..c8163e63633 100644 Binary files a/public/images/emoji/twitter/tomato.png and b/public/images/emoji/twitter/tomato.png differ diff --git a/public/images/emoji/twitter/tongue.png b/public/images/emoji/twitter/tongue.png index 2b730f93390..e98250d2ee4 100644 Binary files a/public/images/emoji/twitter/tongue.png and b/public/images/emoji/twitter/tongue.png differ diff --git a/public/images/emoji/twitter/tools.png b/public/images/emoji/twitter/tools.png new file mode 100644 index 00000000000..2448331da8e Binary files /dev/null and b/public/images/emoji/twitter/tools.png differ diff --git a/public/images/emoji/twitter/top.png b/public/images/emoji/twitter/top.png index eb23f5ef3c8..da019b78eaa 100644 Binary files a/public/images/emoji/twitter/top.png and b/public/images/emoji/twitter/top.png differ diff --git a/public/images/emoji/twitter/tophat.png b/public/images/emoji/twitter/tophat.png index 2adb554c60c..558cbc37549 100644 Binary files a/public/images/emoji/twitter/tophat.png and b/public/images/emoji/twitter/tophat.png differ diff --git a/public/images/emoji/twitter/track_next.png b/public/images/emoji/twitter/track_next.png new file mode 100644 index 00000000000..9aafe8deb86 Binary files /dev/null and b/public/images/emoji/twitter/track_next.png differ diff --git a/public/images/emoji/twitter/track_previous.png b/public/images/emoji/twitter/track_previous.png new file mode 100644 index 00000000000..d6f3c89e275 Binary files /dev/null and b/public/images/emoji/twitter/track_previous.png differ diff --git a/public/images/emoji/twitter/trackball.png b/public/images/emoji/twitter/trackball.png new file mode 100644 index 00000000000..8205a4e8431 Binary files /dev/null and b/public/images/emoji/twitter/trackball.png differ diff --git a/public/images/emoji/twitter/tractor.png b/public/images/emoji/twitter/tractor.png index 1f984972a80..3f85ef3f542 100644 Binary files a/public/images/emoji/twitter/tractor.png and b/public/images/emoji/twitter/tractor.png differ diff --git a/public/images/emoji/twitter/traffic_light.png b/public/images/emoji/twitter/traffic_light.png index 48b5d29a426..aa83e08d7d0 100644 Binary files a/public/images/emoji/twitter/traffic_light.png and b/public/images/emoji/twitter/traffic_light.png differ diff --git a/public/images/emoji/twitter/train.png b/public/images/emoji/twitter/train.png index 013893b76f8..6fad581c798 100644 Binary files a/public/images/emoji/twitter/train.png and b/public/images/emoji/twitter/train.png differ diff --git a/public/images/emoji/twitter/train2.png b/public/images/emoji/twitter/train2.png index c7120d915eb..1ce7231db29 100644 Binary files a/public/images/emoji/twitter/train2.png and b/public/images/emoji/twitter/train2.png differ diff --git a/public/images/emoji/twitter/tram.png b/public/images/emoji/twitter/tram.png index 2297b1de0c5..878ac023f9a 100644 Binary files a/public/images/emoji/twitter/tram.png and b/public/images/emoji/twitter/tram.png differ diff --git a/public/images/emoji/twitter/triangular_flag_on_post.png b/public/images/emoji/twitter/triangular_flag_on_post.png index 2243d6db66b..94a0c030b11 100644 Binary files a/public/images/emoji/twitter/triangular_flag_on_post.png and b/public/images/emoji/twitter/triangular_flag_on_post.png differ diff --git a/public/images/emoji/twitter/triangular_ruler.png b/public/images/emoji/twitter/triangular_ruler.png index 2c8045da485..52c61fa057d 100644 Binary files a/public/images/emoji/twitter/triangular_ruler.png and b/public/images/emoji/twitter/triangular_ruler.png differ diff --git a/public/images/emoji/twitter/trident.png b/public/images/emoji/twitter/trident.png index 5eee6c02f5e..968747edb7b 100644 Binary files a/public/images/emoji/twitter/trident.png and b/public/images/emoji/twitter/trident.png differ diff --git a/public/images/emoji/twitter/triumph.png b/public/images/emoji/twitter/triumph.png index 65d90497a0d..31d2aea9766 100644 Binary files a/public/images/emoji/twitter/triumph.png and b/public/images/emoji/twitter/triumph.png differ diff --git a/public/images/emoji/twitter/trolleybus.png b/public/images/emoji/twitter/trolleybus.png index fe8548106d4..cc6c588f538 100644 Binary files a/public/images/emoji/twitter/trolleybus.png and b/public/images/emoji/twitter/trolleybus.png differ diff --git a/public/images/emoji/twitter/trophy.png b/public/images/emoji/twitter/trophy.png index 8010d8cdfa4..842a4e9174d 100644 Binary files a/public/images/emoji/twitter/trophy.png and b/public/images/emoji/twitter/trophy.png differ diff --git a/public/images/emoji/twitter/tropical_drink.png b/public/images/emoji/twitter/tropical_drink.png index 16f2c8822cd..3d3131af074 100644 Binary files a/public/images/emoji/twitter/tropical_drink.png and b/public/images/emoji/twitter/tropical_drink.png differ diff --git a/public/images/emoji/twitter/tropical_fish.png b/public/images/emoji/twitter/tropical_fish.png index 4a02ce1c35e..273059a1c8c 100644 Binary files a/public/images/emoji/twitter/tropical_fish.png and b/public/images/emoji/twitter/tropical_fish.png differ diff --git a/public/images/emoji/twitter/truck.png b/public/images/emoji/twitter/truck.png index 5baf34cff60..05ae5ffc871 100644 Binary files a/public/images/emoji/twitter/truck.png and b/public/images/emoji/twitter/truck.png differ diff --git a/public/images/emoji/twitter/trumpet.png b/public/images/emoji/twitter/trumpet.png index d46d206be2f..55eda7897bf 100644 Binary files a/public/images/emoji/twitter/trumpet.png and b/public/images/emoji/twitter/trumpet.png differ diff --git a/public/images/emoji/twitter/tshirt.png b/public/images/emoji/twitter/tshirt.png index bf78d21c060..e9461499f49 100644 Binary files a/public/images/emoji/twitter/tshirt.png and b/public/images/emoji/twitter/tshirt.png differ diff --git a/public/images/emoji/twitter/tulip.png b/public/images/emoji/twitter/tulip.png index 64b50b690b9..f0b86589a93 100644 Binary files a/public/images/emoji/twitter/tulip.png and b/public/images/emoji/twitter/tulip.png differ diff --git a/public/images/emoji/twitter/turkey.png b/public/images/emoji/twitter/turkey.png new file mode 100644 index 00000000000..20856a9e8b0 Binary files /dev/null and b/public/images/emoji/twitter/turkey.png differ diff --git a/public/images/emoji/twitter/turtle.png b/public/images/emoji/twitter/turtle.png index dc2d666ffa6..2c763eb7bb3 100644 Binary files a/public/images/emoji/twitter/turtle.png and b/public/images/emoji/twitter/turtle.png differ diff --git a/public/images/emoji/twitter/tv.png b/public/images/emoji/twitter/tv.png index 2bbee71c3e0..b487503fe7a 100644 Binary files a/public/images/emoji/twitter/tv.png and b/public/images/emoji/twitter/tv.png differ diff --git a/public/images/emoji/twitter/twisted_rightwards_arrows.png b/public/images/emoji/twitter/twisted_rightwards_arrows.png index fc1e421606f..5046a51b9e4 100644 Binary files a/public/images/emoji/twitter/twisted_rightwards_arrows.png and b/public/images/emoji/twitter/twisted_rightwards_arrows.png differ diff --git a/public/images/emoji/twitter/two_hearts.png b/public/images/emoji/twitter/two_hearts.png index 0d0068f3086..f06417a1589 100644 Binary files a/public/images/emoji/twitter/two_hearts.png and b/public/images/emoji/twitter/two_hearts.png differ diff --git a/public/images/emoji/twitter/two_men_holding_hands.png b/public/images/emoji/twitter/two_men_holding_hands.png index f0cbbb54389..8d92e353144 100644 Binary files a/public/images/emoji/twitter/two_men_holding_hands.png and b/public/images/emoji/twitter/two_men_holding_hands.png differ diff --git a/public/images/emoji/twitter/two_women_holding_hands.png b/public/images/emoji/twitter/two_women_holding_hands.png index f13ef4254b6..ecd95a9fc5e 100644 Binary files a/public/images/emoji/twitter/two_women_holding_hands.png and b/public/images/emoji/twitter/two_women_holding_hands.png differ diff --git a/public/images/emoji/twitter/u5272.png b/public/images/emoji/twitter/u5272.png index 212a6758582..859d9139f96 100644 Binary files a/public/images/emoji/twitter/u5272.png and b/public/images/emoji/twitter/u5272.png differ diff --git a/public/images/emoji/twitter/u5408.png b/public/images/emoji/twitter/u5408.png index e4ee50c85c2..327b529cd9c 100644 Binary files a/public/images/emoji/twitter/u5408.png and b/public/images/emoji/twitter/u5408.png differ diff --git a/public/images/emoji/twitter/u55b6.png b/public/images/emoji/twitter/u55b6.png index 6fe0b6f229e..3dc3f4c5075 100644 Binary files a/public/images/emoji/twitter/u55b6.png and b/public/images/emoji/twitter/u55b6.png differ diff --git a/public/images/emoji/twitter/u6307.png b/public/images/emoji/twitter/u6307.png index 53ea0942fa7..bc6995841e8 100644 Binary files a/public/images/emoji/twitter/u6307.png and b/public/images/emoji/twitter/u6307.png differ diff --git a/public/images/emoji/twitter/u6708.png b/public/images/emoji/twitter/u6708.png index 75c4af6975d..2cda0d29179 100644 Binary files a/public/images/emoji/twitter/u6708.png and b/public/images/emoji/twitter/u6708.png differ diff --git a/public/images/emoji/twitter/u6709.png b/public/images/emoji/twitter/u6709.png index f2cb50f9814..8eb5b60aa63 100644 Binary files a/public/images/emoji/twitter/u6709.png and b/public/images/emoji/twitter/u6709.png differ diff --git a/public/images/emoji/twitter/u6e80.png b/public/images/emoji/twitter/u6e80.png index 597b02eefb5..10bd555e3cb 100644 Binary files a/public/images/emoji/twitter/u6e80.png and b/public/images/emoji/twitter/u6e80.png differ diff --git a/public/images/emoji/twitter/u7121.png b/public/images/emoji/twitter/u7121.png index 75e6e0fae02..06f7d61c723 100644 Binary files a/public/images/emoji/twitter/u7121.png and b/public/images/emoji/twitter/u7121.png differ diff --git a/public/images/emoji/twitter/u7533.png b/public/images/emoji/twitter/u7533.png index b94f801411e..ef5cb065acc 100644 Binary files a/public/images/emoji/twitter/u7533.png and b/public/images/emoji/twitter/u7533.png differ diff --git a/public/images/emoji/twitter/u7981.png b/public/images/emoji/twitter/u7981.png index 82764f6d4d9..ea2ea8f4ab9 100644 Binary files a/public/images/emoji/twitter/u7981.png and b/public/images/emoji/twitter/u7981.png differ diff --git a/public/images/emoji/twitter/u7a7a.png b/public/images/emoji/twitter/u7a7a.png index 12205ed88ab..e053172a915 100644 Binary files a/public/images/emoji/twitter/u7a7a.png and b/public/images/emoji/twitter/u7a7a.png differ diff --git a/public/images/emoji/twitter/uk.png b/public/images/emoji/twitter/uk.png index f31e458c1dc..1790afe9cd6 100644 Binary files a/public/images/emoji/twitter/uk.png and b/public/images/emoji/twitter/uk.png differ diff --git a/public/images/emoji/twitter/umbrella.png b/public/images/emoji/twitter/umbrella.png index 8e4e3508c89..0d063ddaefe 100644 Binary files a/public/images/emoji/twitter/umbrella.png and b/public/images/emoji/twitter/umbrella.png differ diff --git a/public/images/emoji/twitter/umbrella2.png b/public/images/emoji/twitter/umbrella2.png new file mode 100644 index 00000000000..24e72f080b2 Binary files /dev/null and b/public/images/emoji/twitter/umbrella2.png differ diff --git a/public/images/emoji/twitter/unamused.png b/public/images/emoji/twitter/unamused.png index 0ceb3708287..71d2b7bba10 100644 Binary files a/public/images/emoji/twitter/unamused.png and b/public/images/emoji/twitter/unamused.png differ diff --git a/public/images/emoji/twitter/underage.png b/public/images/emoji/twitter/underage.png index 702cf425b81..c19179fc34a 100644 Binary files a/public/images/emoji/twitter/underage.png and b/public/images/emoji/twitter/underage.png differ diff --git a/public/images/emoji/twitter/unicorn.png b/public/images/emoji/twitter/unicorn.png new file mode 100644 index 00000000000..4afcbe217f5 Binary files /dev/null and b/public/images/emoji/twitter/unicorn.png differ diff --git a/public/images/emoji/twitter/unlock.png b/public/images/emoji/twitter/unlock.png index 764cabd9302..9fc5764fb16 100644 Binary files a/public/images/emoji/twitter/unlock.png and b/public/images/emoji/twitter/unlock.png differ diff --git a/public/images/emoji/twitter/up.png b/public/images/emoji/twitter/up.png index 799607c2b37..d4a1b9db961 100644 Binary files a/public/images/emoji/twitter/up.png and b/public/images/emoji/twitter/up.png differ diff --git a/public/images/emoji/twitter/upside_down.png b/public/images/emoji/twitter/upside_down.png new file mode 100644 index 00000000000..e8abd438126 Binary files /dev/null and b/public/images/emoji/twitter/upside_down.png differ diff --git a/public/images/emoji/twitter/urn.png b/public/images/emoji/twitter/urn.png new file mode 100644 index 00000000000..cc65fe127e1 Binary files /dev/null and b/public/images/emoji/twitter/urn.png differ diff --git a/public/images/emoji/twitter/us.png b/public/images/emoji/twitter/us.png index 2a0cbf0009c..a9807a157d3 100644 Binary files a/public/images/emoji/twitter/us.png and b/public/images/emoji/twitter/us.png differ diff --git a/public/images/emoji/twitter/v.png b/public/images/emoji/twitter/v.png index c6e9b645342..2fb5e98118c 100644 Binary files a/public/images/emoji/twitter/v.png and b/public/images/emoji/twitter/v.png differ diff --git a/public/images/emoji/twitter/vertical_traffic_light.png b/public/images/emoji/twitter/vertical_traffic_light.png index 286901f2fe0..f614f5cbeac 100644 Binary files a/public/images/emoji/twitter/vertical_traffic_light.png and b/public/images/emoji/twitter/vertical_traffic_light.png differ diff --git a/public/images/emoji/twitter/vhs.png b/public/images/emoji/twitter/vhs.png index 4583077e229..33f48127f91 100644 Binary files a/public/images/emoji/twitter/vhs.png and b/public/images/emoji/twitter/vhs.png differ diff --git a/public/images/emoji/twitter/vibration_mode.png b/public/images/emoji/twitter/vibration_mode.png index cb81a51c3a8..b3f1aaffd21 100644 Binary files a/public/images/emoji/twitter/vibration_mode.png and b/public/images/emoji/twitter/vibration_mode.png differ diff --git a/public/images/emoji/twitter/video_camera.png b/public/images/emoji/twitter/video_camera.png index acc4578753c..307190a9a0e 100644 Binary files a/public/images/emoji/twitter/video_camera.png and b/public/images/emoji/twitter/video_camera.png differ diff --git a/public/images/emoji/twitter/video_game.png b/public/images/emoji/twitter/video_game.png index d84ae0786b4..f8a6230387f 100644 Binary files a/public/images/emoji/twitter/video_game.png and b/public/images/emoji/twitter/video_game.png differ diff --git a/public/images/emoji/twitter/violin.png b/public/images/emoji/twitter/violin.png index 7d2e82d5d86..c82f693b8e2 100644 Binary files a/public/images/emoji/twitter/violin.png and b/public/images/emoji/twitter/violin.png differ diff --git a/public/images/emoji/twitter/virgo.png b/public/images/emoji/twitter/virgo.png index 7d10568d7c1..8de2e5a19a9 100644 Binary files a/public/images/emoji/twitter/virgo.png and b/public/images/emoji/twitter/virgo.png differ diff --git a/public/images/emoji/twitter/volcano.png b/public/images/emoji/twitter/volcano.png index fc733b42ae9..0c66f10974e 100644 Binary files a/public/images/emoji/twitter/volcano.png and b/public/images/emoji/twitter/volcano.png differ diff --git a/public/images/emoji/twitter/volleyball.png b/public/images/emoji/twitter/volleyball.png new file mode 100644 index 00000000000..08edda74404 Binary files /dev/null and b/public/images/emoji/twitter/volleyball.png differ diff --git a/public/images/emoji/twitter/vs.png b/public/images/emoji/twitter/vs.png index 706965c12e2..e58f0f1b454 100644 Binary files a/public/images/emoji/twitter/vs.png and b/public/images/emoji/twitter/vs.png differ diff --git a/public/images/emoji/twitter/vulcan.png b/public/images/emoji/twitter/vulcan.png new file mode 100644 index 00000000000..72cc1170de7 Binary files /dev/null and b/public/images/emoji/twitter/vulcan.png differ diff --git a/public/images/emoji/twitter/walking.png b/public/images/emoji/twitter/walking.png index 7f6b71175c7..a25eb9fcf2e 100644 Binary files a/public/images/emoji/twitter/walking.png and b/public/images/emoji/twitter/walking.png differ diff --git a/public/images/emoji/twitter/waning_crescent_moon.png b/public/images/emoji/twitter/waning_crescent_moon.png index 38edbadb376..99b267a016a 100644 Binary files a/public/images/emoji/twitter/waning_crescent_moon.png and b/public/images/emoji/twitter/waning_crescent_moon.png differ diff --git a/public/images/emoji/twitter/waning_gibbous_moon.png b/public/images/emoji/twitter/waning_gibbous_moon.png index d8072a3e4d1..16c9ae19cd5 100644 Binary files a/public/images/emoji/twitter/waning_gibbous_moon.png and b/public/images/emoji/twitter/waning_gibbous_moon.png differ diff --git a/public/images/emoji/twitter/warning.png b/public/images/emoji/twitter/warning.png index 310d2256af1..66c3df48422 100644 Binary files a/public/images/emoji/twitter/warning.png and b/public/images/emoji/twitter/warning.png differ diff --git a/public/images/emoji/twitter/wastebasket.png b/public/images/emoji/twitter/wastebasket.png new file mode 100644 index 00000000000..9e8f4719ece Binary files /dev/null and b/public/images/emoji/twitter/wastebasket.png differ diff --git a/public/images/emoji/twitter/watch.png b/public/images/emoji/twitter/watch.png index c52c19b2734..0375c468559 100644 Binary files a/public/images/emoji/twitter/watch.png and b/public/images/emoji/twitter/watch.png differ diff --git a/public/images/emoji/twitter/water_buffalo.png b/public/images/emoji/twitter/water_buffalo.png index 4787a61a7a3..c456e0decb3 100644 Binary files a/public/images/emoji/twitter/water_buffalo.png and b/public/images/emoji/twitter/water_buffalo.png differ diff --git a/public/images/emoji/twitter/watermelon.png b/public/images/emoji/twitter/watermelon.png index 4d84a2b3061..3b01a358426 100644 Binary files a/public/images/emoji/twitter/watermelon.png and b/public/images/emoji/twitter/watermelon.png differ diff --git a/public/images/emoji/twitter/wave.png b/public/images/emoji/twitter/wave.png index 2f219a4a6c5..8013d5f0b34 100644 Binary files a/public/images/emoji/twitter/wave.png and b/public/images/emoji/twitter/wave.png differ diff --git a/public/images/emoji/twitter/wavy_dash.png b/public/images/emoji/twitter/wavy_dash.png index 3fcfdfb0ecb..4f5446954c4 100644 Binary files a/public/images/emoji/twitter/wavy_dash.png and b/public/images/emoji/twitter/wavy_dash.png differ diff --git a/public/images/emoji/twitter/waxing_crescent_moon.png b/public/images/emoji/twitter/waxing_crescent_moon.png index 526f78da3b7..625da5f5fdf 100644 Binary files a/public/images/emoji/twitter/waxing_crescent_moon.png and b/public/images/emoji/twitter/waxing_crescent_moon.png differ diff --git a/public/images/emoji/twitter/waxing_gibbous_moon.png b/public/images/emoji/twitter/waxing_gibbous_moon.png index 319561d7109..d8411fd27a5 100644 Binary files a/public/images/emoji/twitter/waxing_gibbous_moon.png and b/public/images/emoji/twitter/waxing_gibbous_moon.png differ diff --git a/public/images/emoji/twitter/wc.png b/public/images/emoji/twitter/wc.png index 0c779cd4775..f500db80e8c 100644 Binary files a/public/images/emoji/twitter/wc.png and b/public/images/emoji/twitter/wc.png differ diff --git a/public/images/emoji/twitter/weary.png b/public/images/emoji/twitter/weary.png index 1ef63c7e737..f9facbd9c6e 100644 Binary files a/public/images/emoji/twitter/weary.png and b/public/images/emoji/twitter/weary.png differ diff --git a/public/images/emoji/twitter/wedding.png b/public/images/emoji/twitter/wedding.png index 6483199e4ad..b89a5655bd5 100644 Binary files a/public/images/emoji/twitter/wedding.png and b/public/images/emoji/twitter/wedding.png differ diff --git a/public/images/emoji/twitter/whale.png b/public/images/emoji/twitter/whale.png index 2e5f613f4e7..2c83b0b2244 100644 Binary files a/public/images/emoji/twitter/whale.png and b/public/images/emoji/twitter/whale.png differ diff --git a/public/images/emoji/twitter/whale2.png b/public/images/emoji/twitter/whale2.png index e1fd1fdd67f..ec0479c1073 100644 Binary files a/public/images/emoji/twitter/whale2.png and b/public/images/emoji/twitter/whale2.png differ diff --git a/public/images/emoji/twitter/wheel_of_dharma.png b/public/images/emoji/twitter/wheel_of_dharma.png new file mode 100644 index 00000000000..c4d0c56251b Binary files /dev/null and b/public/images/emoji/twitter/wheel_of_dharma.png differ diff --git a/public/images/emoji/twitter/wheelchair.png b/public/images/emoji/twitter/wheelchair.png index 52966c6889b..108f45d80f9 100644 Binary files a/public/images/emoji/twitter/wheelchair.png and b/public/images/emoji/twitter/wheelchair.png differ diff --git a/public/images/emoji/twitter/white_check_mark.png b/public/images/emoji/twitter/white_check_mark.png index 2ce525a314c..d1769fa2dd5 100644 Binary files a/public/images/emoji/twitter/white_check_mark.png and b/public/images/emoji/twitter/white_check_mark.png differ diff --git a/public/images/emoji/twitter/white_circle.png b/public/images/emoji/twitter/white_circle.png index 1f3f7874e9a..88be70ca5db 100644 Binary files a/public/images/emoji/twitter/white_circle.png and b/public/images/emoji/twitter/white_circle.png differ diff --git a/public/images/emoji/twitter/white_flower.png b/public/images/emoji/twitter/white_flower.png index 1f435957c74..58af191f9b8 100644 Binary files a/public/images/emoji/twitter/white_flower.png and b/public/images/emoji/twitter/white_flower.png differ diff --git a/public/images/emoji/twitter/white_large_square.png b/public/images/emoji/twitter/white_large_square.png index bc9de693ad1..ab37e10932d 100644 Binary files a/public/images/emoji/twitter/white_large_square.png and b/public/images/emoji/twitter/white_large_square.png differ diff --git a/public/images/emoji/twitter/white_medium_small_square.png b/public/images/emoji/twitter/white_medium_small_square.png index 83df4c86df5..139e87753ad 100644 Binary files a/public/images/emoji/twitter/white_medium_small_square.png and b/public/images/emoji/twitter/white_medium_small_square.png differ diff --git a/public/images/emoji/twitter/white_medium_square.png b/public/images/emoji/twitter/white_medium_square.png index 78a5940ebe4..acf09155b5c 100644 Binary files a/public/images/emoji/twitter/white_medium_square.png and b/public/images/emoji/twitter/white_medium_square.png differ diff --git a/public/images/emoji/twitter/white_small_square.png b/public/images/emoji/twitter/white_small_square.png index bcff71a524b..2cb7e3655be 100644 Binary files a/public/images/emoji/twitter/white_small_square.png and b/public/images/emoji/twitter/white_small_square.png differ diff --git a/public/images/emoji/twitter/white_square_button.png b/public/images/emoji/twitter/white_square_button.png index 59089e757c7..f0c1d9fae48 100644 Binary files a/public/images/emoji/twitter/white_square_button.png and b/public/images/emoji/twitter/white_square_button.png differ diff --git a/public/images/emoji/twitter/white_sun_cloud.png b/public/images/emoji/twitter/white_sun_cloud.png new file mode 100644 index 00000000000..cabbfd24972 Binary files /dev/null and b/public/images/emoji/twitter/white_sun_cloud.png differ diff --git a/public/images/emoji/twitter/white_sun_rain_cloud.png b/public/images/emoji/twitter/white_sun_rain_cloud.png new file mode 100644 index 00000000000..1270388a29b Binary files /dev/null and b/public/images/emoji/twitter/white_sun_rain_cloud.png differ diff --git a/public/images/emoji/twitter/white_sun_small_cloud.png b/public/images/emoji/twitter/white_sun_small_cloud.png new file mode 100644 index 00000000000..8757d5503c6 Binary files /dev/null and b/public/images/emoji/twitter/white_sun_small_cloud.png differ diff --git a/public/images/emoji/twitter/wind_blowing_face.png b/public/images/emoji/twitter/wind_blowing_face.png new file mode 100644 index 00000000000..190cfc18a83 Binary files /dev/null and b/public/images/emoji/twitter/wind_blowing_face.png differ diff --git a/public/images/emoji/twitter/wind_chime.png b/public/images/emoji/twitter/wind_chime.png index c6694e8a287..4f18b33e21b 100644 Binary files a/public/images/emoji/twitter/wind_chime.png and b/public/images/emoji/twitter/wind_chime.png differ diff --git a/public/images/emoji/twitter/wine_glass.png b/public/images/emoji/twitter/wine_glass.png index 5cfda51425c..796e3bf2136 100644 Binary files a/public/images/emoji/twitter/wine_glass.png and b/public/images/emoji/twitter/wine_glass.png differ diff --git a/public/images/emoji/twitter/wink.png b/public/images/emoji/twitter/wink.png index ed1b91c16fc..b70c9c2dbd1 100644 Binary files a/public/images/emoji/twitter/wink.png and b/public/images/emoji/twitter/wink.png differ diff --git a/public/images/emoji/twitter/wolf.png b/public/images/emoji/twitter/wolf.png index 13cb94f7b1b..89c8f76da87 100644 Binary files a/public/images/emoji/twitter/wolf.png and b/public/images/emoji/twitter/wolf.png differ diff --git a/public/images/emoji/twitter/woman.png b/public/images/emoji/twitter/woman.png index a5072819355..cf8a07a8c18 100644 Binary files a/public/images/emoji/twitter/woman.png and b/public/images/emoji/twitter/woman.png differ diff --git a/public/images/emoji/twitter/womans_clothes.png b/public/images/emoji/twitter/womans_clothes.png index 5cc359fd152..949e451dc6f 100644 Binary files a/public/images/emoji/twitter/womans_clothes.png and b/public/images/emoji/twitter/womans_clothes.png differ diff --git a/public/images/emoji/twitter/womans_hat.png b/public/images/emoji/twitter/womans_hat.png index be1d7002a4d..15f5c91c906 100644 Binary files a/public/images/emoji/twitter/womans_hat.png and b/public/images/emoji/twitter/womans_hat.png differ diff --git a/public/images/emoji/twitter/womens.png b/public/images/emoji/twitter/womens.png index c4ef94ed795..a6b345e3fe7 100644 Binary files a/public/images/emoji/twitter/womens.png and b/public/images/emoji/twitter/womens.png differ diff --git a/public/images/emoji/twitter/worried.png b/public/images/emoji/twitter/worried.png index fefb226c9c2..9807e884ca7 100644 Binary files a/public/images/emoji/twitter/worried.png and b/public/images/emoji/twitter/worried.png differ diff --git a/public/images/emoji/twitter/wrench.png b/public/images/emoji/twitter/wrench.png index f3fbe3360ec..acb0c4b7a22 100644 Binary files a/public/images/emoji/twitter/wrench.png and b/public/images/emoji/twitter/wrench.png differ diff --git a/public/images/emoji/twitter/writing_hand.png b/public/images/emoji/twitter/writing_hand.png new file mode 100644 index 00000000000..eb2e8c89b92 Binary files /dev/null and b/public/images/emoji/twitter/writing_hand.png differ diff --git a/public/images/emoji/twitter/x.png b/public/images/emoji/twitter/x.png index a245297866d..a3bae6df1d1 100644 Binary files a/public/images/emoji/twitter/x.png and b/public/images/emoji/twitter/x.png differ diff --git a/public/images/emoji/twitter/yellow_heart.png b/public/images/emoji/twitter/yellow_heart.png index 4e7688b61ab..c286ed58ffe 100644 Binary files a/public/images/emoji/twitter/yellow_heart.png and b/public/images/emoji/twitter/yellow_heart.png differ diff --git a/public/images/emoji/twitter/yen.png b/public/images/emoji/twitter/yen.png index 0700b6cbc8c..cec1d8dac79 100644 Binary files a/public/images/emoji/twitter/yen.png and b/public/images/emoji/twitter/yen.png differ diff --git a/public/images/emoji/twitter/yin_yang.png b/public/images/emoji/twitter/yin_yang.png new file mode 100644 index 00000000000..beb2a87dc3e Binary files /dev/null and b/public/images/emoji/twitter/yin_yang.png differ diff --git a/public/images/emoji/twitter/yum.png b/public/images/emoji/twitter/yum.png index cd81753f0e0..064155ae24c 100644 Binary files a/public/images/emoji/twitter/yum.png and b/public/images/emoji/twitter/yum.png differ diff --git a/public/images/emoji/twitter/zap.png b/public/images/emoji/twitter/zap.png index ee193678fcb..3343f39ca18 100644 Binary files a/public/images/emoji/twitter/zap.png and b/public/images/emoji/twitter/zap.png differ diff --git a/public/images/emoji/twitter/zipper_mouth.png b/public/images/emoji/twitter/zipper_mouth.png new file mode 100644 index 00000000000..d59236821bf Binary files /dev/null and b/public/images/emoji/twitter/zipper_mouth.png differ diff --git a/public/images/emoji/twitter/zzz.png b/public/images/emoji/twitter/zzz.png index 9e1ab21bcf1..aca9b61c3fc 100644 Binary files a/public/images/emoji/twitter/zzz.png and b/public/images/emoji/twitter/zzz.png differ diff --git a/public/images/welcome/emoji-completion-2x.png b/public/images/welcome/emoji-completion-2x.png index 8f861983422..b5035b7751f 100644 Binary files a/public/images/welcome/emoji-completion-2x.png and b/public/images/welcome/emoji-completion-2x.png differ diff --git a/public/images/welcome/like-link-flag-bookmark-2x.png b/public/images/welcome/like-link-flag-bookmark-2x.png index 97f3e16540a..bf8b7650d38 100644 Binary files a/public/images/welcome/like-link-flag-bookmark-2x.png and b/public/images/welcome/like-link-flag-bookmark-2x.png differ diff --git a/public/images/welcome/notification-panel-2x.png b/public/images/welcome/notification-panel-2x.png index 57a79c6631b..0f0ab7665d7 100644 Binary files a/public/images/welcome/notification-panel-2x.png and b/public/images/welcome/notification-panel-2x.png differ diff --git a/public/images/welcome/progress-bar-2x.png b/public/images/welcome/progress-bar-2x.png index 7545a9b6cc7..725f0e1b026 100644 Binary files a/public/images/welcome/progress-bar-2x.png and b/public/images/welcome/progress-bar-2x.png differ diff --git a/public/images/welcome/quote-reply-2x.png b/public/images/welcome/quote-reply-2x.png index 7e1c0455ae1..8db31cede6b 100644 Binary files a/public/images/welcome/quote-reply-2x.png and b/public/images/welcome/quote-reply-2x.png differ diff --git a/public/images/welcome/quote-reply-cs.png b/public/images/welcome/quote-reply-cs.png index d3bb1bc934d..0069e84e1fa 100644 Binary files a/public/images/welcome/quote-reply-cs.png and b/public/images/welcome/quote-reply-cs.png differ diff --git a/public/images/welcome/reply-as-linked-topic-2x.png b/public/images/welcome/reply-as-linked-topic-2x.png index 66e129862dc..1a3454f6437 100644 Binary files a/public/images/welcome/reply-as-linked-topic-2x.png and b/public/images/welcome/reply-as-linked-topic-2x.png differ diff --git a/public/images/welcome/reply-post-2x.png b/public/images/welcome/reply-post-2x.png index 659cf7cff39..a532f3c967b 100644 Binary files a/public/images/welcome/reply-post-2x.png and b/public/images/welcome/reply-post-2x.png differ diff --git a/public/images/welcome/reply-topic-2x.png b/public/images/welcome/reply-topic-2x.png index 96df6749e4f..cb1cf9cccf0 100644 Binary files a/public/images/welcome/reply-topic-2x.png and b/public/images/welcome/reply-topic-2x.png differ diff --git a/public/images/welcome/topic-list-select-areas-2x.png b/public/images/welcome/topic-list-select-areas-2x.png index 0652d30446b..f202e8992a5 100644 Binary files a/public/images/welcome/topic-list-select-areas-2x.png and b/public/images/welcome/topic-list-select-areas-2x.png differ diff --git a/public/images/welcome/topic-notification-control-2x.png b/public/images/welcome/topic-notification-control-2x.png index e330e1c0d2e..ed867071c6e 100644 Binary files a/public/images/welcome/topic-notification-control-2x.png and b/public/images/welcome/topic-notification-control-2x.png differ diff --git a/public/images/welcome/topics-new-unread-2x.png b/public/images/welcome/topics-new-unread-2x.png index c39089b18f9..e0337c34b74 100644 Binary files a/public/images/welcome/topics-new-unread-2x.png and b/public/images/welcome/topics-new-unread-2x.png differ diff --git a/public/images/welcome/username-completion-2x.png b/public/images/welcome/username-completion-2x.png index d5237923fea..ab3ca2507ad 100644 Binary files a/public/images/welcome/username-completion-2x.png and b/public/images/welcome/username-completion-2x.png differ diff --git a/public/images/welcome/username-completion-cs.png b/public/images/welcome/username-completion-cs.png index bce11a1a12b..180cc747b7b 100644 Binary files a/public/images/welcome/username-completion-cs.png and b/public/images/welcome/username-completion-cs.png differ diff --git a/public/javascripts/pikaday.js b/public/javascripts/pikaday.js index c0596d22d3b..bc0c64474e6 100644 --- a/public/javascripts/pikaday.js +++ b/public/javascripts/pikaday.js @@ -202,6 +202,9 @@ // first day of week (0: Sunday, 1: Monday etc) firstDay: 0, + // the default flag for moment's strict date parsing + formatStrict: false, + // the minimum/earliest date that can be selected minDate: null, // the maximum/latest date that can be selected @@ -230,6 +233,9 @@ // Render the month after year in the calendar title showMonthAfterYear: false, + // Render days of the calendar grid that fall in the next or previous month + showDaysInNextAndPreviousMonths: false, + // how many months are visible numberOfMonths: 1, @@ -274,10 +280,14 @@ renderDay = function(opts) { - if (opts.isEmpty) { - return ''; - } var arr = []; + if (opts.isEmpty) { + if (opts.showDaysInNextAndPreviousMonths) { + arr.push('is-outside-current-month'); + } else { + return ''; + } + } if (opts.isDisabled) { arr.push('is-disabled'); } @@ -417,7 +427,7 @@ return; } - if (!hasClass(target.parentNode, 'is-disabled')) { + if (!hasClass(target, 'is-disabled')) { if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')) { self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day'))); if (opts.bound) { @@ -472,7 +482,7 @@ return; } if (hasMoment) { - date = moment(opts.field.value, opts.format); + date = moment(opts.field.value, opts.format, opts.formatStrict); date = (date && date.isValid()) ? date.toDate() : null; } else { @@ -638,9 +648,7 @@ this.setMinDate(opts.minDate); } if (opts.maxDate) { - setToStartOfDay(opts.maxDate); - opts.maxYear = opts.maxDate.getFullYear(); - opts.maxMonth = opts.maxDate.getMonth(); + this.setMaxDate(opts.maxDate); } if (isArray(opts.yearRange)) { @@ -828,6 +836,7 @@ this._o.minDate = value; this._o.minYear = value.getFullYear(); this._o.minMonth = value.getMonth(); + this.draw(); }, /** @@ -835,7 +844,11 @@ */ setMaxDate: function(value) { + setToStartOfDay(value); this._o.maxDate = value; + this._o.maxYear = value.getFullYear(); + this._o.maxMonth = value.getMonth(); + this.draw(); }, setStartRange: function(value) @@ -967,6 +980,11 @@ before += 7; } } + var previousMonth = month === 0 ? 11 : month - 1, + nextMonth = month === 11 ? 0 : month + 1, + yearOfPreviousMonth = month === 0 ? year - 1 : year, + yearOfNextMonth = month === 11 ? year + 1 : year, + daysInPreviousMonth = getDaysInMonth(yearOfPreviousMonth, previousMonth); var cells = days + before, after = cells; while(after > 7) { @@ -979,24 +997,41 @@ isSelected = isDate(this._d) ? compareDates(day, this._d) : false, isToday = compareDates(day, now), isEmpty = i < before || i >= (days + before), + dayNumber = 1 + (i - before), + monthNumber = month, + yearNumber = year, isStartRange = opts.startRange && compareDates(opts.startRange, day), isEndRange = opts.endRange && compareDates(opts.endRange, day), isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange, isDisabled = (opts.minDate && day < opts.minDate) || (opts.maxDate && day > opts.maxDate) || (opts.disableWeekends && isWeekend(day)) || - (opts.disableDayFn && opts.disableDayFn(day)), - dayConfig = { - day: 1 + (i - before), - month: month, - year: year, + (opts.disableDayFn && opts.disableDayFn(day)); + + if (isEmpty) { + if (i < before) { + dayNumber = daysInPreviousMonth + dayNumber; + monthNumber = previousMonth; + yearNumber = yearOfPreviousMonth; + } else { + dayNumber = dayNumber - days; + monthNumber = nextMonth; + yearNumber = yearOfNextMonth; + } + } + + var dayConfig = { + day: dayNumber, + month: monthNumber, + year: yearNumber, isSelected: isSelected, isToday: isToday, isDisabled: isDisabled, isEmpty: isEmpty, isStartRange: isStartRange, isEndRange: isEndRange, - isInRange: isInRange + isInRange: isInRange, + showDaysInNextAndPreviousMonths: opts.showDaysInNextAndPreviousMonths }; row.push(renderDay(dayConfig)); diff --git a/script/discourse b/script/discourse index ee847f0365f..af03de89b35 100755 --- a/script/discourse +++ b/script/discourse @@ -134,12 +134,57 @@ class DiscourseCLI < Thor puts 'Requests sent. Clients will refresh on next navigation.' end + desc "export_category", "Export a category, all its topics, and all users who posted in those topics" + def export_category(category_id, filename=nil) + raise "Category id argument is missing!" unless category_id + + load_rails + load_import_export + ImportExport.export_category(category_id, filename) + puts "", "Done", "" + end + + desc "import_category", "Import a category, its topics and the users from the output of the export_category command" + def import_category(filename) + raise "File name argument missing!" unless filename + + puts "Starting import from #{filename}..." + load_rails + load_import_export + ImportExport.import_category(filename) + puts "", "Done", "" + end + + desc "export_topics", "Export topics and all users who posted in that topic. Accepts multiple topic id's" + def export_topics(*topic_ids) + puts "Starting export of topics...", "" + load_rails + load_import_export + ImportExport.export_topics(topic_ids) + puts "", "Done", "" + end + + desc "import_topics", "Import topics and their users from the output of the export_topic command" + def import_topics(filename) + raise "File name argument missing!" unless filename + + puts "Starting import from #{filename}..." + load_rails + load_import_export + ImportExport.import_topics(filename) + puts "", "Done", "" + end + private def load_rails require File.expand_path(File.dirname(__FILE__) + "/../config/environment") end + def load_import_export + require File.expand_path(File.dirname(__FILE__) + "/../lib/import_export/import_export") + end + def do_remap(from, to) sql = "SELECT table_name, column_name FROM information_schema.columns diff --git a/script/import_scripts/base.rb b/script/import_scripts/base.rb index 57bbc24e9d9..5c4cd5bc800 100644 --- a/script/import_scripts/base.rb +++ b/script/import_scripts/base.rb @@ -197,18 +197,20 @@ class ImportScripts::Base def all_records_exist?(type, import_ids) return false if import_ids.empty? - existing = "#{type.to_s.classify}CustomField".constantize.where(name: 'import_id') + Post.exec_sql('CREATE TEMP TABLE import_ids(val varchar(200) PRIMARY KEY)') - if Fixnum === import_ids.first - existing = existing.where('cast(value as int) in (?)', import_ids) - else - existing = existing.where('value in (?)', import_ids) - end + import_id_clause = import_ids.map { |id| "('#{PG::Connection.escape_string(id.to_s)}')" }.join(",") + Post.exec_sql("INSERT INTO import_ids VALUES #{import_id_clause}") + + existing = "#{type.to_s.classify}CustomField".constantize.where(name: 'import_id') + existing = existing.joins('JOIN import_ids ON val = value') if existing.count == import_ids.length - # puts "Skipping #{import_ids.length} already imported #{type}" - true + puts "Skipping #{import_ids.length} already imported #{type}" + return true end + ensure + Post.exec_sql('DROP TABLE import_ids') end # Iterate through a list of user records to be imported. @@ -237,14 +239,18 @@ class ImportScripts::Base elsif u[:email].present? new_user = create_user(u, import_id) - if new_user.valid? && new_user.user_profile.valid? + if new_user && new_user.valid? && new_user.user_profile && new_user.user_profile.valid? @lookup.add_user(import_id.to_s, new_user) created += 1 else failed += 1 - puts "Failed to create user id: #{import_id}, username: #{new_user.username}, email: #{new_user.email}" - puts "user errors: #{new_user.errors.full_messages}" - puts "user_profile errors: #{new_user.user_profiler.errors.full_messages}" + puts "Failed to create user id: #{import_id}, username: #{new_user.try(:username)}, email: #{new_user.try(:email)}" + if new_user.try(:errors) + puts "user errors: #{new_user.errors.full_messages}" + if new_user.try(:user_profile).try(:errors) + puts "user_profile errors: #{new_user.user_profile.errors.full_messages}" + end + end end else failed += 1 @@ -271,13 +277,17 @@ class ImportScripts::Base location = opts.delete(:location) avatar_url = opts.delete(:avatar_url) + # Allow the || operations to work with empty strings '' + opts[:username] = nil if opts[:username].blank? + opts[:name] = User.suggest_name(opts[:email]) unless opts[:name] if opts[:username].blank? || opts[:username].length < User.username_length.begin || opts[:username].length > User.username_length.end || !User.username_available?(opts[:username]) || !UsernameValidator.new(opts[:username]).valid_format? - opts[:username] = UserNameSuggester.suggest(opts[:username] || opts[:name] || opts[:email]) + + opts[:username] = UserNameSuggester.suggest(opts[:username] || opts[:name].presence || opts[:email]) end opts[:email] = opts[:email].downcase opts[:trust_level] = TrustLevel[1] unless opts[:trust_level] @@ -286,6 +296,7 @@ class ImportScripts::Base opts[:last_emailed_at] = opts.fetch(:last_emailed_at, Time.now) u = User.new(opts) + (opts[:custom_fields] || {}).each { |k, v| u.custom_fields[k] = v } u.custom_fields["import_id"] = import_id u.custom_fields["import_username"] = opts[:username] if opts[:username].present? u.custom_fields["import_avatar_url"] = avatar_url if avatar_url.present? @@ -295,8 +306,8 @@ class ImportScripts::Base User.transaction do u.save! if bio_raw.present? || website.present? || location.present? - u.user_profile.bio_raw = bio_raw if bio_raw.present? - u.user_profile.website = website if website.present? + u.user_profile.bio_raw = bio_raw[0..2999] if bio_raw.present? + u.user_profile.website = website unless website.blank? || website !~ UserProfile::WEBSITE_REGEXP u.user_profile.location = location if location.present? u.user_profile.save! end @@ -307,18 +318,18 @@ class ImportScripts::Base end rescue => e # try based on email - if e.record.errors.messages[:email].present? - existing = User.find_by(email: opts[:email].downcase) - if existing + if e.try(:record).try(:errors).try(:messages).try(:[], :email).present? + if existing = User.find_by(email: opts[:email].downcase) existing.custom_fields["import_id"] = import_id existing.save! u = existing end else - puts "Error on record: #{opts}" + puts "Error on record: #{opts.inspect}" raise e end end + post_create_action.try(:call, u) if u.persisted? u # If there was an error creating the user, u.errors has the messages @@ -355,7 +366,6 @@ class ImportScripts::Base end new_category = create_category(params, params[:id]) - @lookup.add_category(params[:id], new_category) created += 1 end @@ -385,6 +395,8 @@ class ImportScripts::Base new_category.custom_fields["import_id"] = import_id if import_id new_category.save! + @lookup.add_category(import_id, new_category) + post_create_action.try(:call, new_category) new_category @@ -449,6 +461,8 @@ class ImportScripts::Base [created, skipped] end + STAFF_GUARDIAN = Guardian.new(User.find(-1)) + def create_post(opts, import_id) user = User.find(opts[:user_id]) post_create_action = opts.delete(:post_create_action) @@ -457,6 +471,7 @@ class ImportScripts::Base opts[:custom_fields] ||= {} opts[:custom_fields]['import_id'] = import_id + opts[:guardian] = STAFF_GUARDIAN if @bbcode_to_md opts[:raw] = opts[:raw].bbcode_to_md(false) rescue opts[:raw] end @@ -631,6 +646,23 @@ class ImportScripts::Base end end + def update_user_signup_date_based_on_first_post + puts "", "setting users' signup date based on the date of their first post" + + total_count = User.count + progress_count = 0 + + User.find_each do |user| + first = user.posts.order('created_at ASC').first + if first + user.created_at = first.created_at + user.save! + end + progress_count += 1 + print_status(progress_count, total_count) + end + end + def html_for_upload(upload, display_filename) @uploader.html_for_upload(upload, display_filename) end diff --git a/script/import_scripts/base/csv_helper.rb b/script/import_scripts/base/csv_helper.rb new file mode 100644 index 00000000000..c505ce71015 --- /dev/null +++ b/script/import_scripts/base/csv_helper.rb @@ -0,0 +1,75 @@ +module ImportScripts + module CsvHelper + class RowResolver + def load(row) + @row = row + end + + def self.create(cols) + Class.new(RowResolver).new(cols) + end + + def initialize(cols) + cols.each_with_index do |col,idx| + self.class.send(:define_method, col.downcase.gsub(/[\W]/, '_').squeeze('_')) do + @row[idx] + end + end + end + end + + def csv_parse(filename, col_sep = ',') + first = true + row = nil + + current_row = "" + double_quote_count = 0 + + File.open(filename).each_line do |line| + + line.strip! + + current_row << "\n" unless current_row.empty? + current_row << line + + double_quote_count += line.scan('"').count + + next if double_quote_count % 2 == 1 # this row continues on a new line. don't parse until we have the whole row. + + raw = begin + CSV.parse(current_row, col_sep: col_sep) + rescue CSV::MalformedCSVError => e + puts e.message + puts "*" * 100 + puts "Bad row skipped, line is: #{line}" + puts + puts current_row + puts + puts "double quote count is : #{double_quote_count}" + puts "*" * 100 + + current_row = "" + double_quote_count = 0 + + next + end[0] + + if first + row = RowResolver.create(raw) + + current_row = "" + double_quote_count = 0 + first = false + next + end + + row.load(raw) + + yield row + + current_row = "" + double_quote_count = 0 + end + end + end +end \ No newline at end of file diff --git a/script/import_scripts/bbpress.rb b/script/import_scripts/bbpress.rb index aba552d11e0..87ee57bdd14 100644 --- a/script/import_scripts/bbpress.rb +++ b/script/import_scripts/bbpress.rb @@ -1,124 +1,193 @@ -# `dropdb bbpress` -# `createdb bbpress` -# `bundle exec rake db:migrate` - require 'mysql2' require File.expand_path(File.dirname(__FILE__) + "/base.rb") -BB_PRESS_DB = ENV['BBPRESS_DB'] || "bbpress" -DB_TABLE_PREFIX = "wp_" - class ImportScripts::Bbpress < ImportScripts::Base + BB_PRESS_DB ||= ENV['BBPRESS_DB'] || "bbpress" + BATCH_SIZE ||= 1000 + def initialize super @client = Mysql2::Client.new( host: "localhost", username: "root", - #password: "password", - database: BB_PRESS_DB + database: BB_PRESS_DB, ) end - def table_name(name) - DB_TABLE_PREFIX + name - end - def execute - users_results = @client.query(" - SELECT id, - user_login username, - display_name name, - user_url website, - user_email email, - user_registered created_at - FROM #{table_name 'users'}", cache_rows: false) - - puts '', "creating users" - - create_users(users_results) do |u| - ActiveSupport::HashWithIndifferentAccess.new(u) - end - - - puts '', '', "creating categories" - - create_categories(@client.query("SELECT id, post_name, post_parent from #{table_name 'posts'} WHERE post_type = 'forum' AND post_name != '' ORDER BY post_parent")) do |c| - result = {id: c['id'], name: c['post_name']} - parent_id = c['post_parent'].to_i - if parent_id > 0 - result[:parent_category_id] = category_id_from_imported_category_id(parent_id) - end - result - end - - import_posts + import_users + import_categories + import_topics_and_posts end - def import_posts - puts '', "creating topics and posts" + def import_users + puts "", "importing users..." - total_count = @client.query(" - SELECT count(*) count - FROM #{table_name 'posts'} + last_user_id = -1 + total_users = bbpress_query("SELECT COUNT(*) count FROM wp_users WHERE user_email LIKE '%@%'").first["count"] + + batches(BATCH_SIZE) do |offset| + users = bbpress_query(<<-SQL + SELECT id, user_nicename, display_name, user_email, user_registered, user_url + FROM wp_users + WHERE user_email LIKE '%@%' + AND id > #{last_user_id} + ORDER BY id + LIMIT #{BATCH_SIZE} + SQL + ).to_a + + break if users.empty? + + last_user_id = users[-1]["id"] + user_ids = users.map { |u| u["id"].to_i } + + next if all_records_exist?(:users, user_ids) + + user_ids_sql = user_ids.join(",") + + users_description = {} + bbpress_query(<<-SQL + SELECT user_id, meta_value description + FROM wp_usermeta + WHERE user_id IN (#{user_ids_sql}) + AND meta_key = 'description' + SQL + ).each { |um| users_description[um["user_id"]] = um["description"] } + + users_last_activity = {} + bbpress_query(<<-SQL + SELECT user_id, meta_value last_activity + FROM wp_usermeta + WHERE user_id IN (#{user_ids_sql}) + AND meta_key = 'last_activity' + SQL + ).each { |um| users_last_activity[um["user_id"]] = um["last_activity"] } + + create_users(users, total: total_users, offset: offset) do |u| + { + id: u["id"].to_i, + username: u["user_nicename"], + email: u["user_email"].downcase, + name: u["display_name"], + created_at: u["user_registered"], + website: u["user_url"], + bio_raw: users_description[u["id"]], + last_seen_at: users_last_activity[u["id"]], + } + end + end + end + + def import_categories + puts "", "importing categories..." + + categories = bbpress_query(<<-SQL + SELECT id, post_name, post_parent + FROM wp_posts + WHERE post_type = 'forum' + AND LENGTH(COALESCE(post_name, '')) > 0 + ORDER BY post_parent, id + SQL + ) + + create_categories(categories) do |c| + category = { id: c['id'], name: c['post_name'] } + if (parent_id = c['post_parent'].to_i) > 0 + category[:parent_category_id] = category_id_from_imported_category_id(parent_id) + end + category + end + end + + def import_topics_and_posts + puts "", "importing topics and posts..." + + last_post_id = -1 + total_posts = bbpress_query(<<-SQL + SELECT COUNT(*) count + FROM wp_posts WHERE post_status <> 'spam' - AND post_type IN ('topic', 'reply')").first['count'] + AND post_type IN ('topic', 'reply') + SQL + ).first["count"] - batch_size = 1000 + batches(BATCH_SIZE) do |offset| + posts = bbpress_query(<<-SQL + SELECT id, + post_author, + post_date, + post_content, + post_title, + post_type, + post_parent + FROM wp_posts + WHERE post_status <> 'spam' + AND post_type IN ('topic', 'reply') + AND id > #{last_post_id} + ORDER BY id + LIMIT #{BATCH_SIZE} + SQL + ).to_a - batches(batch_size) do |offset| - results = @client.query(" - SELECT id, - post_author, - post_date, - post_content, - post_title, - post_type, - post_parent - FROM #{table_name 'posts'} - WHERE post_status <> 'spam' - AND post_type IN ('topic', 'reply') - ORDER BY id - LIMIT #{batch_size} - OFFSET #{offset}", cache_rows: false) + break if posts.empty? - break if results.size < 1 + last_post_id = posts[-1]["id"].to_i + post_ids = posts.map { |p| p["id"].to_i } - next if all_records_exist? :posts, results.map {|p| p["id"].to_i} + next if all_records_exist?(:posts, post_ids) - create_posts(results, total: total_count, offset: offset) do |post| + post_ids_sql = post_ids.join(",") + + posts_likes = {} + bbpress_query(<<-SQL + SELECT post_id, meta_value likes + FROM wp_postmeta + WHERE post_id IN (#{post_ids_sql}) + AND meta_key = 'Likes' + SQL + ).each { |pm| posts_likes[pm["post_id"]] = pm["likes"].to_i } + + create_posts(posts, total: total_posts, offset: offset) do |p| skip = false - mapped = {} - mapped[:id] = post["id"] - mapped[:user_id] = user_id_from_imported_user_id(post["post_author"]) || find_user_by_import_id(post["post_author"]).try(:id) || -1 - mapped[:raw] = post["post_content"] - if mapped[:raw] - mapped[:raw] = mapped[:raw].gsub("
    ", "```\n").gsub("
    ", "\n```") + post = { + id: p["id"], + user_id: user_id_from_imported_user_id(p["post_author"]) || find_user_by_import_id(p["post_author"]).try(:id) || -1, + raw: p["post_content"], + created_at: p["post_date"], + like_count: posts_likes[p["id"]], + } + + if post[:raw].present? + post[:raw].gsub!("
    ", "```\n")
    +          post[:raw].gsub!("
    ", "\n```") end - mapped[:created_at] = post["post_date"] - mapped[:custom_fields] = {import_id: post["id"]} - if post["post_type"] == "topic" - mapped[:category] = category_id_from_imported_category_id(post["post_parent"]) - mapped[:title] = CGI.unescapeHTML post["post_title"] + if p["post_type"] == "topic" + post[:category] = category_id_from_imported_category_id(p["post_parent"]) + post[:title] = CGI.unescapeHTML(p["post_title"]) else - parent = topic_lookup_from_imported_post_id(post["post_parent"]) - if parent - mapped[:topic_id] = parent[:topic_id] - mapped[:reply_to_post_number] = parent[:post_number] if parent[:post_number] > 1 + if parent = topic_lookup_from_imported_post_id(p["post_parent"]) + post[:topic_id] = parent[:topic_id] + post[:reply_to_post_number] = parent[:post_number] if parent[:post_number] > 1 else - puts "Skipping #{post["id"]}: #{post["post_content"][0..40]}" + puts "Skipping #{p["id"]}: #{p["post_content"][0..40]}" skip = true end end - skip ? nil : mapped + skip ? nil : post end end end + def bbpress_query(sql) + @client.query(sql, cache_rows: false) + end + end ImportScripts::Bbpress.new.perform diff --git a/script/import_scripts/discuz_x.rb b/script/import_scripts/discuz_x.rb index f252ddb861d..791b6c38da2 100644 --- a/script/import_scripts/discuz_x.rb +++ b/script/import_scripts/discuz_x.rb @@ -7,6 +7,8 @@ # This script is tested only on Simplified Chinese Discuz! X instances # If you want to import data other than Simplified Chinese, email me. +require 'php_serialize' +require 'miro' require 'mysql2' require File.expand_path(File.dirname(__FILE__) + "/base.rb") @@ -34,9 +36,23 @@ class ImportScripts::DiscuzX < ImportScripts::Base database: DISCUZX_DB ) @first_post_id_by_topic_id = {} + + @internal_url_regexps = [ + /http(?:s)?:\/\/#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}\/forum\.php\?mod=viewthread(?:&|&)tid=(?\d+)(?:[^\[\]\s]*)(?:pid=?(?\d+))?(?:[^\[\]\s]*)/, + /http(?:s)?:\/\/#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}\/viewthread\.php\?tid=(?\d+)(?:[^\[\]\s]*)(?:pid=?(?\d+))?(?:[^\[\]\s]*)/, + /http(?:s)?:\/\/#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}\/forum\.php\?mod=redirect(?:&|&)goto=findpost(?:&|&)pid=(?\d+)(?:&|&)ptid=(?\d+)(?:[^\[\]\s]*)/, + /http(?:s)?:\/\/#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}\/redirect\.php\?goto=findpost(?:&|&)pid=(?\d+)(?:&|&)ptid=(?\d+)(?:[^\[\]\s]*)/, + /http(?:s)?:\/\/#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}\/forumdisplay\.php\?fid=(?\d+)(?:[^\[\]\s]*)/, + /http(?:s)?:\/\/#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}\/forum\.php\?mod=forumdisplay(?:&|&)fid=(?\d+)(?:[^\[\]\s]*)/, + /http(?:s)?:\/\/#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}\/(?index)\.php(?:[^\[\]\s]*)/, + /http(?:s)?:\/\/#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}\/(?stats)\.php(?:[^\[\]\s]*)/, + /http(?:s)?:\/\/#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}\/misc.php\?mod=(?stat|ranklist)(?:[^\[\]\s]*)/ + ] + end def execute + get_knowledge_about_duplicated_email import_users import_categories import_posts @@ -53,19 +69,53 @@ class ImportScripts::DiscuzX < ImportScripts::Base def get_knowledge_about_group group_table = table_name 'common_usergroup' result = mysql_query( - "SELECT groupid group_id, radminid role_id, type, grouptitle title + "SELECT groupid group_id, radminid role_id FROM #{group_table};") - @moderator_group_id = -1 - @admin_group_id = -1 + @moderator_group_id = [] + @admin_group_id = [] + #@banned_group_id = [4,5] # 禁止的用户及其帖子均不导入,如果你想导入这些用户和帖子,请把这个数组清空。 result.each do |group| - role_id = group['role_id'] - group_id = group['group_id'] - case group['title'].strip - when '管理员' - @admin_admin_id = role_id - when '超级版主' - @moderator_admin_id = role_id + case group['role_id'] + when 1 # 管理员 + @admin_group_id << group['group_id'] + when 2, 3 # 超级版主、版主。如果你不希望原普通版主成为Discourse版主,把3去掉。 + @moderator_group_id << group['group_id'] + end + end + end + + def get_knowledge_about_category_slug + @category_slug = {} + results = mysql_query("SELECT svalue value + FROM #{table_name 'common_setting'} + WHERE skey = 'forumkeys'") + + return if results.size < 1 + value = results.first['value'] + + return if value.blank? + + PHP.unserialize(value).each do |category_import_id, slug| + next if slug.blank? + @category_slug[category_import_id] = slug + end + end + + def get_knowledge_about_duplicated_email + @duplicated_email = {} + results = mysql_query( + "select a.uid uid, b.uid import_id from pre_common_member a + join (select uid, email from pre_common_member group by email having count(email) > 1 order by uid asc) b USING(email) + where a.uid != b.uid") + + users = @lookup.instance_variable_get :@users + + results.each do |row| + @duplicated_email[row['uid']] = row['import_id'] + user_id = users[row['import_id']] + if user_id + users[row['uid']] = user_id end end end @@ -79,51 +129,63 @@ class ImportScripts::DiscuzX < ImportScripts::Base user_table = table_name 'common_member' profile_table = table_name 'common_member_profile' status_table = table_name 'common_member_status' + forum_table = table_name 'common_member_field_forum' + home_table = table_name 'common_member_field_home' total_count = mysql_query("SELECT count(*) count FROM #{user_table};").first['count'] batches(BATCH_SIZE) do |offset| results = mysql_query( - "SELECT u.uid id, u.username username, u.email email, u.adminid admin_id, su.regdate regdate, s.regip regip, - u.emailstatus email_confirmed, u.avatarstatus avatar_exists, p.site website, p.resideprovince province, - p.residecity city, p.residedist country, p.residecommunity community, p.residesuite apartment, - p.bio bio, s.lastip last_visit_ip, s.lastvisit last_visit_time, s.lastpost last_posted_at, - s.lastsendmail last_emailed_at + "SELECT u.uid id, u.username username, u.email email, u.groupid group_id, + su.regdate regdate, su.password password_hash, su.salt salt, + s.regip regip, s.lastip last_visit_ip, s.lastvisit last_visit_time, s.lastpost last_posted_at, s.lastsendmail last_emailed_at, + u.emailstatus email_confirmed, u.avatarstatus avatar_exists, + p.site website, p.address address, p.bio bio, p.realname realname, p.qq qq, + p.resideprovince resideprovince, p.residecity residecity, p.residedist residedist, p.residecommunity residecommunity, + p.resideprovince birthprovince, p.birthcity birthcity, p.birthdist birthdist, p.birthcommunity birthcommunity, + h.spacecss spacecss, h.spacenote spacenote, + f.customstatus customstatus, f.sightml sightml FROM #{user_table} u - JOIN #{sensitive_user_table} su ON su.uid = u.uid - JOIN #{profile_table} p ON p.uid = u.uid - JOIN #{status_table} s ON s.uid = u.uid + LEFT JOIN #{sensitive_user_table} su USING(uid) + LEFT JOIN #{profile_table} p USING(uid) + LEFT JOIN #{status_table} s USING(uid) + LEFT JOIN #{forum_table} f USING(uid) + LEFT JOIN #{home_table} h USING(uid) ORDER BY u.uid ASC LIMIT #{BATCH_SIZE} OFFSET #{offset};") break if results.size < 1 - next if all_records_exist? :users, users.map {|u| u["id"].to_i} + # TODO: breaks the scipt reported by some users + # next if all_records_exist? :users, users.map {|u| u["id"].to_i} create_users(results, total: total_count, offset: offset) do |user| { id: user['id'], email: user['email'], username: user['username'], - name: user['username'], - created_at: Time.zone.at(user['regdate']), + name: first_exists(user['realname'], user['customstatus'], user['username']), + import_pass: user['password_hash'], + active: true, + salt: user['salt'], + # TODO: title: user['customstatus'], # move custom title to name since discourse can't let user custom title https://meta.discourse.org/t/let-users-custom-their-title/37626 + created_at: user['regdate'] ? Time.zone.at(user['regdate']) : nil, registration_ip_address: user['regip'], ip_address: user['last_visit_ip'], last_seen_at: user['last_visit_time'], last_emailed_at: user['last_emailed_at'], last_posted_at: user['last_posted_at'], - moderator: user['admin_id'] == @moderator_admin_id, - admin: user['admin_id'] == @admin_admin_id, - active: true, - website: user['website'], - bio_raw: user['bio'], - location: "#{user['province']}#{user['city']}#{user['country']}#{user['community']}#{user['apartment']}", + moderator: @moderator_group_id.include?(user['group_id']), + admin: @admin_group_id.include?(user['group_id']), + website: (user['website'] and user['website'].include?('.')) ? user['website'].strip : ( user['qq'] and user['qq'].strip == user['qq'].strip.to_i and user['qq'].strip.to_i > 10000 ) ? 'http://user.qzone.qq.com/' + user['qq'].strip : nil, + bio_raw: first_exists((user['bio'] and CGI.unescapeHTML(user['bio'])), user['sightml'], user['spacenote']).strip[0,3000], + location: first_exists(user['address'], (!user['resideprovince'].blank? ? [user['resideprovince'], user['residecity'], user['residedist'], user['residecommunity']] : [user['birthprovince'], user['birthcity'], user['birthdist'], user['birthcommunity']]).reject{|location|location.blank?}.join(' ')), post_create_action: lambda do |newmember| if user['avatar_exists'] == 1 and newmember.uploaded_avatar_id.blank? path, filename = discuzx_avatar_fullpath(user['id']) if path begin upload = create_upload(newmember.id, path, filename) - if upload.persisted? + if !upload.nil? && upload.persisted? newmember.import_mode = false newmember.create_user_avatar newmember.import_mode = true @@ -137,9 +199,42 @@ class ImportScripts::DiscuzX < ImportScripts::Base end end end + if !user['spacecss'].blank? and newmember.user_profile.profile_background.blank? + # profile background + if matched = user['spacecss'].match(/body\s*{[^}]*url\('?(.+?)'?\)/i) + body_background = matched[1].split(ORIGINAL_SITE_PREFIX, 2).last + end + if matched = user['spacecss'].match(/#hd\s*{[^}]*url\('?(.+?)'?\)/i) + header_background = matched[1].split(ORIGINAL_SITE_PREFIX, 2).last + end + if matched = user['spacecss'].match(/.blocktitle\s*{[^}]*url\('?(.+?)'?\)/i) + blocktitle_background = matched[1].split(ORIGINAL_SITE_PREFIX, 2).last + end + if matched = user['spacecss'].match(/#ct\s*{[^}]*url\('?(.+?)'?\)/i) + content_background = matched[1].split(ORIGINAL_SITE_PREFIX, 2).last + end + + if body_background || header_background || blocktitle_background || content_background + profile_background = first_exists(header_background, body_background, content_background, blocktitle_background) + card_background = first_exists(content_background, body_background, header_background, blocktitle_background) + upload = create_upload(newmember.id, File.join(DISCUZX_BASE_DIR, profile_background), File.basename(profile_background)) + if upload + newmember.user_profile.upload_profile_background upload + else + puts "WARNING: #{user['username']} (UID: #{user['id']}) profile_background file did not persist!" + end + upload = create_upload(newmember.id, File.join(DISCUZX_BASE_DIR, card_background), File.basename(card_background)) + if upload + newmember.user_profile.upload_card_background upload + else + puts "WARNING: #{user['username']} (UID: #{user['id']}) card_background file did not persist!" + end + end + end # we don't send email to the unconfirmed user newmember.update(email_digests: user['email_confirmed'] == 1) if newmember.email_digests + newmember.update(name: '') if !newmember.name.blank? and newmember.name == newmember.username end } end @@ -149,27 +244,57 @@ class ImportScripts::DiscuzX < ImportScripts::Base def import_categories puts '', "creating categories" + get_knowledge_about_category_slug + forums_table = table_name 'forum_forum' forums_data_table = table_name 'forum_forumfield' results = mysql_query(" SELECT f.fid id, f.fup parent_id, f.name, f.type type, f.status status, f.displayorder position, - d.description description + d.description description, d.rules rules, d.icon, d.extra extra FROM #{forums_table} f - JOIN #{forums_data_table} d ON f.fid = d.fid + LEFT JOIN #{forums_data_table} d USING(fid) ORDER BY parent_id ASC, id ASC ") max_position = Category.all.max_by(&:position).position create_categories(results) do |row| - next if row['type'] == 'group' || row['status'].to_i == 3 + next if row['type'] == 'group' or row['status'] == 2 # or row['status'].to_i == 3 # 如果不想导入群组,取消注释 + extra = PHP.unserialize(row['extra']) if !row['extra'].blank? + if extra and !extra["namecolor"].blank? + color = extra["namecolor"][1,6] + end Category.all.max_by(&:position).position + h = { id: row['id'], name: row['name'], description: row['description'], - position: row['position'].to_i + max_position + position: row['position'].to_i + max_position, + color: color, + suppress_from_homepage: (row['status'] == 0 or row['status'] == 3), + post_create_action: lambda do |category| + if slug = @category_slug[row['id']] + category.update(slug: slug) + end + + raw = process_discuzx_post(row['rules'], nil) + if @bbcode_to_md + raw = raw.bbcode_to_md(false) rescue raw + end + category.topic.posts.first.update_attribute(:raw, raw) + if !row['icon'].empty? + upload = create_upload(Discourse::SYSTEM_USER_ID, File.join(DISCUZX_BASE_DIR, ATTACHMENT_DIR, '../common', row['icon']), File.basename(row['icon'])) + if upload + category.logo_url = upload.url + # FIXME: I don't know how to get '/shared' by script. May change to Rails.root + category.color = Miro::DominantColors.new(File.join('/shared', category.logo_url)).to_hex.first[1,6] if !color + category.save! + end + end + category + end } if row['parent_id'].to_i > 0 h[:parent_category_id] = category_id_from_imported_category_id(row['parent_id']) @@ -181,6 +306,7 @@ class ImportScripts::DiscuzX < ImportScripts::Base def import_posts puts "", "creating topics and posts" + users_table = table_name 'common_member' posts_table = table_name 'forum_post' topics_table = table_name 'forum_thread' @@ -195,16 +321,18 @@ class ImportScripts::DiscuzX < ImportScripts::Base p.authorid user_id, p.message raw, p.dateline post_time, - p.first is_first_post, - p.invisible status - FROM #{posts_table} p, - #{topics_table} t - WHERE p.tid = t.tid + p2.pid first_id, + p.invisible status, + t.special special + FROM #{posts_table} p + JOIN #{posts_table} p2 ON p2.first AND p2.tid = p.tid + JOIN #{topics_table} t ON t.tid = p.tid + where t.tid < 10000 ORDER BY id ASC, topic_id ASC LIMIT #{BATCH_SIZE} OFFSET #{offset}; ") - + # u.status != -1 AND u.groupid != 4 AND u.groupid != 5 用户未被锁定、禁访或禁言。在现实中的 Discuz 论坛,禁止的用户通常是广告机或驱逐的用户,这些不需要导入。 break if results.size < 1 next if all_records_exist? :posts, results.map {|p| p["id"].to_i} @@ -218,40 +346,95 @@ class ImportScripts::DiscuzX < ImportScripts::Base mapped[:raw] = process_discuzx_post(m['raw'], m['id']) mapped[:created_at] = Time.zone.at(m['post_time']) - if m['is_first_post'] == 1 + if m['id'] == m['first_id'] mapped[:category] = category_id_from_imported_category_id(m['category_id']) mapped[:title] = CGI.unescapeHTML(m['title']) - @first_post_id_by_topic_id[m['topic_id']] = m['id'] + + if m['special'] == 1 + results = mysql_query(" + SELECT multiple, maxchoices + FROM #{table_name 'forum_poll'} + WHERE tid = #{m['topic_id']}") + poll = results.first || {} + results = mysql_query(" + SELECT polloption + FROM #{table_name 'forum_polloption'} + WHERE tid = #{m['topic_id']} + ORDER BY displayorder") + if results.empty? + puts "WARNING: can't find poll options for topic #{m['topic_id']}, skip poll" + else + mapped[:raw].prepend "[poll#{poll['multiple'] ? ' type=multiple' : ''}#{poll['maxchoices'] > 0 ? " max=#{poll['maxchoices']}" : ''}]\n#{results.map{|option|'- ' + option['polloption']}.join("\n")}\n[/poll]\n" + end + end else - parent = topic_lookup_from_imported_post_id(@first_post_id_by_topic_id[m['topic_id']]) + parent = topic_lookup_from_imported_post_id(m['first_id']) if parent mapped[:topic_id] = parent[:topic_id] - post_id = post_id_from_imported_post_id(find_post_id_by_quote_number(m['raw']).to_i) - if (post = Post.find_by(id: post_id)) - mapped[:reply_to_post_number] = post.post_number + reply_post_import_id = find_post_id_by_quote_number(m['raw']) + if reply_post_import_id + post_id = post_id_from_imported_post_id(reply_post_import_id.to_i) + if (post = Post.find_by(id: post_id)) + if post.topic_id == mapped[:topic_id] + mapped[:reply_to_post_number] = post.post_number + else + puts "post #{m['id']} reply to another topic, skip reply" + end + else + puts "post #{m['id']} reply to not exists post #{reply_post_import_id}, skip reply" + end end else puts "Parent topic #{m['topic_id']} doesn't exist. Skipping #{m['id']}: #{m['title'][0..40]}" skip = true end + end - if [-5, -3, -1].include? m['status'] || mapped[:raw].blank? + if m['status'] & 1 == 1 || mapped[:raw].blank? mapped[:post_create_action] = lambda do |post| PostDestroyer.new(Discourse.system_user, post).perform_delete end - elsif m['status'] == -2# waiting for approve + elsif (m['status'] & 2) >> 1 == 1 # waiting for approve mapped[:post_create_action] = lambda do |post| PostAction.act(Discourse.system_user, post, 6, {take_action: false}) end end - skip ? nil : mapped end end end + def import_bookmarks + puts '', 'creating bookmarks' + favorites_table = table_name 'home_favorite' + posts_table = table_name 'forum_post' + + total_count = mysql_query("SELECT count(*) count FROM #{favorites_table} WHERE idtype = 'tid'").first['count'] + batches(BATCH_SIZE) do |offset| + results = mysql_query(" + SELECT p.pid post_id, f.uid user_id + FROM #{favorites_table} f + JOIN #{posts_table} p ON f.id = p.tid + WHERE f.idtype = 'tid' AND p.first + LIMIT #{BATCH_SIZE} + OFFSET #{offset};") + + break if results.size < 1 + + # next if all_records_exist? + + create_bookmarks(results, total: total_count, offset: offset) do |row| + { + user_id: row['user_id'], + post_id: row['post_id'] + } + end + end + end + + def import_private_messages puts '', 'creating private messages' @@ -285,7 +468,7 @@ class ImportScripts::DiscuzX < ImportScripts::Base break if results.size < 1 - next if all_records_exist? :posts, results.map {|m| "pm:#{m['id']}"} + # next if all_records_exist? :posts, results.map {|m| "pm:#{m['id']}"} create_posts(results, total: total_count, offset: offset) do |m| skip = false @@ -349,8 +532,9 @@ class ImportScripts::DiscuzX < ImportScripts::Base result.first['id'].to_s == pm_id.to_s end - def process_discuzx_post(raw, import_id) + def process_and_upload_inline_images(raw) inline_image_regex = /\[img\]([\s\S]*?)\[\/img\]/ + s = raw.dup s.gsub!(inline_image_regex) do |d| @@ -361,14 +545,65 @@ class ImportScripts::DiscuzX < ImportScripts::Base upload ? html_for_upload(upload, filename) : nil end + end + + def process_discuzx_post(raw, import_id) + # raw = process_and_upload_inline_images(raw) + s = raw.dup + # Strip the quote # [quote] quotation includes the topic which is the same as reply to in Discourse # We get the pid to find the post number the post reply to. So it can be stripped - s = s.gsub(/\[quote\][\s\S]*?\[\/quote\]/i, '').strip s = s.gsub(/\[b\]回复 \[url=forum.php\?mod=redirect&goto=findpost&pid=\d+&ptid=\d+\].* 的帖子\[\/url\]\[\/b\]/i, '').strip + s = s.gsub(/\[b\]回复 \[url=https?:\/\/#{ORIGINAL_SITE_PREFIX}\/redirect.php\?goto=findpost&pid=\d+&ptid=\d+\].*?\[\/url\].*?\[\/b\]/i, '').strip - # Convert image bbcode + s.gsub!(/\[quote\](.*)?\[\/quote\]/im) do |matched| + content = $1 + post_import_id = find_post_id_by_quote_number(content) + if post_import_id + post_id = post_id_from_imported_post_id(post_import_id.to_i) + if (post = Post.find_by(id: post_id)) + "[quote=\"#{post.user.username}\", post: #{post.post_number}, topic: #{post.topic_id}]\n#{content}\n[/quote]" + else + puts "post #{import_id} quote to not exists post #{post_import_id}, skip reply" + matched[0] + end + else + matched[0] + end + end + + s.gsub!(/\[size=2\]\[color=#999999\].*? 发表于 [\d\-\: ]*\[\/color\] \[url=forum.php\?mod=redirect&goto=findpost&pid=\d+&ptid=\d+\].*?\[\/url\]\[\/size\]/i, '') + s.gsub!(/\[size=2\]\[color=#999999\].*? 发表于 [\d\-\: ]*\[\/color\] \[url=https?:\/\/#{ORIGINAL_SITE_PREFIX}\/redirect.php\?goto=findpost&pid=\d+&ptid=\d+\].*?\[\/url\]\[\/size\]/i, '') + + # convert quote + s.gsub!(/\[quote\](.*?)\[\/quote\]/m) { "\n" + ($1.strip).gsub(/^/, '> ') + "\n" } + + # truncate line space, preventing line starting with many blanks to be parsed as code blocks + s.gsub!(/^ {4,}/, ' ') + + # TODO: Much better to use bbcode-to-md gem + # Convert image bbcode with width and height + s.gsub!(/\[img[^\]]*\]https?:\/\/#{ORIGINAL_SITE_PREFIX}\/(.*)\[\/img\]/i, '[x-attach]\1[/x-attach]') # dont convert attachment + s.gsub!(/]*src="https?:\/\/#{ORIGINAL_SITE_PREFIX}\/(.*)".*?>/i, '[x-attach]\1[/x-attach]') # dont convert attachment + s.gsub!(/\[img[^\]]*\]https?:\/\/www\.touhou\.cc\/blog\/(.*)\[\/img\]/i, '[x-attach]../blog/\1[/x-attach]') # 私货 + s.gsub!(/\[img[^\]]*\]https?:\/\/www\.touhou\.cc\/ucenter\/avatar.php\?uid=(\d+)[^\]]*\[\/img\]/i) { "[x-attach]#{discuzx_avatar_fullpath($1,false)[0]}[/x-attach]" } # 私货 s.gsub!(/\[img=(\d+),(\d+)\]([^\]]*)\[\/img\]/i, '') + s.gsub!(/\[img\]([^\]]*)\[\/img\]/i, '') + + s.gsub!(/\[qq\]([^\]]*)\[\/qq\]/i, 'QQ 交谈') + + s.gsub!(/\[email\]([^\]]*)\[\/email\]/i, '[url=mailto:\1]\1[/url]') # bbcode-to-md can convert it + s.gsub!(/\[s\]([^\]]*)\[\/s\]/i, '\1') + s.gsub!(/\[sup\]([^\]]*)\[\/sup\]/i, '\1') + s.gsub!(/\[sub\]([^\]]*)\[\/sub\]/i, '\1') + s.gsub!(/\[hr\]/i, "\n---\n") + + # remove the media tag + s.gsub!(/\[\/?media[^\]]*\]/i, "\n") + s.gsub!(/\[\/?flash[^\]]*\]/i, "\n") + s.gsub!(/\[\/?audio[^\]]*\]/i, "\n") + s.gsub!(/\[\/?video[^\]]*\]/i, "\n") # Remove the font, p and backcolor tag # Discourse doesn't support the font tag @@ -390,11 +625,14 @@ class ImportScripts::DiscuzX < ImportScripts::Base # Remove the hide tag s.gsub!(/\[\/?hide\]/i, '') + s.gsub!(/\[\/?free[^\]]*\]/i, "\n") # Remove the align tag # still don't know what it is - s.gsub!(/\[align=[^\]]*?\]/i, '') + s.gsub!(/\[align=[^\]]*?\]/i, "\n") s.gsub!(/\[\/align\]/i, "\n") + s.gsub!(/\[float=[^\]]*?\]/i, "\n") + s.gsub!(/\[\/float\]/i, "\n") # Convert code s.gsub!(/\[\/?code\]/i, "\n```\n") @@ -424,39 +662,65 @@ class ImportScripts::DiscuzX < ImportScripts::Base # [url][b]text[/b][/url] to **[url]text[/url]** s.gsub!(/(\[url=[^\[\]]*?\])\[b\](\S*)\[\/b\](\[\/url\])/, '**\1\2\3**') - s.gsub!(internal_url_regexp) do |discuzx_link| - replace_internal_link(discuzx_link, $1) + @internal_url_regexps.each do |internal_url_regexp| + s.gsub!(internal_url_regexp) do |discuzx_link| + replace_internal_link(discuzx_link, ($~[:tid].to_i rescue nil), ($~[:pid].to_i rescue nil), ($~[:fid].to_i rescue nil), ($~[:action] rescue nil)) + end end # @someone without the url s.gsub!(/@\[url=[^\[\]]*?\](\S*)\[\/url\]/i, '@\1') + s.scan(/http(?:s)?:\/\/#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}\/[^\[\]\s]*/) {|link|puts "WARNING: post #{import_id} can't replace internal url #{link}"} + s.strip end - def replace_internal_link(discuzx_link, import_topic_id) - results = mysql_query("SELECT pid - FROM #{table_name 'forum_post'} - WHERE tid = #{import_topic_id} - ORDER BY pid ASC - LIMIT 1") - - return discuzx_link unless results.size > 0 - - linked_topic_id = results.first['pid'] - lookup = topic_lookup_from_imported_post_id(linked_topic_id) - - return discuzx_link unless lookup - - if (t = Topic.find_by(id: lookup[:topic_id])) - "#{NEW_SITE_PREFIX}/t/#{t.slug}/#{t.id}" - else - discuzx_link + def replace_internal_link(discuzx_link, import_topic_id, import_post_id, import_category_id, action) + if import_post_id + post_id = post_id_from_imported_post_id import_post_id + if post_id + post = Post.find post_id + return post.full_url if post + end end - end - def internal_url_regexp - @internal_url_regexp ||= Regexp.new("http(?:s)?://#{ORIGINAL_SITE_PREFIX.gsub('.', '\.')}/forum\\.php\\?mod=viewthread&tid=(\\d+)(?:[^\\]\\[]*)") + if import_topic_id + + results = mysql_query("SELECT pid + FROM #{table_name 'forum_post'} + WHERE tid = #{import_topic_id} AND first + LIMIT 1") + + return discuzx_link unless results.size > 0 + + linked_post_id = results.first['pid'] + lookup = topic_lookup_from_imported_post_id(linked_post_id) + + if lookup + return "#{NEW_SITE_PREFIX}#{lookup[:url]}" + else + return discuzx_link + end + + end + + if import_category_id + category_id = category_id_from_imported_category_id import_category_id + if category_id + category = Category.find category_id + return category.url if category + end + end + + case action + when 'index' + return "#{NEW_SITE_PREFIX}/" + when 'stat', 'stats', 'ranklist' + return "#{NEW_SITE_PREFIX}/users" + end + + discuzx_link end def pm_url_regexp @@ -470,8 +734,7 @@ class ImportScripts::DiscuzX < ImportScripts::Base SiteSetting.authorized_extensions = setting if setting != SiteSetting.authorized_extensions attachment_regex = /\[attach\](\d+)\[\/attach\]/ - - user = Discourse.system_user + attachment_link_regex = /\[x-attach\](.+)\[\/x-attach\]/ current_count = 0 total_count = mysql_query("SELECT count(*) count FROM #{table_name 'forum_post'};").first['count'] @@ -482,13 +745,20 @@ class ImportScripts::DiscuzX < ImportScripts::Base puts '', "Importing attachments...", '' Post.find_each do |post| + next unless post.custom_fields['import_id'] == post.custom_fields['import_id'].to_i.to_s + + user = post.user + current_count += 1 print_status current_count, total_count new_raw = post.raw.dup + + inline_attachments = [] + new_raw.gsub!(attachment_regex) do |s| - matches = attachment_regex.match(s) - attachment_id = matches[1] + attachment_id = $1.to_i + inline_attachments.push attachment_id upload, filename = find_upload(user, post, attachment_id) unless upload @@ -498,6 +768,41 @@ class ImportScripts::DiscuzX < ImportScripts::Base html_for_upload(upload, filename) end + new_raw.gsub!(attachment_link_regex) do |s| + attachment_file = $1 + + filename = File.basename(attachment_file) + upload = create_upload(user.id, File.join(DISCUZX_BASE_DIR, attachment_file), filename) + unless upload + fail_count += 1 + next + end + + html_for_upload(upload, filename) + end + + sql = "SELECT aid + FROM #{table_name 'forum_attachment'} + WHERE pid = #{post.custom_fields['import_id']}" + if !inline_attachments.empty? + sql << " AND aid NOT IN (#{inline_attachments.join(',')})" + end + + results = mysql_query(sql) + + results.each do |attachment| + attachment_id = attachment['aid'] + upload, filename = find_upload(user, post, attachment_id) + unless upload + fail_count += 1 + next + end + html = html_for_upload(upload, filename) + unless new_raw.include? html + new_raw << "\n" + new_raw << html + end + end if new_raw != post.raw PostRevisor.new(post).revise!(post.user, { raw: new_raw }, { bypass_bump: true, edit_reason: '从 Discuz 中导入附件' }) @@ -513,7 +818,7 @@ class ImportScripts::DiscuzX < ImportScripts::Base end # Create the full path to the discuz avatar specified from user id - def discuzx_avatar_fullpath(user_id) + def discuzx_avatar_fullpath(user_id, absolute=true) padded_id = user_id.to_s.rjust(9, '0') part_1 = padded_id[0..2] @@ -522,16 +827,23 @@ class ImportScripts::DiscuzX < ImportScripts::Base part_4 = padded_id[-2..-1] file_name = "#{part_4}_avatar_big.jpg" - return File.join(DISCUZX_BASE_DIR, AVATAR_DIR, part_1, part_2, part_3, file_name), file_name + if absolute + return File.join(DISCUZX_BASE_DIR, AVATAR_DIR, part_1, part_2, part_3, file_name), file_name + else + return File.join(AVATAR_DIR, part_1, part_2, part_3, file_name), file_name + end end # post id is in the quote block def find_post_id_by_quote_number(raw) - s = raw.dup - quote_reply = s.match(/\[quote\][\S\s]*pid=(\d+)[\S\s]*\[\/quote\]/) - reply = s.match(/url=forum.php\?mod=redirect&goto=findpost&pid=(\d+)&ptid=\d+/) - - quote_reply ? quote_reply[1] : (reply ? reply[1] : nil) + case raw + when /\[url=forum.php\?mod=redirect&goto=findpost&pid=(\d+)&ptid=\d+\]/ #standard + $1 + when /\[url=https?:\/\/#{ORIGINAL_SITE_PREFIX}\/redirect.php\?goto=findpost&pid=(\d+)&ptid=\d+\]/ # old discuz 7 format + $1 + when /\[quote\][\S\s]*pid=(\d+)[\S\s]*\[\/quote\]/ # quote + $1 + end end # for some reason, discuz inlined some png file @@ -632,6 +944,10 @@ class ImportScripts::DiscuzX < ImportScripts::Base return nil end + def first_exists(*items) + items.find{|item|!item.blank?} || '' + end + def mysql_query(sql) @client.query(sql, cache_rows: false) end diff --git a/script/import_scripts/disqus.rb b/script/import_scripts/disqus.rb index be2418dc8bc..06d9af1a1fb 100644 --- a/script/import_scripts/disqus.rb +++ b/script/import_scripts/disqus.rb @@ -151,8 +151,7 @@ class DisqusSAX < Nokogiri::XML::SAX::Document @threads.delete(id) else # Normalize titles - t[:title].gsub!(@strip, '') if @strip.present? - t[:title].strip! + t[:title] = [:title].gsub(@strip, '').strip if @strip.present? end end diff --git a/script/import_scripts/jive.rb b/script/import_scripts/jive.rb new file mode 100644 index 00000000000..c64e87a66bb --- /dev/null +++ b/script/import_scripts/jive.rb @@ -0,0 +1,408 @@ +# Jive importer +require 'nokogiri' +require 'csv' +require File.expand_path(File.dirname(__FILE__) + "/base.rb") + +class ImportScripts::Jive < ImportScripts::Base + + BATCH_SIZE = 1000 + CATEGORY_IDS = [2023,2003,2004,2042,2036,2029] # categories that should be imported + + def initialize(path) + @path = path + super() + @bbcode_to_md = true + + puts "loading post mappings..." + @post_number_map = {} + Post.pluck(:id, :post_number).each do |post_id, post_number| + @post_number_map[post_id] = post_number + end + end + + def created_post(post) + @post_number_map[post.id] = post.post_number + super + end + + def execute + import_users + import_groups + import_group_members + import_categories + import_posts + + # Topic.update_all(closed: true) + end + + class RowResolver + def load(row) + @row = row + end + + def self.create(cols) + Class.new(RowResolver).new(cols) + end + + def initialize(cols) + cols.each_with_index do |col,idx| + self.class.send(:define_method, col) do + @row[idx] + end + end + end + end + + def load_user_batch!(users, offset, total) + if users.length > 0 + create_users(users, offset: offset, total: total) do |user| + user + end + users.clear + end + end + + def csv_parse(name) + filename = "#{@path}/#{name}.csv" + first = true + row = nil + + current_row = ""; + double_quote_count = 0 + + File.open(filename).each_line do |line| + + line.gsub!(/\\(.{1})/){|m| m[-1] == '"'? '""': m[-1]} + line.strip! + + current_row << "\n" unless current_row.empty? + current_row << line + + double_quote_count += line.scan('"').count + + if double_quote_count % 2 == 1 + next + end + + raw = begin + CSV.parse(current_row) + rescue CSV::MalformedCSVError => e + puts e.message + puts "*" * 100 + puts "Bad row skipped, line is: #{line}" + puts + puts current_row + puts + puts "double quote count is : #{double_quote_count}" + puts "*" * 100 + + current_row = "" + double_quote_count = 0 + next + end[0] + + if first + row = RowResolver.create(raw) + + current_row = "" + double_quote_count = 0 + first = false + next + end + + row.load(raw) + + yield row + + current_row = "" + double_quote_count = 0 + end + end + + def total_rows(table) + File.foreach("#{@path}/#{table}.csv").inject(0) {|c, line| c+1} - 1 + end + + def import_groups + puts "", "importing groups..." + + rows = [] + csv_parse("groups") do |row| + rows << {id: row.groupid, name: row.name} + end + + create_groups(rows) do |row| + row + end + end + + def import_users + puts "", "creating users" + + count = 0 + users = [] + + total = total_rows("users") + + csv_parse("users") do |row| + + id = row.userid + + email = "#{row.email}" + + # fake it + if row.email.blank? || row.email !~ /@/ + email = SecureRandom.hex << "@domain.com" + end + + name = "#{row.firstname} #{row.lastname}" + username = row.username + created_at = DateTime.parse(row.creationdate) + last_seen_at = DateTime.parse(row.lastloggedin) + is_activated = row.userenabled + + username = name if username == "NULL" + username = email.split("@")[0] if username.blank? + name = email.split("@")[0] if name.blank? + + users << { + id: id, + email: email, + name: name, + username: username, + created_at: created_at, + last_seen_at: last_seen_at, + active: is_activated.to_i == 1, + approved: true + } + + count += 1 + if count % BATCH_SIZE == 0 + load_user_batch! users, count - users.length, total + end + + end + + load_user_batch! users, count, total + end + + def import_group_members + puts "", "importing group members..." + + csv_parse("group_members") do |row| + user_id = user_id_from_imported_user_id(row.userid) + group_id = group_id_from_imported_group_id(row.groupid) + + if user_id && group_id + GroupUser.find_or_create_by(user_id: user_id, group_id: group_id) + end + end + end + + def import_categories + rows = [] + + csv_parse("communities") do |row| + next unless CATEGORY_IDS.include?(row.communityid.to_i) + rows << {id: row.communityid, name: "#{row.name} (#{row.communityid})"} + end + + create_categories(rows) do |row| + row + end + end + + def normalize_raw!(raw) + raw = raw.dup + raw = raw[5..-6] + + doc = Nokogiri::HTML.fragment(raw) + doc.css('img').each do |img| + img.remove if img['class'] == "jive-image" + end + + raw = doc.to_html + raw = raw[4..-1] + + raw + end + + def import_post_batch!(posts, topics, offset, total) + create_posts(posts, total: total, offset: offset) do |post| + + mapped = {} + + mapped[:id] = post[:id] + mapped[:user_id] = user_id_from_imported_user_id(post[:user_id]) || -1 + mapped[:raw] = post[:body] + mapped[:created_at] = post[:created_at] + + topic = topics[post[:topic_id]] + + unless topic + p "MISSING TOPIC #{post[:topic_id]}" + p post + next + end + + unless topic[:post_id] + mapped[:category] = category_id_from_imported_category_id(topic[:category_id]) + mapped[:title] = post[:title] + topic[:post_id] = post[:id] + else + parent = topic_lookup_from_imported_post_id(topic[:post_id]) + next unless parent + + mapped[:topic_id] = parent[:topic_id] + + reply_to_post_id = post_id_from_imported_post_id(post[:reply_id]) + if reply_to_post_id + reply_to_post_number = @post_number_map[reply_to_post_id] + if reply_to_post_number && reply_to_post_number > 1 + mapped[:reply_to_post_number] = reply_to_post_number + end + end + end + + next if topic[:deleted] or post[:deleted] + + mapped + end + + posts.clear + end + + def import_posts + puts "", "creating topics and posts" + + topic_map = {} + thread_map = {} + + csv_parse("messages") do |thread| + + next unless CATEGORY_IDS.include?(thread.containerid.to_i) + + if !thread.parentmessageid + # topic + + thread_map[thread.threadid] = thread.messageid + + #IMAGE UPLOADER + if thread.imagecount + Dir.foreach("/var/www/discourse/script/import_scripts/jive/img/#{thread.messageid}") do |item| + next if item == '.' or item == '..' or item == '.DS_Store' + photo_path = "/var/www/discourse/script/import_scripts/jive/img/#{thread.messageid}/#{item}" + upload = create_upload(thread.userid, photo_path, File.basename(photo_path)) + if upload.persisted? + puts "Image upload is successful for #{photo_path}, new path is #{upload.url}!" + thread.body.gsub!(item,upload.url) + else + puts "Error: Image upload is not successful for #{photo_path}!" + end + end + end + + #ATTACHMENT UPLOADER + if thread.attachmentcount + Dir.foreach("/var/www/discourse/script/import_scripts/jive/attach/#{thread.messageid}") do |item| + next if item == '.' or item == '..' or item == '.DS_Store' + attach_path = "/var/www/discourse/script/import_scripts/jive/attach/#{thread.messageid}/#{item}" + upload = create_upload(thread.userid, attach_path, File.basename(attach_path)) + if upload.persisted? + puts "Attachment upload is successful for #{attach_path}, new path is #{upload.url}!" + thread.body.gsub!(item,upload.url) + thread.body << "

    #{attachment_html(upload,item)}" + else + puts "Error: Attachment upload is not successful for #{attach_path}!" + end + end + end + + topic_map[thread.messageid] = { + id: thread.messageid, + topic_id: thread.messageid, + category_id: thread.containerid, + user_id: thread.userid, + title: thread.subject, + body: normalize_raw!(thread.body || thread.subject || ""), + created_at: DateTime.parse(thread.creationdate), + } + + end + end + + total = total_rows("messages") + posts = [] + count = 0 + + topic_map.each do |_, topic| + posts << topic if topic[:body] + count+=1 + end + + csv_parse("messages") do |thread| + # post + + next unless CATEGORY_IDS.include?(thread.containerid.to_i) + + if thread.parentmessageid + + #IMAGE UPLOADER + if thread.imagecount + Dir.foreach("/var/www/discourse/script/import_scripts/jive/img/#{thread.messageid}") do |item| + next if item == '.' or item == '..' or item == '.DS_Store' + photo_path = "/var/www/discourse/script/import_scripts/jive/img/#{thread.messageid}/#{item}" + upload = create_upload(thread.userid, photo_path, File.basename(photo_path)) + if upload.persisted? + puts "Image upload is successful for #{photo_path}, new path is #{upload.url}!" + thread.body.gsub!(item,upload.url) + else + puts "Error: Image upload is not successful for #{photo_path}!" + end + end + end + + #ATTACHMENT UPLOADER + if thread.attachmentcount + Dir.foreach("/var/www/discourse/script/import_scripts/jive/attach/#{thread.messageid}") do |item| + next if item == '.' or item == '..' or item == '.DS_Store' + attach_path = "/var/www/discourse/script/import_scripts/jive/attach/#{thread.messageid}/#{item}" + upload = create_upload(thread.userid, attach_path, File.basename(attach_path)) + if upload.persisted? + puts "Attachment upload is successful for #{attach_path}, new path is #{upload.url}!" + thread.body.gsub!(item,upload.url) + thread.body << "

    #{attachment_html(upload,item)}" + else + puts "Error: Attachment upload is not successful for #{attach_path}!" + end + end + end + + row = { + id: thread.messageid, + topic_id: thread_map["#{thread.threadid}"], + user_id: thread.userid, + title: thread.subject, + body: normalize_raw!(thread.body), + created_at: DateTime.parse(thread.creationdate) + } + posts << row + count+=1 + + if posts.length > 0 && posts.length % BATCH_SIZE == 0 + import_post_batch!(posts, topic_map, count - posts.length, total) + end + end + end + + import_post_batch!(posts, topic_map, count - posts.length, total) if posts.length > 0 + end + +end + +unless ARGV[0] && Dir.exist?(ARGV[0]) + puts "", "Usage:", "", "bundle exec ruby script/import_scripts/jive.rb DIRNAME", "" + exit 1 +end + +ImportScripts::Jive.new(ARGV[0]).perform diff --git a/script/import_scripts/kunena3.rb b/script/import_scripts/kunena3.rb index 49b3f24e917..4c0042ff012 100644 --- a/script/import_scripts/kunena3.rb +++ b/script/import_scripts/kunena3.rb @@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + "/base.rb") class ImportScripts::Kunena < ImportScripts::Base - KUNENA_DB = "accentral_jos1" + KUNENA_DB = "DATABASENAME" def initialize super @@ -11,9 +11,9 @@ class ImportScripts::Kunena < ImportScripts::Base @users = {} @client = Mysql2::Client.new( - host: "aircadetcentral.net", - username: "accentral_jos1", - password: "Lc3bwPL7iEY(8", + host: "HOSTNAME.COM", + username: "DATABASE_USER_NAME", + password: "DATABASE_USER_PASSWORD", database: KUNENA_DB ) end @@ -48,7 +48,7 @@ class ImportScripts::Kunena < ImportScripts::Base import_posts begin - create_admin(email: 'dave@ricey.co', username: UserNameSuggester.suggest('DJRice')) + create_admin(email: 'CHANGE@ME.COM', username: UserNameSuggester.suggest('CHAMGEME')) rescue => e puts '', "Failed to create admin user" puts e.message diff --git a/script/import_scripts/lithium.rb b/script/import_scripts/lithium.rb index 795f04f366a..1591cb8f2b6 100644 --- a/script/import_scripts/lithium.rb +++ b/script/import_scripts/lithium.rb @@ -54,6 +54,7 @@ class ImportScripts::Lithium < ImportScripts::Base def execute SiteSetting.allow_html_tables = true + @max_start_id = Post.maximum(:id) import_categories import_users @@ -307,11 +308,12 @@ class ImportScripts::Lithium < ImportScripts::Base end def import_posts - puts "", "importing posts..." post_count = mysql_query("SELECT COUNT(*) count FROM message2 WHERE id <> root_id").first["count"] + puts "", "importing posts... (#{post_count})" + batches(BATCH_SIZE) do |offset| posts = mysql_query <<-SQL SELECT id, body, deleted, user_id, @@ -629,7 +631,6 @@ class ImportScripts::Lithium < ImportScripts::Base import_mode: true } - unless topic_id msg[:title] = @htmlentities.decode(topic["subject"]).strip[0...255] msg[:archetype] = Archetype.private_message @@ -739,15 +740,26 @@ SQL def post_process_posts puts "", "Postprocessing posts..." + current = 0 max = Post.count - Post.all.find_each do |post| + mysql_query("create index idxUniqueId on message2(unique_id)") rescue nil + + Post.where('id > ?', @max_start_id).find_each do |post| begin - new_raw = postprocess_post_raw(post.raw, post.user_id) + id = post.custom_fields["import_unique_id"] + next unless id + raw = mysql_query("select body from message2 where unique_id = '#{id}'").first['body'] + unless raw + puts "Missing raw for post: #{post.id}" + next + end + new_raw = postprocess_post_raw(raw, post.user_id) post.raw = new_raw post.save rescue PrettyText::JavaScriptError + puts "GOT A JS error on post: #{post.id}" nil ensure print_status(current += 1, max) @@ -825,7 +837,7 @@ SQL end def mysql_query(sql) - @client.query(sql, cache_rows: false) + @client.query(sql, cache_rows: true) end end diff --git a/script/import_scripts/mbox.rb b/script/import_scripts/mbox.rb index d47b5553fc7..cf50d1aed91 100755 --- a/script/import_scripts/mbox.rb +++ b/script/import_scripts/mbox.rb @@ -37,6 +37,7 @@ class ImportScripts::Mbox < ImportScripts::Base topics = [] topic_lookup = {} + topic_titles = {} replies = [] all_messages do |mail, filename| @@ -44,21 +45,84 @@ class ImportScripts::Mbox < ImportScripts::Base msg_id = mail['Message-ID'].to_s reply_to = mail['In-Reply-To'].to_s + title = clean_title(mail['Subject'].to_s) + date = Time.parse(mail['date'].to_s).to_i if reply_to.present? topic = topic_lookup[reply_to] || reply_to topic_lookup[msg_id] = topic - replies << {id: msg_id, topic: topic, file: filename} + replies << {id: msg_id, topic: topic, file: filename, title: title, date: date} else - topics << {id: msg_id, file: filename} + topics << {id: msg_id, file: filename, title: title, date: date} + topic_titles[title] ||= msg_id end end + replies.sort! {|a, b| a[:date] <=> b[:date]} + topics.sort! {|a, b| a[:date] <=> b[:date]} + + # Replies without parents should be hoisted to topics + to_hoist = [] + replies.each do |r| + to_hoist << r if !topic_lookup[r[:topic]] + end + + to_hoist.each do |h| + replies.delete(h) + topics << {id: h[:id], file: h[:file], title: h[:title], date: h[:date]} + topic_titles[h[:title]] ||= h[:id] + end + + # Topics with duplicate replies should be replies + to_group = [] + topics.each do |t| + first = topic_titles[t[:title]] + to_group << t if first && first != t[:id] + end + + to_group.each do |t| + topics.delete(t) + replies << {id: t[:id], topic: topic_titles[t[:title]], file: t[:file], title: t[:title], date: t[:date]} + end + + replies.sort! {|a, b| a[:date] <=> b[:date]} + topics.sort! {|a, b| a[:date] <=> b[:date]} + + File.write(USER_INDEX_PATH, {users: users}.to_json) File.write(TOPIC_INDEX_PATH, {topics: topics}.to_json) File.write(REPLY_INDEX_PATH, {replies: replies}.to_json) end + def clean_title(title) + #Strip mailing list name from subject + title = title.gsub(/\[[^\]]+\]+/, '').strip + + original_length = title.length + + #Strip Reply prefix from title (Standard and localized) + title = title.gsub(/^Re: */i, '') + title = title.gsub(/^R: */i, '') #Italian + title = title.gsub(/^RIF: */i, '') #Italian + + #Strip Forward prefix from title (Standard and localized) + title = title.gsub(/^Fwd: */i, '') + title = title.gsub(/^I: */i, '') #Italian + + title.strip + + #In case of mixed localized prefixes there could be many of them if the mail client didn't strip the localized ones + if original_length > title.length + clean_title(title) + else + title + end + end + + def clean_raw(raw) + raw.gsub(/-- \nYou received this message because you are subscribed to the Google Groups "[^"]*" group.\nTo unsubscribe from this group and stop receiving emails from it, send an email to [^+@]+\+unsubscribe@googlegroups.com\.\nFor more options, visit https:\/\/groups\.google\.com\/groups\/opt_out\./, '') + end + def import_users puts "", "importing users" @@ -82,11 +146,11 @@ class ImportScripts::Mbox < ImportScripts::Base end def parse_email(msg) - receiver = Email::Receiver.new(msg, skip_sanity_check: true) + receiver = Email::Receiver.new(msg) mail = Mail.read_from_string(msg) mail.body - selected = receiver.select_body(mail) + selected = receiver.select_body selected.force_encoding(selected.encoding).encode("UTF-8") end @@ -100,27 +164,43 @@ class ImportScripts::Mbox < ImportScripts::Base topics = all_topics[offset..offset+BATCH_SIZE-1] break if topics.nil? - next if all_records_exist? :posts, topics.map {|t| t['id'].to_i} + next if all_records_exist? :posts, topics.map {|t| t['id']} create_posts(topics, total: topic_count, offset: offset) do |t| raw_email = File.read(t['file']) - receiver = Email::Receiver.new(raw_email, skip_sanity_check: true) + receiver = Email::Receiver.new(raw_email) mail = Mail.read_from_string(raw_email) mail.body - selected = receiver.select_body(mail) + selected = receiver.select_body next unless selected raw = selected.force_encoding(selected.encoding).encode("UTF-8") - title = mail.subject.gsub(/\[[^\]]+\]+/, '').strip + title = mail.subject + + # import the attachments + mail.attachments.each do |attachment| + tmp = Tempfile.new("discourse-email-attachment") + begin + # read attachment + File.open(tmp.path, "w+b") { |f| f.write attachment.body.decoded } + # create the upload for the user + upload = Upload.create_for(user_id_from_imported_user_id(mail.from.first) || Discourse::SYSTEM_USER_ID, tmp, attachment.filename, tmp.size ) + if upload && upload.errors.empty? + raw << "\n\n#{receiver.attachment_markdown(upload)}\n\n" + end + ensure + tmp.try(:close!) rescue nil + end + end { id: t['id'], - title: title, + title: clean_title(title), user_id: user_id_from_imported_user_id(mail.from.first) || Discourse::SYSTEM_USER_ID, created_at: mail.date, category: CATEGORY_ID, - raw: raw, + raw: clean_raw(raw), cook_method: Post.cook_methods[:email] } end end @@ -129,9 +209,6 @@ class ImportScripts::Mbox < ImportScripts::Base def import_replies puts "", "creating topic replies" - all_topics = ::JSON.parse(File.read(TOPIC_INDEX_PATH))['topics'] - topic_count = all_topics.size - replies = ::JSON.parse(File.read(REPLY_INDEX_PATH))['replies'] post_count = replies.size @@ -139,7 +216,7 @@ class ImportScripts::Mbox < ImportScripts::Base posts = replies[offset..offset+BATCH_SIZE-1] break if posts.nil? - next if all_records_exist? :posts, posts.map {|p| p['id'].to_i} + next if all_records_exist? :posts, posts.map {|p| p['id']} create_posts(posts, total: post_count, offset: offset) do |p| parent_id = p['topic'] @@ -150,18 +227,34 @@ class ImportScripts::Mbox < ImportScripts::Base next unless topic_id raw_email = File.read(p['file']) - receiver = Email::Receiver.new(raw_email, skip_sanity_check: true) + receiver = Email::Receiver.new(raw_email) mail = Mail.read_from_string(raw_email) mail.body - selected = receiver.select_body(mail) + selected = receiver.select_body raw = selected.force_encoding(selected.encoding).encode("UTF-8") + # import the attachments + mail.attachments.each do |attachment| + tmp = Tempfile.new("discourse-email-attachment") + begin + # read attachment + File.open(tmp.path, "w+b") { |f| f.write attachment.body.decoded } + # create the upload for the user + upload = Upload.create_for(user_id_from_imported_user_id(mail.from.first) || Discourse::SYSTEM_USER_ID, tmp, attachment.filename, tmp.size ) + if upload && upload.errors.empty? + raw << "\n\n#{receiver.attachment_markdown(upload)}\n\n" + end + ensure + tmp.try(:close!) rescue nil + end + end + { id: id, topic_id: topic_id, user_id: user_id_from_imported_user_id(mail.from.first) || Discourse::SYSTEM_USER_ID, created_at: mail.date, - raw: raw, + raw: clean_raw(raw), cook_method: Post.cook_methods[:email] } end end diff --git a/script/import_scripts/mybb.rb b/script/import_scripts/mybb.rb index b76e1e0d919..c6d104e28ff 100644 --- a/script/import_scripts/mybb.rb +++ b/script/import_scripts/mybb.rb @@ -2,7 +2,7 @@ require "mysql2" require File.expand_path(File.dirname(__FILE__) + "/base.rb") # Call it like this: -# RAILS_ENV=production bundle exec ruby script/import_scripts/mybb.rb +# RAILS_ENV=production ruby script/import_scripts/mybb.rb class ImportScripts::MyBB < ImportScripts::Base MYBB_DB = "mybb_db" @@ -48,7 +48,7 @@ class ImportScripts::MyBB < ImportScripts::Base break if results.size < 1 - next if all_records_exist? :users, users.map {|u| u["id"].to_i} + next if all_records_exist? :users, results.map {|u| u["id"].to_i} create_users(results, total: total_count, offset: offset) do |user| { id: user['id'], @@ -153,9 +153,42 @@ class ImportScripts::MyBB < ImportScripts::Base puts '', "banned users are not implemented" end + # Discourse usernames don't allow spaces + def convert_username(username, post_id) + count = 0 + username.gsub!(/\s+/) { |a| count += 1; '_' } + # Warn on MyBB bug that places post text in the quote line - http://community.mybb.com/thread-180526.html + if count > 5 + puts "Warning: probably incorrect quote in post #{post_id}" + end + return username + end + + # Take an original post id and return the migrated topic id and post number for it + def post_id_to_post_num_and_topic(quoted_post_id, post_id) + quoted_post_id_from_imported = post_id_from_imported_post_id(quoted_post_id.to_i) + if quoted_post_id_from_imported + begin + post = Post.find(quoted_post_id_from_imported) + return "post:#{post.post_number}, topic:#{post.topic_id}" + rescue + puts "Could not find migrated post #{quoted_post_id_from_imported} quoted by original post #{post_id} as #{quoted_post_id}" + return "" + end + else + puts "Original post #{post_id} quotes nonexistent post #{quoted_post_id}" + return "" + end + end + def process_mybb_post(raw, import_id) s = raw.dup + # convert the quote line + s.gsub!(/\[quote='([^']+)'.*?pid='(\d+).*?\]/) { + "[quote=\"#{convert_username($1, import_id)}, " + post_id_to_post_num_and_topic($2, import_id) + '"]' + } + # :) is encoded as :) s.gsub!(/(?:.*)/, '\1') @@ -187,3 +220,4 @@ class ImportScripts::MyBB < ImportScripts::Base end ImportScripts::MyBB.new.perform + diff --git a/script/import_scripts/nabble.rb b/script/import_scripts/nabble.rb index 78e48497509..ccf8d495ec4 100644 --- a/script/import_scripts/nabble.rb +++ b/script/import_scripts/nabble.rb @@ -1,5 +1,38 @@ require File.expand_path(File.dirname(__FILE__) + "/base.rb") require 'pg' +require_relative 'base/uploader' + +=begin + if you want to create mock users for posts made by anonymous participants, + run the following SQL prior to importing. + +-- first attribute any anonymous posts to existing users (if any) + +UPDATE node +SET owner_id = p.user_id, anonymous_name = NULL +FROM ( SELECT lower(name) AS name, user_id FROM user_ ) p +WHERE p.name = lower(node.anonymous_name) + AND owner_id IS NULL; + +-- then create mock users + +INSERT INTO user_ (email, name, joined, registered) + SELECT lower(anonymous_name) || '@dummy.com', MIN(anonymous_name), MIN(when_created), MIN(when_created) + FROM node + WHERE anonymous_name IS NOT NULL + GROUP BY lower(anonymous_name); + +-- then move these posts to the new users +-- (yes, this is the same query as the first one indeed) + +UPDATE node +SET owner_id = p.user_id, anonymous_name = NULL +FROM ( SELECT lower(name) AS name, user_id FROM user_ ) p +WHERE p.name = lower(node.anonymous_name) + AND owner_id IS NULL; + +=end + class ImportScripts::Nabble < ImportScripts::Base # CHANGE THESE BEFORE RUNNING THE IMPORTER @@ -15,6 +48,7 @@ class ImportScripts::Nabble < ImportScripts::Base @tagmap = [] @td = PG::TextDecoder::TimestampWithTimeZone.new @client = PG.connect(dbname: DB_NAME) + @uploader = ImportScripts::Uploader.new end def execute @@ -42,17 +76,45 @@ class ImportScripts::Nabble < ImportScripts::Base next if all_records_exist? :users, users.map {|u| u["user_id"].to_i} - create_users(users, total: total_count, offset: offset) do |user| + create_users(users, total: total_count, offset: offset) do |row| { - id: user["user_id"], - email: user["email"] || (SecureRandom.hex << "@domain.com"), - created_at: Time.zone.at(@td.decode(user["joined"])), - name: user["name"] + id: row["user_id"], + email: row["email"] || (SecureRandom.hex << "@domain.com"), + created_at: Time.zone.at(@td.decode(row["joined"])), + name: row["name"], + post_create_action: proc do |user| + import_avatar(user, row["user_id"]) + end } end end end + def import_avatar(user, org_id) + filename = 'avatar' + org_id.to_s + path = File.join('/tmp/nab', filename) + res = @client.exec("SELECT content FROM file_avatar WHERE name='avatar100.png' AND user_id = #{org_id} LIMIT 1") + return if res.ntuples() < 1 + + binary = res[0]['content'] + File.open(path, 'wb') { |f| + f.write(PG::Connection.unescape_bytea(binary)) + } + + upload = @uploader.create_upload(user.id, path, filename) + + if upload.persisted? + user.import_mode = false + user.create_user_avatar + user.import_mode = true + user.user_avatar.update(custom_upload_id: upload.id) + user.update(uploaded_avatar_id: upload.id) + else + Rails.logger.error("Could not persist avatar for user #{user.username}") + end + + end + def parse_email(msg) receiver = Email::Receiver.new(msg, skip_sanity_check: true) mail = Mail.read_from_string(msg) @@ -87,6 +149,8 @@ class ImportScripts::Nabble < ImportScripts::Base create_posts(topics, total: topic_count, offset: offset) do |t| raw = body_from(t) next unless raw + raw = process_content(raw) + raw = process_attachments(raw, t['node_id']) { id: t['node_id'], title: t['subject'], @@ -94,7 +158,7 @@ class ImportScripts::Nabble < ImportScripts::Base created_at: Time.zone.at(@td.decode(t["when_created"])), category: CATEGORY_ID, raw: raw, - cook_method: Post.cook_methods[:email] } + cook_method: Post.cook_methods[:regular] } end end end @@ -105,6 +169,60 @@ class ImportScripts::Nabble < ImportScripts::Base puts "Skipped #{p['node_id']}" end + def process_content(txt) + txt.gsub! /\/, '[quote="\1"]' + txt.gsub! /\<\/quote\>/, '[/quote]' + txt.gsub!(/\(.*?)\<\/raw\>/m) do |match| + c = Regexp.last_match[1].indent(4); + "\n#{c}\n" + end + + # lines starting with # are comments, not headings, insert a space to prevent markdown + txt.gsub! /\n#/m, ' #' + + # in the languagetool forum, quite a lot of XML was not marked as raw + # so we treat ... and ... as raw + + # uncomment below if you want to use this + + #txt.gsub!(/(.*?<\/rule>)/m) do |match| + # c = Regexp.last_match[2].indent(4); + # "\n #{c}\n" + #end + #txt.gsub!(/(.*?<\/category>)/m) do |match| + # c = Regexp.last_match[2].indent(4); + # "\n #{c}\n" + #end + txt + end + + def process_attachments(txt, postid) + txt.gsub!(//m) do |match| + basename = Regexp.last_match[1] + fn = File.join('/tmp/nab', basename) + + binary = @client.exec("SELECT content FROM file_node WHERE name='#{basename}' AND node_id = #{postid}")[0]['content'] + File.open(fn, 'wb') { |f| + f.write(PG::Connection.unescape_bytea(binary)) + } + upload = @uploader.create_upload(0, fn, basename) + @uploader.embedded_image_html(upload) + end + + txt.gsub!(/(.*?)<\/nabble_a>/m) do |match| + basename = Regexp.last_match[1] + fn = File.join('/tmp/nab', basename) + + binary = @client.exec("SELECT content FROM file_node WHERE name='#{basename}' AND node_id = #{postid}")[0]['content'] + File.open(fn, 'wb') { |f| + f.write(PG::Connection.unescape_bytea(binary)) + } + upload = @uploader.create_upload(0, fn, basename) + @uploader.attachment_html(upload, basename) + end + txt + end + def import_replies puts "", "creating topic replies" @@ -143,15 +261,31 @@ class ImportScripts::Nabble < ImportScripts::Base raw = body_from(p) next unless raw + raw = process_content(raw) + raw = process_attachments(raw, id) { id: id, topic_id: topic_id, user_id: user_id_from_imported_user_id(p['owner_id']) || Discourse::SYSTEM_USER_ID, created_at: Time.zone.at(@td.decode(p["when_created"])), raw: raw, - cook_method: Post.cook_methods[:email] } + cook_method: Post.cook_methods[:regular] } end end end end +class String + def indent(count, char = ' ') + gsub(/([^\n]*)(\n|$)/) do |match| + last_iteration = ($1 == "" && $2 == "") + line = "" + line << (char * count) unless last_iteration + line << $1 + line << $2 + line + end + end +end + + ImportScripts::Nabble.new.perform diff --git a/script/import_scripts/phorum.rb b/script/import_scripts/phorum.rb new file mode 100644 index 00000000000..1345b008061 --- /dev/null +++ b/script/import_scripts/phorum.rb @@ -0,0 +1,218 @@ +require "mysql2" + +require File.expand_path(File.dirname(__FILE__) + "/base.rb") + +class ImportScripts::Phorum < ImportScripts::Base + + PHORUM_DB = "piwik" + TABLE_PREFIX = "pw_" + BATCH_SIZE = 1000 + + def initialize + super + + @client = Mysql2::Client.new( + host: "localhost", + username: "root", + password: "pa$$word", + database: PHORUM_DB + ) + end + + def execute + import_users + import_categories + import_posts + end + + def import_users + puts '', "creating users" + + total_count = mysql_query("SELECT count(*) count FROM #{TABLE_PREFIX}users;").first['count'] + + batches(BATCH_SIZE) do |offset| + results = mysql_query( + "SELECT user_id id, username, email, real_name name, date_added created_at, + date_last_active last_seen_at, admin + FROM #{TABLE_PREFIX}users + WHERE #{TABLE_PREFIX}users.active = 1 + LIMIT #{BATCH_SIZE} + OFFSET #{offset};") + + break if results.size < 1 + + create_users(results, total: total_count, offset: offset) do |user| + next if user['username'].blank? + { id: user['id'], + email: user['email'], + username: user['username'], + name: user['name'], + created_at: Time.zone.at(user['created_at']), + last_seen_at: Time.zone.at(user['last_seen_at']), + admin: user['admin'] == 1 } + end + end + end + + def import_categories + puts "", "importing categories..." + + categories = mysql_query(" + SELECT forum_id id, name, description, active + FROM #{TABLE_PREFIX}forums + ORDER BY forum_id ASC + ").to_a + + create_categories(categories) do |category| + next if category['active'] == 0 + { + id: category['id'], + name: category["name"], + description: category["description"] + } + end + + # uncomment below lines to create permalink + # categories.each do |category| + # Permalink.create(url: "list.php?#{category['id']}", category_id: category_id_from_imported_category_id(category['id'].to_i)) + # end + end + + def import_posts + puts "", "creating topics and posts" + + total_count = mysql_query("SELECT count(*) count from #{TABLE_PREFIX}messages").first["count"] + + batches(BATCH_SIZE) do |offset| + results = mysql_query(" + SELECT m.message_id id, + m.parent_id, + m.forum_id category_id, + m.subject title, + m.user_id user_id, + m.body raw, + m.closed closed, + m.datestamp created_at + FROM #{TABLE_PREFIX}messages m + ORDER BY m.datestamp + LIMIT #{BATCH_SIZE} + OFFSET #{offset}; + ").to_a + + break if results.size < 1 + + create_posts(results, total: total_count, offset: offset) do |m| + skip = false + mapped = {} + + mapped[:id] = m['id'] + mapped[:user_id] = user_id_from_imported_user_id(m['user_id']) || -1 + mapped[:raw] = process_raw_post(m['raw'], m['id']) + mapped[:created_at] = Time.zone.at(m['created_at']) + + if m['parent_id'] == 0 + mapped[:category] = category_id_from_imported_category_id(m['category_id'].to_i) + mapped[:title] = CGI.unescapeHTML(m['title']) + else + parent = topic_lookup_from_imported_post_id(m['parent_id']) + if parent + mapped[:topic_id] = parent[:topic_id] + else + puts "Parent post #{m['parent_id']} doesn't exist. Skipping #{m["id"]}: #{m["title"][0..40]}" + skip = true + end + end + + skip ? nil : mapped + end + + # uncomment below lines to create permalink + # results.each do |post| + # if post['parent_id'] == 0 + # topic = topic_lookup_from_imported_post_id(post['id'].to_i) + # Permalink.create(url: "read.php?#{post['category_id']},#{post['id']}", topic_id: topic[:topic_id].to_i) + # end + # end + end + + end + + def process_raw_post(raw, import_id) + s = raw.dup + + # :) is encoded as :) + s.gsub!(/]+) \/>/, '\1') + + # Some links look like this: http://www.onegameamonth.com + s.gsub!(/(.+)<\/a>/, '[\2](\1)') + + # Many phpbb bbcode tags have a hash attached to them. Examples: + # [url=https://google.com:1qh1i7ky]click here[/url:1qh1i7ky] + # [quote="cybereality":b0wtlzex]Some text.[/quote:b0wtlzex] + s.gsub!(/:(?:\w{8})\]/, ']') + + # Remove mybb video tags. + s.gsub!(/(^\[video=.*?\])|(\[\/video\]$)/, '') + + s = CGI.unescapeHTML(s) + + # phpBB shortens link text like this, which breaks our markdown processing: + # [http://answers.yahoo.com/question/index ... 223AAkkPli](http://answers.yahoo.com/question/index?qid=20070920134223AAkkPli) + # + # Work around it for now: + s.gsub!(/\[http(s)?:\/\/(www\.)?/, '[') + + # [QUOTE]...[/QUOTE] + s.gsub!(/\[quote\](.+?)\[\/quote\]/im) { "\n> #{$1}\n" } + + # [URL=...]...[/URL] + s.gsub!(/\[url="?(.+?)"?\](.+)\[\/url\]/i) { "[#{$2}](#{$1})" } + + # [IMG]...[/IMG] + s.gsub!(/\[\/?img\]/i, "") + + # convert list tags to ul and list=1 tags to ol + # (basically, we're only missing list=a here...) + s.gsub!(/\[list\](.*?)\[\/list\]/m, '[ul]\1[/ul]') + s.gsub!(/\[list=1\](.*?)\[\/list\]/m, '[ol]\1[/ol]') + # convert *-tags to li-tags so bbcode-to-md can do its magic on phpBB's lists: + s.gsub!(/\[\*\](.*?)\n/, '[li]\1[/li]') + + # [CODE]...[/CODE] + s.gsub!(/\[\/?code\]/i, "\n```\n") + # [HIGHLIGHT]...[/HIGHLIGHT] + s.gsub!(/\[\/?highlight\]/i, "\n```\n") + + # [YOUTUBE][/YOUTUBE] + s.gsub!(/\[youtube\](.+?)\[\/youtube\]/i) { "\nhttps://www.youtube.com/watch?v=#{$1}\n" } + + # [youtube=425,350]id[/youtube] + s.gsub!(/\[youtube="?(.+?)"?\](.+)\[\/youtube\]/i) { "\nhttps://www.youtube.com/watch?v=#{$2}\n" } + + # [MEDIA=youtube]id[/MEDIA] + s.gsub!(/\[MEDIA=youtube\](.+?)\[\/MEDIA\]/i) { "\nhttps://www.youtube.com/watch?v=#{$1}\n" } + + # [ame="youtube_link"]title[/ame] + s.gsub!(/\[ame="?(.+?)"?\](.+)\[\/ame\]/i) { "\n#{$1}\n" } + + # [VIDEO=youtube;]...[/VIDEO] + s.gsub!(/\[video=youtube;([^\]]+)\].*?\[\/video\]/i) { "\nhttps://www.youtube.com/watch?v=#{$1}\n" } + + # [USER=706]@username[/USER] + s.gsub!(/\[user="?(.+?)"?\](.+)\[\/user\]/i) { $2 } + + # Remove the color tag + s.gsub!(/\[color=[#a-z0-9]+\]/i, "") + s.gsub!(/\[\/color\]/i, "") + + s.gsub!(/\[hr\]/i, "
    ") + + s + end + + def mysql_query(sql) + @client.query(sql, cache_rows: false) + end +end + +ImportScripts::Phorum.new.perform diff --git a/script/import_scripts/phpbb3/database/database.rb b/script/import_scripts/phpbb3/database/database.rb index 731f05b8a12..b63d0356331 100644 --- a/script/import_scripts/phpbb3/database/database.rb +++ b/script/import_scripts/phpbb3/database/database.rb @@ -34,6 +34,7 @@ module ImportScripts::PhpBB3 def create_database_client Mysql2::Client.new( host: @database_settings.host, + port: @database_settings.port, username: @database_settings.username, password: @database_settings.password, database: @database_settings.schema diff --git a/script/import_scripts/phpbb3/database/database_3_0.rb b/script/import_scripts/phpbb3/database/database_3_0.rb index e06d8f7ba5f..b25395abad2 100644 --- a/script/import_scripts/phpbb3/database/database_3_0.rb +++ b/script/import_scripts/phpbb3/database/database_3_0.rb @@ -86,7 +86,7 @@ module ImportScripts::PhpBB3 end def get_first_post_id(topic_id) - query(<<-SQL).first[:topic_first_post_id] + query(<<-SQL).try(:first).try(:[], :topic_first_post_id) SELECT topic_first_post_id FROM #{@table_prefix}_topics WHERE topic_id = #{topic_id} diff --git a/script/import_scripts/phpbb3/database/database_3_1.rb b/script/import_scripts/phpbb3/database/database_3_1.rb index f51f1b5a4c7..2dfc5054a8a 100644 --- a/script/import_scripts/phpbb3/database/database_3_1.rb +++ b/script/import_scripts/phpbb3/database/database_3_1.rb @@ -1,16 +1,20 @@ require_relative 'database_3_0' -require_relative '../support/constants/constants' +require_relative '../support/constants' module ImportScripts::PhpBB3 class Database_3_1 < Database_3_0 def fetch_users(offset) query(<<-SQL) - SELECT u.user_id, u.user_email, u.username, u.user_password, u.user_regdate, u.user_lastvisit, u.user_ip, + SELECT u.user_id, u.user_email, u.username, + CASE WHEN u.user_password LIKE '$2y$%' + THEN CONCAT('$2a$', SUBSTRING(u.user_password, 5)) + ELSE u.user_password + END AS user_password, u.user_regdate, u.user_lastvisit, u.user_ip, u.user_type, u.user_inactive_reason, g.group_name, b.ban_start, b.ban_end, b.ban_reason, u.user_posts, f.pf_phpbb_website AS user_website, f.pf_phpbb_location AS user_from, u.user_birthday, u.user_avatar_type, u.user_avatar FROM #{@table_prefix}_users u - JOIN #{@table_prefix}_profile_fields_data f ON (u.user_id = f.user_id) + LEFT OUTER JOIN #{@table_prefix}_profile_fields_data f ON (u.user_id = f.user_id) JOIN #{@table_prefix}_groups g ON (g.group_id = u.group_id) LEFT OUTER JOIN #{@table_prefix}_banlist b ON ( u.user_id = b.ban_userid AND b.ban_exclude = 0 AND diff --git a/script/import_scripts/phpbb3/database/database_base.rb b/script/import_scripts/phpbb3/database/database_base.rb index 3c8b4b37181..a63cecf4c2e 100644 --- a/script/import_scripts/phpbb3/database/database_base.rb +++ b/script/import_scripts/phpbb3/database/database_base.rb @@ -13,7 +13,7 @@ module ImportScripts::PhpBB3 # Executes a database query. def query(sql) - @database_client.query(sql, cache_rows: false, symbolize_keys: true) + @database_client.query(sql, cache_rows: true, symbolize_keys: true) end # Executes a database query and returns the value of the 'count' column. diff --git a/script/import_scripts/phpbb3/importer.rb b/script/import_scripts/phpbb3/importer.rb index 11592b40d18..83d748fa6ed 100644 --- a/script/import_scripts/phpbb3/importer.rb +++ b/script/import_scripts/phpbb3/importer.rb @@ -56,7 +56,7 @@ module ImportScripts::PhpBB3 rows = @database.fetch_users(offset) break if rows.size < 1 - next if all_records_exist? :users, importer.map_to_import_ids(rows) + next if all_records_exist?(:users, importer.map_users_to_import_ids(rows)) create_users(rows, total: total_count, offset: offset) do |row| importer.map_user(row) @@ -73,6 +73,8 @@ module ImportScripts::PhpBB3 rows = @database.fetch_anonymous_users(offset) break if rows.size < 1 + next if all_records_exist?(:users, importer.map_anonymous_users_to_import_ids(rows)) + create_users(rows, total: total_count, offset: offset) do |row| importer.map_anonymous_user(row) end @@ -98,12 +100,37 @@ module ImportScripts::PhpBB3 rows = @database.fetch_posts(offset) break if rows.size < 1 + next if all_records_exist?(:posts, importer.map_to_import_ids(rows)) + create_posts(rows, total: total_count, offset: offset) do |row| importer.map_post(row) end end end + # uncomment below lines to create permalink for categories + # def create_category(opts, import_id) + # new_category = super + # url = "viewforum.php?f=#{import_id}" + # if !Permalink.find_by(url: url) + # Permalink.create(url: url, category_id: new_category.id) + # end + # new_category + # end + + # uncomment below lines to create permalink for topics + # def create_post(opts, import_id) + # post = super + # if post && (topic = post.topic) && (category = topic.category) + # url = "viewtopic.php?f=#{category.custom_fields["import_id"]}&t=#{opts[:import_topic_id]}" + + # if !Permalink.find_by(url: url) + # Permalink.create(url: url, topic_id: topic.id) + # end + # end + # post + # end + def import_private_messages if @settings.fix_private_messages puts '', 'fixing private messages' @@ -118,6 +145,8 @@ module ImportScripts::PhpBB3 rows = @database.fetch_messages(@settings.fix_private_messages, offset) break if rows.size < 1 + next if all_records_exist?(:posts, importer.map_to_import_ids(rows)) + create_posts(rows, total: total_count, offset: offset) do |row| importer.map_message(row) end @@ -143,8 +172,10 @@ module ImportScripts::PhpBB3 # no need for this since the importer sets last_seen_at for each user during the import end + # Do not use the bbcode_to_md in base.rb. If enabled, it will be + # used in text_processor.rb instead. def use_bbcode_to_md? - @settings.use_bbcode_to_md + false end def batches diff --git a/script/import_scripts/phpbb3/importers/attachment_importer.rb b/script/import_scripts/phpbb3/importers/attachment_importer.rb index e41ca7a1209..37f7695c9c7 100644 --- a/script/import_scripts/phpbb3/importers/attachment_importer.rb +++ b/script/import_scripts/phpbb3/importers/attachment_importer.rb @@ -22,7 +22,7 @@ module ImportScripts::PhpBB3 filename = CGI.unescapeHTML(row[:real_filename]) upload = @uploader.create_upload(user_id, path, filename) - if upload.nil? || !upload.valid? + if upload.nil? || !upload.persisted? puts "Failed to upload #{path}" puts upload.errors.inspect if upload else diff --git a/script/import_scripts/phpbb3/importers/avatar_importer.rb b/script/import_scripts/phpbb3/importers/avatar_importer.rb index 3db8b701004..825bc445faf 100644 --- a/script/import_scripts/phpbb3/importers/avatar_importer.rb +++ b/script/import_scripts/phpbb3/importers/avatar_importer.rb @@ -24,14 +24,15 @@ module ImportScripts::PhpBB3 filename = "avatar#{File.extname(path)}" upload = @uploader.create_upload(user.id, path, filename) - if upload.persisted? + if upload.present? && upload.persisted? user.import_mode = false user.create_user_avatar user.import_mode = true user.user_avatar.update(custom_upload_id: upload.id) user.update(uploaded_avatar_id: upload.id) else - Rails.logger.error("Could not persist avatar for user #{user.username}") + puts "Failed to upload avatar for user #{user.username}: #{path}" + puts upload.errors.inspect if upload end rescue SystemCallError => err Rails.logger.error("Could not import avatar for user #{user.username}: #{err.message}") diff --git a/script/import_scripts/phpbb3/importers/message_importer.rb b/script/import_scripts/phpbb3/importers/message_importer.rb index 6200b0b0230..0ebab7d242a 100644 --- a/script/import_scripts/phpbb3/importers/message_importer.rb +++ b/script/import_scripts/phpbb3/importers/message_importer.rb @@ -13,12 +13,17 @@ module ImportScripts::PhpBB3 @settings = settings end + def map_to_import_ids(rows) + rows.map { |row| get_import_id(row) } + end + + def map_message(row) user_id = @lookup.user_id_from_imported_user_id(row[:author_id]) || Discourse.system_user.id attachments = import_attachments(row, user_id) mapped = { - id: "pm:#{row[:msg_id]}", + id: get_import_id(row), user_id: user_id, created_at: Time.zone.at(row[:message_time]), raw: @text_processor.process_private_msg(row[:message_text], attachments) @@ -79,5 +84,9 @@ module ImportScripts::PhpBB3 import_user_id.to_s == author_id.to_s ? nil : @lookup.find_user_by_import_id(import_user_id).try(:username) end.compact end + + def get_import_id(row) + "pm:#{row[:msg_id]}" + end end end diff --git a/script/import_scripts/phpbb3/importers/poll_importer.rb b/script/import_scripts/phpbb3/importers/poll_importer.rb index b3099f20c1b..e6bae5b40b7 100644 --- a/script/import_scripts/phpbb3/importers/poll_importer.rb +++ b/script/import_scripts/phpbb3/importers/poll_importer.rb @@ -22,6 +22,8 @@ module ImportScripts::PhpBB3 poll_text = get_poll_text(options, poll) extracted_poll = extract_default_poll(topic_id, poll_text) + return if extracted_poll.nil? + update_poll(extracted_poll, options, topic_id, poll) mapped_poll = { @@ -83,6 +85,9 @@ module ImportScripts::PhpBB3 extracted_polls.each do |poll| return poll if poll['name'] == @default_poll_name end + + puts "Failed to extract poll for topic id #{topic_id}. The poll text is:" + puts poll_text end # @param poll [ImportScripts::PhpBB3::Poll] diff --git a/script/import_scripts/phpbb3/importers/post_importer.rb b/script/import_scripts/phpbb3/importers/post_importer.rb index be0daebbf22..a00335232c3 100644 --- a/script/import_scripts/phpbb3/importers/post_importer.rb +++ b/script/import_scripts/phpbb3/importers/post_importer.rb @@ -13,6 +13,10 @@ module ImportScripts::PhpBB3 @settings = settings end + def map_to_import_ids(rows) + rows.map { |row| row[:post_id] } + end + def map_post(row) imported_user_id = row[:post_username].blank? ? row[:poster_id] : row[:post_username] user_id = @lookup.user_id_from_imported_user_id(imported_user_id) || Discourse.system_user.id @@ -24,7 +28,8 @@ module ImportScripts::PhpBB3 id: row[:post_id], user_id: user_id, created_at: Time.zone.at(row[:post_time]), - raw: @text_processor.process_post(row[:post_text], attachments) + raw: @text_processor.process_post(row[:post_text], attachments), + import_topic_id: row[:topic_id] } if is_first_post diff --git a/script/import_scripts/phpbb3/importers/user_importer.rb b/script/import_scripts/phpbb3/importers/user_importer.rb index aeef5ec8627..ca50197a95d 100644 --- a/script/import_scripts/phpbb3/importers/user_importer.rb +++ b/script/import_scripts/phpbb3/importers/user_importer.rb @@ -9,8 +9,8 @@ module ImportScripts::PhpBB3 @settings = settings end - def map_to_import_ids(array) - array.map {|u| u[:user_id]} + def map_users_to_import_ids(rows) + rows.map { |row| row[:user_id] } end def map_user(row) @@ -42,6 +42,10 @@ module ImportScripts::PhpBB3 } end + def map_anonymous_users_to_import_ids(rows) + rows.map { |row| row[:post_username] } + end + def map_anonymous_user(row) username = row[:post_username] @@ -68,7 +72,8 @@ module ImportScripts::PhpBB3 def parse_birthdate(row) return nil if row[:user_birthday].blank? - Date.strptime(row[:user_birthday].delete(' '), '%d-%m-%Y') rescue nil + birthdate = Date.strptime(row[:user_birthday].delete(' '), '%d-%m-%Y') rescue nil + birthdate && birthdate.year > 0 ? birthdate : nil end # Suspends the user if it is currently banned. @@ -86,10 +91,12 @@ module ImportScripts::PhpBB3 end if disable_email - user.email_digests = false - user.email_private_messages = false - user.email_direct = false - user.email_always = false + user_option = user.user_option + user_option.email_digests = false + user_option.email_private_messages = false + user_option.email_direct = false + user_option.email_always = false + user_option.save! end if user.save diff --git a/script/import_scripts/phpbb3/settings.yml b/script/import_scripts/phpbb3/settings.yml index d7ee6174e23..4e7cb9bcb4a 100644 --- a/script/import_scripts/phpbb3/settings.yml +++ b/script/import_scripts/phpbb3/settings.yml @@ -3,6 +3,7 @@ database: type: MySQL # currently only MySQL is supported - more to come soon host: localhost + port: 3306 username: root password: schema: phpbb @@ -16,8 +17,9 @@ import: # This is the path to the root directory of your current phpBB installation (or a copy of it). # The importer expects to find the /files and /images directories within the base directory. + # You need to change this to something like /var/www/phpbb if you are not using the Docker based importer. # This is only needed if you want to import avatars, attachments or custom smilies. - phpbb_base_dir: /var/www/phpbb + phpbb_base_dir: /shared/import/data site_prefix: # this is needed for rewriting internal links in posts diff --git a/script/import_scripts/phpbb3/support/settings.rb b/script/import_scripts/phpbb3/support/settings.rb index 1c68c5f8b7a..e2182a0bc7e 100644 --- a/script/import_scripts/phpbb3/support/settings.rb +++ b/script/import_scripts/phpbb3/support/settings.rb @@ -61,6 +61,7 @@ module ImportScripts::PhpBB3 class DatabaseSettings attr_reader :type attr_reader :host + attr_reader :port attr_reader :username attr_reader :password attr_reader :schema @@ -70,6 +71,7 @@ module ImportScripts::PhpBB3 def initialize(yaml) @type = yaml['type'] @host = yaml['host'] + @port = yaml['port'] @username = yaml['username'] @password = yaml['password'] @schema = yaml['schema'] diff --git a/script/import_scripts/phpbb3/support/smiley_processor.rb b/script/import_scripts/phpbb3/support/smiley_processor.rb index f79a24c4659..342cadfaabf 100644 --- a/script/import_scripts/phpbb3/support/smiley_processor.rb +++ b/script/import_scripts/phpbb3/support/smiley_processor.rb @@ -28,7 +28,7 @@ module ImportScripts::PhpBB3 def add_default_smilies { [':D', ':-D', ':grin:'] => ':smiley:', - [':)', ':-)', ':smile:'] => ':smile:', + [':)', ':-)', ':smile:'] => ':slight_smile:', [';)', ';-)', ':wink:'] => ':wink:', [':(', ':-(', ':sad:'] => ':frowning:', [':o', ':-o', ':eek:'] => ':astonished:', @@ -65,7 +65,7 @@ module ImportScripts::PhpBB3 filename = File.basename(path) upload = @uploader.create_upload(Discourse::SYSTEM_USER_ID, path, filename) - if upload.nil? || !upload.valid? + if upload.nil? || !upload.persisted? puts "Failed to upload #{path}" puts upload.errors.inspect if upload html = nil diff --git a/script/import_scripts/phpbb3/support/text_processor.rb b/script/import_scripts/phpbb3/support/text_processor.rb index c0e99e4dd2a..edd104f6d33 100644 --- a/script/import_scripts/phpbb3/support/text_processor.rb +++ b/script/import_scripts/phpbb3/support/text_processor.rb @@ -9,6 +9,7 @@ module ImportScripts::PhpBB3 @database = database @smiley_processor = smiley_processor + @settings = settings @new_site_prefix = settings.new_site_prefix create_internal_link_regexps(settings.original_site_prefix) end @@ -18,6 +19,9 @@ module ImportScripts::PhpBB3 text = CGI.unescapeHTML(text) clean_bbcodes(text) + if @settings.use_bbcode_to_md + text = bbcode_to_md(text) + end process_smilies(text) process_links(text) process_lists(text) @@ -46,6 +50,15 @@ module ImportScripts::PhpBB3 text.gsub!(/:(?:\w{8})\]/, ']') end + def bbcode_to_md(text) + begin + text.bbcode_to_md(false) + rescue e + puts "Problem converting \n#{text}\n using ruby-bbcode-to-md" + text + end + end + def process_smilies(text) @smiley_processor.replace_smilies(text) end diff --git a/script/import_scripts/quandora/README.md b/script/import_scripts/quandora/README.md new file mode 100644 index 00000000000..d010ede3454 --- /dev/null +++ b/script/import_scripts/quandora/README.md @@ -0,0 +1,21 @@ + +To get started, copy the config.ex.yml to config.yml, and then update the properties for your Quandora instance. + +``` +domain: 'my-quandora-domain' +username: 'my-quandora-username' +password: 'my-quandora-password' +``` + +Create the directory for the json files to export: `mkdir output` +Then run `ruby export.rb /path/to/config.yml` + +To import, run `ruby import.rb` + +To run tests, include id's for a KB and Question that includes answers and comments + +``` +kb_id: 'some-kb-id' +question_id: 'some-question-id' +``` + diff --git a/script/import_scripts/quandora/export.rb b/script/import_scripts/quandora/export.rb new file mode 100644 index 00000000000..529486f1d72 --- /dev/null +++ b/script/import_scripts/quandora/export.rb @@ -0,0 +1,30 @@ +require 'yaml' +require_relative 'quandora_api' + +def load_config file + config = YAML::load_file(File.join(__dir__, file)) + @domain = config['domain'] + @username = config['username'] + @password = config['password'] +end + +def export + api = QuandoraApi.new @domain, @username, @password + bases = api.list_bases + bases.each do |base| + question_list = api.list_questions base['objectId'], 1000 + question_list.each do |q| + question_id = q['uid'] + question = api.get_question question_id + File.open("output/#{question_id}.json", 'w') do |f| + puts question['title'] + f.write question.to_json + f.close + end + end + end +end + +load_config ARGV.shift +export + diff --git a/script/import_scripts/quandora/import.rb b/script/import_scripts/quandora/import.rb new file mode 100644 index 00000000000..452e755557a --- /dev/null +++ b/script/import_scripts/quandora/import.rb @@ -0,0 +1,94 @@ +require_relative './quandora_question.rb' +require File.expand_path(File.dirname(__FILE__) + "/../base.rb") + +class ImportScripts::Quandora < ImportScripts::Base + + JSON_FILES_DIR = "output" + + def initialize + super + @system_user = Discourse.system_user + @questions = [] + Dir.foreach(JSON_FILES_DIR) do |filename| + next if filename == '.' or filename == '..' + question = File.read JSON_FILES_DIR + '/' + filename + @questions << question + end + end + + def execute + puts "", "Importing from Quandora..." + import_questions @questions + EmailToken.delete_all + puts "", "Done" + end + + def import_questions questions + topics = 0 + total = questions.size + + questions.each do |question| + q = QuandoraQuestion.new question + import_users q.users + created_topic = import_topic q.topic + if created_topic + import_posts q.replies, created_topic.topic_id + end + topics += 1 + print_status topics, total + end + puts "", "Imported #{topics} topics." + end + + def import_users users + users.each do |user| + create_user user, user[:id] + end + end + + def import_topic topic + post = nil + if post_id = post_id_from_imported_post_id(topic[:id]) + post = Post.find(post_id) # already imported this topic + else + topic[:user_id] = user_id_from_imported_user_id(topic[:author_id]) || -1 + topic[:category] = 'quandora-import' + + post = create_post(topic, topic[:id]) + + unless created_topic.is_a?(Post) + puts "Error creating topic #{topic[:id]}. Skipping." + puts created_topic.inspect + end + end + + post + end + + def import_posts posts, topic_id + posts.each do |post| + import_post post, topic_id + end + end + + def import_post post, topic_id + if post_id_from_imported_post_id(post[:id]) + return # already imported + end + post[:topic_id] = topic_id + post[:user_id] = user_id_from_imported_user_id(post[:author_id]) + new_post = create_post post, post[:id] + unless new_post.is_a?(Post) + puts "Error creating post #{post[:id]}. Skipping." + puts new_post.inspect + end + end + + def file_full_path(relpath) + File.join JSON_FILES_DIR, relpath.split("?").first + end +end + +if __FILE__==$0 + ImportScripts::Quandora.new.perform +end diff --git a/script/import_scripts/quandora/quandora_api.rb b/script/import_scripts/quandora/quandora_api.rb new file mode 100644 index 00000000000..37ef726f1f4 --- /dev/null +++ b/script/import_scripts/quandora/quandora_api.rb @@ -0,0 +1,54 @@ +require 'base64' +require 'json' +require 'rest-client' + +class QuandoraApi + + attr_accessor :domain, :username, :password + + def initialize domain, username, password + @domain = domain + @username = username + @password = password + end + + def base_url domain + "https://#{domain}.quandora.com/m/json" + end + + def auth_header username, password + encoded = Base64.encode64 "#{username}:#{password}" + {:Authorization => "Basic #{encoded.strip!}"} + end + + def list_bases_url + "#{base_url @domain}/kb" + end + + def list_questions_url kb_id, limit + url = "#{base_url @domain}/kb/#{kb_id}/list" + url = "#{url}?l=#{limit}" if limit + url + end + + def request url + JSON.parse(RestClient.get url, auth_header(@username, @password)) + end + + def list_bases + response = request list_bases_url + response['data'] + end + + def list_questions kb_id, limit = nil + url = list_questions_url(kb_id, limit) + response = request url + response['data']['result'] + end + + def get_question question_id + url = "#{base_url @domain}/q/#{question_id}" + response = request url + response['data'] + end +end diff --git a/script/import_scripts/quandora/quandora_question.rb b/script/import_scripts/quandora/quandora_question.rb new file mode 100644 index 00000000000..c8611b558cb --- /dev/null +++ b/script/import_scripts/quandora/quandora_question.rb @@ -0,0 +1,109 @@ +require 'json' +require 'cgi' +require 'time' + +class QuandoraQuestion + + def initialize question_json + @question = JSON.parse question_json + end + + def topic + topic = {} + topic[:id] = @question['uid'] + topic[:author_id] = @question['author']['uid'] + topic[:title] = unescape @question['title'] + topic[:raw] = unescape @question['content'] + topic[:created_at] = Time.parse @question['created'] + topic + end + + def users + users = {} + user = user_from_author @question['author'] + users[user[:id]] = user + replies.each do |reply| + user = user_from_author reply[:author] + users[user[:id]] = user + end + users.values.to_a + end + + def user_from_author author + email = author['email'] + email = "#{author['uid']}@noemail.com" unless email + + user = {} + user[:id] = author['uid'] + user[:name] = "#{author['firstName']} #{author['lastName']}" + user[:email] = email + user[:staged] = true + user + end + + def replies + posts = [] + answers = @question['answersList'] + comments = @question['comments'] + comments.each_with_index do |comment, i| + posts << post_from_comment(comment, i, @question) + end + answers.each do |answer| + posts << post_from_answer(answer) + comments = answer['comments'] + comments.each_with_index do |comment, i| + posts << post_from_comment(comment, i, answer) + end + end + order_replies posts + end + + def order_replies posts + posts = posts.sort_by { |p| p[:created_at] } + posts.each_with_index do |p, i| + p[:post_number] = i + 2 + end + posts.each do |p| + parent = posts.select { |pp| pp[:id] == p[:parent_id] } + p[:reply_to_post_number] = parent[0][:post_number] if parent.size > 0 + end + posts + end + + def post_from_answer answer + post = {} + post[:id] = answer['uid'] + post[:parent_id] = @question['uid'] + post[:author] = answer['author'] + post[:author_id] = answer['author']['uid'] + post[:raw] = unescape answer['content'] + post[:created_at] = Time.parse answer['created'] + post + end + + def post_from_comment comment, index, parent + if comment['created'] + created_at = Time.parse comment['created'] + else + created_at = Time.parse parent['created'] + end + parent_id = parent['uid'] + parent_id = "#{parent['uid']}-#{index-1}" if index > 0 + post = {} + id = "#{parent['uid']}-#{index}" + post[:id] = id + post[:parent_id] = parent_id + post[:author] = comment['author'] + post[:author_id] = comment['author']['uid'] + post[:raw] = unescape comment['text'] + post[:created_at] = created_at + post + end + + private + + def unescape html + return nil unless html + CGI.unescapeHTML html + end +end diff --git a/script/import_scripts/quandora/test/config.ex.yml b/script/import_scripts/quandora/test/config.ex.yml new file mode 100644 index 00000000000..177aea4b727 --- /dev/null +++ b/script/import_scripts/quandora/test/config.ex.yml @@ -0,0 +1,6 @@ +domain: 'my-quandora-domain' +username: 'my-quandora-username' +password: 'my-quandora-password' + +kb_id: 'some-kb-id' +question_id: 'some-question-id' diff --git a/script/import_scripts/quandora/test/test_data.rb b/script/import_scripts/quandora/test/test_data.rb new file mode 100644 index 00000000000..044b63c58c4 --- /dev/null +++ b/script/import_scripts/quandora/test/test_data.rb @@ -0,0 +1,179 @@ + BASES = '{ + "type" : "kbase", + "data" : [ { + "objectId" : "90b1ccf3-35aa-4d6f-848e-e7c122d92c58", + "objectName" : "hotdogs", + "title" : "Hot Dogs", + "description" : "This knowledge base is for questions about Hot Dogs" + } ] + }' + + QUESTIONS = '{ + "type": "question-search-result", + "data": { + "totalSize": 445, + "offset": 0, + "limit": 1000, + "result": [ { + "uid": "dd2cf490-f564-4147-9943-57682c7fac73", + "title": "How can we improve the office?", + "summary": "Hi everyone, I’d love to hear your suggestions about how we can make our office a more pleasant place to work", + "votes": 2, + "views": 107, + "answers": 5, + "commentsCount": 3, + "created": "2013-01-06T18:24:54.62Z", + "modified": "2015-05-03T00:52:45.63Z", + "authorId": "24599c93-0a83-4099-982f-d0d708ea3178", + "baseId": "90b1ccf3-35aa-4d6f-848e-e7c122d92c58", + "prettyUrl": "https://mydomain.quandora.com/general/q/de20ed0a5fe548a59c14d854f9af99f1/How-can-we-improve-the-office", + "accepted": null, + "author": { + "uid": "24599c93-0a83-4099-982f-d0d708ea3178", + "name": "24599c93-0a83-4099-982f-d0d708ea3178", + "email": "flast@mydomain.com", + "firstName": "First", + "lastName": "Last", + "title": "Member", + "score": 236, + "disabled": false, + "badgeCount": [3,0,0], + "avatarUrl": "//www.gravatar.com/avatar/fdf8bd4205dc7ad908ea0578a111cb89?d=mm&s=%s" + }, + "tags": [ { + "uid": "88a08f00-3038-4e96-8c26-4a777b46871c", + "name": "office", + "category": null + }] + }] + } + }' + + QUESTION = '{ + "type" : "question", + "data" : { + "uid" : "de20ed0a-5fe5-48a5-9c14-d854f9af99f1", + "title" : "How can we improve the office?", + "votes" : 2, + "views" : 107, + "answers" : 5, + "commentsCount" : 3, + "created" : "2013-01-06T18:24:54.62Z", + "modified" : "2015-05-03T00:52:45.63Z", + "authorId" : "043c8d91-26f7-44c7-acfa-179f06a4e998", + "baseId" : "7583b6df-2090-46fd-97b5-cdde072ec34e", + "prettyUrl" : "https://mydomain.quandora.com/general/q/de20ed0a5fe548a59c14d854f9af99f1/How-can-we-improve-the-office", + "accepted" : null, + "content" : "

    Hi everyone,

    \n

    I\'d love to hear your suggestions about how we can make our office a more pleasant place to work.

    \n

    What things are we missing from our kitchen or supply closet?

    \n

    If you don\'t regularly come to the office, and what do you think would make you more likely to make the commute?

    \n

    Thanks!

    ", + "contentType" : "markdown", + "answersList" : [ { + "uid" : "78e7dc82-fe0f-4687-8ed9-6ade23d95164", + "contentType" : "markdown", + "content" : "

    The most value I get out of coming to the office is hearing about weird techy glitches, or announcements that the company has to make.

    \n

    The bulletin board, at least in Ohio, seems to have died off a bit. It would be easy to say that people are intimidated by the large group, but in some meetings I think there\'s another problem: it\'s often the case that people just say \'come and grab me after the meeting\'. I\'m sure that works well, but I like it when a summary of the solution arrives back via email or at the next meeting, so that the whole office can benefit from the knowledge transfer.

    ", + "comments" : [ ], + "votes" : 3, + "created" : "2013-01-07T04:59:56.26Z", + "accepted" : false, + "authorId" : "acfd09c6-8bf8-4342-98de-3d7fc4c60ec0", + "author" : { + "uid" : "acfd09c6-8bf8-4342-98de-3d7fc4c60ec0", + "name" : "acfd09c6-8bf8-4342-98de-3d7fc4c60ec0", + "email" : "hharry@mydomain.com", + "firstName" : "Harry", + "lastName" : "Helpful", + "title" : "Member", + "score" : 1615, + "disabled" : false, + "badgeCount" : null, + "avatarUrl" : "//www.gravatar.com/avatar/e3cbc264af6d2392b7f323cebbbcfea6?d=mm&s=%s" + } + }, { + "uid" : "b6864e72-1a03-4f49-aa7f-d2781b14f69c", + "contentType" : "markdown", + "content" : "

    For Ohio: i don\'t know if you\'ve already tried this, but I recommend doing the meetings in the beginning of the day. That way people are more likely to come into the office early, rather than after lunch :)

    ", + "comments" : [ { + "author" : { + "uid" : "204973f4-2dfe-494c-b1b2-3cd1cbac34f0", + "name" : "204973f4-2dfe-494c-b1b2-3cd1cbac34f0", + "email" : "eexcited@mydomain.com", + "firstName" : "Eddy", + "lastName" : "Excited", + "title" : "Member", + "score" : 516, + "disabled" : false, + "badgeCount" : null, + "avatarUrl" : "//www.gravatar.com/avatar/baa5f96720477108e685d38f5a7fa21c?d=mm&s=%s" + }, + "created" : "2016-01-22T15:38:55.91Z", + "text" : "Great idea! I think more people will overlap here if we start our days at the same time.", + "hash" : "7f45b063f8f52eead80a784ca37e901a" + } ], + "votes" : 2, + "created" : "2013-01-08T16:49:32.80Z", + "accepted" : false, + "authorId" : "da0a6658-fa06-420a-9027-7a8051e4ec29", + "author" : { + "uid" : "da0a6658-fa06-420a-9027-7a8051e4ec29", + "name" : "da0a6658-fa06-420a-9027-7a8051e4ec29", + "email" : "ssmartypants@mydomain.com", + "firstName" : "Sam", + "lastName" : "Smarty-Pants", + "title" : "Member", + "score" : 3485, + "disabled" : false, + "badgeCount" : null, + "avatarUrl" : "//www.gravatar.com/avatar/e0be54fafea799f30abb6eacd2459cf6?d=mm&s=%s" + } + } ], + "comments" : [ { + "author" : { + "uid" : "acfd09c6-8bf8-4342-98de-3d7fc4c60ec0", + "name" : "acfd09c6-8bf8-4342-98de-3d7fc4c60ec0", + "email" : "hhelpful@mydomain.com", + "firstName" : "Harry", + "lastName" : "Helpful", + "title" : "Member", + "score" : 236, + "disabled" : false, + "badgeCount" : [ 3, 0, 0 ], + "avatarUrl" : "//www.gravatar.com/avatar/e3cbc264af6d2392b7f323cebbbcfea6?d=mm&s=%s" + }, + "created" : "2016-01-20T15:38:55.91Z", + "text" : "Also, what hopes and expectations do you have of the new meeting space that we will be starting to use this week?", + "hash" : "226dbd023cc4e786bf1e7bc08989bde7" + }, { + "author" : { + "uid" : "7fcdc8ee-ab92-43a9-84a6-665aa4edbb49", + "name" : "7fcdc8ee-ab92-43a9-84a6-665aa4edbb49", + "email" : "ggreatful@mydomain.com", + "firstName" : "Greta", + "lastName" : "Greatful", + "title" : "Member", + "score" : 516, + "disabled" : false, + "badgeCount" : null, + "avatarUrl" : "//www.gravatar.com/avatar/d6027aecba638fc8c402c6138e799007?d=mm&s=%s" + }, + "created" : "2016-01-21T15:38:55.91Z", + "text" : "I love coming into the office. The view is great, the food is wonderful, and I get to hang out with some awesome people!", + "hash" : "7f45b063f8f52eead80a784ca37e901a" + } ], + "author" : { + "uid" : "8c07ba39-1e2b-406f-b3cf-3da78431d399", + "name" : "8c07ba39-1e2b-406f-b3cf-3da78431d399", + "email" : "iinquisitive@mydomain.com", + "firstName" : "Ida", + "lastName" : "Inquisitive", + "title" : "Member", + "score" : 236, + "disabled" : false, + "badgeCount" : [ 3, 0, 0 ], + "avatarUrl" : "//www.gravatar.com/avatar/187f4bff7780e4a12b727c3ad81cfbac?d=mm&s=%s" + }, + "tags" : [ { + "uid" : "53f65082-f081-4fc9-9bd5-a739599ee2b3", + "name" : "office", + "category" : null + } ] + } +}' diff --git a/script/import_scripts/quandora/test/test_quandora_api.rb b/script/import_scripts/quandora/test/test_quandora_api.rb new file mode 100644 index 00000000000..ecdb976e0bd --- /dev/null +++ b/script/import_scripts/quandora/test/test_quandora_api.rb @@ -0,0 +1,90 @@ +require 'minitest/autorun' +require 'yaml' +require_relative '../quandora_api.rb' +require_relative './test_data.rb' + +class TestQuandoraApi < Minitest::Test + + DEBUG = false + + def initialize args + config = YAML::load_file(File.join(__dir__, 'config.yml')) + @domain = config['domain'] + @username = config['username'] + @password = config['password'] + @kb_id = config['kb_id'] + @question_id = config['question_id'] + super args + end + + def setup + @quandora = QuandoraApi.new @domain, @username, @password + end + + def test_intialize + assert_equal @domain, @quandora.domain + assert_equal @username, @quandora.username + assert_equal @password, @quandora.password + end + + def test_base_url + assert_equal 'https://mydomain.quandora.com/m/json', @quandora.base_url('mydomain') + end + + def test_auth_header + user = 'Aladdin' + password = 'open sesame' + auth_header = @quandora.auth_header user, password + assert_equal 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==', auth_header[:Authorization] + end + + def test_list_bases_element_has_expected_structure + element = @quandora.list_bases[0] + expected = JSON.parse(BASES)['data'][0] + debug element + check_keys expected, element + end + + def test_list_questions_has_expected_structure + response = @quandora.list_questions @kb_id, 1 + debug response + check_keys JSON.parse(QUESTIONS)['data']['result'][0], response[0] + end + + def test_get_question_has_expected_structure + question = @quandora.get_question @question_id + expected = JSON.parse(QUESTION)['data'] + check_keys expected, question + + expected_comment = expected['comments'][0] + actual_comment = question['comments'][0] + check_keys expected_comment, actual_comment + + expected_answer = expected['answersList'][1] + actual_answer = question['answersList'][0] + check_keys expected_answer, actual_answer + + expected_answer_comment = expected_answer['comments'][0] + actual_answer_comment = actual_answer['comments'][0] + check_keys expected_answer_comment, actual_answer_comment + end + + private + + def check_keys expected, actual + msg = "### caller[0]:\nKey not found in actual keys: #{actual.keys}\n" + expected.keys.each do |k| + assert (actual.keys.include? k), "#{k}" + end + end + + def debug message, show=false + if show || DEBUG + puts '### ' + caller[0] + puts '' + puts message + puts '' + puts '' + end + end +end diff --git a/script/import_scripts/quandora/test/test_quandora_question.rb b/script/import_scripts/quandora/test/test_quandora_question.rb new file mode 100644 index 00000000000..ceba01e0063 --- /dev/null +++ b/script/import_scripts/quandora/test/test_quandora_question.rb @@ -0,0 +1,136 @@ +require 'minitest/autorun' +require 'cgi' +require 'time' +require_relative '../quandora_question.rb' +require_relative './test_data.rb' + +class TestQuandoraQuestion < Minitest::Test + + def setup + @data = JSON.parse(QUESTION)['data'] + @question = QuandoraQuestion.new @data.to_json + end + + def test_topic + topic = @question.topic + assert_equal @data['uid'], topic[:id] + assert_equal @data['author']['uid'], topic[:author_id] + assert_equal unescape(@data['title']), topic[:title] + assert_equal unescape(@data['content']), topic[:raw] + assert_equal Time.parse(@data['created']), topic[:created_at] + end + + def test_user_from_author + author = {} + author['uid'] = 'uid' + author['firstName'] = 'Joe' + author['lastName'] = 'Schmoe' + author['email'] = 'joe.schmoe@mydomain.com' + + user = @question.user_from_author author + + assert_equal 'uid', user[:id] + assert_equal 'Joe Schmoe', user[:name] + assert_equal 'joe.schmoe@mydomain.com', user[:email] + assert_equal true, user[:staged] + end + + def test_user_from_author_with_no_email + author = {} + author['uid'] = 'foo' + user = @question.user_from_author author + assert_equal 'foo@noemail.com', user[:email] + end + + def test_replies + replies = @question.replies + assert_equal 5, replies.size + assert_equal 2, replies[0][:post_number] + assert_equal 3, replies[1][:post_number] + assert_equal 4, replies[2][:post_number] + assert_equal 5, replies[3][:post_number] + assert_equal 6, replies[4][:post_number] + assert_equal nil, replies[0][:reply_to_post_number] + assert_equal nil, replies[1][:reply_to_post_number] + assert_equal nil, replies[2][:reply_to_post_number] + assert_equal 4, replies[3][:reply_to_post_number] + assert_equal 3, replies[4][:reply_to_post_number] + assert_equal '2013-01-07 04:59:56 UTC', replies[0][:created_at].to_s + assert_equal '2013-01-08 16:49:32 UTC', replies[1][:created_at].to_s + assert_equal '2016-01-20 15:38:55 UTC', replies[2][:created_at].to_s + assert_equal '2016-01-21 15:38:55 UTC', replies[3][:created_at].to_s + assert_equal '2016-01-22 15:38:55 UTC', replies[4][:created_at].to_s + end + + def test_post_from_answer + answer = {} + answer['uid'] = 'uid' + answer['content'] = 'content' + answer['created'] = '2013-01-06T18:24:54.62Z' + answer['author'] = {'uid' => 'auid'} + + post = @question.post_from_answer answer + + assert_equal 'uid', post[:id] + assert_equal @question.topic[:id], post[:parent_id] + assert_equal answer['author'], post[:author] + assert_equal 'auid', post[:author_id] + assert_equal 'content', post[:raw] + assert_equal Time.parse('2013-01-06T18:24:54.62Z'), post[:created_at] + end + + def test_post_from_comment + comment = {} + comment['text'] = 'text' + comment['created'] = '2013-01-06T18:24:54.62Z' + comment['author'] = {'uid' => 'auid'} + parent = {'uid' => 'parent-uid'} + + post = @question.post_from_comment comment, 0, parent + + assert_equal 'parent-uid-0', post[:id] + assert_equal 'parent-uid', post[:parent_id] + assert_equal comment['author'], post[:author] + assert_equal 'auid', post[:author_id] + assert_equal 'text', post[:raw] + assert_equal Time.parse('2013-01-06T18:24:54.62Z'), post[:created_at] + end + + def test_post_from_comment_uses_parent_created_if_necessary + comment = {} + comment['author'] = {'uid' => 'auid'} + parent = {'created' => '2013-01-06T18:24:54.62Z'} + + post = @question.post_from_comment comment, 0, parent + + assert_equal Time.parse('2013-01-06T18:24:54.62Z'), post[:created_at] + end + + def test_post_from_comment_uses_previous_comment_as_parent + comment = {} + comment['author'] = {'uid' => 'auid'} + parent = {'uid' => 'parent-uid', 'created' => '2013-01-06T18:24:54.62Z'} + + post = @question.post_from_comment comment, 1, parent + + assert_equal 'parent-uid-1', post[:id] + assert_equal 'parent-uid-0', post[:parent_id] + assert_equal Time.parse('2013-01-06T18:24:54.62Z'), post[:created_at] + end + + def test_users + users = @question.users + assert_equal 5, users.size + assert_equal 'Ida Inquisitive', users[0][:name] + assert_equal 'Harry Helpful', users[1][:name] + assert_equal 'Sam Smarty-Pants', users[2][:name] + assert_equal 'Greta Greatful', users[3][:name] + assert_equal 'Eddy Excited', users[4][:name] + end + + private + + def unescape html + CGI.unescapeHTML html + end +end diff --git a/script/import_scripts/sourceforge.rb b/script/import_scripts/sourceforge.rb new file mode 100644 index 00000000000..d1b85366f4d --- /dev/null +++ b/script/import_scripts/sourceforge.rb @@ -0,0 +1,137 @@ +require_relative 'base.rb' + +# Import script for SourceForge discussions. +# +# See the following instructions on how to export your discussions from SourceForge: +# https://sourceforge.net/p/forge/documentation/Project%20Data%20Export/ +# +# Change the constants (PROJECT_NAME and JSON_FILE) before running the importer! +# +# Use the following command to run the importer within the Docker container: +# su discourse -c 'ruby /var/www/discourse/script/import_scripts/sourceforge.rb' + +class ImportScripts::Sourceforge < ImportScripts::Base + # When the URL of your project is https://sourceforge.net/projects/foo/ + # than the value of PROJECT_NAME is 'foo' + PROJECT_NAME = 'project_name' + + # This is the path to the discussion.json that you exported from SourceForge. + JSON_FILE = '/path/to/discussion.json' + + def initialize + super + + @system_user = Discourse.system_user + end + + def execute + puts '', 'Importing from SourceForge...' + + load_json + + import_categories + import_topics + end + + def load_json + @json = MultiJson.load(File.read(JSON_FILE), :symbolize_keys => true) + end + + def import_categories + puts '', 'importing categories' + + create_categories(@json[:forums]) do |forum| + { + id: forum[:shortname], + name: forum[:name], + post_create_action: proc do |category| + changes = {raw: forum[:description]} + opts = {revised_at: Time.now, bypass_bump: true} + + post = category.topic.first_post + post.revise(@system_user, changes, opts) + end + } + end + end + + def import_topics + puts '', 'importing posts' + imported_post_count = 0 + total_post_count = count_posts + + @json[:forums].each do |forum| + imported_category_id = @lookup.category_id_from_imported_category_id(forum[:shortname]) + + forum[:threads].each do |thread| + posts = thread[:posts] + next if posts.size == 0 + + first_post = posts[0] + first_post_id = post_id_of(thread, first_post) + imported_topic = nil + + create_posts(posts, total: total_post_count, offset: imported_post_count) do |post| + mapped = { + id: "#{thread[:_id]}_#{post[:slug]}", + user_id: @system_user, + created_at: Time.zone.parse(post[:timestamp]), + raw: process_post_text(forum, thread, post) + } + + if post == first_post + mapped[:category] = imported_category_id + mapped[:title] = thread[:subject][0...255] + else + if imported_topic.nil? + imported_topic = @lookup.topic_lookup_from_imported_post_id(first_post_id) + end + + mapped[:topic_id] = imported_topic[:topic_id] + end + + imported_post_count += 1 + mapped + end + end + end + end + + def count_posts + total_count = 0 + + @json[:forums].each do |forum| + forum[:threads].each do |thread| + total_count += thread[:posts].size + end + end + + total_count + end + + def post_id_of(thread, post) + "#{thread[:_id]}_#{post[:slug]}" + end + + def process_post_text(forum, thread, post) + text = post[:text] + text.gsub!(/~{3,}/, '```') # Discourse doesn't recognize ~~~ as beginning/end of code blocks + + # SourceForge doesn't allow symbols in usernames, so we are safe here. + # Well, unless it's the anonymous user, which has an evil asterisk in the JSON file... + username = post[:author] + username = 'anonymous' if username == '*anonymous' + + # anonymous and nobody are nonexistent users. Make sure we don't create links for them. + user_without_profile = username == 'anonymous' || username == 'nobody' + user_link = user_without_profile ? username : "[#{username}](https://sourceforge.net/u/#{username}/)" + + # Create a nice looking header for each imported post that links to the author's user profile and the old post. + post_date = Time.zone.parse(post[:timestamp]).strftime('%A, %B %d, %Y') + post_url = "https://sourceforge.net/p/#{PROJECT_NAME}/discussion/#{forum[:shortname]}/thread/#{thread[:_id]}/##{post[:slug]}" + + "**#{user_link}** wrote on [#{post_date}](#{post_url}):\n\n#{text}" + end +end + +ImportScripts::Sourceforge.new.perform diff --git a/script/import_scripts/tnation.rb b/script/import_scripts/tnation.rb deleted file mode 100644 index 438327c7b0e..00000000000 --- a/script/import_scripts/tnation.rb +++ /dev/null @@ -1,483 +0,0 @@ -# custom importer for www.t-nation.com, feel free to borrow ideas - -require 'mysql2' -require File.expand_path(File.dirname(__FILE__) + "/base.rb") - -class ImportScripts::Tnation < ImportScripts::Base - - BATCH_SIZE = 1000 - - # List of user custom fields that will be imported - USER_CUSTOM_FIELDS = %w{WEIGHT HEIGHT} - - # Posts older than this date will *not* be imported - THRESHOLD_DATE = 6.months.ago - - # Ordered list of category ids that will be imported - MIGRATED_CATEGORY_IDS = [ - # Biotest Forums - 255, # Micro-PA Users - 236, # Biotest Supplement Advice - 23, # Supplements and Nutrition - 84, # Velocity Diet Support - 219, # Velocity Diet Recipes - 207, # Before / After Photos - 206, # Diet Logs - # Training (87?, 61?) - 83, # Training Logs - 208, # Christian Thibaudeau Coaching - 250, # Jim Wendler 5/3/1 Coaching - 234, # Bigger Stronger Leaner - 39, # Bodybuilding - 29, # Powerlifting - 229, # Figure Athletes - 81, # Powerful Women - 64, # Over 35 Lifter - 62, # Beginners - 82, # Combat - 212, # Conditioning - 210, # Olympic Lifting - 211, # Strongman - 216, # Injuries and Rehab - # Off Topic - 3, # Get a Life - 32, # Politics and World Issues - 6, # Rate My Physique Photos - # Pharma - 217, # T Replacement - 40, # Steroids - ] - - MIGRATED_CATEGORY_IDS_SQL = MIGRATED_CATEGORY_IDS.join(",") - - PARENT_CATEGORIES = ["Biotest Forums", "Training", "Off Topic", "Pharma"] - - PARENT_CATEGORY_ID = { - # Biotest Forums - 255 => "biotest-forums", - 236 => "biotest-forums", - 23 => "biotest-forums", - 84 => "biotest-forums", - 219 => "biotest-forums", - 207 => "biotest-forums", - 206 => "biotest-forums", - # Training - 83 => "training", - 208 => "training", - 250 => "training", - 234 => "training", - 39 => "training", - 29 => "training", - 229 => "training", - 81 => "training", - 64 => "training", - 62 => "training", - 82 => "training", - 212 => "training", - 210 => "training", - 211 => "training", - 216 => "training", - # Off Topic - 3 => "off-topic", - 32 => "off-topic", - 6 => "off-topic", - # Pharma - 217 => "pharma", - 40 => "pharma", - } - - HIGHLIGHTED_CATEGORY_IDS = [255, 236, 23, 83, 208, 39].to_set - - def initialize - super - - # load existing topics - @topic_to_first_post_id = {} - PostCustomField.where(name: 'import_topic_mapping').uniq.pluck(:value).each do |m| - map = MultiJson.load(m) - @topic_to_first_post_id[map[0]] = map[1] - end - - # custom site settings - SiteSetting.title = "T Nation Forums" - SiteSetting.top_menu = "categories|latest|top|unread" - - SiteSetting.category_colors = "C03|A03" - SiteSetting.limit_suggested_to_category = true - SiteSetting.fixed_category_positions = true - SiteSetting.show_subcategory_list = true - SiteSetting.allow_uncategorized_topics = false - SiteSetting.uncategorized_description = nil - - SiteSetting.enable_badges = false - - SiteSetting.authorized_extensions = "jpg|jpeg|png|gif|svg" - SiteSetting.max_image_size_kb = 10_000.kilobytes - SiteSetting.max_attachment_size_kb = 10_000.kilobytes - end - - def execute - list_imported_user_ids - - import_users - import_categories - import_posts - - build_topic_mapping - - update_topic_views - close_locked_topics - - delete_banned_users - - download_avatars - - # TODO? handle edits? - - # TODO? mute_users (ignore_list) - - # TODO? watch_category (category_subscription, notify_category) - # TODO? watch_topic (topic_subscription) - end - - def list_imported_user_ids - puts "", "listing imported user_ids..." - - author_ids = forum_query <<-SQL - SELECT DISTINCT(author_id) - FROM forum_message - WHERE category_id IN (#{MIGRATED_CATEGORY_IDS_SQL}) - AND date >= '#{THRESHOLD_DATE}' - AND topic_id NOT IN (SELECT topicId FROM topicDelete) - SQL - - @imported_user_ids_sql = author_ids.to_a.map { |d| d["author_id"] }.join(",") - end - - def import_users - puts "", "importing users..." - - user_count = users_query("SELECT COUNT(id) AS count FROM user WHERE id IN (#{@imported_user_ids_sql})").first["count"] - - batches(BATCH_SIZE) do |offset| - users = users_query <<-SQL - SELECT id, username, email, active - FROM user - WHERE id IN (#{@imported_user_ids_sql}) - ORDER BY id - LIMIT #{BATCH_SIZE} - OFFSET #{offset} - SQL - - users = users.to_a - - break if users.size < 1 - - next if all_records_exist? :users, users.map {|u| u["id"].to_i} - - user_bios = {} - user_avatars = {} - user_properties = {} - user_ids_sql = users.map { |u| u["id"] }.join(",") - - # properties - attributes = users_query <<-SQL - SELECT userid, pkey AS "key", TRIM(COALESCE(pvalue, "")) AS "value" - FROM property - WHERE userid IN (#{user_ids_sql}) - AND LENGTH(TRIM(COALESCE(pvalue, ""))) > 0 - SQL - - attributes.each do |a| - user_properties[a["userid"]] ||= {} - user_properties[a["userid"]][a["key"]] = a["value"] - end - - # bios - bios = forum_query <<-SQL - SELECT uid, TRIM(COALESCE(quip, "")) AS "bio" - FROM myt_oneliner - WHERE uid IN (#{user_ids_sql}) - AND LENGTH(TRIM(COALESCE(quip, ""))) > 0 - SQL - - bios.each { |b| user_bios[b["uid"]] = b["bio"] } - - # avatars - avatars = forum_query <<-SQL - SELECT userid, filename - FROM forum_avatar - WHERE userid IN (#{user_ids_sql}) - AND width > 0 - AND height > 0 - SQL - - avatars.each { |a| user_avatars[a["userid"]] = a["filename"] } - - # actually create users - create_users(users, total: user_count, offset: offset) do |user| - properties = user_properties[user["id"]] || {} - name = "#{properties["fname"]} #{properties["lname"]}".strip - avatar_url = forum_avatar_url(user_avatars[user["id"]]) if user_avatars.include?(user["id"]) - - { - id: user["id"], - name: name.presence || user["username"], - username: user["username"], - email: user["email"], - created_at: properties["join_date"].presence || properties["JOIN_DATE"].presence, - active: user["active"], - website: properties["website"], - location: properties["LOCATION"].presence || properties["city"].presence, - date_of_birth: properties["BIRTHDATE"], - bio_raw: user_bios[user["id"]], - avatar_url: avatar_url, - post_create_action: proc do |new_user| - USER_CUSTOM_FIELDS.each do |field| - new_user.custom_fields[field.downcase] = properties[field] if properties.include?(field) - end - new_user.save - end - } - end - end - end - - def import_categories - puts "", "importing categories..." - - position = Category.count - - # create parent categories - create_categories(PARENT_CATEGORIES) do |c| - { - id: c.parameterize, - name: c, - description: c, - color: "A03", - position: position, - post_create_action: proc do position += 1; end - } - end - - # children categories - categories = forum_query <<-SQL - SELECT id, name, description, is_veteran - FROM forum_category - WHERE id IN (#{MIGRATED_CATEGORY_IDS_SQL}) - ORDER BY id - SQL - - create_categories(categories) do |category| - name = category["name"].strip - { - id: category["id"], - name: name, - description: category["description"].strip.presence || name, - position: MIGRATED_CATEGORY_IDS.index(category["id"]) + position, - parent_category_id: category_id_from_imported_category_id(PARENT_CATEGORY_ID[category["id"]]), - read_restricted: category["is_veteran"] == 1, - color: HIGHLIGHTED_CATEGORY_IDS.include?(category["id"]) ? "C03" : "A03", - } - end - end - - def import_posts - puts "", "importing posts..." - - post_count = forum_query <<-SQL - SELECT COUNT(id) AS count - FROM forum_message - WHERE author_id IN (#{@imported_user_ids_sql}) - AND category_id IN (#{MIGRATED_CATEGORY_IDS_SQL}) - AND date >= '#{THRESHOLD_DATE}' - AND topic_id NOT IN (SELECT topicId FROM topicDelete) - AND status = 1 - AND (edit_parent IS NULL OR edit_parent = -1) - AND topic_id > 0 - SQL - - post_count = post_count.first["count"] - - batches(BATCH_SIZE) do |offset| - posts = forum_query <<-SQL - SELECT fm.id, fm.category_id, fm.topic_id, fm.date, fm.author_id, fm.subject, fm.message, ft.sticky - FROM forum_message fm - LEFT JOIN forum_topic ft ON fm.topic_id = ft.id - WHERE fm.author_id IN (#{@imported_user_ids_sql}) - AND fm.category_id IN (#{MIGRATED_CATEGORY_IDS_SQL}) - AND fm.date >= '#{THRESHOLD_DATE}' - AND fm.topic_id NOT IN (SELECT topicId FROM topicDelete) - AND fm.status = 1 - AND (fm.edit_parent IS NULL OR fm.edit_parent = -1) - AND fm.topic_id > 0 - ORDER BY fm.id - LIMIT #{BATCH_SIZE} - OFFSET #{offset} - SQL - - posts = posts.to_a - - break if posts.size < 1 - next if all_records_exist? :posts, posts.map {|p| p['id'].to_i} - - # load images - forum_images = {} - message_ids_sql = posts.map { |p| p["id"] }.join(",") - - images = forum_query <<-SQL - SELECT message_id, filename - FROM forum_image - WHERE message_id IN (#{message_ids_sql}) - AND width > 0 - AND height > 0 - SQL - - images.each do |image| - forum_images[image["message_id"]] ||= [] - forum_images[image["message_id"]] << image["filename"] - end - - create_posts(posts, total: post_count, offset: offset) do |post| - raw = post["message"] - - if forum_images.include?(post["id"]) - forum_images[post["id"]].each do |filename| - raw = forum_image_url(filename) + "\n\n" + raw - end - end - - p = { - id: post["id"], - user_id: user_id_from_imported_user_id(post["author_id"]) || -1, - created_at: post["date"], - raw: raw, - custom_fields: {} - } - - if @topic_to_first_post_id.include?(post["topic_id"]) && t = topic_lookup_from_imported_post_id(@topic_to_first_post_id[post["topic_id"]]) - first_post_id = @topic_to_first_post_id[post["topic_id"]] - p[:topic_id] = t[:topic_id] - else - @topic_to_first_post_id[post["topic_id"]] = first_post_id = post["id"] - p[:title] = post["subject"].strip - p[:category] = category_id_from_imported_category_id(post["category_id"]) - p[:pinned_at] = post["date"] if post["sticky"] == 1 - end - - p[:custom_fields][:import_topic_mapping] = MultiJson.dump([post["topic_id"], first_post_id]) - - p - end - end - end - - def build_topic_mapping - puts "", "building topic mapping..." - - @existing_topics = {} - - PostCustomField.where(name: 'import_topic_mapping').uniq.pluck(:value).each do |m| - map = MultiJson.load(m) - @existing_topics[map[0]] = topic_lookup_from_imported_post_id(map[1])[:topic_id] - end - - @topic_ids_sql = @existing_topics.keys.join(",") - end - - def update_topic_views - puts "", "updating topic views..." - - topic_views = forum_query("SELECT topic_id, views FROM topic_views WHERE topic_id IN (#{@topic_ids_sql}) ORDER BY topic_id").to_a - update_topic_views_sql = topic_views.map { |tv| "UPDATE topics SET views = #{tv['views']} WHERE id = #{@existing_topics[tv['topic_id']]}" }.join(";") - postgresql_query(update_topic_views_sql) - end - - def close_locked_topics - puts "", "closing locked topics..." - - locked_topic_ids = forum_query("SELECT id FROM forum_topic WHERE id IN (#{@topic_ids_sql}) AND locked = 1 ORDER BY id").to_a.map { |d| d["id"] } - - current = 0 - max = locked_topic_ids.count - - locked_topic_ids.each do |id| - print_status(current += 1, max) - topic = Topic.find_by(id: @existing_topics[id]) - next if topic.blank? - topic.update_status("closed", true, Discourse.system_user) - end - end - - def delete_banned_users - puts "", "deleting banned users..." - - user_destroyer = UserDestroyer.new(Discourse.system_user) - - ids_from_banned_users = forum_query("SELECT user_id FROM banned_users WHERE user_id IN (#{@imported_user_ids_sql})").to_a.map { |d| @existing_users[d["user_id"]] } - ids_from_cookie_of_death = forum_query("SELECT userid FROM cookie_of_death WHERE userid IN (#{@imported_user_ids_sql})").to_a.map { |d| @existing_users[d["userid"]] } - - banned_user_ids = (ids_from_banned_users.to_set | ids_from_cookie_of_death.to_set).to_a - - current = 0 - max = User.where(id: banned_user_ids).count - - User.where(id: banned_user_ids.to_a).find_each do |user| - print_status(current += 1, max) - user_destroyer.destroy(user, delete_posts: true) - end - end - - def download_avatars - puts "", "downloading avatars..." - - current = 0 - max = UserCustomField.where(name: "import_avatar_url").count - - UserCustomField.where(name: "import_avatar_url").pluck(:user_id, :value).each do |user_id, avatar_url| - begin - print_status(current += 1, max) - user = User.find(user_id) - next unless user.uploaded_avatar_id.blank? - avatar = FileHelper.download(avatar_url, SiteSetting.max_image_size_kb.kilobytes, "avatar") - upload = Upload.create_for(user_id, avatar, File.basename(avatar_url), avatar.size) - if upload.persisted? - user.create_user_avatar - user.user_avatar.update(custom_upload_id: upload.id) - user.update(uploaded_avatar_id: upload.id) - end - avatar.try(:close!) rescue nil - rescue OpenURI::HTTPError, Net::ReadTimeout - end - end - end - - def forum_avatar_url(filename) - "http://images.t-nation.com/avatar_images/#{filename[0]}/#{filename[1]}/#{filename}" - end - - def forum_image_url(filename) - "http://images.t-nation.com/forum_images/#{filename[0]}/#{filename[1]}/#{filename}" - end - - # def forum_video_url(filename) - # "http://images.t-nation.com/forum_images/forum_video/fullSize/#{filename}.flv" - # end - - def forum_query(sql) - @biotest_forum ||= Mysql2::Client.new(username: "root", database: "biotest_forum") - @biotest_forum.query(sql) - end - - def users_query(sql) - @biotest_users ||= Mysql2::Client.new(username: "root", database: "biotest_users") - @biotest_users.query(sql) - end - - def postgresql_query(sql) - ActiveRecord::Base.connection.execute(sql) - end - -end - -ImportScripts::Tnation.new.perform diff --git a/script/import_scripts/vanilla_mysql.rb b/script/import_scripts/vanilla_mysql.rb index e472ce525b7..13237e7b87f 100644 --- a/script/import_scripts/vanilla_mysql.rb +++ b/script/import_scripts/vanilla_mysql.rb @@ -7,6 +7,7 @@ class ImportScripts::VanillaSQL < ImportScripts::Base VANILLA_DB = "vanilla_mysql" TABLE_PREFIX = "GDN_" BATCH_SIZE = 1000 + CONVERT_HTML = true def initialize super @@ -29,6 +30,10 @@ class ImportScripts::VanillaSQL < ImportScripts::Base def import_users puts '', "creating users" + @user_is_deleted = false + @last_deleted_username = nil + username = nil + total_count = mysql_query("SELECT count(*) count FROM #{TABLE_PREFIX}User;").first['count'] batches(BATCH_SIZE) do |offset| @@ -42,21 +47,37 @@ class ImportScripts::VanillaSQL < ImportScripts::Base break if results.size < 1 - next if all_records_exist? :users, users.map {|u| u['UserID'].to_i} + next if all_records_exist? :users, results.map {|u| u['UserID'].to_i} create_users(results, total: total_count, offset: offset) do |user| next if user['Email'].blank? next if user['Name'].blank? + + if user['Name'] == '[Deleted User]' + # EVERY deleted user record in Vanilla has the same username: [Deleted User] + # Save our UserNameSuggester some pain: + @user_is_deleted = true + username = @last_deleted_username || user['Name'] + else + @user_is_deleted = false + username = user['Name'] + end + { id: user['UserID'], email: user['Email'], - username: user['Name'], + username: username, name: user['Name'], created_at: user['DateInserted'] == nil ? 0 : Time.zone.at(user['DateInserted']), bio_raw: user['About'], registration_ip_address: user['InsertIPAddress'], last_seen_at: user['DateLastActive'] == nil ? 0 : Time.zone.at(user['DateLastActive']), location: user['Location'], - admin: user['Admin'] == 1 } + admin: user['Admin'] == 1, + post_create_action: proc do |newuser| + if @user_is_deleted + @last_deleted_username = newuser.username + end + end } end end end @@ -169,17 +190,19 @@ class ImportScripts::VanillaSQL < ImportScripts::Base # [SAMP]...[/SAMP] raw.gsub!(/\[\/?samp\]/i, "`") - # replace all chevrons with HTML entities - # NOTE: must be done - # - AFTER all the "code" processing - # - BEFORE the "quote" processing - raw = raw.gsub(/`([^`]+)`/im) { "`" + $1.gsub("<", "\u2603") + "`" } - .gsub("<", "<") - .gsub("\u2603", "<") + unless CONVERT_HTML + # replace all chevrons with HTML entities + # NOTE: must be done + # - AFTER all the "code" processing + # - BEFORE the "quote" processing + raw = raw.gsub(/`([^`]+)`/im) { "`" + $1.gsub("<", "\u2603") + "`" } + .gsub("<", "<") + .gsub("\u2603", "<") - raw = raw.gsub(/`([^`]+)`/im) { "`" + $1.gsub(">", "\u2603") + "`" } - .gsub(">", ">") - .gsub("\u2603", ">") + raw = raw.gsub(/`([^`]+)`/im) { "`" + $1.gsub(">", "\u2603") + "`" } + .gsub(">", ">") + .gsub("\u2603", ">") + end # [URL=...]...[/URL] raw.gsub!(/\[url="?(.+?)"?\](.+)\[\/url\]/i) { "[#{$2}](#{$1})" } @@ -224,7 +247,8 @@ class ImportScripts::VanillaSQL < ImportScripts::Base end def mysql_query(sql) - @client.query(sql, cache_rows: false) + @client.query(sql) + # @client.query(sql, cache_rows: false) #segfault: cache_rows: false causes segmentation fault end end diff --git a/script/import_scripts/vbulletin.rb b/script/import_scripts/vbulletin.rb index 22e5883db38..588e1ddff1d 100644 --- a/script/import_scripts/vbulletin.rb +++ b/script/import_scripts/vbulletin.rb @@ -210,7 +210,7 @@ class ImportScripts::VBulletin < ImportScripts::Base SQL break if topics.size < 1 - next if all_records_exist? :posts, topics.map {|t| "thread-#{topic["threadid"]}" } + next if all_records_exist? :posts, topics.map {|t| "thread-#{t["threadid"]}" } create_posts(topics, total: topic_count, offset: offset) do |topic| raw = preprocess_post_raw(topic["raw"]) rescue nil @@ -555,7 +555,7 @@ class ImportScripts::VBulletin < ImportScripts::Base end def mysql_query(sql) - @client.query(sql, cache_rows: false) + @client.query(sql, cache_rows: true) end end diff --git a/script/import_scripts/xenforo.rb b/script/import_scripts/xenforo.rb index 41f7cd15874..7cfd04b6d6f 100644 --- a/script/import_scripts/xenforo.rb +++ b/script/import_scripts/xenforo.rb @@ -42,7 +42,7 @@ class ImportScripts::XenForo < ImportScripts::Base break if results.size < 1 - next if all_records_exist? :users, users.map {|u| u["id"].to_i} + next if all_records_exist? :users, results.map {|u| u["id"].to_i} create_users(results, total: total_count, offset: offset) do |user| next if user['username'].blank? diff --git a/script/import_scripts/zoho.rb b/script/import_scripts/zoho.rb new file mode 100644 index 00000000000..99b15dcc64a --- /dev/null +++ b/script/import_scripts/zoho.rb @@ -0,0 +1,238 @@ + + + +### +### +### The output of this importer is bad. +### +### Improving it means getting better quality export data from Zoho, +### or doing a lot more work on this importer. +### +### Consider leaving data in Zoho and starting fresh in Discourse. +### +### + + + + + + + + + +# Import from Zoho. +# Be sure to get the posts CSV file, AND the user list csv file with people's email addresses. +# You may need to contact Zoho support for the user list. +# +# * Zoho data doesn't indicate which users are admins or moderators, so you'll need to grant +# those privileges manually after the import finishes. +# * The posts and users csv files don't seem to have consistent usernames, and sometimes use +# full names instead of usernames. This may cause duplicate users with slightly different +# usernames to be created. + +require 'csv' +require File.expand_path(File.dirname(__FILE__) + "/base.rb") +require File.expand_path(File.dirname(__FILE__) + "/base/csv_helper.rb") + +# Call it like this: +# bundle exec ruby script/import_scripts/zoho.rb +class ImportScripts::Zoho < ImportScripts::Base + + include ImportScripts::CsvHelper + + BATCH_SIZE = 1000 + + def initialize(path) + @path = path + @all_posts = [] + @categories = {} # key is the parent category, value is an array of sub-categories + @topic_mapping = {} + @current_row = nil + super() + end + + def execute + import_users + import_posts + update_tl0 + update_user_signup_date_based_on_first_post + end + + def cleanup_zoho_username(s) + s.strip.gsub(/[^A-Za-z0-9_\.\-]/, '') + end + + def import_users + puts "", "Importing users" + create_users( CSV.parse(File.read(File.join(@path, 'users.csv'))) ) do |u| + username = cleanup_zoho_username(u[0]) + { + id: username, + username: username, + email: u[1], + created_at: Time.zone.now + } + end + end + + def import_posts + # 0 Forum Name + # 1 Category Name + # 2 Topic Title + # 3 Permalink + # 4 Posted Time + # 5 Content + # 6 Author + # 7 Attachments + # 8 Votes + + count = 0 + + puts "", "Parsing posts CSV" + + csv_parse(File.join(@path, "posts.csv")) do |row| + @all_posts << row.dup + if @categories[row.forum_name].nil? + @categories[row.forum_name] = [] + end + + unless @categories[row.forum_name].include?(row.category_name) + @categories[row.forum_name] << row.category_name + end + end + + puts "", "Creating categories" + + # Create categories + @categories.each do |parent, subcats| + c = create_category({name: parent}, parent) + subcats.each do |subcat| + next if subcat == "Uncategorized" || subcat == "Uncategorised" + create_category({name: subcat, parent_category_id: c.id}, "#{parent}:#{subcat}") + end + end + + puts "", "Creating topics and posts" + + created, skipped = create_posts(@all_posts, total: @all_posts.size) do |row| + @current_row = row + + # fetch user + username = cleanup_zoho_username(row.author) + + next if username.blank? # no author for this post, so skip + + user_id = user_id_from_imported_user_id(username) + + if user_id.nil? + # user CSV file didn't have a user with this username. create it now with an invalid email address. + u = create_user( + { id: username, + username: username, + email: "#{username}@example.com", + created_at: Time.zone.parse(row.posted_time) }, + username + ) + user_id = u.id + end + + if @topic_mapping[row.permalink].nil? + category_id = nil + if row.category_name != "Uncategorized" && row.category_name != "Uncategorised" + category_id = category_id_from_imported_category_id("#{row.forum_name}:#{row.category_name}") + else + category_id = category_id_from_imported_category_id(row.forum_name) + end + + # create topic + { + id: import_post_id(row), + user_id: user_id, + category: category_id, + title: CGI.unescapeHTML(row.topic_title), + raw: cleanup_post(row.content), + created_at: Time.zone.parse(row.posted_time) + } + # created_post callback will be called + else + { + id: import_post_id(row), + user_id: user_id, + raw: cleanup_post(row.content), + created_at: Time.zone.parse(row.posted_time), + topic_id: @topic_mapping[row.permalink] + } + end + end + + puts "" + puts "Created: #{created}" + puts "Skipped: #{skipped}" + puts "" + end + + def created_post(post) + unless @topic_mapping[@current_row.permalink] + @topic_mapping[@current_row.permalink] = post.topic_id + end + end + + # Note that Zoho doesn't render code blocks the same way all the time, + # but this seems to catch the most common format: + ZOHO_CODE_BLOCK_START = /
      / + + TOO_MANY_LINE_BREAKS = /[\n ]{3,}/ + STYLE_ATTR = /(\s)*style="(.)*"/ + + def cleanup_post(raw) + + # Check if Zoho's most common form of a code block is present. + # If so, don't clean up the post as much because we can't tell which markup + # is inside the code block. These posts will look worse than others. + has_code_block = !!(raw =~ ZOHO_CODE_BLOCK_START) + + x = raw.gsub(STYLE_ATTR, '') + + if has_code_block + # We have to assume all lists in this post are meant to be code blocks + # to make it somewhat readable. + x.gsub!(/( )*
        (\s)*/, "") + x.gsub!(/( )*<\/ol>/, "") + x.gsub!('
      1. ', '') + x.gsub!('
      2. ', '') + else + # No code block (probably...) so clean up more aggressively. + x.gsub!("\n", " ") + x.gsub!('
        ', "\n\n") + x.gsub('
        ', ' ') + x.gsub!("
        ", "\n") + x.gsub!('', '') + x.gsub!('', '') + x.gsub!(/]*)>/, '') + x.gsub!('', '') + end + + x.gsub!(TOO_MANY_LINE_BREAKS, "\n\n") + + CGI.unescapeHTML(x) + end + + + def import_post_id(row) + # Try to make up a unique id based on the data Zoho gives us. + # The posted_time seems to be the same for all posts in a topic, so we can't use that. + Digest::SHA1.hexdigest "#{row.permalink}:#{row.content}" + end + +end + +unless ARGV[0] && Dir.exist?(ARGV[0]) + if ARGV[0] && !Dir.exist?(ARGV[0]) + puts "", "ERROR! Dir #{ARGV[0]} not found.", "" + end + + puts "", "Usage:", "", " bundle exec ruby script/import_scripts/zoho.rb DIRNAME", "" + exit 1 +end + +ImportScripts::Zoho.new(ARGV[0]).perform diff --git a/script/nginx_analyze.rb b/script/nginx_analyze.rb index bffcfe00927..90d415258a3 100644 --- a/script/nginx_analyze.rb +++ b/script/nginx_analyze.rb @@ -37,7 +37,7 @@ class LogAnalyzer end def is_mobile? - user_agent =~ /Mobile|webOS|Nexus 7/ && !(user_agent =~ /iPad/) + user_agent =~ /Mobile|Android|webOS/ && !(user_agent =~ /iPad|Nexus (7|10)/) end def parsed_time diff --git a/script/pull_translations.rb b/script/pull_translations.rb index 98da5ad419d..231482fcb26 100644 --- a/script/pull_translations.rb +++ b/script/pull_translations.rb @@ -6,6 +6,7 @@ # team will pull them in. require 'open3' +require_relative '../lib/locale_file_walker' if `which tx`.strip.empty? puts '', 'The Transifex client needs to be installed to use this script.' @@ -17,10 +18,11 @@ if `which tx`.strip.empty? exit 1 end -locales = Dir.glob(File.expand_path('../../config/locales/client.*.yml', __FILE__)).map {|x| x.split('.')[-2]}.select {|x| x != 'en'}.sort.join(',') +languages = Dir.glob(File.expand_path('../../config/locales/client.*.yml', __FILE__)) + .map { |x| x.split('.')[-2] }.select { |x| x != 'en' }.sort puts 'Pulling new translations...', '' -command = "tx pull --mode=developer --language=#{locales} #{ARGV.include?('force') ? '-f' : ''}" +command = "tx pull --mode=developer --language=#{languages.join(',')} #{ARGV.include?('force') ? '-f' : ''}" Open3.popen2e(command) do |stdin, stdout_err, wait_thr| while (line = stdout_err.gets) @@ -46,19 +48,180 @@ END YML_DIRS = ['config/locales', 'plugins/poll/config/locales', 'vendor/gems/discourse_imgur/lib/discourse_imgur/locale'] +YML_FILE_PREFIXES = ['server', 'client'] -# Add comments to the top of files -['client', 'server'].each do |base| - YML_DIRS.each do |dir| - Dir.glob(File.expand_path("../../#{dir}/#{base}.*.yml", __FILE__)).each do |file_name| - language = File.basename(file_name).match(Regexp.new("#{base}\\.([^\\.]*)\\.yml"))[1] +def yml_path(dir, prefix, language) + path = "../../#{dir}/#{prefix}.#{language}.yml" + path = File.expand_path(path, __FILE__) + File.exists?(path) ? path : nil +end - lines = File.readlines(file_name) - lines.collect! {|line| line =~ /^[a-z_]+:$/i ? "#{language}:" : line} +# Add comments to the top of files and replace the language (first key in YAML file) +def update_file_header(filename, language) + lines = File.readlines(filename) + lines.collect! {|line| line =~ /^[a-z_]+:$/i ? "#{language}:" : line} - File.open(file_name, 'w+') do |f| - f.puts(YML_FILE_COMMENTS, '') unless lines[0][0] == '#' - f.puts(lines) + File.open(filename, 'w+') do |f| + f.puts(YML_FILE_COMMENTS, '') unless lines[0][0] == '#' + f.puts(lines) + end +end + +class YamlAliasFinder < LocaleFileWalker + def initialize + @anchors = {} + @aliases = Hash.new { |hash, key| hash[key] = [] } + end + + def parse_file(filename) + document = Psych.parse_file(filename) + handle_document(document) + {anchors: @anchors, aliases: @aliases} + end + + private + + def handle_alias(node, depth, parents) + @aliases[node.anchor] << parents.dup + end + + def handle_mapping(node, depth, parents) + if node.anchor + @anchors[parents.dup] = node.anchor + end + end +end + +class YamlAliasSynchronizer < LocaleFileWalker + def initialize(original_alias_data) + @anchors = original_alias_data[:anchors] + @aliases = original_alias_data[:aliases] + @used_anchors = Set.new + + calculate_required_keys + end + + def add_to(filename) + stream = Psych.parse_stream(File.read(filename)) + stream.children.each { |document| handle_document(document) } + + add_aliases + write_yaml(stream, filename) + end + + private + + def calculate_required_keys + @required_keys = {} + + @aliases.each_value do |key_sets| + key_sets.each do |keys| + until keys.empty? + add_needed_node(keys) + keys = keys.dup + keys.pop + end + end + end + + add_needed_node([]) unless @required_keys.empty? + end + + def add_needed_node(keys) + @required_keys[keys] = {mapping: nil, scalar: nil, alias: nil} + end + + def write_yaml(stream, filename) + yaml = stream.to_yaml(nil, {:line_width => -1}) + + File.open(filename, 'w') do |file| + file.write(yaml) + end + end + + def handle_scalar(node, depth, parents) + super(node, depth, parents) + + if @required_keys.has_key?(parents) + @required_keys[parents][:scalar] = node + end + end + + def handle_alias(node, depth, parents) + if @required_keys.has_key?(parents) + @required_keys[parents][:alias] = node + end + end + + def handle_mapping(node, depth, parents) + if @anchors.has_key?(parents) + node.anchor = @anchors[parents] + @used_anchors.add(node.anchor) + end + + if @required_keys.has_key?(parents) + @required_keys[parents][:mapping] = node + end + end + + def add_aliases + @used_anchors.each do |anchor| + @aliases[anchor].each do |keys| + parents = [] + parent_node = @required_keys[[]] + + keys.each_with_index do |key, index| + parents << key + current_node = @required_keys[parents] + is_last = index == keys.size - 1 + add_node(current_node, parent_node, key, is_last ? anchor : nil) + parent_node = current_node + end + end + end + end + + def add_node(node, parent_node, scalar_name, anchor) + parent_mapping = parent_node[:mapping] + parent_mapping.children ||= [] + + if node[:scalar].nil? + node[:scalar] = Psych::Nodes::Scalar.new(scalar_name) + parent_mapping.children << node[:scalar] + end + + if anchor.nil? + if node[:mapping].nil? + node[:mapping] = Psych::Nodes::Mapping.new + parent_mapping.children << node[:mapping] + end + elsif node[:alias].nil? + parent_mapping.children << Psych::Nodes::Alias.new(anchor) + end + end +end + +def get_english_alias_data(dir, prefix) + filename = yml_path(dir, prefix, 'en') + filename ? YamlAliasFinder.new.parse_file(filename) : nil +end + +def add_anchors_and_aliases(english_alias_data, filename) + if english_alias_data + YamlAliasSynchronizer.new(english_alias_data).add_to(filename) + end +end + +YML_DIRS.each do |dir| + YML_FILE_PREFIXES.each do |prefix| + english_alias_data = get_english_alias_data(dir, prefix) + + languages.each do |language| + filename = yml_path(dir, prefix, language) + + if filename + add_anchors_and_aliases(english_alias_data, filename) + update_file_header(filename, language) end end end diff --git a/spec/components/active_record/connection_adapters/postgresql_fallback_adapter_spec.rb b/spec/components/active_record/connection_adapters/postgresql_fallback_adapter_spec.rb new file mode 100644 index 00000000000..05e6b68cd9e --- /dev/null +++ b/spec/components/active_record/connection_adapters/postgresql_fallback_adapter_spec.rb @@ -0,0 +1,135 @@ +require 'rails_helper' +require_dependency 'active_record/connection_adapters/postgresql_fallback_adapter' + +describe ActiveRecord::ConnectionHandling do + let(:replica_host) { "1.1.1.1" } + let(:replica_port) { 6432 } + + let(:config) do + ActiveRecord::Base.configurations[Rails.env].merge({ + "adapter" => "postgresql_fallback", + "replica_host" => replica_host, + "replica_port" => replica_port + }).symbolize_keys! + end + + let(:postgresql_fallback_handler) { PostgreSQLFallbackHandler.instance } + + after do + postgresql_fallback_handler.setup! + end + + describe "#postgresql_fallback_connection" do + it 'should return a PostgreSQL adapter' do + expect(ActiveRecord::Base.postgresql_fallback_connection(config)) + .to be_an_instance_of(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) + end + + context 'when master server is down' do + let(:multisite_db) { "database_2" } + + let(:multisite_config) do + { + host: 'localhost1', + port: 5432, + replica_host: replica_host, + replica_port: replica_port + } + end + + before do + @replica_connection = mock('replica_connection') + end + + after do + with_multisite_db(multisite_db) { Discourse.disable_readonly_mode } + Discourse.disable_readonly_mode + ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[Rails.env]) + end + + it 'should failover to a replica server' do + RailsMultisite::ConnectionManagement.stubs(:all_dbs).returns(['default', multisite_db]) + ::PostgreSQLFallbackHandler.instance.setup! + + [config, multisite_config].each do |configuration| + ActiveRecord::Base.expects(:postgresql_connection).with(configuration).raises(PG::ConnectionBad) + ActiveRecord::Base.expects(:verify_replica).with(@replica_connection) + + ActiveRecord::Base.expects(:postgresql_connection).with(configuration.merge({ + host: replica_host, port: replica_port + })).returns(@replica_connection) + end + + expect(postgresql_fallback_handler.master).to eq(true) + + expect { ActiveRecord::Base.postgresql_fallback_connection(config) } + .to raise_error(PG::ConnectionBad) + + expect{ ActiveRecord::Base.postgresql_fallback_connection(config) } + .to change{ Discourse.readonly_mode? }.from(false).to(true) + + expect(postgresql_fallback_handler.master).to eq(false) + + with_multisite_db(multisite_db) do + expect(postgresql_fallback_handler.master).to eq(true) + + expect { ActiveRecord::Base.postgresql_fallback_connection(multisite_config) } + .to raise_error(PG::ConnectionBad) + + expect{ ActiveRecord::Base.postgresql_fallback_connection(multisite_config) } + .to change{ Discourse.readonly_mode? }.from(false).to(true) + + expect(postgresql_fallback_handler.master).to eq(false) + end + + ActiveRecord::Base.unstub(:postgresql_connection) + + current_threads = Thread.list + + expect{ ActiveRecord::Base.connection_pool.checkout } + .to change{ Thread.list.size }.by(1) + + # Ensure that we don't try to connect back to the replica when a thread + # is running + begin + ActiveRecord::Base.postgresql_fallback_connection(config) + rescue PG::ConnectionBad => e + # This is expected if the thread finishes before the above is called. + end + + # Wait for the thread to finish execution + (Thread.list - current_threads).each(&:join) + + expect(Discourse.readonly_mode?).to eq(false) + + expect(PostgreSQLFallbackHandler.instance.master).to eq(true) + + expect(ActiveRecord::Base.connection_pool.connections.count).to eq(0) + + expect(ActiveRecord::Base.connection) + .to be_an_instance_of(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) + end + end + + context 'when both master and replica server is down' do + it 'should raise the right error' do + ActiveRecord::Base.expects(:postgresql_connection).with(config).raises(PG::ConnectionBad).once + + ActiveRecord::Base.expects(:postgresql_connection).with(config.dup.merge({ + host: replica_host, port: replica_port + })).raises(PG::ConnectionBad).once + + 2.times do + expect { ActiveRecord::Base.postgresql_fallback_connection(config) } + .to raise_error(PG::ConnectionBad) + end + end + end + end + + def with_multisite_db(dbname) + RailsMultisite::ConnectionManagement.expects(:current_db).returns(dbname).at_least_once + yield + RailsMultisite::ConnectionManagement.unstub(:current_db) + end +end diff --git a/spec/components/admin_user_index_query_spec.rb b/spec/components/admin_user_index_query_spec.rb index f07f59c5edb..071120bd95b 100644 --- a/spec/components/admin_user_index_query_spec.rb +++ b/spec/components/admin_user_index_query_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'admin_user_index_query' describe AdminUserIndexQuery do diff --git a/spec/components/archetype_spec.rb b/spec/components/archetype_spec.rb index a4cffe853ec..84d6164ea0a 100644 --- a/spec/components/archetype_spec.rb +++ b/spec/components/archetype_spec.rb @@ -1,6 +1,6 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require 'archetype' describe Archetype do diff --git a/spec/components/auth/default_current_user_provider_spec.rb b/spec/components/auth/default_current_user_provider_spec.rb index b8cbd5fe9a7..7cf69760735 100644 --- a/spec/components/auth/default_current_user_provider_spec.rb +++ b/spec/components/auth/default_current_user_provider_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'auth/default_current_user_provider' describe Auth::DefaultCurrentUserProvider do diff --git a/spec/components/auth/facebook_authenticator_spec.rb b/spec/components/auth/facebook_authenticator_spec.rb index 70c14491b72..5091ac56630 100644 --- a/spec/components/auth/facebook_authenticator_spec.rb +++ b/spec/components/auth/facebook_authenticator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' # In the ghetto ... getting the spec to run in autospec # thing is we need to load up all auth really early pre-fork diff --git a/spec/components/auth/google_oauth2_authenticator_spec.rb b/spec/components/auth/google_oauth2_authenticator_spec.rb index f14996e13cd..ecf5230d503 100644 --- a/spec/components/auth/google_oauth2_authenticator_spec.rb +++ b/spec/components/auth/google_oauth2_authenticator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' # For autospec: Auth.send(:remove_const, :GoogleOAuth2Authenticator) diff --git a/spec/components/auth/open_id_authenticator_spec.rb b/spec/components/auth/open_id_authenticator_spec.rb index 78fdc00ad2e..6b295dcc198 100644 --- a/spec/components/auth/open_id_authenticator_spec.rb +++ b/spec/components/auth/open_id_authenticator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' # In the ghetto ... getting the spec to run in autospec # thing is we need to load up all auth really early pre-fork diff --git a/spec/components/avatar_lookup_spec.rb b/spec/components/avatar_lookup_spec.rb index 9285360061c..539ef48a244 100644 --- a/spec/components/avatar_lookup_spec.rb +++ b/spec/components/avatar_lookup_spec.rb @@ -1,6 +1,6 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require_dependency 'avatar_lookup' describe AvatarLookup do diff --git a/spec/components/cache_spec.rb b/spec/components/cache_spec.rb index 385ab584285..387cea9e236 100644 --- a/spec/components/cache_spec.rb +++ b/spec/components/cache_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'cache' describe Cache do diff --git a/spec/components/common_passwords/common_passwords_spec.rb b/spec/components/common_passwords/common_passwords_spec.rb index f1213432810..483a67c0e59 100644 --- a/spec/components/common_passwords/common_passwords_spec.rb +++ b/spec/components/common_passwords/common_passwords_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" require_dependency "common_passwords/common_passwords" describe CommonPasswords do diff --git a/spec/components/composer_messages_finder_spec.rb b/spec/components/composer_messages_finder_spec.rb index 2a48b11a54f..9e7c20c4c97 100644 --- a/spec/components/composer_messages_finder_spec.rb +++ b/spec/components/composer_messages_finder_spec.rb @@ -1,5 +1,5 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require 'composer_messages_finder' describe ComposerMessagesFinder do @@ -109,6 +109,21 @@ describe ComposerMessagesFinder do UserHistory.create!(action: UserHistory.actions[:notified_about_avatar], target_user_id: user.id ) expect(finder.check_avatar_notification).to be_blank end + + it "doesn't notify users if 'disable_avatar_education_message' setting is enabled" do + SiteSetting.disable_avatar_education_message = true + expect(finder.check_avatar_notification).to be_blank + end + + it "doesn't notify users if 'sso_overrides_avatar' setting is enabled" do + SiteSetting.sso_overrides_avatar = true + expect(finder.check_avatar_notification).to be_blank + end + + it "doesn't notify users if 'allow_uploaded_avatars' setting is disabled" do + SiteSetting.allow_uploaded_avatars = false + expect(finder.check_avatar_notification).to be_blank + end end context '.check_sequential_replies' do @@ -137,7 +152,6 @@ describe ComposerMessagesFinder do context "reply" do let(:finder) { ComposerMessagesFinder.new(user, composerAction: 'reply', topic_id: topic.id) } - it "does not give a message to users who are still in the 'education' phase" do user.stubs(:post_count).returns(9) expect(finder.check_sequential_replies).to be_blank @@ -148,7 +162,6 @@ describe ComposerMessagesFinder do expect(finder.check_sequential_replies).to be_blank end - it "will notify you if it hasn't in the current topic" do UserHistory.create!(action: UserHistory.actions[:notified_about_sequential_replies], target_user_id: user.id, topic_id: topic.id+1 ) expect(finder.check_sequential_replies).to be_present @@ -164,6 +177,11 @@ describe ComposerMessagesFinder do expect(finder.check_sequential_replies).to be_blank end + it "doesn't notify in message" do + Topic.any_instance.expects(:private_message?).returns(true) + expect(finder.check_sequential_replies).to be_blank + end + context "success" do let!(:message) { finder.check_sequential_replies } @@ -310,4 +328,3 @@ describe ComposerMessagesFinder do end end - diff --git a/spec/components/concern/category_hashtag_spec.rb b/spec/components/concern/category_hashtag_spec.rb new file mode 100644 index 00000000000..c57ac891633 --- /dev/null +++ b/spec/components/concern/category_hashtag_spec.rb @@ -0,0 +1,34 @@ +require 'rails_helper' + +describe CategoryHashtag do + describe '#query_from_hashtag_slug' do + let(:parent_category) { Fabricate(:category) } + let(:child_category) { Fabricate(:category, parent_category: parent_category) } + + it "should return the right result for a parent category slug" do + expect(Category.query_from_hashtag_slug(parent_category.slug)) + .to eq(parent_category) + end + + it "should return the right result for a parent and child category slug" do + expect(Category.query_from_hashtag_slug("#{parent_category.slug}#{CategoryHashtag::SEPARATOR}#{child_category.slug}")) + .to eq(child_category) + end + + it "should return nil for incorrect parent category slug" do + expect(Category.query_from_hashtag_slug("random-slug")).to eq(nil) + end + + it "should return nil for incorrect parent and child category slug" do + expect(Category.query_from_hashtag_slug("random-slug#{CategoryHashtag::SEPARATOR}random-slug")).to eq(nil) + end + + it "should be case sensitive" do + parent_category.update_attributes!(slug: "ApPlE") + child_category.update_attributes!(slug: "OraNGE") + + expect(Category.query_from_hashtag_slug("apple")).to eq(nil) + expect(Category.query_from_hashtag_slug("apple:orange")).to eq(nil) + end + end +end diff --git a/spec/components/concern/has_custom_fields_spec.rb b/spec/components/concern/has_custom_fields_spec.rb index 48ef6110088..d429c13a8ea 100644 --- a/spec/components/concern/has_custom_fields_spec.rb +++ b/spec/components/concern/has_custom_fields_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe HasCustomFields do diff --git a/spec/components/concern/positionable_spec.rb b/spec/components/concern/positionable_spec.rb index 4e4b6d490ac..1bf08f63e17 100644 --- a/spec/components/concern/positionable_spec.rb +++ b/spec/components/concern/positionable_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe Positionable do diff --git a/spec/components/content_buffer_spec.rb b/spec/components/content_buffer_spec.rb index 8e6299896b1..f13492eb8ca 100644 --- a/spec/components/content_buffer_spec.rb +++ b/spec/components/content_buffer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'content_buffer' describe ContentBuffer do diff --git a/spec/components/cooked_post_processor_spec.rb b/spec/components/cooked_post_processor_spec.rb index 683fdf855a7..80071340064 100644 --- a/spec/components/cooked_post_processor_spec.rb +++ b/spec/components/cooked_post_processor_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" require "cooked_post_processor" describe CookedPostProcessor do @@ -114,13 +114,15 @@ describe CookedPostProcessor do # hmmm this should be done in a cleaner way OptimizedImage.expects(:resize).returns(true) + + FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0) end it "generates overlay information" do cpp.post_process_images - expect(cpp.html).to match_html '

        ' expect(cpp).to be_dirty end @@ -141,13 +143,14 @@ describe CookedPostProcessor do # hmmm this should be done in a cleaner way OptimizedImage.expects(:resize).returns(true) + FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0) end it "generates overlay information" do cpp.post_process_images - expect(cpp.html).to match_html '

        ' expect(cpp).to be_dirty end @@ -264,6 +267,12 @@ describe CookedPostProcessor do expect(cpp.get_size("http://foo.bar/image2.png")).to eq([100, 200]) end + it "returns nil if FastImage can't get the original size" do + Discourse.store.class.any_instance.expects(:has_been_uploaded?).returns(true) + FastImage.expects(:size).returns(nil) + expect(cpp.get_size("http://foo.bar/image3.png")).to eq(nil) + end + end end @@ -341,9 +350,7 @@ describe CookedPostProcessor do it "uses schemaless url for uploads" do cpp.optimize_urls - expect(cpp.html).to match_html 'Link - Google - ' + expect(cpp.html).to match_html '

        Link

        Google

        text.txt (20 Bytes)

        ' end context "when CDN is enabled" do @@ -351,17 +358,20 @@ describe CookedPostProcessor do it "does use schemaless CDN url for http uploads" do Rails.configuration.action_controller.stubs(:asset_host).returns("http://my.cdn.com") cpp.optimize_urls - expect(cpp.html).to match_html 'Link - Google - ' + expect(cpp.html).to match_html '

        Link

        Google

        text.txt (20 Bytes)

        ' end it "does not use schemaless CDN url for https uploads" do Rails.configuration.action_controller.stubs(:asset_host).returns("https://my.cdn.com") cpp.optimize_urls - expect(cpp.html).to match_html 'Link - Google - ' + expect(cpp.html).to match_html '

        Link

        Google

        text.txt (20 Bytes)

        ' + end + + it "does not use CDN when login is required" do + SiteSetting.login_required = true + Rails.configuration.action_controller.stubs(:asset_host).returns("http://my.cdn.com") + cpp.optimize_urls + expect(cpp.html).to match_html '

        Link

        Google

        text.txt (20 Bytes)

        ' end end @@ -405,10 +415,10 @@ describe CookedPostProcessor do before { post.id = 42 } - it "ensures only one job is scheduled right after the ninja_edit_window" do + it "ensures only one job is scheduled right after the editing_grace_period" do Jobs.expects(:cancel_scheduled_job).with(:pull_hotlinked_images, post_id: post.id).once - delay = SiteSetting.ninja_edit_window + 1 + delay = SiteSetting.editing_grace_period + 1 Jobs.expects(:enqueue_in).with(delay.seconds, :pull_hotlinked_images, post_id: post.id, bypass_bump: false).once cpp.pull_hotlinked_images diff --git a/spec/components/crawler_detection_spec.rb b/spec/components/crawler_detection_spec.rb index 56b5d99becb..601fde6c338 100644 --- a/spec/components/crawler_detection_spec.rb +++ b/spec/components/crawler_detection_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'crawler_detection' describe CrawlerDetection do diff --git a/spec/components/current_user_spec.rb b/spec/components/current_user_spec.rb index 3f439d6a039..2cb1061e088 100644 --- a/spec/components/current_user_spec.rb +++ b/spec/components/current_user_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'current_user' describe CurrentUser do diff --git a/spec/components/demon/base_spec.rb b/spec/components/demon/base_spec.rb index 58a5811d8b9..1f1615fc63e 100644 --- a/spec/components/demon/base_spec.rb +++ b/spec/components/demon/base_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'demon/base' describe Demon do diff --git a/spec/components/directory_helper_spec.rb b/spec/components/directory_helper_spec.rb index 1620713fadb..18b4384ca21 100644 --- a/spec/components/directory_helper_spec.rb +++ b/spec/components/directory_helper_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'directory_helper' describe DirectoryHelper do diff --git a/spec/components/discourse_diff_spec.rb b/spec/components/discourse_diff_spec.rb index 37cb7357a87..c21737ad851 100644 --- a/spec/components/discourse_diff_spec.rb +++ b/spec/components/discourse_diff_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'discourse_diff' describe DiscourseDiff do diff --git a/spec/components/discourse_event_spec.rb b/spec/components/discourse_event_spec.rb index 281cb7e09d4..2a262822a2b 100644 --- a/spec/components/discourse_event_spec.rb +++ b/spec/components/discourse_event_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'discourse_event' describe DiscourseEvent do diff --git a/spec/components/discourse_hub_spec.rb b/spec/components/discourse_hub_spec.rb index 95d911a66bb..b9ebdee2828 100644 --- a/spec/components/discourse_hub_spec.rb +++ b/spec/components/discourse_hub_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'discourse_hub' describe DiscourseHub do diff --git a/spec/components/discourse_i18n_spec.rb b/spec/components/discourse_i18n_spec.rb new file mode 100644 index 00000000000..f41b9caafae --- /dev/null +++ b/spec/components/discourse_i18n_spec.rb @@ -0,0 +1,181 @@ +require 'rails_helper' +require 'i18n/backend/discourse_i18n' +require 'translation_override' + +describe I18n::Backend::DiscourseI18n do + + let(:backend) { I18n::Backend::DiscourseI18n.new } + + before do + I18n.reload! + backend.store_translations(:en, :foo => 'Foo in :en', :bar => 'Bar in :en', :wat => "Hello %{count}") + backend.store_translations(:en, :items => {:one => 'one item', :other => "%{count} items" }) + backend.store_translations(:de, :bar => 'Bar in :de') + backend.store_translations(:'de-AT', :baz => 'Baz in :de-AT') + end + + after do + I18n.locale = :en + I18n.reload! + end + + it 'translates the basics as expected' do + expect(backend.translate(:en, 'foo')).to eq("Foo in :en") + expect(backend.translate(:en, 'items', count: 1)).to eq("one item") + expect(backend.translate(:en, 'items', count: 3)).to eq("3 items") + expect(backend.translate(:en, 'wat', count: 3)).to eq("Hello 3") + end + + it 'can be searched by key or value' do + expect(backend.search(:en, 'fo')).to eq({'foo' => 'Foo in :en'}) + expect(backend.search(:en, 'foo')).to eq({'foo' => 'Foo in :en' }) + expect(backend.search(:en, 'Foo')).to eq({'foo' => 'Foo in :en' }) + expect(backend.search(:en, 'hello')).to eq({'wat' => 'Hello %{count}' }) + expect(backend.search(:en, 'items.one')).to eq({'items.one' => 'one item' }) + end + + it 'can return multiple results' do + results = backend.search(:en, 'item') + + expect(results['items.one']).to eq('one item') + expect(results['items.other']).to eq('%{count} items') + end + + it 'uses fallback locales for searching' do + expect(backend.search(:de, 'bar')).to eq({'bar' => 'Bar in :de'}) + expect(backend.search(:de, 'foo')).to eq({'foo' => 'Foo in :en'}) + end + + describe '#exists?' do + it 'returns true when a key is given that exists' do + expect(backend.exists?(:de, :bar)).to eq(true) + end + + it 'returns true when a key is given that exists in a fallback locale of the locale' do + expect(backend.exists?(:de, :foo)).to eq(true) + end + + it 'returns true when an existing key and an existing locale is given' do + expect(backend.exists?(:en, :foo)).to eq(true) + expect(backend.exists?(:de, :bar)).to eq(true) + expect(backend.exists?(:'de-AT', :baz)).to eq(true) + end + + it 'returns false when a non-existing key and an existing locale is given' do + expect(backend.exists?(:en, :bogus)).to eq(false) + expect(backend.exists?(:de, :bogus)).to eq(false) + expect(backend.exists?(:'de-AT', :bogus)).to eq(false) + end + + it 'returns true when a key is given which is missing from the given locale and exists in a fallback locale' do + expect(backend.exists?(:de, :foo)).to eq(true) + expect(backend.exists?(:'de-AT', :foo)).to eq(true) + end + + it 'returns true when a key is given which is missing from the given locale and all its fallback locales' do + expect(backend.exists?(:de, :baz)).to eq(false) + expect(backend.exists?(:'de-AT', :bogus)).to eq(false) + end + end + + describe 'with overrides' do + it 'returns the overridden key' do + TranslationOverride.upsert!('en', 'foo', 'Overwritten foo') + expect(I18n.translate('foo')).to eq('Overwritten foo') + + TranslationOverride.upsert!('en', 'foo', 'new value') + expect(I18n.translate('foo')).to eq('new value') + end + + it 'returns the overridden key after switching the locale' do + TranslationOverride.upsert!('en', 'foo', 'Overwritten foo in EN') + TranslationOverride.upsert!('de', 'foo', 'Overwritten foo in DE') + + expect(I18n.translate('foo')).to eq('Overwritten foo in EN') + I18n.locale = :de + expect(I18n.translate('foo')).to eq('Overwritten foo in DE') + end + + it "can be searched" do + TranslationOverride.upsert!('en', 'wat', 'Overwritten value') + expect(I18n.search('wat', backend: backend)).to eq({'wat' => 'Overwritten value'}) + expect(I18n.search('Overwritten', backend: backend)).to eq({'wat' => 'Overwritten value'}) + expect(I18n.search('Hello', backend: backend)).to eq({}) + end + + it 'supports disabling' do + orig_title = I18n.t('title') + TranslationOverride.upsert!('en', 'title', 'overridden title') + + I18n.overrides_disabled do + expect(I18n.translate('title')).to eq(orig_title) + end + expect(I18n.translate('title')).to eq('overridden title') + end + + it 'supports interpolation' do + TranslationOverride.upsert!('en', 'foo', 'hello %{world}') + I18n.backend.store_translations(:en, foo: 'bar') + expect(I18n.translate('foo', world: 'foo')).to eq('hello foo') + end + + it 'supports interpolation named count' do + TranslationOverride.upsert!('en', 'wat', 'goodbye %{count}') + I18n.backend.store_translations(:en, wat: 'bar') + expect(I18n.translate('wat', count: 123)).to eq('goodbye 123') + end + + it 'ignores interpolation named count if it is not applicable' do + TranslationOverride.upsert!('en', 'test', 'goodbye') + I18n.backend.store_translations(:en, test: 'foo') + I18n.backend.store_translations(:en, wat: 'bar') + expect(I18n.translate('wat', count: 1)).to eq('bar') + end + + it 'supports one and other' do + TranslationOverride.upsert!('en', 'items.one', 'one fish') + TranslationOverride.upsert!('en', 'items.other', '%{count} fishies') + I18n.backend.store_translations(:en, items: { one: 'one item', other: "%{count} items" }) + expect(I18n.translate('items', count: 13)).to eq('13 fishies') + expect(I18n.translate('items', count: 1)).to eq('one fish') + end + + it 'supports one and other when only a single pluralization key is overridden' do + TranslationOverride.upsert!('en', 'keys.magic.other', "no magic keys") + I18n.backend.store_translations(:en, keys: { magic: { one: 'one magic key', other: "%{count} magic keys" } }) + expect(I18n.translate('keys.magic', count: 1)).to eq("one magic key") + expect(I18n.translate('keys.magic', count: 2)).to eq("no magic keys") + end + + it 'supports ActiveModel::Naming#human' do + Fish = Class.new(ActiveRecord::Base) + + TranslationOverride.upsert!('en', 'fish', "fake fish") + I18n.backend.store_translations(:en, fish: "original fish") + + expect(Fish.model_name.human).to eq('Fish') + end + + describe "client json" do + it "is empty by default" do + expect(I18n.client_overrides_json('en')).to eq("{}") + end + + it "doesn't return server overrides" do + TranslationOverride.upsert!('en', 'foo', 'bar') + expect(I18n.client_overrides_json('en')).to eq("{}") + end + + it "returns client overrides" do + TranslationOverride.upsert!('en', 'js.foo', 'bar') + TranslationOverride.upsert!('en', 'admin_js.beep', 'boop') + json = ::JSON.parse(I18n.client_overrides_json('en')) + + expect(json).to be_present + expect(json['js.foo']).to eq('bar') + expect(json['admin_js.beep']).to eq('boop') + end + end + end + +end diff --git a/spec/components/discourse_plugin_registry_spec.rb b/spec/components/discourse_plugin_registry_spec.rb index 98c5709ac17..6c4d128e204 100644 --- a/spec/components/discourse_plugin_registry_spec.rb +++ b/spec/components/discourse_plugin_registry_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'discourse_plugin_registry' describe DiscoursePluginRegistry do diff --git a/spec/components/discourse_plugin_spec.rb b/spec/components/discourse_plugin_spec.rb index 8910b0f2ade..699447d74ba 100644 --- a/spec/components/discourse_plugin_spec.rb +++ b/spec/components/discourse_plugin_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'discourse_plugin' describe DiscoursePlugin do diff --git a/spec/components/discourse_redis_spec.rb b/spec/components/discourse_redis_spec.rb new file mode 100644 index 00000000000..c2d05c85dbe --- /dev/null +++ b/spec/components/discourse_redis_spec.rb @@ -0,0 +1,98 @@ +require 'rails_helper' + +describe DiscourseRedis do + let(:slave_host) { 'testhost' } + let(:slave_port) { 1234 } + + let(:config) do + DiscourseRedis.config.dup.merge({ + slave_host: 'testhost', slave_port: 1234, connector: DiscourseRedis::Connector + }) + end + + let(:fallback_handler) { DiscourseRedis::FallbackHandler.instance } + + context '.slave_host' do + it 'should return the right config' do + slave_config = DiscourseRedis.slave_config(config) + expect(slave_config[:host]).to eq(slave_host) + expect(slave_config[:port]).to eq(slave_port) + end + end + + context 'when redis connection is to a slave redis server' do + it 'should check the status of the master server' do + begin + fallback_handler.master = false + $redis.without_namespace.expects(:get).raises(Redis::CommandError.new("READONLY")) + fallback_handler.expects(:verify_master).once + $redis.get('test') + ensure + fallback_handler.master = true + end + end + end + + describe DiscourseRedis::Connector do + let(:connector) { DiscourseRedis::Connector.new(config) } + + it 'should return the master config when master is up' do + expect(connector.resolve).to eq(config) + end + + it 'should return the slave config when master is down' do + begin + Redis::Client.any_instance.expects(:call).raises(Redis::CannotConnectError).twice + expect { connector.resolve }.to raise_error(Redis::CannotConnectError) + + config = connector.resolve + + expect(config[:host]).to eq(slave_host) + expect(config[:port]).to eq(slave_port) + ensure + fallback_handler.master = true + end + end + + it "should return the slave config when master's hostname cannot be resolved" do + begin + error = RuntimeError.new('Name or service not known') + + Redis::Client.any_instance.expects(:call).raises(error).twice + expect { connector.resolve }.to raise_error(error) + + config = connector.resolve + + expect(config[:host]).to eq(slave_host) + expect(config[:port]).to eq(slave_port) + ensure + fallback_handler.master = true + end + end + + it "should raise the right error" do + error = RuntimeError.new('test error') + Redis::Client.any_instance.expects(:call).raises(error).twice + 2.times { expect { connector.resolve }.to raise_error(error) } + end + end + + describe DiscourseRedis::FallbackHandler do + describe '#initiate_fallback_to_master' do + it 'should fallback to the master server once it is up' do + begin + fallback_handler.master = false + Redis::Client.any_instance.expects(:call).with([:info]).returns(DiscourseRedis::FallbackHandler::MASTER_LINK_STATUS) + Redis::Client.any_instance.expects(:call).with([:client, [:kill, 'type', 'normal']]) + + fallback_handler.initiate_fallback_to_master + + expect(fallback_handler.master).to eq(true) + expect(Discourse.recently_readonly?).to eq(false) + ensure + fallback_handler.master = true + end + end + end + end +end diff --git a/spec/components/discourse_sass_compiler_spec.rb b/spec/components/discourse_sass_compiler_spec.rb index 1bd144f11e6..baa998cf3a4 100644 --- a/spec/components/discourse_sass_compiler_spec.rb +++ b/spec/components/discourse_sass_compiler_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'sass/discourse_sass_compiler' describe DiscourseSassCompiler do diff --git a/spec/components/discourse_spec.rb b/spec/components/discourse_spec.rb index 5765a6d425f..b8b108519e0 100644 --- a/spec/components/discourse_spec.rb +++ b/spec/components/discourse_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'discourse' describe Discourse do @@ -62,9 +62,9 @@ describe Discourse do expect(Discourse.site_contact_user).to eq(another_admin) end - it 'returns the first admin user otherwise' do + it 'returns the system user otherwise' do SiteSetting.stubs(:site_contact_username).returns(nil) - expect(Discourse.site_contact_user).to eq(admin) + expect(Discourse.site_contact_user.username).to eq("system") end end @@ -111,8 +111,12 @@ describe Discourse do end it "returns true when the key is present in redis" do - $redis.expects(:get).with(Discourse.readonly_mode_key).returns("1") - expect(Discourse.readonly_mode?).to eq(true) + begin + $redis.set(Discourse.readonly_mode_key, 1) + expect(Discourse.readonly_mode?).to eq(true) + ensure + $redis.del(Discourse.readonly_mode_key) + end end it "returns true when Discourse is recently read only" do @@ -121,6 +125,13 @@ describe Discourse do end end + context ".received_readonly!" do + it "sets the right time" do + time = Discourse.received_readonly! + expect(Discourse.last_read_only['default']).to eq(time) + end + end + context "#handle_exception" do class TempSidekiqLogger < Sidekiq::ExceptionHandler::Logger diff --git a/spec/components/discourse_stylesheets_spec.rb b/spec/components/discourse_stylesheets_spec.rb index c7be72e96da..ec3cead6e99 100644 --- a/spec/components/discourse_stylesheets_spec.rb +++ b/spec/components/discourse_stylesheets_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'sass/discourse_stylesheets' describe DiscourseStylesheets do diff --git a/spec/components/discourse_updates_spec.rb b/spec/components/discourse_updates_spec.rb index 185a163649e..7f3f1234af1 100644 --- a/spec/components/discourse_updates_spec.rb +++ b/spec/components/discourse_updates_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'discourse_updates' describe DiscourseUpdates do diff --git a/spec/components/distributed_cache_spec.rb b/spec/components/distributed_cache_spec.rb index a26f6fbbd32..f1deda95d28 100644 --- a/spec/components/distributed_cache_spec.rb +++ b/spec/components/distributed_cache_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'distributed_cache' describe DistributedCache do @@ -15,10 +15,11 @@ describe DistributedCache do c1 = DistributedCache.new("test1") c2 = DistributedCache.new("test1") - set = {a: 1, b: 1} set = Set.new set << 1 set << "b" + set << 92803984 + set << 93739739873973 c1["cats"] = set diff --git a/spec/components/distributed_memoizer_spec.rb b/spec/components/distributed_memoizer_spec.rb index 097797f803e..5639a6a30dd 100644 --- a/spec/components/distributed_memoizer_spec.rb +++ b/spec/components/distributed_memoizer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'distributed_memoizer' describe DistributedMemoizer do diff --git a/spec/components/distributed_mutex_spec.rb b/spec/components/distributed_mutex_spec.rb index d8a42ffbce8..e8b30827977 100644 --- a/spec/components/distributed_mutex_spec.rb +++ b/spec/components/distributed_mutex_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'distributed_mutex' describe DistributedMutex do diff --git a/spec/components/email/email_spec.rb b/spec/components/email/email_spec.rb index 95ac50c7970..fbdc3949478 100644 --- a/spec/components/email/email_spec.rb +++ b/spec/components/email/email_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'email' describe Email do diff --git a/spec/components/email/message_builder_spec.rb b/spec/components/email/message_builder_spec.rb index 7515dee03fc..05a4abd92d4 100644 --- a/spec/components/email/message_builder_spec.rb +++ b/spec/components/email/message_builder_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'email/message_builder' describe Email::MessageBuilder do @@ -181,6 +181,23 @@ describe Email::MessageBuilder do end + context "with unsubscribe_via_email_link true" do + let(:message_with_unsubscribe_via_email) { Email::MessageBuilder.new(to_address, + body: 'hello world', + add_unsubscribe_link: true, + add_unsubscribe_via_email_link: true, + unsubscribe_url: "/t/1234/unsubscribe") } + + it "can add an unsubscribe via email link" do + SiteSetting.stubs(:unsubscribe_via_email_footer).returns(true) + expect(message_with_unsubscribe_via_email.body).to match(/mailto:reply@#{Discourse.current_hostname}\?subject=unsubscribe/) + end + + it "does not add unsubscribe via email link without site setting set" do + expect(message_with_unsubscribe_via_email.body).to_not match(/mailto:reply@#{Discourse.current_hostname}\?subject=unsubscribe/) + end + end + end context "template_args" do diff --git a/spec/components/email/receiver_spec.rb b/spec/components/email/receiver_spec.rb index a94951d1840..01afbb6f89d 100644 --- a/spec/components/email/receiver_spec.rb +++ b/spec/components/email/receiver_spec.rb @@ -1,610 +1,330 @@ -# -*- encoding : utf-8 -*- - -require 'spec_helper' -require 'email/receiver' +require "rails_helper" +require "email/receiver" describe Email::Receiver do before do - SiteSetting.reply_by_email_address = "reply+%{reply_key}@appmail.adventuretime.ooo" - SiteSetting.email_in = false - SiteSetting.title = "Discourse" + SiteSetting.email_in = true + SiteSetting.reply_by_email_address = "reply+%{reply_key}@bar.com" end - describe 'parse_body' do - def test_parse_body(mail_string) - Email::Receiver.new(nil).parse_body(Mail::Message.new mail_string) + def email(email_name) + fixture_file("emails/#{email_name}.eml") + end + + def process(email_name) + Email::Receiver.new(email(email_name)).process! + end + + it "raises an EmptyEmailError when 'mail_string' is blank" do + expect { Email::Receiver.new(nil) }.to raise_error(Email::Receiver::EmptyEmailError) + expect { Email::Receiver.new("") }.to raise_error(Email::Receiver::EmptyEmailError) + end + + it "raises and UserNotFoundError when staged users are disabled" do + SiteSetting.enable_staged_users = false + expect { process(:user_not_found) }.to raise_error(Email::Receiver::UserNotFoundError) + end + + it "raises an AutoGeneratedEmailError when the mail is auto generated" do + expect { process(:auto_generated_precedence) }.to raise_error(Email::Receiver::AutoGeneratedEmailError) + expect { process(:auto_generated_header) }.to raise_error(Email::Receiver::AutoGeneratedEmailError) + end + + it "raises a NoBodyDetectedError when the body is blank" do + expect { process(:no_body) }.to raise_error(Email::Receiver::NoBodyDetectedError) + end + + it "raises an InactiveUserError when the sender is inactive" do + Fabricate(:user, email: "inactive@bar.com", active: false) + expect { process(:inactive_sender) }.to raise_error(Email::Receiver::InactiveUserError) + end + + it "raises a BlockedUserError when the sender has been blocked" do + Fabricate(:user, email: "blocked@bar.com", blocked: true) + expect { process(:blocked_sender) }.to raise_error(Email::Receiver::BlockedUserError) + end + + skip "doesn't raise an InactiveUserError when the sender is staged" do + Fabricate(:user, email: "staged@bar.com", active: false, staged: true) + expect { process(:staged_sender) }.not_to raise_error + end + + it "raises a BadDestinationAddress when destinations aren't matching any of the incoming emails" do + expect { process(:bad_destinations) }.to raise_error(Email::Receiver::BadDestinationAddress) + end + + context "reply" do + + let(:reply_key) { "4f97315cc828096c9cb34c6f1a0d6fe8" } + let(:user) { Fabricate(:user, email: "discourse@bar.com") } + let(:topic) { create_topic(user: user) } + let(:post) { create_post(topic: topic, user: user) } + let!(:email_log) { Fabricate(:email_log, reply_key: reply_key, user: user, topic: topic, post: post) } + + it "uses MD5 of 'mail_string' there is no message_id" do + mail_string = email(:missing_message_id) + expect { Email::Receiver.new(mail_string).process! }.to change { IncomingEmail.count } + expect(IncomingEmail.last.message_id).to eq(Digest::MD5.hexdigest(mail_string)) end - it "raises EmptyEmailError if the message is blank" do - expect { test_parse_body("") }.to raise_error(Email::Receiver::EmptyEmailError) + it "raises a ReplyUserNotMatchingError when the email address isn't matching the one we sent the notification to" do + expect { process(:reply_user_not_matching) }.to raise_error(Email::Receiver::ReplyUserNotMatchingError) end - it "raises EmptyEmailError if the message is not an email" do - expect { test_parse_body("asdf" * 30) }.to raise_error(Email::Receiver::EmptyEmailError) + it "raises a TopicNotFoundError when the topic was deleted" do + topic.update_columns(deleted_at: 1.day.ago) + expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicNotFoundError) end - it "raises EmptyEmailError if there is no reply content" do - expect { test_parse_body(fixture_file("emails/no_content_reply.eml")) }.to raise_error(Email::Receiver::EmptyEmailError) + it "raises a TopicClosedError when the topic was closed" do + topic.update_columns(closed: true) + expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicClosedError) end - skip "raises EmailUnparsableError if the headers are corrupted" do - expect { ; }.to raise_error(Email::Receiver::EmailUnparsableError) + it "raises an InvalidPost when there was an error while creating the post" do + expect { process(:too_small) }.to raise_error(Email::Receiver::InvalidPost) end - it "can parse the html section" do - expect(test_parse_body(fixture_file("emails/html_only.eml"))).to eq("The EC2 instance - I've seen that there tends to be odd and " + - "unrecommended settings on the Bitnami installs that I've checked out.") + it "raises an InvalidPost when there are too may mentions" do + SiteSetting.max_mentions_per_post = 1 + Fabricate(:user, username: "user1") + Fabricate(:user, username: "user2") + expect { process(:too_many_mentions) }.to raise_error(Email::Receiver::InvalidPost) end - it "supports a Dutch reply" do - expect(test_parse_body(fixture_file("emails/dutch.eml"))).to eq("Dit is een antwoord in het Nederlands.") + it "raises an InvalidPostAction when they aren't allowed to like a post" do + topic.update_columns(archived: true) + expect { process(:like) }.to raise_error(Email::Receiver::InvalidPostAction) end - it "supports a Hebrew reply" do - I18n.expects(:t).with('user_notifications.previous_discussion').returns('כלטוב') + it "works" do + expect { process(:text_reply) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("This is a text reply :)") + expect(topic.posts.last.via_email).to eq(true) + expect(topic.posts.last.cooked).not_to match(/
        HTML reply ;)") + + expect { process(:hebrew_reply) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("שלום! מה שלומך היום?") + + expect { process(:chinese_reply) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("您好! 你今天好吗?") + + expect { process(:reply_with_weird_encoding) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("This is a reply with a weird encoding.") end - it "supports a BIG5-encoded reply" do - I18n.expects(:t).with('user_notifications.previous_discussion').returns('媽!我上電視了!') - - # The force_encoding call is only needed for the test - it is passed on fine to the cooked post - expect(test_parse_body(fixture_file("emails/big5.eml"))).to eq("媽!我上電視了!") + it "prefers text over html" do + expect { process(:text_and_html_reply) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("This is the *text* part.") end - it "removes 'via' lines if they match the site title" do - SiteSetting.title = "Discourse" - - expect(test_parse_body(fixture_file("emails/via_line.eml"))).to eq("Hello this email has content!") + it "removes the 'on , wrote' quoting line" do + expect { process(:on_date_contact_wrote) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("This is the actual reply.") end - it "removes an 'on date wrote' quoting line" do - expect(test_parse_body(fixture_file("emails/on_wrote.eml"))).to eq("Sure, all you need to do is frobnicate the foobar and you'll be all set!") - end - - it "removes the 'Previous Discussion' marker" do - expect(test_parse_body(fixture_file("emails/previous.eml"))).to eq("This will not include the previous discussion that is present in this email.") + it "removes the 'Previous Replies' marker" do + expect { process(:previous_replies) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("This will not include the previous discussion that is present in this email.") end it "handles multiple paragraphs" do - expect(test_parse_body(fixture_file("emails/paragraphs.eml"))). - to eq( -"Is there any reason the *old* candy can't be be kept in silos while the new candy -is imported into *new* silos? - -The thing about candy is it stays delicious for a long time -- we can just keep -it there without worrying about it too much, imo. - -Thanks for listening." - ) + expect { process(:paragraphs) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("Do you like liquorice?\n\nI really like them. One could even say that I am *addicted* to liquorice. Anf if\nyou can mix it up with some anise, then I'm in heaven ;)") end - it "handles multiple paragraphs when parsing html" do - expect(test_parse_body(fixture_file("emails/html_paragraphs.eml"))). - to eq( -"Awesome! - -Pleasure to have you here! - -:boom:" - ) + it "handles invalid from header" do + expect { process(:invalid_from) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("This email was sent with an invalid from header field.") end - it "handles newlines" do - expect(test_parse_body(fixture_file("emails/newlines.eml"))). - to eq( -"This is my reply. -It is my best reply. -It will also be my *only* reply." - ) + describe 'Unsubscribing via email' do + let(:last_email) { ActionMailer::Base.deliveries.last } + + describe 'unsubscribe_subject.eml' do + it 'sends an email asking the user to confirm the unsubscription' do + expect { process("unsubscribe_subject") }.to change { ActionMailer::Base.deliveries.count }.by(1) + expect(last_email.to.length).to eq 1 + expect(last_email.from.length).to eq 1 + expect(last_email.from).to include "noreply@#{Discourse.current_hostname}" + expect(last_email.to).to include "discourse@bar.com" + expect(last_email.subject).to eq I18n.t(:"unsubscribe_mailer.subject_template").gsub("%{site_title}", SiteSetting.title) + end + + it 'does nothing unless unsubscribe_via_email is turned on' do + SiteSetting.stubs("unsubscribe_via_email").returns(false) + before_deliveries = ActionMailer::Base.deliveries.count + expect { process("unsubscribe_subject") }.to raise_error { Email::Receiver::BadDestinationAddress } + expect(before_deliveries).to eq ActionMailer::Base.deliveries.count + end + end + + describe 'unsubscribe_body.eml' do + it 'sends an email asking the user to confirm the unsubscription' do + expect { process("unsubscribe_body") }.to change { ActionMailer::Base.deliveries.count }.by(1) + expect(last_email.to.length).to eq 1 + expect(last_email.from.length).to eq 1 + expect(last_email.from).to include "noreply@#{Discourse.current_hostname}" + expect(last_email.to).to include "discourse@bar.com" + expect(last_email.subject).to eq I18n.t(:"unsubscribe_mailer.subject_template").gsub("%{site_title}", SiteSetting.title) + end + + it 'does nothing unless unsubscribe_via_email is turned on' do + SiteSetting.stubs(:unsubscribe_via_email).returns(false) + before_deliveries = ActionMailer::Base.deliveries.count + expect { process("unsubscribe_body") }.to raise_error { Email::Receiver::InvalidPost } + expect(before_deliveries).to eq ActionMailer::Base.deliveries.count + end + end end it "handles inline reply" do - expect(test_parse_body(fixture_file("emails/inline_reply.eml"))). - to eq( -"On Wed, Oct 8, 2014 at 11:12 AM, techAPJ wrote: - -> techAPJ -> November 28 -> -> Test reply. -> -> First paragraph. -> -> Second paragraph. -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in -> your browser. -> ------------------------------ -> Previous Replies codinghorror -> -> November 28 -> -> We're testing the latest GitHub email processing library which we are -> integrating now. -> -> https://github.com/github/email_reply_parser -> -> Go ahead and reply to this topic and I'll reply from various email clients -> for testing. -> ------------------------------ -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in -> your browser. -> -> To unsubscribe from these emails, visit your user preferences -> . -> - -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over -the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown -fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over -the lazy dog. The quick brown fox jumps over the lazy dog." - ) + expect { process(:inline_reply) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("> WAT November 28\n>\n> This is the previous post.\n\nAnd this is *my* reply :+1:") end - it "should not include previous replies" do - expect(test_parse_body(fixture_file("emails/previous_replies.eml"))).not_to match /Previous Replies/ + it "retrieves the first part of multiple replies" do + expect { process(:inline_mixed_replies) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("> WAT November 28\n>\n> This is the previous post.\n\nAnd this is *my* reply :+1:\n\n> This is another post.\n\nAnd this is **another** reply.") end - it "strips iPhone signature" do - expect(test_parse_body(fixture_file("emails/iphone_signature.eml"))).not_to match /Sent from my iPhone/ + it "strips mobile/webmail signatures" do + expect { process(:iphone_signature) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("This is not the signature you're looking for.") end - it "properly renders email reply from gmail web client" do - expect(test_parse_body(fixture_file("emails/gmail_web.eml"))). - to eq( -"### This is a reply from standard GMail in Google Chrome. - -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over -the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown -fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over -the lazy dog. The quick brown fox jumps over the lazy dog. - -Here's some **bold** text in Markdown. - -Here's a link http://example.com" - ) + it "strips 'original message' context" do + expect { process(:original_message) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("This is a reply :)") end - it "properly renders email reply from iOS default mail client" do - expect(test_parse_body(fixture_file("emails/ios_default.eml"))). - to eq( -"### this is a reply from iOS default mail + it "add the 'elided' part of the original message only for private messages" do + topic.update_columns(category_id: nil, archetype: Archetype.private_message) + topic.allowed_users << user + topic.save -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. - -Here's some **bold** markdown text. - -Here's a link http://example.com" - ) + expect { process(:original_message) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to eq("This is a reply :)\n\n
        \n···\n---Original Message---\nThis part should not be included\n
        ") end - it "properly renders email reply from Android 5 gmail client" do - expect(test_parse_body(fixture_file("emails/android_gmail.eml"))). - to eq( -"### this is a reply from Android 5 gmail + it "supports attached images" do + expect { process(:no_body_with_image) }.to change { topic.posts.count } + expect(topic.posts.last.raw).to match(// - expect(Upload.find_by(sha1: upload_sha)).not_to eq(nil) - end - - end - - # === Failure Conditions === - - describe "too_short.eml" do - let!(:reply_key) { '636ca428858779856c226bb145ef4fad' } - let!(:email_raw) { - fixture_file("emails/too_short.eml") - .gsub("TO", "reply+#{reply_key}@appmail.adventuretime.ooo") - .gsub("FROM", replying_user_email) - .gsub("SUBJECT", "re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux'") - } - - it "raises an InvalidPost error" do - SiteSetting.min_post_length = 5 - expect { receiver.process }.to raise_error(Email::Receiver::InvalidPost) - end - end - - describe "too_many_mentions.eml" do - let!(:reply_key) { '636ca428858779856c226bb145ef4fad' } - let!(:email_raw) { fixture_file("emails/too_many_mentions.eml") } - - it "raises an InvalidPost error" do - SiteSetting.max_mentions_per_post = 10 - (1..11).each do |i| - Fabricate(:user, username: "user#{i}").save - end - - expect { receiver.process }.to raise_error(Email::Receiver::InvalidPost) - end - end - - describe "auto response email replies should not be accepted" do - let!(:reply_key) { '636ca428858779856c226bb145ef4fad' } - let!(:email_raw) { fixture_file("emails/auto_reply.eml") } - it "raises a AutoGeneratedEmailError" do - expect { receiver.process }.to raise_error(Email::Receiver::AutoGeneratedEmailError) - end + it "ensures posts aren't dated in the future" do + expect { process(:from_the_future) }.to change { topic.posts.count } + expect(topic.posts.last.created_at).to be_within(1.minute).of(DateTime.now) end end - describe "posting reply to a closed topic" do - let(:reply_key) { raise "Override this in a lower describe block" } - let(:email_raw) { raise "Override this in a lower describe block" } - let(:receiver) { Email::Receiver.new(email_raw) } - let(:topic) { Fabricate(:topic, closed: true) } - let(:post) { Fabricate(:post, topic: topic, post_number: 1) } - let(:replying_user_email) { 'jake@adventuretime.ooo' } - let(:replying_user) { Fabricate(:user, email: replying_user_email, trust_level: 2) } - let(:email_log) { EmailLog.new(reply_key: reply_key, - post: post, - post_id: post.id, - topic_id: topic.id, - email_type: 'user_posted', - user: replying_user, - user_id: replying_user.id, - to_address: replying_user_email - ) } + context "new message to a group" do - before do - email_log.save + let!(:group) { Fabricate(:group, incoming_email: "team@bar.com|meat@bar.com") } + + it "handles encoded display names" do + expect { process(:encoded_display_name) }.to change(Topic, :count) + + topic = Topic.last + expect(topic.title).to eq("I need help") + expect(topic.private_message?).to eq(true) + expect(topic.allowed_groups).to include(group) + + user = topic.user + expect(user.staged).to eq(true) + expect(user.username).to eq("random.name") + expect(user.name).to eq("Случайная Имя") end - describe "should not create post" do - let!(:reply_key) { '59d8df8370b7e95c5a49fbf86aeb2c93' } - let!(:email_raw) { fixture_file("emails/valid_reply.eml") } - it "raises a TopicClosedError" do - expect { receiver.process }.to raise_error(Email::Receiver::TopicClosedError) - end - end - end - - describe "posting reply to a deleted topic" do - let(:reply_key) { raise "Override this in a lower describe block" } - let(:email_raw) { raise "Override this in a lower describe block" } - let(:receiver) { Email::Receiver.new(email_raw) } - let(:deleted_topic) { Fabricate(:deleted_topic) } - let(:post) { Fabricate(:post, topic: deleted_topic, post_number: 1) } - let(:replying_user_email) { 'jake@adventuretime.ooo' } - let(:replying_user) { Fabricate(:user, email: replying_user_email, trust_level: 2) } - let(:email_log) { EmailLog.new(reply_key: reply_key, - post: post, - post_id: post.id, - topic_id: deleted_topic.id, - email_type: 'user_posted', - user: replying_user, - user_id: replying_user.id, - to_address: replying_user_email - ) } - - before do - email_log.save + it "handles email with no subject" do + expect { process(:no_subject) }.to change(Topic, :count) + expect(Topic.last.title).to eq("Incoming email from some@one.com") end - describe "should not create post" do - let!(:reply_key) { '59d8df8370b7e95c5a49fbf86aeb2c93' } - let!(:email_raw) { fixture_file("emails/valid_reply.eml") } - it "raises a TopicNotFoundError" do - expect { receiver.process }.to raise_error(Email::Receiver::TopicNotFoundError) - end - end - end - - describe "posting a new topic" do - let(:category_destination) { raise "Override this in a lower describe block" } - let(:email_raw) { raise "Override this in a lower describe block" } - let(:allow_strangers) { false } - # ---- - let(:receiver) { Email::Receiver.new(email_raw) } - let(:user_email) { 'jake@adventuretime.ooo' } - let(:user) { Fabricate(:user, email: user_email, trust_level: 2)} - let(:category) { Fabricate(:category, email_in: category_destination, email_in_allow_strangers: allow_strangers) } - - before do - SiteSetting.email_in = true - user.save - category.save + it "invites everyone in the chain but emails configured as 'incoming' (via reply, group or category)" do + expect { process(:cc) }.to change(Topic, :count) + emails = Topic.last.allowed_users.pluck(:email) + expect(emails.size).to eq(3) + expect(emails).to include("someone@else.com", "discourse@bar.com", "wat@bar.com") end - describe "too_short.eml" do - let!(:category_destination) { 'incoming+amazing@appmail.adventuretime.ooo' } - let(:email_raw) { - fixture_file("emails/too_short.eml") - .gsub("TO", category_destination) - .gsub("FROM", user_email) - .gsub("SUBJECT", "A long subject that passes the checks") - } + it "associates email replies using both 'In-Reply-To' and 'References' headers" do + expect { process(:email_reply_1) }.to change(Topic, :count) - it "does not create a topic if the post fails" do - before_topic_count = Topic.count + topic = Topic.last - expect { receiver.process }.to raise_error(Email::Receiver::InvalidPost) + expect { process(:email_reply_2) }.to change { topic.posts.count } + expect { process(:email_reply_3) }.to change { topic.posts.count } - expect(Topic.count).to eq(before_topic_count) - end + # Why 5 when we only processed 3 emails? + # - 3 of them are indeed "regular" posts generated from the emails + # - The 2 others are "small action" posts automatically added because + # we invited 2 users (two@foo.com and three@foo.com) + expect(topic.posts.count).to eq(5) + # trash all but the 1st post + topic.ordered_posts[1..-1].each(&:trash!) + + expect { process(:email_reply_4) }.to change { topic.posts.count } + end + + it "supports any kind of attachments when 'allow_all_attachments_for_group_messages' is enabled" do + SiteSetting.allow_all_attachments_for_group_messages = true + expect { process(:attached_rb_file) }.to change(Topic, :count) + expect(Post.last.raw).to match(/discourse\.rb/) end end - def fill_email(mail, from, to, body = nil, subject = nil) - result = mail.gsub("FROM", from).gsub("TO", to) - if body - result.gsub!(/Hey.*/m, body) - end - if subject - result.sub!(/We .*/, subject) - end - result - end + context "new topic in a category" do - def process_email(opts) - incoming_email = fixture_file("emails/valid_incoming.eml") - email = fill_email(incoming_email, opts[:from], opts[:to], opts[:body], opts[:subject]) - Email::Receiver.new(email).process - end - - describe "with a valid email" do - let(:reply_key) { "59d8df8370b7e95c5a49fbf86aeb2c93" } - let(:to) { SiteSetting.reply_by_email_address.gsub("%{reply_key}", reply_key) } - - let(:valid_reply) { - reply = fixture_file("emails/valid_reply.eml") - to = SiteSetting.reply_by_email_address.gsub("%{reply_key}", reply_key) - fill_email(reply, "test@test.com", to) - } - - let(:receiver) { Email::Receiver.new(valid_reply) } - let(:post) { create_post } - let(:user) { post.user } - let(:email_log) { EmailLog.new(reply_key: reply_key, - post_id: post.id, - topic_id: post.topic_id, - user_id: post.user_id, - post: post, - user: user, - email_type: 'test', - to_address: 'test@test.com' - ) } - let(:reply_body) { -"I could not disagree more. I am obviously biased but adventure time is the -greatest show ever created. Everyone should watch it. - -- Jake out" } - - describe "with an email log" do - - it "extracts data" do - expect{ receiver.process }.to raise_error(Email::Receiver::EmailLogNotFound) - - email_log.save! - receiver.process - - expect(receiver.body).to eq(reply_body) - expect(receiver.email_log).to eq(email_log) - end + let!(:category) { Fabricate(:category, email_in: "category@bar.com|category@foo.com", email_in_allow_strangers: false) } + it "raises a StrangersNotAllowedError when 'email_in_allow_strangers' is disabled" do + expect { process(:new_user) }.to raise_error(Email::Receiver::StrangersNotAllowedError) end - end - - describe "processes an email to a category" do - before do - SiteSetting.email_in = true + it "raises an InsufficientTrustLevelError when user's trust level isn't enough" do + Fabricate(:user, email: "existing@bar.com", trust_level: 3) + SiteSetting.email_in_min_trust = 4 + expect { process(:existing_user) }.to raise_error(Email::Receiver::InsufficientTrustLevelError) end + it "works" do + user = Fabricate(:user, email: "existing@bar.com", trust_level: SiteSetting.email_in_min_trust) + group = Fabricate(:group) - it "correctly can target categories" do - to = "some@email.com" + group.add(user) + group.save - Fabricate(:category, email_in_allow_strangers: false, email_in: to) - SiteSetting.email_in_min_trust = TrustLevel[4].to_s - - # no email in for user - expect{ - process_email(from: "cobb@dob.com", to: "invalid@address.com") - }.to raise_error(Email::Receiver::BadDestinationAddress) - - # valid target invalid user - expect{ - process_email(from: "cobb@dob.com", to: to) - }.to raise_error(Email::Receiver::UserNotFoundError) - - # untrusted - user = Fabricate(:user) - expect{ - process_email(from: user.email, to: to) - }.to raise_error(Email::Receiver::UserNotSufficientTrustLevelError) - - # trusted - user.trust_level = 4 - user.save - - process_email(from: user.email, to: to) - expect(user.posts.count).to eq(1) - - # email too short - message = nil - begin - process_email(from: user.email, to: to, body: "x", subject: "this is my new topic title") - rescue Email::Receiver::InvalidPost => e - message = e.message - end - - expect(e.message).to include("too short") - end - - - it "blocks user in restricted group from creating topic" do - to = "some@email.com" - - restricted_user = Fabricate(:user, trust_level: 4) - restricted_group = Fabricate(:group) - restricted_group.add(restricted_user) - restricted_group.save - - category = Fabricate(:category, email_in_allow_strangers: false, email_in: to) - category.set_permissions(restricted_group => :readonly) + category.set_permissions(group => :create_post) category.save - expect{ - process_email(from: restricted_user.email, to: to) - }.to raise_error(Discourse::InvalidAccess) - end + # raises an InvalidAccess when the user doesn't have the privileges to create a topic + expect { process(:existing_user) }.to raise_error(Discourse::InvalidAccess) + category.update_columns(email_in_allow_strangers: true) - end - - - describe "processes an unknown email sender to category" do - before do - SiteSetting.email_in = true - end - - - it "rejects anon email" do - Fabricate(:category, email_in_allow_strangers: false, email_in: "bob@bob.com") - expect { process_email(from: "test@test.com", to: "bob@bob.com") }.to raise_error(Email::Receiver::UserNotFoundError) - end - - it "creates a topic for allowed category" do - Fabricate(:category, email_in_allow_strangers: true, email_in: "bob@bob.com") - process_email(from: "test@test.com", to: "bob@bob.com") - - # This is the current implementation but it is wrong, it should register an account - expect(Discourse.system_user.posts.order("id desc").limit(1).pluck(:raw).first).to include("Hey folks") - + # allows new user to create a topic + expect { process(:new_user) }.to change(Topic, :count) end end diff --git a/spec/components/email/renderer_spec.rb b/spec/components/email/renderer_spec.rb index 7800ae865a3..c546b8fd115 100644 --- a/spec/components/email/renderer_spec.rb +++ b/spec/components/email/renderer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'email/renderer' describe Email::Renderer do diff --git a/spec/components/email/sender_spec.rb b/spec/components/email/sender_spec.rb index 55f56e4c351..1fc6d71ad18 100644 --- a/spec/components/email/sender_spec.rb +++ b/spec/components/email/sender_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'email/sender' describe Email::Sender do @@ -7,7 +7,13 @@ describe Email::Sender do SiteSetting.expects(:disable_emails).returns(true) Mail::Message.any_instance.expects(:deliver_now).never message = Mail::Message.new(to: "hello@world.com" , body: "hello") - Email::Sender.new(message, :hello).send + expect(Email::Sender.new(message, :hello).send).to eq(nil) + end + + it "doesn't deliver mail when the message is of type NullMail" do + Mail::Message.any_instance.expects(:deliver_now).never + message = ActionMailer::Base::NullMail.new + expect(Email::Sender.new(message, :hello).send).to eq(nil) end it "doesn't deliver mail when the message is nil" do @@ -66,11 +72,14 @@ describe Email::Sender do context "adds a List-ID header to identify the forum" do before do - message.header['X-Discourse-Topic-Id'] = 5577 + category = Fabricate(:category, name: 'Name With Space') + topic = Fabricate(:topic, category_id: category.id) + message.header['X-Discourse-Topic-Id'] = topic.id end When { email_sender.send } Then { expect(message.header['List-ID']).to be_present } + Then { expect(message.header['List-ID'].to_s).to match('name-with-space') } end context "adds a Message-ID header even when topic id is not present" do diff --git a/spec/components/email/styles_spec.rb b/spec/components/email/styles_spec.rb index 3a190e9cc2d..1f8bb953bf1 100644 --- a/spec/components/email/styles_spec.rb +++ b/spec/components/email/styles_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'email' describe Email::Styles do diff --git a/spec/components/email_updater_spec.rb b/spec/components/email_updater_spec.rb new file mode 100644 index 00000000000..74ec89e2f2f --- /dev/null +++ b/spec/components/email_updater_spec.rb @@ -0,0 +1,135 @@ +require 'rails_helper' +require_dependency 'email_updater' + +describe EmailUpdater do + let(:old_email) { 'old.email@example.com' } + let(:new_email) { 'new.email@example.com' } + + it "provides better error message when a staged user has the same email" do + Fabricate(:user, staged: true, email: new_email) + + user = Fabricate(:user, email: old_email) + updater = EmailUpdater.new(user.guardian, user) + updater.change_to(new_email) + + expect(updater.errors).to be_present + expect(updater.errors.messages[:base].first).to be I18n.t("change_email.error_staged") + end + + context 'as a regular user' do + let(:user) { Fabricate(:user, email: old_email) } + let(:updater) { EmailUpdater.new(user.guardian, user) } + + before do + Jobs.expects(:enqueue).once.with(:user_email, has_entries(type: :confirm_new_email, to_address: new_email)) + updater.change_to(new_email) + @change_req = user.email_change_requests.first + end + + it "starts the new confirmation process" do + expect(updater.errors).to be_blank + + expect(@change_req).to be_present + expect(@change_req.change_state).to eq(EmailChangeRequest.states[:authorizing_new]) + + expect(@change_req.old_email).to eq(old_email) + expect(@change_req.new_email).to eq(new_email) + expect(@change_req.old_email_token).to be_blank + expect(@change_req.new_email_token.email).to eq(new_email) + end + + context 'confirming an invalid token' do + it "produces an error" do + updater.confirm('random') + expect(updater.errors).to be_present + expect(user.reload.email).not_to eq(new_email) + end + end + + context 'confirming a valid token' do + it "updates the user's email" do + Jobs.expects(:enqueue).once.with(:user_email, has_entries(type: :notify_old_email, to_address: old_email)) + updater.confirm(@change_req.new_email_token.token) + expect(updater.errors).to be_blank + expect(user.reload.email).to eq(new_email) + + @change_req.reload + expect(@change_req.change_state).to eq(EmailChangeRequest.states[:complete]) + end + end + + end + + context 'as a staff user' do + let(:user) { Fabricate(:moderator, email: old_email) } + let(:updater) { EmailUpdater.new(user.guardian, user) } + + before do + Jobs.expects(:enqueue).once.with(:user_email, has_entries(type: :confirm_old_email, to_address: old_email)) + updater.change_to(new_email) + @change_req = user.email_change_requests.first + end + + it "starts the old confirmation process" do + expect(updater.errors).to be_blank + + expect(@change_req.old_email).to eq(old_email) + expect(@change_req.new_email).to eq(new_email) + expect(@change_req).to be_present + expect(@change_req.change_state).to eq(EmailChangeRequest.states[:authorizing_old]) + + expect(@change_req.old_email_token.email).to eq(old_email) + expect(@change_req.new_email_token).to be_blank + end + + context 'confirming an invalid token' do + it "produces an error" do + updater.confirm('random') + expect(updater.errors).to be_present + expect(user.reload.email).not_to eq(new_email) + end + end + + context 'confirming a valid token' do + before do + Jobs.expects(:enqueue).once.with(:user_email, has_entries(type: :confirm_new_email, to_address: new_email)) + updater.confirm(@change_req.old_email_token.token) + @change_req.reload + end + + it "starts the new update process" do + expect(updater.errors).to be_blank + expect(user.reload.email).to eq(old_email) + + expect(@change_req.change_state).to eq(EmailChangeRequest.states[:authorizing_new]) + expect(@change_req.new_email_token).to be_present + end + + it "cannot be confirmed twice" do + updater.confirm(@change_req.old_email_token.token) + expect(updater.errors).to be_present + expect(user.reload.email).to eq(old_email) + + @change_req.reload + expect(@change_req.change_state).to eq(EmailChangeRequest.states[:authorizing_new]) + expect(@change_req.new_email_token.email).to eq(new_email) + end + + context "completing the new update process" do + before do + Jobs.expects(:enqueue).with(:user_email, has_entries(type: :notify_old_email, to_address: old_email)).never + updater.confirm(@change_req.new_email_token.token) + end + + it "updates the user's email" do + expect(updater.errors).to be_blank + expect(user.reload.email).to eq(new_email) + + @change_req.reload + expect(@change_req.change_state).to eq(EmailChangeRequest.states[:complete]) + end + end + end + end +end + diff --git a/spec/components/enum_spec.rb b/spec/components/enum_spec.rb index 58ab150ed1a..d7977e1ee96 100644 --- a/spec/components/enum_spec.rb +++ b/spec/components/enum_spec.rb @@ -1,38 +1,52 @@ -require 'spec_helper' +require 'rails_helper' require 'email' describe Enum do - let(:enum) { Enum.new(:jake, :finn, :princess_bubblegum, :peppermint_butler) } + let(:array_enum) { Enum.new(:jake, :finn, :princess_bubblegum, :peppermint_butler) } + let(:hash_enum) { Enum.new(jake: 1, finn: 2, princess_bubblegum: 3, peppermint_butler: 4) } describe ".[]" do it "looks up a number by symbol" do - expect(enum[:princess_bubblegum]).to eq(3) + expect(array_enum[:princess_bubblegum]).to eq(3) + expect(hash_enum[:princess_bubblegum]).to eq(3) end it "looks up a symbol by number" do - expect(enum[2]).to eq(:finn) + expect(array_enum[2]).to eq(:finn) + expect(hash_enum[2]).to eq(:finn) end end describe ".valid?" do it "returns true if a key exists" do - expect(enum.valid?(:finn)).to eq(true) + expect(array_enum.valid?(:finn)).to eq(true) + expect(hash_enum.valid?(:finn)).to eq(true) end it "returns false if a key does not exist" do - expect(enum.valid?(:obama)).to eq(false) + expect(array_enum.valid?(:obama)).to eq(false) + expect(hash_enum.valid?(:obama)).to eq(false) end end describe ".only" do it "returns only the values we ask for" do - expect(enum.only(:jake, :princess_bubblegum)).to eq({ jake: 1, princess_bubblegum: 3 }) + expect(array_enum.only(:jake, :princess_bubblegum)).to eq({ jake: 1, princess_bubblegum: 3 }) + expect(hash_enum.only(:jake, :princess_bubblegum)).to eq({ jake: 1, princess_bubblegum: 3 }) end end describe ".except" do it "returns everything but the values we ask to delete" do - expect(enum.except(:jake, :princess_bubblegum)).to eq({ finn: 2, peppermint_butler: 4 }) + expect(array_enum.except(:jake, :princess_bubblegum)).to eq({ finn: 2, peppermint_butler: 4 }) + expect(hash_enum.except(:jake, :princess_bubblegum)).to eq({ finn: 2, peppermint_butler: 4 }) + end + end + + context "allows to specify number of first enum member" do + it "number of first enum member should be 0 " do + start_enum = Enum.new(:jake, :finn, :princess_bubblegum, :peppermint_butler, start: 0) + expect(start_enum[:princess_bubblegum]).to eq(2) end end end diff --git a/spec/components/file_store/local_store_spec.rb b/spec/components/file_store/local_store_spec.rb index d3d523d7486..2ef9097a5c8 100644 --- a/spec/components/file_store/local_store_spec.rb +++ b/spec/components/file_store/local_store_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'file_store/local_store' describe FileStore::LocalStore do diff --git a/spec/components/file_store/s3_store_spec.rb b/spec/components/file_store/s3_store_spec.rb index ae598889484..8b9a6309f56 100644 --- a/spec/components/file_store/s3_store_spec.rb +++ b/spec/components/file_store/s3_store_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'file_store/s3_store' require 'file_store/local_store' diff --git a/spec/components/filter_best_posts_spec.rb b/spec/components/filter_best_posts_spec.rb index ca04ee7834a..565e7fe6cf9 100644 --- a/spec/components/filter_best_posts_spec.rb +++ b/spec/components/filter_best_posts_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'filter_best_posts' require 'topic_view' diff --git a/spec/components/flag_query_spec.rb b/spec/components/flag_query_spec.rb index de6f0fb0e2f..9609ab6acc3 100644 --- a/spec/components/flag_query_spec.rb +++ b/spec/components/flag_query_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'flag_query' describe FlagQuery do diff --git a/spec/components/freedom_patches/pool_drainer_spec.rb b/spec/components/freedom_patches/pool_drainer_spec.rb index ad44e37af36..e46abe9a84e 100644 --- a/spec/components/freedom_patches/pool_drainer_spec.rb +++ b/spec/components/freedom_patches/pool_drainer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'pool drainer' do let(:pool) do diff --git a/spec/components/freedom_patches/safe_buffer_spec.rb b/spec/components/freedom_patches/safe_buffer_spec.rb index 61bba0de9ec..0f61435015f 100644 --- a/spec/components/freedom_patches/safe_buffer_spec.rb +++ b/spec/components/freedom_patches/safe_buffer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency "freedom_patches/safe_buffer" describe ActiveSupport::SafeBuffer do diff --git a/spec/components/freedom_patches/schema_migration_details_spec.rb b/spec/components/freedom_patches/schema_migration_details_spec.rb new file mode 100644 index 00000000000..951f5f7c4f0 --- /dev/null +++ b/spec/components/freedom_patches/schema_migration_details_spec.rb @@ -0,0 +1,31 @@ +require 'rails_helper' +require_dependency "freedom_patches/schema_migration_details" + +describe FreedomPatches::SchemaMigrationDetails do + + # we usually don't really need this model so lets not clutter up with it + class SchemaMigrationDetail < ActiveRecord::Base + end + + class TestMigration < ActiveRecord::Migration + def up + sleep 0.001 + end + end + + it "logs information on migration" do + migration = TestMigration.new("awesome_migration","20160225050318") + + ActiveRecord::Base.connection_pool.with_connection do |conn| + migration.exec_migration(conn, :up) + end + + info = SchemaMigrationDetail.find_by(version: "20160225050318") + + expect(info.duration).to be > 0 + expect(info.git_version).to eq Discourse.git_version + expect(info.direction).to eq "up" + expect(info.rails_version).to eq Rails.version + expect(info.name).to eq "awesome_migration" + end +end diff --git a/spec/components/gaps_spec.rb b/spec/components/gaps_spec.rb index 780d297ef08..2e76b16d1ff 100644 --- a/spec/components/gaps_spec.rb +++ b/spec/components/gaps_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'cache' describe Gaps do diff --git a/spec/components/global_path_spec.rb b/spec/components/global_path_spec.rb new file mode 100644 index 00000000000..41b778c9af3 --- /dev/null +++ b/spec/components/global_path_spec.rb @@ -0,0 +1,30 @@ +require 'rails_helper' +require 'global_path' + +class GlobalPathInstance + extend GlobalPath +end + +describe GlobalPath do + + context 'cdn_relative_path' do + def cdn_relative_path(p) + GlobalPathInstance.cdn_relative_path(p) + end + + it "just returns path for no cdn" do + expect(cdn_relative_path("/test")).to eq("/test") + end + + it "returns path when a cdn is defined with a path" do + GlobalSetting.expects(:cdn_url).returns("//something.com/foo") + expect(cdn_relative_path("/test")).to eq("/foo/test") + end + + it "returns path when a cdn is defined with a path" do + GlobalSetting.expects(:cdn_url).returns("https://something.com:221/foo") + expect(cdn_relative_path("/test")).to eq("/foo/test") + end + + end +end diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb index 66430c8f82d..8f5ef5ae10e 100644 --- a/spec/components/guardian_spec.rb +++ b/spec/components/guardian_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'guardian' require_dependency 'post_destroyer' @@ -7,6 +7,7 @@ describe Guardian do let(:user) { build(:user) } let(:moderator) { build(:moderator) } let(:admin) { build(:admin) } + let(:trust_level_2) { build(:user, trust_level: 2) } let(:trust_level_3) { build(:user, trust_level: 3) } let(:trust_level_4) { build(:user, trust_level: 4) } let(:another_admin) { build(:admin) } @@ -63,12 +64,20 @@ describe Guardian do end it "returns false for notify_user if private messages are disabled" do - SiteSetting.stubs(:enable_private_messages).returns(false) + SiteSetting.enable_private_messages = false user.trust_level = TrustLevel[2] expect(Guardian.new(user).post_can_act?(post, :notify_user)).to be_falsey expect(Guardian.new(user).post_can_act?(post, :notify_moderators)).to be_falsey end + it "returns false for notify_user if private messages are enabled but threshold not met" do + SiteSetting.enable_private_messages = true + SiteSetting.min_trust_to_send_messages = 2 + user.trust_level = TrustLevel[1] + expect(Guardian.new(user).post_can_act?(post, :notify_user)).to be_falsey + expect(Guardian.new(user).post_can_act?(post, :notify_moderators)).to be_truthy + end + describe "trust levels" do it "returns true for a new user liking something" do user.trust_level = TrustLevel[0] @@ -148,15 +157,21 @@ describe Guardian do expect(Guardian.new(user).can_send_private_message?(another_user)).to be_truthy end + it "disallows pms to other users if trust level is not met" do + SiteSetting.min_trust_to_send_messages = TrustLevel[2] + user.trust_level = TrustLevel[1] + expect(Guardian.new(user).can_send_private_message?(another_user)).to be_falsey + end + context "enable_private_messages is false" do - before { SiteSetting.stubs(:enable_private_messages).returns(false) } + before { SiteSetting.enable_private_messages = false } it "returns false if user is not the contact user" do expect(Guardian.new(user).can_send_private_message?(another_user)).to be_falsey end it "returns true for the contact user and system user" do - SiteSetting.stubs(:site_contact_username).returns(user.username) + SiteSetting.site_contact_username = user.username expect(Guardian.new(user).can_send_private_message?(another_user)).to be_truthy expect(Guardian.new(Discourse.system_user).can_send_private_message?(another_user)).to be_truthy end @@ -172,6 +187,30 @@ describe Guardian do expect(Guardian.new(user).can_send_private_message?(suspended_user)).to be_falsey end end + + context "author is blocked" do + before do + user.blocked = true + user.save + end + + it "returns true if target is staff" do + expect(Guardian.new(user).can_send_private_message?(admin)).to be_truthy + expect(Guardian.new(user).can_send_private_message?(moderator)).to be_truthy + end + + it "returns false if target is not staff" do + expect(Guardian.new(user).can_send_private_message?(another_user)).to be_falsey + end + + it "returns true if target is a staff group" do + Group::STAFF_GROUPS.each do |name| + g = Group[name] + g.alias_level = Group::ALIAS_LEVELS[:everyone] + expect(Guardian.new(user).can_send_private_message?(g)).to be_truthy + end + end + end end describe 'can_reply_as_new_topic' do @@ -277,7 +316,7 @@ describe Guardian do let(:admin) { Fabricate(:admin) } let(:private_category) { Fabricate(:private_category, group: group) } let(:group_private_topic) { Fabricate(:topic, category: private_category) } - let(:group_manager) { group_private_topic.user.tap { |u| group.add(u); group.appoint_manager(u) } } + let(:group_owner) { group_private_topic.user.tap { |u| group.add_owner(u) } } it 'handles invitation correctly' do expect(Guardian.new(nil).can_invite_to?(topic)).to be_falsey @@ -302,12 +341,6 @@ describe Guardian do expect(Guardian.new(coding_horror).can_invite_to?(topic)).to be_falsey end - it 'returns false when local logins are disabled' do - SiteSetting.stubs(:enable_local_logins).returns(false) - expect(Guardian.new(moderator).can_invite_to?(topic)).to be_falsey - expect(Guardian.new(user).can_invite_to?(topic)).to be_falsey - end - it 'returns false for normal user on private topic' do expect(Guardian.new(user).can_invite_to?(private_topic)).to be_falsey end @@ -316,8 +349,8 @@ describe Guardian do expect(Guardian.new(admin).can_invite_to?(private_topic)).to be_truthy end - it 'returns true for a group manager' do - expect(Guardian.new(group_manager).can_invite_to?(group_private_topic)).to be_truthy + it 'returns true for a group owner' do + expect(Guardian.new(group_owner).can_invite_to?(group_private_topic)).to be_truthy end end @@ -345,6 +378,57 @@ describe Guardian do end end + describe 'a Category' do + + it 'allows public categories' do + public_category = build(:category, read_restricted: false) + expect(Guardian.new.can_see?(public_category)).to be_truthy + end + + it 'correctly handles secure categories' do + normal_user = build(:user) + staged_user = build(:user, staged: true) + admin_user = build(:user, admin: true) + + secure_category = build(:category, read_restricted: true) + expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey + expect(Guardian.new(staged_user).can_see?(secure_category)).to be_falsey + expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy + + secure_category = build(:category, read_restricted: true, email_in: "foo@bar.com") + expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey + expect(Guardian.new(staged_user).can_see?(secure_category)).to be_falsey + expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy + + secure_category = build(:category, read_restricted: true, email_in_allow_strangers: true) + expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey + expect(Guardian.new(staged_user).can_see?(secure_category)).to be_falsey + expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy + + secure_category = build(:category, read_restricted: true, email_in: "foo@bar.com", email_in_allow_strangers: true) + expect(Guardian.new(normal_user).can_see?(secure_category)).to be_falsey + expect(Guardian.new(staged_user).can_see?(secure_category)).to be_truthy + expect(Guardian.new(admin_user).can_see?(secure_category)).to be_truthy + end + + it 'allows members of an authorized group' do + user = Fabricate(:user) + group = Fabricate(:group) + + secure_category = Fabricate(:category) + secure_category.set_permissions(group => :readonly) + secure_category.save + + expect(Guardian.new(user).can_see?(secure_category)).to be_falsey + + group.add(user) + group.save + + expect(Guardian.new(user).can_see?(secure_category)).to be_truthy + end + + end + describe 'a Topic' do it 'allows non logged in users to view topics' do expect(Guardian.new.can_see?(topic)).to be_truthy @@ -485,7 +569,7 @@ describe Guardian do it 'is true if the author has public edit history' do public_post_revision = Fabricate(:post_revision) - public_post_revision.post.user.edit_history_public = true + public_post_revision.post.user.user_option.edit_history_public = true expect(Guardian.new.can_see?(public_post_revision)).to be_truthy end end @@ -508,7 +592,7 @@ describe Guardian do it 'is true if the author has public edit history' do public_post_revision = Fabricate(:post_revision) - public_post_revision.post.user.edit_history_public = true + public_post_revision.post.user.user_option.edit_history_public = true expect(Guardian.new.can_see?(public_post_revision)).to be_truthy end end @@ -652,11 +736,34 @@ describe Guardian do it "doesn't allow new posts from admins" do expect(Guardian.new(admin).can_create?(Post, topic)).to be_falsey end - end + context "private message" do + let(:private_message) { Fabricate(:topic, archetype: Archetype.private_message, category_id: nil) } - end + before { user.save! } + + it "allows new posts by people included in the pm" do + private_message.topic_allowed_users.create!(user_id: user.id) + expect(Guardian.new(user).can_create?(Post, private_message)).to be_truthy + end + + it "doesn't allow new posts by people not invited to the pm" do + expect(Guardian.new(user).can_create?(Post, private_message)).to be_falsey + end + + it "allows new posts from blocked users included in the pm" do + user.update_attribute(:blocked, true) + private_message.topic_allowed_users.create!(user_id: user.id) + expect(Guardian.new(user).can_create?(Post, private_message)).to be_truthy + end + + it "doesn't allow new posts from blocked users not invited to the pm" do + user.update_attribute(:blocked, true) + expect(Guardian.new(user).can_create?(Post, private_message)).to be_falsey + end + end + end # can_create? a Post end @@ -943,6 +1050,11 @@ describe Guardian do topic.archetype = 'private_message' expect(Guardian.new(trust_level_3).can_edit?(topic)).to eq(false) end + + it 'returns false at trust level 4' do + topic.archetype = 'private_message' + expect(Guardian.new(trust_level_4).can_edit?(topic)).to eq(false) + end end context 'archived' do @@ -956,8 +1068,12 @@ describe Guardian do expect(Guardian.new(admin).can_edit?(archived_topic)).to be_truthy end - it 'returns true at trust level 3' do - expect(Guardian.new(trust_level_3).can_edit?(archived_topic)).to be_truthy + it 'returns true at trust level 4' do + expect(Guardian.new(trust_level_4).can_edit?(archived_topic)).to be_truthy + end + + it 'returns false at trust level 3' do + expect(Guardian.new(trust_level_3).can_edit?(archived_topic)).to be_falsey end it 'returns false as a topic creator' do @@ -1990,16 +2106,54 @@ describe Guardian do end describe 'can_wiki?' do + let(:post) { build(:post, created_at: 1.minute.ago) } + it 'returns false for regular user' do - expect(Guardian.new(coding_horror).can_wiki?).to be_falsey + expect(Guardian.new(coding_horror).can_wiki?(post)).to be_falsey + end + + it "returns false when user does not satisfy trust level but owns the post" do + own_post = Fabricate(:post, user: trust_level_2) + expect(Guardian.new(trust_level_2).can_wiki?(own_post)).to be_falsey + end + + it "returns false when user satisfies trust level but tries to wiki someone else's post" do + SiteSetting.min_trust_to_allow_self_wiki = 2 + expect(Guardian.new(trust_level_2).can_wiki?(post)).to be_falsey + end + + it 'returns true when user satisfies trust level and owns the post' do + SiteSetting.min_trust_to_allow_self_wiki = 2 + own_post = Fabricate(:post, user: trust_level_2) + expect(Guardian.new(trust_level_2).can_wiki?(own_post)).to be_truthy end it 'returns true for admin user' do - expect(Guardian.new(admin).can_wiki?).to be_truthy + expect(Guardian.new(admin).can_wiki?(post)).to be_truthy end it 'returns true for trust_level_4 user' do - expect(Guardian.new(trust_level_4).can_wiki?).to be_truthy + expect(Guardian.new(trust_level_4).can_wiki?(post)).to be_truthy + end + + context 'post is older than post_edit_time_limit' do + let(:old_post) { build(:post, user: trust_level_2, created_at: 6.minutes.ago) } + before do + SiteSetting.min_trust_to_allow_self_wiki = 2 + SiteSetting.post_edit_time_limit = 5 + end + + it 'returns false when user satisfies trust level and owns the post' do + expect(Guardian.new(trust_level_2).can_wiki?(old_post)).to be_falsey + end + + it 'returns true for admin user' do + expect(Guardian.new(admin).can_wiki?(old_post)).to be_truthy + end + + it 'returns true for trust_level_4 user' do + expect(Guardian.new(trust_level_4).can_wiki?(post)).to be_truthy + end end end end diff --git a/spec/components/has_errors_spec.rb b/spec/components/has_errors_spec.rb index 9ea4d1a0682..f9b6876501c 100644 --- a/spec/components/has_errors_spec.rb +++ b/spec/components/has_errors_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'has_errors' describe HasErrors do diff --git a/spec/components/highlight_js/highlight_js_spec.rb b/spec/components/highlight_js/highlight_js_spec.rb index ec7e12db241..22010aeb984 100644 --- a/spec/components/highlight_js/highlight_js_spec.rb +++ b/spec/components/highlight_js/highlight_js_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'highlight_js/highlight_js' describe HighlightJs do diff --git a/spec/components/html_prettify_spec.rb b/spec/components/html_prettify_spec.rb new file mode 100644 index 00000000000..1f1b6fad2c3 --- /dev/null +++ b/spec/components/html_prettify_spec.rb @@ -0,0 +1,30 @@ +require 'rails_helper' +require 'html_prettify' + +describe HtmlPrettify do + + def t(source, expected) + expect(HtmlPrettify.render(source)).to eq(expected) + end + + it 'correctly prettifies html' do + t "

        All's well!

        ", "

        All’s well!

        " + t "

        Eatin' Lunch'.

        ", "

        Eatin’ Lunch’.

        " + t "

        a 1/4. is a fraction but not 1/4/2000

        ", "

        a ¼. is a fraction but not 1/4/2000

        " + t "

        Well that'll be the day

        ", "

        Well that’ll be the day

        " + t %(

        "Quoted text"

        ), %(

        “Quoted text”

        ) + t "

        I've been meaning to tell you ..

        ", "

        I’ve been meaning to tell you ..

        " + t "

        single `backticks` in HTML should be preserved

        ", "

        single `backticks` in HTML should be preserved

        " + t "

        double hyphen -- ndash --- mdash

        ", "

        double hyphen – ndash — mdash

        " + t "a long time ago...", "a long time ago…" + t "is 'this a mistake'?", "is ‘this a mistake’?" + t ERB::Util.html_escape("'that went well'"), "‘that went well’" + t '"that went well"', "“that went well”" + t ERB::Util.html_escape('"that went well"'), "“that went well”" + + t 'src="test.png"> yay', "src=“test.png”> yay" + + t ERB::Util.html_escape(' yay'), "<img src=“test.png”> yay" + end + +end diff --git a/spec/components/image_sizer_spec.rb b/spec/components/image_sizer_spec.rb index e8e705862fa..f371d6acd4b 100644 --- a/spec/components/image_sizer_spec.rb +++ b/spec/components/image_sizer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'image_sizer' describe ImageSizer do diff --git a/spec/components/import/normalize_spec.rb b/spec/components/import/normalize_spec.rb index 8175801e11b..3eff19f034a 100644 --- a/spec/components/import/normalize_spec.rb +++ b/spec/components/import/normalize_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" require_dependency "import/normalize" describe Import::Normalize do diff --git a/spec/components/js_locale_helper_spec.rb b/spec/components/js_locale_helper_spec.rb index 18d73d2df2d..337553f7fac 100644 --- a/spec/components/js_locale_helper_spec.rb +++ b/spec/components/js_locale_helper_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'js_locale_helper' describe JsLocaleHelper do @@ -173,6 +173,16 @@ describe JsLocaleHelper do ctx.load(Rails.root + 'app/assets/javascripts/locales/i18n.js') ctx.eval(js) end + + it "finds moment.js locale file for #{locale[:value]}" do + content = JsLocaleHelper.moment_locale(locale[:value]) + + if (locale[:value] == 'en') + expect(content).to eq('') + else + expect(content).to_not eq('') + end + end end end diff --git a/spec/components/json_error_spec.rb b/spec/components/json_error_spec.rb index cd0c469310a..eae021fe4c9 100644 --- a/spec/components/json_error_spec.rb +++ b/spec/components/json_error_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'json_error' shared_examples "a generic error" do diff --git a/spec/components/letter_avatar_spec.rb b/spec/components/letter_avatar_spec.rb index c044e1f4222..d19aa883d88 100644 --- a/spec/components/letter_avatar_spec.rb +++ b/spec/components/letter_avatar_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'letter_avatar' describe LetterAvatar do diff --git a/spec/components/middleware/anonymous_cache_spec.rb b/spec/components/middleware/anonymous_cache_spec.rb index 8bff0ae3318..8dce0e5bcc0 100644 --- a/spec/components/middleware/anonymous_cache_spec.rb +++ b/spec/components/middleware/anonymous_cache_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" require_dependency "middleware/anonymous_cache" describe Middleware::AnonymousCache::Helper do diff --git a/spec/components/middleware/request_tracker_spec.rb b/spec/components/middleware/request_tracker_spec.rb index cbb8b68d38a..12fd9fe5515 100644 --- a/spec/components/middleware/request_tracker_spec.rb +++ b/spec/components/middleware/request_tracker_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" require_dependency "middleware/request_tracker" describe Middleware::RequestTracker do diff --git a/spec/components/new_post_manager_spec.rb b/spec/components/new_post_manager_spec.rb index 2c45185c62d..955292e7b3a 100644 --- a/spec/components/new_post_manager_spec.rb +++ b/spec/components/new_post_manager_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'new_post_manager' describe NewPostManager do @@ -69,9 +69,10 @@ describe NewPostManager do end end - context 'with a high approval post count' do + context 'with a high approval post count and TL0' do before do SiteSetting.approve_post_count = 100 + topic.user.trust_level = 0 end it "will return an enqueue result" do result = NewPostManager.default_handler(manager) @@ -80,6 +81,29 @@ describe NewPostManager do end end + context 'with a high approval post count and TL1' do + before do + SiteSetting.approve_post_count = 100 + topic.user.trust_level = 1 + end + it "will return an enqueue result" do + result = NewPostManager.default_handler(manager) + expect(NewPostManager.queue_enabled?).to eq(true) + expect(result.action).to eq(:enqueued) + end + end + + context 'with a high approval post count, but TL2' do + before do + SiteSetting.approve_post_count = 100 + topic.user.trust_level = 2 + end + it "will return an enqueue result" do + result = NewPostManager.default_handler(manager) + expect(result).to be_nil + end + end + context 'with a high trust level setting' do before do SiteSetting.approve_unless_trust_level = 4 diff --git a/spec/components/new_post_result_spec.rb b/spec/components/new_post_result_spec.rb index 3c555e79315..3c1ad258a12 100644 --- a/spec/components/new_post_result_spec.rb +++ b/spec/components/new_post_result_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'new_post_result' describe NewPostResult do diff --git a/spec/components/onebox/engine/discourse_local_onebox_spec.rb b/spec/components/onebox/engine/discourse_local_onebox_spec.rb index 4ca2d8eaf3c..3646e97290a 100644 --- a/spec/components/onebox/engine/discourse_local_onebox_spec.rb +++ b/spec/components/onebox/engine/discourse_local_onebox_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Onebox::Engine::DiscourseLocalOnebox do it "matches for a topic url" do @@ -35,9 +35,14 @@ describe Onebox::Engine::DiscourseLocalOnebox do end it "returns some onebox goodness if post exists and can be seen" do - url = "#{Discourse.base_url}#{post2.url}" + url = "#{Discourse.base_url}#{post2.url}?source_topic_id=#{post2.topic_id+1}" Guardian.any_instance.stubs(:can_see?).returns(true) html = Onebox.preview(url).to_s + expect(html).to include(post2.excerpt) + expect(html).to include(post2.topic.title) + + url = "#{Discourse.base_url}#{post2.url}" + html = Onebox.preview(url).to_s expect(html).to include(post2.user.username) expect(html).to include(post2.excerpt) end @@ -55,11 +60,16 @@ describe Onebox::Engine::DiscourseLocalOnebox do end it "returns a link if not allowed to see the post" do - url = "#{topic.url}" + url = topic.url Guardian.any_instance.stubs(:can_see?).returns(false) expect(Onebox.preview(url).to_s).to eq("#{url}") end + it "replaces emoji in the title" do + topic.update_column(:title, "Who wants to eat a :hamburger:") + expect(Onebox.preview(topic.url).to_s).to match(/hamburger.png/) + end + it "returns some onebox goodness if post exists and can be seen" do SiteSetting.external_system_avatars_enabled = false url = "#{topic.url}" @@ -69,4 +79,81 @@ describe Onebox::Engine::DiscourseLocalOnebox do expect(html).to include("topic-info") end end + + context "for a link to an internal audio or video file" do + + it "returns nil if file type is not audio or video" do + url = "#{Discourse.base_url}/uploads/default/original/3X/5/c/24asdf42.pdf" + expect(Onebox.preview(url).to_s).to eq("") + end + + it "returns some onebox goodness for audio file" do + url = "#{Discourse.base_url}/uploads/default/original/3X/5/c/24asdf42.mp3" + html = Onebox.preview(url).to_s + expect(html).to eq("") + end + + it "returns some onebox goodness for video file" do + url = "#{Discourse.base_url}/uploads/default/original/3X/5/c/24asdf42.mp4" + html = Onebox.preview(url).to_s + expect(html).to eq("") + end + end + + context "When deployed to a subfolder" do + let(:base_url) { "http://test.localhost/subfolder" } + let(:base_uri) { "/subfolder" } + + before do + Discourse.stubs(:base_url).returns(base_url) + Discourse.stubs(:base_uri).returns(base_uri) + end + + it "matches for a topic url" do + url = "#{Discourse.base_url}/t/hot-topic" + expect(Onebox.has_matcher?(url)).to eq(true) + expect(Onebox::Matcher.new(url).oneboxed).to eq(described_class) + end + + it "matches for a post url" do + url = "#{Discourse.base_url}/t/hot-topic/23/2" + expect(Onebox.has_matcher?(url)).to eq(true) + expect(Onebox::Matcher.new(url).oneboxed).to eq(described_class) + end + + context "for a link to a post" do + let(:post) { Fabricate(:post) } + let(:post2) { Fabricate(:post, topic: post.topic, post_number: 2) } + + it "returns a link if post isn't found" do + url = "#{Discourse.base_url}/t/not-exist/3/2" + expect(Onebox.preview(url).to_s).to eq("#{url}") + end + + it "returns a link if not allowed to see the post" do + url = "#{Discourse.base_url}#{post2.url}" + Guardian.any_instance.stubs(:can_see?).returns(false) + expect(Onebox.preview(url).to_s).to eq("#{url}") + end + + it "returns a link if post is hidden" do + hidden_post = Fabricate(:post, topic: post.topic, post_number: 2, hidden: true, hidden_reason_id: Post.hidden_reasons[:flag_threshold_reached]) + url = "#{Discourse.base_url}#{hidden_post.url}" + expect(Onebox.preview(url).to_s).to eq("#{url}") + end + + it "returns some onebox goodness if post exists and can be seen" do + url = "#{Discourse.base_url}#{post2.url}?source_topic_id=#{post2.topic_id+1}" + Guardian.any_instance.stubs(:can_see?).returns(true) + html = Onebox.preview(url).to_s + expect(html).to include(post2.excerpt) + expect(html).to include(post2.topic.title) + + url = "#{Discourse.base_url}#{post2.url}" + html = Onebox.preview(url).to_s + expect(html).to include(post2.user.username) + expect(html).to include(post2.excerpt) + end + end + end end diff --git a/spec/components/onebox/engine/flash_video_onebox_spec.rb b/spec/components/onebox/engine/flash_video_onebox_spec.rb index 0bcc1d3e913..d63ca37d3ab 100644 --- a/spec/components/onebox/engine/flash_video_onebox_spec.rb +++ b/spec/components/onebox/engine/flash_video_onebox_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'onebox/engine/flash_video_onebox' describe Onebox::Engine::FlashVideoOnebox do diff --git a/spec/components/oneboxer_spec.rb b/spec/components/oneboxer_spec.rb index 96f1524a393..7714d3f2c25 100644 --- a/spec/components/oneboxer_spec.rb +++ b/spec/components/oneboxer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'oneboxer' describe Oneboxer do diff --git a/spec/components/onpdiff_spec.rb b/spec/components/onpdiff_spec.rb index 09c6ff41dc3..0644edaaa8e 100644 --- a/spec/components/onpdiff_spec.rb +++ b/spec/components/onpdiff_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'onpdiff' describe ONPDiff do diff --git a/spec/components/pinned_check_spec.rb b/spec/components/pinned_check_spec.rb index 009de0e7cab..5845abcad3a 100644 --- a/spec/components/pinned_check_spec.rb +++ b/spec/components/pinned_check_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'pinned_check' describe PinnedCheck do diff --git a/spec/components/plugin/filter_manager_spec.rb b/spec/components/plugin/filter_manager_spec.rb index 1ff4ee96404..44e98d530e5 100644 --- a/spec/components/plugin/filter_manager_spec.rb +++ b/spec/components/plugin/filter_manager_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'plugin/filter_manager' describe Plugin::FilterManager do diff --git a/spec/components/plugin/instance_spec.rb b/spec/components/plugin/instance_spec.rb index fc87a425ed7..8fb270ba561 100644 --- a/spec/components/plugin/instance_spec.rb +++ b/spec/components/plugin/instance_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'plugin/instance' describe Plugin::Instance do diff --git a/spec/components/plugin/metadata_spec.rb b/spec/components/plugin/metadata_spec.rb index 782b9a6ed4b..4f8783b0d64 100644 --- a/spec/components/plugin/metadata_spec.rb +++ b/spec/components/plugin/metadata_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'plugin/metadata' describe Plugin::Metadata do diff --git a/spec/components/post_action_creator_spec.rb b/spec/components/post_action_creator_spec.rb new file mode 100644 index 00000000000..3b577fa4043 --- /dev/null +++ b/spec/components/post_action_creator_spec.rb @@ -0,0 +1,21 @@ +require 'rails_helper' +require 'post_action_creator' + +describe PostActionCreator do + let(:user) { Fabricate(:user) } + let(:post) { Fabricate(:post) } + let(:like_type_id) { PostActionType.types[:like] } + + + describe 'perform' do + it 'creates a post action' do + expect { PostActionCreator.new(user, post).perform(like_type_id) }.to change { PostAction.count }.by(1) + expect(PostAction.find_by(user: user, post: post, post_action_type_id: like_type_id)).to be_present + end + + it 'does not create an invalid post action' do + expect { PostActionCreator.new(user, nil).perform(like_type_id) }.to raise_error(Discourse::InvalidAccess) + end + end + +end diff --git a/spec/components/post_creator_spec.rb b/spec/components/post_creator_spec.rb index 5b492434229..6b5cf4602b0 100644 --- a/spec/components/post_creator_spec.rb +++ b/spec/components/post_creator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'post_creator' require 'topic_subtype' @@ -78,6 +78,7 @@ describe PostCreator do DiscourseEvent.expects(:trigger).with(:after_validate_topic, anything, anything).once DiscourseEvent.expects(:trigger).with(:before_create_topic, anything, anything).once DiscourseEvent.expects(:trigger).with(:after_trigger_post_process, anything).once + DiscourseEvent.expects(:trigger).with(:markdown_context, anything).at_least_once creator.create end @@ -324,13 +325,13 @@ describe PostCreator do end it "fails for dupe post accross topic" do - first = create_post - second = create_post + first = create_post(raw: "this is a test #{SecureRandom.hex}") + second = create_post(raw: "this is a test #{SecureRandom.hex}") dupe = "hello 123 test #{SecureRandom.hex}" - response_1 = create_post(raw: dupe, user: first.user, topic_id: first.topic_id) - response_2 = create_post(raw: dupe, user: first.user, topic_id: second.topic_id) + response_1 = PostCreator.create(first.user, raw: dupe, topic_id: first.topic_id) + response_2 = PostCreator.create(first.user, raw: dupe, topic_id: second.topic_id) expect(response_1.errors.count).to eq(0) expect(response_2.errors.count).to eq(1) @@ -445,7 +446,7 @@ describe PostCreator do raw: raw, cooking_options: { traditional_markdown_linebreaks: true }) - Post.any_instance.expects(:cook).with(raw, has_key(:traditional_markdown_linebreaks)).returns(raw) + Post.any_instance.expects(:cook).with(raw, has_key(:traditional_markdown_linebreaks)).twice.returns(raw) creator.create end end @@ -478,6 +479,13 @@ describe PostCreator do expect(unrelated.notifications.count).to eq(0) expect(post.topic.subtype).to eq(TopicSubtype.user_to_user) + # PMs do not increase post count or topic count + expect(post.user.user_stat.post_count).to eq(0) + expect(post.user.user_stat.topic_count).to eq(0) + + # archive this message and ensure archive is cleared for all users on reply + UserArchivedMessage.create(user_id: target_user2.id, topic_id: post.topic_id) + # if an admin replies they should be added to the allowed user list admin = Fabricate(:admin) PostCreator.create(admin, raw: 'hi there welcome topic, I am a mod', @@ -485,6 +493,18 @@ describe PostCreator do post.topic.reload expect(post.topic.topic_allowed_users.where(user_id: admin.id).count).to eq(1) + + expect(UserArchivedMessage.where(user_id: target_user2.id, topic_id: post.topic_id).count).to eq(0) + + # if another admin replies and is already member of the group, don't add them to topic_allowed_users + group = Fabricate(:group) + post.topic.topic_allowed_groups.create!(group: group) + admin2 = Fabricate(:admin) + group.add(admin2) + + PostCreator.create(admin2, raw: 'I am also an admin, and a mod', topic_id: post.topic_id) + + expect(post.topic.topic_allowed_users.where(user_id: admin2.id).count).to eq(0) end end @@ -544,7 +564,7 @@ describe PostCreator do target_group_names: group.name) end - it 'acts correctly' do + it 'can post to a group correctly' do expect(post.topic.archetype).to eq(Archetype.private_message) expect(post.topic.topic_allowed_users.count).to eq(1) expect(post.topic.topic_allowed_groups.count).to eq(1) @@ -590,12 +610,12 @@ describe PostCreator do describe "word_count" do it "has a word count" do - creator = PostCreator.new(user, title: 'some inspired poetry for a rainy day', raw: 'mary had a little lamb, little lamb, little lamb. mary had a little lamb') + creator = PostCreator.new(user, title: 'some inspired poetry for a rainy day', raw: 'mary had a little lamb, little lamb, little lamb. mary had a little lamb. Здравствуйте') post = creator.create - expect(post.word_count).to eq(14) + expect(post.word_count).to eq(15) post.topic.reload - expect(post.topic.word_count).to eq(14) + expect(post.topic.word_count).to eq(15) end end @@ -684,4 +704,19 @@ describe PostCreator do end end + context "staged users" do + let(:staged) { Fabricate(:staged) } + + it "automatically watches all messages it participates in" do + post = PostCreator.create(staged, + title: "this is the title of a topic created by a staged user", + raw: "this is the content of a topic created by a staged user ;)" + ) + topic_user = TopicUser.find_by(user_id: staged.id, topic_id: post.topic_id) + expect(topic_user.notification_level).to eq(TopicUser.notification_levels[:watching]) + expect(topic_user.notifications_reason_id).to eq(TopicUser.notification_reasons[:auto_watch]) + end + + end + end diff --git a/spec/components/post_destroyer_spec.rb b/spec/components/post_destroyer_spec.rb index a5a91c4c753..00573a5f4de 100644 --- a/spec/components/post_destroyer_spec.rb +++ b/spec/components/post_destroyer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'post_destroyer' describe PostDestroyer do diff --git a/spec/components/post_enqueuer_spec.rb b/spec/components/post_enqueuer_spec.rb index b7d6c372966..2e1bddad934 100644 --- a/spec/components/post_enqueuer_spec.rb +++ b/spec/components/post_enqueuer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'post_enqueuer' describe PostEnqueuer do diff --git a/spec/components/post_revisor_spec.rb b/spec/components/post_revisor_spec.rb index efcd03054a4..4667ede9cd3 100644 --- a/spec/components/post_revisor_spec.rb +++ b/spec/components/post_revisor_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'post_revisor' describe PostRevisor do @@ -74,7 +74,7 @@ describe PostRevisor do describe 'ninja editing' do it 'correctly applies edits' do - SiteSetting.stubs(:ninja_edit_window).returns(1.minute) + SiteSetting.stubs(:editing_grace_period).returns(1.minute) subject.revise!(post.user, { raw: 'updated body' }, revised_at: post.updated_at + 10.seconds) post.reload @@ -87,12 +87,12 @@ describe PostRevisor do end it "doesn't create a new version" do - SiteSetting.stubs(:ninja_edit_window).returns(1.minute) + SiteSetting.stubs(:editing_grace_period).returns(1.minute) # making a revision - subject.revise!(post.user, { raw: 'updated body' }, revised_at: post.updated_at + SiteSetting.ninja_edit_window + 1.seconds) + subject.revise!(post.user, { raw: 'updated body' }, revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds) # "roll back" - subject.revise!(post.user, { raw: 'Hello world' }, revised_at: post.updated_at + SiteSetting.ninja_edit_window + 2.seconds) + subject.revise!(post.user, { raw: 'Hello world' }, revised_at: post.updated_at + SiteSetting.editing_grace_period + 2.seconds) post.reload @@ -107,7 +107,7 @@ describe PostRevisor do let!(:revised_at) { post.updated_at + 2.minutes } before do - SiteSetting.stubs(:ninja_edit_window).returns(1.minute.to_i) + SiteSetting.stubs(:editing_grace_period).returns(1.minute.to_i) subject.revise!(post.user, { raw: 'updated body' }, revised_at: revised_at) post.reload end @@ -278,14 +278,14 @@ describe PostRevisor do describe 'with a new body' do let(:changed_by) { Fabricate(:coding_horror) } - let!(:result) { subject.revise!(changed_by, { raw: "lets update the body" }) } + let!(:result) { subject.revise!(changed_by, { raw: "lets update the body. Здравствуйте" }) } it 'returns true' do expect(result).to eq(true) end it 'updates the body' do - expect(post.raw).to eq("lets update the body") + expect(post.raw).to eq("lets update the body. Здравствуйте") end it 'sets the invalidate oneboxes attribute' do @@ -306,14 +306,14 @@ describe PostRevisor do end it "updates the word count" do - expect(post.word_count).to eq(4) + expect(post.word_count).to eq(5) post.topic.reload - expect(post.topic.word_count).to eq(4) + expect(post.topic.word_count).to eq(5) end context 'second poster posts again quickly' do before do - SiteSetting.stubs(:ninja_edit_window).returns(1.minute.to_i) + SiteSetting.stubs(:editing_grace_period).returns(1.minute.to_i) subject.revise!(changed_by, { raw: 'yet another updated body' }, revised_at: post.updated_at + 10.seconds) post.reload end diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index f9c7333c611..d01cd512751 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'pretty_text' describe PrettyText do @@ -8,10 +8,23 @@ describe PrettyText do describe "Cooking" do + describe "off topic quoting" do + it "can correctly populate topic title" do + topic = Fabricate(:topic, title: "this is a test topic") + expected = < +

        ddd

        +HTML + expect(PrettyText.cook("[quote=\"EvilTrout, post:2, topic:#{topic.id}\"]ddd\n[/quote]", topic_id: 1)).to match_html expected + end + end + describe "with avatar" do let(:default_avatar) { "//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/{size}.png" } - before(:each) do + before do eviltrout = User.new User.stubs(:default_template).returns(default_avatar) User.expects(:find_by).with(username_lower: "eviltrout").returns(eviltrout) @@ -35,6 +48,11 @@ describe PrettyText do expect(PrettyText.cook('@hello @hello @hello')).to match_html "

        @hello @hello @hello

        " end + it "should handle group mentions with a hyphen and without" do + expect(PrettyText.cook('@hello @hello-hello')).to match_html "

        @hello @hello-hello

        " + end + + it "should sanitize the html" do expect(PrettyText.cook("")).to match_html "

        " end @@ -170,6 +188,10 @@ describe PrettyText do expect(PrettyText.extract_links("\n").to_a).to be_empty end + it "doesn't extract links from elided parts" do + expect(PrettyText.extract_links("
        cnn
        \n").to_a).to be_empty + end + def extract_urls(text) PrettyText.extract_links(text).map(&:url).to_a end @@ -230,9 +252,14 @@ describe PrettyText do expect(PrettyText.excerpt("'", 500, text_entities: true)).to eq("'") end - it "should have an option to preserve emojis" do - emoji_image = "heart" - expect(PrettyText.excerpt(emoji_image, 100, { keep_emojis: true })).to match_html(emoji_image) + it "should have an option to preserve emoji images" do + emoji_image = "heart" + expect(PrettyText.excerpt(emoji_image, 100, { keep_emoji_images: true })).to match_html(emoji_image) + end + + it "should have an option to preserve emoji codes" do + emoji_code = ":heart:" + expect(PrettyText.excerpt(emoji_code, 100, { keep_emoji_codes: true })).to eq(":heart:") end end @@ -365,7 +392,29 @@ describe PrettyText do table = "
        test
        a
        " expect(PrettyText.cook(table)).to match_html("") end + end + describe "emoji" do + it "replaces unicode emoji with our emoji sets if emoji is enabled" do + expect(PrettyText.cook("💣")).to match(/\:bomb\:/) + end + + it "doesn't replace emoji in inline code blocks with our emoji sets if emoji is enabled" do + expect(PrettyText.cook("`💣`")).not_to match(/\:bomb\:/) + end + + it "doesn't replace emoji in code blocks with our emoji sets if emoji is enabled" do + expect(PrettyText.cook("```\n💣`\n```\n")).not_to match(/\:bomb\:/) + end + + it "replaces some glyphs that are not in the emoji range" do + expect(PrettyText.cook("☺")).to match(/\:slight_smile\:/) + end + + it "doesn't replace unicode emoji if emoji is disabled" do + SiteSetting.enable_emoji = false + expect(PrettyText.cook("💣")).not_to match(/\:bomb\:/) + end end end diff --git a/spec/components/promotion_spec.rb b/spec/components/promotion_spec.rb index 71d80a27381..d15ace0d4ba 100644 --- a/spec/components/promotion_spec.rb +++ b/spec/components/promotion_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'promotion' describe Promotion do diff --git a/spec/components/rate_limiter_spec.rb b/spec/components/rate_limiter_spec.rb index 1c264fb3d13..1cf43b11c9f 100644 --- a/spec/components/rate_limiter_spec.rb +++ b/spec/components/rate_limiter_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'rate_limiter' describe RateLimiter do @@ -39,6 +39,16 @@ describe RateLimiter do end end + context "remaining" do + it "updates correctly" do + expect(rate_limiter.remaining).to eq(2) + rate_limiter.performed! + expect(rate_limiter.remaining).to eq(1) + rate_limiter.performed! + expect(rate_limiter.remaining).to eq(0) + end + end + context "multiple calls" do before do rate_limiter.performed! @@ -47,6 +57,7 @@ describe RateLimiter do it "returns false for can_perform when the limit has been hit" do expect(rate_limiter.can_perform?).to eq(false) + expect(rate_limiter.remaining).to eq(0) end it "raises an error the third time called" do @@ -54,10 +65,10 @@ describe RateLimiter do end context "as an admin/moderator" do - it "returns true for can_perform if the user is an admin" do user.admin = true expect(rate_limiter.can_perform?).to eq(true) + expect(rate_limiter.remaining).to eq(2) end it "doesn't raise an error when an admin performs the task" do @@ -74,8 +85,6 @@ describe RateLimiter do user.moderator = true expect { rate_limiter.performed! }.not_to raise_error end - - end context "rollback!" do @@ -90,14 +99,9 @@ describe RateLimiter do it "raises no error now that there is room" do expect { rate_limiter.performed! }.not_to raise_error end - end end - end - - - end diff --git a/spec/components/redis_store_spec.rb b/spec/components/redis_store_spec.rb index d32e56d768e..c4180ed6ed2 100644 --- a/spec/components/redis_store_spec.rb +++ b/spec/components/redis_store_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'cache' describe "Redis Store" do diff --git a/spec/components/s3_helper_spec.rb b/spec/components/s3_helper_spec.rb index 4b1919785ad..0ee326b65b2 100644 --- a/spec/components/s3_helper_spec.rb +++ b/spec/components/s3_helper_spec.rb @@ -1,5 +1,5 @@ require "s3_helper" -require "spec_helper" +require "rails_helper" describe "S3Helper" do diff --git a/spec/components/scheduler/defer_spec.rb b/spec/components/scheduler/defer_spec.rb index 6f8d30ebf0e..49fbde58c74 100644 --- a/spec/components/scheduler/defer_spec.rb +++ b/spec/components/scheduler/defer_spec.rb @@ -1,5 +1,5 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require_dependency 'scheduler/defer' describe Scheduler::Defer do diff --git a/spec/components/scheduler/manager_spec.rb b/spec/components/scheduler/manager_spec.rb index 3f7fa93c87f..7261a79fe38 100644 --- a/spec/components/scheduler/manager_spec.rb +++ b/spec/components/scheduler/manager_spec.rb @@ -1,5 +1,5 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require 'scheduler/scheduler' describe Scheduler::Manager do diff --git a/spec/components/scheduler/schedule_info_spec.rb b/spec/components/scheduler/schedule_info_spec.rb index 96afbb8672a..fab1e2b0698 100644 --- a/spec/components/scheduler/schedule_info_spec.rb +++ b/spec/components/scheduler/schedule_info_spec.rb @@ -1,5 +1,5 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require 'scheduler/scheduler' describe Scheduler::ScheduleInfo do diff --git a/spec/components/score_calculator_spec.rb b/spec/components/score_calculator_spec.rb index 34694c317ec..bcf41ebaa97 100644 --- a/spec/components/score_calculator_spec.rb +++ b/spec/components/score_calculator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'score_calculator' describe ScoreCalculator do diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb index 462b1191126..7a0e580643b 100644 --- a/spec/components/search_spec.rb +++ b/spec/components/search_spec.rb @@ -1,6 +1,6 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require_dependency 'search' describe Search do @@ -85,6 +85,21 @@ describe Search do expect(result.users.length).to eq(1) expect(result.users[0].id).to eq(user.id) end + + context 'hiding user profiles' do + before { SiteSetting.stubs(:hide_user_profiles_from_public).returns(true) } + + it 'returns no result for anon' do + expect(result.users.length).to eq(0) + end + + it 'returns a result for logged in users' do + result = Search.execute('bruce', type_filter: 'user', guardian: Guardian.new(user)) + expect(result.users.length).to eq(1) + end + + end + end context 'inactive users' do @@ -96,6 +111,15 @@ describe Search do end end + context 'staged users' do + let(:staged) { Fabricate(:staged) } + let(:result) { Search.execute(staged.username) } + + it 'does not return a result' do + expect(result.users.length).to eq(0) + end + end + context 'private messages' do let(:topic) { @@ -119,7 +143,6 @@ describe Search do TopicAllowedUser.create!(user_id: reply.user_id, topic_id: topic.id) TopicAllowedUser.create!(user_id: post.user_id, topic_id: topic.id) - results = Search.execute('mars', type_filter: 'private_messages', guardian: Guardian.new(reply.user)) @@ -369,19 +392,55 @@ describe Search do expect(Search.execute('社區指南').posts.first.id).to eq(post.id) expect(Search.execute('指南').posts.first.id).to eq(post.id) end + + it 'finds chinese topic based on title if tokenization is forced' do + skip("skipped until pg app installs the db correctly") if RbConfig::CONFIG["arch"] =~ /darwin/ + + SiteSetting.search_tokenize_chinese_japanese_korean = true + + topic = Fabricate(:topic, title: 'My Title Discourse社區指南') + post = Fabricate(:post, topic: topic) + + expect(Search.execute('社區指南').posts.first.id).to eq(post.id) + expect(Search.execute('指南').posts.first.id).to eq(post.id) + end end describe 'Advanced search' do - it 'supports min_age and max_age in:first user:' do - topic = Fabricate(:topic, created_at: 3.months.ago) + it 'supports pinned and unpinned' do + topic = Fabricate(:topic) Fabricate(:post, raw: 'hi this is a test 123 123', topic: topic) _post = Fabricate(:post, raw: 'boom boom shake the room', topic: topic) - expect(Search.execute('test min_age:100').posts.length).to eq(1) - expect(Search.execute('test min_age:10').posts.length).to eq(0) - expect(Search.execute('test max_age:10').posts.length).to eq(1) - expect(Search.execute('test max_age:100').posts.length).to eq(0) + topic.update_pinned(true) + + user = Fabricate(:user) + guardian = Guardian.new(user) + + expect(Search.execute('boom in:pinned').posts.length).to eq(1) + expect(Search.execute('boom in:unpinned', guardian: guardian).posts.length).to eq(0) + + topic.clear_pin_for(user) + + expect(Search.execute('boom in:unpinned', guardian: guardian).posts.length).to eq(1) + end + + it 'supports before and after in:first user:' do + + time = Time.zone.parse('2001-05-20 2:55') + freeze_time(time) + + topic = Fabricate(:topic) + Fabricate(:post, raw: 'hi this is a test 123 123', topic: topic, created_at: time.months_ago(2)) + _post = Fabricate(:post, raw: 'boom boom shake the room', topic: topic) + + expect(Search.execute('test before:1').posts.length).to eq(1) + expect(Search.execute('test before:2001-04-20').posts.length).to eq(1) + expect(Search.execute('test before:2001').posts.length).to eq(0) + expect(Search.execute('test before:monday').posts.length).to eq(1) + + expect(Search.execute('test after:jan').posts.length).to eq(1) expect(Search.execute('test in:first').posts.length).to eq(1) expect(Search.execute('boom').posts.length).to eq(1) @@ -389,6 +448,7 @@ describe Search do expect(Search.execute('user:nobody').posts.length).to eq(0) expect(Search.execute("user:#{_post.user.username}").posts.length).to eq(1) + expect(Search.execute("user:#{_post.user_id}").posts.length).to eq(1) end it 'supports group' do @@ -476,5 +536,34 @@ describe Search do Post.exec_sql("SELECT to_tsvector('bbb') @@ " << ts_query) end + context '#word_to_date' do + it 'parses relative dates correctly' do + time = Time.zone.parse('2001-02-20 2:55') + freeze_time(time) + + expect(Search.word_to_date('yesterday')).to eq(time.beginning_of_day.yesterday) + expect(Search.word_to_date('suNday')).to eq(Time.zone.parse('2001-02-18')) + expect(Search.word_to_date('thursday')).to eq(Time.zone.parse('2001-02-15')) + expect(Search.word_to_date('deCember')).to eq(Time.zone.parse('2000-12-01')) + expect(Search.word_to_date('deC')).to eq(Time.zone.parse('2000-12-01')) + expect(Search.word_to_date('january')).to eq(Time.zone.parse('2001-01-01')) + expect(Search.word_to_date('jan')).to eq(Time.zone.parse('2001-01-01')) + + + expect(Search.word_to_date('100')).to eq(time.beginning_of_day.days_ago(100)) + + expect(Search.word_to_date('invalid')).to eq(nil) + end + + it 'parses absolute dates correctly' do + expect(Search.word_to_date('2001-1-20')).to eq(Time.zone.parse('2001-01-20')) + expect(Search.word_to_date('2030-10-2')).to eq(Time.zone.parse('2030-10-02')) + expect(Search.word_to_date('2030-10')).to eq(Time.zone.parse('2030-10-01')) + expect(Search.word_to_date('2030')).to eq(Time.zone.parse('2030-01-01')) + expect(Search.word_to_date('2030-01-32')).to eq(nil) + expect(Search.word_to_date('10000')).to eq(nil) + end + end + end diff --git a/spec/components/sidekiq/pausable_spec.rb b/spec/components/sidekiq/pausable_spec.rb index 887702489cc..092b3190013 100644 --- a/spec/components/sidekiq/pausable_spec.rb +++ b/spec/components/sidekiq/pausable_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'sidekiq/pausable' describe Sidekiq do diff --git a/spec/components/site_setting_extension_spec.rb b/spec/components/site_setting_extension_spec.rb index 82afd880c97..f6982e8ef0c 100644 --- a/spec/components/site_setting_extension_spec.rb +++ b/spec/components/site_setting_extension_spec.rb @@ -1,8 +1,25 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'site_setting_extension' require_dependency 'site_settings/local_process_provider' describe SiteSettingExtension do + + describe '#types' do + context "verify enum sequence" do + before do + @types = SiteSetting.types + end + + it "'string' should be at 1st position" do + expect(@types[:string]).to eq(1) + end + + it "'value_list' should be at 12th position" do + expect(@types[:value_list]).to eq(12) + end + end + end + let :provider_local do SiteSettings::LocalProcessProvider.new end @@ -123,6 +140,17 @@ describe SiteSettingExtension do settings.set("test_setting", 12) expect(settings.test_setting).to eq(12) end + + it "should publish changes to clients" do + settings.setting("test_setting", 100) + settings.client_setting("test_setting") + + messages = MessageBus.track_publish do + settings.test_setting = 88 + end + + expect(messages.map(&:channel).include?('/client_settings')).to eq(true) + end end end @@ -430,6 +458,30 @@ describe SiteSettingExtension do end end + context "with blank global setting" do + before do + GlobalSetting.stubs(:nada).returns('') + settings.setting(:nada, 'nothing', shadowed_by_global: true) + settings.refresh! + end + + it "should return default cause nothing is set" do + expect(settings.nada).to eq('nothing') + end + end + + context "with a false override" do + before do + GlobalSetting.stubs(:bool).returns(false) + settings.setting(:bool, true, shadowed_by_global: true) + settings.refresh! + end + + it "should return default cause nothing is set" do + expect(settings.bool).to eq(false) + end + end + context "with global setting" do before do GlobalSetting.stubs(:trout_api_key).returns('purringcat') diff --git a/spec/components/site_settings/db_provider_spec.rb b/spec/components/site_settings/db_provider_spec.rb index ded17ce96d6..64bd7b0b70d 100644 --- a/spec/components/site_settings/db_provider_spec.rb +++ b/spec/components/site_settings/db_provider_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'site_settings/db_provider' describe SiteSettings::DbProvider do diff --git a/spec/components/site_settings/local_process_provider_spec.rb b/spec/components/site_settings/local_process_provider_spec.rb index e4db9c90f6f..6293216d677 100644 --- a/spec/components/site_settings/local_process_provider_spec.rb +++ b/spec/components/site_settings/local_process_provider_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'site_settings/local_process_provider' describe SiteSettings::LocalProcessProvider do diff --git a/spec/components/site_settings/yaml_loader_spec.rb b/spec/components/site_settings/yaml_loader_spec.rb index 6fc59b623a3..a011817274b 100644 --- a/spec/components/site_settings/yaml_loader_spec.rb +++ b/spec/components/site_settings/yaml_loader_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'site_settings/yaml_loader' describe SiteSettings::YamlLoader do @@ -41,7 +41,7 @@ describe SiteSettings::YamlLoader do it "loads simple settings" do receiver.expects(:setting).with('category1', 'title', 'My Site', {}).once receiver.expects(:setting).with('category1', 'contact_email', 'webmaster@example.com', {}).once - receiver.expects(:setting).with('category2', 'ninja_edit_window', true, {}).once + receiver.expects(:setting).with('category2', 'editing_grace_period', true, {}).once receiver.expects(:setting).with('category3', 'reply_by_email_address', '', {}).once receiver.load_yaml(simple) end diff --git a/spec/components/slug_spec.rb b/spec/components/slug_spec.rb index 4173ab93288..aee9c81f7ad 100644 --- a/spec/components/slug_spec.rb +++ b/spec/components/slug_spec.rb @@ -1,6 +1,6 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require 'slug' describe Slug do diff --git a/spec/components/spam_handler_spec.rb b/spec/components/spam_handler_spec.rb index bde8f0b2b10..64508d6ecaa 100644 --- a/spec/components/spam_handler_spec.rb +++ b/spec/components/spam_handler_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" require "spam_handler" describe SpamHandler do diff --git a/spec/components/sql_builder_spec.rb b/spec/components/sql_builder_spec.rb index 72926085d21..870c55a685e 100644 --- a/spec/components/sql_builder_spec.rb +++ b/spec/components/sql_builder_spec.rb @@ -1,5 +1,5 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require_dependency 'sql_builder' describe SqlBuilder do diff --git a/spec/components/suggested_topics_builder_spec.rb b/spec/components/suggested_topics_builder_spec.rb index 414185582ae..c860fe0dc11 100644 --- a/spec/components/suggested_topics_builder_spec.rb +++ b/spec/components/suggested_topics_builder_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'suggested_topics_builder' describe SuggestedTopicsBuilder do diff --git a/spec/components/system_message_spec.rb b/spec/components/system_message_spec.rb index fe1eab93583..dbbeff71ed7 100644 --- a/spec/components/system_message_spec.rb +++ b/spec/components/system_message_spec.rb @@ -1,25 +1,30 @@ -require 'spec_helper' +require 'rails_helper' require 'system_message' require 'topic_subtype' describe SystemMessage do - let!(:admin) { Fabricate(:admin) } context 'send' do - let(:user) { Fabricate(:user) } - let(:system_message) { SystemMessage.new(user) } - let(:post) { system_message.create(:welcome_invite) } - let(:topic) { post.topic } - it 'should create a post correctly' do + + admin = Fabricate(:admin) + user = Fabricate(:user) + SiteSetting.site_contact_username = admin.username + system_message = SystemMessage.new(user) + post = system_message.create(:welcome_invite) + topic = post.topic + expect(post).to be_present expect(post).to be_valid expect(topic).to be_private_message expect(topic).to be_valid expect(topic.subtype).to eq(TopicSubtype.system_message) expect(topic.allowed_users.include?(user)).to eq(true) + expect(topic.allowed_users.include?(admin)).to eq(true) + + expect(UserArchivedMessage.where(user_id: admin.id, topic_id: topic.id).length).to eq(1) end end diff --git a/spec/components/text_cleaner_spec.rb b/spec/components/text_cleaner_spec.rb index 278177a292e..cf203c709cc 100644 --- a/spec/components/text_cleaner_spec.rb +++ b/spec/components/text_cleaner_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'text_cleaner' describe TextCleaner do diff --git a/spec/components/text_sentinel_spec.rb b/spec/components/text_sentinel_spec.rb index cd9e41d6678..ea11c1c1457 100644 --- a/spec/components/text_sentinel_spec.rb +++ b/spec/components/text_sentinel_spec.rb @@ -1,6 +1,6 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require 'text_sentinel' describe TextSentinel do @@ -74,6 +74,11 @@ describe TextSentinel do expect(TextSentinel.new(valid_string.upcase)).not_to be_valid end + it "allows all caps topics when loud posts are allowed" do + SiteSetting.stubs(:allow_uppercase_posts).returns(true) + expect(TextSentinel.new(valid_string.upcase)).to be_valid + end + it "enforces the minimum entropy" do expect(TextSentinel.new(valid_string, min_entropy: 16)).to be_valid end diff --git a/spec/components/topic_creator_spec.rb b/spec/components/topic_creator_spec.rb index c858ebaa1b0..dcca1dd101a 100644 --- a/spec/components/topic_creator_spec.rb +++ b/spec/components/topic_creator_spec.rb @@ -1,15 +1,16 @@ -require 'spec_helper' +require 'rails_helper' describe TopicCreator do - let(:user) { Fabricate(:user) } + let(:user) { Fabricate(:user, trust_level: TrustLevel[2]) } let(:moderator) { Fabricate(:moderator) } let(:admin) { Fabricate(:admin) } let(:valid_attrs) { Fabricate.attributes_for(:topic) } + let(:pm_valid_attrs) { {raw: 'this is a new post', title: 'this is a new title', archetype: Archetype.private_message, target_usernames: moderator.username} } describe '#create' do - context 'success cases' do + context 'topic success cases' do before do TopicCreator.any_instance.expects(:save_topic).returns(true) TopicCreator.any_instance.expects(:watch_topic).returns(true) @@ -49,6 +50,32 @@ describe TopicCreator do end end end - end + context 'private message' do + + context 'success cases' do + before do + TopicCreator.any_instance.expects(:save_topic).returns(true) + TopicCreator.any_instance.expects(:watch_topic).returns(true) + SiteSetting.stubs(:allow_duplicate_topic_titles?).returns(true) + end + + it "should be possible for a regular user to send private message" do + expect(TopicCreator.create(user, Guardian.new(user), pm_valid_attrs)).to be_valid + end + + it "min_trust_to_create_topic setting should not be checked when sending private message" do + SiteSetting.min_trust_to_create_topic = TrustLevel[4] + expect(TopicCreator.create(user, Guardian.new(user), pm_valid_attrs)).to be_valid + end + end + + context 'failure cases' do + it "min_trust_to_send_messages setting should be checked when sending private message" do + SiteSetting.min_trust_to_send_messages = TrustLevel[4] + expect(-> { TopicCreator.create(user, Guardian.new(user), pm_valid_attrs) }).to raise_error(ActiveRecord::Rollback) + end + end + end + end end diff --git a/spec/components/topic_query_spec.rb b/spec/components/topic_query_spec.rb index c06c6623b56..276ee765677 100644 --- a/spec/components/topic_query_spec.rb +++ b/spec/components/topic_query_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'topic_view' describe TopicQuery do @@ -232,6 +232,33 @@ describe TopicQuery do # returns the topics in reverse posters order if requested" do expect(ids_in_order('posters', false)).to eq([archived_topic, closed_topic, invisible_topic, future_topic, regular_topic, pinned_topic].map(&:id)) + + # sets a custom field for each topic to emulate a plugin + regular_topic.custom_fields["sheep"] = 26 + pinned_topic.custom_fields["sheep"] = 47 + archived_topic.custom_fields["sheep"] = 69 + invisible_topic.custom_fields["sheep"] = 12 + closed_topic.custom_fields["sheep"] = 31 + future_topic.custom_fields["sheep"] = 53 + + regular_topic.save + pinned_topic.save + archived_topic.save + invisible_topic.save + closed_topic.save + future_topic.save + + # adds the custom field as a viable sort option + class ::TopicQuery + SORTABLE_MAPPING["sheep"] = "custom_fields.sheep" + end + # returns the topics in the sheep order if requested" do + expect(ids_in_order('sheep')).to eq([archived_topic, future_topic, pinned_topic, closed_topic, regular_topic, invisible_topic].map(&:id)) + + # returns the topics in reverse sheep order if requested" do + expect(ids_in_order('sheep', false)).to eq([invisible_topic, regular_topic, closed_topic, pinned_topic, future_topic, archived_topic].map(&:id)) + + end end @@ -294,8 +321,8 @@ describe TopicQuery do context 'user with auto_track_topics list_unread' do before do - user.auto_track_topics_after_msecs = 0 - user.save + user.user_option.auto_track_topics_after_msecs = 0 + user.user_option.save end it 'only contains the partially read topic' do @@ -360,8 +387,8 @@ describe TopicQuery do expect(topic_query.list_new.topics).to eq([new_topic]) - user.new_topic_duration_minutes = 5 - user.save + user.user_option.new_topic_duration_minutes = 5 + user.user_option.save new_topic.created_at = 10.minutes.ago new_topic.save expect(topic_query.list_new.topics).to eq([]) @@ -374,6 +401,7 @@ describe TopicQuery do it "returns an empty set" do expect(topics).to be_blank + expect(topic_query.list_latest.topics).to be_blank end context 'un-muted' do @@ -383,6 +411,7 @@ describe TopicQuery do it "returns the topic again" do expect(topics).to eq([new_topic]) + expect(topic_query.list_latest.topics).not_to be_blank end end end @@ -444,8 +473,70 @@ describe TopicQuery do end end - context 'suggested_for' do + context 'suggested_for message do' do + let(:user) do + Fabricate(:admin) + end + + let(:sender) do + Fabricate(:admin) + end + + let(:group_with_user) do + group = Fabricate(:group) + group.add(user) + group.save + group + end + + def create_pm(user, opts=nil) + unless opts + opts = user + user = nil + end + + create_post(opts.merge(user: user, archetype: Archetype.private_message)).topic + end + + def read(user,topic,post_number) + TopicUser.update_last_read(user, topic, post_number, 10000) + end + + it 'returns the correct suggestions' do + + + pm_to_group = create_pm(sender, target_group_names: [group_with_user.name]) + pm_to_user = create_pm(sender, target_usernames: [user.username]) + + new_pm = create_pm(target_usernames: [user.username]) + + unread_pm = create_pm(target_usernames: [user.username]) + read(user,unread_pm, 0) + + old_unrelated_pm = create_pm(target_usernames: [user.username]) + read(user, old_unrelated_pm, 1) + + + related_by_user_pm = create_pm(sender, target_usernames: [user.username]) + read(user, related_by_user_pm, 1) + + + related_by_group_pm = create_pm(sender, target_group_names: [group_with_user.name]) + read(user, related_by_group_pm, 1) + + + expect(TopicQuery.new(user).list_suggested_for(pm_to_group).topics.map(&:id)).to( + eq([related_by_group_pm.id, related_by_user_pm.id, pm_to_user.id]) + ) + + expect(TopicQuery.new(user).list_suggested_for(pm_to_user).topics.map(&:id)).to( + eq([new_pm.id, unread_pm.id, related_by_user_pm.id]) + ) + end + end + + context 'suggested_for' do before do RandomTopicSelector.clear_cache! @@ -497,8 +588,8 @@ describe TopicQuery do let!(:fully_read_archived) { Fabricate(:post, user: creator).topic } before do - user.auto_track_topics_after_msecs = 0 - user.save + user.user_option.auto_track_topics_after_msecs = 0 + user.user_option.save TopicUser.update_last_read(user, partially_read.id, 0, 0) TopicUser.update_last_read(user, fully_read.id, 1, 0) TopicUser.update_last_read(user, fully_read_closed.id, 1, 0) diff --git a/spec/components/topic_retriever_spec.rb b/spec/components/topic_retriever_spec.rb index ac1f04622b3..89db716b23a 100644 --- a/spec/components/topic_retriever_spec.rb +++ b/spec/components/topic_retriever_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'topic_retriever' describe TopicRetriever do diff --git a/spec/components/topic_view_spec.rb b/spec/components/topic_view_spec.rb index ad23e0ade59..6cdccf01668 100644 --- a/spec/components/topic_view_spec.rb +++ b/spec/components/topic_view_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'topic_view' describe TopicView do diff --git a/spec/components/topics_bulk_action_spec.rb b/spec/components/topics_bulk_action_spec.rb index 2a3396d2dc5..0003ee2dc5c 100644 --- a/spec/components/topics_bulk_action_spec.rb +++ b/spec/components/topics_bulk_action_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'topics_bulk_action' describe TopicsBulkAction do @@ -153,4 +153,31 @@ describe TopicsBulkAction do end end end + + describe "unlist" do + let(:topic) { Fabricate(:topic) } + + context "when the user can moderate the topic" do + it "unlists the topic and returns the topic_id" do + Guardian.any_instance.expects(:can_moderate?).returns(true) + Guardian.any_instance.expects(:can_create?).returns(true) + tba = TopicsBulkAction.new(topic.user, [topic.id], type: 'unlist') + topic_ids = tba.perform! + expect(topic_ids).to eq([topic.id]) + topic.reload + expect(topic).not_to be_visible + end + end + + context "when the user can't edit the topic" do + it "doesn't unlist the topic" do + Guardian.any_instance.expects(:can_moderate?).returns(false) + tba = TopicsBulkAction.new(topic.user, [topic.id], type: 'unlist') + topic_ids = tba.perform! + expect(topic_ids).to be_blank + topic.reload + expect(topic).to be_visible + end + end + end end diff --git a/spec/components/trashable_spec.rb b/spec/components/trashable_spec.rb index aa54d85d463..6cebdc50b48 100644 --- a/spec/components/trashable_spec.rb +++ b/spec/components/trashable_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'trashable' describe Trashable do diff --git a/spec/components/trust_level_spec.rb b/spec/components/trust_level_spec.rb new file mode 100644 index 00000000000..87f0b08cd9b --- /dev/null +++ b/spec/components/trust_level_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +describe TrustLevel do + describe 'levels' do + context "verify enum sequence" do + before do + @levels = TrustLevel.levels + end + + it "'newuser' should be at 0 position" do + expect(@levels[:newuser]).to eq(0) + end + + it "'leader' should be at 4th position" do + expect(@levels[:leader]).to eq(4) + end + end + end +end diff --git a/spec/components/unread_spec.rb b/spec/components/unread_spec.rb index cf9d814ac3f..cfbf4570537 100644 --- a/spec/components/unread_spec.rb +++ b/spec/components/unread_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'unread' describe Unread do diff --git a/spec/components/url_helper_spec.rb b/spec/components/url_helper_spec.rb index ae2c37d1e7e..e9f580f6124 100644 --- a/spec/components/url_helper_spec.rb +++ b/spec/components/url_helper_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'url_helper' describe UrlHelper do diff --git a/spec/components/user_name_suggester_spec.rb b/spec/components/user_name_suggester_spec.rb index ec9eb7a46b7..6046aa6ef7e 100644 --- a/spec/components/user_name_suggester_spec.rb +++ b/spec/components/user_name_suggester_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'user_name_suggester' describe UserNameSuggester do @@ -50,21 +50,31 @@ describe UserNameSuggester do end it "doesn't suggest reserved usernames" do - SiteSetting.reserved_usernames = 'admin|steve|steve1' - expect(UserNameSuggester.suggest("admin@hissite.com")).to eq('admin1') + SiteSetting.reserved_usernames = 'myadmin|steve|steve1' + expect(UserNameSuggester.suggest("myadmin@hissite.com")).to eq('myadmin1') expect(UserNameSuggester.suggest("steve")).to eq('steve2') end + it "doesn't suggest generic usernames" do + UserNameSuggester::GENERIC_NAMES.each do |name| + expect(UserNameSuggester.suggest("#{name}@apple.org")).to eq('apple') + end + end + it "removes leading character if it is not alphanumeric" do - expect(UserNameSuggester.suggest("_myname")).to eq('myname') + expect(UserNameSuggester.suggest(".myname")).to eq('myname') + end + + it "allows leading _" do + expect(UserNameSuggester.suggest("_myname")).to eq('_myname') end it "removes trailing characters if they are invalid" do expect(UserNameSuggester.suggest("myname!^$=")).to eq('myname') end - it "replace dots" do - expect(UserNameSuggester.suggest("my.name")).to eq('my_name') + it "allows dots in the middle" do + expect(UserNameSuggester.suggest("my.name")).to eq('my.name') end it "remove leading dots" do @@ -81,7 +91,16 @@ describe UserNameSuggester do end it 'should handle typical facebook usernames' do - expect(UserNameSuggester.suggest('roger.nelson.3344913')).to eq('roger_nelson_33') + expect(UserNameSuggester.suggest('roger.nelson.3344913')).to eq('roger.nelson.33') + end + + it 'removes underscore at the end of long usernames that get truncated' do + expect(UserNameSuggester.suggest('uuuuuuuuuuuuuu_u')).to_not end_with('_') + end + + it "adds number if it's too short after removing trailing underscore" do + User.stubs(:username_length).returns(8..8) + expect(UserNameSuggester.suggest('uuuuuuu_u')).to eq('uuuuuuu1') end end diff --git a/spec/components/validators/allowed_ip_address_validator_spec.rb b/spec/components/validators/allowed_ip_address_validator_spec.rb index ecef8497edf..b2af99f5b7f 100644 --- a/spec/components/validators/allowed_ip_address_validator_spec.rb +++ b/spec/components/validators/allowed_ip_address_validator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe AllowedIpAddressValidator do diff --git a/spec/components/validators/email_setting_validator_spec.rb b/spec/components/validators/email_setting_validator_spec.rb index 67fd6e82da0..a143b381171 100644 --- a/spec/components/validators/email_setting_validator_spec.rb +++ b/spec/components/validators/email_setting_validator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe EmailSettingValidator do describe '#valid_value?' do diff --git a/spec/components/validators/email_validator_spec.rb b/spec/components/validators/email_validator_spec.rb index 887b6dbde7d..b219de6ba61 100644 --- a/spec/components/validators/email_validator_spec.rb +++ b/spec/components/validators/email_validator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe EmailValidator do diff --git a/spec/components/validators/integer_setting_validator_spec.rb b/spec/components/validators/integer_setting_validator_spec.rb index 64b28194316..d681f2bc63f 100644 --- a/spec/components/validators/integer_setting_validator_spec.rb +++ b/spec/components/validators/integer_setting_validator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe IntegerSettingValidator do describe '#valid_value?' do diff --git a/spec/components/validators/ip_address_format_validator_spec.rb b/spec/components/validators/ip_address_format_validator_spec.rb index 20265a2d16d..a91c2d85cd6 100644 --- a/spec/components/validators/ip_address_format_validator_spec.rb +++ b/spec/components/validators/ip_address_format_validator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe IpAddressFormatValidator do diff --git a/spec/components/validators/password_validator_spec.rb b/spec/components/validators/password_validator_spec.rb index cc328421fe7..3cfe4f43571 100644 --- a/spec/components/validators/password_validator_spec.rb +++ b/spec/components/validators/password_validator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency "common_passwords/common_passwords" describe PasswordValidator do @@ -40,6 +40,15 @@ describe PasswordValidator do validate expect(record.errors[:password]).to be_present end + + it "adds an error when user is admin and password is less than 15 chars" do + SiteSetting.min_admin_password_length = 15 + + @password = "12345678912" + record.admin = true + validate + expect(record.errors[:password]).to be_present + end end context "min password length is 12" do @@ -55,6 +64,7 @@ describe PasswordValidator do context "password is commonly used" do before do + SiteSetting.stubs(:min_password_length).returns(8) CommonPasswords.stubs(:common_password?).returns(true) end @@ -74,7 +84,7 @@ describe PasswordValidator do end it "adds an error when password is the same as the username" do - @password = "porkchops1" + @password = "porkchops1234" record.username = @password validate expect(record.errors[:password]).to be_present diff --git a/spec/components/validators/post_validator_spec.rb b/spec/components/validators/post_validator_spec.rb index 064da5c7099..d7e8e68fc7e 100644 --- a/spec/components/validators/post_validator_spec.rb +++ b/spec/components/validators/post_validator_spec.rb @@ -1,14 +1,9 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'validators/post_validator' describe Validators::PostValidator do - let :post do - build(:post) - end - - let :validator do - Validators::PostValidator.new({}) - end + let(:post) { build(:post) } + let(:validator) { Validators::PostValidator.new({}) } context "stripped_length" do it "adds an error for short raw" do @@ -45,6 +40,55 @@ describe Validators::PostValidator do end end + context "too_many_mentions" do + before do + SiteSetting.newuser_max_mentions_per_post = 2 + SiteSetting.max_mentions_per_post = 3 + end + + it "should be invalid when new user exceeds max mentions limit" do + post.acting_user = build(:newuser) + post.expects(:raw_mentions).returns(['jake', 'finn', 'jake_old']) + validator.max_mention_validator(post) + expect(post.errors.count).to be > 0 + end + + it "should be invalid when elder user exceeds max mentions limit" do + post.acting_user = build(:trust_level_4) + post.expects(:raw_mentions).returns(['jake', 'finn', 'jake_old', 'jake_new']) + validator.max_mention_validator(post) + expect(post.errors.count).to be > 0 + end + + it "should be valid when new user does not exceed max mentions limit" do + post.acting_user = build(:newuser) + post.expects(:raw_mentions).returns(['jake', 'finn']) + validator.max_mention_validator(post) + expect(post.errors.count).to be(0) + end + + it "should be valid when elder user does not exceed max mentions limit" do + post.acting_user = build(:trust_level_4) + post.expects(:raw_mentions).returns(['jake', 'finn', 'jake_old']) + validator.max_mention_validator(post) + expect(post.errors.count).to be(0) + end + + it "should be valid for moderator in all cases" do + post.acting_user = build(:moderator) + post.expects(:raw_mentions).never + validator.max_mention_validator(post) + expect(post.errors.count).to be(0) + end + + it "should be valid for admin in all cases" do + post.acting_user = build(:admin) + post.expects(:raw_mentions).never + validator.max_mention_validator(post) + expect(post.errors.count).to be(0) + end + end + context "invalid post" do it "should be invalid" do validator.validate(post) @@ -86,25 +130,32 @@ describe Validators::PostValidator do end end - context "post is for a static page and acting_user is an admin" do - before do - @tos_post = build(:post) - @tos_post.acting_user = Fabricate(:admin) - SiteSetting.stubs(:tos_topic_id).returns(@tos_post.topic_id) - end - + shared_examples "almost no validations" do it "skips most validations" do - v = Validators::PostValidator.new({}) - v.expects(:stripped_length).never - v.expects(:raw_quality).never - v.expects(:max_posts_validator).never - v.expects(:max_mention_validator).never - v.expects(:max_images_validator).never - v.expects(:max_attachments_validator).never - v.expects(:max_links_validator).never - v.expects(:unique_post_validator).never - v.validate(@tos_post) + validator.expects(:stripped_length).never + validator.expects(:raw_quality).never + validator.expects(:max_posts_validator).never + validator.expects(:max_mention_validator).never + validator.expects(:max_images_validator).never + validator.expects(:max_attachments_validator).never + validator.expects(:max_links_validator).never + validator.expects(:unique_post_validator).never + validator.validate(post) end end + context "admin editing a static page" do + before do + post.acting_user = build(:admin) + SiteSetting.stubs(:tos_topic_id).returns(post.topic_id) + end + + include_examples "almost no validations" + end + + context "staged user" do + before { post.acting_user = build(:user, staged: true) } + include_examples "almost no validations" + end + end diff --git a/spec/components/validators/quality_title_validator_spec.rb b/spec/components/validators/quality_title_validator_spec.rb index 065fcdcfd16..b6bf864a809 100644 --- a/spec/components/validators/quality_title_validator_spec.rb +++ b/spec/components/validators/quality_title_validator_spec.rb @@ -1,6 +1,6 @@ # encoding: UTF-8 -require 'spec_helper' +require 'rails_helper' require 'validators/quality_title_validator' require 'ostruct' diff --git a/spec/components/validators/reply_by_email_address_validator_spec.rb b/spec/components/validators/reply_by_email_address_validator_spec.rb index 81f6f24a016..ac580b7f016 100644 --- a/spec/components/validators/reply_by_email_address_validator_spec.rb +++ b/spec/components/validators/reply_by_email_address_validator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ReplyByEmailAddressValidator do diff --git a/spec/components/validators/reply_by_email_enabled_validator_spec.rb b/spec/components/validators/reply_by_email_enabled_validator_spec.rb new file mode 100644 index 00000000000..e7cd318ed5a --- /dev/null +++ b/spec/components/validators/reply_by_email_enabled_validator_spec.rb @@ -0,0 +1,31 @@ +require 'rails_helper' + +describe ReplyByEmailEnabledValidator do + + describe '#valid_value?' do + subject(:validator) { described_class.new } + + it "only validates when enabling the setting" do + expect(validator.valid_value?("f")).to eq(true) + end + + it "returns false if reply_by_email_address is missing" do + SiteSetting.expects(:reply_by_email_address).returns("") + expect(validator.valid_value?("t")).to eq(false) + end + + it "returns false if email polling is disabled" do + SiteSetting.expects(:reply_by_email_address).returns("foo.%{reply_key}+42@bar.com") + SiteSetting.expects(:email_polling_enabled?).returns(false) + expect(validator.valid_value?("t")).to eq(false) + end + + it "returns true when email polling is enabled and the reply_by_email_address is configured" do + SiteSetting.expects(:reply_by_email_address).returns("foo.%{reply_key}+42@bar.com") + SiteSetting.expects(:email_polling_enabled?).returns(true) + expect(validator.valid_value?("t")).to eq(true) + end + + end + +end diff --git a/spec/components/validators/string_setting_validator_spec.rb b/spec/components/validators/string_setting_validator_spec.rb index 69370d6433e..890c2dc939d 100644 --- a/spec/components/validators/string_setting_validator_spec.rb +++ b/spec/components/validators/string_setting_validator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe StringSettingValidator do diff --git a/spec/components/validators/topic_title_length_validator_spec.rb b/spec/components/validators/topic_title_length_validator_spec.rb index 427d4eaf04a..2f960247ad5 100644 --- a/spec/components/validators/topic_title_length_validator_spec.rb +++ b/spec/components/validators/topic_title_length_validator_spec.rb @@ -1,6 +1,6 @@ # encoding: UTF-8 -require 'spec_helper' +require 'rails_helper' require 'validators/topic_title_length_validator' describe TopicTitleLengthValidator do diff --git a/spec/components/validators/user_full_name_validator_spec.rb b/spec/components/validators/user_full_name_validator_spec.rb index 1b06d00ed88..bfa57b74b4b 100644 --- a/spec/components/validators/user_full_name_validator_spec.rb +++ b/spec/components/validators/user_full_name_validator_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe UserFullNameValidator do let(:validator) { described_class.new({attributes: :name}) } diff --git a/spec/components/validators/username_setting_validator_spec.rb b/spec/components/validators/username_setting_validator_spec.rb index fcc417a0a21..8e06e4fd832 100644 --- a/spec/components/validators/username_setting_validator_spec.rb +++ b/spec/components/validators/username_setting_validator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UsernameSettingValidator do describe '#valid_value?' do diff --git a/spec/components/version_spec.rb b/spec/components/version_spec.rb index 8bf3e28512a..26c24337bc1 100644 --- a/spec/components/version_spec.rb +++ b/spec/components/version_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'version' describe Discourse::VERSION do diff --git a/spec/controllers/admin/admin_controller_spec.rb b/spec/controllers/admin/admin_controller_spec.rb index 21206230f89..f0e29511dd3 100644 --- a/spec/controllers/admin/admin_controller_spec.rb +++ b/spec/controllers/admin/admin_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::AdminController do diff --git a/spec/controllers/admin/api_controller_spec.rb b/spec/controllers/admin/api_controller_spec.rb index f940ddea5c8..2805a2d4b1d 100644 --- a/spec/controllers/admin/api_controller_spec.rb +++ b/spec/controllers/admin/api_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::ApiController do diff --git a/spec/controllers/admin/backups_controller_spec.rb b/spec/controllers/admin/backups_controller_spec.rb index a16efe26070..050201a6ab0 100644 --- a/spec/controllers/admin/backups_controller_spec.rb +++ b/spec/controllers/admin/backups_controller_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe Admin::BackupsController do diff --git a/spec/controllers/admin/badges_controller_spec.rb b/spec/controllers/admin/badges_controller_spec.rb index 94e9c763ec2..5591ac6804a 100644 --- a/spec/controllers/admin/badges_controller_spec.rb +++ b/spec/controllers/admin/badges_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::BadgesController do diff --git a/spec/controllers/admin/color_schemes_controller_spec.rb b/spec/controllers/admin/color_schemes_controller_spec.rb index cebda75720c..9059330b44d 100644 --- a/spec/controllers/admin/color_schemes_controller_spec.rb +++ b/spec/controllers/admin/color_schemes_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::ColorSchemesController do it "is a subclass of AdminController" do diff --git a/spec/controllers/admin/dashboard_controller_spec.rb b/spec/controllers/admin/dashboard_controller_spec.rb index c501fe4c783..8bc31307cf2 100644 --- a/spec/controllers/admin/dashboard_controller_spec.rb +++ b/spec/controllers/admin/dashboard_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'discourse_version_check' describe Admin::DashboardController do diff --git a/spec/controllers/admin/email_controller_spec.rb b/spec/controllers/admin/email_controller_spec.rb index 2820cb15431..86d2b42e9a0 100644 --- a/spec/controllers/admin/email_controller_spec.rb +++ b/spec/controllers/admin/email_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::EmailController do @@ -66,7 +66,7 @@ describe Admin::EmailController do end it "previews the digest" do - xhr :get, :preview_digest, last_seen_at: 1.week.ago + xhr :get, :preview_digest, last_seen_at: 1.week.ago, username: user.username expect(response).to be_success end end diff --git a/spec/controllers/admin/embeddable_hosts_controller_spec.rb b/spec/controllers/admin/embeddable_hosts_controller_spec.rb index d3d83cac5c4..54a97ed938e 100644 --- a/spec/controllers/admin/embeddable_hosts_controller_spec.rb +++ b/spec/controllers/admin/embeddable_hosts_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::EmbeddableHostsController do diff --git a/spec/controllers/admin/embedding_controller_spec.rb b/spec/controllers/admin/embedding_controller_spec.rb index 5913e9fdcf4..49a989e15be 100644 --- a/spec/controllers/admin/embedding_controller_spec.rb +++ b/spec/controllers/admin/embedding_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::EmbeddingController do diff --git a/spec/controllers/admin/emojis_controller_spec.rb b/spec/controllers/admin/emojis_controller_spec.rb index 23a0256f5ed..fa776bb8921 100644 --- a/spec/controllers/admin/emojis_controller_spec.rb +++ b/spec/controllers/admin/emojis_controller_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe Admin::EmojisController do diff --git a/spec/controllers/admin/flags_controller_spec.rb b/spec/controllers/admin/flags_controller_spec.rb index 60ab321147c..76599d2df7f 100644 --- a/spec/controllers/admin/flags_controller_spec.rb +++ b/spec/controllers/admin/flags_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::FlagsController do diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb index 75bc9ddac12..96fb3d229ab 100644 --- a/spec/controllers/admin/groups_controller_spec.rb +++ b/spec/controllers/admin/groups_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::GroupsController do @@ -30,12 +30,36 @@ describe Admin::GroupsController do "automatic_membership_retroactive"=>false, "title"=>nil, "primary_group"=>false, - "grant_trust_level"=>nil + "grant_trust_level"=>nil, + "incoming_email"=>nil, + "notification_level"=>2, + "has_messages"=>false, + "mentionable"=>false }]) end end + context ".bulk" do + it "can assign users to a group by email or username" do + group = Fabricate(:group, name: "test", primary_group: true, title: 'WAT') + user = Fabricate(:user) + user2 = Fabricate(:user) + + xhr :put, :bulk_perform, group_id: group.id, users: [user.username.upcase, user2.email, 'doesnt_exist'] + + expect(response).to be_success + + user.reload + expect(user.primary_group).to eq(group) + expect(user.title).to eq("WAT") + + user2.reload + expect(user2.primary_group).to eq(group) + + end + end + context ".create" do it "strip spaces on the group name" do @@ -107,92 +131,6 @@ describe Admin::GroupsController do end - context ".add_members" do - it "cannot add members to automatic groups" do - xhr :put, :add_members, id: 1, usernames: "l77t" - expect(response.status).to eq(422) - end - - context "is able to add several members to a group" do - - let(:user1) { Fabricate(:user) } - let(:user2) { Fabricate(:user) } - let(:group) { Fabricate(:group) } - - it "adds by username" do - xhr :put, :add_members, id: group.id, usernames: [user1.username, user2.username].join(",") - - expect(response).to be_success - group.reload - expect(group.users.count).to eq(2) - end - - it "adds by id" do - xhr :put, :add_members, id: group.id, user_ids: [user1.id, user2.id].join(",") - - expect(response).to be_success - group.reload - expect(group.users.count).to eq(2) - end - end - - it "returns 422 if member already exists" do - group = Fabricate(:group) - existing_member = Fabricate(:user) - group.add(existing_member) - group.save - - xhr :put, :add_members, id: group.id, usernames: existing_member.username - expect(response.status).to eq(422) - end - - end - - context ".remove_member" do - - it "cannot remove members from automatic groups" do - xhr :put, :remove_member, id: 1, user_id: 42 - expect(response.status).to eq(422) - end - - context "is able to remove a member" do - - let(:user) { Fabricate(:user) } - let(:group) { Fabricate(:group) } - - before do - group.add(user) - group.save - end - - it "removes by id" do - xhr :delete, :remove_member, id: group.id, user_id: user.id - - expect(response).to be_success - group.reload - expect(group.users.count).to eq(0) - end - - it "removes by username" do - xhr :delete, :remove_member, id: group.id, username: user.username - - expect(response).to be_success - group.reload - expect(group.users.count).to eq(0) - end - - it "removes user.primary_group_id when user is removed from group" do - user.primary_group_id = group.id - user.save - - xhr :delete, :remove_member, id: group.id, username: user.username - - user.reload - expect(user.primary_group_id).to eq(nil) - end - end - - end end diff --git a/spec/controllers/admin/impersonate_controller_spec.rb b/spec/controllers/admin/impersonate_controller_spec.rb index 5130551ef81..54eb1ee1f6a 100644 --- a/spec/controllers/admin/impersonate_controller_spec.rb +++ b/spec/controllers/admin/impersonate_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::ImpersonateController do diff --git a/spec/controllers/admin/permalinks_controller_spec.rb b/spec/controllers/admin/permalinks_controller_spec.rb index c885363bfd0..fe5652597d2 100644 --- a/spec/controllers/admin/permalinks_controller_spec.rb +++ b/spec/controllers/admin/permalinks_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::PermalinksController do diff --git a/spec/controllers/admin/plugins_controller_spec.rb b/spec/controllers/admin/plugins_controller_spec.rb index 70c281c73d9..2873523e325 100644 --- a/spec/controllers/admin/plugins_controller_spec.rb +++ b/spec/controllers/admin/plugins_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::PluginsController do diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb index b57ae429aa4..92da083f324 100644 --- a/spec/controllers/admin/reports_controller_spec.rb +++ b/spec/controllers/admin/reports_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::ReportsController do diff --git a/spec/controllers/admin/screened_emails_controller_spec.rb b/spec/controllers/admin/screened_emails_controller_spec.rb index f05b80ce737..07adde47542 100644 --- a/spec/controllers/admin/screened_emails_controller_spec.rb +++ b/spec/controllers/admin/screened_emails_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::ScreenedEmailsController do it "is a subclass of AdminController" do diff --git a/spec/controllers/admin/screened_ip_addresses_controller_spec.rb b/spec/controllers/admin/screened_ip_addresses_controller_spec.rb index e814c7abf12..64cbfa0f80d 100644 --- a/spec/controllers/admin/screened_ip_addresses_controller_spec.rb +++ b/spec/controllers/admin/screened_ip_addresses_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::ScreenedIpAddressesController do diff --git a/spec/controllers/admin/screened_urls_controller_spec.rb b/spec/controllers/admin/screened_urls_controller_spec.rb index 8d9fce01f0d..3bd763d2bb9 100644 --- a/spec/controllers/admin/screened_urls_controller_spec.rb +++ b/spec/controllers/admin/screened_urls_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::ScreenedUrlsController do it "is a subclass of AdminController" do diff --git a/spec/controllers/admin/site_customizations_controller_spec.rb b/spec/controllers/admin/site_customizations_controller_spec.rb index f8b598b9f3e..2695f17c7e7 100644 --- a/spec/controllers/admin/site_customizations_controller_spec.rb +++ b/spec/controllers/admin/site_customizations_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::SiteCustomizationsController do diff --git a/spec/controllers/admin/site_settings_controller_spec.rb b/spec/controllers/admin/site_settings_controller_spec.rb index 702598c8f5b..59ff5ba0420 100644 --- a/spec/controllers/admin/site_settings_controller_spec.rb +++ b/spec/controllers/admin/site_settings_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::SiteSettingsController do diff --git a/spec/controllers/admin/site_text_types_controller_spec.rb b/spec/controllers/admin/site_text_types_controller_spec.rb deleted file mode 100644 index d2431f60c8f..00000000000 --- a/spec/controllers/admin/site_text_types_controller_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' - -describe Admin::SiteTextTypesController do - - it "is a subclass of AdminController" do - expect(Admin::SiteTextTypesController < Admin::AdminController).to eq(true) - end - - context 'while logged in as an admin' do - before do - @user = log_in(:admin) - end - - context ' .index' do - it 'returns success' do - xhr :get, :index - expect(response).to be_success - end - - it 'returns JSON' do - xhr :get, :index - expect(::JSON.parse(response.body)).to be_present - end - end - end - -end diff --git a/spec/controllers/admin/site_texts_controller_spec.rb b/spec/controllers/admin/site_texts_controller_spec.rb index d6bf42d113b..557646000fb 100644 --- a/spec/controllers/admin/site_texts_controller_spec.rb +++ b/spec/controllers/admin/site_texts_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::SiteTextsController do @@ -11,17 +11,74 @@ describe Admin::SiteTextsController do @user = log_in(:admin) end - context '.show' do - let(:text_type) { SiteText.text_types.first.text_type } - - it 'returns success' do - xhr :get, :show, id: text_type + context '.index' do + it 'returns json' do + xhr :get, :index, q: 'title' expect(response).to be_success + expect(::JSON.parse(response.body)).to be_present + end + end + + context '.show' do + it 'returns a site text for a key that exists' do + xhr :get, :show, id: 'title' + expect(response).to be_success + + json = ::JSON.parse(response.body) + expect(json).to be_present + + site_text = json['site_text'] + expect(site_text).to be_present + + expect(site_text['id']).to eq('title') + expect(site_text['value']).to eq(I18n.t(:title)) end - it 'returns JSON' do - xhr :get, :show, id: text_type - expect(::JSON.parse(response.body)).to be_present + it 'returns not found for missing keys' do + xhr :get, :show, id: 'made_up_no_key_exists' + expect(response).not_to be_success + end + end + + context '.update and .revert' do + it 'updates and reverts the key' do + orig_title = I18n.t(:title) + + xhr :put, :update, id: 'title', site_text: {value: 'hello'} + expect(response).to be_success + + json = ::JSON.parse(response.body) + expect(json).to be_present + + site_text = json['site_text'] + expect(site_text).to be_present + + expect(site_text['id']).to eq('title') + expect(site_text['value']).to eq('hello') + + + # Revert + xhr :put, :revert, id: 'title' + expect(response).to be_success + + json = ::JSON.parse(response.body) + expect(json).to be_present + + site_text = json['site_text'] + expect(site_text).to be_present + + expect(site_text['id']).to eq('title') + expect(site_text['value']).to eq(orig_title) + end + + it 'returns not found for missing keys' do + xhr :put, :update, id: 'made_up_no_key_exists', site_text: {value: 'hello'} + expect(response).not_to be_success + end + + it 'logs the change' do + StaffActionLogger.any_instance.expects(:log_site_text_change).once + xhr :put, :update, id: 'title', site_text: {value: 'hello'} end end end diff --git a/spec/controllers/admin/staff_action_logs_controller_spec.rb b/spec/controllers/admin/staff_action_logs_controller_spec.rb index 8f638a33d71..a5665717089 100644 --- a/spec/controllers/admin/staff_action_logs_controller_spec.rb +++ b/spec/controllers/admin/staff_action_logs_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::StaffActionLogsController do it "is a subclass of AdminController" do diff --git a/spec/controllers/admin/user_fields_controller_spec.rb b/spec/controllers/admin/user_fields_controller_spec.rb index fe63ce860de..cb0c95c9308 100644 --- a/spec/controllers/admin/user_fields_controller_spec.rb +++ b/spec/controllers/admin/user_fields_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::UserFieldsController do diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 4f93fe55a55..d49745940b4 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'single_sign_on' describe Admin::UsersController do @@ -37,7 +37,6 @@ describe Admin::UsersController do expect(UserHistory.where(action: UserHistory.actions[:check_email], acting_user_id: @user.id).count).to eq(0) xhr :get, :index, show_emails: "true" - data = ::JSON.parse(response.body) expect(UserHistory.where(action: UserHistory.actions[:check_email], acting_user_id: @user.id).count).to eq(1) end @@ -48,14 +47,14 @@ describe Admin::UsersController do describe '.show' do context 'an existing user' do it 'returns success' do - xhr :get, :show, id: @user.username + xhr :get, :show, id: @user.id expect(response).to be_success end end context 'an existing user' do it 'returns success' do - xhr :get, :show, id: 'foobar' + xhr :get, :show, id: 0 expect(response).not_to be_success end end @@ -173,6 +172,22 @@ describe Admin::UsersController do end end + context '.add_group' do + let(:user) { Fabricate(:user) } + let(:group) { Fabricate(:group) } + + it 'adds the user to the group' do + xhr :post, :add_group, group_id: group.id, user_id: user.id + expect(response).to be_success + + expect(GroupUser.where(user_id: user.id, group_id: group.id).exists?).to eq(true) + + # Doing it again doesn't raise an error + xhr :post, :add_group, group_id: group.id, user_id: user.id + expect(response).to be_success + end + end + context '.primary_group' do before do @another_user = Fabricate(:coding_horror) @@ -492,52 +507,66 @@ describe Admin::UsersController do end - it 'can sync up sso' do - log_in(:admin) - SiteSetting.enable_sso = true - SiteSetting.sso_overrides_email = true - SiteSetting.sso_overrides_name = true - SiteSetting.sso_overrides_username = true + context '#sync_sso' do + let(:sso) { SingleSignOn.new } + let(:sso_secret) { "sso secret" } - SiteSetting.sso_secret = "sso secret" + before do + log_in(:admin) - sso = SingleSignOn.new - sso.sso_secret = "sso secret" - sso.name = "Bob The Bob" - sso.username = "bob" - sso.email = "bob@bob.com" - sso.external_id = "1" + SiteSetting.enable_sso = true + SiteSetting.sso_overrides_email = true + SiteSetting.sso_overrides_name = true + SiteSetting.sso_overrides_username = true + SiteSetting.sso_secret = sso_secret + sso.sso_secret = sso_secret + end - user = DiscourseSingleSignOn.parse(sso.payload) - .lookup_or_create_user - sso.name = "Bill" - sso.username = "Hokli$$!!" - sso.email = "bob2@bob.com" + it 'can sync up with the sso' do + sso.name = "Bob The Bob" + sso.username = "bob" + sso.email = "bob@bob.com" + sso.external_id = "1" - xhr :post, :sync_sso, Rack::Utils.parse_query(sso.payload) - expect(response).to be_success + user = DiscourseSingleSignOn.parse(sso.payload) + .lookup_or_create_user - user.reload - expect(user.email).to eq("bob2@bob.com") - expect(user.name).to eq("Bill") - expect(user.username).to eq("Hokli") + sso.name = "Bill" + sso.username = "Hokli$$!!" + sso.email = "bob2@bob.com" - # It can also create new users - sso = SingleSignOn.new - sso.sso_secret = "sso secret" - sso.name = "Dr. Claw" - sso.username = "dr_claw" - sso.email = "dr@claw.com" - sso.external_id = "2" - xhr :post, :sync_sso, Rack::Utils.parse_query(sso.payload) - expect(response).to be_success + xhr :post, :sync_sso, Rack::Utils.parse_query(sso.payload) + expect(response).to be_success - user = User.where(email: 'dr@claw.com').first - expect(user).to be_present - expect(user.ip_address).to be_blank + user.reload + expect(user.email).to eq("bob2@bob.com") + expect(user.name).to eq("Bill") + expect(user.username).to eq("Hokli") + end + it 'should create new users' do + sso.name = "Dr. Claw" + sso.username = "dr_claw" + sso.email = "dr@claw.com" + sso.external_id = "2" + xhr :post, :sync_sso, Rack::Utils.parse_query(sso.payload) + expect(response).to be_success + + user = User.where(email: 'dr@claw.com').first + expect(user).to be_present + expect(user.ip_address).to be_blank + end + + it 'should return the right message if the record is invalid' do + sso.email = "" + sso.name = "" + sso.external_id = "1" + + xhr :post, :sync_sso, Rack::Utils.parse_query(sso.payload) + expect(response.status).to eq(403) + expect(JSON.parse(response.body)["message"]).to include("Email can't be blank") + end end - end diff --git a/spec/controllers/admin/versions_controller_spec.rb b/spec/controllers/admin/versions_controller_spec.rb index deca11ecc40..0353062d470 100644 --- a/spec/controllers/admin/versions_controller_spec.rb +++ b/spec/controllers/admin/versions_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'version' describe Admin::VersionsController do diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 9d0e17c0acf..1d46068aac6 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopicsController do before do @@ -13,6 +13,10 @@ describe TopicsController do request.env['HTTP_REFERER'] = ref end + def set_accept_language(locale) + request.env['HTTP_ACCEPT_LANGUAGE'] = locale + end + it "doesn't store an incoming link when there's no referer" do expect { get :show, id: topic.id @@ -33,7 +37,7 @@ describe TopicsController do end it "uses the application layout even with an escaped fragment param" do - get :show, {'topic_id' => topic.id, 'slug' => topic.slug, '_escaped_fragment_' => 'true'} + get :show, {'topic_id' => topic.id, 'slug' => topic.slug, '_escaped_fragment_' => 'true'} expect(response).to render_template(layout: 'application') assert_select "meta[name=fragment]", false, "it doesn't have the meta tag" end @@ -51,7 +55,7 @@ describe TopicsController do end it "uses the crawler layout when there's an _escaped_fragment_ param" do - get :show, topic_id: topic.id, slug: topic.slug, _escaped_fragment_: 'true' + get :show, topic_id: topic.id, slug: topic.slug, _escaped_fragment_: 'true' expect(response).to render_template(layout: 'crawler') assert_select "meta[name=fragment]", false, "it doesn't have the meta tag" end @@ -62,9 +66,6 @@ describe TopicsController do render_views context "when not a crawler" do - before do - CrawlerDetection.expects(:crawler?).returns(false) - end it "renders with the application layout" do get :show, topic_id: topic.id, slug: topic.slug expect(response).to render_template(layout: 'application') @@ -73,10 +74,8 @@ describe TopicsController do end context "when a crawler" do - before do - CrawlerDetection.expects(:crawler?).returns(true) - end it "renders with the crawler layout" do + request.env["HTTP_USER_AGENT"] = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" get :show, topic_id: topic.id, slug: topic.slug expect(response).to render_template(layout: 'crawler') assert_select "meta[name=fragment]", false, "it doesn't have the meta tag" @@ -85,25 +84,117 @@ describe TopicsController do end - describe 'set_locale' do - it 'sets the one the user prefers' do - SiteSetting.stubs(:allow_user_locale).returns(true) + describe 'clear_notifications' do + it 'correctly clears notifications if specified via cookie' do + notification = Fabricate(:notification) + log_in_user(notification.user) - user = Fabricate(:user, locale: :fr) - log_in_user(user) + request.cookies['cn'] = "2828,100,#{notification.id}" - get :show, {topic_id: topic.id} + get :show, {topic_id: 100} + + expect(response.cookies['cn']).to eq nil + + notification.reload + expect(notification.read).to eq true - expect(I18n.locale).to eq(:fr) end - it 'is sets the default locale when the setting not enabled' do - user = Fabricate(:user, locale: :fr) - log_in_user(user) + it 'correctly clears notifications if specified via header' do + notification = Fabricate(:notification) + log_in_user(notification.user) - get :show, {topic_id: topic.id} + request.headers['Discourse-Clear-Notifications'] = "2828,100,#{notification.id}" - expect(I18n.locale).to eq(:en) + get :show, {topic_id: 100} + + notification.reload + expect(notification.read).to eq true + end + end + + describe "set_locale" do + context "allow_user_locale disabled" do + context "accept-language header differs from default locale" do + before do + SiteSetting.stubs(:allow_user_locale).returns(false) + SiteSetting.stubs(:default_locale).returns("en") + set_accept_language("fr") + end + + context "with an anonymous user" do + it "uses the default locale" do + get :show, {topic_id: topic.id} + + expect(I18n.locale).to eq(:en) + end + end + + context "with a logged in user" do + it "it uses the default locale" do + user = Fabricate(:user, locale: :fr) + log_in_user(user) + + get :show, {topic_id: topic.id} + + expect(I18n.locale).to eq(:en) + end + end + end + end + + context "set_locale_from_accept_language_header enabled" do + context "accept-language header differs from default locale" do + before do + SiteSetting.stubs(:allow_user_locale).returns(true) + SiteSetting.stubs(:set_locale_from_accept_language_header).returns(true) + SiteSetting.stubs(:default_locale).returns("en") + set_accept_language("fr") + end + + context "with an anonymous user" do + it "uses the locale from the headers" do + get :show, {topic_id: topic.id} + + expect(I18n.locale).to eq(:fr) + end + end + + context "with a logged in user" do + it "uses the user's preferred locale" do + user = Fabricate(:user, locale: :fr) + log_in_user(user) + + get :show, {topic_id: topic.id} + + expect(I18n.locale).to eq(:fr) + end + end + end + + context "the preferred locale includes a region" do + it "returns the locale and region separated by an underscore" do + SiteSetting.stubs(:set_locale_from_accept_language_header).returns(true) + SiteSetting.stubs(:default_locale).returns("en") + set_accept_language("zh-CN") + + get :show, {topic_id: topic.id} + + expect(I18n.locale).to eq(:zh_CN) + end + end + + context 'accept-language header is not set' do + it 'uses the site default locale' do + SiteSetting.stubs(:allow_user_locale).returns(true) + SiteSetting.stubs(:default_locale).returns('en') + set_accept_language('') + + get :show, {topic_id: topic.id} + + expect(I18n.locale).to eq(:en) + end + end end end diff --git a/spec/controllers/badges_controller_spec.rb b/spec/controllers/badges_controller_spec.rb index ab98f35cf81..a2bb4420dcd 100644 --- a/spec/controllers/badges_controller_spec.rb +++ b/spec/controllers/badges_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe BadgesController do let!(:badge) { Fabricate(:badge) } diff --git a/spec/controllers/categories_controller_spec.rb b/spec/controllers/categories_controller_spec.rb index f03cfd05e8c..d9d9240b544 100644 --- a/spec/controllers/categories_controller_spec.rb +++ b/spec/controllers/categories_controller_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe CategoriesController do describe "create" do @@ -64,6 +64,7 @@ describe CategoriesController do expect(category.slug).to eq("hello-cat") expect(category.color).to eq("ff0") expect(category.auto_close_hours).to eq(72) + expect(UserHistory.count).to eq(1) end end end @@ -90,6 +91,7 @@ describe CategoriesController do it "deletes the record" do Guardian.any_instance.expects(:can_delete_category?).returns(true) expect { xhr :delete, :destroy, id: @category.slug}.to change(Category, :count).by(-1) + expect(UserHistory.count).to eq(1) end end @@ -215,6 +217,19 @@ describe CategoriesController do expect(@category.auto_close_hours).to eq(72) expect(@category.custom_fields).to eq({"dancing" => "frogs"}) end + + it 'logs the changes correctly' do + @category.update!(permissions: { "admins" => CategoryGroup.permission_types[:create_post] }) + + xhr :put , :update, id: @category.id, name: 'new name', + color: @category.color, text_color: @category.text_color, + slug: @category.slug, + permissions: { + "everyone" => CategoryGroup.permission_types[:create_post] + } + + expect(UserHistory.count).to eq(2) + end end end diff --git a/spec/controllers/category_hashtags_controller_spec.rb b/spec/controllers/category_hashtags_controller_spec.rb new file mode 100644 index 00000000000..e5f1515614c --- /dev/null +++ b/spec/controllers/category_hashtags_controller_spec.rb @@ -0,0 +1,46 @@ +require 'rails_helper' + +describe CategoryHashtagsController do + describe "check" do + describe "logged in" do + before do + log_in(:user) + end + + it 'only returns the categories that are valid' do + category = Fabricate(:category) + xhr :get, :check, category_slugs: [category.slug, 'none'] + + expect(JSON.parse(response.body)).to eq( + { "valid" => [{ "slug" => category.hashtag_slug, "url" => category.url_with_id }] } + ) + end + + it 'does not return restricted categories for a normal user' do + group = Fabricate(:group) + private_category = Fabricate(:private_category, group: group) + xhr :get, :check, category_slugs: [private_category.slug] + + expect(JSON.parse(response.body)).to eq({ "valid" => [] }) + end + + it 'returns restricted categories for an admin' do + admin = log_in(:admin) + group = Fabricate(:group) + group.add(admin) + private_category = Fabricate(:private_category, group: group) + xhr :get, :check, category_slugs: [private_category.slug] + + expect(JSON.parse(response.body)).to eq( + { "valid" => [{ "slug" => private_category.hashtag_slug, "url" => private_category.url_with_id }] } + ) + end + end + + describe "not logged in" do + it 'raises an exception' do + expect { xhr :get, :check, category_slugs: [] }.to raise_error(Discourse::NotLoggedIn) + end + end + end +end diff --git a/spec/controllers/clicks_controller_spec.rb b/spec/controllers/clicks_controller_spec.rb index 18b9ad77958..3beaf783ef6 100644 --- a/spec/controllers/clicks_controller_spec.rb +++ b/spec/controllers/clicks_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ClicksController do diff --git a/spec/controllers/composer_messages_controller_spec.rb b/spec/controllers/composer_messages_controller_spec.rb index 4c7b77fe2d7..2365439153d 100644 --- a/spec/controllers/composer_messages_controller_spec.rb +++ b/spec/controllers/composer_messages_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ComposerMessagesController do diff --git a/spec/controllers/directory_items_controller_spec.rb b/spec/controllers/directory_items_controller_spec.rb index b33b0590eb6..38132d8e211 100644 --- a/spec/controllers/directory_items_controller_spec.rb +++ b/spec/controllers/directory_items_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe DirectoryItemsController do diff --git a/spec/controllers/draft_controller_spec.rb b/spec/controllers/draft_controller_spec.rb index 86bc5a9b671..1153e7529ca 100644 --- a/spec/controllers/draft_controller_spec.rb +++ b/spec/controllers/draft_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe DraftController do diff --git a/spec/controllers/email_controller_spec.rb b/spec/controllers/email_controller_spec.rb index c1635c53130..0376076b9f9 100644 --- a/spec/controllers/email_controller_spec.rb +++ b/spec/controllers/email_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe EmailController do @@ -21,7 +21,11 @@ describe EmailController do context '.resubscribe' do - let(:user) { Fabricate(:user, email_digests: false) } + let(:user) { + user = Fabricate(:user) + user.user_option.update_columns(email_digests: false) + user + } let(:key) { DigestUnsubscribeKey.create_key_for(user) } context 'with a valid key' do @@ -31,7 +35,7 @@ describe EmailController do end it 'subscribes the user' do - expect(user.email_digests).to eq(true) + expect(user.user_option.email_digests).to eq(true) end end @@ -39,9 +43,28 @@ describe EmailController do context '.unsubscribe' do - let(:user) { Fabricate(:user) } + let(:user) { + user = Fabricate(:user) + user.user_option.update_columns(email_always: true, email_digests: true, email_direct: true, email_private_messages: true) + user + } let(:key) { DigestUnsubscribeKey.create_key_for(user) } + context 'from confirm unsubscribe email' do + before do + get :unsubscribe, key: key, from_all: true + user.reload + end + + it 'unsubscribes from all emails' do + options = user.user_option + expect(options.email_digests).to eq false + expect(options.email_direct).to eq false + expect(options.email_private_messages).to eq false + expect(options.email_always).to eq false + end + end + context 'with a valid key' do before do get :unsubscribe, key: key @@ -49,7 +72,7 @@ describe EmailController do end it 'unsubscribes the user' do - expect(user.email_digests).to eq(false) + expect(user.user_option.email_digests).to eq(false) end it "sets the appropriate instance variables" do @@ -76,7 +99,7 @@ describe EmailController do end it 'does not unsubscribe the user' do - expect(user.email_digests).to eq(true) + expect(user.user_option.email_digests).to eq(true) end it 'sets the appropriate instance variables' do @@ -94,7 +117,7 @@ describe EmailController do end it 'unsubscribes the user' do - expect(user.email_digests).to eq(false) + expect(user.user_option.email_digests).to eq(false) end it 'sets the appropriate instance variables' do diff --git a/spec/controllers/embed_controller_spec.rb b/spec/controllers/embed_controller_spec.rb index 9947844c7e1..9539666d6c9 100644 --- a/spec/controllers/embed_controller_spec.rb +++ b/spec/controllers/embed_controller_spec.rb @@ -1,9 +1,10 @@ -require 'spec_helper' +require 'rails_helper' describe EmbedController do let(:host) { "eviltrout.com" } let(:embed_url) { "http://eviltrout.com/2013/02/10/why-discourse-uses-emberjs.html" } + let(:discourse_username) { "eviltrout" } it "is 404 without an embed_url" do get :comments @@ -94,6 +95,12 @@ describe EmbedController do TopicView.expects(:new).with(123, nil, {limit: 100, exclude_first: true, exclude_deleted_users: true}) get :comments, embed_url: embed_url end + + it "provides the topic retriever with the discourse username when provided" do + TopicRetriever.expects(:new).with(embed_url, has_entry({author_username: discourse_username})) + get :comments, embed_url: embed_url, discourse_username: discourse_username + end + end end diff --git a/spec/controllers/export_csv_controller_spec.rb b/spec/controllers/export_csv_controller_spec.rb index 440ccc11ef0..3505512bc45 100644 --- a/spec/controllers/export_csv_controller_spec.rb +++ b/spec/controllers/export_csv_controller_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe ExportCsvController do let(:export_filename) { "user-archive-codinghorror-150115-234817-999.csv.gz" } diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index a148b5eea55..fded427a080 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe GroupsController do let(:group) { Fabricate(:group) } @@ -26,18 +26,16 @@ describe GroupsController do end describe "counts" do - it "ensures the group can be seen" do - Guardian.any_instance.expects(:can_see?).with(group).returns(false) - xhr :get, :counts, group_id: group.name - expect(response).not_to be_success - end - - it "performs the query and responds with JSON" do - Guardian.any_instance.expects(:can_see?).with(group).returns(true) - Group.any_instance.expects(:posts_for).returns(Group.none) + it "returns counts if it can be seen" do xhr :get, :counts, group_id: group.name expect(response).to be_success end + + it "returns no counts if it can not be seen" do + group.update_columns(visible: false) + xhr :get, :counts, group_id: group.name + expect(response).not_to be_success + end end describe "posts" do @@ -90,18 +88,18 @@ describe GroupsController do it "refuses membership changes to unauthorized users" do Guardian.any_instance.stubs(:can_edit?).with(group).returns(false) - xhr :put, :add_members, group_id: group.name, usernames: "bob" + xhr :put, :add_members, id: group.id, usernames: "bob" expect(response).to be_forbidden - xhr :delete, :remove_member, group_id: group.name, username: "bob" + xhr :delete, :remove_member, id: group.id, username: "bob" expect(response).to be_forbidden end it "cannot add members to automatic groups" do Guardian.any_instance.stubs(:is_admin?).returns(true) - auto_group = Fabricate(:group, name: "auto_group", automatic: true) + group = Fabricate(:group, name: "auto_group", automatic: true) - xhr :put, :add_members, group_id: group.name, usernames: "bob" + xhr :put, :add_members, id: group.id, usernames: "bob" expect(response).to be_forbidden end end @@ -117,44 +115,132 @@ describe GroupsController do it "can make incremental adds" do user2 = Fabricate(:user) - xhr :put, :add_members, group_id: group.name, usernames: user2.username + xhr :put, :add_members, id: group.id, usernames: user2.username expect(response).to be_success group.reload expect(group.users.count).to eq(2) end - it "succeeds silently when adding non-existent users" do - xhr :put, :add_members, group_id: group.name, usernames: "nosuchperson" - - expect(response).to be_success - group.reload - expect(group.users.count).to eq(1) - end - - it "succeeds silently when adding duplicate users" do - xhr :put, :add_members, group_id: group.name, usernames: @user1.username - - expect(response).to be_success - group.reload - expect(group.users).to eq([@user1]) - end - it "can make incremental deletes" do - xhr :delete, :remove_member, group_id: group.name, username: @user1.username + xhr :delete, :remove_member, id: group.id, username: @user1.username expect(response).to be_success group.reload expect(group.users.count).to eq(0) end - it "succeeds silently when removing non-members" do - user2 = Fabricate(:user) - xhr :delete, :remove_member, group_id: group.name, username: user2.username + end + context ".add_members" do + + before do + @admin = log_in(:admin) + end + + it "cannot add members to automatic groups" do + xhr :put, :add_members, id: 1, usernames: "l77t" + expect(response.status).to eq(403) + end + + context "is able to add several members to a group" do + + let(:user1) { Fabricate(:user) } + let(:user2) { Fabricate(:user) } + let(:group) { Fabricate(:group) } + + it "adds by username" do + xhr :put, :add_members, id: group.id, usernames: [user1.username, user2.username].join(",") + + expect(response).to be_success + group.reload + expect(group.users.count).to eq(2) + end + + it "adds by id" do + xhr :put, :add_members, id: group.id, user_ids: [user1.id, user2.id].join(",") + + expect(response).to be_success + group.reload + expect(group.users.count).to eq(2) + end + end + + it "returns 422 if member already exists" do + group = Fabricate(:group) + existing_member = Fabricate(:user) + group.add(existing_member) + group.save + + xhr :put, :add_members, id: group.id, usernames: existing_member.username + expect(response.status).to eq(422) + end + + end + + context ".remove_member" do + + before do + @admin = log_in(:admin) + end + + it "cannot remove members from automatic groups" do + xhr :put, :remove_member, id: 1, user_id: 42 + expect(response.status).to eq(403) + end + + context "is able to remove a member" do + + let(:user) { Fabricate(:user) } + let(:group) { Fabricate(:group) } + + before do + group.add(user) + group.save + end + + it "removes by id" do + xhr :delete, :remove_member, id: group.id, user_id: user.id + + expect(response).to be_success + group.reload + expect(group.users.count).to eq(0) + end + + it "removes by username" do + xhr :delete, :remove_member, id: group.id, username: user.username + + expect(response).to be_success + group.reload + expect(group.users.count).to eq(0) + end + + it "removes user.primary_group_id when user is removed from group" do + user.primary_group_id = group.id + user.save + + xhr :delete, :remove_member, id: group.id, username: user.username + + user.reload + expect(user.primary_group_id).to eq(nil) + end + end + + end + + describe '.posts_feed' do + it 'renders RSS' do + get :posts_feed, group_id: group.name, format: :rss expect(response).to be_success - group.reload - expect(group.users.count).to eq(1) + expect(response.content_type).to eq('application/rss+xml') + end + end + + describe '.mentions_feed' do + it 'renders RSS' do + get :mentions_feed, group_id: group.name, format: :rss + expect(response).to be_success + expect(response.content_type).to eq('application/rss+xml') end end diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index 7acdf7874ea..745c781f9cb 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe InvitesController do @@ -218,6 +218,16 @@ describe InvitesController do end end + context 'user is already logged in' do + let!(:user) { log_in } + let(:topic) { Fabricate(:topic) } + let(:invite) { topic.invite_by_email(topic.user, "iceking@adventuretime.ooo") } + + it "doesn't redeem the invite" do + Invite.any_instance.stubs(:redeem).never + get :show, id: invite.invite_key + end + end end context '.create_disposable_invite' do diff --git a/spec/controllers/list_controller_spec.rb b/spec/controllers/list_controller_spec.rb index 41f343ca10b..e2de6b62356 100644 --- a/spec/controllers/list_controller_spec.rb +++ b/spec/controllers/list_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ListController do @@ -83,6 +83,26 @@ describe ListController do it { is_expected.to respond_with(:success) } end + context 'with a link that has a parent slug, slug and id in its path' do + let(:child_category) { Fabricate(:category, parent_category: category) } + + context "with valid slug" do + before do + xhr :get, :category_latest, parent_category: category.slug, category: child_category.slug, id: child_category.id + end + + it { is_expected.to redirect_to(child_category.url) } + end + + context "with invalid slug" do + before do + xhr :get, :category_latest, parent_category: 'random slug', category: 'random slug', id: child_category.id + end + + it { is_expected.to redirect_to(child_category.url) } + end + end + context 'another category exists with a number at the beginning of its name' do # One category has another category's id at the beginning of its name let!(:other_category) { Fabricate(:category, name: "#{category.id} name") } @@ -228,4 +248,30 @@ describe ListController do end + describe "categories suppression" do + let(:category_one) { Fabricate(:category) } + let(:sub_category) { Fabricate(:category, parent_category: category_one, suppress_from_homepage: true) } + let!(:topic_in_sub_category) { Fabricate(:topic, category: sub_category) } + + let(:category_two) { Fabricate(:category, suppress_from_homepage: true) } + let!(:topic_in_category_two) { Fabricate(:topic, category: category_two) } + + it "suppresses categories from the homepage" do + get SiteSetting.homepage, format: :json + expect(response).to be_success + + topic_titles = JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["title"] } + expect(topic_titles).not_to include(topic_in_sub_category.title, topic_in_category_two.title) + end + + it "does not suppress" do + get SiteSetting.homepage, category: category_one.id, format: :json + expect(response).to be_success + + topic_titles = JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["title"] } + expect(topic_titles).to include(topic_in_sub_category.title) + end + + end + end diff --git a/spec/controllers/manifest_json_controller_spec.rb b/spec/controllers/manifest_json_controller_spec.rb new file mode 100644 index 00000000000..d0fd39e836a --- /dev/null +++ b/spec/controllers/manifest_json_controller_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +RSpec.describe ManifestJsonController do + context 'index' do + it 'returns the right output' do + title = 'MyApp' + SiteSetting.title = title + get :index + expect(response.body).to include(title) + end + end +end diff --git a/spec/controllers/notifications_controller_spec.rb b/spec/controllers/notifications_controller_spec.rb index 175aea63b6a..da58fc6e6c3 100644 --- a/spec/controllers/notifications_controller_spec.rb +++ b/spec/controllers/notifications_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe NotificationsController do diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb index def39e3d485..62f803cea41 100644 --- a/spec/controllers/omniauth_callbacks_controller_spec.rb +++ b/spec/controllers/omniauth_callbacks_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Users::OmniauthCallbacksController do diff --git a/spec/controllers/onebox_controller_spec.rb b/spec/controllers/onebox_controller_spec.rb index 12eaa3103a0..a2f5c381740 100644 --- a/spec/controllers/onebox_controller_spec.rb +++ b/spec/controllers/onebox_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe OneboxController do diff --git a/spec/controllers/permalinks_controller_spec.rb b/spec/controllers/permalinks_controller_spec.rb index d90b3de690c..d88f7c7d671 100644 --- a/spec/controllers/permalinks_controller_spec.rb +++ b/spec/controllers/permalinks_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PermalinksController do describe 'show' do @@ -10,6 +10,16 @@ describe PermalinksController do expect(response.status).to eq(301) end + it "should work for subfolder installs too" do + GlobalSetting.stubs(:relative_url_root).returns('/forum') + Discourse.stubs(:base_uri).returns("/forum") + permalink = Fabricate(:permalink) + Permalink.any_instance.stubs(:target_url).returns('/forum/t/the-topic-slug/42') + get :show, url: permalink.url + expect(response).to redirect_to('/forum/t/the-topic-slug/42') + expect(response.status).to eq(301) + end + it "should apply normalizations" do SiteSetting.permalink_normalizations = "/(.*)\\?.*/\\1" diff --git a/spec/controllers/post_action_users_controller_spec.rb b/spec/controllers/post_action_users_controller_spec.rb new file mode 100644 index 00000000000..c915b5e5b55 --- /dev/null +++ b/spec/controllers/post_action_users_controller_spec.rb @@ -0,0 +1,34 @@ +require 'rails_helper' + +describe PostActionUsersController do + let!(:post) { Fabricate(:post, user: log_in) } + + it 'raises an error without an id' do + expect { + xhr :get, :index, post_action_type_id: PostActionType.types[:like] + }.to raise_error(ActionController::ParameterMissing) + end + + it 'raises an error without a post action type' do + expect { + xhr :get, :index, id: post.id + }.to raise_error(ActionController::ParameterMissing) + end + + it "fails when the user doesn't have permission to see the post" do + Guardian.any_instance.expects(:can_see?).with(post).returns(false) + xhr :get, :index, id: post.id, post_action_type_id: PostActionType.types[:like] + expect(response).to be_forbidden + end + + it 'raises an error when the post action type cannot be seen' do + Guardian.any_instance.expects(:can_see_post_actors?).with(instance_of(Topic), PostActionType.types[:like]).returns(false) + xhr :get, :index, id: post.id, post_action_type_id: PostActionType.types[:like] + expect(response).to be_forbidden + end + + it 'succeeds' do + xhr :get, :index, id: post.id, post_action_type_id: PostActionType.types[:like] + expect(response).to be_success + end +end diff --git a/spec/controllers/post_actions_controller_spec.rb b/spec/controllers/post_actions_controller_spec.rb index 09e00b3b5fb..ca822b832e4 100644 --- a/spec/controllers/post_actions_controller_spec.rb +++ b/spec/controllers/post_actions_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PostActionsController do @@ -7,7 +7,7 @@ describe PostActionsController do expect { xhr :post, :create }.to raise_error(Discourse::NotLoggedIn) end - describe 'logged in' do + describe 'logged in as moderator' do before do @user = log_in(:moderator) @post = Fabricate(:post, user: Fabricate(:coding_horror)) @@ -154,39 +154,4 @@ describe PostActionsController do end - describe 'users' do - - let!(:post) { Fabricate(:post, user: log_in) } - - it 'raises an error without an id' do - expect { - xhr :get, :users, post_action_type_id: PostActionType.types[:like] - }.to raise_error(ActionController::ParameterMissing) - end - - it 'raises an error without a post action type' do - expect { - xhr :get, :users, id: post.id - }.to raise_error(ActionController::ParameterMissing) - end - - it "fails when the user doesn't have permission to see the post" do - Guardian.any_instance.expects(:can_see?).with(post).returns(false) - xhr :get, :users, id: post.id, post_action_type_id: PostActionType.types[:like] - expect(response).to be_forbidden - end - - it 'raises an error when the post action type cannot be seen' do - Guardian.any_instance.expects(:can_see_post_actors?).with(instance_of(Topic), PostActionType.types[:like]).returns(false) - xhr :get, :users, id: post.id, post_action_type_id: PostActionType.types[:like] - expect(response).to be_forbidden - end - - it 'succeeds' do - xhr :get, :users, id: post.id, post_action_type_id: PostActionType.types[:like] - expect(response).to be_success - end - - end - end diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index cc42bf48e41..da23e399cf1 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' shared_examples 'finding and showing post' do let(:user) { log_in } @@ -53,6 +53,79 @@ end describe PostsController do + describe 'latest' do + let(:user) { log_in } + let!(:public_topic) { Fabricate(:topic) } + let!(:post) { Fabricate(:post, user: user, topic: public_topic) } + let!(:private_topic) { Fabricate(:topic, archetype: Archetype.private_message, category: nil) } + let!(:private_post) { Fabricate(:post, user: user, topic: private_topic) } + let!(:topicless_post) { Fabricate(:post, user: user, raw: '

        Car 54, where are you?

        ') } + + context "public posts" do + before do + topicless_post.update topic_id: -100 + end + + it 'returns public posts with topic for json' do + xhr :get, :latest, id: "latest_posts", format: :json + expect(response).to be_success + json = ::JSON.parse(response.body) + post_ids = json['latest_posts'].map { |p| p['id'] } + expect(post_ids).to include post.id + expect(post_ids).to_not include private_post.id + expect(post_ids).to_not include topicless_post.id + end + + it 'returns public posts with topic for rss' do + xhr :get, :latest, id: "latest_posts", format: :rss + expect(response).to be_success + expect(assigns(:posts)).to include post + expect(assigns(:posts)).to_not include private_post + expect(assigns(:posts)).to_not include topicless_post + end + end + + context 'private posts' do + before do + Guardian.any_instance.expects(:can_see?).with(private_post).returns(true) + end + + it 'returns private posts for json' do + xhr :get, :latest, id: "private_posts", format: :json + expect(response).to be_success + json = ::JSON.parse(response.body) + post_ids = json['private_posts'].map { |p| p['id'] } + expect(post_ids).to include private_post.id + expect(post_ids).to_not include post.id + end + + it 'returns private posts for rss' do + xhr :get, :latest, id: "private_posts", format: :rss + expect(response).to be_success + expect(assigns(:posts)).to include private_post + expect(assigns(:posts)).to_not include post + end + end + end + + describe 'user_posts_feed' do + let(:user) { log_in } + let!(:public_topic) { Fabricate(:topic) } + let!(:post) { Fabricate(:post, user: user, topic: public_topic) } + let!(:private_topic) { Fabricate(:topic, archetype: Archetype.private_message, category: nil) } + let!(:private_post) { Fabricate(:post, user: user, topic: private_topic) } + let!(:topicless_post) { Fabricate(:post, user: user, raw: '

        Car 54, where are you?

        ') } + + it 'returns public posts with topic for rss' do + topicless_post.update topic_id: -100 + xhr :get, :user_posts_feed, username: user.username, format: :rss + expect(response).to be_success + expect(assigns(:posts)).to include post + expect(assigns(:posts)).to_not include private_post + expect(assigns(:posts)).to_not include topicless_post + end + end + describe 'cooked' do before do post = Post.new(cooked: 'wat') @@ -262,16 +335,18 @@ describe PostsController do include_examples 'action requires login', :put, :update, id: 2 - describe 'when logged in' do + let(:post) { Fabricate(:post, user: logged_in_as) } + let(:update_params) do + { + id: post.id, + post: { raw: 'edited body', edit_reason: 'typo' }, + image_sizes: { 'http://image.com/image.jpg' => {'width' => 123, 'height' => 456} }, + } + end + let(:moderator) { Fabricate(:moderator) } - let(:post) { Fabricate(:post, user: log_in) } - let(:update_params) do - { - id: post.id, - post: { raw: 'edited body', edit_reason: 'typo' }, - image_sizes: { 'http://image.com/image.jpg' => {'width' => 123, 'height' => 456} }, - } - end + describe 'when logged in as a regular user' do + let(:logged_in_as) { log_in } it 'does not allow to update when edit time limit expired' do Guardian.any_instance.stubs(:can_edit?).with(post).returns(false) @@ -316,6 +391,28 @@ describe PostsController do xhr :put, :update, update_params end + it "doesn't allow updating of deleted posts" do + first_post = post.topic.ordered_posts.first + PostDestroyer.new(moderator, first_post).destroy + + xhr :put, :update, update_params + expect(response).not_to be_success + end + end + + describe "when logged in as staff" do + let(:logged_in_as) { log_in(:moderator) } + + it "supports updating posts in deleted topics" do + first_post = post.topic.ordered_posts.first + PostDestroyer.new(moderator, first_post).destroy + + xhr :put, :update, update_params + expect(response).to be_success + + post.reload + expect(post.raw).to eq('edited body') + end end end @@ -358,7 +455,7 @@ describe PostsController do let(:post) {Fabricate(:post, user: user)} it "raises an error if the user doesn't have permission to wiki the post" do - Guardian.any_instance.expects(:can_wiki?).returns(false) + Guardian.any_instance.expects(:can_wiki?).with(post).returns(false) xhr :put, :wiki, post_id: post.id, wiki: 'true' @@ -366,7 +463,7 @@ describe PostsController do end it "can wiki a post" do - Guardian.any_instance.expects(:can_wiki?).returns(true) + Guardian.any_instance.expects(:can_wiki?).with(post).returns(true) xhr :put, :wiki, post_id: post.id, wiki: 'true' @@ -376,7 +473,7 @@ describe PostsController do it "can unwiki a post" do wikied_post = Fabricate(:post, user: user, wiki: true) - Guardian.any_instance.expects(:can_wiki?).returns(true) + Guardian.any_instance.expects(:can_wiki?).with(wikied_post).returns(true) xhr :put, :wiki, post_id: wikied_post.id, wiki: 'false' @@ -533,6 +630,40 @@ describe PostsController do expect(parsed['cooked']).to be_present end + it "can send a message to a group" do + + group = Group.create(name: 'test_group', alias_level: Group::ALIAS_LEVELS[:nobody]) + user1 = Fabricate(:user) + group.add(user1) + + xhr :post, :create, { + raw: 'I can haz a test', + title: 'I loves my test', + target_usernames: group.name, + archetype: Archetype.private_message + } + + expect(response).not_to be_success + + # allow pm to this group + group.update_columns(alias_level: Group::ALIAS_LEVELS[:everyone]) + + xhr :post, :create, { + raw: 'I can haz a test', + title: 'I loves my test', + target_usernames: group.name, + archetype: Archetype.private_message + } + + expect(response).to be_success + + parsed = ::JSON.parse(response.body) + post = Post.find(parsed['id']) + + expect(post.topic.topic_allowed_users.length).to eq(1) + expect(post.topic.topic_allowed_groups.length).to eq(1) + end + it "returns the nested post with a param" do xhr :post, :create, {raw: 'this is the test content', title: 'this is the test title for the topic', @@ -746,6 +877,79 @@ describe PostsController do end + describe 'revert post to a specific revision' do + include_examples 'action requires login', :put, :revert, post_id: 123, revision: 2 + + let(:post) { Fabricate(:post, user: logged_in_as, raw: "Lorem ipsum dolor sit amet, cu nam libris tractatos, ancillae senserit ius ex") } + let(:post_revision) { Fabricate(:post_revision, post: post, modifications: {"raw" => ["this is original post body.", "this is edited post body."]}) } + let(:blank_post_revision) { Fabricate(:post_revision, post: post, modifications: {"edit_reason" => ["edit reason #1", "edit reason #2"]}) } + let(:same_post_revision) { Fabricate(:post_revision, post: post, modifications: {"raw" => ["Lorem ipsum dolor sit amet, cu nam libris tractatos, ancillae senserit ius ex", "this is edited post body."]}) } + + let(:revert_params) do + { + post_id: post.id, + revision: post_revision.number + } + end + let(:moderator) { Fabricate(:moderator) } + + describe 'when logged in as a regular user' do + let(:logged_in_as) { log_in } + + it "does not work" do + xhr :put, :revert, revert_params + expect(response).to_not be_success + end + end + + describe "when logged in as staff" do + let(:logged_in_as) { log_in(:moderator) } + + it "throws an exception when revision is < 2" do + expect { + xhr :put, :revert, post_id: post.id, revision: 1 + }.to raise_error(Discourse::InvalidParameters) + end + + it "fails when post_revision record is not found" do + xhr :put, :revert, post_id: post.id, revision: post_revision.number + 1 + expect(response).to_not be_success + end + + it "fails when post record is not found" do + xhr :put, :revert, post_id: post.id + 1, revision: post_revision.number + expect(response).to_not be_success + end + + it "fails when revision is blank" do + xhr :put, :revert, post_id: post.id, revision: blank_post_revision.number + + expect(response.status).to eq(422) + expect(JSON.parse(response.body)['errors']).to include(I18n.t('revert_version_same')) + end + + it "fails when revised version is same as current version" do + xhr :put, :revert, post_id: post.id, revision: same_post_revision.number + + expect(response.status).to eq(422) + expect(JSON.parse(response.body)['errors']).to include(I18n.t('revert_version_same')) + end + + it "works!" do + xhr :put, :revert, revert_params + expect(response).to be_success + end + + it "supports reverting posts in deleted topics" do + first_post = post.topic.ordered_posts.first + PostDestroyer.new(moderator, first_post).destroy + + xhr :put, :revert, revert_params + expect(response).to be_success + end + end + end + describe 'expandable embedded posts' do let(:post) { Fabricate(:post) } @@ -835,8 +1039,7 @@ describe PostsController do Fabricate(:moderator) group = Fabricate(:group) - group.add(user) - group.appoint_manager(user) + group.add_owner(user) secured_category = Fabricate(:private_category, group: group) secured_post = create_post(user: user, category: secured_category) diff --git a/spec/controllers/queued_posts_controller_spec.rb b/spec/controllers/queued_posts_controller_spec.rb index 1e4210797ad..f6c4b4a62c7 100644 --- a/spec/controllers/queued_posts_controller_spec.rb +++ b/spec/controllers/queued_posts_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'queued_posts_controller' require_dependency 'queued_post' diff --git a/spec/controllers/robots_txt_controller_spec.rb b/spec/controllers/robots_txt_controller_spec.rb index 615cca3f606..8ee44f9a47e 100644 --- a/spec/controllers/robots_txt_controller_spec.rb +++ b/spec/controllers/robots_txt_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe RobotsTxtController do diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index d44f311880d..ceb07f93de8 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe SearchController do diff --git a/spec/controllers/session_controller_spec.rb b/spec/controllers/session_controller_spec.rb index 59a838a52f4..492093b438e 100644 --- a/spec/controllers/session_controller_spec.rb +++ b/spec/controllers/session_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe SessionController do @@ -264,40 +264,61 @@ describe SessionController do expect(response.code).to eq('419') end - it 'can act as an SSO provider' do - SiteSetting.enable_sso_provider = true - SiteSetting.enable_sso = false - SiteSetting.enable_local_logins = true - SiteSetting.sso_secret = "topsecret" + describe 'can act as an SSO provider' do + before do + SiteSetting.enable_sso_provider = true + SiteSetting.enable_sso = false + SiteSetting.enable_local_logins = true + SiteSetting.sso_secret = "topsecret" - sso = SingleSignOn.new - sso.nonce = "mynonce" - sso.sso_secret = SiteSetting.sso_secret - sso.return_sso_url = "http://somewhere.over.rainbow/sso" + @sso = SingleSignOn.new + @sso.nonce = "mynonce" + @sso.sso_secret = SiteSetting.sso_secret + @sso.return_sso_url = "http://somewhere.over.rainbow/sso" - get :sso_provider, Rack::Utils.parse_query(sso.payload) + @user = Fabricate(:user, password: "frogs", active: true, admin: true) + EmailToken.update_all(confirmed: true) + end - expect(response).to redirect_to("/login") + it "successfully logs in and redirects user to return_sso_url when the user is not logged in" do + get :sso_provider, Rack::Utils.parse_query(@sso.payload) + expect(response).to redirect_to("/login") - user = Fabricate(:user, password: "frogs", active: true, admin: true) - EmailToken.update_all(confirmed: true) + xhr :post, :create, login: @user.username, password: "frogs", format: :json - xhr :post, :create, login: user.username, password: "frogs", format: :json + location = cookies[:sso_destination_url] + # javascript code will handle redirection of user to return_sso_url + expect(location).to match(/^http:\/\/somewhere.over.rainbow\/sso/) - location = response.header["Location"] - expect(location).to match(/^http:\/\/somewhere.over.rainbow\/sso/) + payload = location.split("?")[1] + sso2 = SingleSignOn.parse(payload, "topsecret") - payload = location.split("?")[1] + expect(sso2.email).to eq(@user.email) + expect(sso2.name).to eq(@user.name) + expect(sso2.username).to eq(@user.username) + expect(sso2.external_id).to eq(@user.id.to_s) + expect(sso2.admin).to eq(true) + expect(sso2.moderator).to eq(false) + end - sso2 = SingleSignOn.parse(payload, "topsecret") + it "successfully redirects user to return_sso_url when the user is logged in" do + log_in_user(@user) - expect(sso2.email).to eq(user.email) - expect(sso2.name).to eq(user.name) - expect(sso2.username).to eq(user.username) - expect(sso2.external_id).to eq(user.id.to_s) - expect(sso2.admin).to eq(true) - expect(sso2.moderator).to eq(false) + get :sso_provider, Rack::Utils.parse_query(@sso.payload) + location = response.header["Location"] + expect(location).to match(/^http:\/\/somewhere.over.rainbow\/sso/) + + payload = location.split("?")[1] + sso2 = SingleSignOn.parse(payload, "topsecret") + + expect(sso2.email).to eq(@user.email) + expect(sso2.name).to eq(@user.name) + expect(sso2.username).to eq(@user.username) + expect(sso2.external_id).to eq(@user.id.to_s) + expect(sso2.admin).to eq(true) + expect(sso2.moderator).to eq(false) + end end describe 'local attribute override from SSO payload' do @@ -507,6 +528,7 @@ describe SessionController do let(:permitted_ip_address) { '111.234.23.11' } before do Fabricate(:screened_ip_address, ip_address: permitted_ip_address, action_type: ScreenedIpAddress.actions[:allow_admin]) + SiteSetting.stubs(:use_admin_ip_whitelist).returns(true) end it 'is successful for admin at the ip address' do @@ -616,15 +638,28 @@ describe SessionController do end context 'do nothing to system username' do - let(:user) { Discourse.system_user } + let(:system) { Discourse.system_user } it 'generates no token for system username' do - expect { xhr :post, :forgot_password, login: user.username}.not_to change(EmailToken, :count) + expect { xhr :post, :forgot_password, login: system.username}.not_to change(EmailToken, :count) end it 'enqueues no email' do Jobs.expects(:enqueue).never - xhr :post, :forgot_password, login: user.username + xhr :post, :forgot_password, login: system.username + end + end + + context 'for a staged account' do + let!(:staged) { Fabricate(:staged) } + + it 'generates no token for staged username' do + expect { xhr :post, :forgot_password, login: staged.username}.not_to change(EmailToken, :count) + end + + it 'enqueues no email' do + Jobs.expects(:enqueue).never + xhr :post, :forgot_password, login: staged.username end end end diff --git a/spec/controllers/similar_topics_controller_spec.rb b/spec/controllers/similar_topics_controller_spec.rb index fc6c3f9d47f..93dfa5ef9e0 100644 --- a/spec/controllers/similar_topics_controller_spec.rb +++ b/spec/controllers/similar_topics_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe SimilarTopicsController do context 'similar_to' do diff --git a/spec/controllers/site_customizations_controller_spec.rb b/spec/controllers/site_customizations_controller_spec.rb index d9948d5950c..d3a0f17451d 100644 --- a/spec/controllers/site_customizations_controller_spec.rb +++ b/spec/controllers/site_customizations_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe SiteCustomizationsController do diff --git a/spec/controllers/static_controller_spec.rb b/spec/controllers/static_controller_spec.rb index 786445e16b8..b5b8eb0b748 100644 --- a/spec/controllers/static_controller_spec.rb +++ b/spec/controllers/static_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe StaticController do diff --git a/spec/controllers/stylesheets_controller_spec.rb b/spec/controllers/stylesheets_controller_spec.rb index a74ab3df727..5a5f9cf05f7 100644 --- a/spec/controllers/stylesheets_controller_spec.rb +++ b/spec/controllers/stylesheets_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe StylesheetsController do diff --git a/spec/controllers/topics_controller_spec.rb b/spec/controllers/topics_controller_spec.rb index aba6ae9fec5..d06b4ff1cd7 100644 --- a/spec/controllers/topics_controller_spec.rb +++ b/spec/controllers/topics_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' def topics_controller_show_gen_perm_tests(expected, ctx) expected.each do |sym, status| @@ -563,6 +563,11 @@ describe TopicsController do expect(response).to redirect_to(topic.relative_url + "/42?page=123") end + it 'does not accept page params as an array' do + xhr :get, :show, id: topic.slug, post_number: 42, page: [2] + expect(response).to redirect_to("#{topic.relative_url}/42?page=1") + end + it 'returns 404 when an invalid slug is given and no id' do xhr :get, :show, id: 'nope-nope' expect(response.status).to eq(404) @@ -573,6 +578,11 @@ describe TopicsController do expect(response.status).to eq(404) end + it 'returns a 404 for an ID that is larger than postgres limits' do + xhr :get, :show, topic_id: 50142173232201640412, slug: 'topic-that-is-made-up' + expect(response.status).to eq(404) + end + context 'a topic with nil slug exists' do before do @nil_slug_topic = Fabricate(:topic) @@ -939,7 +949,7 @@ describe TopicsController do describe 'when logged in as group manager' do let(:group_manager) { log_in } - let(:group) { Fabricate(:group).tap { |g| g.add(group_manager); g.appoint_manager(group_manager) } } + let(:group) { Fabricate(:group).tap { |g| g.add_owner(group_manager) } } let(:private_category) { Fabricate(:private_category, group: group) } let(:group_private_topic) { Fabricate(:topic, category: private_category, user: group_manager) } let(:recipient) { 'jake@adventuretime.ooo' } @@ -1024,6 +1034,46 @@ describe TopicsController do Topic.any_instance.expects(:set_auto_close).with(nil, anything) xhr :put, :autoclose, topic_id: @topic.id, auto_close_time: nil, auto_close_based_on_last_post: false, timezone_offset: -240 end + + it "will close a topic when the time expires" do + topic = Fabricate(:topic) + Timecop.freeze(20.hours.ago) do + create_post(topic: topic, raw: "This is the body of my cool post in the topic, but it's a bit old now") + end + topic.save + + Jobs.expects(:enqueue_at).at_least_once + xhr :put, :autoclose, topic_id: topic.id, auto_close_time: 24, auto_close_based_on_last_post: true + + topic.reload + expect(topic.closed).to eq(false) + expect(topic.posts.last.raw).to match(/cool post/) + + Timecop.freeze(5.hours.from_now) do + Jobs::CloseTopic.new.execute({topic_id: topic.id, user_id: @admin.id}) + end + + topic.reload + expect(topic.closed).to eq(true) + expect(topic.posts.last.raw).to match(/automatically closed/) + end + + it "will immediately close if the last post is old enough" do + topic = Fabricate(:topic) + Timecop.freeze(20.hours.ago) do + create_post(topic: topic) + end + topic.save + Topic.reset_highest(topic.id) + topic.reload + + xhr :put, :autoclose, topic_id: topic.id, auto_close_time: 10, auto_close_based_on_last_post: true + + topic.reload + expect(topic.closed).to eq(true) + expect(topic.posts.last.raw).to match(/after the last reply/) + expect(topic.posts.last.raw).to match(/10 hours/) + end end end @@ -1096,7 +1146,7 @@ describe TopicsController do it "delegates work to `TopicsBulkAction`" do topics_bulk_action = mock - TopicsBulkAction.expects(:new).with(user, topic_ids, operation).returns(topics_bulk_action) + TopicsBulkAction.expects(:new).with(user, topic_ids, operation, group: nil).returns(topics_bulk_action) topics_bulk_action.expects(:perform!) xhr :put, :bulk, topic_ids: topic_ids, operation: operation end diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb index b85c3cdc6f1..4a57897e771 100644 --- a/spec/controllers/uploads_controller_spec.rb +++ b/spec/controllers/uploads_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UploadsController do @@ -19,6 +19,13 @@ describe UploadsController do }) end + let(:fake_jpg) do + ActionDispatch::Http::UploadedFile.new({ + filename: 'fake.jpg', + tempfile: file_from_fixtures("fake.jpg") + }) + end + let(:text_file) do ActionDispatch::Http::UploadedFile.new({ filename: 'LICENSE.TXT', @@ -106,6 +113,32 @@ describe UploadsController do expect(message.data["errors"]).to be end + it 'ensures allow_uploaded_avatars is enabled when uploading an avatar' do + SiteSetting.stubs(:allow_uploaded_avatars).returns(false) + xhr :post, :create, file: logo, type: "avatar" + expect(response).to_not be_success + end + + it 'ensures sso_overrides_avatar is not enabled when uploading an avatar' do + SiteSetting.stubs(:sso_overrides_avatar).returns(true) + xhr :post, :create, file: logo, type: "avatar" + expect(response).to_not be_success + end + + it 'returns an error when it could not determine the dimensions of an image' do + Jobs.expects(:enqueue).with(:create_thumbnails, anything).never + + message = MessageBus.track_publish do + xhr :post, :create, file: fake_jpg, type: "composer" + end.first + + expect(response.status).to eq 200 + + expect(message.channel).to eq("/uploads/composer") + expect(message.data["errors"]).to be + expect(message.data["errors"][0]).to eq(I18n.t("upload.images.size_not_found")) + end + end end diff --git a/spec/controllers/user_actions_controller_spec.rb b/spec/controllers/user_actions_controller_spec.rb index 38be9207647..b1914dea233 100644 --- a/spec/controllers/user_actions_controller_spec.rb +++ b/spec/controllers/user_actions_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'post_enqueuer' describe UserActionsController do diff --git a/spec/controllers/user_avatars_controller_spec.rb b/spec/controllers/user_avatars_controller_spec.rb index 19b4696342c..92630ddb877 100644 --- a/spec/controllers/user_avatars_controller_spec.rb +++ b/spec/controllers/user_avatars_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserAvatarsController do @@ -11,6 +11,8 @@ describe UserAvatarsController do SiteSetting.s3_upload_bucket = "test" SiteSetting.s3_cdn_url = "http://cdn.com" + FakeWeb.register_uri(:get, "http://cdn.com/something/else", :body => 'image') + GlobalSetting.expects(:cdn_url).returns("http://awesome.com/boom") @@ -30,7 +32,7 @@ describe UserAvatarsController do expect(response).to redirect_to("http://awesome.com/boom/user_avatar/default/#{user.username_lower}/98/#{upload.id}_#{OptimizedImage::VERSION}.png") get :show, size: 98, username: user.username, version: upload.id, hostname: 'default' - expect(response).to redirect_to("http://cdn.com/something/else") + expect(response.body).to eq("image") end it 'serves image even if size missing and its in local mode' do diff --git a/spec/controllers/user_badges_controller_spec.rb b/spec/controllers/user_badges_controller_spec.rb index f191ef4f35d..0046f614049 100644 --- a/spec/controllers/user_badges_controller_spec.rb +++ b/spec/controllers/user_badges_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserBadgesController do let(:user) { Fabricate(:user) } @@ -12,9 +12,11 @@ describe UserBadgesController do xhr :get, :index, badge_id: badge.id expect(response.status).to eq(200) + parsed = JSON.parse(response.body) expect(parsed["topics"]).to eq(nil) - expect(parsed["user_badges"][0]["post_id"]).to eq(nil) + expect(parsed["badges"].length).to eq(1) + expect(parsed["user_badge_info"]["user_badges"][0]["post_id"]).to eq(nil) end end @@ -38,7 +40,7 @@ describe UserBadgesController do expect(response.status).to eq(200) parsed = JSON.parse(response.body) - expect(parsed["user_badges"].length).to eq(1) + expect(parsed["user_badge_info"]["user_badges"].length).to eq(1) end it 'includes counts when passed the aggregate argument' do diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index fb258ec0937..ff0e0d58c4e 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -1,49 +1,95 @@ -require 'spec_helper' +require 'rails_helper' describe UsersController do describe '.show' do - let!(:user) { log_in } - it 'returns success' do - xhr :get, :show, username: user.username, format: :json - expect(response).to be_success - json = JSON.parse(response.body) + context "anon" do - expect(json["user"]["has_title_badges"]).to eq(false) + let(:user) { Discourse.system_user } - end - - it "returns not found when the username doesn't exist" do - xhr :get, :show, username: 'madeuppity' - expect(response).not_to be_success - end - - it 'returns not found when the user is inactive' do - inactive = Fabricate(:user, active: false) - xhr :get, :show, username: inactive.username - expect(response).not_to be_success - end - - it "raises an error on invalid access" do - Guardian.any_instance.expects(:can_see?).with(user).returns(false) - xhr :get, :show, username: user.username - expect(response).to be_forbidden - end - - context "fetching a user by external_id" do - before { user.create_single_sign_on_record(external_id: '997', last_payload: '') } - - it "returns fetch for a matching external_id" do - xhr :get, :show, external_id: '997' + it "returns success" do + xhr :get, :show, username: user.username, format: :json expect(response).to be_success end - it "returns not found when external_id doesn't match" do - xhr :get, :show, external_id: '99' + it "raises an error for anon when profiles are hidden" do + SiteSetting.stubs(:hide_user_profiles_from_public).returns(true) + xhr :get, :show, username: user.username, format: :json expect(response).not_to be_success end + end + + context "logged in" do + + let(:user) { log_in } + + it 'returns success' do + xhr :get, :show, username: user.username, format: :json + expect(response).to be_success + json = JSON.parse(response.body) + + expect(json["user"]["has_title_badges"]).to eq(false) + end + + it "returns not found when the username doesn't exist" do + xhr :get, :show, username: 'madeuppity' + expect(response).not_to be_success + end + + it 'returns not found when the user is inactive' do + inactive = Fabricate(:user, active: false) + xhr :get, :show, username: inactive.username + expect(response).not_to be_success + end + + it "raises an error on invalid access" do + Guardian.any_instance.expects(:can_see?).with(user).returns(false) + xhr :get, :show, username: user.username + expect(response).to be_forbidden + end + + describe "user profile views" do + let(:other_user) { Fabricate(:user) } + + it "should track a user profile view for a signed in user" do + UserProfileView.expects(:add).with(other_user.user_profile.id, request.remote_ip, user.id) + xhr :get, :show, username: other_user.username + end + + it "should not track a user profile view for a user viewing his own profile" do + UserProfileView.expects(:add).never + xhr :get, :show, username: user.username + end + + it "should track a user profile view for an anon user" do + UserProfileView.expects(:add).with(other_user.user_profile.id, request.remote_ip, nil) + xhr :get, :show, username: other_user.username + end + + it "skips tracking" do + UserProfileView.expects(:add).never + xhr :get, :show, { username: user.username, skip_track_visit: true } + end + end + + context "fetching a user by external_id" do + before { user.create_single_sign_on_record(external_id: '997', last_payload: '') } + + it "returns fetch for a matching external_id" do + xhr :get, :show, external_id: '997' + expect(response).to be_success + end + + it "returns not found when external_id doesn't match" do + xhr :get, :show, external_id: '99' + expect(response).not_to be_success + end + end + + end + end describe '.user_preferences_redirect' do @@ -58,26 +104,6 @@ describe UsersController do end end - describe '.authorize_email' do - it 'errors out for invalid tokens' do - get :authorize_email, token: 'asdfasdf' - expect(response).to be_success - expect(flash[:error]).to be_present - end - - context 'valid token' do - it 'authorizes with a correct token' do - user = Fabricate(:user) - email_token = user.email_tokens.create(email: user.email) - - get :authorize_email, token: email_token.token - expect(response).to be_success - expect(flash[:error]).to be_blank - expect(session[:current_user_id]).to be_present - end - end - end - describe '.activate_account' do before do UsersController.any_instance.stubs(:honeypot_or_challenge_fails?).returns(false) @@ -173,60 +199,6 @@ describe UsersController do end end - describe '.change_email' do - let(:new_email) { 'bubblegum@adventuretime.ooo' } - - it "requires you to be logged in" do - expect { xhr :put, :change_email, username: 'asdf', email: new_email }.to raise_error(Discourse::NotLoggedIn) - end - - context 'when logged in' do - let!(:user) { log_in } - - it 'raises an error without an email parameter' do - expect { xhr :put, :change_email, username: user.username }.to raise_error(ActionController::ParameterMissing) - end - - it "raises an error if you can't edit the user's email" do - Guardian.any_instance.expects(:can_edit_email?).with(user).returns(false) - xhr :put, :change_email, username: user.username, email: new_email - expect(response).to be_forbidden - end - - context 'when the new email address is taken' do - let!(:other_user) { Fabricate(:coding_horror) } - it 'raises an error' do - expect { xhr :put, :change_email, username: user.username, email: other_user.email }.to raise_error(Discourse::InvalidParameters) - end - - it 'raises an error if there is whitespace too' do - expect { xhr :put, :change_email, username: user.username, email: other_user.email + ' ' }.to raise_error(Discourse::InvalidParameters) - end - end - - context 'when new email is different case of existing email' do - let!(:other_user) { Fabricate(:user, email: 'case.insensitive@gmail.com')} - - it 'raises an error' do - expect { xhr :put, :change_email, username: user.username, email: other_user.email.upcase }.to raise_error(Discourse::InvalidParameters) - end - end - - context 'success' do - - it 'has an email token' do - expect { xhr :put, :change_email, username: user.username, email: new_email }.to change(EmailToken, :count) - end - - it 'enqueues an email authorization' do - Jobs.expects(:enqueue).with(:user_email, has_entries(type: :authorize_email, user_id: user.id, to_address: new_email)) - xhr :put, :change_email, username: user.username, email: new_email - end - end - end - - end - describe '.password_reset' do let(:user) { Fabricate(:user) } @@ -272,7 +244,7 @@ describe UsersController do old_token = user.auth_token get :password_reset, token: token - put :password_reset, token: token, password: 'newpassword' + put :password_reset, token: token, password: 'hg9ow8yhg98o' expect(response).to be_success expect(assigns[:error]).to be_blank @@ -280,6 +252,16 @@ describe UsersController do expect(user.auth_token).to_not eq old_token expect(user.auth_token.length).to eq 32 end + + it "doesn't invalidate the token when loading the page" do + user = Fabricate(:user, auth_token: SecureRandom.hex(16)) + email_token = user.email_tokens.create(email: user.email) + + get :password_reset, token: email_token.token + + email_token.reload + expect(email_token.confirmed).to eq(false) + end end context 'submit change' do @@ -301,20 +283,38 @@ describe UsersController do end it "logs in the user" do - put :password_reset, token: token, password: 'newpassword' + put :password_reset, token: token, password: 'ksjafh928r' expect(assigns(:user).errors).to be_blank expect(session[:current_user_id]).to be_present end it "doesn't log in the user when not approved" do SiteSetting.expects(:must_approve_users?).returns(true) - put :password_reset, token: token, password: 'newpassword' + put :password_reset, token: token, password: 'ksjafh928r' expect(assigns(:user).errors).to be_blank expect(session[:current_user_id]).to be_blank end end end + describe '.confirm_email_token' do + let(:user) { Fabricate(:user) } + + it "token doesn't match any records" do + email_token = user.email_tokens.create(email: user.email) + get :confirm_email_token, token: SecureRandom.hex, format: :json + expect(response).to be_success + expect(email_token.reload.confirmed).to eq(false) + end + + it "token matches" do + email_token = user.email_tokens.create(email: user.email) + get :confirm_email_token, token: email_token.token, format: :json + expect(response).to be_success + expect(email_token.reload.confirmed).to eq(true) + end + end + describe '.admin_login' do let(:admin) { Fabricate(:admin) } let(:user) { Fabricate(:user) } @@ -390,6 +390,15 @@ describe UsersController do email: @user.email end + context 'when creating a user' do + it 'sets the user locale to I18n.locale' do + SiteSetting.stubs(:default_locale).returns('en') + I18n.stubs(:locale).returns(:fr) + post_user + expect(User.find_by(username: @user.username).locale).to eq('fr') + end + end + context 'when creating a non active user (unconfirmed email)' do it 'returns a 500 when local logins are disabled' do @@ -634,7 +643,7 @@ describe UsersController do context "with values for the fields" do let(:create_params) { { name: @user.name, - password: 'watwatwat', + password: 'watwatwatwat', username: @user.username, email: @user.email, user_fields: { @@ -684,7 +693,7 @@ describe UsersController do context "without values for the fields" do let(:create_params) { { name: @user.name, - password: 'watwatwat', + password: 'watwatwatwat', username: @user.username, email: @user.email, } } @@ -700,6 +709,17 @@ describe UsersController do end end + context "when taking over a staged account" do + let!(:staged) { Fabricate(:staged, email: "staged@account.com") } + + it "succeeds" do + xhr :post, :create, email: staged.email, username: "zogstrip", password: "P4ssw0rd$$" + result = ::JSON.parse(response.body) + expect(result["success"]).to eq(true) + expect(User.find_by(email: staged.email).staged).to eq(false) + end + end + end context '.username' do @@ -1081,6 +1101,19 @@ describe UsersController do end + context 'a locale is chosen that differs from I18n.locale' do + it "updates the user's locale" do + I18n.stubs(:locale).returns('fr') + + put :update, + username: user.username, + locale: :fa_IR + + expect(User.find_by(username: user.username).locale).to eq('fa_IR') + end + + end + context "with user fields" do context "an editable field" do let!(:user_field) { Fabricate(:user_field) } @@ -1129,9 +1162,7 @@ describe UsersController do it 'does not allow the update' do user = Fabricate(:user, name: 'Billy Bob') log_in_user(user) - guardian = Guardian.new(user) - guardian.stubs(:ensure_can_edit!).with(user).raises(Discourse::InvalidAccess.new) - Guardian.stubs(new: guardian).with(user) + Guardian.any_instance.expects(:can_edit?).with(user).returns(false) put :update, username: user.username, name: 'Jim Tom' @@ -1317,6 +1348,18 @@ describe UsersController do expect(response).to be_forbidden end + it "raises an error when sso_overrides_avatar is disabled" do + SiteSetting.stubs(:sso_overrides_avatar).returns(true) + xhr :put, :pick_avatar, username: user.username, upload_id: upload.id, type: "custom" + expect(response).to_not be_success + end + + it "raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is disabled" do + SiteSetting.stubs(:allow_uploaded_avatars).returns(false) + xhr :put, :pick_avatar, username: user.username, upload_id: upload.id, type: "custom" + expect(response).to_not be_success + end + it 'can successfully pick the system avatar' do xhr :put, :pick_avatar, username: user.username expect(response).to be_success @@ -1406,10 +1449,10 @@ describe UsersController do describe '.my_redirect' do - it "returns 404 if the user is not logged in" do + it "redirects if the user is not logged in" do get :my_redirect, path: "wat" expect(response).not_to be_success - expect(response).not_to be_redirect + expect(response).to be_redirect end context "when the user is logged in" do @@ -1470,4 +1513,47 @@ describe UsersController do end + describe ".is_local_username" do + + let(:user) { Fabricate(:user) } + + it "finds the user" do + xhr :get, :is_local_username, username: user.username + expect(response).to be_success + json = JSON.parse(response.body) + expect(json["valid"][0]).to eq(user.username) + end + + it "supports multiples usernames" do + xhr :get, :is_local_username, usernames: [user.username, "system"] + expect(response).to be_success + json = JSON.parse(response.body) + expect(json["valid"].size).to eq(2) + end + + it "never includes staged accounts" do + staged = Fabricate(:user, staged: true) + xhr :get, :is_local_username, usernames: [staged.username] + expect(response).to be_success + json = JSON.parse(response.body) + expect(json["valid"].size).to eq(0) + end + + end + + context '#summary' do + + it "generates summary info" do + user = Fabricate(:user) + create_post(user: user) + + xhr :get, :summary, username: user.username_lower + expect(response).to be_success + json = JSON.parse(response.body) + + expect(json["user_summary"]["topic_count"]).to eq(1) + expect(json["user_summary"]["post_count"]).to eq(1) + end + end + end diff --git a/spec/controllers/users_email_controller_spec.rb b/spec/controllers/users_email_controller_spec.rb new file mode 100644 index 00000000000..0a2bfe99ce3 --- /dev/null +++ b/spec/controllers/users_email_controller_spec.rb @@ -0,0 +1,106 @@ +require 'rails_helper' + +describe UsersEmailController do + + describe '.confirm' do + it 'errors out for invalid tokens' do + get :confirm, token: 'asdfasdf' + expect(response).to be_success + expect(assigns(:update_result)).to eq(:error) + end + + context 'valid old address token' do + let(:user) { Fabricate(:moderator) } + let(:updater) { EmailUpdater.new(user.guardian, user) } + + before do + updater.change_to('new.n.cool@example.com') + end + + it 'confirms with a correct token' do + get :confirm, token: user.email_tokens.last.token + expect(response).to be_success + expect(assigns(:update_result)).to eq(:authorizing_new) + end + end + + context 'valid new address token' do + let(:user) { Fabricate(:user) } + let(:updater) { EmailUpdater.new(user.guardian, user) } + + before do + updater.change_to('new.n.cool@example.com') + end + + it 'confirms with a correct token' do + get :confirm, token: user.email_tokens.last.token + expect(response).to be_success + expect(assigns(:update_result)).to eq(:complete) + end + end + end + + describe '.update' do + let(:new_email) { 'bubblegum@adventuretime.ooo' } + + it "requires you to be logged in" do + expect { xhr :put, :update, username: 'asdf', email: new_email }.to raise_error(Discourse::NotLoggedIn) + end + + context 'when logged in' do + let!(:user) { log_in } + + it 'raises an error without an email parameter' do + expect { xhr :put, :update, username: user.username }.to raise_error(ActionController::ParameterMissing) + end + + it "raises an error if you can't edit the user's email" do + Guardian.any_instance.expects(:can_edit_email?).with(user).returns(false) + xhr :put, :update, username: user.username, email: new_email + expect(response).to be_forbidden + end + + context 'when the new email address is taken' do + let!(:other_user) { Fabricate(:coding_horror) } + it 'raises an error' do + xhr :put, :update, username: user.username, email: other_user.email + expect(response).to_not be_success + end + + it 'raises an error if there is whitespace too' do + xhr :put, :update, username: user.username, email: other_user.email + ' ' + expect(response).to_not be_success + end + end + + context 'when new email is different case of existing email' do + let!(:other_user) { Fabricate(:user, email: 'case.insensitive@gmail.com')} + + it 'raises an error' do + xhr :put, :update, username: user.username, email: other_user.email.upcase + expect(response).to_not be_success + end + end + + it 'raises an error when new email domain is present in email_domains_blacklist site setting' do + SiteSetting.email_domains_blacklist = "mailinator.com" + xhr :put, :update, username: user.username, email: "not_good@mailinator.com" + expect(response).to_not be_success + end + + it 'raises an error when new email domain is not present in email_domains_whitelist site setting' do + SiteSetting.email_domains_whitelist = "discourse.org" + xhr :put, :update, username: user.username, email: new_email + expect(response).to_not be_success + end + + context 'success' do + it 'has an email token' do + expect { xhr :put, :update, username: user.username, email: new_email }.to change(EmailChangeRequest, :count) + end + end + end + + end + +end diff --git a/spec/fabricators/category_group_fabricator.rb b/spec/fabricators/category_group_fabricator.rb new file mode 100644 index 00000000000..898825b80ea --- /dev/null +++ b/spec/fabricators/category_group_fabricator.rb @@ -0,0 +1,5 @@ +Fabricator(:category_group) do + category + group + permission_type 1 +end diff --git a/spec/fabricators/post_fabricator.rb b/spec/fabricators/post_fabricator.rb index 317238a611e..43c479fabf4 100644 --- a/spec/fabricators/post_fabricator.rb +++ b/spec/fabricators/post_fabricator.rb @@ -12,6 +12,7 @@ Fabricator(:post_with_long_raw_content, from: :post) do end Fabricator(:post_with_youtube, from: :post) do + raw 'http://www.youtube.com/watch?v=9bZkp7q19f0' cooked '

        http://www.youtube.com/watch?v=9bZkp7q19f0

        ' end @@ -48,53 +49,54 @@ Fabricator(:post_with_plenty_of_images, from: :post) do
        -

        With an emoji! smile

        +

        With an emoji! smile

        ' end Fabricator(:post_with_uploaded_image, from: :post) do - cooked '' + raw '' end Fabricator(:post_with_an_attachment, from: :post) do - cooked 'archive.zip' + raw 'archive.zip' end Fabricator(:post_with_unsized_images, from: :post) do - cooked ' + raw ' ' end Fabricator(:post_with_image_urls, from: :post) do - cooked ' + raw ' ' end Fabricator(:post_with_large_image, from: :post) do - cooked '' + raw '' end Fabricator(:post_with_large_image_and_title, from: :post) do - cooked '' + raw '' end Fabricator(:post_with_uploads, from: :post) do - cooked ' + raw ' Link ' end Fabricator(:post_with_uploads_and_links, from: :post) do - cooked ' + raw ' Link Google +text.txt (20 Bytes) ' end diff --git a/spec/fabricators/site_text_fabricator.rb b/spec/fabricators/site_text_fabricator.rb deleted file mode 100644 index 34023da8f63..00000000000 --- a/spec/fabricators/site_text_fabricator.rb +++ /dev/null @@ -1,14 +0,0 @@ -Fabricator(:site_text) do - text_type "great.poem" - value "%{flower} are red. %{food} are blue." -end - -Fabricator(:site_text_basic, from: :site_text) do - text_type "breaking.bad" - value "best show ever" -end - -Fabricator(:site_text_site_setting, from: :site_text) do - text_type "site.replacement" - value "%{title} is evil." -end diff --git a/spec/fabricators/user_fabricator.rb b/spec/fabricators/user_fabricator.rb index 13e0ce61c6c..5cad8011f9f 100644 --- a/spec/fabricators/user_fabricator.rb +++ b/spec/fabricators/user_fabricator.rb @@ -99,3 +99,7 @@ Fabricator(:anonymous, from: :user) do user.save! end end + +Fabricator(:staged, from: :user) do + staged true +end diff --git a/spec/fabricators/user_option_fabricator.rb b/spec/fabricators/user_option_fabricator.rb new file mode 100644 index 00000000000..f42ddaec9c0 --- /dev/null +++ b/spec/fabricators/user_option_fabricator.rb @@ -0,0 +1,2 @@ +Fabricator(:user_option) do +end diff --git a/spec/fixtures/emails/android_gmail.eml b/spec/fixtures/emails/android_gmail.eml deleted file mode 100644 index 21c5dde2346..00000000000 --- a/spec/fixtures/emails/android_gmail.eml +++ /dev/null @@ -1,177 +0,0 @@ -Delivered-To: reply@discourse.org -Return-Path: -MIME-Version: 1.0 -In-Reply-To: -References: - -Date: Fri, 28 Nov 2014 12:53:21 -0800 -Subject: Re: [Discourse Meta] [Lounge] Testing default email replies -From: Walter White -To: Discourse Meta -Content-Type: multipart/alternative; boundary=089e0149cfa485c6630508f173df - ---089e0149cfa485c6630508f173df -Content-Type: text/plain; charset=UTF-8 - -### this is a reply from Android 5 gmail - -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over -the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown -fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. -The quick brown fox jumps over the lazy dog. - -This is **bold** in Markdown. - -This is a link to http://example.com -On Nov 28, 2014 12:36 PM, "Arpit Jalan" wrote: - -> techAPJ -> November 28 -> -> Test reply. -> -> First paragraph. -> -> Second paragraph. -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in -> your browser. -> ------------------------------ -> Previous Replies codinghorror -> -> November 28 -> -> We're testing the latest GitHub email processing library which we are -> integrating now. -> -> https://github.com/github/email_reply_parser -> -> Go ahead and reply to this topic and I'll reply from various email clients -> for testing. -> ------------------------------ -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in -> your browser. -> -> To unsubscribe from these emails, visit your user preferences -> . -> - ---089e0149cfa485c6630508f173df -Content-Type: text/html; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable - -

        ### this is a reply from Android 5 gmail

        -

        The quick brown fox jumps over the lazy dog. The quick brown= - fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. = -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over= - the lazy dog. The quick brown fox jumps over the lazy dog.

        -

        This is **bold** in Markdown.

        -

        This is a link to http://exam= -ple.com

        -
        On Nov 28, 2014 12:36 PM, "Arpit Jalan"= -; <info@discourse.org> wrot= -e:
        - - - - - - - - - - - -
        - - - techAPJ
        - November 28 -
        -

        Test reply.

        - -

        First paragraph.

        - -

        Second paragraph.

        -
        - - -
        -

        To respond, reply to this email or visit https:/= -/meta.discourse.org/t/testing-default-email-replies/22638/3 in your bro= -wser.

        -
        -
        -

        Previous Replies

        - - - - - - - - - - - -
        - - - codinghorror - November 28 -
        -

        We're testing the latest GitHub emai= -l processing library which we are integrating now.

        - -

        https://github.com/github/email_reply_parser

        - -

        Go ahead and reply to this topic and I&#= -39;ll reply from various email clients for testing.

        -
        - - -
        - -
        -

        To respond, reply to this email or visit https://met= -a.discourse.org/t/testing-default-email-replies/22638/3 in your browser= -.

        -
        -
        -

        To unsubscribe from these emails, visit your user preferences.

        -
        -
        -
        - ---089e0149cfa485c6630508f173df-- diff --git a/spec/fixtures/emails/attached_rb_file.eml b/spec/fixtures/emails/attached_rb_file.eml new file mode 100644 index 00000000000..960b3e6d676 --- /dev/null +++ b/spec/fixtures/emails/attached_rb_file.eml @@ -0,0 +1,31 @@ +Return-Path: +From: Foo Bar +To: team@bar.com +Date: Mon, 29 Feb 2016 21:54:01 +0100 +Message-ID: <56d4afe991ed0_3ab83fdf94441a20677f0@HAL.lan.mail> +Subject: Email with .rb file attached +Mime-Version: 1.0 +Content-Type: multipart/mixed; + boundary="--==_mimepart_56d4afe991d17_3ab83fdf94441a206765"; + charset=UTF-8 +Content-Transfer-Encoding: 7bit + + +----==_mimepart_56d4afe991d17_3ab83fdf94441a206765 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 7bit + +Please find the source code of Discourse attached. +----==_mimepart_56d4afe991d17_3ab83fdf94441a206765 +Content-Type: application/x-ruby; + charset=UTF-8; + filename=discourse.rb +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename=discourse.rb +Content-ID: <56d4afe992cb6_3ab83fdf94441a20678c3@HAL.lan.mail> + +cHV0cyAiSGVsbG8gRGlzY291cnNlIgo= + +----==_mimepart_56d4afe991d17_3ab83fdf94441a206765-- diff --git a/spec/fixtures/emails/attached_txt_file.eml b/spec/fixtures/emails/attached_txt_file.eml new file mode 100644 index 00000000000..a568baab628 --- /dev/null +++ b/spec/fixtures/emails/attached_txt_file.eml @@ -0,0 +1,30 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Sat, 30 Jan 2016 01:10:11 +0100 +Message-ID: <38@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: multipart/mixed; + boundary="--==_mimepart_56abff5d49749_ddf83fca6d033a28548ad"; + charset=UTF-8 +Content-Transfer-Encoding: 7bit + + +----==_mimepart_56abff5d49749_ddf83fca6d033a28548ad +Content-Type: text/plain; + charset=UTF-8; + filename=text.txt +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; + filename=text.txt +Content-ID: <56abff637aac_ddf83fca6d033a2855099@HAL.lan.mail> + +This is a txt file. + +----==_mimepart_56abff5d49749_ddf83fca6d033a28548ad +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 7bit + +Please find some text file attached. +----==_mimepart_56abff5d49749_ddf83fca6d033a28548ad-- diff --git a/spec/fixtures/emails/attachment.eml b/spec/fixtures/emails/attachment.eml deleted file mode 100644 index f25c3d1a449..00000000000 --- a/spec/fixtures/emails/attachment.eml +++ /dev/null @@ -1,351 +0,0 @@ -Message-ID: <51C22E52.1030509@darthvader.ca> -Date: Wed, 19 Jun 2013 18:18:58 -0400 -From: Anakin Skywalker -User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130510 Thunderbird/17.0.6 -MIME-Version: 1.0 -To: Han Solo via Death Star -Subject: Re: [Death Star] [PM] re: Regarding your post in "Site Customization - not working" -References: <51d23d33f41fb_5f4e4b35d7d60798@xwing.mail> -In-Reply-To: <51d23d33f41fb_5f4e4b35d7d60798@xwing.mail> -Content-Type: multipart/mixed; boundary=047d7b45041e19c68004eb9f3de8 - ---047d7b45041e19c68004eb9f3de8 -Content-Type: multipart/alternative; boundary=047d7b45041e19c67b04eb9f3de6 - ---047d7b45041e19c67b04eb9f3de6 -Content-Type: text/plain; charset=ISO-8859-1 - -here is an image attachment - - -On Tue, Nov 19, 2013 at 5:11 PM, Neil wrote: - -> Neil -> November 19 -> -> Actually, deleting a spammer does what it's supposed to. It does mark the -> topic as deleted. -> -> That topic has id 11002, and you're right that the user was deleted. -> -> @eviltrout Any idea why it showed up in -> suggested topics? -> -> To respond, reply to this email or visit -> http://meta.discourse.org/t/spam-post-pops-back-up-in-suggested-topics/11005/5in your browser. -> ------------------------------ -> Previous Replies Neil -> November 19 -> -> Looks like a bug when deleting a spammer. I'll look at it. -> riking -> November 19 -> -> codinghorror: -> -> I can't even find that topic by name. -> -> In that case, I'm fairly certain someone used the 'Delete Spammer' -> function on the user, which would explain your inability to find it - it's -> gone. -> -> I'm raising this because, well, it's gone and shouldn't be showing up. And -> even if it was hanging around, it should be invisible to me, and not -> showing up in Suggested Topics. -> codinghorror -> November 19 -> -> Hmm, that's interesting -- can you have a look @eviltrout? -> I can't even find that topic by name. -> riking -> November 19 -> -> I'm one of the users who flagged this particular spam post, and it was -> promptly deleted/hidden, but it just popped up in the Suggested Topics box: -> -> Pasted image1125x220 27.7 KB -> -> -> We may want to recheck the suppression on these. -> ------------------------------ -> -> To respond, reply to this email or visit -> http://meta.discourse.org/t/spam-post-pops-back-up-in-suggested-topics/11005/5in your browser. -> -> To unsubscribe from these emails, visit your user preferences -> . -> - ---047d7b45041e19c67b04eb9f3de6 -Content-Type: text/html; charset=ISO-8859-1 -Content-Transfer-Encoding: quoted-printable - -
        here is an image attachment


        On Tue, Nov 19, 2013 at 5:11 PM, Neil = -<info@discourse.org> wrote:
        -
        - - - - - - - - -
        - - - Neil<= -/a>
        -No= -vember 19 -
        -

        Actually, deleting a spammer does what it's s= -upposed to. It does mark the topic as deleted.

        - -

        That topic has id 11002, and you're right tha= -t the user was deleted.

        - -

        @eviltrout Any idea why it showed up in suggested topics?

        -
        -
        -

        To respond, reply to this email or visit http://meta.discourse.org/t/spam-post-pops-back= --up-in-suggested-topics/11005/5 in your browser.

        - -
        -
        -

        Previous Replies

        - - - - - - - - - -
        - - - Neil<= -/a>
        -No= -vember 19 -

        Looks= - like a bug when deleting a spammer. I'll look at it.

        - - - - - - - - -
        - - - rik= -ing
        -No= -vember 19 -
        -

        -
        -codinghorror:
        -

        I can't even find that topic by n= -ame.

        - -

        In that case, I'm fairly certain someone used= - the 'Delete Spammer' function on the user, which would explain you= -r inability to find it - it's gone.

        - -

        I'm raising this because, well, it's gone= - and shouldn't be showing up. And even if it was hanging around, it sho= -uld be invisible to me, and not showing up in Suggested Topics.

        -
        - - - - - - - - -
        - - - codinghorror
        -No= -vember 19 -

        Hmm, = -that's interesting -- can you have a look @eviltrout? I can't even find that topic by= - name.

        -
        - - - - - - - - -
        - - - rik= -ing
        -No= -vember 19 -
        -

        I'm one of the users who flagged this particu= -lar spam post, and it was promptly deleted/hidden, but it just popped up in= - the Suggested Topics box:

        - -

        - - -

        We may want to recheck the suppression on these.<= -/p> -

        -
        -
        -

        To respond, reply to this email or visit http://meta.discourse.org/t/spam-post-pops-back-up-= -in-suggested-topics/11005/5 in your browser.

        - -
        -
        -

        To unsubscribe from these emails, visit your user pre= -ferences.

        -
        -

        - ---047d7b45041e19c67b04eb9f3de6-- ---047d7b45041e19c68004eb9f3de8 -Content-Type: image/png; name="bricks.png" -Content-Disposition: attachment; filename="bricks.png" -Content-Transfer-Encoding: base64 -X-Attachment-Id: f_ho8uteve0 - -iVBORw0KGgoAAAANSUhEUgAAASEAAAB+CAIAAADk0DDaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ -bWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdp -bj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6 -eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEz -NDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJo -dHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlw -dGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAv -IiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RS -ZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpD -cmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNl -SUQ9InhtcC5paWQ6MDYxQjcyOUUzMDM1MTFFM0JFRTFBOTQ1RUY4QUU4MDIiIHhtcE1NOkRvY3Vt -ZW50SUQ9InhtcC5kaWQ6MDYxQjcyOUYzMDM1MTFFM0JFRTFBOTQ1RUY4QUU4MDIiPiA8eG1wTU06 -RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowNjFCNzI5QzMwMzUxMUUzQkVF -MUE5NDVFRjhBRTgwMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowNjFCNzI5RDMwMzUxMUUz -QkVFMUE5NDVFRjhBRTgwMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1w -bWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pm2fyz0AAAyISURBVHja7F2/i11FFL6rL12aBdlGRDCF -EQmEbVJtChfSJJDGRkgZBBsVUhgQ7NSkCKiFVUr/AUGbhW1MlWaJBAkWVsFmG0HshMT7duJk9szc -uefOjzPn3vd9xfL2/bh35rtnznfOuXNnth7c/6ID2Lh261vO13669wm4SsZ7H3396gmePXu2OkH/ -Yr4Mv4IrCgAYY8Am4vnz51sn8EVsXth68P7eYq7Kj4cP3H+v79fq2tWDX/u/d25/7n/08/3PzIvb -u3vLs3sxhh/vXrOvb9/50v1o77W/X340B5IXMsbsta931eN24I6uRQ4wd3SJkUwYnqkLQ6wIAHWx -gn/Nx3ff3Ov/njvbWFcXFibESdZw3aFjAKBDx46Ofk/42e7u2/3f4G8jH5XF07+O7es3tnfSThps -beRNA/PRmd1rxrlGkMNDf8a2DLskJzOcRrJ5/7czb/Z/fzk8qESyjBlDxwBAZT4WGd/1/CtxLcaz -ZiLYWvOmezpXxMQwxKQYwzIkK2S4LMnQMQCorGMm4C7irhp6nUzPHfSs7un6176jffT4cULSuGkM -+1mWq5b2jDlqRpJGdWNsFqNLxqrstfejxEzjA8l+LBpkm+DihQucmodyhhErAoCOmkcvx4t3xsG4 -RaZEbgOeZZNMwu9u+P7EkkiGjgGADh2LDH21Ehd0Wvz82E/VqiLOsE6JizM8iWSZ2n0TM4aOAYAO -HUvzDW0RbNhoa8ld0Ui2cPHCBU7JCwz7DDPzMc7dEf0krzqAESsCIBmxIgAsN1YUSKMlU/9N8KxD -+b02hvn3oDWbMXQMADZMxyIOtUnqn1lTVluuWAzD+kmGjgGAeh2rcfMu7YDCd8PFKss10qRkhiV1 -Q7J2X8+Mpe+PuRcpOCEgp59lOWry1GCRfgVJdg+STFRxK4yTLFnzSCCZacaIFQGgcqworP5FvKlM -YFBwvuIGkszscny+Ij9WlJ/SyY+8oGMAUFnHZIa+tpnjRVrCn68o0PFFMqztdGkkQ8cAQCQfI87A -X0lGlZtJW4gmx9Mnr5lDGuyenawko82RJ5OczLCflfHriprNGDoGAOL5WD/63QX7tU1USV7oq2FH -yKmNf7Ukq2V4RiRrNuOVf+3LLsSrYXTlI7l2TwLUSgvxahhdNRhmRuMkQNVmxogVAUBEx9yh7zoz -STc2quwFHVKTdX7sc/WtGB4NUMsynH/AqXOpdJoxdAwAKuuYGwc3SXj0TL2NIFi7n+pfWyU8c2E4 -p6mazRg6BgAi+ZgbRIpF2yRDKIhRuRhdMJTTu8v7VyY9dpFAcr4nJhlCDZKTGS4uNTrNOLBXLeeU -beuhVefm8Q8bma/4ZLt756+XRyMkM0+xVJL5x4zU7nuGe1iSNZsxYkUAqBwrBoXbf1Os2F3E/cg0 -NeJle//qPyRLGkZiLcmJ83MhOVK7d8OEIZKDZizTcjwHDQCCOubGtfHbdpNSVc6+UuYL1/f33JRx -RttwRfKxvv2mI4Ze63pHb4zySWZuj9Z/gTDczWc3uUik4OqSJZljxt2UslYRM4aOAUBlHTNDPxJN -EmEx/wbfPBUcHy2fu4iXPeiOu22aPAyR7Eu3JTl4ITaH4QjWDPfYZjHc1oxXoxHL0DtumyIJJWl3 -8CHF0QZkJqxFbsj4ExE4aw0Er32wj3GG48Unsg4Zh2T/dHb05iy9mBnnE5KZ8xWHSK5nxt3Ak6DB -IyNWBADBmkca+P6YfPr08JS8vFD/kGc69au8+dTJP89xz5kkT2J4iGTTfkuy35jgNZJkOIdkYTM+ -RdeYGUPHAKCyjpV1BqXwZHs8nxGG8VsHR+u/r1+6sX7rdM3jj3/WPvjc2eNgR9QyrJPkqzfvBqtK -PcmEYf0kQ8cAoC62rr4FEibAKJipd333zb2hr/m+FphKskWwrjgjhrfO7+zgonLw8ae3bPRirrp5 -Jz7YgEm4vH/F/df4srmTjFgRAKBjOkQsqGAG7kdAvoL18jU0h2aOJEPHAKCyjn34wY2hz9xomIC4 -GfPNtJ1FyW8jJ423Ie7/cnpnvmzyAZIw1OtdPsnkXO4P7Uf1Llm9CxE5sqtywdSulJlN6iB0DAAq -69j3X92ND8rgqHXdwNBvR4e7+4W4L0xug+/5gv5s9Mi9g/QVLO5TM3vHVJtI++OdCrJX8JKNXohS -ZjYaZYiZ2dChoGMAUFnHvn1LS13xzM1bHH/z7kOU79Lx26XxLOXf+7jdl8uwa8Ar5sqsZPk482R1 -WRyZS3vSxKAo//nwh/Xfrru9u7e8a+Mv0FeD5O7EQ5GRZvHz/c/s600guR7Dj1DzAIDGsaIrbmlb -0dnFRsh+oaOyaX5lHa3RXNe/Xul2hprK34+UNM9/TY5vWz70acdexMZvedpWdP6pO/aq8f3X/Mjc -kkwY7pK21Q0yk8Yh+UICwzkkB814lGTXjKFjANBOx0aH/qjX4bwZdADGy3b/zwR1J1nb54KC25O6 -p+AIy1TxKQjOhmCZDEdIdlMyc+vWkuw+eRXcZdeehcleK5KVmDF0DABa6FiRhZzS3K3rAOzjDEwd -S0gXJ31UFkUWckpzt1bH3MlHHB3LbJiwrNUz4yE7CZrxKnigIovIBkkcqjQII3KB6117clXESN4o -hmXM2C/hRPaMR6wIAHWxqudaguVO88I9XbKaNdn3tZJrzyfZDxDs6XLihSb7vupk2Cd51IxNKA4d -AwARHavtVIJ3ISO5L//hnFn4VwGSh4gdKuEwl7kGyUN3g4LTGAjMcwDQMQCYrY4FnUHatKNMzGhP -syLulkNy2hPQINl9zTTjVUFC+UUIX3+rItIYzZYxtEULM34jYSRB8cVn5kiyjBkjVgQAlbFicHzz -d/4cFVmxJb40xzYJJPOfAzDL18ksDKqW5GQznhQrQscAYBE1j0ggG4QpemJV0KokAzIMQ8cAQETH -ZCo/m+BZI0wG64StGC5eu1fCsCozNjf6Vw2z0syqveZyRXA4geTaI00bw5h3DwAS4I6xzH24p6IX -2UlLw+e4wxpdS3ColVqiRHOKd61neC4kQ8cAoC64tfuykW6TJ3OL9MtNA4LTmpKJKp5LzJpkwrB7 -kByimpgxdAwAdOhYmqcfQsE5wcLzTYtIlgDD3dic4EnPjwncdQiS3LCqWcSM8Rw0AMxTx4r4Hm3P -QQs7coEuT5oNLNB3bc+/FGmJmRK4GurtpNPkEBRcbIQfyQTT4rRF8MWMLG21n2SSgwxPmncfNImE -RfAlh7EeM0asCACCsWLyQl8NJT64IHvaJh1imfTCSNY230qPGWMuFQAI6ljD9UAjixhPjZ5rLHat -wb+2YtgnucZi10rChBokG0DHAEBExwoO+iJF2KlPQFv/2mRaLTMJLEVykzK3q2AaSK7KcCmSTz0/ -1hCZlWX3h/LBmJ45gVMZnjTPw/62STA2X5IRKwKAYKxYMK0cXcuS4wKnPgnvxmnMXuS74d5pTT1v -keoIh+FRkgUYztc6PwgXq44UNGPoGACI61i9uXlFDvtk+8VmquZoZCIP8xRti871ihalGO66XJKb -l/U1mDHmUgFAIx2LD9Pm/qn3r/5DsqRtJNqWLHYX8fFtSXYVjJDsNoykJWIkFwlVZBg2+dhK59CP -VJbtmDEhjWsW8fs2/HoAcx3z/gvX9/dIUj6XLYLiDNuOWJI5DE+qB3BINp8Skme3CRNiRQAQjxWV -46A77jwFi0QCJPc1XjD45kv/fbT8Cx+p3a8Z7sEmmQiLZXjoQrzQug0gGTUPABDUsZwYt8gMJrub -06iXjTtXP/UayiLcLkeydvtmcJo/swH2+JkM55BMJvsw51KVJTnOcDcwzX8Sw6rMGPkYAIjomOsP -MudT5/ycOA/+jFX3hmmRNkf8Mfn06eEpz/cijQm5/+DPhUkmDE+aS2Xv+xdpc5zhU3QdUgG3JA8x -rMqMMZcKAATzseboncfB0dp/XL151//0j3/W7uHc2WNfwQq624Igt5WUMLzWgf9Jvnjyphsp9CQT -hn2SM6OGGgxrI9kw/PqlGy/HmG+prRAcXaMjjTDepDtPumOOKeghuY9hgtvicBgGyXGY0WXoRawI -ABLYOr+jYk6KWVGV1Dy6icvZAqMMu/7VAnvbFzdjN0yAjgHA0mseZukO4lnNv70zMI4BjrZgjOA7 -WqhZcZJde4aOAUDlfOz7r+6SYdd7OPJv51Si3AQp6CD9Hw65TytW/tCPwz9y/FyRb7r/Tu3pEFHx -/g7pCbOR8SP7Le/DBNI7v+Uckl2VC2YdkQMmXAi/zfGm+t8hJ2U2tdQldr/5nwADACLM1IGrPYuL -AAAAAElFTkSuQmCC ---047d7b45041e19c68004eb9f3de8-- diff --git a/spec/fixtures/emails/auto_generated_header.eml b/spec/fixtures/emails/auto_generated_header.eml new file mode 100644 index 00000000000..74e0e9d4fd4 --- /dev/null +++ b/spec/fixtures/emails/auto_generated_header.eml @@ -0,0 +1,8 @@ +Return-Path: +From: Foo Bar +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <3@foo.bar.mail> +Auto-Submitted: auto-generated +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit diff --git a/spec/fixtures/emails/auto_generated_precedence.eml b/spec/fixtures/emails/auto_generated_precedence.eml new file mode 100644 index 00000000000..bc82e2b3c26 --- /dev/null +++ b/spec/fixtures/emails/auto_generated_precedence.eml @@ -0,0 +1,8 @@ +Return-Path: +From: Foo Bar +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <2@foo.bar.mail> +Precedence: list +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit diff --git a/spec/fixtures/emails/auto_reply.eml b/spec/fixtures/emails/auto_reply.eml deleted file mode 100644 index 7999c8d78b7..00000000000 --- a/spec/fixtures/emails/auto_reply.eml +++ /dev/null @@ -1,21 +0,0 @@ -Return-Path: -Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 -Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 -Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 -Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 -Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: reply+636ca428858779856c226bb145ef4fad@appmail.adventuretime.ooo -Message-ID: -Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' -Mime-Version: 1.0 -Content-Type: text/plain; - charset=ISO-8859-1 -Content-Transfer-Encoding: 7bit -Auto-Submitted: auto-generated -X-Sieve: CMU Sieve 2.2 -X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, - 13 Jun 2013 14:03:48 -0700 (PDT) -X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 - -Test reply to Discourse email digest diff --git a/spec/fixtures/emails/bad_destinations.eml b/spec/fixtures/emails/bad_destinations.eml new file mode 100644 index 00000000000..5690e66778b --- /dev/null +++ b/spec/fixtures/emails/bad_destinations.eml @@ -0,0 +1,11 @@ +Return-Path: +From: Foo Bar +To: wat@bar.com +Cc: foofoo@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <9@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. diff --git a/spec/fixtures/emails/big5.eml b/spec/fixtures/emails/big5.eml deleted file mode 100644 index 4a7b2082486..00000000000 --- a/spec/fixtures/emails/big5.eml +++ /dev/null @@ -1,26 +0,0 @@ - -Delivered-To: discourse-reply+cd480e301683c9902891f15968bf07a5@discourse.org -Received: by 10.194.216.104 with SMTP id op8csp80593wjc; - Wed, 24 Jul 2013 07:59:14 -0700 (PDT) -Return-Path: -References: <51efeb9b36c34_66dc2dfce6811866@discourse.mail> -From: Walter White -In-Reply-To: <51efeb9b36c34_66dc2dfce6811866@discourse.mail> -Mime-Version: 1.0 (1.0) -Date: Wed, 24 Jul 2013 15:59:10 +0100 -Message-ID: <4597127794206131679@unknownmsgid> -Subject: Re: [Discourse] new reply to your post in 'Crystal Blue' -To: walter via Discourse -Content-Type: multipart/alternative; boundary=20cf301cc47ada510404f040b262 - ---20cf301cc47ada510404f040b262 -Content-Type: text/plain; charset=Big5 -Content-Transfer-Encoding: base64 - -tv2hSafapFe5cbX4pEahSQ0K ---20cf301cc47ada510404f040b262 -Content-Type: text/html; charset=Big5 -Content-Transfer-Encoding: base64 - -PGRpdiBkaXI9Imx0ciI+tv2hSafapFe5cbX4pEahSTxicj48L2Rpdj4NCg== ---20cf301cc47ada510404f040b262-- diff --git a/spec/fixtures/emails/blocked_sender.eml b/spec/fixtures/emails/blocked_sender.eml new file mode 100644 index 00000000000..19bab362379 --- /dev/null +++ b/spec/fixtures/emails/blocked_sender.eml @@ -0,0 +1,9 @@ +Return-Path: +From: Foo Bar +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <8@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. diff --git a/spec/fixtures/emails/bottom_reply.eml b/spec/fixtures/emails/bottom_reply.eml deleted file mode 100644 index 5fc992971fc..00000000000 --- a/spec/fixtures/emails/bottom_reply.eml +++ /dev/null @@ -1,160 +0,0 @@ -Received: by 10.107.19.29 with SMTP id b29csp111716ioj; - Wed, 30 Jul 2014 17:52:05 -0700 (PDT) -X-Received: by 10.194.238.6 with SMTP id vg6mr11340975wjc.24.1406767925330; - Wed, 30 Jul 2014 17:52:05 -0700 (PDT) -Received: from localhost (localhost [127.0.0.1]) - by bendel.debian.org (Postfix) with QMQP - id 18F5C417; Thu, 31 Jul 2014 00:52:04 +0000 (UTC) -Old-Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on bendel.debian.org -X-Spam-Level: -X-Spam-Status: No, score=-25.9 required=4.0 tests=FOURLA,LDOSUBSCRIBER, - LDO_WHITELIST,MURPHY_DEBIAN_MESSAGE,PGPSIGNATURE autolearn=unavailable - version=3.3.2 -X-Original-To: lists-debian-ctte@bendel.debian.org -Delivered-To: lists-debian-ctte@bendel.debian.org -Received: from localhost (localhost [127.0.0.1]) - by bendel.debian.org (Postfix) with ESMTP id CE6CDEE - for ; Thu, 31 Jul 2014 00:51:52 +0000 (UTC) -X-Virus-Scanned: at lists.debian.org with policy bank en-lt -X-Amavis-Spam-Status: No, score=-11.9 tagged_above=-10000 required=5.3 - tests=[BAYES_00=-2, FOURLA=0.1, LDO_WHITELIST=-5, PGPSIGNATURE=-5] - autolearn=ham -Received: from bendel.debian.org ([127.0.0.1]) - by localhost (lists.debian.org [127.0.0.1]) (amavisd-new, port 2525) - with ESMTP id SB451DwGZCOe for ; - Thu, 31 Jul 2014 00:51:47 +0000 (UTC) -X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_BL_NJABL=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .debian. - helo: .becquer.dodds. - helo-domain: .dodds.) FROM/MX_MATCHES_NOT_HELO(DOMAIN)=0; rate: -5 -Received: from becquer.dodds.net (becquer.dodds.net [207.224.24.209]) - by bendel.debian.org (Postfix) with ESMTP id 8E89A2B4 - for ; Thu, 31 Jul 2014 00:51:47 +0000 (UTC) -Received: from virgil.dodds.net (unknown [192.168.15.59]) - by becquer.dodds.net (Postfix) with ESMTPA id 9B0A9256EB - for ; Wed, 30 Jul 2014 17:51:19 -0700 (PDT) -Received: by virgil.dodds.net (Postfix, from userid 1000) - id 942FB60199; Wed, 30 Jul 2014 17:51:15 -0700 (PDT) -Date: Wed, 30 Jul 2014 17:51:15 -0700 -From: Jake -To: incoming+amazing@appmail.adventuretime.ooo -Subject: Re: Next Debian CTTE IRC Meeting at date -d'Thu Jul 31 17:00:00 UTC - 2014' -Message-ID: <20140731005115.GA19044@virgil.dodds.net> -Mail-Followup-To: debian-ctte@lists.debian.org -References: <20140730213924.GA12356@teltox.donarmstrong.com> -MIME-Version: 1.0 -Content-Type: multipart/signed; micalg=pgp-sha256; - protocol="application/pgp-signature"; boundary="qMm9M+Fa2AknHoGS" -Content-Disposition: inline -In-Reply-To: <20140730213924.GA12356@teltox.donarmstrong.com> -User-Agent: Mutt/1.5.23 (2014-03-12) -X-Debian-Message: Signature check passed for Debian member -X-Rc-Virus: 2007-09-13_01 -X-Rc-Spam: 2008-11-04_01 -Resent-Message-ID: -Resent-From: debian-ctte@lists.debian.org -X-Mailing-List: archive/latest/4791 -X-Loop: debian-ctte@lists.debian.org -List-Id: -List-Post: -List-Help: -List-Subscribe: -List-Unsubscribe: -Precedence: list -Resent-Sender: debian-ctte-request@lists.debian.org -Resent-Date: Thu, 31 Jul 2014 00:52:04 +0000 (UTC) - - ---qMm9M+Fa2AknHoGS -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -Content-Transfer-Encoding: quoted-printable - -On Wed, Jul 30, 2014 at 02:39:24PM -0700, Don Armstrong wrote: -> The next Debian CTTE IRC meeting is at=20 - -> date -d 'Thu Jul 31 17:00:00 UTC 2014' on irc.debian.org in -> #debian-ctte. - -> The current meeting agenda is here, and more up-to-date ones may be -> found in the git repository. - -> #startmeeting - -> #topic Who is here? - -> #topic Next Meeting? - -> #topic #717076 Decide between libjpeg-turbo and libjpeg8 et al. - -This has been voted on; should probably be removed from the agenda, someone -just needs to confirm the vote results and get it on the website. (AIUI the -archive has already begun moving on accordingly.) - -> #topic #636783 constitution: super-majority bug - -> #topic #636783 constitution: casting vote - -> #topic #636783 constitution: minimum discussion period - -> #topic #636783 constitution: TC member retirement/rollover - -> #topic #636783 constitution: TC chair retirement/rollover - -> #topic #681419 Depends: foo | foo-nonfree - -> #topic #741573 menu systems and mime-support - -> #topic #746715 init system fallout - -Also voted and just needs to be confirmed. - -> #topic #750135 Maintainer of aptitude package ->=20 -> #topic #752400 Advice on util-linux - -This has been closed by mutual agreement of the people involved and doesn't -require any action from the TC. Removed from the agenda. - -There's also bug #744246, which was assigned to the TC at my request but -without any preamble so it may have escaped notice. However, that situation -has been evolving constructively among the related parties (apparently, an -informal comment from a member of the release team was mistaken for a -release team position, so that's now being revisited), so I don't believe -this is anything we need to put on the agenda for tomorrow despite being on -the open bug list. - ---=20 -Steve Langasek Give me a lever long enough and a Free OS -Debian Developer to set it on, and I can move the world. -Ubuntu Developer http://www.debian.org/ -slangasek@ubuntu.com vorlon@debian.org - ---qMm9M+Fa2AknHoGS -Content-Type: application/pgp-signature; name="signature.asc" -Content-Description: Digital signature - ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1 - -iQIcBAEBCAAGBQJT2ZMDAAoJEFaNMPMhshM9GLsP/244S3wtYZEeVgJWIdB5PE0A -sZVezEA692y++/0oVZVecwV67yBOyfSjPPetdAph2UDMRtfurwxfj2BkbOFA2+Y6 -++MErbmC3V7IGpd/L/fFGdXgvMQT2MNBpw0fnMA7bLpNjCvoj+Hr1HXRUcWoJSlj -WmHWwWSTVRcHg8a3iWYJzY6XfLyEEgHlahrlKvJExsTx/9mc1qg7g8KGdnhzHFBl -ttdH2fxpAk/624dReCcw5RKmOLfZ1HsEl9XcVe1cb4K+MDaQiXmoEK5v3xaNz1tS -NK5v2D5gDs229zoxKzQnnzOPLHxqI5E0L9PpI/mu4T9z7H2bHR3U5BvhnT99t5uw -ydf2cZNGY0uFCV3Rvn07BfAIW5WSXhOfN/5IymRKmdhjsTiwZ/wFjFrK8tVjtERu -yeyA7RIYiblGCEKYIYLWSxhoXeEdmAdfp6EA2/IA1CpgMB+ZdSfaeMgFY7xosgmG -ax3NTnaKyhr1QEUJ2gjAwHnKjuGbRVDAinYrSvP0o8Bh9sAs2BN2negWBCZVwwkN -S9hWTjVqsBmpaPOt5SEDwDo9O9dfzkmaamDsxOuUEz9F7v5jYg0mxA/WbogGty9R -vOMKxdxRkzflL/CferVbkzL/EkZRDfWDp9SleZggrpz7miiNDbS7jdRzJ4EttmJ8 -gHBAVrOzcnbIPOIkk9pw -=KXIu ------END PGP SIGNATURE----- - ---qMm9M+Fa2AknHoGS-- - - --- -To UNSUBSCRIBE, email to debian-ctte-REQUEST@lists.debian.org -with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org -Archive: https://lists.debian.org/20140731005115.GA19044@virgil.dodds.net diff --git a/spec/fixtures/emails/boundary.eml b/spec/fixtures/emails/boundary.eml deleted file mode 100644 index 1250fe498b0..00000000000 --- a/spec/fixtures/emails/boundary.eml +++ /dev/null @@ -1,61 +0,0 @@ - -MIME-Version: 1.0 -Received: by 10.64.14.41 with HTTP; Wed, 19 Jun 2013 06:29:41 -0700 (PDT) -In-Reply-To: <51c19490e928a_13442dd8ae892548@tree.mail> -References: <51c19490e928a_13442dd8ae892548@tree.mail> -Date: Wed, 19 Jun 2013 09:29:41 -0400 -Delivered-To: finn@adventuretime.ooo -Message-ID: -Subject: Re: [Adventure Time] jake mentioned you in 'peppermint butler is - missing' -From: Finn the Human -To: jake via Adventure Time -Content-Type: multipart/alternative; boundary=001a11c206a073876a04df81d2a9 - ---001a11c206a073876a04df81d2a9 -Content-Type: text/plain; charset=ISO-8859-1 - -I'll look into it, thanks! - - -On Wednesday, June 19, 2013, jake via Discourse wrote: - -> jake mentioned you in 'peppermint butler is missing' on Adventure -> Time: -> ------------------------------ -> -> yeah, just noticed this cc @jake -> ------------------------------ -> -> Please visit this link to respond: -> http://adventuretime.ooo/t/peppermint-butler-is-missing/7628/2 -> -> To unsubscribe from these emails, visit your user preferences -> . -> - ---001a11c206a073876a04df81d2a9 -Content-Type: text/html; charset=ISO-8859-1 -Content-Transfer-Encoding: quoted-printable - -I'll look into it, thanks!

        On Wednesday, June 19, 2= -013, jake via Adventure Time wrote:

        sa= -m mentioned you in 'Duplicate message are shown in profile' on Adve= -nture Time

        - - -

        yeah, just noticed this cc @eviltrout

        - -

        Please visit this link to respond: http= -://adventuretime.ooo/t/peppermint-butler-is-missing/7628/2 - - -

        To unsubscribe from these emails, visit your user preferences.

        -
        - ---001a11c206a073876a04df81d2a9-- diff --git a/spec/fixtures/emails/cc.eml b/spec/fixtures/emails/cc.eml new file mode 100644 index 00000000000..c54363b909f --- /dev/null +++ b/spec/fixtures/emails/cc.eml @@ -0,0 +1,12 @@ +Return-Path: +From: Foo Bar +To: someone@else.com +CC: team@bar.com, wat@bar.com, reply+d400310beeae61d785c2ac6a2aacb210@bar.com +Subject: The more, the merrier +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <30@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + +It is more fun with more people. diff --git a/spec/fixtures/emails/chinese_reply.eml b/spec/fixtures/emails/chinese_reply.eml new file mode 100644 index 00000000000..befb3b1cbb7 --- /dev/null +++ b/spec/fixtures/emails/chinese_reply.eml @@ -0,0 +1,10 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <17@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=Big5 +Content-Transfer-Encoding: base64 + +5oKo5aW977yBIOS9oOS7iuWkqeWlveWQl++8nw== diff --git a/spec/fixtures/emails/dutch.eml b/spec/fixtures/emails/dutch.eml deleted file mode 100644 index 7be08dc4938..00000000000 --- a/spec/fixtures/emails/dutch.eml +++ /dev/null @@ -1,20 +0,0 @@ - -Delivered-To: discourse-reply+cd480e301683c9902891f15968bf07a5@discourse.org -Received: by 10.194.216.104 with SMTP id op8csp80593wjc; - Wed, 24 Jul 2013 07:59:14 -0700 (PDT) -Return-Path: -References: <51efeb9b36c34_66dc2dfce6811866@discourse.mail> -From: Walter White -In-Reply-To: <51efeb9b36c34_66dc2dfce6811866@discourse.mail> -Mime-Version: 1.0 (1.0) -Date: Wed, 24 Jul 2013 15:59:10 +0100 -Message-ID: <4597127794206131679@unknownmsgid> -Subject: Re: [Discourse] new reply to your post in 'Crystal Blue' -To: walter via Discourse -Content-Type: multipart/alternative; boundary=001a11c20edc15a39304e2432790 - -Dit is een antwoord in het Nederlands. - -Op 18 juli 2013 10:23 schreef Sander Datema het volgende: - -Dit is de originele post. \ No newline at end of file diff --git a/spec/fixtures/emails/email_reply_1.eml b/spec/fixtures/emails/email_reply_1.eml new file mode 100644 index 00000000000..fdf4a5f2f89 --- /dev/null +++ b/spec/fixtures/emails/email_reply_1.eml @@ -0,0 +1,12 @@ +Return-Path: +From: One +To: team@bar.com +Cc: two@foo.com, three@foo.com +Subject: Testing email threading +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <34@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +This is email reply **1**. diff --git a/spec/fixtures/emails/email_reply_2.eml b/spec/fixtures/emails/email_reply_2.eml new file mode 100644 index 00000000000..fde2e03390d --- /dev/null +++ b/spec/fixtures/emails/email_reply_2.eml @@ -0,0 +1,13 @@ +Return-Path: +From: Two +To: one@foo.com +Cc: team@bar.com, three@foo.com +Subject: RE: Testing email threading +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <35@foo.bar.mail> +In-Reply-To: <34@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +This is email reply **2**. diff --git a/spec/fixtures/emails/email_reply_3.eml b/spec/fixtures/emails/email_reply_3.eml new file mode 100644 index 00000000000..3b4eb6d0c05 --- /dev/null +++ b/spec/fixtures/emails/email_reply_3.eml @@ -0,0 +1,14 @@ +Return-Path: +From: Three +To: one@foo.com +Cc: team@bar.com, two@foo.com +Subject: RE: Testing email threading +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <36@foo.bar.mail> +In-Reply-To: <35@foo.bar.mail> +References: <34@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +This is email reply **3**. diff --git a/spec/fixtures/emails/email_reply_4.eml b/spec/fixtures/emails/email_reply_4.eml new file mode 100644 index 00000000000..4c54d008497 --- /dev/null +++ b/spec/fixtures/emails/email_reply_4.eml @@ -0,0 +1,15 @@ +Return-Path: +From: One +To: two@foo.com +Cc: team@bar.com, three@foo.com +Subject: RE: Testing email threading +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <37@foo.bar.mail> +In-Reply-To: <36@foo.bar.mail> +References: <34@foo.bar.mail> + <35@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +This is email reply **4**. diff --git a/spec/fixtures/emails/empty.eml b/spec/fixtures/emails/empty.eml deleted file mode 100644 index 85bebc66245..00000000000 --- a/spec/fixtures/emails/empty.eml +++ /dev/null @@ -1,21 +0,0 @@ -Return-Path: -Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 -Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 -Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 -Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 -Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo -Message-ID: -Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' -Mime-Version: 1.0 -Content-Type: text/plain; - charset=ISO-8859-1 -Content-Transfer-Encoding: 7bit -X-Sieve: CMU Sieve 2.2 -X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, - 13 Jun 2013 14:03:48 -0700 (PDT) -X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 - - - diff --git a/spec/fixtures/emails/encoded_display_name.eml b/spec/fixtures/emails/encoded_display_name.eml new file mode 100644 index 00000000000..1b5d6bb3a10 --- /dev/null +++ b/spec/fixtures/emails/encoded_display_name.eml @@ -0,0 +1,11 @@ +Return-Path: +From: =?UTF-8?B?0KHQu9GD0YfQsNC50L3QsNGP?= =?UTF-8?B?INCY0LzRjw==?= +To: meat@bar.com +Subject: I need help +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <29@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + +Будьте здоровы! diff --git a/spec/fixtures/emails/existing_user.eml b/spec/fixtures/emails/existing_user.eml new file mode 100644 index 00000000000..db41b91ac50 --- /dev/null +++ b/spec/fixtures/emails/existing_user.eml @@ -0,0 +1,11 @@ +Return-Path: +From: Foo Bar +To: category@bar.com +Subject: This is a topic from an existing user +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <32@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + +Hey, this is a topic from an existing user ;) diff --git a/spec/fixtures/emails/from_the_future.eml b/spec/fixtures/emails/from_the_future.eml new file mode 100644 index 00000000000..6e14c442e1d --- /dev/null +++ b/spec/fixtures/emails/from_the_future.eml @@ -0,0 +1,10 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Wed, 01 Jan 3000 00:00:00 +0100 +Message-ID: <4@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Back to the future! diff --git a/spec/fixtures/emails/gmail_web.eml b/spec/fixtures/emails/gmail_web.eml deleted file mode 100644 index 8bb83835711..00000000000 --- a/spec/fixtures/emails/gmail_web.eml +++ /dev/null @@ -1,181 +0,0 @@ -Delivered-To: reply@discourse.org -Return-Path: -MIME-Version: 1.0 -In-Reply-To: -References: - -Date: Fri, 28 Nov 2014 12:36:49 -0800 -Subject: Re: [Discourse Meta] [Lounge] Testing default email replies -From: Walter White -To: Discourse Meta -Content-Type: multipart/alternative; boundary=001a11c2e04e6544f30508f138ba - ---001a11c2e04e6544f30508f138ba -Content-Type: text/plain; charset=UTF-8 - -### This is a reply from standard GMail in Google Chrome. - -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over -the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown -fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over -the lazy dog. The quick brown fox jumps over the lazy dog. - -Here's some **bold** text in Markdown. - -Here's a link http://example.com - -On Fri, Nov 28, 2014 at 12:35 PM, Arpit Jalan wrote: - -> techAPJ -> November 28 -> -> Test reply. -> -> First paragraph. -> -> Second paragraph. -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in -> your browser. -> ------------------------------ -> Previous Replies codinghorror -> -> November 28 -> -> We're testing the latest GitHub email processing library which we are -> integrating now. -> -> https://github.com/github/email_reply_parser -> -> Go ahead and reply to this topic and I'll reply from various email clients -> for testing. -> ------------------------------ -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in -> your browser. -> -> To unsubscribe from these emails, visit your user preferences -> . -> - ---001a11c2e04e6544f30508f138ba -Content-Type: text/html; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable - -
        ### This is a reply from standard GMail in Google Chr= -ome.

        The quick brown fox jumps over the lazy dog. = -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over= - the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown= - fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. = -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over= - the lazy dog.=C2=A0

        Here's some **bold** text= - in Markdown.

        Here's a link http://example.com
        <= -br>
        On Fri, Nov 28, 2014 at 12:35 PM, Arpit Jalan= - <info@discourse.org> wrote:
        - - - - - - - - - - - -
        - - - techAPJ
        - November 28 -
        -

        Test reply.

        - -

        First paragraph.

        - -

        Second paragraph.

        -
        - - -
        -

        To respond, reply to this email or visit https:/= -/meta.discourse.org/t/testing-default-email-replies/22638/3 in your bro= -wser.

        -
        -
        -

        Previous Replies

        - - - - - - - - - - - -
        - - - codinghorror - November 28 -
        -

        We're testing the latest GitHub emai= -l processing library which we are integrating now.

        - -

        https://github.com/github/email_reply_parser

        - -

        Go ahead and reply to this topic and I&#= -39;ll reply from various email clients for testing.

        -
        - - -
        - -
        -

        To respond, reply to this email or visit https://met= -a.discourse.org/t/testing-default-email-replies/22638/3 in your browser= -.

        -
        -
        -

        To unsubscribe from these emails, visit your user preferences.

        -
        -
        -

        - ---001a11c2e04e6544f30508f138ba-- diff --git a/spec/fixtures/emails/hebrew.eml b/spec/fixtures/emails/hebrew.eml deleted file mode 100644 index f4c8f01adc3..00000000000 --- a/spec/fixtures/emails/hebrew.eml +++ /dev/null @@ -1,17 +0,0 @@ - -Delivered-To: discourse-reply+cd480e301683c9902891f15968bf07a5@discourse.org -Received: by 10.194.216.104 with SMTP id op8csp80593wjc; - Wed, 24 Jul 2013 07:59:14 -0700 (PDT) -Return-Path: -References: <51efeb9b36c34_66dc2dfce6811866@discourse.mail> -From: Walter White -In-Reply-To: <51efeb9b36c34_66dc2dfce6811866@discourse.mail> -Mime-Version: 1.0 (1.0) -Date: Wed, 24 Jul 2013 15:59:10 +0100 -Message-ID: <4597127794206131679@unknownmsgid> -Subject: Re: [Discourse] new reply to your post in 'Crystal Blue' -To: walter via Discourse -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: base64 - -16nXnNeV150= \ No newline at end of file diff --git a/spec/fixtures/emails/hebrew_reply.eml b/spec/fixtures/emails/hebrew_reply.eml new file mode 100644 index 00000000000..450e2dea2fc --- /dev/null +++ b/spec/fixtures/emails/hebrew_reply.eml @@ -0,0 +1,10 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <16@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: base64 + +16nXnNeV150hINee15Qg16nXnNeV157XmiDXlNeZ15XXnT8= diff --git a/spec/fixtures/emails/html_only.eml b/spec/fixtures/emails/html_only.eml deleted file mode 100644 index 561b8db2c79..00000000000 --- a/spec/fixtures/emails/html_only.eml +++ /dev/null @@ -1,93 +0,0 @@ - -Delivered-To: walter@breakingbad.com -Received: by 10.64.13.41 with SMTP id m9csp29769iec; - Thu, 20 Jun 2013 08:53:22 -0700 (PDT) -X-Received: by 10.252.23.9 with SMTP id p9mr4055675lag.4.1371743601980; - Thu, 20 Jun 2013 08:53:21 -0700 (PDT) -Received: from mail-la0-x229.google.com (mail-la0-x229.google.com [2a00:1450:4010:c03::229]) - by mx.google.com with ESMTPS id u4si430203lae.48.2013.06.20.08.53.20 - for - (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); - Thu, 20 Jun 2013 08:53:21 -0700 (PDT) -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=google.com; s=20120113; - h=x-forwarded-to:x-forwarded-for:delivered-to:x-return-path - :content-type:mime-version:content-transfer-encoding:x-mailer - :message-id:date:subject:from:in-reply-to:to:resent-date:resent-from - :resent-to:resent-subject:resent-message-id:resent-user-agent - :x-scanned-by:x-gm-message-state; - bh=9O67r74ofh9WkEaKTRB/frQ3MKOtQlbCac2mz0/MiyY=; - b=YVAo2/JDMP53RxDmqDEKNcEMtggtfaVyq2DoseZ6vBAfB7G6NtHC9ZEkRs4oGhk6LU - fnyAPe0wnz5d9WINoMAuuTRIhplLxzcqysduSnAJAQ2qqR7mFBnlj9wJeVEKltNwmUME - nPwxsf8go20VBzrZCtECPedcLi60wbl32NCXVn0qwt2LvKiy6ktSS5Xgb4zY8i4dfXAP - 6Y5gu32boooWIb9DkH1TJkn3C0RrEugNlw/DUnXrnkFefgxWF3pt/zcoW/wYRyikOdx+ - smBClgR9my6QmsS2KsQrMvWJZUva7fddTiZ6FC22e4hW+8Wha0RaZOZu5O7hjg6G4/1g - IEyg== -X-Received: by 10.112.55.9 with SMTP id n9mr5916187lbp.5.1371743600857; - Thu, 20 Jun 2013 08:53:20 -0700 (PDT) -X-Forwarded-To: walter@breakingbad.com -X-Forwarded-For: walter@breakingbad.com -Delivered-To: walter@breakingbad.com -Content-Type: text/html; charset="us-ascii" -MIME-Version: 1.0 -Content-Transfer-Encoding: quoted-printable -X-Mailer: BlackBerry Email (10.1.0.1720) -Message-ID: <20130619231548.6307981.74194.2379@breakingbad.com> -Date: Wed, 19 Jun 2013 19:15:48 -0400 -Subject: Re: [Discourse Meta] [PM] re: Regarding your post in "Site - Customization not working" -From: aaron@breakingbad.com -In-Reply-To: <51c238655a394_5f4e3ce6690667bd@tiefighter2.mail> -To: reply+20c1b0a8bd1a63c0163cc7e7641ca06b@appmail.adventuretime.ooo -ReSent-Date: Thu, 20 Jun 2013 11:53:08 -0400 (EDT) -ReSent-From: Aaron -ReSent-Subject: Re: [Discourse Meta] [PM] re: Regarding your post in "Site - Customization not working" -X-Gm-Message-State: ALoCoQl1BtN83rAX7At808XAPv1yCqUK3Du2IvK7eCyY3jsI77u4e5cak28307pYYHAo1JlO/Eu9 - -
        The EC2 instance - I've seen that th= -ere tends to be odd and unrecommended settings on the Bitnami installs that= - I've checked out.
        = - = -

        = - = -
        = - = - = -
        = -From: Grizzly B via Discourse Meta
        Sent: Wednesday, J= -une 19, 2013 19:02
        To: aaron@breakingbad.com
        = -Reply To: Grizzly B via Discourse Meta
        Subject: [Disc= -ourse Meta] [PM] re: Regarding your post in "Site Customization
        not wor= -king"

        Grizzly B just sent you a private message

        - -

        Log in to our EC2 instance -or- log into a new Digital Ocean instanc= -e?

        - -

        Please visit this link to respond: http://= -meta.discourse.org/t/regarding-your-post-in-site-customization-not-working/= -7641/5

        - -

        To unsubscribe from these emails, visit your user preferences.

        -
        diff --git a/spec/fixtures/emails/html_paragraphs.eml b/spec/fixtures/emails/html_paragraphs.eml deleted file mode 100644 index 3fe37fb8b17..00000000000 --- a/spec/fixtures/emails/html_paragraphs.eml +++ /dev/null @@ -1,205 +0,0 @@ - -MIME-Version: 1.0 -Received: by 10.25.161.144 with HTTP; Tue, 7 Oct 2014 22:17:17 -0700 (PDT) -X-Originating-IP: [117.207.85.84] -In-Reply-To: <5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail> -References: - <5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail> -Date: Wed, 8 Oct 2014 10:47:17 +0530 -Delivered-To: arpit@techapj.com -Message-ID: -Subject: Re: [Discourse] [Meta] Welcome to techAPJ's Discourse! -From: Arpit Jalan -To: Discourse -Content-Type: multipart/alternative; boundary=001a114119d8f4e46e0504e26d5b - ---001a114119d8f4e46e0504e26d5b -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable - -Awesome! - -Pleasure to have you here! - -:boom: - -On Wed, Oct 8, 2014 at 10:46 AM, ajalan -wrote: - -> ajalan -> -> October 8 -> -> Nice to be here! Thanks! [image: smile] -> -> To respond, reply to this email or visit -> http://discourse.techapj.com/t/welcome-to-techapjs-discourse/35/2 -> -> in your browser. -> ------------------------------ -> Previous Replies techAPJ -> -> October 8 -> -> Welcome to techAPJ's Discourse! -> ------------------------------ -> -> To respond, reply to this email or visit -> http://discourse.techapj.com/t/welcome-to-techapjs-discourse/35/2 -> -> in your browser. -> -> To unsubscribe from these emails, visit your user preferences -> -> . -> - ---001a114119d8f4e46e0504e26d5b -Content-Type: text/html; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable - -
        Awesome!

        Pleasure to have you here!

        :boom:

        On Wed, Oct 8, 2014 at 10:46 AM, ajalan <info@unconfigured.discourse.org> wrote:
        - - - - - - - - - - - -
        - - - ajalan
        - October 8 -

        Nice to be here! Thanks! 3D"smile"

        - - -
        -

        To respond, reply to this email or visit http://discourse= -.techapj.com/t/welcome-to-techapjs-discourse/35/2 in your browser.

        -
        -
        -

        Previous Replies

        - - - - - - - - - - - -
        - - - techAPJ
        - October 8 -

        Welcome to techAPJ's Discourse!

        - - -
        - -
        -

        To respond, reply to this email or visit http://discourse.tec= -hapj.com/t/welcome-to-techapjs-discourse/35/2 in your browser.

        -
        -
        -

        To unsubscribe from these emails, visit your user preferences.

        -
        -
        - -
        = -
        - ---001a114119d8f4e46e0504e26d5b-- diff --git a/spec/fixtures/emails/html_reply.eml b/spec/fixtures/emails/html_reply.eml new file mode 100644 index 00000000000..28e5feff851 --- /dev/null +++ b/spec/fixtures/emails/html_reply.eml @@ -0,0 +1,10 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <18@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/html; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + +
        This is a HTML reply ;)
        diff --git a/spec/fixtures/emails/inactive_sender.eml b/spec/fixtures/emails/inactive_sender.eml new file mode 100644 index 00000000000..d22e9507887 --- /dev/null +++ b/spec/fixtures/emails/inactive_sender.eml @@ -0,0 +1,9 @@ +Return-Path: +From: Foo Bar +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <8@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. diff --git a/spec/fixtures/emails/inline_image.eml b/spec/fixtures/emails/inline_image.eml new file mode 100644 index 00000000000..52188b2a787 --- /dev/null +++ b/spec/fixtures/emails/inline_image.eml @@ -0,0 +1,76 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <28@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: multipart/related; boundary=001a114b2eccff183a052998ec68 + +--001a114b2eccff183a052998ec68 +Content-Type: multipart/alternative; boundary=001a114b2eccff1836052998ec67 + +--001a114b2eccff1836052998ec67 +Content-Type: text/plain; charset=UTF-8 + +Before + +[image: 内嵌图片 1] + +After + +--001a114b2eccff1836052998ec67 +Content-Type: text/html; charset=UTF-8 + +
        Before

        内嵌图片 1
        +

        After
        + +--001a114b2eccff1836052998ec67-- +--001a114b2eccff183a052998ec68 +Content-Type: image/png; name="logo.png" +Content-Disposition: inline; filename="logo.png" +Content-Transfer-Encoding: base64 +Content-ID: +X-Attachment-Id: ii_1525434659ddb4cb + +iVBORw0KGgoAAAANSUhEUgAAAPQAAABCCAMAAABXYgukAAABhlBMVEUAAAAjHyAjHyAjHyAjHyAj +HyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAAqVAAru/lGyTxXCL/+a5UHiHZGyTq +NyPtRCM7HyHwWCLrPCOEHSL95Z31g0W1HCMgs1wAqnghKC0Aq5YJirsAqm6oHCMPb5QArccUXnsS +Z4hAvWj80ouP1oXoKyR4HSL0eTz4q2j+76XsQCOf24vpLyNsHiJgHiEYTGHyZiucHSPzcDTf76IL +ga7qMyMwuGIArdEaQ1T7yIJwzHn2l1f6vnovHyDuTCPNHCQfMTr3oV/wVCL5tHEHk8gArKDnJyTv +UCIAruUWVW4ArLMQrlYNeKEEnNVQwm0cOkcAq4KA0X/mHyQAqVoArKkAq4wCpeIArdvnIyT1jU4A +qmQUXV3v9KikRSHP6pwwIyBHHiHKUSLxaDTtSCMCpLpgx3PaHyTtSSy/5Zetw3b83JSVSiT0i1eg +MSI+qVa2JCMrbVbiX0Ygs2YArL2LkGApkWQLf2kSZmpFMZD0AAAAEHRSTlMAEFCAv8+vQCBw72CP +358w5xEcGAAABxJJREFUeF7lmuW/uzoMh1eKrUApbMfd9efu7u5u193d739+gbHQBtg49x3b99U5 +H7asD0mTNNAoE9GobohUukmtxqDLbhoCi5nOICNruigWc+0BRXY80UN8ELEtQ/QWo4OGTFzRX4Y/ +UMy+ISqpOUi7mYmK4oPDLKpLJ4PBzMVOZAwEdVNgje6dmZ+fX5vZ+1mhrwcwto+stTKNnRgdxH3t +q0B7r6W4d/fEirivHR24HE48Ja47yO+NX22nujlxuDU/ialrXq9NmWUmQd7TIQZNTX9zBCczGYCy +mjVrmoxyIgnrDvLJS5d3jUSa3XXr/fbU+Ayipvi2mTUMbmAeT5AvJcCgy3P3fkbUNrTs6QWrNtAU +Mb+cSJBnR7B27fv4U5TBkQlaG0czKW3HzPfiwAYvK9r/OXI1hq5hWzI5FkF/GTHPHRgp1vc/qq5G +WcGpC7QnQPMR88E4tEdK9ctvMjQjKYAB+bxufcloXKoQM9ah4ENAllxLzFodQ1wBWos29M12e99I +Ly0sHius1cSCXF6n6J6MHD3dbh+f7Qm9O/hqSaIm9e26IXVPtdu3RnrqVLB4GsV37eQo0X0Ggrtc +Z4Nz5wXIRQB129JjSbm60A/6YrC8gjZ13aQD85UouqOuBODKN/VqeF2A0nunxwK3E4fqOm3mU5vf +pKZu0qafB/BpZASuVJVNTd4kqW03Mq3lEK3YsEs1AtAsK1hJvbrRF/q7IAjXcVOmK+MU2rWqKwi2 +m/2aR5UUSKgnXcEdMgBkHX76ey4kFr/rPqZYtnlGyC0wA9BJ7v6hCvTGbQGyctDEQKMGIFDEpEsa +U65oVaE5lBBfsuBl0dJkQpZLiqCPj1SCDpfKoOFvnOlsQ2CZBNiQeDXolMhMmUHML5t2GiQHfbU9 +Vwn6Tpjl7yaGdgrPnzYTeRmQTLF4BWiQhm+08BAzokbQ+ytCbwIAxdCmCuDIIY/llg7caXVoFoUR +2jk+OkoZOkSCrkBfqQi9O4beKodOQ86yKAPmzJme61gaTUOdOXIMeC5tuh4ESDXoZsN2YIhBLY0D +Mxg2nE5Gy7wg5Dp9sAr0xXhPb5WHd7ZmYqTM4AnPgswFaZaDIeXhkl4BGjKGlX3FYt0dzZWdAvve +U6DXWtNVoM+q0FYxNE+Auow891yEGLzzDwE76tqEXQXalqGFlrClzETguR18Sh7wt/ZUgD4VBMH9 +cmjY057clTPYamV9MM1NNWgFaKOhAArdyhm2c4+uXBn6Sutl+0aVLf1BGD4ob04sITC21aNP5zCN +QLdIrwBtSjgY2+0Y1iV56Z1Sp7/3+peshSBYDqWS1UDQcvr2NMWbfnkfbBbch97QEA24Ipo2GC6R +Aj3aGu/bnBwKguBcGKIHeaUdGSc4H2ExHN2AWh0aMgHUhOrQYu3lVJ829KOFJLpXlEqLe2/CUTPQ +C1rsAJrkoUG+h3qDqtCTY9M3+tar4GEo9SYahk6kZStw+0B7O4C2CqBBhDIpu1aHFmNnTvbpxhJH +S0dLgqDzb2bZVfa0LkOb0Eo6laGV/kPoAM2tvJCnWxOXejF/8iiIi3T4GJjN8qU7DBbm98jeLq4s +UGAlShVa2RUYG8zR0iGHCn20NTXbj3lZcbRTBE1IZwUeLN7Lu7r7t5brIczMtKWeT90e0EQpFBYY +tvpBzxye68e8GobSCIEVBqlhEFgA1Ft00HXgfTQGjMqyGcnYvA4RgQJelL3TO2MAKoPvpvK5XQA9 +P3GhR7FKmO+H4ZMlgKZF0LzbY5sAbTN1cGBzdJKC+mqbimkDakB2IndlaGBODRAPoKna7xOanINy +0GNflHefT4OUOXwmQDaGhtbCoFSXFkYhNnRKuaG8fOhlB0DdQA+MHEhNOmRjH0MDKqdU2kiEde1S +zWpylk2wlDx291YZ8tdBrOcx8wN0HEbQrkDye7QKDvQVWBbQYOmovBed1j3IezkxW4U++u0BqE0v +Dp0C4t3bCfKr16HKzEgBNMdrhHWVzke0wrtRco3ZBdD4tintb36+oOSxn9KMdXEhhny0/fTFi+3t +R0FHb2I3vz2Gh3758C5+y47o5WTY18xBhyW0aAyNDXC5bGJmBP3rbEq8+ubhu403r4JMq69j5PD2 +deTDokRGMTOeTObHw8RUrti43uNBJ4aGW4r7AV/Ho0gM/XtE/MfinY37t1fWtx6H4cbr5cVIz+/8 ++S6M9XYTxxmGhlkzDGpkEQfYPI7qp9X9DuMJF56JY3t6Ism+ZaLpNjYsPNfP1+nJv/7+59+t891T +4/X1t6GsJ5tLaN9I8q1Yvvo/eBl/EK7kL9mNIpFO+9hHZR+y8W+KXjq2vtIBf3J681luXFlfYc6h +eOV7GJkb/5d5+KCbjaGDZlZjiKChwA8RNEx1hwcanvIPGbThAPKQQBvQuQ4FtKeb8GrOQOg/pxLS +uIDrr6oAAAAASUVORK5CYII= +--001a114b2eccff183a052998ec68-- diff --git a/spec/fixtures/emails/inline_mixed_replies.eml b/spec/fixtures/emails/inline_mixed_replies.eml new file mode 100644 index 00000000000..05c299e96aa --- /dev/null +++ b/spec/fixtures/emails/inline_mixed_replies.eml @@ -0,0 +1,19 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <24@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 + +On Tue, Jan 15, 2016 at 11:12 AM, Bar Foo wrote: + +> WAT November 28 +> +> This is the previous post. + +And this is *my* reply :+1: + +> This is another post. + +And this is **another** reply. diff --git a/spec/fixtures/emails/inline_reply.eml b/spec/fixtures/emails/inline_reply.eml index 39625a225da..b65518e2aa4 100644 --- a/spec/fixtures/emails/inline_reply.eml +++ b/spec/fixtures/emails/inline_reply.eml @@ -1,60 +1,15 @@ - -MIME-Version: 1.0 -In-Reply-To: -References: - <5434ced4ee0f9_663fb0b5f76070593b@discourse-app.mail> -Date: Mon, 1 Dec 2014 20:48:40 +0530 -Delivered-To: someone@googlemail.com -Subject: Re: [Discourse] [Meta] Testing reply via email -From: Walter White -To: Discourse -Content-Type: multipart/alternative; boundary=20cf30363f8522466905092920a6 - ---20cf30363f8522466905092920a6 +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <23@foo.bar.mail> +Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable -On Wed, Oct 8, 2014 at 11:12 AM, techAPJ -wrote: +On Tue, Jan 15, 2016 at 11:12 AM, Bar Foo wrote: -> techAPJ -> November 28 -> -> Test reply. -> -> First paragraph. -> -> Second paragraph. -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in -> your browser. -> ------------------------------ -> Previous Replies codinghorror -> -> November 28 -> -> We're testing the latest GitHub email processing library which we are -> integrating now. -> -> https://github.com/github/email_reply_parser -> -> Go ahead and reply to this topic and I'll reply from various email clients -> for testing. -> ------------------------------ -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in -> your browser. -> -> To unsubscribe from these emails, visit your user preferences -> . +> WAT November 28 > +> This is the previous post. -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over -the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown -fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over -the lazy dog. The quick brown fox jumps over the lazy dog. - ---20cf30363f8522466905092920a6-- +And this is *my* reply :+1: diff --git a/spec/fixtures/emails/invalid_from.eml b/spec/fixtures/emails/invalid_from.eml new file mode 100644 index 00000000000..38dc0fbc8ed --- /dev/null +++ b/spec/fixtures/emails/invalid_from.eml @@ -0,0 +1,9 @@ +Return-Path: +From: Foo Bar [THIS IS INVALID] +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <41@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 + +This email was sent with an invalid from header field. diff --git a/spec/fixtures/emails/ios_default.eml b/spec/fixtures/emails/ios_default.eml deleted file mode 100644 index 8d4d58feb16..00000000000 --- a/spec/fixtures/emails/ios_default.eml +++ /dev/null @@ -1,136 +0,0 @@ -Delivered-To: reply@discourse.org -Return-Path: -From: Walter White -Content-Type: multipart/alternative; - boundary=Apple-Mail-B41C7F8E-3639-49B0-A5D5-440E125A7105 -Content-Transfer-Encoding: 7bit -Mime-Version: 1.0 (1.0) -Subject: Re: [Discourse Meta] [Lounge] Testing default email replies -Date: Fri, 28 Nov 2014 12:41:41 -0800 -References: -In-Reply-To: -To: Discourse Meta -X-Mailer: iPhone Mail (12B436) - - ---Apple-Mail-B41C7F8E-3639-49B0-A5D5-440E125A7105 -Content-Type: text/plain; - charset=us-ascii -Content-Transfer-Encoding: quoted-printable - -### this is a reply from iOS default mail - -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over t= -he lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fo= -x jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The q= -uick brown fox jumps over the lazy dog. The quick brown fox jumps over the l= -azy dog.=20 - -Here's some **bold** markdown text. - -Here's a link http://example.com - - -> On Nov 28, 2014, at 12:35 PM, Arpit Jalan wrote: ->=20 ->=20 -> techAPJ -> November 28 -> Test reply. ->=20 -> First paragraph. ->=20 -> Second paragraph. ->=20 -> To respond, reply to this email or visit https://meta.discourse.org/t/test= -ing-default-email-replies/22638/3 in your browser. ->=20 -> Previous Replies ->=20 -> codinghorror -> November 28 -> We're testing the latest GitHub email processing library which we are inte= -grating now. ->=20 -> https://github.com/github/email_reply_parser ->=20 -> Go ahead and reply to this topic and I'll reply from various email clients= - for testing. ->=20 -> To respond, reply to this email or visit https://meta.discourse.org/t/test= -ing-default-email-replies/22638/3 in your browser. ->=20 -> To unsubscribe from these emails, visit your user preferences. - ---Apple-Mail-B41C7F8E-3639-49B0-A5D5-440E125A7105 -Content-Type: text/html; - charset=utf-8 -Content-Transfer-Encoding: 7bit - -
        ### this is a reply from iOS default mail

        The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. 

        Here's some **bold** markdown text.

        Here's a link http://example.com


        On Nov 28, 2014, at 12:35 PM, Arpit Jalan <info@discourse.org> wrote:

        - - - - - - - - - - - -
        - - - techAPJ
        - November 28 -
        -

        Test reply.

        - -

        First paragraph.

        - -

        Second paragraph.

        -
        - - -
        -

        To respond, reply to this email or visit https://meta.discourse.org/t/testing-default-email-replies/22638/3 in your browser.

        -
        -
        -

        Previous Replies

        - - - - - - - - - - - -
        - - - codinghorror
        - November 28 -
        -

        We're testing the latest GitHub email processing library which we are integrating now.

        - -

        https://github.com/github/email_reply_parser

        - -

        Go ahead and reply to this topic and I'll reply from various email clients for testing.

        -
        - - -
        - -
        -

        To respond, reply to this email or visit https://meta.discourse.org/t/testing-default-email-replies/22638/3 in your browser.

        -
        -
        -

        To unsubscribe from these emails, visit your user preferences.

        -
        -
        -
        ---Apple-Mail-B41C7F8E-3639-49B0-A5D5-440E125A7105-- diff --git a/spec/fixtures/emails/iphone_signature.eml b/spec/fixtures/emails/iphone_signature.eml index d314ad1f1ea..79183b4a3f0 100644 --- a/spec/fixtures/emails/iphone_signature.eml +++ b/spec/fixtures/emails/iphone_signature.eml @@ -1,29 +1,11 @@ -Delivered-To: test@mail.com -Return-Path: -From: Walter White -Content-Type: multipart/alternative; - boundary=Apple-Mail-8E182EEF-9DBC-41DE-A593-DF2E5EBD3975 -Content-Transfer-Encoding: 7bit -Mime-Version: 1.0 (1.0) -Subject: Re: Signature in email replies! -Date: Thu, 23 Oct 2014 14:43:49 +0530 -References: <1234@mail.gmail.com> -In-Reply-To: <1234@mail.gmail.com> -To: Arpit Jalan -X-Mailer: iPhone Mail (12A405) +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <25@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +This is not the signature you're looking for. ---Apple-Mail-8E182EEF-9DBC-41DE-A593-DF2E5EBD3975 -Content-Type: text/plain; - charset=us-ascii -Content-Transfer-Encoding: 7bit - -This post should not include signature. - -Sent from my iPhone - -> On 23-Oct-2014, at 9:45 am, Arpit Jalan wrote: -> -> Signature in email replies! - ---Apple-Mail-8E182EEF-9DBC-41DE-A593-DF2E5EBD3975 +Sent from my iMachine diff --git a/spec/fixtures/emails/like.eml b/spec/fixtures/emails/like.eml new file mode 100644 index 00000000000..39829fcaab7 --- /dev/null +++ b/spec/fixtures/emails/like.eml @@ -0,0 +1,10 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <13@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + ++1 diff --git a/spec/fixtures/emails/missing_message_id.eml b/spec/fixtures/emails/missing_message_id.eml new file mode 100644 index 00000000000..0fbad2fadcb --- /dev/null +++ b/spec/fixtures/emails/missing_message_id.eml @@ -0,0 +1,8 @@ +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Some body diff --git a/spec/fixtures/emails/multiple_destinations.eml b/spec/fixtures/emails/multiple_destinations.eml deleted file mode 100644 index 6d31bbf1974..00000000000 --- a/spec/fixtures/emails/multiple_destinations.eml +++ /dev/null @@ -1,40 +0,0 @@ -Return-Path: -Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 -Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 -Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 -Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 -Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: finn@adventuretime.ooo, reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo -Message-ID: -Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' -Mime-Version: 1.0 -Content-Type: text/plain; - charset=ISO-8859-1 -Content-Transfer-Encoding: 7bit -X-Sieve: CMU Sieve 2.2 -X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, - 13 Jun 2013 14:03:48 -0700 (PDT) -X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 - -I could not disagree more. I am obviously biased but adventure time is the -greatest show ever created. Everyone should watch it. - -- Jake out - - -On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta - wrote: -> -> -> -> eviltrout posted in 'Adventure Time Sux' on Discourse Meta: -> -> --- -> hey guys everyone knows adventure time sucks! -> -> --- -> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3 -> -> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences). -> \ No newline at end of file diff --git a/spec/fixtures/emails/new_user.eml b/spec/fixtures/emails/new_user.eml new file mode 100644 index 00000000000..fdae501ab9c --- /dev/null +++ b/spec/fixtures/emails/new_user.eml @@ -0,0 +1,11 @@ +Return-Path: +From: Foo Bar +To: category@foo.com +Subject: This is a topic from a complete stranger +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <31@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + +Hey, this is a topic from a complete stranger ;) diff --git a/spec/fixtures/emails/newlines.eml b/spec/fixtures/emails/newlines.eml deleted file mode 100644 index cf03b9d18bc..00000000000 --- a/spec/fixtures/emails/newlines.eml +++ /dev/null @@ -1,84 +0,0 @@ -In-Reply-To: -Date: Wed, 8 Oct 2014 10:36:19 +0530 -Delivered-To: walter.white@googlemail.com -Subject: Re: [Discourse] Welcome to Discourse -From: Walter White -To: Discourse -Content-Type: multipart/alternative; boundary=bcaec554078cc3d0c10504e24661 - ---bcaec554078cc3d0c10504e24661 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable - -This is my reply. -It is my best reply. -It will also be my *only* reply. - -On Wed, Oct 8, 2014 at 10:33 AM, ajalan -wrote: - -> ajalan -> -> October 8 -> -> Awesome! Thank You! [image: +1] -> -> To respond, reply to this email or visit -> http://discourse.techapj.com/t/welcome-to-discourse/8/2 -> -> in your browser. -> ------------------------------ -> Previous Replies system -> -> October 8 -> -> The first paragraph of this pinned topic will be visible as a welcome -> message to all new visitors on your homepage. It's important! -> -> *Edit this* into a brief description of your community: -> -> - Who is it for? -> - What can they find here? -> - Why should they come here? -> - Where can they read more (links, resources, etc)? -> -> You may want to close this topic via the wrench icon at the upper right, -> so that replies don't pile up on an announcement. -> ------------------------------ -> -> To respond, reply to this email or visit -> http://discourse.techapj.com/t/welcome-to-discourse/8/2 -> -> in your browser. -> -> To unsubscribe from these emails, visit your user preferences -> -> . -> - ---bcaec554078cc3d0c10504e24661 diff --git a/spec/fixtures/emails/no_body.eml b/spec/fixtures/emails/no_body.eml new file mode 100644 index 00000000000..02afbe73315 --- /dev/null +++ b/spec/fixtures/emails/no_body.eml @@ -0,0 +1,7 @@ +Return-Path: +From: Foo Bar +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <5@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit diff --git a/spec/fixtures/emails/no_body_with_image.eml b/spec/fixtures/emails/no_body_with_image.eml new file mode 100644 index 00000000000..7e768d118dc --- /dev/null +++ b/spec/fixtures/emails/no_body_with_image.eml @@ -0,0 +1,75 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <6@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: multipart/mixed; + boundary="--==_mimepart_56990c8d3f66c_7cb53ffbb98602004746e"; + charset=UTF-8 +Content-Transfer-Encoding: 7bit + + +----==_mimepart_56990c8d3f66c_7cb53ffbb98602004746e +Content-Type: image/png; + charset=UTF-8; + filename=logo.png +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename=logo.png +Content-ID: <56990c92d6c64_7cb53ffbb986020047616@foo.bar.mail> + +iVBORw0KGgoAAAANSUhEUgAAAPQAAABCCAMAAABXYgukAAABhlBMVEUAAAAj +HyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAjHyAj +HyAAqVAAru/lGyTxXCL/+a5UHiHZGyTqNyPtRCM7HyHwWCLrPCOEHSL95Z31 +g0W1HCMgs1wAqnghKC0Aq5YJirsAqm6oHCMPb5QArccUXnsSZ4hAvWj80ouP +1oXoKyR4HSL0eTz4q2j+76XsQCOf24vpLyNsHiJgHiEYTGHyZiucHSPzcDTf +76ILga7qMyMwuGIArdEaQ1T7yIJwzHn2l1f6vnovHyDuTCPNHCQfMTr3oV/w +VCL5tHEHk8gArKDnJyTvUCIAruUWVW4ArLMQrlYNeKEEnNVQwm0cOkcAq4KA +0X/mHyQAqVoArKkAq4wCpeIArdvnIyT1jU4AqmQUXV3v9KikRSHP6pwwIyBH +HiHKUSLxaDTtSCMCpLpgx3PaHyTtSSy/5Zetw3b83JSVSiT0i1egMSI+qVa2 +JCMrbVbiX0Ygs2YArL2LkGApkWQLf2kSZmpFMZD0AAAAEHRSTlMAEFCAv8+v +QCBw72CP358w5xEcGAAABxJJREFUeF7lmuW/uzoMh1eKrUApbMfd9efu7u5u +193d739+gbHQBtg49x3b99U5H7asD0mTNNAoE9GobohUukmtxqDLbhoCi5nO +ICNruigWc+0BRXY80UN8ELEtQ/QWo4OGTFzRX4Y/UMy+ISqpOUi7mYmK4oPD +LKpLJ4PBzMVOZAwEdVNgje6dmZ+fX5vZ+1mhrwcwto+stTKNnRgdxH3tq0B7 +r6W4d/fEirivHR24HE48Ja47yO+NX22nujlxuDU/ialrXq9NmWUmQd7TIQZN +TX9zBCczGYCymjVrmoxyIgnrDvLJS5d3jUSa3XXr/fbU+Ayipvi2mTUMbmAe +T5AvJcCgy3P3fkbUNrTs6QWrNtAUMb+cSJBnR7B27fv4U5TBkQlaG0czKW3H +zPfiwAYvK9r/OXI1hq5hWzI5FkF/GTHPHRgp1vc/qq5GWcGpC7QnQPMR88E4 +tEdK9ctvMjQjKYAB+bxufcloXKoQM9ah4ENAllxLzFodQ1wBWos29M12e99I +Ly0sHius1cSCXF6n6J6MHD3dbh+f7Qm9O/hqSaIm9e26IXVPtdu3RnrqVLB4 +GsV37eQo0X0GgrtcZ4Nz5wXIRQB129JjSbm60A/6YrC8gjZ13aQD85UouqOu +BODKN/VqeF2A0nunxwK3E4fqOm3mU5vfpKZu0qafB/BpZASuVJVNTd4kqW03 +Mq3lEK3YsEs1AtAsK1hJvbrRF/q7IAjXcVOmK+MU2rWqKwi2m/2aR5UUSKgn +XcEdMgBkHX76ey4kFr/rPqZYtnlGyC0wA9BJ7v6hCvTGbQGyctDEQKMGIFDE +pEsaU65oVaE5lBBfsuBl0dJkQpZLiqCPj1SCDpfKoOFvnOlsQ2CZBNiQeDXo +lMhMmUHML5t2GiQHfbU9Vwn6Tpjl7yaGdgrPnzYTeRmQTLF4BWiQhm+08BAz +okbQ+ytCbwIAxdCmCuDIIY/llg7caXVoFoUR2jk+OkoZOkSCrkBfqQi9O4be +KodOQ86yKAPmzJme61gaTUOdOXIMeC5tuh4ESDXoZsN2YIhBLY0DMxg2nE5G +y7wg5Dp9sAr0xXhPb5WHd7ZmYqTM4AnPgswFaZaDIeXhkl4BGjKGlX3FYt0d +zZWdAvveU6DXWtNVoM+q0FYxNE+Auow891yEGLzzDwE76tqEXQXalqGFlrCl +zETguR18Sh7wt/ZUgD4VBMH9cmjY057clTPYamV9MM1NNWgFaKOhAArdyhm2 +c4+uXBn6Sutl+0aVLf1BGD4ob04sITC21aNP5zCNQLdIrwBtSjgY2+0Y1iV5 +6Z1Sp7/3+peshSBYDqWS1UDQcvr2NMWbfnkfbBbch97QEA24Ipo2GC6RAj3a +Gu/bnBwKguBcGKIHeaUdGSc4H2ExHN2AWh0aMgHUhOrQYu3lVJ829KOFJLpX +lEqLe2/CUTPQC1rsAJrkoUG+h3qDqtCTY9M3+tar4GEo9SYahk6kZStw+0B7 +O4C2CqBBhDIpu1aHFmNnTvbpxhJHS0dLgqDzb2bZVfa0LkOb0Eo6laGV/kPo +AM2tvJCnWxOXejF/8iiIi3T4GJjN8qU7DBbm98jeLq4sUGAlShVa2RUYG8zR +0iGHCn20NTXbj3lZcbRTBE1IZwUeLN7Lu7r7t5brIczMtKWeT90e0EQpFBYY +tvpBzxye68e8GobSCIEVBqlhEFgA1Ft00HXgfTQGjMqyGcnYvA4RgQJelL3T +O2MAKoPvpvK5XQA9P3GhR7FKmO+H4ZMlgKZF0LzbY5sAbTN1cGBzdJKC+mqb +imkDakB2IndlaGBODRAPoKna7xOanINy0GNflHefT4OUOXwmQDaGhtbCoFSX +FkYhNnRKuaG8fOhlB0DdQA+MHEhNOmRjH0MDKqdU2kiEde1SzWpylk2wlDx2 +91YZ8tdBrOcx8wN0HEbQrkDye7QKDvQVWBbQYOmovBed1j3IezkxW4U++u0B +qE0vDp0C4t3bCfKr16HKzEgBNMdrhHWVzke0wrtRco3ZBdD4tintb36+oOSx +n9KMdXEhhny0/fTFi+3tR0FHb2I3vz2Gh3758C5+y47o5WTY18xBhyW0aAyN +DXC5bGJmBP3rbEq8+ubhu403r4JMq69j5PD2deTDokRGMTOeTObHw8RUrti4 +3uNBJ4aGW4r7AV/Ho0gM/XtE/MfinY37t1fWtx6H4cbr5cVIz+/8+S6M9XYT +xxmGhlkzDGpkEQfYPI7qp9X9DuMJF56JY3t6Ism+ZaLpNjYsPNfP1+nJv/7+ +59+t891T4/X1t6GsJ5tLaN9I8q1Yvvo/eBl/EK7kL9mNIpFO+9hHZR+y8W+K +Xjq2vtIBf3J681luXFlfYc6heOV7GJkb/5d5+KCbjaGDZlZjiKChwA8RNEx1 +hwcanvIPGbThAPKQQBvQuQ4FtKeb8GrOQOg/pxLSuIDrr6oAAAAASUVORK5C +YII= + +----==_mimepart_56990c8d3f66c_7cb53ffbb98602004746e-- diff --git a/spec/fixtures/emails/no_content_reply.eml b/spec/fixtures/emails/no_content_reply.eml deleted file mode 100644 index 95eb2055ce6..00000000000 --- a/spec/fixtures/emails/no_content_reply.eml +++ /dev/null @@ -1,34 +0,0 @@ -Return-Path: -Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 -Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 -Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 -Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 -Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo -Message-ID: -Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' -Mime-Version: 1.0 -Content-Type: text/plain; - charset=ISO-8859-1 -Content-Transfer-Encoding: 7bit -X-Sieve: CMU Sieve 2.2 -X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, - 13 Jun 2013 14:03:48 -0700 (PDT) -X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 - -On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta - wrote: -> -> -> -> eviltrout posted in 'Adventure Time Sux' on Discourse Meta: -> -> --- -> hey guys everyone knows adventure time sucks! -> -> --- -> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3 -> -> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences). -> \ No newline at end of file diff --git a/spec/fixtures/emails/no_subject.eml b/spec/fixtures/emails/no_subject.eml new file mode 100644 index 00000000000..ccfd9ea599f --- /dev/null +++ b/spec/fixtures/emails/no_subject.eml @@ -0,0 +1,9 @@ +From: Some One +To: meat@bar.com +Date: Mon, 1 Feb 2016 00:12:43 +0100 +Message-ID: <40@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + +This is an email with no subject... diff --git a/spec/fixtures/emails/on_date_contact_wrote.eml b/spec/fixtures/emails/on_date_contact_wrote.eml new file mode 100644 index 00000000000..33f0527d934 --- /dev/null +++ b/spec/fixtures/emails/on_date_contact_wrote.eml @@ -0,0 +1,19 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <20@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 + +This is the actual reply. + +On Tue, Jan 14, 2016 at 0:42 AM, Bar Foo wrote: + +> This is the previous email. +> And it had +> +> a lot +> +> +> of lines ;) diff --git a/spec/fixtures/emails/on_wrote.eml b/spec/fixtures/emails/on_wrote.eml deleted file mode 100644 index feb59bd27bb..00000000000 --- a/spec/fixtures/emails/on_wrote.eml +++ /dev/null @@ -1,277 +0,0 @@ - -MIME-Version: 1.0 -Received: by 10.107.9.17 with HTTP; Tue, 9 Sep 2014 16:18:19 -0700 (PDT) -In-Reply-To: <540f16d4c08d9_4a3f9ff6d61890391c@tiefighter4-meta.mail> -References: - <540f16d4c08d9_4a3f9ff6d61890391c@tiefighter4-meta.mail> -Date: Tue, 9 Sep 2014 16:18:19 -0700 -Delivered-To: kanepyork@gmail.com -Message-ID: -Subject: Re: [Discourse Meta] Badge icons - where to find them? -From: Kane York -To: Discourse Meta -Content-Type: multipart/alternative; boundary=001a11c34c389e728f0502aa26a0 - ---001a11c34c389e728f0502aa26a0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable - -Sure, all you need to do is frobnicate the foobar and you'll be all set! - -On Tue, Sep 9, 2014 at 8:03 AM, gordon_ryan wrote: - -> gordon_ryan -> September 9 -> -> @riking - willing to step by -> step of the custom icon method for an admittedly ignorant admin? Seriousl= -y -> confused. -> -> Or anyone else who knows how to do this [image: smiley] -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/badge-icons-where-to-find-them/18058/9 in -> your browser. -> ------------------------------ -> Previous Replies riking -> July 25 -> -> Check out the "HTML Head" section in the "Content" tab of the admin panel= -. -> meglio -> July 25 -> -> How will it load the related custom font? -> riking -> July 25 -> -> Here's an example of the styles that FA applies. I'll use fa-heart"> as the example. -> -> .fa { -> display: inline-block; -> font-family: FontAwesome; -> font-style: normal; -> font-weight: normal; -> line-height: 1; -> -webkit-font-smoothing: antialiased; -> -moz-osx-font-smoothing: grayscale; -> } -> .fa-heart:before { -> content: "\f004"; -> } -> -> So you could do this in your site stylesheet: -> -> .fa-custom-burger:before { -> content: "\01f354"; -> font-family: inherit; -> } -> -> And get =F0=9F=8D=94 as your badge icon when you enter custom-burger. -> ------------------------------ -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/badge-icons-where-to-find-them/18058/9 in -> your browser. -> -> To unsubscribe from these emails, visit your user preferences -> . -> - ---001a11c34c389e728f0502aa26a0 -Content-Type: text/html; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable - -
        Sure, all you need to do is frobnicate the foobar and you'll be all s= -et!


        = -
        On Tue, Sep 9, 2014 at 8:03 AM, gordon_ryan = -<info@discourse.org> wrote:
        - - - - - - - - - - - - -
        - - - gordon_ryan
        - September 9 -
        -

        @riking- willing to step by step of the custom icon me= -thod for an admittedly ignorant admin? Seriously confused.

        - -

        Or anyone else who knows how to do this = -3D"smiley"

        -
        - - -
        -

        To respond, reply to this email or visit https:= -//meta.discourse.org/t/badge-icons-where-to-find-them/18058/9 in your b= -rowser.

        -
        -
        -

        Previous Replies

        - - - - - - - - - - - -
        - - - riking
        - July 25 -

        Check out the "HTML Head" section in the "Content&= -quot; tab of the admin panel.

        - - - - - - - - - - - -
        - - - meglio
        - July 25 -

        How will it load the related custom font?

        - - - - - - - - - - - -
        - - - riking
        - July 25 -
        -

        Here's an example of the styles that= - FA applies. I'll use <i class=3D"fa fa-heart"></i> as the e= -xample.

        - -

        -
        .fa {
        -  display: inline-block;
        -  font-family: FontAwesome;
        -  font-style: normal;
        -  font-weight: normal;
        -  line-height: 1;
        -  -webkit-font-smoothing: antialiased;
        -  -moz-osx-font-smoothing: grayscale;
        -}
        -.fa-heart:before {
        -  content: "\f004";
        -}
        - -

        So you could do this in your site styles= -heet:

        - -

        -
        .fa-custom-burger:before {
        -  content: "\01f354";
        -  font-family: inherit;
        -}
        - -

        And get =F0=9F=8D=94 as your badge icon = -when you enter cus= -tom-burger.

        -
        - - -
        - -
        -

        To respond, reply to this email or visit https://me= -ta.discourse.org/t/badge-icons-where-to-find-them/18058/9 in your brows= -er.

        -
        -
        -

        To unsubscribe from these emails, visit your user preferences.

        -
        -
        -

        - ---001a11c34c389e728f0502aa26a0-- \ No newline at end of file diff --git a/spec/fixtures/emails/original_message.eml b/spec/fixtures/emails/original_message.eml new file mode 100644 index 00000000000..8dbc5d1820c --- /dev/null +++ b/spec/fixtures/emails/original_message.eml @@ -0,0 +1,12 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <27@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 + +This is a reply :) + +---Original Message--- +This part should not be included diff --git a/spec/fixtures/emails/outlook.eml b/spec/fixtures/emails/outlook.eml deleted file mode 100644 index fb1f590a30e..00000000000 --- a/spec/fixtures/emails/outlook.eml +++ /dev/null @@ -1,188 +0,0 @@ - -MIME-Version: 1.0 -Received: by 10.25.161.144 with HTTP; Tue, 7 Oct 2014 22:17:17 -0700 (PDT) -X-Originating-IP: [117.207.85.84] -In-Reply-To: <5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail> -References: - <5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail> -Date: Wed, 8 Oct 2014 10:47:17 +0530 -Delivered-To: arpit@techapj.com -Message-ID: -Subject: Re: [Discourse] [Meta] Welcome to techAPJ's Discourse! -From: Arpit Jalan -To: Discourse Accept-Language: en-US -Content-Language: en-US -X-MS-Has-Attach: -X-MS-TNEF-Correlator: -x-originating-ip: [134.68.31.227] -Content-Type: multipart/alternative; - boundary="_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_" -MIME-Version: 1.0 - ---_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_ -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: base64 - -TWljcm9zb2Z0IE91dGxvb2sgMjAxMA0KDQpGcm9tOiBtaWNoYWVsIFttYWlsdG86dGFsa0BvcGVu -bXJzLm9yZ10NClNlbnQ6IE1vbmRheSwgT2N0b2JlciAxMywgMjAxNCA5OjM4IEFNDQpUbzogUG93 -ZXIsIENocmlzDQpTdWJqZWN0OiBbUE1dIFlvdXIgcG9zdCBpbiAiQnVyZ2VyaGF1czogTmV3IHJl -c3RhdXJhbnQgLyBsdW5jaCB2ZW51ZSINCg0KDQptaWNoYWVsPGh0dHA6Ly9jbC5vcGVubXJzLm9y -Zy90cmFjay9jbGljay8zMDAzOTkwNS90YWxrLm9wZW5tcnMub3JnP3A9ZXlKeklqb2liR2xaYTFW -MGVYaENZMDFNUlRGc1VESm1ZelZRTTBabGVqRTRJaXdpZGlJNk1Td2ljQ0k2SW50Y0luVmNJam96 -TURBek9Ua3dOU3hjSW5aY0lqb3hMRndpZFhKc1hDSTZYQ0pvZEhSd2N6cGNYRnd2WEZ4Y0wzUmhi -R3N1YjNCbGJtMXljeTV2Y21kY1hGd3ZkWE5sY25OY1hGd3ZiV2xqYUdGbGJGd2lMRndpYVdSY0lq -cGNJbVExWW1Nd04yTmtORFJqWkRRNE1HTTRZVGcyTXpsalpXSTFOemd6WW1ZMlhDSXNYQ0oxY214 -ZmFXUnpYQ0k2VzF3aVlqaGtPRGcxTWprNU56ZG1aalkxWldZeU5URTNPV1JpTkdZeU1XSTNOekZq -TnpoalpqaGtPRndpWFgwaWZRPg0KT2N0b2JlciAxMw0KDQpodHRwczovL3RhbGsub3Blbm1ycy5v -cmcvdC9idXJnZXJoYXVzLW5ldy1yZXN0YXVyYW50LWx1bmNoLXZlbnVlLzY3Mi8zPGh0dHA6Ly9j -bC5vcGVubXJzLm9yZy90cmFjay9jbGljay8zMDAzOTkwNS90YWxrLm9wZW5tcnMub3JnP3A9ZXlK -eklqb2lVRVJJU1VOeVIzbFZNRGRCVlZocFduUjNXV3g0TVdOc1RXNVpJaXdpZGlJNk1Td2ljQ0k2 -SW50Y0luVmNJam96TURBek9Ua3dOU3hjSW5aY0lqb3hMRndpZFhKc1hDSTZYQ0pvZEhSd2N6cGNY -Rnd2WEZ4Y0wzUmhiR3N1YjNCbGJtMXljeTV2Y21kY1hGd3ZkRnhjWEM5aWRYSm5aWEpvWVhWekxX -NWxkeTF5WlhOMFlYVnlZVzUwTFd4MWJtTm9MWFpsYm5WbFhGeGNMelkzTWx4Y1hDOHpYQ0lzWENK -cFpGd2lPbHdpWkRWaVl6QTNZMlEwTkdOa05EZ3dZemhoT0RZek9XTmxZalUzT0ROaVpqWmNJaXhj -SW5WeWJGOXBaSE5jSWpwYlhDSmlOelppWWprMFpURmlOekk1WlRrMlpUUmxaV000TkdSbU1qUTRN -RE13WWpZeVlXWXlNR00wWENKZGZTSjk+DQoNCkxvb2tzIGxpa2UgeW91ciByZXBseS1ieS1lbWFp -bCB3YXNuJ3QgcHJvY2Vzc2VkIGNvcnJlY3RseSBieSBvdXIgc29mdHdhcmUuIENhbiB5b3UgbGV0 -IG1lIGtub3cgd2hhdCB2ZXJzaW9uL09TIG9mIHdoYXQgZW1haWwgcHJvZ3JhbSB5b3UncmUgdXNp -bmc/IFdlIHdpbGwgd2FudCB0byB0cnkgdG8gZml4IHRoZSBidWcuIDpzbWlsZToNCg0KVGhhbmtz -IQ0KDQoNCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQoNClRvIHJlc3BvbmQsIHJl -cGx5IHRvIHRoaXMgZW1haWwgb3IgdmlzaXQgaHR0cHM6Ly90YWxrLm9wZW5tcnMub3JnL3QveW91 -ci1wb3N0LWluLWJ1cmdlcmhhdXMtbmV3LXJlc3RhdXJhbnQtbHVuY2gtdmVudWUvNjc0LzE8aHR0 -cDovL2NsLm9wZW5tcnMub3JnL3RyYWNrL2NsaWNrLzMwMDM5OTA1L3RhbGsub3Blbm1ycy5vcmc/ -cD1leUp6SWpvaWVYaDJWbnBGTUhSMU1uRm5aRWR1TlhFd01GcFFPVlp0VFZvNElpd2lkaUk2TVN3 -aWNDSTZJbnRjSW5WY0lqb3pNREF6T1Rrd05TeGNJblpjSWpveExGd2lkWEpzWENJNlhDSm9kSFJ3 -Y3pwY1hGd3ZYRnhjTDNSaGJHc3ViM0JsYm0xeWN5NXZjbWRjWEZ3dmRGeGNYQzk1YjNWeUxYQnZj -M1F0YVc0dFluVnlaMlZ5YUdGMWN5MXVaWGN0Y21WemRHRjFjbUZ1ZEMxc2RXNWphQzEyWlc1MVpW -eGNYQzgyTnpSY1hGd3ZNVndpTEZ3aWFXUmNJanBjSW1RMVltTXdOMk5rTkRSalpEUTRNR000WVRn -Mk16bGpaV0kxTnpnelltWTJYQ0lzWENKMWNteGZhV1J6WENJNlcxd2lZamMyWW1JNU5HVXhZamN5 -T1dVNU5tVTBaV1ZqT0RSa1pqSTBPREF6TUdJMk1tRm1NakJqTkZ3aVhYMGlmUT4gaW4geW91ciBi -cm93c2VyLg0KDQpUbyB1bnN1YnNjcmliZSBmcm9tIHRoZXNlIGVtYWlscywgdmlzaXQgeW91ciB1 -c2VyIHByZWZlcmVuY2VzPGh0dHA6Ly9jbC5vcGVubXJzLm9yZy90cmFjay9jbGljay8zMDAzOTkw -NS90YWxrLm9wZW5tcnMub3JnP3A9ZXlKeklqb2lkVXh1V2xnNVZGYzBPV1pXUzBZNGJGZExkbWx5 -V0dzeFRWOXpJaXdpZGlJNk1Td2ljQ0k2SW50Y0luVmNJam96TURBek9Ua3dOU3hjSW5aY0lqb3hM -RndpZFhKc1hDSTZYQ0pvZEhSd2N6cGNYRnd2WEZ4Y0wzUmhiR3N1YjNCbGJtMXljeTV2Y21kY1hG -d3ZiWGxjWEZ3dmNISmxabVZ5Wlc1alpYTmNJaXhjSW1sa1hDSTZYQ0prTldKak1EZGpaRFEwWTJR -ME9EQmpPR0U0TmpNNVkyVmlOVGM0TTJKbU5sd2lMRndpZFhKc1gybGtjMXdpT2x0Y0ltSTRNV1V3 -WmpBMU5EWTVORE0wTnpneU0yRm1NakEyTmpGalpqYzNaR05pTjJOaFl6ZG1NakpjSWwxOUluMD4u -DQoNCg== - ---_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_ -Content-Type: text/html; charset="utf-8" -Content-Transfer-Encoding: base64 - -PGh0bWwgeG1sbnM6dj0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwiIHhtbG5zOm89InVy -bjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSIgeG1sbnM6dz0idXJuOnNjaGVt -YXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6d29yZCIgeG1sbnM6bT0iaHR0cDovL3NjaGVtYXMubWlj -cm9zb2Z0LmNvbS9vZmZpY2UvMjAwNC8xMi9vbW1sIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv -VFIvUkVDLWh0bWw0MCI+DQo8aGVhZD4NCjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIg -Y29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4NCjxtZXRhIG5hbWU9IkdlbmVyYXRv -ciIgY29udGVudD0iTWljcm9zb2Z0IFdvcmQgMTQgKGZpbHRlcmVkIG1lZGl1bSkiPg0KPCEtLVtp -ZiAhbXNvXT48c3R5bGU+dlw6KiB7YmVoYXZpb3I6dXJsKCNkZWZhdWx0I1ZNTCk7fQ0Kb1w6KiB7 -YmVoYXZpb3I6dXJsKCNkZWZhdWx0I1ZNTCk7fQ0Kd1w6KiB7YmVoYXZpb3I6dXJsKCNkZWZhdWx0 -I1ZNTCk7fQ0KLnNoYXBlIHtiZWhhdmlvcjp1cmwoI2RlZmF1bHQjVk1MKTt9DQo8L3N0eWxlPjwh -W2VuZGlmXS0tPjxzdHlsZT48IS0tDQovKiBGb250IERlZmluaXRpb25zICovDQpAZm9udC1mYWNl -DQoJe2ZvbnQtZmFtaWx5OkNhbGlicmk7DQoJcGFub3NlLTE6MiAxNSA1IDIgMiAyIDQgMyAyIDQ7 -fQ0KQGZvbnQtZmFjZQ0KCXtmb250LWZhbWlseTpUYWhvbWE7DQoJcGFub3NlLTE6MiAxMSA2IDQg -MyA1IDQgNCAyIDQ7fQ0KLyogU3R5bGUgRGVmaW5pdGlvbnMgKi8NCnAuTXNvTm9ybWFsLCBsaS5N -c29Ob3JtYWwsIGRpdi5Nc29Ob3JtYWwNCgl7bWFyZ2luOjBpbjsNCgltYXJnaW4tYm90dG9tOi4w -MDAxcHQ7DQoJZm9udC1zaXplOjEyLjBwdDsNCglmb250LWZhbWlseToiVGltZXMgTmV3IFJvbWFu -Iiwic2VyaWYiO30NCmE6bGluaywgc3Bhbi5Nc29IeXBlcmxpbmsNCgl7bXNvLXN0eWxlLXByaW9y -aXR5Ojk5Ow0KCWNvbG9yOmJsdWU7DQoJdGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZTt9DQphOnZp -c2l0ZWQsIHNwYW4uTXNvSHlwZXJsaW5rRm9sbG93ZWQNCgl7bXNvLXN0eWxlLXByaW9yaXR5Ojk5 -Ow0KCWNvbG9yOnB1cnBsZTsNCgl0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lO30NCnANCgl7bXNv -LXN0eWxlLXByaW9yaXR5Ojk5Ow0KCW1zby1tYXJnaW4tdG9wLWFsdDphdXRvOw0KCW1hcmdpbi1y -aWdodDowaW47DQoJbXNvLW1hcmdpbi1ib3R0b20tYWx0OmF1dG87DQoJbWFyZ2luLWxlZnQ6MGlu -Ow0KCWZvbnQtc2l6ZToxMi4wcHQ7DQoJZm9udC1mYW1pbHk6IlRpbWVzIE5ldyBSb21hbiIsInNl -cmlmIjt9DQpzcGFuLkVtYWlsU3R5bGUxOA0KCXttc28tc3R5bGUtdHlwZTpwZXJzb25hbC1yZXBs -eTsNCglmb250LWZhbWlseToiQ2FsaWJyaSIsInNhbnMtc2VyaWYiOw0KCWNvbG9yOiMxRjQ5N0Q7 -fQ0KLk1zb0NocERlZmF1bHQNCgl7bXNvLXN0eWxlLXR5cGU6ZXhwb3J0LW9ubHk7DQoJZm9udC1m -YW1pbHk6IkNhbGlicmkiLCJzYW5zLXNlcmlmIjt9DQpAcGFnZSBXb3JkU2VjdGlvbjENCgl7c2l6 -ZTo4LjVpbiAxMS4waW47DQoJbWFyZ2luOjEuMGluIDEuMGluIDEuMGluIDEuMGluO30NCmRpdi5X -b3JkU2VjdGlvbjENCgl7cGFnZTpXb3JkU2VjdGlvbjE7fQ0KLS0+PC9zdHlsZT48IS0tW2lmIGd0 -ZSBtc28gOV0+PHhtbD4NCjxvOnNoYXBlZGVmYXVsdHMgdjpleHQ9ImVkaXQiIHNwaWRtYXg9IjEw -MjYiIC8+DQo8L3htbD48IVtlbmRpZl0tLT48IS0tW2lmIGd0ZSBtc28gOV0+PHhtbD4NCjxvOnNo -YXBlbGF5b3V0IHY6ZXh0PSJlZGl0Ij4NCjxvOmlkbWFwIHY6ZXh0PSJlZGl0IiBkYXRhPSIxIiAv -Pg0KPC9vOnNoYXBlbGF5b3V0PjwveG1sPjwhW2VuZGlmXS0tPg0KPC9oZWFkPg0KPGJvZHkgbGFu -Zz0iRU4tVVMiIGxpbms9ImJsdWUiIHZsaW5rPSJwdXJwbGUiPg0KPGRpdiBjbGFzcz0iV29yZFNl -Y3Rpb24xIj4NCjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTEu -MHB0O2ZvbnQtZmFtaWx5OiZxdW90O0NhbGlicmkmcXVvdDssJnF1b3Q7c2Fucy1zZXJpZiZxdW90 -Oztjb2xvcjojMUY0OTdEIj5NaWNyb3NvZnQgT3V0bG9vayAyMDEwPG86cD48L286cD48L3NwYW4+ -PC9wPg0KPHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMS4wcHQ7 -Zm9udC1mYW1pbHk6JnF1b3Q7Q2FsaWJyaSZxdW90OywmcXVvdDtzYW5zLXNlcmlmJnF1b3Q7O2Nv -bG9yOiMxRjQ5N0QiPjxvOnA+Jm5ic3A7PC9vOnA+PC9zcGFuPjwvcD4NCjxwIGNsYXNzPSJNc29O -b3JtYWwiPjxiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTAuMHB0O2ZvbnQtZmFtaWx5OiZxdW90 -O1RhaG9tYSZxdW90OywmcXVvdDtzYW5zLXNlcmlmJnF1b3Q7Ij5Gcm9tOjwvc3Bhbj48L2I+PHNw -YW4gc3R5bGU9ImZvbnQtc2l6ZToxMC4wcHQ7Zm9udC1mYW1pbHk6JnF1b3Q7VGFob21hJnF1b3Q7 -LCZxdW90O3NhbnMtc2VyaWYmcXVvdDsiPiBtaWNoYWVsIFttYWlsdG86dGFsa0BvcGVubXJzLm9y -Z10NCjxicj4NCjxiPlNlbnQ6PC9iPiBNb25kYXksIE9jdG9iZXIgMTMsIDIwMTQgOTozOCBBTTxi -cj4NCjxiPlRvOjwvYj4gUG93ZXIsIENocmlzPGJyPg0KPGI+U3ViamVjdDo8L2I+IFtQTV0gWW91 -ciBwb3N0IGluICZxdW90O0J1cmdlcmhhdXM6IE5ldyByZXN0YXVyYW50IC8gbHVuY2ggdmVudWUm -cXVvdDs8bzpwPjwvbzpwPjwvc3Bhbj48L3A+DQo8cCBjbGFzcz0iTXNvTm9ybWFsIj48bzpwPiZu -YnNwOzwvbzpwPjwvcD4NCjxkaXY+DQo8dGFibGUgY2xhc3M9Ik1zb05vcm1hbFRhYmxlIiBib3Jk -ZXI9IjAiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMCI+DQo8dGJvZHk+DQo8dHI+DQo8 -dGQgdmFsaWduPSJ0b3AiIHN0eWxlPSJwYWRkaW5nOjBpbiAwaW4gMGluIDBpbiI+PC90ZD4NCjx0 -ZCBzdHlsZT0icGFkZGluZzowaW4gMGluIDBpbiAwaW4iPg0KPHAgY2xhc3M9Ik1zb05vcm1hbCIg -c3R5bGU9Im1hcmdpbi1ib3R0b206MTguNzVwdCI+PGEgaHJlZj0iaHR0cDovL2NsLm9wZW5tcnMu -b3JnL3RyYWNrL2NsaWNrLzMwMDM5OTA1L3RhbGsub3Blbm1ycy5vcmc/cD1leUp6SWpvaWJHbFph -MVYwZVhoQ1kwMU1SVEZzVURKbVl6VlFNMFpsZWpFNElpd2lkaUk2TVN3aWNDSTZJbnRjSW5WY0lq -b3pNREF6T1Rrd05TeGNJblpjSWpveExGd2lkWEpzWENJNlhDSm9kSFJ3Y3pwY1hGd3ZYRnhjTDNS -aGJHc3ViM0JsYm0xeWN5NXZjbWRjWEZ3dmRYTmxjbk5jWEZ3dmJXbGphR0ZsYkZ3aUxGd2lhV1Jj -SWpwY0ltUTFZbU13TjJOa05EUmpaRFE0TUdNNFlUZzJNemxqWldJMU56Z3pZbVkyWENJc1hDSjFj -bXhmYVdSelhDSTZXMXdpWWpoa09EZzFNams1TnpkbVpqWTFaV1l5TlRFM09XUmlOR1l5TVdJM056 -RmpOemhqWmpoa09Gd2lYWDBpZlEiIHRhcmdldD0iX2JsYW5rIj48Yj48c3BhbiBzdHlsZT0iZm9u -dC1zaXplOjEwLjBwdDtmb250LWZhbWlseTomcXVvdDtUYWhvbWEmcXVvdDssJnF1b3Q7c2Fucy1z -ZXJpZiZxdW90Oztjb2xvcjojMDA2Njk5O3RleHQtZGVjb3JhdGlvbjpub25lIj5taWNoYWVsPC9z -cGFuPjwvYj48L2E+PGJyPg0KPHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTo4LjVwdDtmb250LWZhbWls -eTomcXVvdDtUYWhvbWEmcXVvdDssJnF1b3Q7c2Fucy1zZXJpZiZxdW90Oztjb2xvcjojOTk5OTk5 -Ij5PY3RvYmVyIDEzPC9zcGFuPg0KPG86cD48L286cD48L3A+DQo8L3RkPg0KPC90cj4NCjx0cj4N -Cjx0ZCBjb2xzcGFuPSIyIiBzdHlsZT0icGFkZGluZzozLjc1cHQgMGluIDBpbiAwaW4iPg0KPHAg -Y2xhc3M9Ik1zb05vcm1hbCIgc3R5bGU9Im1hcmdpbi1ib3R0b206MTguNzVwdCI+PGEgaHJlZj0i -aHR0cDovL2NsLm9wZW5tcnMub3JnL3RyYWNrL2NsaWNrLzMwMDM5OTA1L3RhbGsub3Blbm1ycy5v -cmc/cD1leUp6SWpvaVVFUklTVU55UjNsVk1EZEJWVmhwV25SM1dXeDRNV05zVFc1Wklpd2lkaUk2 -TVN3aWNDSTZJbnRjSW5WY0lqb3pNREF6T1Rrd05TeGNJblpjSWpveExGd2lkWEpzWENJNlhDSm9k -SFJ3Y3pwY1hGd3ZYRnhjTDNSaGJHc3ViM0JsYm0xeWN5NXZjbWRjWEZ3dmRGeGNYQzlpZFhKblpY -Sm9ZWFZ6TFc1bGR5MXlaWE4wWVhWeVlXNTBMV3gxYm1Ob0xYWmxiblZsWEZ4Y0x6WTNNbHhjWEM4 -elhDSXNYQ0pwWkZ3aU9sd2laRFZpWXpBM1kyUTBOR05rTkRnd1l6aGhPRFl6T1dObFlqVTNPRE5p -WmpaY0lpeGNJblZ5YkY5cFpITmNJanBiWENKaU56WmlZamswWlRGaU56STVaVGsyWlRSbFpXTTRO -R1JtTWpRNE1ETXdZall5WVdZeU1HTTBYQ0pkZlNKOSI+PGI+PHNwYW4gc3R5bGU9ImNvbG9yOiMw -MDY2OTk7dGV4dC1kZWNvcmF0aW9uOm5vbmUiPmh0dHBzOi8vdGFsay5vcGVubXJzLm9yZy90L2J1 -cmdlcmhhdXMtbmV3LXJlc3RhdXJhbnQtbHVuY2gtdmVudWUvNjcyLzM8L3NwYW4+PC9iPjwvYT4N -CjxvOnA+PC9vOnA+PC9wPg0KPHAgc3R5bGU9Im1hcmdpbi10b3A6MGluIj5Mb29rcyBsaWtlIHlv -dXIgcmVwbHktYnktZW1haWwgd2Fzbid0IHByb2Nlc3NlZCBjb3JyZWN0bHkgYnkgb3VyIHNvZnR3 -YXJlLiBDYW4geW91IGxldCBtZSBrbm93IHdoYXQgdmVyc2lvbi9PUyBvZiB3aGF0IGVtYWlsIHBy -b2dyYW0geW91J3JlIHVzaW5nPyBXZSB3aWxsIHdhbnQgdG8gdHJ5IHRvIGZpeCB0aGUgYnVnLiA6 -c21pbGU6PG86cD48L286cD48L3A+DQo8cCBzdHlsZT0ibWFyZ2luLXRvcDowaW4iPlRoYW5rcyE8 -bzpwPjwvbzpwPjwvcD4NCjwvdGQ+DQo8L3RyPg0KPC90Ym9keT4NCjwvdGFibGU+DQo8ZGl2IGNs -YXNzPSJNc29Ob3JtYWwiIGFsaWduPSJjZW50ZXIiIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+ -DQo8aHIgc2l6ZT0iMSIgd2lkdGg9IjEwMCUiIGFsaWduPSJjZW50ZXIiPg0KPC9kaXY+DQo8ZGl2 -Pg0KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiM2NjY2NjYiPlRvIHJlc3BvbmQsIHJlcGx5IHRvIHRo -aXMgZW1haWwgb3IgdmlzaXQgPGEgaHJlZj0iaHR0cDovL2NsLm9wZW5tcnMub3JnL3RyYWNrL2Ns -aWNrLzMwMDM5OTA1L3RhbGsub3Blbm1ycy5vcmc/cD1leUp6SWpvaWVYaDJWbnBGTUhSMU1uRm5a -RWR1TlhFd01GcFFPVlp0VFZvNElpd2lkaUk2TVN3aWNDSTZJbnRjSW5WY0lqb3pNREF6T1Rrd05T -eGNJblpjSWpveExGd2lkWEpzWENJNlhDSm9kSFJ3Y3pwY1hGd3ZYRnhjTDNSaGJHc3ViM0JsYm0x -eWN5NXZjbWRjWEZ3dmRGeGNYQzk1YjNWeUxYQnZjM1F0YVc0dFluVnlaMlZ5YUdGMWN5MXVaWGN0 -Y21WemRHRjFjbUZ1ZEMxc2RXNWphQzEyWlc1MVpWeGNYQzgyTnpSY1hGd3ZNVndpTEZ3aWFXUmNJ -anBjSW1RMVltTXdOMk5rTkRSalpEUTRNR000WVRnMk16bGpaV0kxTnpnelltWTJYQ0lzWENKMWNt -eGZhV1J6WENJNlcxd2lZamMyWW1JNU5HVXhZamN5T1dVNU5tVTBaV1ZqT0RSa1pqSTBPREF6TUdJ -Mk1tRm1NakJqTkZ3aVhYMGlmUSI+DQo8Yj48c3BhbiBzdHlsZT0iY29sb3I6IzAwNjY5OTt0ZXh0 -LWRlY29yYXRpb246bm9uZSI+aHR0cHM6Ly90YWxrLm9wZW5tcnMub3JnL3QveW91ci1wb3N0LWlu -LWJ1cmdlcmhhdXMtbmV3LXJlc3RhdXJhbnQtbHVuY2gtdmVudWUvNjc0LzE8L3NwYW4+PC9iPjwv -YT4gaW4geW91ciBicm93c2VyLjxvOnA+PC9vOnA+PC9zcGFuPjwvcD4NCjwvZGl2Pg0KPGRpdj4N -CjxwPjxzcGFuIHN0eWxlPSJjb2xvcjojNjY2NjY2Ij5UbyB1bnN1YnNjcmliZSBmcm9tIHRoZXNl -IGVtYWlscywgdmlzaXQgeW91ciA8YSBocmVmPSJodHRwOi8vY2wub3Blbm1ycy5vcmcvdHJhY2sv -Y2xpY2svMzAwMzk5MDUvdGFsay5vcGVubXJzLm9yZz9wPWV5SnpJam9pZFV4dVdsZzVWRmMwT1da -V1MwWTRiRmRMZG1seVdHc3hUVjl6SWl3aWRpSTZNU3dpY0NJNkludGNJblZjSWpvek1EQXpPVGt3 -TlN4Y0luWmNJam94TEZ3aWRYSnNYQ0k2WENKb2RIUndjenBjWEZ3dlhGeGNMM1JoYkdzdWIzQmxi -bTF5Y3k1dmNtZGNYRnd2YlhsY1hGd3ZjSEpsWm1WeVpXNWpaWE5jSWl4Y0ltbGtYQ0k2WENKa05X -SmpNRGRqWkRRMFkyUTBPREJqT0dFNE5qTTVZMlZpTlRjNE0ySm1ObHdpTEZ3aWRYSnNYMmxrYzF3 -aU9sdGNJbUk0TVdVd1pqQTFORFk1TkRNME56Z3lNMkZtTWpBMk5qRmpaamMzWkdOaU4yTmhZemRt -TWpKY0lsMTlJbjAiPg0KPGI+PHNwYW4gc3R5bGU9ImNvbG9yOiMwMDY2OTk7dGV4dC1kZWNvcmF0 -aW9uOm5vbmUiPnVzZXIgcHJlZmVyZW5jZXM8L3NwYW4+PC9iPjwvYT4uPG86cD48L286cD48L3Nw -YW4+PC9wPg0KPC9kaXY+DQo8L2Rpdj4NCjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxpbWcgYm9yZGVy -PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBpZD0iX3gwMDAwX2kxMDI2IiBzcmM9Imh0dHA6Ly9j -bC5vcGVubXJzLm9yZy90cmFjay9vcGVuLnBocD91PTMwMDM5OTA1JmFtcDtpZD1kNWJjMDdjZDQ0 -Y2Q0ODBjOGE4NjM5Y2ViNTc4M2JmNiI+PG86cD48L286cD48L3A+DQo8L2Rpdj4NCjwvYm9keT4N -CjwvaHRtbD4NCg== - ---_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_-- diff --git a/spec/fixtures/emails/paragraphs.cooked b/spec/fixtures/emails/paragraphs.cooked deleted file mode 100644 index da83260e09c..00000000000 --- a/spec/fixtures/emails/paragraphs.cooked +++ /dev/null @@ -1,7 +0,0 @@ -

        Is there any reason the old candy can't be be kept in silos while the new candy -is imported into new silos?

        - -

        The thing about candy is it stays delicious for a long time -- we can just keep -it there without worrying about it too much, imo.

        - -

        Thanks for listening.

        \ No newline at end of file diff --git a/spec/fixtures/emails/paragraphs.eml b/spec/fixtures/emails/paragraphs.eml index 2d5b5283f7e..7fb2bd3733e 100644 --- a/spec/fixtures/emails/paragraphs.eml +++ b/spec/fixtures/emails/paragraphs.eml @@ -1,42 +1,12 @@ -Return-Path: -Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 -Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 -Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 -Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 -Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo -Message-ID: -Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <22@foo.bar.mail> Mime-Version: 1.0 -Content-Type: text/plain; - charset=ISO-8859-1 -Content-Transfer-Encoding: 7bit -X-Sieve: CMU Sieve 2.2 -X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, - 13 Jun 2013 14:03:48 -0700 (PDT) -X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 +Content-Type: text/plain; charset=UTF-8 -Is there any reason the *old* candy can't be be kept in silos while the new candy -is imported into *new* silos? +Do you like liquorice? -The thing about candy is it stays delicious for a long time -- we can just keep -it there without worrying about it too much, imo. - -Thanks for listening. - -On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta - wrote: -> -> -> -> eviltrout posted in 'Adventure Time Sux' on Discourse Meta: -> -> --- -> hey guys everyone knows adventure time sucks! -> -> --- -> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3 -> -> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences). -> +I really like them. One could even say that I am *addicted* to liquorice. Anf if +you can mix it up with some anise, then I'm in heaven ;) diff --git a/spec/fixtures/emails/previous.eml b/spec/fixtures/emails/previous.eml deleted file mode 100644 index 24ac5a63deb..00000000000 --- a/spec/fixtures/emails/previous.eml +++ /dev/null @@ -1,38 +0,0 @@ - -Delivered-To: discourse-reply+cd480e301683c9902891f15968bf07a5@discourse.org -Received: by 10.194.216.104 with SMTP id op8csp80593wjc; - Wed, 24 Jul 2013 07:59:14 -0700 (PDT) -Return-Path: -References: <51efeb9b36c34_66dc2dfce6811866@discourse.mail> -From: Walter White -In-Reply-To: <51efeb9b36c34_66dc2dfce6811866@discourse.mail> -Mime-Version: 1.0 (1.0) -Date: Wed, 24 Jul 2013 15:59:10 +0100 -Message-ID: <4597127794206131679@unknownmsgid> -Subject: Re: [Discourse] new reply to your post in 'Crystal Blue' -To: walter via Discourse -Content-Type: multipart/alternative; boundary=001a11c20edc15a39304e2432790 - -This will not include the previous discussion that is present in this email. - ------------------------------ -Previous discussion -skylerwhite July 24 - -This is a reply. - fring July 24 - -This is an older reply. - hank_schrader July 24 - -Of course another reply here. - walterwhite July 24 - - ------------------------------ - -To respond, reply to this email or visit -http://discourse.org/t/crystal-blue/5043/10in -your browser. - -To unsubscribe from these emails, visit your user -preferences -. diff --git a/spec/fixtures/emails/previous_replies.eml b/spec/fixtures/emails/previous_replies.eml index 3fd74482c07..441f90cc596 100644 --- a/spec/fixtures/emails/previous_replies.eml +++ b/spec/fixtures/emails/previous_replies.eml @@ -1,180 +1,23 @@ -Delivered-To: reply@discourse.org -MIME-Version: 1.0 -In-Reply-To: -References: - -Date: Fri, 28 Nov 2014 12:55:32 -0800 -Subject: Re: [Discourse Meta] [Lounge] Testing default email replies -From: Walter White -To: Discourse Meta -Content-Type: multipart/alternative; boundary=001a1137c9285318bb0508f17bc5 - ---001a1137c9285318bb0508f17bc5 +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <21@foo.bar.mail> +Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 -### this is a reply from iOS Gmail app +This will not include the previous discussion that is present in this email. -The quick brown fox jumps over the lazy dog. The quick brown fox jumps over -the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown -fox jumps over the lazy dog. The quick brown fox jumps over the lazy -dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps -over the lazy dog. +--- +*Previous Replies* -This is **bold** text in Markdown. +This is previous reply #1. -This is a link to http://example.com +Posted by foo bar on 01/15/2016 -On Friday, November 28, 2014, Arpit Jalan wrote: +--- +[Visit the Topic](https://bar.com/t/wat/1/1) to respond -> techAPJ -> November 28 -> -> Test reply. -> -> First paragraph. -> -> Second paragraph. -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in -> your browser. -> ------------------------------ -> Previous Replies codinghorror -> -> November 28 -> -> We're testing the latest GitHub email processing library which we are -> integrating now. -> -> https://github.com/github/email_reply_parser -> -> Go ahead and reply to this topic and I'll reply from various email clients -> for testing. -> ------------------------------ -> -> To respond, reply to this email or visit -> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in -> your browser. -> -> To unsubscribe from these emails, visit your user preferences -> . -> - ---001a1137c9285318bb0508f17bc5 -Content-Type: text/html; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable - -### this is a reply from iOS Gmail app

        The quick brown f= -ox jumps over the lazy dog.=C2=A0The quick brown fox jumps over the lazy dog.=C2=A0The quic= -k brown fox jumps over the lazy dog.=C2=A0The quick brown fox jumps over th= -e lazy dog.=C2=A0The quick brown fox jumps over the lazy dog.=C2=A0The quic= -k brown fox jumps over the lazy dog.=C2=A0The quick brown fox jumps over th= -e lazy dog.=C2=A0

        This is **bold** text in Markdown.

        This is a link to http://example.com

        On Friday, November 28, 2014, Arpit Jalan <
        info@discourse.org> wrote:
        - - - - - - - - - - - -
        - - - techAPJ
        - November 28 -
        -

        Test reply.

        - -

        First paragraph.

        - -

        Second paragraph.

        -
        - - -
        -

        To respond, reply to this email or visit https:/= -/meta.discourse.org/t/testing-default-email-replies/22638/3 in your bro= -wser.

        -
        -
        -

        Previous Replies

        - - - - - - - - - - - -
        - - - codinghorror - November 28 -
        -

        We're testing the latest GitHub emai= -l processing library which we are integrating now.

        - -

        https://github.com/github/email_reply_parser

        - -

        Go ahead and reply to this topic and I&#= -39;ll reply from various email clients for testing.

        -
        - - -
        - -
        -

        To respond, reply to this email or visit https://met= -a.discourse.org/t/testing-default-email-replies/22638/3 in your browser= -.

        -
        -
        -

        To unsubscribe from these emails, visit your user preferences.

        -
        -
        -
    - ---001a1137c9285318bb0508f17bc5-- +To stop receiving notifications for this particular topic, [click here](h= +ttps://bar.com/t/wat/1/unsubscribe). To unsubscribe from these emails, ch= +ange your [user preferences](https://bar.com/my/preferences). diff --git a/spec/fixtures/emails/readonly.eml b/spec/fixtures/emails/readonly.eml new file mode 100644 index 00000000000..7572bff6685 --- /dev/null +++ b/spec/fixtures/emails/readonly.eml @@ -0,0 +1,11 @@ +Return-Path: +From: Foo Bar +To: category@bar.com +Subject: This is a topic from a restricted user +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <33@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + +Hey, this is a topic from a restricted user ;) diff --git a/spec/fixtures/emails/reply_user_matching.eml b/spec/fixtures/emails/reply_user_matching.eml new file mode 100644 index 00000000000..caead84676e --- /dev/null +++ b/spec/fixtures/emails/reply_user_matching.eml @@ -0,0 +1,10 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <11@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. diff --git a/spec/fixtures/emails/reply_user_not_matching.eml b/spec/fixtures/emails/reply_user_not_matching.eml new file mode 100644 index 00000000000..c6523f966e4 --- /dev/null +++ b/spec/fixtures/emails/reply_user_not_matching.eml @@ -0,0 +1,10 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <10@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. diff --git a/spec/fixtures/emails/reply_with_weird_encoding.eml b/spec/fixtures/emails/reply_with_weird_encoding.eml new file mode 100644 index 00000000000..c764584e802 --- /dev/null +++ b/spec/fixtures/emails/reply_with_weird_encoding.eml @@ -0,0 +1,9 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <42@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; charset=unicode-1-1-utf-7 + +This is a reply with a weird encoding. diff --git a/spec/fixtures/emails/staged_sender.eml b/spec/fixtures/emails/staged_sender.eml new file mode 100644 index 00000000000..e7828e9146e --- /dev/null +++ b/spec/fixtures/emails/staged_sender.eml @@ -0,0 +1,9 @@ +Return-Path: +From: Foo Bar +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <39@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. diff --git a/spec/fixtures/emails/text_and_html_reply.eml b/spec/fixtures/emails/text_and_html_reply.eml new file mode 100644 index 00000000000..5fb87780abe --- /dev/null +++ b/spec/fixtures/emails/text_and_html_reply.eml @@ -0,0 +1,19 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <19@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: multipart/alternative; boundary=001a11469b1296cf8d052963bde5 + +--001a11469b1296cf8d052963bde5 +Content-Type: text/plain; charset=UTF-8 + +This is the *text* part. + +--001a11469b1296cf8d052963bde5 +Content-Type: text/html; charset=UTF-8 + +
    This is the html part.
    + +--001a11469b1296cf8d052963bde5-- diff --git a/spec/fixtures/emails/text_reply.eml b/spec/fixtures/emails/text_reply.eml new file mode 100644 index 00000000000..1d295a3f233 --- /dev/null +++ b/spec/fixtures/emails/text_reply.eml @@ -0,0 +1,10 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <15@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +This is a text reply :) diff --git a/spec/fixtures/emails/too_many_mentions.eml b/spec/fixtures/emails/too_many_mentions.eml index 9cc7b75c94f..6940955f9cf 100644 --- a/spec/fixtures/emails/too_many_mentions.eml +++ b/spec/fixtures/emails/too_many_mentions.eml @@ -1,31 +1,10 @@ -Return-Path: -Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 -Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 -Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 -Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 -Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: reply+636ca428858779856c226bb145ef4fad@appmail.adventuretime.ooo -Message-ID: -Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <14@foo.bar.mail> Mime-Version: 1.0 -Content-Type: text/plain; - charset=ISO-8859-1 +Content-Type: text/plain Content-Transfer-Encoding: 7bit -X-Sieve: CMU Sieve 2.2 -X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, - 13 Jun 2013 14:03:48 -0700 (PDT) -X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 - -@user1 -@user2 -@user3 -@user4 -@user5 -@user6 -@user7 -@user8 -@user9 -@user10 -@user11 \ No newline at end of file +@user1 @user2 diff --git a/spec/fixtures/emails/too_short.eml b/spec/fixtures/emails/too_short.eml deleted file mode 100644 index 54fed0f98c5..00000000000 --- a/spec/fixtures/emails/too_short.eml +++ /dev/null @@ -1,21 +0,0 @@ -Return-Path: -Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 -Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 -Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 -Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 -Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: TO -Message-ID: -Subject: SUBJECT -Mime-Version: 1.0 -Content-Type: text/plain; - charset=ISO-8859-1 -Content-Transfer-Encoding: 7bit -X-Sieve: CMU Sieve 2.2 -X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, - 13 Jun 2013 14:03:48 -0700 (PDT) -X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 - - -+1 \ No newline at end of file diff --git a/spec/fixtures/emails/too_small.eml b/spec/fixtures/emails/too_small.eml new file mode 100644 index 00000000000..fbc5c8d8853 --- /dev/null +++ b/spec/fixtures/emails/too_small.eml @@ -0,0 +1,10 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <12@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Ok! diff --git a/spec/fixtures/emails/unsubscribe_body.eml b/spec/fixtures/emails/unsubscribe_body.eml new file mode 100644 index 00000000000..1ae876edbdb --- /dev/null +++ b/spec/fixtures/emails/unsubscribe_body.eml @@ -0,0 +1,10 @@ +Return-Path: +From: Foo Bar +To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com +Date: Thu, 13 Jun 2013 17:03:48 -0400 +Message-ID: <55@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain; +Content-Transfer-Encoding: 7bit + +UNSUBSCRIBE diff --git a/spec/fixtures/emails/unsubscribe_subject.eml b/spec/fixtures/emails/unsubscribe_subject.eml new file mode 100644 index 00000000000..84b89079bf3 --- /dev/null +++ b/spec/fixtures/emails/unsubscribe_subject.eml @@ -0,0 +1,11 @@ +Return-Path: +From: Foo Bar +To: reply@bar.com +Date: Thu, 13 Jun 2013 17:03:48 -0400 +Message-ID: <56@foo.bar.mail> +Subject: UnSuBScRiBe +Mime-Version: 1.0 +Content-Type: text/plain; +Content-Transfer-Encoding: 7bit + +I've basically had enough of your mailing list and would very much like it if you went away. diff --git a/spec/fixtures/emails/user_not_found.eml b/spec/fixtures/emails/user_not_found.eml new file mode 100644 index 00000000000..b2863e5d0c1 --- /dev/null +++ b/spec/fixtures/emails/user_not_found.eml @@ -0,0 +1,9 @@ +Return-Path: +From: Not Found +Date: Fri, 15 Jan 2016 00:12:43 +0100 +Message-ID: <50@foo.bar.mail> +Mime-Version: 1.0 +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +Email from an unknown user. diff --git a/spec/fixtures/emails/valid_incoming.cooked b/spec/fixtures/emails/valid_incoming.cooked deleted file mode 100644 index 2bf35825373..00000000000 --- a/spec/fixtures/emails/valid_incoming.cooked +++ /dev/null @@ -1,5 +0,0 @@ -

    Hey folks,

    - -

    I was thinking. Wouldn't it be great if we could post topics via email? Yes it would!

    - -

    Jakie

    diff --git a/spec/fixtures/emails/valid_incoming.eml b/spec/fixtures/emails/valid_incoming.eml deleted file mode 100644 index 5e8db53319e..00000000000 --- a/spec/fixtures/emails/valid_incoming.eml +++ /dev/null @@ -1,25 +0,0 @@ -Return-Path: -Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 -Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 -Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 -Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 -Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: -Message-ID: -Subject: We should have a post-by-email-feature. -Mime-Version: 1.0 -Content-Type: text/plain; - charset=ISO-8859-1 -Content-Transfer-Encoding: 7bit -X-Sieve: CMU Sieve 2.2 -X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, - 13 Jun 2013 14:03:48 -0700 (PDT) -X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 - -Hey folks, - -I was thinking. Wouldn't it be great if we could post topics via email? Yes it would! - -Jakie - diff --git a/spec/fixtures/emails/valid_reply.cooked b/spec/fixtures/emails/valid_reply.cooked deleted file mode 100644 index 4bce79ad12a..00000000000 --- a/spec/fixtures/emails/valid_reply.cooked +++ /dev/null @@ -1,4 +0,0 @@ -

    I could not disagree more. I am obviously biased but adventure time is the -greatest show ever created. Everyone should watch it.

    - -
    • Jake out
    diff --git a/spec/fixtures/emails/valid_reply.eml b/spec/fixtures/emails/valid_reply.eml deleted file mode 100644 index 1e696389954..00000000000 --- a/spec/fixtures/emails/valid_reply.eml +++ /dev/null @@ -1,40 +0,0 @@ -Return-Path: -Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 -Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 -Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 -Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 -Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo -Message-ID: -Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' -Mime-Version: 1.0 -Content-Type: text/plain; - charset=ISO-8859-1 -Content-Transfer-Encoding: 7bit -X-Sieve: CMU Sieve 2.2 -X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, - 13 Jun 2013 14:03:48 -0700 (PDT) -X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 - -I could not disagree more. I am obviously biased but adventure time is the -greatest show ever created. Everyone should watch it. - -- Jake out - - -On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta - wrote: -> -> -> -> eviltrout posted in 'Adventure Time Sux' on Discourse Meta: -> -> --- -> hey guys everyone knows adventure time sucks! -> -> --- -> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3 -> -> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences). -> \ No newline at end of file diff --git a/spec/fixtures/emails/via_line.eml b/spec/fixtures/emails/via_line.eml deleted file mode 100644 index 0b2947ff954..00000000000 --- a/spec/fixtures/emails/via_line.eml +++ /dev/null @@ -1,25 +0,0 @@ - -Delivered-To: discourse-reply+cd480e301683c9902891f15968bf07a5@discourse.org -Received: by 10.194.216.104 with SMTP id op8csp80593wjc; - Wed, 24 Jul 2013 07:59:14 -0700 (PDT) -Return-Path: -References: <51efeb9b36c34_66dc2dfce6811866@discourse.mail> -From: Walter White -In-Reply-To: <51efeb9b36c34_66dc2dfce6811866@discourse.mail> -Mime-Version: 1.0 (1.0) -Date: Wed, 24 Jul 2013 15:59:10 +0100 -Message-ID: <4597127794206131679@unknownmsgid> -Subject: Re: [Discourse] new reply to your post in 'Crystal Blue' -To: walter via Discourse -Content-Type: multipart/alternative; boundary=001a11c20edc15a39304e2432790 - -Hello this email has content! - -codinghorror via Discourse wrote: -> [codinghorror] codinghorror -> -> August 7 -> -> It wouldn't be great at the moment for 100% email, since there's no -> way to be notified of new topics via email. (you can get notified of -> new replies to your posts and topics via email, and reply to them.) diff --git a/spec/fixtures/emails/windows_8_metro.eml b/spec/fixtures/emails/windows_8_metro.eml deleted file mode 100644 index 67d204af562..00000000000 --- a/spec/fixtures/emails/windows_8_metro.eml +++ /dev/null @@ -1,173 +0,0 @@ -Delivered-To: reply@discourse.org -Return-Path: -MIME-Version: 1.0 -From: -To: - =?utf-8?Q?Discourse_Meta?= - -Subject: - =?utf-8?Q?Re:_[Discourse_Meta]_[Lounge]_Testing_default_email_replies?= -Importance: Normal -Date: Fri, 28 Nov 2014 21:29:10 +0000 -In-Reply-To: -References: - , -Content-Type: multipart/alternative; - boundary="_866E2678-BB4F-4DD8-BE18-81B04AD8D1BC_" - ---_866E2678-BB4F-4DD8-BE18-81B04AD8D1BC_ -Content-Transfer-Encoding: base64 -Content-Type: text/plain; charset="utf-8" - -IyMjIHJlcGx5IGZyb20gZGVmYXVsdCBtYWlsIGNsaWVudCBpbiBXaW5kb3dzIDguMSBNZXRybw0K -DQoNClRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWlj -ayBicm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gg -anVtcHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0 -aGUgbGF6eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2cu -IFRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWljayBi -cm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gganVt -cHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUg -bGF6eSBkb2cuDQoNCg0KVGhpcyBpcyBhICoqYm9sZCoqIHdvcmQgaW4gTWFya2Rvd24NCg0KDQpU -aGlzIGlzIGEgbGluayBodHRwOi8vZXhhbXBsZS5jb20NCiANCg0KDQoNCg0KDQpGcm9tOiBBcnBp -dCBKYWxhbg0KU2VudDog4oCORnJpZGF54oCOLCDigI5Ob3ZlbWJlcuKAjiDigI4yOOKAjiwg4oCO -MjAxNCDigI4xMuKAjjrigI4zNeKAjiDigI5QTQ0KVG86IGplZmYgYXR3b29kDQoNCg0KDQoNCg0K -DQogdGVjaEFQSg0KTm92ZW1iZXIgMjggDQoNClRlc3QgcmVwbHkuDQoNCkZpcnN0IHBhcmFncmFw -aC4NCg0KU2Vjb25kIHBhcmFncmFwaC4NCg0KDQoNClRvIHJlc3BvbmQsIHJlcGx5IHRvIHRoaXMg -ZW1haWwgb3IgdmlzaXQgaHR0cHM6Ly9tZXRhLmRpc2NvdXJzZS5vcmcvdC90ZXN0aW5nLWRlZmF1 -bHQtZW1haWwtcmVwbGllcy8yMjYzOC8zIGluIHlvdXIgYnJvd3Nlci4NCg0KDQoNClByZXZpb3Vz -IFJlcGxpZXMNCg0KIGNvZGluZ2hvcnJvcg0KTm92ZW1iZXIgMjggDQoNCldlJ3JlIHRlc3Rpbmcg -dGhlIGxhdGVzdCBHaXRIdWIgZW1haWwgcHJvY2Vzc2luZyBsaWJyYXJ5IHdoaWNoIHdlIGFyZSBp -bnRlZ3JhdGluZyBub3cuDQoNCmh0dHBzOi8vZ2l0aHViLmNvbS9naXRodWIvZW1haWxfcmVwbHlf -cGFyc2VyDQoNCkdvIGFoZWFkIGFuZCByZXBseSB0byB0aGlzIHRvcGljIGFuZCBJJ2xsIHJlcGx5 -IGZyb20gdmFyaW91cyBlbWFpbCBjbGllbnRzIGZvciB0ZXN0aW5nLg0KDQoNCg0KDQoNClRvIHJl -c3BvbmQsIHJlcGx5IHRvIHRoaXMgZW1haWwgb3IgdmlzaXQgaHR0cHM6Ly9tZXRhLmRpc2NvdXJz -ZS5vcmcvdC90ZXN0aW5nLWRlZmF1bHQtZW1haWwtcmVwbGllcy8yMjYzOC8zIGluIHlvdXIgYnJv -d3Nlci4NCg0KDQpUbyB1bnN1YnNjcmliZSBmcm9tIHRoZXNlIGVtYWlscywgdmlzaXQgeW91ciB1 -c2VyIHByZWZlcmVuY2VzLg== - ---_866E2678-BB4F-4DD8-BE18-81B04AD8D1BC_ -Content-Transfer-Encoding: base64 -Content-Type: text/html; charset="utf-8" - -CjxodG1sPgo8aGVhZD4KPG1ldGEgbmFtZT0iZ2VuZXJhdG9yIiBjb250ZW50PSJXaW5kb3dzIE1h -aWwgMTcuNS45NjAwLjIwNjA1Ij4KPHN0eWxlIGRhdGEtZXh0ZXJuYWxzdHlsZT0idHJ1ZSI+PCEt -LQpwLk1zb0xpc3RQYXJhZ3JhcGgsIGxpLk1zb0xpc3RQYXJhZ3JhcGgsIGRpdi5Nc29MaXN0UGFy -YWdyYXBoIHsKbWFyZ2luLXRvcDowaW47Cm1hcmdpbi1yaWdodDowaW47Cm1hcmdpbi1ib3R0b206 -MGluOwptYXJnaW4tbGVmdDouNWluOwptYXJnaW4tYm90dG9tOi4wMDAxcHQ7Cn0KcC5Nc29Ob3Jt -YWwsIGxpLk1zb05vcm1hbCwgZGl2Lk1zb05vcm1hbCB7Cm1hcmdpbjowaW47Cm1hcmdpbi1ib3R0 -b206LjAwMDFwdDsKfQpwLk1zb0xpc3RQYXJhZ3JhcGhDeFNwRmlyc3QsIGxpLk1zb0xpc3RQYXJh -Z3JhcGhDeFNwRmlyc3QsIGRpdi5Nc29MaXN0UGFyYWdyYXBoQ3hTcEZpcnN0LCAKcC5Nc29MaXN0 -UGFyYWdyYXBoQ3hTcE1pZGRsZSwgbGkuTXNvTGlzdFBhcmFncmFwaEN4U3BNaWRkbGUsIGRpdi5N -c29MaXN0UGFyYWdyYXBoQ3hTcE1pZGRsZSwgCnAuTXNvTGlzdFBhcmFncmFwaEN4U3BMYXN0LCBs -aS5Nc29MaXN0UGFyYWdyYXBoQ3hTcExhc3QsIGRpdi5Nc29MaXN0UGFyYWdyYXBoQ3hTcExhc3Qg -ewptYXJnaW4tdG9wOjBpbjsKbWFyZ2luLXJpZ2h0OjBpbjsKbWFyZ2luLWJvdHRvbTowaW47Cm1h -cmdpbi1sZWZ0Oi41aW47Cm1hcmdpbi1ib3R0b206LjAwMDFwdDsKbGluZS1oZWlnaHQ6MTE1JTsK -fQotLT48L3N0eWxlPjwvaGVhZD4KPGJvZHkgZGlyPSJsdHIiPgo8ZGl2IGRhdGEtZXh0ZXJuYWxz -dHlsZT0iZmFsc2UiIGRpcj0ibHRyIiBzdHlsZT0iZm9udC1mYW1pbHk6ICdDYWxpYnJpJywgJ1Nl -Z29lIFVJJywgJ01laXJ5bycsICdNaWNyb3NvZnQgWWFIZWkgVUknLCAnTWljcm9zb2Z0IEpoZW5n -SGVpIFVJJywgJ01hbGd1biBHb3RoaWMnLCAnc2Fucy1zZXJpZic7Zm9udC1zaXplOjEycHQ7Ij48 -ZGl2IHN0eWxlPSJmb250LXNpemU6IDE0cHQ7Ij4jIyMgcmVwbHkgZnJvbSBkZWZhdWx0IG1haWwg -Y2xpZW50IGluIFdpbmRvd3MgOC4xIE1ldHJvPC9kaXY+PGRpdiBzdHlsZT0iZm9udC1zaXplOiAx -NHB0OyI+PGJyPjwvZGl2PjxkaXYgc3R5bGU9ImZvbnQtc2l6ZTogMTRwdDsiPlRoZSBxdWljayBi -cm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gganVt -cHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUg -bGF6eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRo -ZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWljayBicm93 -biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gganVtcHMg -b3ZlciB0aGUgbGF6eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6 -eSBkb2cuIFRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBkb2cuPC9kaXY+ -PGRpdiBzdHlsZT0iZm9udC1zaXplOiAxNHB0OyI+PGJyPjwvZGl2PjxkaXYgc3R5bGU9ImZvbnQt -c2l6ZTogMTRwdDsiPlRoaXMgaXMgYSAqKmJvbGQqKiB3b3JkIGluIE1hcmtkb3duPC9kaXY+PGRp -diBzdHlsZT0iZm9udC1zaXplOiAxNHB0OyI+PGJyPjwvZGl2PjxkaXYgc3R5bGU9ImZvbnQtc2l6 -ZTogMTRwdDsiPlRoaXMgaXMgYSBsaW5rIDxhIGhyZWY9Imh0dHA6Ly9leGFtcGxlLmNvbSI+aHR0 -cDovL2V4YW1wbGUuY29tPC9hPjxicj4mbmJzcDs8L2Rpdj48ZGl2IHN0eWxlPSJmb250LXNpemU6 -IDE0cHQ7Ij48YnI+PC9kaXY+PGRpdiBzdHlsZT0icGFkZGluZy10b3A6IDVweDsgYm9yZGVyLXRv -cC1jb2xvcjogcmdiKDIyOSwgMjI5LCAyMjkpOyBib3JkZXItdG9wLXdpZHRoOiAxcHg7IGJvcmRl -ci10b3Atc3R5bGU6IHNvbGlkOyI+PGRpdj48Zm9udCBmYWNlPSIgJ0NhbGlicmknLCAnU2Vnb2Ug -VUknLCAnTWVpcnlvJywgJ01pY3Jvc29mdCBZYUhlaSBVSScsICdNaWNyb3NvZnQgSmhlbmdIZWkg -VUknLCAnTWFsZ3VuIEdvdGhpYycsICdzYW5zLXNlcmlmJyIgc3R5bGU9J2xpbmUtaGVpZ2h0OiAx -NXB0OyBsZXR0ZXItc3BhY2luZzogMC4wMmVtOyBmb250LWZhbWlseTogIkNhbGlicmkiLCAiU2Vn -b2UgVUkiLCAiTWVpcnlvIiwgIk1pY3Jvc29mdCBZYUhlaSBVSSIsICJNaWNyb3NvZnQgSmhlbmdI -ZWkgVUkiLCAiTWFsZ3VuIEdvdGhpYyIsICJzYW5zLXNlcmlmIjsgZm9udC1zaXplOiAxMnB0Oyc+ -PGI+RnJvbTo8L2I+Jm5ic3A7PGEgaHJlZj0ibWFpbHRvOmluZm9AZGlzY291cnNlLm9yZyIgdGFy -Z2V0PSJfcGFyZW50Ij5BcnBpdCBKYWxhbjwvYT48YnI+PGI+U2VudDo8L2I+Jm5ic3A74oCORnJp -ZGF54oCOLCDigI5Ob3ZlbWJlcuKAjiDigI4yOOKAjiwg4oCOMjAxNCDigI4xMuKAjjrigI4zNeKA -jiDigI5QTTxicj48Yj5Ubzo8L2I+Jm5ic3A7PGEgaHJlZj0ibWFpbHRvOmphdHdvb2RAY29kaW5n -aG9ycm9yLmNvbSIgdGFyZ2V0PSJfcGFyZW50Ij5qZWZmIGF0d29vZDwvYT48L2ZvbnQ+PC9kaXY+ -PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdiBkaXI9IiI+PGRpdj4KCjx0YWJsZSB0YWJpbmRleD0i -LTEiIHN0eWxlPSJtYXJnaW4tYm90dG9tOiAyNXB4OyIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0i -MCIgY2VsbHBhZGRpbmc9IjAiPgogIDx0Ym9keT4KICAgIDx0cj4KICAgICAgPHRkIHN0eWxlPSJ3 -aWR0aDogNTVweDsgdmVydGljYWwtYWxpZ246IHRvcDsiPgogICAgICAgIDxpbWcgd2lkdGg9IjQ1 -IiBoZWlnaHQ9IjQ1IiB0YWJpbmRleD0iLTEiIHN0eWxlPSJtYXgtd2lkdGg6IDEwMCU7IiBzcmM9 -Imh0dHBzOi8vbWV0YS1kaXNjb3Vyc2UuZ2xvYmFsLnNzbC5mYXN0bHkubmV0L3VzZXJfYXZhdGFy -L21ldGEuZGlzY291cnNlLm9yZy90ZWNoYXBqLzQ1LzMyODEucG5nIiBkYXRhLW1zLWltZ3NyYz0i -aHR0cHM6Ly9tZXRhLWRpc2NvdXJzZS5nbG9iYWwuc3NsLmZhc3RseS5uZXQvdXNlcl9hdmF0YXIv -bWV0YS5kaXNjb3Vyc2Uub3JnL3RlY2hhcGovNDUvMzI4MS5wbmciPgogICAgICA8L3RkPgogICAg -ICA8dGQ+CiAgICAgICAgPGEgc3R5bGU9J2NvbG9yOiByZ2IoNTksIDg5LCAxNTIpOyBmb250LWZh -bWlseTogImx1Y2lkYSBncmFuZGUiLHRhaG9tYSx2ZXJkYW5hLGFyaWFsLHNhbnMtc2VyaWY7IGZv -bnQtc2l6ZTogMTNweDsgZm9udC13ZWlnaHQ6IGJvbGQ7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsn -IGhyZWY9Imh0dHBzOi8vbWV0YS5kaXNjb3Vyc2Uub3JnL3VzZXJzL3RlY2hhcGoiIHRhcmdldD0i -X3BhcmVudCI+dGVjaEFQSjwvYT48YnI+CiAgICAgICAgPHNwYW4gc3R5bGU9J3RleHQtYWxpZ246 -IHJpZ2h0OyBjb2xvcjogcmdiKDE1MywgMTUzLCAxNTMpOyBwYWRkaW5nLXJpZ2h0OiA1cHg7IGZv -bnQtZmFtaWx5OiAibHVjaWRhIGdyYW5kZSIsdGFob21hLHZlcmRhbmEsYXJpYWwsc2Fucy1zZXJp -ZjsgZm9udC1zaXplOiAxMXB4Oyc+Tm92ZW1iZXIgMjg8L3NwYW4+CiAgICAgIDwvdGQ+CiAgICA8 -L3RyPgogICAgPHRyPgogICAgICA8dGQgc3R5bGU9InBhZGRpbmctdG9wOiA1cHg7IiBjb2xzcGFu -PSIyIj4KPHAgc3R5bGU9ImJvcmRlcjogMHB4IGJsYWNrOyBib3JkZXItaW1hZ2U6IG5vbmU7IG1h -cmdpbi10b3A6IDBweDsiPlRlc3QgcmVwbHkuPC9wPgoKPHAgc3R5bGU9ImJvcmRlcjogMHB4IGJs -YWNrOyBib3JkZXItaW1hZ2U6IG5vbmU7IG1hcmdpbi10b3A6IDBweDsiPkZpcnN0IHBhcmFncmFw -aC48L3A+Cgo8cCBzdHlsZT0iYm9yZGVyOiAwcHggYmxhY2s7IGJvcmRlci1pbWFnZTogbm9uZTsg -bWFyZ2luLXRvcDogMHB4OyI+U2Vjb25kIHBhcmFncmFwaC48L3A+CjwvdGQ+CiAgICA8L3RyPgog -IDwvdGJvZHk+CjwvdGFibGU+CgoKICA8ZGl2IHN0eWxlPSJjb2xvcjogcmdiKDEwMiwgMTAyLCAx -MDIpOyI+CiAgICA8cD5UbyByZXNwb25kLCByZXBseSB0byB0aGlzIGVtYWlsIG9yIHZpc2l0IDxh -IHN0eWxlPSJjb2xvcjogcmdiKDEwMiwgMTAyLCAxMDIpOyBmb250LXdlaWdodDogYm9sZDsgdGV4 -dC1kZWNvcmF0aW9uOiBub25lOyIgaHJlZj0iaHR0cHM6Ly9tZXRhLmRpc2NvdXJzZS5vcmcvdC90 -ZXN0aW5nLWRlZmF1bHQtZW1haWwtcmVwbGllcy8yMjYzOC8zIiB0YXJnZXQ9Il9wYXJlbnQiPmh0 -dHBzOi8vbWV0YS5kaXNjb3Vyc2Uub3JnL3QvdGVzdGluZy1kZWZhdWx0LWVtYWlsLXJlcGxpZXMv -MjI2MzgvMzwvYT4gaW4geW91ciBicm93c2VyLjwvcD4KICA8L2Rpdj4KICA8aHIgc3R5bGU9ImJv -cmRlcjogMXB4IGJsYWNrOyBib3JkZXItaW1hZ2U6IG5vbmU7IGhlaWdodDogMXB4OyBiYWNrZ3Jv -dW5kLWNvbG9yOiByZ2IoMjIxLCAyMjEsIDIyMSk7Ij4KICA8aDQ+UHJldmlvdXMgUmVwbGllczwv -aDQ+CgogIDx0YWJsZSB0YWJpbmRleD0iLTEiIHN0eWxlPSJtYXJnaW4tYm90dG9tOiAyNXB4OyIg -Ym9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjAiPgogIDx0Ym9keT4KICAg -IDx0cj4KICAgICAgPHRkIHN0eWxlPSJ3aWR0aDogNTVweDsgdmVydGljYWwtYWxpZ246IHRvcDsi -PgogICAgICAgIDxpbWcgd2lkdGg9IjQ1IiBoZWlnaHQ9IjQ1IiB0YWJpbmRleD0iLTEiIHN0eWxl -PSJtYXgtd2lkdGg6IDEwMCU7IiBzcmM9Imh0dHBzOi8vbWV0YS1kaXNjb3Vyc2UuZ2xvYmFsLnNz -bC5mYXN0bHkubmV0L3VzZXJfYXZhdGFyL21ldGEuZGlzY291cnNlLm9yZy9jb2Rpbmdob3Jyb3Iv -NDUvNTI5Ny5wbmciIGRhdGEtbXMtaW1nc3JjPSJodHRwczovL21ldGEtZGlzY291cnNlLmdsb2Jh -bC5zc2wuZmFzdGx5Lm5ldC91c2VyX2F2YXRhci9tZXRhLmRpc2NvdXJzZS5vcmcvY29kaW5naG9y -cm9yLzQ1LzUyOTcucG5nIj4KICAgICAgPC90ZD4KICAgICAgPHRkPgogICAgICAgIDxhIHN0eWxl -PSdjb2xvcjogcmdiKDU5LCA4OSwgMTUyKTsgZm9udC1mYW1pbHk6ICJsdWNpZGEgZ3JhbmRlIix0 -YWhvbWEsdmVyZGFuYSxhcmlhbCxzYW5zLXNlcmlmOyBmb250LXNpemU6IDEzcHg7IGZvbnQtd2Vp -Z2h0OiBib2xkOyB0ZXh0LWRlY29yYXRpb246IG5vbmU7JyBocmVmPSJodHRwczovL21ldGEuZGlz -Y291cnNlLm9yZy91c2Vycy9jb2Rpbmdob3Jyb3IiIHRhcmdldD0iX3BhcmVudCI+Y29kaW5naG9y -cm9yPC9hPjxicj4KICAgICAgICA8c3BhbiBzdHlsZT0ndGV4dC1hbGlnbjogcmlnaHQ7IGNvbG9y -OiByZ2IoMTUzLCAxNTMsIDE1Myk7IHBhZGRpbmctcmlnaHQ6IDVweDsgZm9udC1mYW1pbHk6ICJs -dWNpZGEgZ3JhbmRlIix0YWhvbWEsdmVyZGFuYSxhcmlhbCxzYW5zLXNlcmlmOyBmb250LXNpemU6 -IDExcHg7Jz5Ob3ZlbWJlciAyODwvc3Bhbj4KICAgICAgPC90ZD4KICAgIDwvdHI+CiAgICA8dHI+ -CiAgICAgIDx0ZCBzdHlsZT0icGFkZGluZy10b3A6IDVweDsiIGNvbHNwYW49IjIiPgo8cCBzdHls -ZT0iYm9yZGVyOiAwcHggYmxhY2s7IGJvcmRlci1pbWFnZTogbm9uZTsgbWFyZ2luLXRvcDogMHB4 -OyI+V2UncmUgdGVzdGluZyB0aGUgbGF0ZXN0IEdpdEh1YiBlbWFpbCBwcm9jZXNzaW5nIGxpYnJh -cnkgd2hpY2ggd2UgYXJlIGludGVncmF0aW5nIG5vdy48L3A+Cgo8cCBzdHlsZT0iYm9yZGVyOiAw -cHggYmxhY2s7IGJvcmRlci1pbWFnZTogbm9uZTsgbWFyZ2luLXRvcDogMHB4OyI+PGEgc3R5bGU9 -ImNvbG9yOiByZ2IoMCwgMTAyLCAxNTMpOyBmb250LXdlaWdodDogYm9sZDsgdGV4dC1kZWNvcmF0 -aW9uOiBub25lOyIgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dpdGh1Yi9lbWFpbF9yZXBseV9w -YXJzZXIiIHRhcmdldD0iX3BhcmVudCI+aHR0cHM6Ly9naXRodWIuY29tL2dpdGh1Yi9lbWFpbF9y -ZXBseV9wYXJzZXI8L2E+PC9wPgoKPHAgc3R5bGU9ImJvcmRlcjogMHB4IGJsYWNrOyBib3JkZXIt -aW1hZ2U6IG5vbmU7IG1hcmdpbi10b3A6IDBweDsiPkdvIGFoZWFkIGFuZCByZXBseSB0byB0aGlz -IHRvcGljIGFuZCBJJ2xsIHJlcGx5IGZyb20gdmFyaW91cyBlbWFpbCBjbGllbnRzIGZvciB0ZXN0 -aW5nLjwvcD4KPC90ZD4KICAgIDwvdHI+CiAgPC90Ym9keT4KPC90YWJsZT4KCgo8aHIgc3R5bGU9 -ImJvcmRlcjogMXB4IGJsYWNrOyBib3JkZXItaW1hZ2U6IG5vbmU7IGhlaWdodDogMXB4OyBiYWNr -Z3JvdW5kLWNvbG9yOiByZ2IoMjIxLCAyMjEsIDIyMSk7Ij4KCjxkaXYgc3R5bGU9ImNvbG9yOiBy -Z2IoMTAyLCAxMDIsIDEwMik7Ij4KPHA+VG8gcmVzcG9uZCwgcmVwbHkgdG8gdGhpcyBlbWFpbCBv -ciB2aXNpdCA8YSBzdHlsZT0iY29sb3I6IHJnYigxMDIsIDEwMiwgMTAyKTsgZm9udC13ZWlnaHQ6 -IGJvbGQ7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsiIGhyZWY9Imh0dHBzOi8vbWV0YS5kaXNjb3Vy -c2Uub3JnL3QvdGVzdGluZy1kZWZhdWx0LWVtYWlsLXJlcGxpZXMvMjI2MzgvMyIgdGFyZ2V0PSJf -cGFyZW50Ij5odHRwczovL21ldGEuZGlzY291cnNlLm9yZy90L3Rlc3RpbmctZGVmYXVsdC1lbWFp -bC1yZXBsaWVzLzIyNjM4LzM8L2E+IGluIHlvdXIgYnJvd3Nlci48L3A+CjwvZGl2Pgo8ZGl2IHN0 -eWxlPSJjb2xvcjogcmdiKDEwMiwgMTAyLCAxMDIpOyI+CjxwPlRvIHVuc3Vic2NyaWJlIGZyb20g -dGhlc2UgZW1haWxzLCB2aXNpdCB5b3VyIDxhIHN0eWxlPSJjb2xvcjogcmdiKDEwMiwgMTAyLCAx -MDIpOyBmb250LXdlaWdodDogYm9sZDsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyIgaHJlZj0iaHR0 -cHM6Ly9tZXRhLmRpc2NvdXJzZS5vcmcvbXkvcHJlZmVyZW5jZXMiIHRhcmdldD0iX3BhcmVudCI+ -dXNlciBwcmVmZXJlbmNlczwvYT4uPC9wPgo8L2Rpdj4KPC9kaXY+CjwvZGl2PjxkaXYgc3R5bGU9 -ImZvbnQtc2l6ZTogMTRwdDsiPjxicj48L2Rpdj48L2Rpdj4KPC9ib2R5Pgo8L2h0bWw+Cg== - ---_866E2678-BB4F-4DD8-BE18-81B04AD8D1BC_-- diff --git a/spec/fixtures/emails/wrong_reply_key.eml b/spec/fixtures/emails/wrong_reply_key.eml deleted file mode 100644 index 491e078fb5b..00000000000 --- a/spec/fixtures/emails/wrong_reply_key.eml +++ /dev/null @@ -1,40 +0,0 @@ -Return-Path: -Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 -Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Thu, 13 Jun 2013 17:03:50 -0400 -Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for ; Thu, 13 Jun 2013 14:03:48 -0700 -Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 -Date: Thu, 13 Jun 2013 17:03:48 -0400 -From: Jake the Dog -To: reply+QQd8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo -Message-ID: -Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' -Mime-Version: 1.0 -Content-Type: text/plain; - charset=ISO-8859-1 -Content-Transfer-Encoding: 7bit -X-Sieve: CMU Sieve 2.2 -X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu, - 13 Jun 2013 14:03:48 -0700 (PDT) -X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 - -I could not disagree more. I am obviously biased but adventure time is the -greatest show ever created. Everyone should watch it. - -- Jake out - - -On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta - wrote: -> -> -> -> eviltrout posted in 'Adventure Time Sux' on Discourse Meta: -> -> --- -> hey guys everyone knows adventure time sucks! -> -> --- -> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3 -> -> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences). -> \ No newline at end of file diff --git a/spec/fixtures/images/fake.jpg b/spec/fixtures/images/fake.jpg new file mode 100644 index 00000000000..e59fa523ee0 Binary files /dev/null and b/spec/fixtures/images/fake.jpg differ diff --git a/spec/fixtures/site_settings/simple.yml b/spec/fixtures/site_settings/simple.yml index e53dc0aaae4..9a36d681d42 100644 --- a/spec/fixtures/site_settings/simple.yml +++ b/spec/fixtures/site_settings/simple.yml @@ -3,7 +3,7 @@ category1: contact_email: 'webmaster@example.com' category2: - ninja_edit_window: true + editing_grace_period: true category3: reply_by_email_address: '' diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index b4fcacd5a52..7adf0c2baf4 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ApplicationHelper do @@ -29,28 +29,38 @@ describe ApplicationHelper do context "mobile_view is not set" do it "is false if user agent is not mobile" do - controller.request.stubs(:user_agent).returns('Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.17 Safari/537.36') + controller.request.stubs(:user_agent).returns('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36') expect(helper.mobile_view?).to be_falsey end it "is true for iPhone" do - controller.request.stubs(:user_agent).returns('Mozilla/5.0 (iPhone; U; ru; CPU iPhone OS 4_2_1 like Mac OS X; ru) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5') + controller.request.stubs(:user_agent).returns('Mozilla/5.0 (iPhone; CPU iPhone OS 9_2_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13D15 Safari/601.1') + expect(helper.mobile_view?).to eq(true) + end + + it "is true for Android Samsung Galaxy" do + controller.request.stubs(:user_agent).returns('Mozilla/5.0 (Linux; Android 5.0.2; SAMSUNG SM-G925F Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36') + expect(helper.mobile_view?).to eq(true) + end + + it "is true for Android Google Nexus 5X" do + controller.request.stubs(:user_agent).returns('Mozilla/5.0 (Linux; Android 6.0; Nexus 5X Build/MDB08I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.43 Mobile Safari/537.36') expect(helper.mobile_view?).to eq(true) end it "is false for iPad" do - controller.request.stubs(:user_agent).returns("Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3") + controller.request.stubs(:user_agent).returns("Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B14 3 Safari/601.1") expect(helper.mobile_view?).to eq(false) end it "is false for Nexus 10 tablet" do - controller.request.stubs(:user_agent).returns("Mozilla/5.0 (Linux; Android 4.2.1; Nexus 10 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19") + controller.request.stubs(:user_agent).returns("Mozilla/5.0 (Linux; Android 5.1.1; Nexus 10 Build/LMY49G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.91 Safari/537.36") expect(helper.mobile_view?).to be_falsey end - it "is true for Nexus 7 tablet" do - controller.request.stubs(:user_agent).returns("Mozilla/5.0 (Linux; Android 4.1.2; Nexus 7 Build/JZ054K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19") - expect(helper.mobile_view?).to eq(true) + it "is false for Nexus 7 tablet" do + controller.request.stubs(:user_agent).returns("Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MMB29Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.91 Safari/537.36") + expect(helper.mobile_view?).to be_falsey end end end @@ -84,5 +94,16 @@ describe ApplicationHelper do end end + describe '#rtl_class' do + it "returns 'rtl' when the I18n.locale is rtl" do + I18n.stubs(:locale).returns(:he) + expect(helper.rtl_class).to eq('rtl') + end + + it 'returns an empty string when the I18n.locale is not rtl' do + I18n.stubs(:locale).returns(:zh_TW) + expect(helper.rtl_class).to eq('') + end + end end diff --git a/spec/integration/invite_only_registration_spec.rb b/spec/integration/invite_only_registration_spec.rb index 7e3f95abca7..72575738df9 100644 --- a/spec/integration/invite_only_registration_spec.rb +++ b/spec/integration/invite_only_registration_spec.rb @@ -1,6 +1,6 @@ # encoding: UTF-8 -require 'spec_helper' +require 'rails_helper' describe 'invite only' do diff --git a/spec/integration/same_ip_spammers_spec.rb b/spec/integration/same_ip_spammers_spec.rb index 3b3c7364233..d6341c03c96 100644 --- a/spec/integration/same_ip_spammers_spec.rb +++ b/spec/integration/same_ip_spammers_spec.rb @@ -1,6 +1,6 @@ # encoding: UTF-8 -require 'spec_helper' +require 'rails_helper' describe SpamRulesEnforcer do diff --git a/spec/integration/spam_rules_spec.rb b/spec/integration/spam_rules_spec.rb index 0b040d67cd0..04f8b41ee06 100644 --- a/spec/integration/spam_rules_spec.rb +++ b/spec/integration/spam_rules_spec.rb @@ -1,6 +1,6 @@ # encoding: UTF-8 -require 'spec_helper' +require 'rails_helper' describe SpamRulesEnforcer do diff --git a/spec/integration/topic_auto_close_spec.rb b/spec/integration/topic_auto_close_spec.rb index 41c5438cff2..6f1d5fa2e10 100644 --- a/spec/integration/topic_auto_close_spec.rb +++ b/spec/integration/topic_auto_close_spec.rb @@ -1,28 +1,29 @@ # encoding: UTF-8 -require 'spec_helper' +require 'rails_helper' require 'sidekiq/testing' describe Topic do def scheduled_jobs_for(job_name, params={}) - Sidekiq::Extensions::DelayedClass.jobs.select do |job| - job_args = YAML.load(job['args'][0]) - if job_args[0].to_s == "Jobs::#{job_name.to_s.camelcase}" and job_args[2] and job_args[2][0] - matched = true - params.each do |key, value| - unless job_args[2][0][key] == value - matched = false - break - end + "Jobs::#{job_name.to_s.camelcase}".constantize.jobs.select do |job| + job_args = job['args'][0] + matched = true + params.each do |key, value| + unless job_args[key.to_s] == value + matched = false + break end - matched end + matched end end - before { SiteSetting.stubs(:queue_jobs).returns(true) } + before { + SiteSetting.queue_jobs = true + Jobs::CloseTopic.jobs.clear + } context 'creating a topic without auto-close' do Given(:topic) { Fabricate(:topic, category: category) } diff --git a/spec/integrity/i18n_spec.rb b/spec/integrity/i18n_spec.rb index 2525668f542..c7311b3d44f 100644 --- a/spec/integrity/i18n_spec.rb +++ b/spec/integrity/i18n_spec.rb @@ -1,4 +1,5 @@ -require 'spec_helper' +require 'rails_helper' +require 'locale_file_walker' describe "i18n integrity checks" do @@ -17,7 +18,7 @@ describe "i18n integrity checks" do it "needs an i18n key (notification_types) for each Notification type" do Notification.types.each_key do |type| - next if type == :custom + next if type == :custom || type == :group_message_summary expect(I18n.t("notification_types.#{type}")).not_to match(/translation missing/) end end @@ -57,4 +58,70 @@ describe "i18n integrity checks" do end end + describe 'English locale file' do + locale_files = ['config/locales', 'plugins/**/locales'] + .product(['server.en.yml', 'client.en.yml']) + .collect { |dir, filename| Dir["#{Rails.root}/#{dir}/#{filename}"] } + .flatten + .map { |path| Pathname.new(path).relative_path_from(Rails.root) } + + class DuplicateKeyFinder < LocaleFileWalker + def find_duplicates(filename) + @keys_with_count = {} + + document = Psych.parse_file(filename) + handle_document(document) + + @keys_with_count.delete_if { |key, count| count <= 1 }.keys + end + + protected + + def handle_scalar(node, depth, parents) + super(node, depth, parents) + + key = parents.join('.') + @keys_with_count[key] = @keys_with_count.fetch(key, 0) + 1 + end + end + + module Pluralizations + def self.load(path) + whitelist = Regexp.union([/messages.restrict_dependent_destroy/]) + + yaml = YAML.load_file("#{Rails.root}/#{path}") + pluralizations = find_pluralizations(yaml['en']) + pluralizations.reject! { |key| key.match(whitelist) } + pluralizations + end + + def self.find_pluralizations(hash, parent_key = '', pluralizations = Hash.new) + hash.each do |key, value| + if value.is_a? Hash + current_key = parent_key.blank? ? key : "#{parent_key}.#{key}" + find_pluralizations(value, current_key, pluralizations) + elsif key == 'one' || key == 'other' + pluralizations[parent_key] = hash + end + end + + pluralizations + end + end + + locale_files.each do |path| + context path do + it 'has no duplicate keys' do + duplicates = DuplicateKeyFinder.new.find_duplicates("#{Rails.root}/#{path}") + expect(duplicates).to be_empty + end + + Pluralizations.load(path).each do |key, values| + it "key '#{key}' has valid pluralizations" do + expect(values.keys).to contain_exactly('one', 'other') + end + end + end + end + end end diff --git a/spec/jobs/about_stats_spec.rb b/spec/jobs/about_stats_spec.rb index 68e6393e2c6..25ae8291f83 100644 --- a/spec/jobs/about_stats_spec.rb +++ b/spec/jobs/about_stats_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Jobs::AboutStats do it 'caches the stats' do diff --git a/spec/jobs/automatic_group_membership_spec.rb b/spec/jobs/automatic_group_membership_spec.rb index fe80c04cae2..e6d59993085 100644 --- a/spec/jobs/automatic_group_membership_spec.rb +++ b/spec/jobs/automatic_group_membership_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/regular/automatic_group_membership' describe Jobs::AutomaticGroupMembership do diff --git a/spec/jobs/bulk_invite_spec.rb b/spec/jobs/bulk_invite_spec.rb index 7f795be52c1..77629a6a82f 100644 --- a/spec/jobs/bulk_invite_spec.rb +++ b/spec/jobs/bulk_invite_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Jobs::BulkInvite do diff --git a/spec/jobs/clean_up_email_logs_spec.rb b/spec/jobs/clean_up_email_logs_spec.rb new file mode 100644 index 00000000000..460b4ffbd09 --- /dev/null +++ b/spec/jobs/clean_up_email_logs_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +describe Jobs::CleanUpEmailLogs do + + before do + Fabricate(:email_log, created_at: 2.years.ago, reply_key: "something") + Fabricate(:email_log, created_at: 2.years.ago) + Fabricate(:email_log, created_at: 2.weeks.ago) + Fabricate(:email_log, created_at: 2.days.ago) + end + + it "removes old email logs without a reply_key" do + Jobs::CleanUpEmailLogs.new.execute({}) + expect(EmailLog.count).to eq(3) + end + + it "does not remove old email logs when delete_email_logs_after_days is 0" do + SiteSetting.delete_email_logs_after_days = 0 + Jobs::CleanUpEmailLogs.new.execute({}) + expect(EmailLog.count).to eq(4) + end + +end diff --git a/spec/jobs/clean_up_exports_spec.rb b/spec/jobs/clean_up_exports_spec.rb index b418c8539d3..741ac87a302 100644 --- a/spec/jobs/clean_up_exports_spec.rb +++ b/spec/jobs/clean_up_exports_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/scheduled/clean_up_exports' diff --git a/spec/jobs/clean_up_uploads_spec.rb b/spec/jobs/clean_up_uploads_spec.rb index 5ccede2c41a..9c307b7fccb 100644 --- a/spec/jobs/clean_up_uploads_spec.rb +++ b/spec/jobs/clean_up_uploads_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/scheduled/clean_up_uploads' diff --git a/spec/jobs/close_topic_spec.rb b/spec/jobs/close_topic_spec.rb index d3dfcc8d64e..9efb67ca48d 100644 --- a/spec/jobs/close_topic_spec.rb +++ b/spec/jobs/close_topic_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/base' describe Jobs::CloseTopic do diff --git a/spec/jobs/crawl_topic_link_spec.rb b/spec/jobs/crawl_topic_link_spec.rb index 5d7024b9eb5..8e01178b44e 100644 --- a/spec/jobs/crawl_topic_link_spec.rb +++ b/spec/jobs/crawl_topic_link_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/base' require_dependency 'jobs/regular/crawl_topic_link' diff --git a/spec/jobs/create_missing_avatars_spec.rb b/spec/jobs/create_missing_avatars_spec.rb index 09cd1a9dc30..c57f7f6c543 100644 --- a/spec/jobs/create_missing_avatars_spec.rb +++ b/spec/jobs/create_missing_avatars_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/scheduled/create_missing_avatars' diff --git a/spec/jobs/dashboard_stats_spec.rb b/spec/jobs/dashboard_stats_spec.rb index 79f9865571a..b00130d02de 100644 --- a/spec/jobs/dashboard_stats_spec.rb +++ b/spec/jobs/dashboard_stats_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Jobs::DashboardStats do it 'caches the stats' do diff --git a/spec/jobs/enqueue_digest_emails_spec.rb b/spec/jobs/enqueue_digest_emails_spec.rb index d3f6b354d92..f52a033a045 100644 --- a/spec/jobs/enqueue_digest_emails_spec.rb +++ b/spec/jobs/enqueue_digest_emails_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/base' describe Jobs::EnqueueDigestEmails do @@ -32,6 +32,14 @@ describe Jobs::EnqueueDigestEmails do And { expect(Jobs::EnqueueDigestEmails.new.target_user_ids.include?(unapproved_user.id)).to eq(true) } end + context 'staged users' do + let!(:staged_user) { Fabricate(:active_user, staged: true, last_emailed_at: 1.year.ago, last_seen_at: 1.year.ago) } + + it "doesn't return staged users" do + expect(Jobs::EnqueueDigestEmails.new.target_user_ids.include?(staged_user.id)).to eq(false) + end + end + context 'recently emailed' do let!(:user_emailed_recently) { Fabricate(:active_user, last_emailed_at: 6.days.ago) } diff --git a/spec/jobs/export_csv_file_spec.rb b/spec/jobs/export_csv_file_spec.rb index 80e211c9e43..2f89d34aaf6 100644 --- a/spec/jobs/export_csv_file_spec.rb +++ b/spec/jobs/export_csv_file_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Jobs::ExportCsvFile do @@ -25,7 +25,7 @@ describe Jobs::ExportCsvFile do user = Fabricate(:user) user.create_single_sign_on_record(external_id: "123", last_payload: "xxx", external_email: 'test@test.com') - user = to_hash(user_list_export.find{|u| u[0] == user.id}) + user = to_hash(user_list_export.find{|u| u[0].to_i == user.id}) expect(user["external_id"]).to eq("123") expect(user["external_email"]).to eq("test@test.com") diff --git a/spec/jobs/feature_topic_users_spec.rb b/spec/jobs/feature_topic_users_spec.rb index 8bc9da9dac3..b651e856681 100644 --- a/spec/jobs/feature_topic_users_spec.rb +++ b/spec/jobs/feature_topic_users_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/base' require 'jobs/regular/process_post' diff --git a/spec/jobs/invite_email_spec.rb b/spec/jobs/invite_email_spec.rb index 4b41e4223d5..fc751bab6a5 100644 --- a/spec/jobs/invite_email_spec.rb +++ b/spec/jobs/invite_email_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/base' describe Jobs::InviteEmail do diff --git a/spec/jobs/jobs_base_spec.rb b/spec/jobs/jobs_base_spec.rb index bcc0680d9a2..c8ab2ab56aa 100644 --- a/spec/jobs/jobs_base_spec.rb +++ b/spec/jobs/jobs_base_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/base' describe Jobs::Base do diff --git a/spec/jobs/jobs_spec.rb b/spec/jobs/jobs_spec.rb index 2840b6c3e8d..57d2717b255 100644 --- a/spec/jobs/jobs_spec.rb +++ b/spec/jobs/jobs_spec.rb @@ -1,4 +1,5 @@ -require 'spec_helper' +require "sidekiq/testing" +require 'rails_helper' require_dependency 'jobs/base' describe Jobs do @@ -76,23 +77,27 @@ describe Jobs do end describe 'cancel_scheduled_job' do + it 'deletes the matching job' do - job_to_delete = stub_everything(klass: 'Sidekiq::Extensions::DelayedClass', args: [YAML.dump(['Jobs::DrinkBeer', :delayed_perform, [{beer_id: 42}]])]) - job_to_delete.expects(:delete) - job_to_keep1 = stub_everything(klass: 'Sidekiq::Extensions::DelayedClass', args: [YAML.dump(['Jobs::DrinkBeer', :delayed_perform, [{beer_id: 43}]])]) - job_to_keep1.expects(:delete).never - job_to_keep2 = stub_everything(klass: 'Sidekiq::Extensions::DelayedClass', args: [YAML.dump(['Jobs::DrinkBeer', :delayed_perform, [{beer_id: 44}]])]) - job_to_keep2.expects(:delete).never - Sidekiq::ScheduledSet.stubs(:new).returns( [job_to_keep1, job_to_delete, job_to_keep2] ) - expect(Jobs.cancel_scheduled_job(:drink_beer, {beer_id: 42})).to eq(true) + SiteSetting.queue_jobs = true + + Sidekiq::Testing.disable! do + scheduled_jobs = Sidekiq::ScheduledSet.new + scheduled_jobs.clear + + expect(scheduled_jobs.size).to eq(0) + + Jobs.enqueue_in(1.year, :run_heartbeat, topic_id: 1234) + Jobs.enqueue_in(2.years, :run_heartbeat, topic_id: 5678) + + expect(scheduled_jobs.size).to eq(2) + + Jobs.cancel_scheduled_job(:run_heartbeat, topic_id: 1234) + + expect(scheduled_jobs.size).to eq(1) + end end - it 'returns false when no matching job is scheduled' do - job_to_keep = stub_everything(klass: 'Sidekiq::Extensions::DelayedClass', args: [YAML.dump(['Jobs::DrinkBeer', :delayed_perform, [{beer_id: 43}]])]) - job_to_keep.expects(:delete).never - Sidekiq::ScheduledSet.stubs(:new).returns( [job_to_keep] ) - expect(Jobs.cancel_scheduled_job(:drink_beer, {beer_id: 42})).to eq(false) - end end describe 'enqueue_at' do diff --git a/spec/jobs/notify_mailing_list_subscribers_spec.rb b/spec/jobs/notify_mailing_list_subscribers_spec.rb index 84e94dc58fc..f63b4225ccc 100644 --- a/spec/jobs/notify_mailing_list_subscribers_spec.rb +++ b/spec/jobs/notify_mailing_list_subscribers_spec.rb @@ -1,56 +1,77 @@ -require "spec_helper" +require "rails_helper" describe Jobs::NotifyMailingListSubscribers do context "with mailing list on" do - before { SiteSetting.stubs(:default_email_mailing_list_mode).returns(true) } + before { SiteSetting.default_email_mailing_list_mode = true } + let(:user) { Fabricate(:user) } - context "with mailing list on" do - let(:user) { Fabricate(:user) } + context "SiteSetting.max_emails_per_day_per_user" do - context "with a valid post" do - let!(:post) { Fabricate(:post, user: user) } + it 'stops sending mail once limit is reached' do + SiteSetting.max_emails_per_day_per_user = 2 + post = Fabricate(:post) - it "sends the email to the user" do - UserNotifications.expects(:mailing_list_notify).with(user, post).once - Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) - end + user.email_logs.create(email_type: 'blah', to_address: user.email, user_id: user.id) + user.email_logs.create(email_type: 'blah', to_address: user.email, user_id: user.id) + + Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) + expect(EmailLog.where(user_id: user.id, skipped: true).count).to eq(1) end - - context "with a deleted post" do - let!(:post) { Fabricate(:post, user: user, deleted_at: Time.now) } - - it "doesn't send the email to the user" do - UserNotifications.expects(:mailing_list_notify).with(user, post).never - Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) - end - end - - context "with a user_deleted post" do - let!(:post) { Fabricate(:post, user: user, user_deleted: true) } - - it "doesn't send the email to the user" do - UserNotifications.expects(:mailing_list_notify).with(user, post).never - Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) - end - end - - context "with a deleted topic" do - let!(:post) { Fabricate(:post, user: user) } - - before do - post.topic.update_column(:deleted_at, Time.now) - end - - it "doesn't send the email to the user" do - UserNotifications.expects(:mailing_list_notify).with(user, post).never - Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) - end - end - end - context "to an anonymous user with mailing list on" do + context "totally skipped if mailing list mode disabled" do + + it "sends no email to the user" do + SiteSetting.disable_mailing_list_mode = true + + post = Fabricate(:post) + Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) + expect(EmailLog.count).to eq(0) + end + end + + context "with a valid post" do + let!(:post) { Fabricate(:post, user: user) } + + it "sends the email to the user" do + UserNotifications.expects(:mailing_list_notify).with(user, post).once + Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) + end + end + + context "with a deleted post" do + let!(:post) { Fabricate(:post, user: user, deleted_at: Time.now) } + + it "doesn't send the email to the user" do + UserNotifications.expects(:mailing_list_notify).with(user, post).never + Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) + end + end + + context "with a user_deleted post" do + let!(:post) { Fabricate(:post, user: user, user_deleted: true) } + + it "doesn't send the email to the user" do + UserNotifications.expects(:mailing_list_notify).with(user, post).never + Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) + end + end + + context "with a deleted topic" do + let!(:post) { Fabricate(:post, user: user) } + + before do + post.topic.update_column(:deleted_at, Time.now) + end + + it "doesn't send the email to the user" do + UserNotifications.expects(:mailing_list_notify).with(user, post).never + Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) + end + end + + context "to an anonymous user" do let(:user) { Fabricate(:anonymous) } let!(:post) { Fabricate(:post, user: user) } diff --git a/spec/jobs/notify_moved_posts_spec.rb b/spec/jobs/notify_moved_posts_spec.rb index eb1ed1d394c..29ab275eec5 100644 --- a/spec/jobs/notify_moved_posts_spec.rb +++ b/spec/jobs/notify_moved_posts_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/base' require_dependency 'jobs/regular/process_post' diff --git a/spec/jobs/pending_flags_reminder_spec.rb b/spec/jobs/pending_flags_reminder_spec.rb index ec105b2d402..e73038c0fb2 100644 --- a/spec/jobs/pending_flags_reminder_spec.rb +++ b/spec/jobs/pending_flags_reminder_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Jobs::PendingFlagsReminder do context "notify_about_flags_after is 0" do @@ -14,17 +14,17 @@ describe Jobs::PendingFlagsReminder do context "notify_about_flags_after is 48" do before { SiteSetting.stubs(:notify_about_flags_after).returns(48) } - it "doesn't send email when flags are less than 48 hours old" do + it "doesn't send message when flags are less than 48 hours old" do Fabricate(:flag, created_at: 47.hours.ago) PostAction.stubs(:flagged_posts_count).returns(1) - Email::Sender.any_instance.expects(:send).never + PostCreator.expects(:create).never described_class.new.execute({}) end - it "sends email when there is a flag older than 48 hours" do + it "sends message when there is a flag older than 48 hours" do Fabricate(:flag, created_at: 49.hours.ago) PostAction.stubs(:flagged_posts_count).returns(1) - Email::Sender.any_instance.expects(:send).once.returns(true) + PostCreator.expects(:create).once.returns(true) described_class.new.execute({}) end end diff --git a/spec/jobs/pending_queued_posts_reminder_spec.rb b/spec/jobs/pending_queued_posts_reminder_spec.rb index 4af0e8bbcbb..dd182686da0 100644 --- a/spec/jobs/pending_queued_posts_reminder_spec.rb +++ b/spec/jobs/pending_queued_posts_reminder_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe Jobs::PendingQueuedPostReminder do context "notify_about_queued_posts_after is 0" do diff --git a/spec/jobs/pending_users_reminder_spec.rb b/spec/jobs/pending_users_reminder_spec.rb index a0cbbfb9ce8..c844184522d 100644 --- a/spec/jobs/pending_users_reminder_spec.rb +++ b/spec/jobs/pending_users_reminder_spec.rb @@ -1,24 +1,43 @@ -require 'spec_helper' +require 'rails_helper' describe Jobs::PendingUsersReminder do context 'must_approve_users is true' do before do - SiteSetting.stubs(:must_approve_users).returns(true) + SiteSetting.must_approve_users = true + Jobs::PendingUsersReminder.any_instance.stubs(:previous_newest_username).returns(nil) end it "doesn't send a message to anyone when there are no pending users" do - AdminUserIndexQuery.any_instance.stubs(:find_users_query).returns(stub_everything(count: 0)) PostCreator.expects(:create).never Jobs::PendingUsersReminder.new.execute({}) end - it "sends a message when there are pending users" do - Fabricate(:moderator) - Group.refresh_automatic_group!(:moderators) - AdminUserIndexQuery.any_instance.stubs(:find_users_query).returns(stub_everything(count: 1)) - PostCreator.expects(:create).once - Jobs::PendingUsersReminder.new.execute({}) + context "there are pending users" do + before do + Fabricate(:moderator, approved: true, approved_by_id: -1, approved_at: 1.week.ago) + Group.refresh_automatic_group!(:moderators) + end + + it "sends a message if user was created more than pending_users_reminder_delay hours ago" do + SiteSetting.pending_users_reminder_delay = 8 + Fabricate(:user, created_at: 9.hours.ago) + PostCreator.expects(:create).once + Jobs::PendingUsersReminder.new.execute({}) + end + + it "doesn't send a message if user was created less than pending_users_reminder_delay hours ago" do + SiteSetting.pending_users_reminder_delay = 8 + Fabricate(:user, created_at: 2.hours.ago) + PostCreator.expects(:create).never + Jobs::PendingUsersReminder.new.execute({}) + end + + it "doesn't send a message if pending_users_reminder_delay is -1" do + SiteSetting.pending_users_reminder_delay = -1 + PostCreator.expects(:create).never + Jobs::PendingUsersReminder.new.execute({}) + end end end diff --git a/spec/jobs/periodical_updates_spec.rb b/spec/jobs/periodical_updates_spec.rb index d91a8ac779f..01071f290f6 100644 --- a/spec/jobs/periodical_updates_spec.rb +++ b/spec/jobs/periodical_updates_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/scheduled/periodical_updates' describe Jobs::PeriodicalUpdates do diff --git a/spec/jobs/poll_feed_spec.rb b/spec/jobs/poll_feed_spec.rb index 20f13bc1e7e..b222991cb0e 100644 --- a/spec/jobs/poll_feed_spec.rb +++ b/spec/jobs/poll_feed_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/regular/process_post' describe Jobs::PollFeed do diff --git a/spec/jobs/poll_mailbox_spec.rb b/spec/jobs/poll_mailbox_spec.rb index fc009bfb216..451cf07e355 100644 --- a/spec/jobs/poll_mailbox_spec.rb +++ b/spec/jobs/poll_mailbox_spec.rb @@ -1,27 +1,22 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/regular/process_post' describe Jobs::PollMailbox do - let!(:poller) { Jobs::PollMailbox.new } + let(:poller) { Jobs::PollMailbox.new } describe ".execute" do it "does no polling if pop3_polling_enabled is false" do - SiteSetting.expects(:pop3_polling_enabled?).returns(false) + SiteSetting.expects(:pop3_polling_enabled).returns(false) poller.expects(:poll_pop3).never - poller.execute({}) end - describe "with pop3_polling_enabled" do - - it "calls poll_pop3" do - SiteSetting.expects(:pop3_polling_enabled?).returns(true) - poller.expects(:poll_pop3).once - - poller.execute({}) - end + it "polls when pop3_polling_enabled is true" do + SiteSetting.expects(:pop3_polling_enabled).returns(true) + poller.expects(:poll_pop3).once + poller.execute({}) end end @@ -29,13 +24,8 @@ describe Jobs::PollMailbox do describe ".poll_pop3" do it "logs an error on pop authentication error" do - error = Net::POPAuthenticationError.new - data = { limit_once_per: 1.hour, message_params: { error: error }} - - Net::POP3.any_instance.expects(:start).raises(error) - + Net::POP3.any_instance.expects(:start).raises(Net::POPAuthenticationError.new) Discourse.expects(:handle_job_exception) - poller.poll_pop3 end @@ -43,264 +33,15 @@ describe Jobs::PollMailbox do SiteSetting.pop3_polling_ssl = true Net::POP3.any_instance.stubs(:start) Net::POP3.any_instance.expects(:enable_ssl) - poller.poll_pop3 end - it "does not call enable_ssl when the setting is off" do + it "does not call enable_ssl when the setting is disabled" do SiteSetting.pop3_polling_ssl = false Net::POP3.any_instance.stubs(:start) Net::POP3.any_instance.expects(:enable_ssl).never - poller.poll_pop3 end end - # Testing mock for the email objects that you get - # from Net::POP3.start { |pop| pop.mails } - class MockPop3EmailObject - def initialize(mail_string) - @message = mail_string - @delete_called = 0 - end - - def pop - @message - end - - def delete - @delete_called += 1 - end - - # call 'assert email.deleted?' at the end of the test - def deleted? - @delete_called == 1 - end - end - - def expect_success - poller.expects(:handle_failure).never - end - - def expect_exception(clazz) - poller.expects(:handle_failure).with(anything, instance_of(clazz)) - end - - describe "processing emails" do - let(:category) { Fabricate(:category) } - let(:user) { Fabricate(:user) } - - before do - SiteSetting.email_in = true - SiteSetting.reply_by_email_address = "reply+%{reply_key}@appmail.adventuretime.ooo" - category.email_in = 'incoming+amazing@appmail.adventuretime.ooo' - category.save - user.change_trust_level! 2 - user.username = 'Jake' - user.email = 'jake@adventuretime.ooo' - user.save - end - - describe "a valid incoming email" do - let(:email) { - # this string replacing is kinda dumb - str = fixture_file('emails/valid_incoming.eml') - str = str.gsub("FROM", 'jake@adventuretime.ooo').gsub("TO", 'incoming+amazing@appmail.adventuretime.ooo') - MockPop3EmailObject.new str - } - let(:expected_post) { fixture_file('emails/valid_incoming.cooked') } - - it "posts a new topic with the correct content" do - expect_success - - poller.handle_mail(email) - - topic = Topic.where(category: category).where.not(id: category.topic_id).last - expect(topic).to be_present - expect(topic.title).to eq("We should have a post-by-email-feature") - - post = topic.posts.first - expect(post.cooked.strip).to eq(expected_post.strip) - - expect(email).to be_deleted - end - - describe "with insufficient trust" do - before do - user.change_trust_level! 0 - end - - it "raises a UserNotSufficientTrustLevelError" do - expect_exception Email::Receiver::UserNotSufficientTrustLevelError - - poller.handle_mail(email) - end - - it "posts the topic if allow_strangers is true" do - begin - category.email_in_allow_strangers = true - category.save - - expect_success - poller.handle_mail(email) - topic = Topic.where(category: category).where.not(id: category.topic_id).last - expect(topic).to be_present - expect(topic.title).to eq("We should have a post-by-email-feature") - ensure - category.email_in_allow_strangers = false - category.save - end - end - end - - describe "user in restricted group" do - - it "raises InvalidAccess error" do - restricted_group = Fabricate(:group) - restricted_group.add(user) - restricted_group.save - - category.set_permissions(restricted_group => :readonly) - category.save - - expect_exception Discourse::InvalidAccess - - poller.handle_mail(email) - expect(email).to be_deleted - end - end - end - - describe "a valid reply" do - let(:email) { MockPop3EmailObject.new fixture_file('emails/valid_reply.eml')} - let(:expected_post) { fixture_file('emails/valid_reply.cooked')} - let(:topic) { Fabricate(:topic) } - let(:first_post) { Fabricate(:post, topic: topic, post_number: 1)} - - before do - first_post.save - EmailLog.create(to_address: 'jake@email.example.com', - email_type: 'user_posted', - reply_key: '59d8df8370b7e95c5a49fbf86aeb2c93', - user: user, - post: first_post, - topic: topic) - end - - it "creates a new post" do - expect_success - - poller.handle_mail(email) - - new_post = Post.find_by(topic: topic, post_number: 2) - assert new_post.present? - assert_equal expected_post.strip, new_post.cooked.strip - - expect(email).to be_deleted - end - - it "works with multiple To addresses" do - email = MockPop3EmailObject.new fixture_file('emails/multiple_destinations.eml') - expect_success - - poller.handle_mail(email) - - new_post = Post.find_by(topic: topic, post_number: 2) - assert new_post.present? - assert_equal expected_post.strip, new_post.cooked.strip - - expect(email).to be_deleted - end - - describe "with the wrong reply key" do - let(:email) { MockPop3EmailObject.new fixture_file('emails/wrong_reply_key.eml') } - - it "raises an EmailLogNotFound error" do - expect_exception Email::Receiver::EmailLogNotFound - - poller.handle_mail(email) - expect(email).to be_deleted - end - end - end - - describe "when topic is closed" do - let(:email) { MockPop3EmailObject.new fixture_file('emails/valid_reply.eml')} - let(:topic) { Fabricate(:topic, closed: true) } - let(:first_post) { Fabricate(:post, topic: topic, post_number: 1)} - - before do - first_post.save - EmailLog.create(to_address: 'jake@email.example.com', - email_type: 'user_posted', - reply_key: '59d8df8370b7e95c5a49fbf86aeb2c93', - user: user, - post: first_post, - topic: topic) - end - - describe "should not create post" do - it "raises a TopicClosedError" do - expect_exception Email::Receiver::TopicClosedError - - poller.handle_mail(email) - expect(email).to be_deleted - end - end - end - - describe "when topic is deleted" do - let(:email) { MockPop3EmailObject.new fixture_file('emails/valid_reply.eml')} - let(:deleted_topic) { Fabricate(:deleted_topic) } - let(:first_post) { Fabricate(:post, topic: deleted_topic, post_number: 1)} - - before do - first_post.save - EmailLog.create(to_address: 'jake@email.example.com', - email_type: 'user_posted', - reply_key: '59d8df8370b7e95c5a49fbf86aeb2c93', - user: user, - post: first_post, - topic: deleted_topic) - end - - describe "should not create post" do - it "raises a TopicNotFoundError" do - expect_exception Email::Receiver::TopicNotFoundError - - poller.handle_mail(email) - expect(email).to be_deleted - end - end - end - - describe "in failure conditions" do - - it "a valid reply without an email log raises an EmailLogNotFound error" do - email = MockPop3EmailObject.new fixture_file('emails/valid_reply.eml') - expect_exception Email::Receiver::EmailLogNotFound - - poller.handle_mail(email) - expect(email).to be_deleted - end - - it "a no content reply raises an EmptyEmailError" do - email = MockPop3EmailObject.new fixture_file('emails/no_content_reply.eml') - expect_exception Email::Receiver::EmptyEmailError - - poller.handle_mail(email) - expect(email).to be_deleted - end - - it "a fully empty email raises an EmptyEmailError" do - email = MockPop3EmailObject.new fixture_file('emails/empty.eml') - expect_exception Email::Receiver::EmptyEmailError - - poller.handle_mail(email) - expect(email).to be_deleted - end - - end - end - end diff --git a/spec/jobs/process_post_spec.rb b/spec/jobs/process_post_spec.rb index 723605373a6..35c6b8e2443 100644 --- a/spec/jobs/process_post_spec.rb +++ b/spec/jobs/process_post_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'jobs/regular/process_post' describe Jobs::ProcessPost do diff --git a/spec/jobs/send_system_message_spec.rb b/spec/jobs/send_system_message_spec.rb index 4025c94e0d0..78f739477c8 100644 --- a/spec/jobs/send_system_message_spec.rb +++ b/spec/jobs/send_system_message_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'jobs/regular/send_system_message' describe Jobs::SendSystemMessage do diff --git a/spec/jobs/test_email_spec.rb b/spec/jobs/test_email_spec.rb index 1c5e4ccb97d..252a96b85e5 100644 --- a/spec/jobs/test_email_spec.rb +++ b/spec/jobs/test_email_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/base' describe Jobs::TestEmail do diff --git a/spec/jobs/tl3_promotions_spec.rb b/spec/jobs/tl3_promotions_spec.rb index b7521691a65..7c4aff73541 100644 --- a/spec/jobs/tl3_promotions_spec.rb +++ b/spec/jobs/tl3_promotions_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Jobs::Tl3Promotions do diff --git a/spec/jobs/update_gravatar_spec.rb b/spec/jobs/update_gravatar_spec.rb index c3f9b452950..0c80a3afcf6 100644 --- a/spec/jobs/update_gravatar_spec.rb +++ b/spec/jobs/update_gravatar_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Jobs::UpdateGravatar do diff --git a/spec/jobs/user_email_spec.rb b/spec/jobs/user_email_spec.rb index d9ac680445e..e7405bade79 100644 --- a/spec/jobs/user_email_spec.rb +++ b/spec/jobs/user_email_spec.rb @@ -1,13 +1,14 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'jobs/base' describe Jobs::UserEmail do before do - SiteSetting.stubs(:email_time_window_mins).returns(10) + SiteSetting.email_time_window_mins = 10 end let(:user) { Fabricate(:user, last_seen_at: 11.minutes.ago ) } + let(:staged) { Fabricate(:user, staged: true, last_seen_at: 11.minutes.ago ) } let(:suspended) { Fabricate(:user, last_seen_at: 10.minutes.ago, suspended_at: 5.minutes.ago, suspended_till: 7.days.from_now ) } let(:anonymous) { Fabricate(:anonymous, last_seen_at: 11.minutes.ago ) } let(:mailer) { Mail::Message.new(to: user.email) } @@ -29,12 +30,17 @@ describe Jobs::UserEmail do Jobs::UserEmail.new.execute(type: :digest, user_id: 1234) end + it "doesn't call the mailer when the user is staged" do + UserNotifications.expects(:digest).never + Jobs::UserEmail.new.execute(type: :digest, user_id: staged.id) + end + context 'to_address' do it 'overwrites a to_address when present' do - UserNotifications.expects(:authorize_email).returns(mailer) + UserNotifications.expects(:confirm_new_email).returns(mailer) Email::Sender.any_instance.expects(:send) - Jobs::UserEmail.new.execute(type: :authorize_email, user_id: user.id, to_address: 'jake@adventuretime.ooo') + Jobs::UserEmail.new.execute(type: :confirm_new_email, user_id: user.id, to_address: 'jake@adventuretime.ooo') expect(mailer.to).to eq(['jake@adventuretime.ooo']) end end @@ -49,12 +55,47 @@ describe Jobs::UserEmail do end it "does send an email to a user that's been recently seen but has email_always set" do - user.update_attributes(last_seen_at: 9.minutes.ago, email_always: true) + user.update_attributes(last_seen_at: 9.minutes.ago) + user.user_option.update_attributes(email_always: true) Email::Sender.any_instance.expects(:send) Jobs::UserEmail.new.execute(type: :user_replied, user_id: user.id, post_id: post.id) end end + context "email_log" do + + before { Fabricate(:post) } + + it "creates an email log when the mail is sent (via Email::Sender)" do + last_emailed_at = user.last_emailed_at + + expect { Jobs::UserEmail.new.execute(type: :digest, user_id: user.id) }.to change { EmailLog.count }.by(1) + + email_log = EmailLog.last + expect(email_log.skipped).to eq(false) + expect(email_log.user_id).to eq(user.id) + + # last_emailed_at should have changed + expect(email_log.user.last_emailed_at).to_not eq(last_emailed_at) + end + + it "creates an email log when the mail is skipped" do + last_emailed_at = user.last_emailed_at + user.update_columns(suspended_till: 1.year.from_now) + + expect { Jobs::UserEmail.new.execute(type: :digest, user_id: user.id) }.to change { EmailLog.count }.by(1) + + email_log = EmailLog.last + expect(email_log.skipped).to eq(true) + expect(email_log.skipped_reason).to be_present + expect(email_log.user_id).to eq(user.id) + + # last_emailed_at doesn't change + expect(email_log.user.last_emailed_at).to eq(last_emailed_at) + end + + end + context 'args' do it 'passes a token as an argument when a token is present' do @@ -129,35 +170,72 @@ describe Jobs::UserEmail do ) } - it 'passes a notification as an argument when a notification_id is present' do - Email::Sender.any_instance.expects(:send) - UserNotifications.expects(:user_mentioned).with(user, notification: notification, post: post).returns(mailer) - Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_id: notification.id) - end - it "doesn't send the email if the notification has been seen" do - Email::Sender.any_instance.expects(:send).never notification.update_column(:read, true) - Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_id: notification.id) + message, err = Jobs::UserEmail.new.message_for_email( + user, + post, + :user_mentioned, + notification, + notification.notification_type, + notification.data_hash, + nil, + nil) + + expect(message).to eq nil + expect(err.skipped_reason).to match(/notification.*already/) end it "does send the email if the notification has been seen but the user is set for email_always" do Email::Sender.any_instance.expects(:send) notification.update_column(:read, true) - user.update_column(:email_always, true) + user.user_option.update_column(:email_always, true) Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_id: notification.id) end + it "does not send notification if limit is reached" do + SiteSetting.max_emails_per_day_per_user = 2 + + user.email_logs.create(email_type: 'blah', to_address: user.email, user_id: user.id) + user.email_logs.create(email_type: 'blah', to_address: user.email, user_id: user.id) + + Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_id: notification.id, post_id: post.id) + + expect(EmailLog.where(user_id: user.id, skipped: true).count).to eq(1) + end + + it "doesn't send the mail if the user is using mailing list mode" do + Email::Sender.any_instance.expects(:send).never + user.user_option.update_column(:mailing_list_mode, true) + # sometimes, we pass the notification_id + Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_id: notification.id, post_id: post.id) + # other times, we only pass the type of notification + Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_type: "posted", post_id: post.id) + # When post is nil + Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_type: "posted") + # When post does not have a topic + post = Fabricate(:post) + post.topic.destroy + Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_type: "posted", post_id: post.id) + end + it "doesn't send the email if the post has been user deleted" do Email::Sender.any_instance.expects(:send).never post.update_column(:user_deleted, true) - Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_id: notification.id) + Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_id: notification.id, post_id: post.id) end context 'user is suspended' do it "doesn't send email for a pm from a regular user" do - Email::Sender.any_instance.expects(:send).never - Jobs::UserEmail.new.execute(type: :user_private_message, user_id: suspended.id, notification_id: notification.id) + msg,err = Jobs::UserEmail.new.message_for_email( + suspended, + Fabricate.build(:post), + :user_private_message, + notification + ) + + expect(msg).to eq(nil) + expect(err).not_to eq(nil) end context 'pm from staff' do @@ -170,19 +248,29 @@ describe Jobs::UserEmail do post_number: @pm_from_staff.post_number, data: { original_post_id: @pm_from_staff.id }.to_json ) - UserNotifications.expects(:user_private_message).with(suspended, notification: @pm_notification, post: @pm_from_staff).returns(mailer) end - subject(:execute_user_email_job) { - Jobs::UserEmail.new.execute(type: :user_private_message, user_id: suspended.id, notification_id: @pm_notification.id) } + let :sent_message do + Jobs::UserEmail.new.message_for_email( + suspended, + @pm_from_staff, + :user_private_message, + @pm_notification + ) + end it "sends an email" do - execute_user_email_job + msg,err = sent_message + expect(msg).not_to be(nil) + expect(err).to be(nil) end it "sends an email even if user was last seen recently" do suspended.update_column(:last_seen_at, 1.minute.ago) - execute_user_email_job + + msg,err = sent_message + expect(msg).not_to be(nil) + expect(err).to be(nil) end end end @@ -212,6 +300,4 @@ describe Jobs::UserEmail do end - end - diff --git a/spec/mailers/invite_mailer_spec.rb b/spec/mailers/invite_mailer_spec.rb index 99695ea05ee..ce847a504a7 100644 --- a/spec/mailers/invite_mailer_spec.rb +++ b/spec/mailers/invite_mailer_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe InviteMailer do diff --git a/spec/mailers/rejection_mailer_spec.rb b/spec/mailers/rejection_mailer_spec.rb index 14140009005..a3d76044b2d 100644 --- a/spec/mailers/rejection_mailer_spec.rb +++ b/spec/mailers/rejection_mailer_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe RejectionMailer do diff --git a/spec/mailers/test_mailer_spec.rb b/spec/mailers/test_mailer_spec.rb index f1f6544d643..68308ef0bed 100644 --- a/spec/mailers/test_mailer_spec.rb +++ b/spec/mailers/test_mailer_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe TestMailer do diff --git a/spec/mailers/user_notifications_spec.rb b/spec/mailers/user_notifications_spec.rb index 7f55cc198d2..00ceb74a3af 100644 --- a/spec/mailers/user_notifications_spec.rb +++ b/spec/mailers/user_notifications_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe UserNotifications do @@ -6,21 +6,47 @@ describe UserNotifications do describe "#get_context_posts" do it "does not include hidden/deleted/user_deleted posts in context" do - post = create_post - reply1 = create_post(topic: post.topic) - reply2 = create_post(topic: post.topic) - reply3 = create_post(topic: post.topic) - reply4 = create_post(topic: post.topic) + post1 = create_post + _post2 = Fabricate(:post, topic: post1.topic, deleted_at: 1.day.ago) + _post3 = Fabricate(:post, topic: post1.topic, user_deleted: true) + _post4 = Fabricate(:post, topic: post1.topic, hidden: true) + _post5 = Fabricate(:post, topic: post1.topic, post_type: Post.types[:moderator_action]) + _post6 = Fabricate(:post, topic: post1.topic, post_type: Post.types[:small_action]) + _post7 = Fabricate(:post, topic: post1.topic, post_type: Post.types[:whisper]) + last = Fabricate(:post, topic: post1.topic) - reply1.trash! + post1.user.user_option.email_previous_replies = UserOption.previous_replies_type[:always] - reply2.user_deleted = true - reply2.save + # default is only post #1 + expect(UserNotifications.get_context_posts(last, nil, post1.user).count).to eq(1) + # staff members can also see the whisper + moderator = build(:moderator) + moderator.user_option = UserOption.new + moderator.user_option.email_previous_replies = UserOption.previous_replies_type[:always] + tu = TopicUser.new(topic: post1.topic, user: moderator) + expect(UserNotifications.get_context_posts(last, tu, tu.user).count).to eq(2) + end - reply3.hidden = true - reply3.save + it "allows users to control context" do + post1 = create_post + _post2 = Fabricate(:post, topic: post1.topic) + post3 = Fabricate(:post, topic: post1.topic) + + user = Fabricate(:user) + TopicUser.change(user.id, post1.topic_id, last_emailed_post_number: 1) + topic_user = TopicUser.find_by(user_id: user.id, topic_id: post1.topic_id) + # to avoid reloads after update_columns + user = topic_user.user + user.user_option.update_columns(email_previous_replies: UserOption.previous_replies_type[:unless_emailed]) + + expect(UserNotifications.get_context_posts(post3, topic_user, user).count).to eq(1) + + user.user_option.update_columns(email_previous_replies: UserOption.previous_replies_type[:never]) + expect(UserNotifications.get_context_posts(post3, topic_user, user).count).to eq(0) + + user.user_option.update_columns(email_previous_replies: UserOption.previous_replies_type[:always]) + expect(UserNotifications.get_context_posts(post3, topic_user, user).count).to eq(2) - expect(UserNotifications.get_context_posts(reply4, nil).count).to eq(1) end end @@ -91,50 +117,56 @@ describe UserNotifications do let(:response_by_user) { Fabricate(:user, name: "John Doe") } let(:category) { Fabricate(:category, name: 'India') } let(:topic) { Fabricate(:topic, category: category) } - let(:post) { Fabricate(:post, topic: topic) } - let(:response) { Fabricate(:post, topic: post.topic, user: response_by_user)} + let(:post) { Fabricate(:post, topic: topic, raw: 'This is My super duper cool topic') } + let(:response) { Fabricate(:post, reply_to_post_number: 1, topic: post.topic, user: response_by_user)} let(:user) { Fabricate(:user) } let(:notification) { Fabricate(:notification, user: user) } it 'generates a correct email' do + + # Fabricator is not fabricating this ... SiteSetting.enable_names = true SiteSetting.display_name_on_posts = true - mail = UserNotifications.user_replied(response.user, post: response, notification: notification) - + mail = UserNotifications.user_replied(response.user, + post: response, + notification_type: notification.notification_type, + notification_data_hash: notification.data_hash + ) # from should include full user name expect(mail[:from].display_names).to eql(['John Doe']) # subject should include category name expect(mail.subject).to match(/India/) + mail_html = mail.html_part.to_s + + expect(mail_html.scan(/My super duper cool topic/).count).to eq(1) + expect(mail_html.scan(/In Reply To/).count).to eq(1) + + # 2 "visit topic" link + expect(mail_html.scan(/Visit Topic/).count).to eq(2) + # 2 respond to links cause we have 1 context post - expect(mail.html_part.to_s.scan(/To respond/).count).to eq(2) + expect(mail_html.scan(/to respond/).count).to eq(2) # 1 unsubscribe - expect(mail.html_part.to_s.scan(/To unsubscribe/).count).to eq(1) + expect(mail_html.scan(/To unsubscribe/).count).to eq(1) # side effect, topic user is updated with post number tu = TopicUser.get(post.topic_id, response.user) expect(tu.last_emailed_post_number).to eq(response.post_number) - # in mailing list mode user_replies is not sent through - response.user.mailing_list_mode = true - mail = UserNotifications.user_replied(response.user, post: response, notification: notification) - if Rails.version >= "4.2.0" - expect(mail.message.class).to eq(ActionMailer::Base::NullMail) - else - expect(mail.class).to eq(ActionMailer::Base::NullMail) - end + # no In Reply To if user opts out + response.user.user_option.email_in_reply_to = false + mail = UserNotifications.user_replied(response.user, + post: response, + notification_type: notification.notification_type, + notification_data_hash: notification.data_hash + ) - response.user.mailing_list_mode = nil - mail = UserNotifications.user_replied(response.user, post: response, notification: notification) - if Rails.version >= "4.2.0" - expect(mail.message.class).not_to eq(ActionMailer::Base::NullMail) - else - expect(mail.class).not_to eq(ActionMailer::Base::NullMail) - end + expect(mail.html_part.to_s.scan(/In Reply To/).count).to eq(0) end end @@ -147,7 +179,11 @@ describe UserNotifications do it 'generates a correct email' do SiteSetting.enable_names = false - mail = UserNotifications.user_posted(response.user, post: response, notification: notification) + mail = UserNotifications.user_posted(response.user, + post: response, + notification_type: notification.notification_type, + notification_data_hash: notification.data_hash + ) # from should not include full user name if "show user full names" is disabled expect(mail[:from].display_names).to_not eql(['John Doe']) @@ -158,8 +194,8 @@ describe UserNotifications do # subject should not include category name expect(mail.subject).not_to match(/Uncategorized/) - # 2 respond to links cause we have 1 context post - expect(mail.html_part.to_s.scan(/To respond/).count).to eq(2) + # 1 respond to links as no context by default + expect(mail.html_part.to_s.scan(/to respond/).count).to eq(1) # 1 unsubscribe link expect(mail.html_part.to_s.scan(/To unsubscribe/).count).to eq(1) @@ -179,7 +215,12 @@ describe UserNotifications do it 'generates a correct email' do SiteSetting.enable_names = true - mail = UserNotifications.user_private_message(response.user, post: response, notification: notification) + mail = UserNotifications.user_private_message( + response.user, + post: response, + notification_type: notification.notification_type, + notification_data_hash: notification.data_hash + ) # from should include username if full user name is not provided expect(mail[:from].display_names).to eql(['john']) @@ -187,8 +228,11 @@ describe UserNotifications do # subject should include "[PM]" expect(mail.subject).to match("[PM]") + # 1 "visit message" link + expect(mail.html_part.to_s.scan(/Visit Message/).count).to eq(1) + # 1 respond to link - expect(mail.html_part.to_s.scan(/To respond/).count).to eq(1) + expect(mail.html_part.to_s.scan(/to respond/).count).to eq(1) # 1 unsubscribe link expect(mail.html_part.to_s.scan(/To unsubscribe/).count).to eq(1) @@ -199,18 +243,38 @@ describe UserNotifications do end end + + it 'adds a warning when mail limit is reached' do + SiteSetting.max_emails_per_day_per_user = 2 + user = Fabricate(:user) + user.email_logs.create(email_type: 'blah', to_address: user.email, user_id: user.id, skipped: false) + + post = Fabricate(:post) + reply = Fabricate(:post, topic_id: post.topic_id) + + notification = Fabricate(:notification, topic_id: post.topic_id, post_number: reply.post_number, + user: post.user, data: {original_username: 'bob'}.to_json) + + mail = UserNotifications.user_replied( + user, + post: reply, + notification_type: notification.notification_type, + notification_data_hash: notification.data_hash + ) + + # WARNING: you reached the limit of 100 email notifications per day. Further emails will be suppressed. + # Consider watching less topics or disabling mailing list mode. + expect(mail.html_part.to_s).to match("WARNING: ") + expect(mail.body.to_s).to match("WARNING: ") + end + def expects_build_with(condition) UserNotifications.any_instance.expects(:build_email).with(user.email, condition) - mailer = UserNotifications.send(mail_type, user, notification: notification, post: notification.post) - - if Rails.version >= "4.2.0" - # Starting from Rails 4.2, calling MyMailer.some_method no longer result - # in an immediate call to MyMailer#some_method. Instead, a "lazy proxy" is - # returned (this is changed to support #deliver_later). As a quick hack to - # fix the test, calling #message (or anything, really) would force the - # Mailer object to be created and the method invoked. - mailer.message - end + mailer = UserNotifications.send(mail_type, user, + notification_type: Notification.types[notification.notification_type], + notification_data_hash: notification.data_hash, + post: notification.post) + mailer.message end shared_examples "supports reply by email" do @@ -229,6 +293,15 @@ describe UserNotifications do end end + # The parts of emails that are derived from templates are translated + shared_examples "sets user locale" do + context "set locale for translating templates" do + it "sets the locale" do + expects_build_with(has_key(:locale)) + end + end + end + shared_examples "notification email building" do let(:post) { Fabricate(:post, user: user) } let(:mail_type) { "user_#{notification_type}"} @@ -302,6 +375,7 @@ describe UserNotifications do include_examples "notification email building" do let(:notification_type) { :mentioned } include_examples "supports reply by email" + include_examples "sets user locale" end end @@ -309,6 +383,7 @@ describe UserNotifications do include_examples "notification email building" do let(:notification_type) { :replied } include_examples "supports reply by email" + include_examples "sets user locale" end end @@ -316,6 +391,7 @@ describe UserNotifications do include_examples "notification email building" do let(:notification_type) { :quoted } include_examples "supports reply by email" + include_examples "sets user locale" end end @@ -323,6 +399,7 @@ describe UserNotifications do include_examples "notification email building" do let(:notification_type) { :posted } include_examples "supports reply by email" + include_examples "sets user locale" end end @@ -330,6 +407,7 @@ describe UserNotifications do include_examples "notification email building" do let(:notification_type) { :invited_to_private_message } include_examples "no reply by email" + include_examples "sets user locale" end end @@ -337,7 +415,61 @@ describe UserNotifications do include_examples "notification email building" do let(:notification_type) { :invited_to_topic } include_examples "no reply by email" + include_examples "sets user locale" end end + # notification emails derived from templates are translated into the user's locale + shared_examples "notification derived from template" do + let(:user) { Fabricate(:user, locale: locale) } + let(:mail_type) { mail_type } + let(:notification) { Fabricate(:notification, user: user) } + end + + describe "notifications from template" do + + context "user locale has been set" do + + %w(signup signup_after_approval confirm_old_email notify_old_email confirm_new_email + forgot_password admin_login account_created).each do |mail_type| + include_examples "notification derived from template" do + SiteSetting.default_locale = "en" + let(:locale) { "fr" } + let(:mail_type) { mail_type } + it "sets the locale" do + expects_build_with(has_entry(:locale, "fr")) + end + end + end + end + + context "user locale has not been set" do + %w(signup signup_after_approval notify_old_email confirm_old_email confirm_new_email + forgot_password admin_login account_created).each do |mail_type| + include_examples "notification derived from template" do + SiteSetting.default_locale = "en" + let(:locale) { nil } + let(:mail_type) { mail_type } + it "sets the locale" do + expects_build_with(has_entry(:locale, nil)) + end + end + end + end + + context "user locale is an empty string" do + %w(signup signup_after_approval notify_old_email confirm_new_email confirm_old_email + forgot_password admin_login account_created).each do |mail_type| + include_examples "notification derived from template" do + SiteSetting.default_locale = "en" + let(:locale) { "" } + let(:mail_type) { mail_type } + it "sets the locale" do + expects_build_with(has_entry(:locale, nil)) + end + end + end + end + + end end diff --git a/spec/mailers/version_mailer_spec.rb b/spec/mailers/version_mailer_spec.rb index a662226400f..24b45d0309f 100644 --- a/spec/mailers/version_mailer_spec.rb +++ b/spec/mailers/version_mailer_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe VersionMailer do subject { VersionMailer.send_notice } diff --git a/spec/models/about_spec.rb b/spec/models/about_spec.rb index 3a217eabeaf..145c1acbe47 100644 --- a/spec/models/about_spec.rb +++ b/spec/models/about_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe About do diff --git a/spec/models/admin_dashboard_data_spec.rb b/spec/models/admin_dashboard_data_spec.rb index 36a029b4778..f15a7b2bad1 100644 --- a/spec/models/admin_dashboard_data_spec.rb +++ b/spec/models/admin_dashboard_data_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe AdminDashboardData do diff --git a/spec/models/api_key_spec.rb b/spec/models/api_key_spec.rb index 79aeac601de..5d163dc368d 100644 --- a/spec/models/api_key_spec.rb +++ b/spec/models/api_key_spec.rb @@ -1,5 +1,5 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require_dependency 'api_key' describe ApiKey do diff --git a/spec/models/application_request_spec.rb b/spec/models/application_request_spec.rb index fb436b6367c..7aca4b71d3e 100644 --- a/spec/models/application_request_spec.rb +++ b/spec/models/application_request_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ApplicationRequest do diff --git a/spec/models/backup_spec.rb b/spec/models/backup_spec.rb index 7be314ba886..14b4544e9f8 100644 --- a/spec/models/backup_spec.rb +++ b/spec/models/backup_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'backup' diff --git a/spec/models/badge_spec.rb b/spec/models/badge_spec.rb index f695d1de887..3ee6bf8ce08 100644 --- a/spec/models/badge_spec.rb +++ b/spec/models/badge_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'badge' describe Badge do @@ -14,5 +14,48 @@ describe Badge do expect(Badge.create!(name: "test", badge_type_id: 1).system?).to be false end + it 'auto translates name' do + badge = Badge.find_by_name("Basic User") + name_english = badge.name + + I18n.locale = 'fr' + + expect(badge.display_name).not_to eq(name_english) + end + + it 'handles changes on badge description and long description correctly for system badges' do + badge = Badge.find_by_name("Basic User") + badge.description = badge.description.dup + badge.long_description = badge.long_description.dup + badge.save + badge.reload + + expect(badge[:description]).to eq(nil) + expect(badge[:long_description]).to eq(nil) + + badge.description = "testing" + badge.long_description = "testing it" + + badge.save + badge.reload + + expect(badge[:description]).to eq("testing") + expect(badge[:long_description]).to eq("testing it") + end + + it 'can ensure consistency' do + b = Badge.first + b.grant_count = 100 + b.save + + UserBadge.create!(user_id: -100, badge_id: b.id, granted_at: 1.minute.ago, granted_by_id: -1) + UserBadge.create!(user_id: User.first.id, badge_id: b.id, granted_at: 1.minute.ago, granted_by_id: -1) + + Badge.ensure_consistency! + + b.reload + expect(b.grant_count).to eq(1) + end + end diff --git a/spec/models/badge_type.rb b/spec/models/badge_type.rb index 8fc13e83dc4..5d265d06e19 100644 --- a/spec/models/badge_type.rb +++ b/spec/models/badge_type.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'badge_type' describe BadgeType do diff --git a/spec/models/category_featured_topic_spec.rb b/spec/models/category_featured_topic_spec.rb index 8aa83e21b96..d6ca194e13c 100644 --- a/spec/models/category_featured_topic_spec.rb +++ b/spec/models/category_featured_topic_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe CategoryFeaturedTopic do diff --git a/spec/models/category_featured_user_spec.rb b/spec/models/category_featured_user_spec.rb index de7e0ff0ad5..bdfcbeaef28 100644 --- a/spec/models/category_featured_user_spec.rb +++ b/spec/models/category_featured_user_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe CategoryFeaturedUser do diff --git a/spec/models/category_group_spec.rb b/spec/models/category_group_spec.rb new file mode 100644 index 00000000000..d884f7f91e7 --- /dev/null +++ b/spec/models/category_group_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +describe CategoryGroup do + + describe '#permission_types' do + context "verify enum sequence" do + before do + @permission_types = CategoryGroup.permission_types + end + + it "'full' should be at 1st position" do + expect(@permission_types[:full]).to eq(1) + end + + it "'readonly' should be at 3rd position" do + expect(@permission_types[:readonly]).to eq(3) + end + end + end +end diff --git a/spec/components/category_list_spec.rb b/spec/models/category_list_spec.rb similarity index 74% rename from spec/components/category_list_spec.rb rename to spec/models/category_list_spec.rb index 808abcd5d81..bb4f3d2d83c 100644 --- a/spec/components/category_list_spec.rb +++ b/spec/models/category_list_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'category_list' describe CategoryList do @@ -16,8 +16,8 @@ describe CategoryList do # uncategorized + this expect(CategoryList.new(Guardian.new admin).categories.count).to eq(2) - expect(CategoryList.new(Guardian.new user).categories.count).to eq(0) - expect(CategoryList.new(Guardian.new nil).categories.count).to eq(0) + expect(CategoryList.new(Guardian.new user).categories.count).to eq(1) + expect(CategoryList.new(Guardian.new nil).categories.count).to eq(1) end it "doesn't show topics that you can't view" do @@ -51,55 +51,16 @@ describe CategoryList do let!(:topic_category) { Fabricate(:category) } - context "without a featured topic" do - - it "should not return empty categories" do - expect(category_list.categories).to be_blank - end - - it "returns empty categories for those who can create them" do - SiteSetting.stubs(:allow_uncategorized_topics).returns(true) - Guardian.any_instance.expects(:can_create?).with(Category).returns(true) - expect(category_list.categories).not_to be_blank - end - - it "returns empty categories with descriptions" do - Fabricate(:category, description: 'The category description.') - Guardian.any_instance.expects(:can_create?).with(Category).returns(false) - expect(category_list.categories).not_to be_blank - end - - it 'returns the empty category and a non-empty category for those who can create them' do - SiteSetting.stubs(:allow_uncategorized_topics).returns(true) - Fabricate(:topic, category: Fabricate(:category)) - Guardian.any_instance.expects(:can_create?).with(Category).returns(true) - expect(category_list.categories.size).to eq(3) - expect(category_list.categories).to include(topic_category) - end - - it "doesn't return empty uncategorized category to admins if allow_uncategorized_topics is false" do - SiteSetting.stubs(:allow_uncategorized_topics).returns(false) - expect(CategoryList.new(Guardian.new(user)).categories).to be_empty - expect(CategoryList.new(Guardian.new(admin)).categories.map(&:id)).not_to include(SiteSetting.uncategorized_category_id) - end - - end - context "with a topic in a category" do let!(:topic) { Fabricate(:topic, category: topic_category) } - let(:category) { category_list.categories.first } + let(:category) { category_list.categories.find{|c| c.id == topic_category.id} } it "should return the category" do expect(category).to be_present - end - - it "returns the correct category" do expect(category.id).to eq(topic_category.id) - end - - it "should contain our topic" do expect(category.featured_topics.include?(topic)).to eq(true) end + end context "with pinned topics in a category" do @@ -107,7 +68,7 @@ describe CategoryList do let!(:topic2) { Fabricate(:topic, category: topic_category, bumped_at: 5.minutes.ago) } let!(:topic3) { Fabricate(:topic, category: topic_category, bumped_at: 2.minutes.ago) } let!(:pinned) { Fabricate(:topic, category: topic_category, pinned_at: 10.minutes.ago, bumped_at: 10.minutes.ago) } - let(:category) { category_list.categories.first } + let(:category) { category_list.categories.find{|c| c.id == topic_category.id} } before do SiteSetting.stubs(:category_featured_topics).returns(2) diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb index a00529fb218..4506c0bbe36 100644 --- a/spec/models/category_spec.rb +++ b/spec/models/category_spec.rb @@ -1,6 +1,6 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require_dependency 'post_creator' describe Category do @@ -36,6 +36,15 @@ describe Category do end end + describe "permissions_params" do + it "returns the right group names and permission type" do + category = Fabricate(:category) + group = Fabricate(:group) + category_group = Fabricate(:category_group, category: category, group: group) + expect(category.permissions_params).to eq({ "#{group.name}" => category_group.permission_type }) + end + end + describe "topic_create_allowed and post_create_allowed" do it "works" do @@ -442,7 +451,7 @@ describe Category do before do post = create_post(user: @category.user, category: @category.name) - SiteSetting.stubs(:ninja_edit_window).returns(1.minute.to_i) + SiteSetting.stubs(:editing_grace_period).returns(1.minute.to_i) post.revise(post.user, { raw: 'updated body' }, revised_at: post.updated_at + 2.minutes) Category.update_stats @@ -494,6 +503,22 @@ describe Category do end end + describe "#url_with_id" do + let(:category) { Fabricate(:category, name: 'cats') } + + it "includes the id in the URL" do + expect(category.url_with_id).to eq("/c/#{category.id}-cats") + end + + context "child category" do + let(:child_category) { Fabricate(:category, parent_category_id: category.id, name: 'dogs') } + + it "includes the id in the URL" do + expect(child_category.url_with_id).to eq("/c/cats/dogs/#{child_category.id}") + end + end + end + describe "uncategorized" do let(:cat) { Category.where(id: SiteSetting.uncategorized_category_id).first } @@ -558,4 +583,14 @@ describe Category do end end + describe "find_by_slug" do + it "finds with category and sub category" do + category = Fabricate(:category, slug: 'awesome-category') + sub_category = Fabricate(:category, parent_category_id: category.id, slug: 'awesome-sub-category') + + expect(Category.find_by_slug('awesome-category')).to eq(category) + expect(Category.find_by_slug('awesome-sub-category', 'awesome-category')).to eq(sub_category) + end + end + end diff --git a/spec/models/category_user_spec.rb b/spec/models/category_user_spec.rb index 2365f611b5c..9d7121c5998 100644 --- a/spec/models/category_user_spec.rb +++ b/spec/models/category_user_spec.rb @@ -1,6 +1,6 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require_dependency 'post_creator' describe CategoryUser do @@ -40,7 +40,7 @@ describe CategoryUser do CategoryUser.create!(user: user, category: tracked_category, notification_level: CategoryUser.notification_levels[:tracking]) watched_post = create_post(category: watched_category) - muted_post = create_post(category: muted_category) + _muted_post = create_post(category: muted_category) tracked_post = create_post(category: tracked_category) expect(Notification.where(user_id: user.id, topic_id: watched_post.topic_id).count).to eq 1 @@ -80,6 +80,41 @@ describe CategoryUser do expect(TopicUser.get(post.topic, user)).to be_blank end + it "does not delete TopicUser record when topic category is changed, and new category has same notification level" do + # this is done so as to maintain topic notification state when topic category is changed and the new category has same notification level for the user + # see: https://meta.discourse.org/t/changing-topic-from-one-watched-category-to-another-watched-category-makes-topic-new-again/36517/15 + + user = Fabricate(:user) + watched_category_1 = Fabricate(:category) + watched_category_2 = Fabricate(:category) + CategoryUser.create!(user: user, category: watched_category_1, notification_level: CategoryUser.notification_levels[:watching]) + CategoryUser.create!(user: user, category: watched_category_2, notification_level: CategoryUser.notification_levels[:watching]) + + post = create_post(category: watched_category_1) + tu = TopicUser.get(post.topic, user) + expect(tu.notification_level).to eq TopicUser.notification_levels[:watching] + + # Now, change the topic's category + post.topic.change_category_to_id(watched_category_2.id) + expect(TopicUser.get(post.topic, user)).to eq tu + end + + it "deletes TopicUser record when topic category is changed, and new category has different notification level" do + user = Fabricate(:user) + watched_category = Fabricate(:category) + tracked_category = Fabricate(:category) + CategoryUser.create!(user: user, category: watched_category, notification_level: CategoryUser.notification_levels[:watching]) + CategoryUser.create!(user: user, category: tracked_category, notification_level: CategoryUser.notification_levels[:tracking]) + + post = create_post(category: watched_category) + tu = TopicUser.get(post.topic, user) + expect(tu.notification_level).to eq TopicUser.notification_levels[:watching] + + # Now, change the topic's category + post.topic.change_category_to_id(tracked_category.id) + expect(TopicUser.get(post.topic, user).notification_level).to eq TopicUser.notification_levels[:tracking] + end + it "is destroyed when a user is deleted" do user = Fabricate(:user) category = Fabricate(:category) @@ -95,4 +130,3 @@ describe CategoryUser do end end - diff --git a/spec/models/color_scheme_color_spec.rb b/spec/models/color_scheme_color_spec.rb index e5ec898c6c3..95830f44094 100644 --- a/spec/models/color_scheme_color_spec.rb +++ b/spec/models/color_scheme_color_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ColorSchemeColor do def test_invalid_hex(hex) diff --git a/spec/models/color_scheme_spec.rb b/spec/models/color_scheme_spec.rb index 5ae8fface08..34f75e4d940 100644 --- a/spec/models/color_scheme_spec.rb +++ b/spec/models/color_scheme_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ColorScheme do @@ -42,6 +42,10 @@ describe ColorScheme do end context "hex_for_name without anything enabled" do + before do + ColorScheme.hex_cache.clear + end + it "returns nil for a missing attribute" do expect(described_class.hex_for_name('undefined')).to eq nil end @@ -55,8 +59,8 @@ describe ColorScheme do describe "destroy" do it "also destroys old versions" do c1 = described_class.create(valid_params.merge(version: 2)) - c2 = described_class.create(valid_params.merge(versioned_id: c1.id, version: 1)) - other = described_class.create(valid_params) + _c2 = described_class.create(valid_params.merge(versioned_id: c1.id, version: 1)) + _other = described_class.create(valid_params) expect { c1.destroy }.to change { described_class.count }.by(-2) @@ -69,6 +73,7 @@ describe ColorScheme do end it "returns the enabled color scheme" do + ColorScheme.hex_cache.clear expect(described_class.hex_for_name('$primary_background_color')).to eq nil c = described_class.create(valid_params.merge(enabled: true)) expect(described_class.enabled.id).to eq c.id diff --git a/spec/models/digest_email_site_setting_spec.rb b/spec/models/digest_email_site_setting_spec.rb index dc07f45dbd6..cebcfb2342b 100644 --- a/spec/models/digest_email_site_setting_spec.rb +++ b/spec/models/digest_email_site_setting_spec.rb @@ -1,13 +1,13 @@ -require 'spec_helper' +require 'rails_helper' describe DigestEmailSiteSetting do describe 'valid_value?' do it 'returns true for a valid value as an int' do - expect(DigestEmailSiteSetting.valid_value?(1)).to eq true + expect(DigestEmailSiteSetting.valid_value?(1440)).to eq true end it 'returns true for a valid value as a string' do - expect(DigestEmailSiteSetting.valid_value?('1')).to eq true + expect(DigestEmailSiteSetting.valid_value?('1440')).to eq true end it 'returns false for an invalid value' do diff --git a/spec/models/digest_unsubscribe_key_spec.rb b/spec/models/digest_unsubscribe_key_spec.rb index f658a402191..c9b9bcab500 100644 --- a/spec/models/digest_unsubscribe_key_spec.rb +++ b/spec/models/digest_unsubscribe_key_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'digest_unsubscribe_key' describe DigestUnsubscribeKey do diff --git a/spec/models/directory_item_spec.rb b/spec/models/directory_item_spec.rb index a21211d68bd..6612686e3f7 100644 --- a/spec/models/directory_item_spec.rb +++ b/spec/models/directory_item_spec.rb @@ -1,14 +1,35 @@ -require 'spec_helper' +require 'rails_helper' describe DirectoryItem do + + describe '#period_types' do + context "verify enum sequence" do + before do + @period_types = DirectoryItem.period_types + end + + it "'all' should be at 1st position" do + expect(@period_types[:all]).to eq(1) + end + + it "'quarterly' should be at 6th position" do + expect(@period_types[:quarterly]).to eq(6) + end + end + end + context 'refresh' do - let!(:post) { Fabricate(:post) } + before do + ActiveRecord::Base.observers.enable :all + end + + let!(:post) { create_post } it "creates the record for the user" do DirectoryItem.refresh! expect(DirectoryItem.where(period_type: DirectoryItem.period_types[:all]) .where(user_id: post.user.id) - .exists?).to be_truthy + .where(topic_count: 1).count).to eq(1) end end diff --git a/spec/models/discourse_single_sign_on_spec.rb b/spec/models/discourse_single_sign_on_spec.rb index 08f950b4bf9..552682dde55 100644 --- a/spec/models/discourse_single_sign_on_spec.rb +++ b/spec/models/discourse_single_sign_on_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe DiscourseSingleSignOn do before do diff --git a/spec/models/draft_sequence_spec.rb b/spec/models/draft_sequence_spec.rb index 8ed65ed450a..8fe559a77d5 100644 --- a/spec/models/draft_sequence_spec.rb +++ b/spec/models/draft_sequence_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe DraftSequence do it 'should produce next sequence for a key' do diff --git a/spec/models/draft_spec.rb b/spec/models/draft_spec.rb index 16746ad4ee2..96782b28b45 100644 --- a/spec/models/draft_spec.rb +++ b/spec/models/draft_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Draft do before do diff --git a/spec/models/email_log_spec.rb b/spec/models/email_log_spec.rb index 70a0a799460..3b5ca7df465 100644 --- a/spec/models/email_log_spec.rb +++ b/spec/models/email_log_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe EmailLog do @@ -26,6 +26,21 @@ describe EmailLog do end end + describe '#reached_max_emails?' do + it "tracks when max emails are reached" do + SiteSetting.max_emails_per_day_per_user = 2 + user.email_logs.create(email_type: 'blah', to_address: user.email, user_id: user.id, skipped: true) + user.email_logs.create(email_type: 'blah', to_address: user.email, user_id: user.id) + user.email_logs.create(email_type: 'blah', to_address: user.email, user_id: user.id, created_at: 3.days.ago) + + expect(EmailLog.reached_max_emails?(user)).to eq(false) + + user.email_logs.create(email_type: 'blah', to_address: user.email, user_id: user.id) + + expect(EmailLog.reached_max_emails?(user)).to eq(true) + end + end + describe '#count_per_day' do it "counts sent emails" do user.email_logs.create(email_type: 'blah', to_address: user.email) diff --git a/spec/models/email_token_spec.rb b/spec/models/email_token_spec.rb index b1651ea59ac..cf62b1c5cd3 100644 --- a/spec/models/email_token_spec.rb +++ b/spec/models/email_token_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe EmailToken do diff --git a/spec/models/embeddable_host_spec.rb b/spec/models/embeddable_host_spec.rb index 83043104d93..4ee44c56085 100644 --- a/spec/models/embeddable_host_spec.rb +++ b/spec/models/embeddable_host_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe EmbeddableHost do @@ -20,6 +20,12 @@ describe EmbeddableHost do expect(eh.host).to eq('example.com') end + it "supports ip addresses" do + eh = EmbeddableHost.new(host: '192.168.0.1') + expect(eh).to be_valid + expect(eh.host).to eq('192.168.0.1') + end + describe "allows_embeddable_host" do let!(:host) { Fabricate(:embeddable_host) } diff --git a/spec/models/given_daily_like_spec.rb b/spec/models/given_daily_like_spec.rb new file mode 100644 index 00000000000..b3a86367769 --- /dev/null +++ b/spec/models/given_daily_like_spec.rb @@ -0,0 +1,50 @@ +require 'rails_helper' + +describe GivenDailyLike do + + it 'no errors without a user' do + expect(-> { GivenDailyLike.increment_for(nil) }).not_to raise_error + expect(-> { GivenDailyLike.decrement_for(nil) }).not_to raise_error + end + + context 'with a user' do + let(:user) { Fabricate(:user) } + + def value_for(user_id, date) + GivenDailyLike.find_for(user_id, date).pluck(:likes_given)[0] || 0 + end + + def limit_reached_for(user_id, date) + GivenDailyLike.find_for(user_id, date).pluck(:limit_reached)[0] || false + end + + it 'can be incremented and decremented' do + SiteSetting.max_likes_per_day = 2 + + Timecop.freeze(Date.today) do + dt = Date.today + + expect(value_for(user.id, dt)).to eq(0) + expect(limit_reached_for(user.id, dt)).to eq(false) + + GivenDailyLike.increment_for(user.id) + expect(value_for(user.id, dt)).to eq(1) + expect(limit_reached_for(user.id, dt)).to eq(false) + + GivenDailyLike.increment_for(user.id) + expect(value_for(user.id, dt)).to eq(2) + expect(limit_reached_for(user.id, dt)).to eq(true) + + GivenDailyLike.decrement_for(user.id) + expect(value_for(user.id, dt)).to eq(1) + expect(limit_reached_for(user.id, dt)).to eq(false) + + GivenDailyLike.decrement_for(user.id) + expect(value_for(user.id, dt)).to eq(0) + expect(limit_reached_for(user.id, dt)).to eq(false) + end + end + + end + +end diff --git a/spec/models/global_setting_spec.rb b/spec/models/global_setting_spec.rb index a29886b307f..dbe1b94c2e0 100644 --- a/spec/models/global_setting_spec.rb +++ b/spec/models/global_setting_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'tempfile' describe GlobalSetting::EnvProvider do diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index b1d484d9633..36ad2b32c48 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -1,7 +1,23 @@ -require 'spec_helper' +require 'rails_helper' describe Group do + describe '#builtin' do + context "verify enum sequence" do + before do + @builtin = Group.builtin + end + + it "'moderators' should be at 1st position" do + expect(@builtin[:moderators]).to eq(1) + end + + it "'trust_level_2' should be at 4th position" do + expect(@builtin[:trust_level_2]).to eq(4) + end + end + end + # UGLY but perf is horrible with this callback before do User.set_callback(:create, :after, :ensure_in_trust_level_group) @@ -33,6 +49,26 @@ describe Group do group.name = 'This_Is_A_Name' expect(group.valid?).to eq false end + + it "is invalid for poorly formatted domains" do + group.automatic_membership_email_domains = "wikipedia.org|*@example.com" + expect(group.valid?).to eq false + end + + it "is valid for proper domains" do + group.automatic_membership_email_domains = "discourse.org|wikipedia.org" + expect(group.valid?).to eq true + end + + it "is invalid for bad incoming email" do + group.incoming_email = "foo.bar.org" + expect(group.valid?).to eq(false) + end + + it "is valid for proper incoming email" do + group.incoming_email = "foo@bar.org" + expect(group.valid?).to eq(true) + end end def real_admins @@ -292,21 +328,21 @@ describe Group do let(:group) {Fabricate(:group)} it "by default has no managers" do - expect(group.managers).to be_empty + expect(group.group_users.where('group_users.owner')).to be_empty end it "multiple managers can be appointed" do 2.times do |i| u = Fabricate(:user) - group.appoint_manager(u) + group.add_owner(u) end - expect(group.managers.count).to eq(2) + expect(group.group_users.where('group_users.owner').count).to eq(2) end it "manager has authority to edit membership" do u = Fabricate(:user) expect(Guardian.new(u).can_edit?(group)).to be_falsy - group.appoint_manager(u) + group.add_owner(u) expect(Guardian.new(u).can_edit?(group)).to be_truthy end end diff --git a/spec/models/incoming_link_spec.rb b/spec/models/incoming_link_spec.rb index a03871a66b5..1e32b9d0bd7 100644 --- a/spec/models/incoming_link_spec.rb +++ b/spec/models/incoming_link_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe IncomingLink do diff --git a/spec/models/incoming_links_report_spec.rb b/spec/models/incoming_links_report_spec.rb index 2320298ca35..1ed432f7452 100644 --- a/spec/models/incoming_links_report_spec.rb +++ b/spec/models/incoming_links_report_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe IncomingLinksReport do @@ -40,8 +40,8 @@ describe IncomingLinksReport do r = IncomingLinksReport.find('top_referrers').as_json expect(r[:data]).to eq [ - {username: p1.user.username, num_clicks: 7 + 2, num_topics: 2}, - {username: p2.user.username, num_clicks: 3, num_topics: 1} + {username: p1.user.username, user_id: p1.user.id, num_clicks: 7 + 2, num_topics: 2}, + {username: p2.user.username, user_id: p2.user.id, num_clicks: 3, num_topics: 1} ] r = IncomingLinksReport.find('top_traffic_sources').as_json @@ -98,8 +98,8 @@ describe IncomingLinksReport do Fabricate(:incoming_link, user: bob, post: post1).save end - expect(top_referrers[:data][0]).to eq({username: 'amy', num_clicks: 3, num_topics: 2}) - expect(top_referrers[:data][1]).to eq({username: 'bob', num_clicks: 2, num_topics: 1}) + expect(top_referrers[:data][0]).to eq({username: 'amy', user_id: amy.id, num_clicks: 3, num_topics: 2}) + expect(top_referrers[:data][1]).to eq({username: 'bob', user_id: bob.id, num_clicks: 2, num_topics: 1}) end end diff --git a/spec/models/invite_redeemer_spec.rb b/spec/models/invite_redeemer_spec.rb index bc30a173f5d..a61819fd49c 100644 --- a/spec/models/invite_redeemer_spec.rb +++ b/spec/models/invite_redeemer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe InviteRedeemer do diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb index 63ef8e3db9d..61a6e684666 100644 --- a/spec/models/invite_spec.rb +++ b/spec/models/invite_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Invite do diff --git a/spec/models/locale_site_setting_spec.rb b/spec/models/locale_site_setting_spec.rb index c999e336d58..6a19cb7d8d0 100644 --- a/spec/models/locale_site_setting_spec.rb +++ b/spec/models/locale_site_setting_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe LocaleSiteSetting do diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index af9dbc8e4cc..ef64bcfbe39 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Notification do before do @@ -11,6 +11,22 @@ describe Notification do it { is_expected.to belong_to :user } it { is_expected.to belong_to :topic } + describe '#types' do + context "verify enum sequence" do + before do + @types = Notification.types + end + + it "'mentioned' should be at 1st position" do + expect(@types[:mentioned]).to eq(1) + end + + it "'group_mentioned' should be at 15th position" do + expect(@types[:group_mentioned]).to eq(15) + end + end + end + describe 'post' do let(:topic) { Fabricate(:topic) } let(:post_args) do @@ -69,6 +85,7 @@ describe Notification do end end + describe 'unread counts' do let(:user) { Fabricate(:user) } @@ -142,8 +159,11 @@ describe Notification do before do @topic = Fabricate(:private_message_topic) @post = Fabricate(:post, topic: @topic, user: @topic.user) - PostAlerter.post_created(@post) @target = @post.topic.topic_allowed_users.reject{|a| a.user_id == @post.user_id}[0].user + + TopicUser.change(@target.id, @topic.id, notification_level: TopicUser.notification_levels[:watching]) + + PostAlerter.post_created(@post) end it 'should create and rollup private message notifications' do @@ -155,7 +175,6 @@ describe Notification do Fabricate(:post, topic: @topic, user: @topic.user) @target.reload expect(@target.unread_private_messages).to eq(1) - end end @@ -222,7 +241,7 @@ describe Notification do end Notification.create!(read: true, user_id: user.id, topic_id: 2, post_number: 4, data: '{}', notification_type: 1) - expect(Notification.mark_posts_read(user,2,[1,2,3,4])).to eq(3) + expect { Notification.mark_posts_read(user,2,[1,2,3,4]) }.to change { Notification.where(read: true).count }.by(3) end end diff --git a/spec/models/optimized_image_spec.rb b/spec/models/optimized_image_spec.rb index 6d27e247b9f..40ea15c0d11 100644 --- a/spec/models/optimized_image_spec.rb +++ b/spec/models/optimized_image_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe OptimizedImage do diff --git a/spec/models/permalink_spec.rb b/spec/models/permalink_spec.rb index e86e8c469a1..131fbeae5e8 100644 --- a/spec/models/permalink_spec.rb +++ b/spec/models/permalink_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe Permalink do diff --git a/spec/models/plugin_store_spec.rb b/spec/models/plugin_store_spec.rb index bd84395c8d0..9c236a04368 100644 --- a/spec/models/plugin_store_spec.rb +++ b/spec/models/plugin_store_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" require_dependency "plugin_store" describe PluginStore do diff --git a/spec/models/post_action_spec.rb b/spec/models/post_action_spec.rb index 8bd4648c016..e5809521e75 100644 --- a/spec/models/post_action_spec.rb +++ b/spec/models/post_action_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'post_destroyer' describe PostAction do @@ -12,6 +12,28 @@ describe PostAction do let(:second_post) { Fabricate(:post, topic_id: post.topic_id) } let(:bookmark) { PostAction.new(user_id: post.user_id, post_action_type_id: PostActionType.types[:bookmark] , post_id: post.id) } + def value_for(user_id, dt) + GivenDailyLike.find_for(user_id, dt).pluck(:likes_given)[0] || 0 + end + + describe "rate limits" do + + it "limits redo/undo" do + + RateLimiter.stubs(:disabled?).returns(false) + + PostAction.act(eviltrout, post, PostActionType.types[:like]) + PostAction.remove_act(eviltrout, post, PostActionType.types[:like]) + PostAction.act(eviltrout, post, PostActionType.types[:like]) + PostAction.remove_act(eviltrout, post, PostActionType.types[:like]) + + expect { + PostAction.act(eviltrout, post, PostActionType.types[:like]) + }.to raise_error + + end + end + describe "messaging" do it "doesn't generate title longer than 255 characters" do @@ -43,8 +65,11 @@ describe PostAction do expect(topic_user_ids).to include(codinghorror.id) expect(topic_user_ids).to include(mod.id) - # Notification level should be "Watching" for everyone - expect(topic.topic_users(true).map(&:notification_level).uniq).to eq([TopicUser.notification_levels[:watching]]) + expect(topic.topic_users.where(user_id: mod.id) + .pluck(:notification_level).first).to eq(TopicUser.notification_levels[:tracking]) + + expect(topic.topic_users.where(user_id: codinghorror.id) + .pluck(:notification_level).first).to eq(TopicUser.notification_levels[:watching]) # reply to PM should not clear flag PostCreator.new(mod, topic_id: posts[0].topic_id, raw: "This is my test reply to the user, it should clear flags").create @@ -147,19 +172,24 @@ describe PostAction do describe "update_counters" do it "properly updates topic counters" do - # we need this to test it - TopicUser.change(codinghorror, post.topic, posted: true) + Timecop.freeze(Date.today) do + # we need this to test it + TopicUser.change(codinghorror, post.topic, posted: true) - PostAction.act(moderator, post, PostActionType.types[:like]) - PostAction.act(codinghorror, second_post, PostActionType.types[:like]) + expect(value_for(moderator.id, Date.today)).to eq(0) - post.topic.reload - expect(post.topic.like_count).to eq(2) + PostAction.act(moderator, post, PostActionType.types[:like]) + PostAction.act(codinghorror, second_post, PostActionType.types[:like]) - tu = TopicUser.get(post.topic, codinghorror) - expect(tu.liked).to be true - expect(tu.bookmarked).to be false + post.topic.reload + expect(post.topic.like_count).to eq(2) + expect(value_for(moderator.id, Date.today)).to eq(1) + + tu = TopicUser.get(post.topic, codinghorror) + expect(tu.liked).to be true + expect(tu.bookmarked).to be false + end end end @@ -218,29 +248,33 @@ describe PostAction do end it 'should increase the `like_count` and `like_score` when a user likes something' do - PostAction.act(codinghorror, post, PostActionType.types[:like]) - post.reload - expect(post.like_count).to eq(1) - expect(post.like_score).to eq(1) - post.topic.reload - expect(post.topic.like_count).to eq(1) + Timecop.freeze(Date.today) do + PostAction.act(codinghorror, post, PostActionType.types[:like]) + post.reload + expect(post.like_count).to eq(1) + expect(post.like_score).to eq(1) + post.topic.reload + expect(post.topic.like_count).to eq(1) + expect(value_for(codinghorror.id, Date.today)).to eq(1) - # When a staff member likes it - PostAction.act(moderator, post, PostActionType.types[:like]) - post.reload - expect(post.like_count).to eq(2) - expect(post.like_score).to eq(4) + # When a staff member likes it + PostAction.act(moderator, post, PostActionType.types[:like]) + post.reload + expect(post.like_count).to eq(2) + expect(post.like_score).to eq(4) - # Removing likes - PostAction.remove_act(codinghorror, post, PostActionType.types[:like]) - post.reload - expect(post.like_count).to eq(1) - expect(post.like_score).to eq(3) + # Removing likes + PostAction.remove_act(codinghorror, post, PostActionType.types[:like]) + post.reload + expect(post.like_count).to eq(1) + expect(post.like_score).to eq(3) + expect(value_for(codinghorror.id, Date.today)).to eq(0) - PostAction.remove_act(moderator, post, PostActionType.types[:like]) - post.reload - expect(post.like_count).to eq(0) - expect(post.like_score).to eq(0) + PostAction.remove_act(moderator, post, PostActionType.types[:like]) + post.reload + expect(post.like_count).to eq(0) + expect(post.like_score).to eq(0) + end end end @@ -345,8 +379,8 @@ describe PostAction do post.reload expect(post.hidden).to eq(false) - expect(post.hidden_reason_id).to eq(nil) - expect(post.hidden_at).to be_blank + expect(post.hidden_reason_id).to eq(Post.hidden_reasons[:flag_threshold_reached]) # keep most recent reason + expect(post.hidden_at).to be_present # keep the most recent hidden_at time expect(post.topic.visible).to eq(true) PostAction.act(eviltrout, post, PostActionType.types[:spam]) @@ -461,8 +495,6 @@ describe PostAction do end it "prevents user to act twice at the same time" do - post = Fabricate(:post) - # flags are already being tested all_types_except_flags = PostActionType.types.except(PostActionType.flag_types) all_types_except_flags.values.each do |action| @@ -516,6 +548,22 @@ describe PostAction do topic.reload expect(topic.posts.count).to eq(1) end + + it "should create a notification in the related topic" do + post = Fabricate(:post) + user = Fabricate(:user) + action = PostAction.act(user, post, PostActionType.types[:spam], message: "WAT") + topic = action.reload.related_post.topic + expect(user.notifications.count).to eq(0) + + SiteSetting.expects(:auto_respond_to_flag_actions).returns(true) + PostAction.agree_flags!(post, admin) + + user_notifications = user.notifications + expect(user_notifications.count).to eq(1) + expect(user_notifications.last.topic).to eq(topic) + end + end describe "rate limiting" do diff --git a/spec/models/post_action_type_spec.rb b/spec/models/post_action_type_spec.rb new file mode 100644 index 00000000000..7408ed6693c --- /dev/null +++ b/spec/models/post_action_type_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +describe PostActionType do + + describe '#types' do + context "verify enum sequence" do + before do + @types = PostActionType.types + end + + it "'bookmark' should be at 1st position" do + expect(@types[:bookmark]).to eq(1) + end + + it "'spam' should be at 8th position" do + expect(@types[:spam]).to eq(8) + end + end + end +end diff --git a/spec/models/post_alert_observer_spec.rb b/spec/models/post_alert_observer_spec.rb index 0b72771d60b..be6f8c7876c 100644 --- a/spec/models/post_alert_observer_spec.rb +++ b/spec/models/post_alert_observer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'post_destroyer' describe PostAlertObserver do @@ -21,11 +21,8 @@ describe PostAlertObserver do end context 'when removing a liked post' do - before do - PostAction.act(evil_trout, post, PostActionType.types[:like]) - end - it 'removes a notification' do + PostAction.act(evil_trout, post, PostActionType.types[:like]) expect { PostAction.remove_act(evil_trout, post, PostActionType.types[:like]) }.to change(Notification, :count).by(-1) @@ -74,8 +71,7 @@ describe PostAlertObserver do expect { Guardian.any_instance.expects(:can_see?).with(instance_of(Post)).returns(false) mention_post - PostAlerter.new.after_create_post(mention_post) - PostAlerter.new.after_save_post(mention_post) + PostAlerter.post_created(mention_post) }.not_to change(evil_trout.notifications, :count) end diff --git a/spec/models/post_analyzer_spec.rb b/spec/models/post_analyzer_spec.rb index f2bc5f1f334..3940fa73d82 100644 --- a/spec/models/post_analyzer_spec.rb +++ b/spec/models/post_analyzer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PostAnalyzer do @@ -205,5 +205,15 @@ describe PostAnalyzer do post_analyzer = PostAnalyzer.new("@Jake @Finn @Jake_Old", default_topic_id) expect(post_analyzer.raw_mentions).to eq(['jake', 'finn', 'jake_old']) end + + it "handles hyphen in groupname" do + post_analyzer = PostAnalyzer.new("@org-board", default_topic_id) + expect(post_analyzer.raw_mentions).to eq(['org-board']) + end + + it "ignores emails" do + post_analyzer = PostAnalyzer.new("1@test.com 1@best.com @best @not", default_topic_id) + expect(post_analyzer.raw_mentions).to eq(['best', 'not']) + end end end diff --git a/spec/models/post_detail_spec.rb b/spec/models/post_detail_spec.rb index 940b8a0a416..7697a412523 100644 --- a/spec/models/post_detail_spec.rb +++ b/spec/models/post_detail_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PostDetail do it { is_expected.to belong_to :post } diff --git a/spec/models/post_mover_spec.rb b/spec/models/post_mover_spec.rb index d67ef6e6e0d..c90dcae0cb9 100644 --- a/spec/models/post_mover_spec.rb +++ b/spec/models/post_mover_spec.rb @@ -1,7 +1,23 @@ -require 'spec_helper' +require 'rails_helper' describe PostMover do + describe '#move_types' do + context "verify enum sequence" do + before do + @move_types = PostMover.move_types + end + + it "'new_topic' should be at 1st position" do + expect(@move_types[:new_topic]).to eq(1) + end + + it "'existing_topic' should be at 2nd position" do + expect(@move_types[:existing_topic]).to eq(2) + end + end + end + context 'move_posts' do let(:user) { Fabricate(:user) } let(:another_user) { Fabricate(:evil_trout) } @@ -52,19 +68,20 @@ describe PostMover do context "successfully moved" do before do - topic.expects(:add_moderator_post) TopicUser.update_last_read(user, topic.id, p4.post_number, 0) TopicLink.extract_from(p2) end context "to a new topic" do - let!(:new_topic) { topic.move_posts(user, [p2.id, p4.id], title: "new testing topic name", category_id: category.id) } it "works correctly" do + topic.expects(:add_moderator_post).once + new_topic = topic.move_posts(user, [p2.id, p4.id], title: "new testing topic name", category_id: category.id) + expect(TopicUser.find_by(user_id: user.id, topic_id: topic.id).last_read_post_number).to eq(p3.post_number) expect(new_topic).to be_present - expect(new_topic.featured_user1_id).to eq(another_user.id) + expect(new_topic.featured_user1_id).to eq(p4.user_id) expect(new_topic.like_count).to eq(1) expect(new_topic.category).to eq(category) @@ -97,22 +114,31 @@ describe PostMover do action = UserAction.find_by(user_id: another_user.id) expect(action.target_topic_id).to eq(new_topic.id) end + + it "moving all posts will close the topic" do + topic.expects(:add_moderator_post).twice + new_topic = topic.move_posts(user, [p1.id, p2.id, p3.id, p4.id], title: "new testing topic name", category_id: category.id) + expect(new_topic).to be_present + + topic.reload + expect(topic.closed).to eq(true) + end end context "to an existing topic" do - let!(:destination_topic) { Fabricate(:topic, user: user ) } let!(:destination_op) { Fabricate(:post, topic: destination_topic, user: user) } - let!(:moved_to) { topic.move_posts(user, [p2.id, p4.id], destination_topic_id: destination_topic.id)} it "works correctly" do + topic.expects(:add_moderator_post).once + moved_to = topic.move_posts(user, [p2.id, p4.id], destination_topic_id: destination_topic.id) expect(moved_to).to eq(destination_topic) # Check out new topic moved_to.reload expect(moved_to.posts_count).to eq(3) expect(moved_to.highest_post_number).to eq(3) - expect(moved_to.featured_user1_id).to eq(another_user.id) + expect(moved_to.user_id).to eq(p1.user_id) expect(moved_to.like_count).to eq(1) expect(moved_to.category_id).to eq(SiteSetting.uncategorized_category_id) @@ -144,13 +170,23 @@ describe PostMover do # Should update last reads expect(TopicUser.find_by(user_id: user.id, topic_id: topic.id).last_read_post_number).to eq(p3.post_number) end + + it "moving all posts will close the topic" do + topic.expects(:add_moderator_post).twice + moved_to = topic.move_posts(user, [p1.id, p2.id, p3.id, p4.id], destination_topic_id: destination_topic.id) + expect(moved_to).to be_present + + topic.reload + expect(topic.closed).to eq(true) + end end context "moving the first post" do - let!(:new_topic) { topic.move_posts(user, [p1.id, p2.id], title: "new testing topic name") } - it "copies the OP, doesn't delete it" do + topic.expects(:add_moderator_post).once + new_topic = topic.move_posts(user, [p1.id, p2.id], title: "new testing topic name") + expect(new_topic).to be_present new_topic.posts.reload expect(new_topic.posts.by_post_number.first.raw).to eq(p1.raw) @@ -187,6 +223,10 @@ describe PostMover do context "to an existing topic with a deleted post" do + before do + topic.expects(:add_moderator_post) + end + let!(:destination_topic) { Fabricate(:topic, user: user ) } let!(:destination_op) { Fabricate(:post, topic: destination_topic, user: user) } let!(:destination_deleted_reply) { Fabricate(:post, topic: destination_topic, user: another_user) } diff --git a/spec/models/post_reply_spec.rb b/spec/models/post_reply_spec.rb index 1e34c0ae43b..e3392e338e7 100644 --- a/spec/models/post_reply_spec.rb +++ b/spec/models/post_reply_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PostReply do diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index a85b327f27b..33f9f7d4c23 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -1,9 +1,57 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'post_destroyer' describe Post do before { Oneboxer.stubs :onebox } + describe '#hidden_reasons' do + context "verify enum sequence" do + before do + @hidden_reasons = Post.hidden_reasons + end + + it "'flag_threshold_reached' should be at 1st position" do + expect(@hidden_reasons[:flag_threshold_reached]).to eq(1) + end + + it "'flagged_by_tl3_user' should be at 4th position" do + expect(@hidden_reasons[:flagged_by_tl3_user]).to eq(4) + end + end + end + + describe '#types' do + context "verify enum sequence" do + before do + @types = Post.types + end + + it "'regular' should be at 1st position" do + expect(@types[:regular]).to eq(1) + end + + it "'whisper' should be at 4th position" do + expect(@types[:whisper]).to eq(4) + end + end + end + + describe '#cook_methods' do + context "verify enum sequence" do + before do + @cook_methods = Post.cook_methods + end + + it "'regular' should be at 1st position" do + expect(@cook_methods[:regular]).to eq(1) + end + + it "'email' should be at 3rd position" do + expect(@cook_methods[:email]).to eq(3) + end + end + end + # Help us build a post with a raw body def post_with_body(body, user=nil) args = post_args.merge(raw: body) @@ -89,11 +137,12 @@ describe Post do end describe 'flagging helpers' do - it 'isFlagged is accurate' do - post = Fabricate(:post) - user = Fabricate(:coding_horror) - PostAction.act(user, post, PostActionType.types[:off_topic]) + let(:post) { Fabricate(:post) } + let(:user) { Fabricate(:coding_horror) } + let(:admin) { Fabricate(:admin) } + it 'isFlagged is accurate' do + PostAction.act(user, post, PostActionType.types[:off_topic]) post.reload expect(post.is_flagged?).to eq(true) @@ -101,6 +150,16 @@ describe Post do post.reload expect(post.is_flagged?).to eq(false) end + + it 'has_active_flag is accurate' do + PostAction.act(user, post, PostActionType.types[:spam]) + post.reload + expect(post.has_active_flag?).to eq(true) + + PostAction.defer_flags!(post, admin) + post.reload + expect(post.has_active_flag?).to eq(false) + end end describe "maximum images" do @@ -378,6 +437,11 @@ describe Post do expect(post.raw_mentions).to eq(['jake', 'finn', 'jake_old']) end + it "handles hyphen in groupname" do + post = Fabricate.build(:post, post_args.merge(raw: "@org-board")) + expect(post.raw_mentions).to eq(['org-board']) + end + end context "max mentions" do @@ -481,7 +545,7 @@ describe Post do describe 'ninja editing & edit windows' do - before { SiteSetting.stubs(:ninja_edit_window).returns(1.minute.to_i) } + before { SiteSetting.stubs(:editing_grace_period).returns(1.minute.to_i) } it 'works' do revised_at = post.updated_at + 2.minutes @@ -548,7 +612,7 @@ describe Post do context 'second poster posts again quickly' do it 'is a ninja edit, because the second poster posted again quickly' do - SiteSetting.expects(:ninja_edit_window).returns(1.minute.to_i) + SiteSetting.expects(:editing_grace_period).returns(1.minute.to_i) post.revise(changed_by, { raw: 'yet another updated body' }, revised_at: post.updated_at + 10.seconds) post.reload diff --git a/spec/models/post_timing_spec.rb b/spec/models/post_timing_spec.rb index beb39c3d57d..7817cee98b9 100644 --- a/spec/models/post_timing_spec.rb +++ b/spec/models/post_timing_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PostTiming do diff --git a/spec/models/post_upload_spec.rb b/spec/models/post_upload_spec.rb index 4e370c1a8dd..9830844d670 100644 --- a/spec/models/post_upload_spec.rb +++ b/spec/models/post_upload_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PostUpload do diff --git a/spec/models/queued_post_spec.rb b/spec/models/queued_post_spec.rb index d316fb001ae..8a16ca3a921 100644 --- a/spec/models/queued_post_spec.rb +++ b/spec/models/queued_post_spec.rb @@ -1,8 +1,24 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'queued_post' describe QueuedPost do + describe '#states' do + context "verify enum sequence" do + before do + @states = QueuedPost.states + end + + it "'new' should be at 1st position" do + expect(@states[:new]).to eq(1) + end + + it "'rejected' should be at 3rd position" do + expect(@states[:rejected]).to eq(3) + end + end + end + context "creating a post" do let(:topic) { Fabricate(:topic) } let(:user) { Fabricate(:user) } diff --git a/spec/models/quoted_post_spec.rb b/spec/models/quoted_post_spec.rb index dc34fa4a47a..77bb741339d 100644 --- a/spec/models/quoted_post_spec.rb +++ b/spec/models/quoted_post_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe QuotedPost do it 'correctly extracts quotes in integration test' do diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb index a013f210970..8ea96c9cfcb 100644 --- a/spec/models/report_spec.rb +++ b/spec/models/report_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Report do diff --git a/spec/models/rtl_spec.rb b/spec/models/rtl_spec.rb index 780743a0bbb..74b3462cc1f 100644 --- a/spec/models/rtl_spec.rb +++ b/spec/models/rtl_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe RTL do diff --git a/spec/models/s3_region_site_setting_spec.rb b/spec/models/s3_region_site_setting_spec.rb index aae52e3eda2..ffba50b7f76 100644 --- a/spec/models/s3_region_site_setting_spec.rb +++ b/spec/models/s3_region_site_setting_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe S3RegionSiteSetting do @@ -14,7 +14,7 @@ describe S3RegionSiteSetting do describe 'values' do it 'returns all the S3 regions' do - expect(S3RegionSiteSetting.values.map {|x| x[:value]}.sort).to eq(['us-east-1', 'us-west-1', 'us-west-2', 'us-gov-west-1', 'eu-west-1', 'eu-central-1', 'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1', 'sa-east-1'].sort) + expect(S3RegionSiteSetting.values.map {|x| x[:value]}.sort).to eq(['us-east-1', 'us-west-1', 'us-west-2', 'us-gov-west-1', 'eu-west-1', 'eu-central-1', 'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1', 'ap-northeast-2', 'sa-east-1'].sort) end end diff --git a/spec/models/screened_email_spec.rb b/spec/models/screened_email_spec.rb index 0621b69cdfa..73647731585 100644 --- a/spec/models/screened_email_spec.rb +++ b/spec/models/screened_email_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ScreenedEmail do diff --git a/spec/models/screened_ip_address_spec.rb b/spec/models/screened_ip_address_spec.rb index ef176fb2cda..c26b1151be2 100644 --- a/spec/models/screened_ip_address_spec.rb +++ b/spec/models/screened_ip_address_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ScreenedIpAddress do let(:ip_address) { '99.232.23.124' } @@ -240,20 +240,29 @@ describe ScreenedIpAddress do describe '#block_admin_login?' do context 'no allow_admin records exist' do - it "returns false when user is nil" do - expect(described_class.block_admin_login?(nil, '123.12.12.12')).to eq(false) - end - it "returns false for non-admin user" do + it "returns false when use_admin_ip_whitelist is false" do expect(described_class.block_admin_login?(Fabricate.build(:user), '123.12.12.12')).to eq(false) end - it "returns false for admin user" do - expect(described_class.block_admin_login?(Fabricate.build(:admin), '123.12.12.12')).to eq(false) - end + context "use_admin_ip_whitelist is true" do + before { SiteSetting.stubs(:use_admin_ip_whitelist).returns(true) } - it "returns false for admin user and ip_address arg is nil" do - expect(described_class.block_admin_login?(Fabricate.build(:admin), nil)).to eq(false) + it "returns false when user is nil" do + expect(described_class.block_admin_login?(nil, '123.12.12.12')).to eq(false) + end + + it "returns false for non-admin user" do + expect(described_class.block_admin_login?(Fabricate.build(:user), '123.12.12.12')).to eq(false) + end + + it "returns false for admin user" do + expect(described_class.block_admin_login?(Fabricate.build(:admin), '123.12.12.12')).to eq(false) + end + + it "returns false for admin user and ip_address arg is nil" do + expect(described_class.block_admin_login?(Fabricate.build(:admin), nil)).to eq(false) + end end end @@ -263,24 +272,32 @@ describe ScreenedIpAddress do Fabricate(:screened_ip_address, ip_address: @permitted_ip_address, action_type: described_class.actions[:allow_admin]) end - it "returns false when user is nil" do - expect(described_class.block_admin_login?(nil, @permitted_ip_address)).to eq(false) + it "returns false when use_admin_ip_whitelist is false" do + expect(described_class.block_admin_login?(Fabricate.build(:admin), '123.12.12.12')).to eq(false) end - it "returns false for an admin user at the allowed ip address" do - expect(described_class.block_admin_login?(Fabricate.build(:admin), @permitted_ip_address)).to eq(false) - end + context "use_admin_ip_whitelist is true" do + before { SiteSetting.stubs(:use_admin_ip_whitelist).returns(true) } - it "returns true for an admin user at another ip address" do - expect(described_class.block_admin_login?(Fabricate.build(:admin), '123.12.12.12')).to eq(true) - end + it "returns false when user is nil" do + expect(described_class.block_admin_login?(nil, @permitted_ip_address)).to eq(false) + end - it "returns false for regular user at allowed ip address" do - expect(described_class.block_admin_login?(Fabricate.build(:user), @permitted_ip_address)).to eq(false) - end + it "returns false for an admin user at the allowed ip address" do + expect(described_class.block_admin_login?(Fabricate.build(:admin), @permitted_ip_address)).to eq(false) + end - it "returns false for regular user at another ip address" do - expect(described_class.block_admin_login?(Fabricate.build(:user), '123.12.12.12')).to eq(false) + it "returns true for an admin user at another ip address" do + expect(described_class.block_admin_login?(Fabricate.build(:admin), '123.12.12.12')).to eq(true) + end + + it "returns false for regular user at allowed ip address" do + expect(described_class.block_admin_login?(Fabricate.build(:user), @permitted_ip_address)).to eq(false) + end + + it "returns false for regular user at another ip address" do + expect(described_class.block_admin_login?(Fabricate.build(:user), '123.12.12.12')).to eq(false) + end end end end diff --git a/spec/models/screened_url_spec.rb b/spec/models/screened_url_spec.rb index bdebf88ecc7..6da3fd47696 100644 --- a/spec/models/screened_url_spec.rb +++ b/spec/models/screened_url_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ScreenedUrl do diff --git a/spec/models/search_observer_spec.rb b/spec/models/search_observer_spec.rb index 34455c4155c..dc0a2daaf38 100644 --- a/spec/models/search_observer_spec.rb +++ b/spec/models/search_observer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe SearchObserver do diff --git a/spec/models/site_customization_spec.rb b/spec/models/site_customization_spec.rb index b3ab1a8459c..ca87b12bcac 100644 --- a/spec/models/site_customization_spec.rb +++ b/spec/models/site_customization_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe SiteCustomization do @@ -91,5 +91,65 @@ describe SiteCustomization do expect(c.stylesheet_baked).not_to be_present end + it 'should correct bad html in body_tag_baked and head_tag_baked' do + c = SiteCustomization.create!(user_id: -1, name: "test", head_tag: "I am bold", body_tag: "I am bold") + expect(c.head_tag_baked).to eq("I am bold") + expect(c.body_tag_baked).to eq("I am bold") + end + + it 'should precompile fragments in body and head tags' do + with_template = < + {{hello}} + + +HTML + c = SiteCustomization.create!(user_id: -1, name: "test", head_tag: with_template, body_tag: with_template) + expect(c.head_tag_baked).to match(/HTMLBars/) + expect(c.body_tag_baked).to match(/HTMLBars/) + expect(c.body_tag_baked).to match(/EmberCompatHandlebars/) + expect(c.head_tag_baked).to match(/EmberCompatHandlebars/) + end + + it 'should create body_tag_baked on demand if needed' do + c = SiteCustomization.create!(user_id: -1, name: "test", head_tag: "test", enabled: true) + c.update_columns(head_tag_baked: nil) + expect(SiteCustomization.custom_head_tag).to match(/test<\/b>/) + end + + context "plugin api" do + def transpile(html) + c = SiteCustomization.create!(user_id: -1, name: "test", head_tag: html, body_tag: html) + c.head_tag_baked + end + + it "transpiles ES6 code" do + html = < + const x = 1; + +HTML + + transpiled = transpile(html) + expect(transpiled).to match(/\/) + expect(transpiled).to match(/var x = 1;/) + expect(transpiled).to match(/_registerPluginCode\('0.1'/) + end + + it "converts errors to a script type that is not evaluated" do + html = < + const x = 1; + x = 2; + +HTML + + transpiled = transpile(html) + expect(transpiled).to match(/text\/discourse-js-error/) + expect(transpiled).to match(/read-only/) + end + end end diff --git a/spec/models/site_setting_spec.rb b/spec/models/site_setting_spec.rb index 444bd6f032b..b4ac6a8ff2b 100644 --- a/spec/models/site_setting_spec.rb +++ b/spec/models/site_setting_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'site_setting' require_dependency 'site_setting_extension' diff --git a/spec/models/site_spec.rb b/spec/models/site_spec.rb index 392d1bf47a9..a3376a4c4e9 100644 --- a/spec/models/site_spec.rb +++ b/spec/models/site_spec.rb @@ -1,8 +1,11 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'site' describe Site do it "omits categories users can not write to from the category list" do + + ActiveRecord::Base.observers.enable :anon_site_json_cache_observer + category = Fabricate(:category) user = Fabricate(:user) diff --git a/spec/models/site_text_spec.rb b/spec/models/site_text_spec.rb deleted file mode 100644 index 2245683593d..00000000000 --- a/spec/models/site_text_spec.rb +++ /dev/null @@ -1,83 +0,0 @@ -require 'spec_helper' - -describe SiteText do - - it { is_expected.to validate_presence_of :value } - - - describe "#text_for" do - - it "returns an empty string for a missing text_type" do - expect(SiteText.text_for('something_random')).to eq("") - end - - it "returns the default value for a text` type with a default" do - expect(SiteText.text_for("usage_tips")).to be_present - end - - it "correctly expires and bypasses cache" do - SiteSetting.enable_sso = false - text = SiteText.create!(text_type: "got.sso", value: "got sso: %{enable_sso}") - expect(SiteText.text_for("got.sso")).to eq("got sso: false") - SiteText.text_for("got.sso").frozen? == true - - SiteSetting.enable_sso = true - wait_for do - SiteText.text_for("got.sso") == "got sso: true" - end - - text.value = "I gots sso: %{enable_sso}" - text.save! - - wait_for do - SiteText.text_for("got.sso") == "I gots sso: true" - end - - expect(SiteText.text_for("got.sso", enable_sso: "frog")).to eq("I gots sso: frog") - end - - context "without replacements" do - let!(:site_text) { Fabricate(:site_text_basic) } - - it "returns the simple string" do - expect(SiteText.text_for('breaking.bad')).to eq("best show ever") - end - - end - - context "with replacements" do - let!(:site_text) { Fabricate(:site_text) } - let(:replacements) { {flower: 'roses', food: 'grapes'} } - - it "returns the correct string with replacements" do - expect(SiteText.text_for('great.poem', replacements)).to eq("roses are red. grapes are blue.") - end - - it "doesn't mind extra keys in the replacements" do - expect(SiteText.text_for('great.poem', replacements.merge(extra: 'key'))).to eq("roses are red. grapes are blue.") - end - - it "ignores missing keys" do - expect(SiteText.text_for('great.poem', flower: 'roses')).to eq("roses are red. %{food} are blue.") - end - end - - - context "replacing site_settings" do - let!(:site_text) { Fabricate(:site_text_site_setting) } - - it "replaces site_settings by default" do - SiteSetting.title = "Evil Trout" - expect(SiteText.text_for('site.replacement')).to eq("Evil Trout is evil.") - end - - it "allows us to override the default site settings" do - SiteSetting.title = "Evil Trout" - expect(SiteText.text_for('site.replacement', title: 'Good Tuna')).to eq("Good Tuna is evil.") - end - - end - - end - -end diff --git a/spec/models/stylesheet_cache_spec.rb b/spec/models/stylesheet_cache_spec.rb index ef26433bbbf..eb52d07bcc3 100644 --- a/spec/models/stylesheet_cache_spec.rb +++ b/spec/models/stylesheet_cache_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe StylesheetCache do diff --git a/spec/models/top_menu_item_spec.rb b/spec/models/top_menu_item_spec.rb index 4f716f8e5fd..a92df985ffc 100644 --- a/spec/models/top_menu_item_spec.rb +++ b/spec/models/top_menu_item_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopMenuItem do before(:each) { SiteSetting.stubs(:top_menu).returns('one,-nope|two|three,-not|four,ignored|category/xyz') } diff --git a/spec/models/top_topic_spec.rb b/spec/models/top_topic_spec.rb index 4bb99d7c90c..7c73a98b3cd 100644 --- a/spec/models/top_topic_spec.rb +++ b/spec/models/top_topic_spec.rb @@ -1,7 +1,23 @@ -require 'spec_helper' +require 'rails_helper' describe TopTopic do + describe '#sorted_periods' do + context "verify enum sequence" do + before do + @sorted_periods = TopTopic.sorted_periods + end + + it "'daily' should be at 1st position" do + expect(@sorted_periods[:daily]).to eq(1) + end + + it "'all' should be at 6th position" do + expect(@sorted_periods[:all]).to eq(6) + end + end + end + it { is_expected.to belong_to :topic } context "refresh!" do @@ -22,9 +38,108 @@ describe TopTopic do it "should have top topics" do expect(TopTopic.pluck(:topic_id)).to match_array([t1.id, t2.id]) end - end - end + describe "#compute_top_score_for" do + + let(:user) { Fabricate(:user) } + let(:coding_horror) { Fabricate(:coding_horror) } + + let!(:topic_1) { Fabricate(:topic, posts_count: 10, like_count: 28) } + let!(:t1_post_1) { Fabricate(:post, topic: topic_1, like_count: 28, post_number: 1)} + + let!(:topic_2) { Fabricate(:topic, posts_count: 10, like_count: 20) } + let!(:t2_post_1) { Fabricate(:post, topic: topic_2, like_count: 10, post_number: 1) } + let!(:t2_post_2) { Fabricate(:post, topic: topic_2, like_count: 10) } + + let!(:topic_3) { Fabricate(:topic, posts_count: 10) } + let!(:t3_post_1) { Fabricate(:post, topic_id: topic_3.id) } + let!(:t3_view_1) { TopicViewItem.add(topic_3.id, '127.0.0.1', user) } + let!(:t3_view_2) { TopicViewItem.add(topic_3.id, '127.0.0.2', coding_horror) } + + # Note: all topics has 10 posts so we can skip "0 - ((10 - topics.posts_count) / 20) * #{period}_op_likes_count" calculation + + it "should compute top score" do + # Default Formula: log(views_count) * {2} + op_likes_count * {0.5} + LEAST(likes_count / posts_count, {3}) + 10 + log(posts_count) + # + # topic_1 => 0 + 14 + 3 + 10 + 0 => 27 + # topic_2 => 0 + 5 + 3 + 10 + 0.301029995664 => 18.301029995664 + # topic_3 => 0.602059991328 + 0 + 0 + 10 + 0 => 10.602059991328 + + TopTopic.refresh! + top_topics = TopTopic.all + + expect(top_topics.where(topic_id: topic_1.id).pluck(:yearly_score).first).to eq(27) + expect(top_topics.where(topic_id: topic_2.id).pluck(:yearly_score).first).to eq(18.301029995664) + expect(top_topics.where(topic_id: topic_3.id).pluck(:yearly_score).first).to eq(10.602059991328) + + # when 'top_topics_formula_log_views_multiplier' setting is changed + SiteSetting.top_topics_formula_log_views_multiplier = 4 + SiteSetting.top_topics_formula_first_post_likes_multiplier = 0.5 # unchanged + SiteSetting.top_topics_formula_least_likes_per_post_multiplier = 3 # unchanged + + # New Formula: log(views_count) * {4} + op_likes_count * {0.5} + LEAST(likes_count / posts_count, {3}) + 10 + log(posts_count) + # + # topic_1 => 0 + 14 + 3 + 10 + 0 => 27 + # topic_2 => 0 + 5 + 3 + 10 + 0.301029995664 => 18.301029995664 + # topic_3 => 1.2041199826559 + 0 + 0 + 10 + 0 => 11.2041199826559 + + TopTopic.refresh! + top_topics = TopTopic.all + + expect(top_topics.where(topic_id: topic_1.id).pluck(:yearly_score).first).to eq(27) + expect(top_topics.where(topic_id: topic_2.id).pluck(:yearly_score).first).to eq(18.301029995664) + expect(top_topics.where(topic_id: topic_3.id).pluck(:yearly_score).first).to eq(11.2041199826559) + + # when 'top_topics_formula_first_post_likes_multiplier' setting is changed + SiteSetting.top_topics_formula_log_views_multiplier = 2 # unchanged + SiteSetting.top_topics_formula_first_post_likes_multiplier = 2 + SiteSetting.top_topics_formula_least_likes_per_post_multiplier = 3 # unchanged + + # New Formula: log(views_count) * {2} + op_likes_count * {2} + LEAST(likes_count / posts_count, {3}) + 10 + log(posts_count) + # + # topic_1 => 0 + 56 + 3 + 10 + 0 => 69 + # topic_2 => 0 + 20 + 3 + 10 + 0.301029995664 => 33.301029995664 + # topic_3 => 0.602059991328 + 0 + 0 + 10 + 0 => 10.602059991328 + + TopTopic.refresh! + top_topics = TopTopic.all + + expect(top_topics.where(topic_id: topic_1.id).pluck(:yearly_score).first).to eq(69) + expect(top_topics.where(topic_id: topic_2.id).pluck(:yearly_score).first).to eq(33.301029995664) + expect(top_topics.where(topic_id: topic_3.id).pluck(:yearly_score).first).to eq(10.602059991328) + + # when 'top_topics_formula_least_likes_per_post_multiplier' setting is changed + SiteSetting.top_topics_formula_log_views_multiplier = 2 # unchanged + SiteSetting.top_topics_formula_first_post_likes_multiplier = 0.5 # unchanged + SiteSetting.top_topics_formula_least_likes_per_post_multiplier = 6 + + # New Formula: log(views_count) * {2} + op_likes_count * {0.5} + LEAST(likes_count / posts_count, {6}) + 10 + log(posts_count) + # + # topic_1 => 0 + 14 + 6 + 10 + 0 => 30 + # topic_2 => 0 + 5 + 6 + 10 + 0.301029995664 => 21.301029995664 + # topic_3 => 0.602059991328 + 0 + 0 + 10 + 0 => 10.602059991328 + + TopTopic.refresh! + top_topics = TopTopic.all + + expect(top_topics.where(topic_id: topic_1.id).pluck(:yearly_score).first).to eq(30) + expect(top_topics.where(topic_id: topic_2.id).pluck(:yearly_score).first).to eq(21.301029995664) + expect(top_topics.where(topic_id: topic_3.id).pluck(:yearly_score).first).to eq(10.602059991328) + + # handles invalid string value + SiteSetting.top_topics_formula_log_views_multiplier = "not good" + SiteSetting.top_topics_formula_first_post_likes_multiplier = "not good" + SiteSetting.top_topics_formula_least_likes_per_post_multiplier = "not good" + + TopTopic.refresh! + top_topics = TopTopic.all + + expect(top_topics.where(topic_id: topic_1.id).pluck(:yearly_score).first).to eq(27) + expect(top_topics.where(topic_id: topic_2.id).pluck(:yearly_score).first).to eq(18.301029995664) + expect(top_topics.where(topic_id: topic_3.id).pluck(:yearly_score).first).to eq(10.602059991328) + + end + end end diff --git a/spec/models/topic_allowed_user_spec.rb b/spec/models/topic_allowed_user_spec.rb index c3a8a85c251..6b78330900c 100644 --- a/spec/models/topic_allowed_user_spec.rb +++ b/spec/models/topic_allowed_user_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopicAllowedUser do it { is_expected.to belong_to :user } diff --git a/spec/models/topic_embed_spec.rb b/spec/models/topic_embed_spec.rb index 8c9b3409d8f..564259c4919 100644 --- a/spec/models/topic_embed_spec.rb +++ b/spec/models/topic_embed_spec.rb @@ -1,4 +1,5 @@ -require 'spec_helper' +require 'rails_helper' +require 'stringio' describe TopicEmbed do @@ -30,7 +31,8 @@ describe TopicEmbed do expect(post.cooked).to eq(post.raw) # It converts relative URLs to absolute - expect(post.cooked.start_with?("hello world new post hello ")).to eq(true) + expect(post.cooked).to have_tag('a', with: { href: 'http://eviltrout.com/hello' }) + expect(post.cooked).to have_tag('img', with: { src: 'http://eviltrout.com/images/wat.jpg' }) expect(post.topic.has_topic_embed?).to eq(true) expect(TopicEmbed.where(topic_id: post.topic_id)).to be_present @@ -58,4 +60,78 @@ describe TopicEmbed do end + describe '.find_remote' do + + context 'post with allowed classes "foo" and "emoji"' do + + let(:user) { Fabricate(:user) } + let(:url) { 'http://eviltrout.com/123' } + let(:contents) { "my normal size emoji

    Hi

    " } + let!(:embeddable_host) { Fabricate(:embeddable_host) } + let!(:file) { StringIO.new } + + content = '' + + before(:each) do + SiteSetting.stubs(:embed_classname_whitelist).returns 'emoji , foo' + file.stubs(:read).returns contents + TopicEmbed.stubs(:open).returns file + title, content = TopicEmbed.find_remote(url) + end + + it 'img node has emoji class' do + expect(content).to have_tag('img', with: { class: 'emoji' }) + end + + it 'img node has foo class' do + expect(content).to have_tag('img', with: { class: 'foo' }) + end + + it 'p node has foo class' do + expect(content).to have_tag('p', with: { class: 'foo' }) + end + + it 'nodes removes classes other than emoji' do + expect(content).to have_tag('img', without: { class: 'other' }) + end + + end + + context 'post with no allowed classes' do + + let(:user) { Fabricate(:user) } + let(:url) { 'http://eviltrout.com/123' } + let(:contents) { "my normal size emoji

    Hi

    " } + let!(:embeddable_host) { Fabricate(:embeddable_host) } + let!(:file) { StringIO.new } + + content = '' + + before(:each) do + SiteSetting.stubs(:embed_classname_whitelist).returns ' ' + file.stubs(:read).returns contents + TopicEmbed.stubs(:open).returns file + title, content = TopicEmbed.find_remote(url) + end + + it 'img node doesn\'t have emoji class' do + expect(content).to have_tag('img', without: { class: 'emoji' }) + end + + it 'img node doesn\'t have foo class' do + expect(content).to have_tag('img', without: { class: 'foo' }) + end + + it 'p node doesn\'t foo class' do + expect(content).to have_tag('p', without: { class: 'foo' }) + end + + it 'img node doesn\'t have other class' do + expect(content).to have_tag('img', without: { class: 'other' }) + end + + end + + end + end diff --git a/spec/models/topic_featured_users_spec.rb b/spec/models/topic_featured_users_spec.rb index 593cda22eda..71ff4a54235 100644 --- a/spec/models/topic_featured_users_spec.rb +++ b/spec/models/topic_featured_users_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopicFeaturedUsers do it 'ensures consistenct' do diff --git a/spec/models/topic_invite_spec.rb b/spec/models/topic_invite_spec.rb index d93e9eb34fb..8c55ee1ca79 100644 --- a/spec/models/topic_invite_spec.rb +++ b/spec/models/topic_invite_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopicInvite do diff --git a/spec/models/topic_link_click_spec.rb b/spec/models/topic_link_click_spec.rb index b8c4bb8c7c1..5dd27a3fe8f 100644 --- a/spec/models/topic_link_click_spec.rb +++ b/spec/models/topic_link_click_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopicLinkClick do diff --git a/spec/models/topic_link_spec.rb b/spec/models/topic_link_spec.rb index 41eca976f69..a8338311b2a 100644 --- a/spec/models/topic_link_spec.rb +++ b/spec/models/topic_link_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopicLink do @@ -37,7 +37,7 @@ http://b.com/#{'a'*500} it 'works' do # has the forum topic links - expect(topic.topic_links.count).to eq(2) + expect(topic.topic_links.count).to eq(3) # works with markdown links expect(topic.topic_links.exists?(url: "http://a.com/")).to eq(true) diff --git a/spec/models/topic_participants_summary_spec.rb b/spec/models/topic_participants_summary_spec.rb index b704752490a..29e2edb4cf6 100644 --- a/spec/models/topic_participants_summary_spec.rb +++ b/spec/models/topic_participants_summary_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopicParticipantsSummary do describe '#summary' do diff --git a/spec/models/topic_posters_summary_spec.rb b/spec/models/topic_posters_summary_spec.rb index 72cd027c69d..928e772b654 100644 --- a/spec/models/topic_posters_summary_spec.rb +++ b/spec/models/topic_posters_summary_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopicPostersSummary do describe '#summary' do diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb index ccaed7b06e4..6c071fce293 100644 --- a/spec/models/topic_spec.rb +++ b/spec/models/topic_spec.rb @@ -1,6 +1,6 @@ # encoding: utf-8 -require 'spec_helper' +require 'rails_helper' require_dependency 'post_destroyer' describe Topic do @@ -214,7 +214,7 @@ describe Topic do context 'title_fancy_entities disabled' do before do - SiteSetting.stubs(:title_fancy_entities).returns(false) + SiteSetting.title_fancy_entities = false end it "doesn't add entities to the title" do @@ -224,11 +224,26 @@ describe Topic do context 'title_fancy_entities enabled' do before do - SiteSetting.stubs(:title_fancy_entities).returns(true) + SiteSetting.title_fancy_entities = true end - it "converts the title to have fancy entities" do + it "converts the title to have fancy entities and updates" do expect(topic.fancy_title).to eq("“this topic” – has “fancy stuff”") + topic.title = "this is my test hello world... yay" + topic.user.save! + topic.save! + topic.reload + expect(topic.fancy_title).to eq("This is my test hello world… yay") + + topic.title = "I made a change to the title" + topic.save! + + topic.reload + expect(topic.fancy_title).to eq("I made a change to the title") + + # another edge case + topic.title = "this is another edge case" + expect(topic.fancy_title).to eq("this is another edge case") end end end @@ -363,7 +378,7 @@ describe Topic do expect(topic.invite(topic.user, walter.username)).to eq(true) expect(topic.allowed_users.include?(walter)).to eq(true) - expect(topic.remove_allowed_user(walter.username)).to eq(true) + expect(topic.remove_allowed_user(topic.user, walter.username)).to eq(true) topic.reload expect(topic.allowed_users.include?(walter)).to eq(false) end @@ -371,6 +386,11 @@ describe Topic do it 'creates a notification' do expect { topic.invite(topic.user, walter.username) }.to change(Notification, :count) end + + it 'creates a small action post' do + expect { topic.invite(topic.user, walter.username) }.to change(Post, :count) + expect { topic.remove_allowed_user(topic.user, walter.username) }.to change(Post, :count) + end end context 'by email' do @@ -449,7 +469,7 @@ describe Topic do it "doesn't bump the topic on an edit to the last post that doesn't result in a new version" do expect { - SiteSetting.expects(:ninja_edit_window).returns(5.minutes) + SiteSetting.expects(:editing_grace_period).returns(5.minutes) @last_post.revise(@last_post.user, { raw: 'updated contents' }, revised_at: @last_post.created_at + 10.seconds) @topic.reload }.not_to change(@topic, :bumped_at) @@ -1276,6 +1296,16 @@ describe Topic do expect(Topic.for_digest(user, 1.year.ago, top_order: true)).to be_blank end + it "doesn't return topics from suppressed categories" do + user = Fabricate(:user) + category = Fabricate(:category) + Fabricate(:topic, category: category) + + SiteSetting.digest_suppress_categories = "#{category.id}" + + expect(Topic.for_digest(user, 1.year.ago, top_order: true)).to be_blank + end + it "doesn't return topics from TL0 users" do new_user = Fabricate(:user, trust_level: 0) Fabricate(:topic, user_id: new_user.id) @@ -1283,6 +1313,16 @@ describe Topic do expect(Topic.for_digest(user, 1.year.ago, top_order: true)).to be_blank end + it "returns topics from TL0 users if enabled in preferences" do + new_user = Fabricate(:user, trust_level: 0) + topic = Fabricate(:topic, user_id: new_user.id) + + u = Fabricate(:user) + u.user_option.include_tl0_in_digests = true + + expect(Topic.for_digest(u, 1.year.ago, top_order: true)).to eq([topic]) + end + end describe 'secured' do @@ -1300,6 +1340,47 @@ describe Topic do end end + describe 'all_allowed_users' do + let(:group) { Fabricate(:group) } + let(:topic) { Fabricate(:topic, allowed_groups: [group]) } + let!(:allowed_user) { Fabricate(:user) } + let!(:allowed_group_user) { Fabricate(:user) } + let!(:moderator) { Fabricate(:user, moderator: true) } + let!(:rando) { Fabricate(:user) } + + before do + topic.allowed_users << allowed_user + group.users << allowed_group_user + end + + it 'includes allowed_users' do + expect(topic.all_allowed_users).to include allowed_user + end + + it 'includes allowed_group_users' do + expect(topic.all_allowed_users).to include allowed_group_user + end + + it 'includes moderators if flagged and a pm' do + topic.stubs(:has_flags?).returns(true) + topic.stubs(:private_message?).returns(true) + expect(topic.all_allowed_users).to include moderator + end + + it 'does not include moderators if pm without flags' do + topic.stubs(:private_message?).returns(true) + expect(topic.all_allowed_users).not_to include moderator + end + + it 'does not include moderators for regular topic' do + expect(topic.all_allowed_users).not_to include moderator + end + + it 'does not include randos' do + expect(topic.all_allowed_users).not_to include rando + end + end + describe '#listable_count_per_day' do before(:each) do Timecop.freeze @@ -1482,7 +1563,7 @@ describe Topic do context 'invite by group manager' do let(:group_manager) { Fabricate(:user) } - let(:group) { Fabricate(:group).tap { |g| g.add(group_manager); g.appoint_manager(group_manager) } } + let(:group) { Fabricate(:group).tap { |g| g.add_owner(group_manager) } } let(:private_category) { Fabricate(:private_category, group: group) } let(:group_private_topic) { Fabricate(:topic, category: private_category, user: group_manager) } @@ -1507,9 +1588,36 @@ describe Topic do expect(Guardian.new(walter).can_see?(group_private_topic)).to be_truthy end end + end - context 'to a previously-invited user' do + it "Correctly sets #message_archived?" do + topic = Fabricate(:private_message_topic) + user = topic.user + expect(topic.message_archived?(user)).to eq(false) + + group = Fabricate(:group) + group.add(user) + + TopicAllowedGroup.create!(topic_id: topic.id, group_id: group.id) + GroupArchivedMessage.create!(topic_id: topic.id, group_id: group.id) + + expect(topic.message_archived?(user)).to eq(true) + end + + it 'will trigger :topic_status_updated' do + topic = Fabricate(:topic) + user = topic.user + user.admin = true + @topic_status_event_triggered = false + + DiscourseEvent.on(:topic_status_updated) do + @topic_status_event_triggered = true end + + topic.update_status('closed', true, user) + topic.reload + + expect(@topic_status_event_triggered).to eq(true) end end diff --git a/spec/models/topic_status_update_spec.rb b/spec/models/topic_status_update_spec.rb index 787c56aa906..549adb9e872 100644 --- a/spec/models/topic_status_update_spec.rb +++ b/spec/models/topic_status_update_spec.rb @@ -1,20 +1,23 @@ # encoding: UTF-8 -require 'spec_helper' +require 'rails_helper' require_dependency 'post_destroyer' +# TODO - test pinning, create_moderator_post + describe TopicStatusUpdate do let(:user) { Fabricate(:user) } let(:admin) { Fabricate(:admin) } it "avoids notifying on automatically closed topics" do - # TODO: TopicStatusUpdate should supress message bus updates from the users it "pretends to read" + # TODO: TopicStatusUpdate should suppress message bus updates from the users it "pretends to read" post = PostCreator.create(user, raw: "this is a test post 123 this is a test post", title: "hello world title", ) # TODO needed so counts sync up, PostCreator really should not give back out-of-date Topic + post.topic.set_auto_close('10') post.topic.reload TopicStatusUpdate.new(post.topic, admin).update!("autoclosed", true) @@ -27,6 +30,7 @@ describe TopicStatusUpdate do it "adds an autoclosed message" do topic = create_topic + topic.set_auto_close('10') TopicStatusUpdate.new(topic, admin).update!("autoclosed", true) @@ -39,13 +43,14 @@ describe TopicStatusUpdate do it "adds an autoclosed message based on last post" do topic = create_topic topic.auto_close_based_on_last_post = true + topic.set_auto_close('10') TopicStatusUpdate.new(topic, admin).update!("autoclosed", true) last_post = topic.posts.last expect(last_post.post_type).to eq(Post.types[:small_action]) expect(last_post.action_code).to eq('autoclosed.enabled') - expect(last_post.raw).to eq(I18n.t("topic_statuses.autoclosed_enabled_lastpost_minutes", count: 0)) + expect(last_post.raw).to eq(I18n.t("topic_statuses.autoclosed_enabled_lastpost_hours", count: 10)) end end diff --git a/spec/models/topic_tracking_state_spec.rb b/spec/models/topic_tracking_state_spec.rb index de8e3ff6b9e..5410f69eed4 100644 --- a/spec/models/topic_tracking_state_spec.rb +++ b/spec/models/topic_tracking_state_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopicTrackingState do @@ -41,8 +41,6 @@ describe TopicTrackingState do it "correctly handles capping" do - $redis.del TopicUser.unread_cap_key - user = Fabricate(:user) post1 = create_post @@ -67,20 +65,6 @@ describe TopicTrackingState do report = TopicTrackingState.report(user.id) expect(report.length).to eq(3) - SiteSetting.max_tracked_new_unread = 5 - # business logic, we allow for 2/5th new .. 2/5th unread ... 1/5th buffer - - TopicUser.cap_unread_backlog! - - report = TopicTrackingState.report(user.id) - expect(report.length).to eq(3) - - TopicUser.cap_unread_later(user.id) - TopicUser.cap_unread_backlog! - - report = TopicTrackingState.report(user.id) - expect(report.length).to eq(2) - end it "correctly gets the tracking state" do diff --git a/spec/models/topic_user_spec.rb b/spec/models/topic_user_spec.rb index 4498d6e3608..f51b90b3352 100644 --- a/spec/models/topic_user_spec.rb +++ b/spec/models/topic_user_spec.rb @@ -1,7 +1,39 @@ -require 'spec_helper' +require 'rails_helper' describe TopicUser do + describe '#notification_levels' do + context "verify enum sequence" do + before do + @notification_levels = TopicUser.notification_levels + end + + it "'muted' should be at 0 position" do + expect(@notification_levels[:muted]).to eq(0) + end + + it "'watching' should be at 3rd position" do + expect(@notification_levels[:watching]).to eq(3) + end + end + end + + describe '#notification_reasons' do + context "verify enum sequence" do + before do + @notification_reasons = TopicUser.notification_reasons + end + + it "'created_topic' should be at 1st position" do + expect(@notification_reasons[:created_topic]).to eq(1) + end + + it "'plugin_changed' should be at 9th position" do + expect(@notification_reasons[:plugin_changed]).to eq(9) + end + end + end + it { is_expected.to belong_to :user } it { is_expected.to belong_to :topic } @@ -16,7 +48,12 @@ describe TopicUser do let(:topic_creator_user) { TopicUser.get(topic, topic.user) } let(:post) { Fabricate(:post, topic: topic, user: user) } - let(:new_user) { Fabricate(:user, auto_track_topics_after_msecs: 1000) } + let(:new_user) { + u = Fabricate(:user) + u.user_option.update_columns(auto_track_topics_after_msecs: 1000) + u + } + let(:topic_new_user) { TopicUser.get(topic, new_user)} let(:yesterday) { DateTime.now.yesterday } @@ -36,15 +73,15 @@ describe TopicUser do describe 'notifications' do it 'should be set to tracking if auto_track_topics is enabled' do - user.update_column(:auto_track_topics_after_msecs, 0) + user.user_option.update_column(:auto_track_topics_after_msecs, 0) ensure_topic_user expect(TopicUser.get(topic, user).notification_level).to eq(TopicUser.notification_levels[:tracking]) end it 'should reset regular topics to tracking topics if auto track is changed' do ensure_topic_user - user.auto_track_topics_after_msecs = 0 - user.save + user.user_option.auto_track_topics_after_msecs = 0 + user.user_option.save expect(topic_user.notification_level).to eq(TopicUser.notification_levels[:tracking]) end diff --git a/spec/models/topic_view_item_spec.rb b/spec/models/topic_view_item_spec.rb index fd15a7592bf..ff5940a3a45 100644 --- a/spec/models/topic_view_item_spec.rb +++ b/spec/models/topic_view_item_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TopicViewItem do diff --git a/spec/models/trust_level3_requirements_spec.rb b/spec/models/trust_level3_requirements_spec.rb index 77f96aed112..764aef8ac91 100644 --- a/spec/models/trust_level3_requirements_spec.rb +++ b/spec/models/trust_level3_requirements_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TrustLevel3Requirements do @@ -14,6 +14,11 @@ describe TrustLevel3Requirements do end describe "requirements" do + it "time_period uses site setting" do + SiteSetting.stubs(:tl3_time_period).returns(80) + expect(tl3_requirements.time_period).to eq(80) + end + it "min_days_visited uses site setting" do SiteSetting.stubs(:tl3_requires_days_visited).returns(66) expect(tl3_requirements.min_days_visited).to eq(66) @@ -62,10 +67,24 @@ describe TrustLevel3Requirements do expect(tl3_requirements.min_likes_received_days).to eq(7) expect(tl3_requirements.min_likes_received_users).to eq(5) end + + it "min_likes_received_days is capped" do + SiteSetting.tl3_requires_likes_received = 600 + expect(tl3_requirements.min_likes_received).to eq(600) + expect(tl3_requirements.min_likes_received_days).to eq(75) # 0.75 * tl3_time_period + end + + it "min_likes_received_days works when time_period is 1" do + SiteSetting.tl3_requires_likes_received = 20 + SiteSetting.tl3_time_period = 1 + expect(tl3_requirements.min_likes_received).to eq(20) + expect(tl3_requirements.min_likes_received_days).to eq(1) + expect(tl3_requirements.min_likes_received_users).to eq(5) + end end describe "days_visited" do - it "counts visits when posts were read no further back than 100 days ago" do + it "counts visits when posts were read no further back than 100 days (default time period) ago" do user.save user.update_posts_read!(1, at: 2.days.ago) user.update_posts_read!(1, at: 3.days.ago) @@ -73,6 +92,17 @@ describe TrustLevel3Requirements do user.update_posts_read!(3, at: 101.days.ago) expect(tl3_requirements.days_visited).to eq(2) end + + it "respects tl3_time_period setting" do + SiteSetting.tl3_time_period = 200 + user.save + user.update_posts_read!(1, at: 2.days.ago) + user.update_posts_read!(1, at: 3.days.ago) + user.update_posts_read!(0, at: 4.days.ago) + user.update_posts_read!(3, at: 101.days.ago) + user.update_posts_read!(4, at: 201.days.ago) + expect(tl3_requirements.days_visited).to eq(3) + end end describe "num_topics_replied_to" do @@ -93,7 +123,7 @@ describe TrustLevel3Requirements do end describe "topics_viewed" do - it "counts topics views within last 100 days, not counting a topic more than once" do + it "counts topics views within last 100 days (default time period), not counting a topic more than once" do user.save make_view(9, 1.day.ago, user.id) make_view(9, 3.days.ago, user.id) # same topic, different day @@ -101,6 +131,17 @@ describe TrustLevel3Requirements do make_view(2, 101.days.ago, user.id) # too long ago expect(tl3_requirements.topics_viewed).to eq(2) end + + it "counts topics views within last 200 days, respecting tl3_time_period setting" do + SiteSetting.tl3_time_period = 200 + user.save + make_view(9, 1.day.ago, user.id) + make_view(9, 3.days.ago, user.id) # same topic, different day + make_view(3, 4.days.ago, user.id) + make_view(2, 101.days.ago, user.id) + make_view(4, 201.days.ago, user.id) # too long ago + expect(tl3_requirements.topics_viewed).to eq(3) + end end describe "posts_read" do diff --git a/spec/models/twitter_user_info_spec.rb b/spec/models/twitter_user_info_spec.rb index 1ed1457f281..708b3d4c60b 100644 --- a/spec/models/twitter_user_info_spec.rb +++ b/spec/models/twitter_user_info_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe TwitterUserInfo do it "does not overflow" do diff --git a/spec/models/upload_spec.rb b/spec/models/upload_spec.rb index 2e3d17c6bea..deddf2b795c 100644 --- a/spec/models/upload_spec.rb +++ b/spec/models/upload_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'digest/sha1' describe Upload do @@ -62,7 +62,6 @@ describe Upload do end it "computes width & height for images" do - FastImage.any_instance.expects(:size).returns([100, 200]) ImageSizer.expects(:resize) image.expects(:rewind).twice Upload.create_for(user_id, image, image_filename, image_filesize) diff --git a/spec/models/user_action_spec.rb b/spec/models/user_action_spec.rb index e4fd78823ed..9e2ec982d06 100644 --- a/spec/models/user_action_spec.rb +++ b/spec/models/user_action_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserAction do diff --git a/spec/models/user_archived_message_spec.rb b/spec/models/user_archived_message_spec.rb new file mode 100644 index 00000000000..cb3567b5db2 --- /dev/null +++ b/spec/models/user_archived_message_spec.rb @@ -0,0 +1,21 @@ +require 'rails_helper' + +describe UserArchivedMessage do + it 'Does not move archived muted messages back to inbox' do + user = Fabricate(:admin) + user2 = Fabricate(:admin) + + topic = create_post(user: user, + skip_validations: true, + target_usernames: [user2.username,user.username].join(","), + archetype: Archetype.private_message).topic + + UserArchivedMessage.archive!(user.id, topic.id) + expect(topic.message_archived?(user)).to eq(true) + + TopicUser.change(user.id, topic.id, notification_level: TopicUser.notification_levels[:muted]) + UserArchivedMessage.move_to_inbox!(user.id, topic.id) + expect(topic.message_archived?(user)).to eq(true) + end +end + diff --git a/spec/models/user_avatar_spec.rb b/spec/models/user_avatar_spec.rb index a46ce21b48d..944a0785c6c 100644 --- a/spec/models/user_avatar_spec.rb +++ b/spec/models/user_avatar_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserAvatar do let(:avatar){ diff --git a/spec/models/user_badge.rb b/spec/models/user_badge.rb index 76b9c9c9e42..5161b413dab 100644 --- a/spec/models/user_badge.rb +++ b/spec/models/user_badge.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'user_badge' describe UserBadge do diff --git a/spec/models/user_email_observer_spec.rb b/spec/models/user_email_observer_spec.rb index 5289b0d6a94..2bd23dd8e18 100644 --- a/spec/models/user_email_observer_spec.rb +++ b/spec/models/user_email_observer_spec.rb @@ -1,197 +1,149 @@ -require 'spec_helper' +require 'rails_helper' describe UserEmailObserver do - context 'user_mentioned' do + let(:topic) { Fabricate(:topic) } + let(:post) { Fabricate(:post, topic: topic) } - let(:user) { Fabricate(:user) } - let!(:notification) { Fabricate(:notification, user: user) } + # something is off with fabricator + def create_notification(type, user=nil) + user ||= Fabricate(:user) + Notification.create(data: "{\"a\": 1}", user: user, notification_type: type, topic: topic, post_number: post.post_number) + end + + shared_examples "enqueue" do it "enqueues a job for the email" do - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, type: :user_mentioned, user_id: notification.user_id, notification_id: notification.id) - UserEmailObserver.send(:new).after_commit(notification) + Jobs.expects(:enqueue_in).with(delay, :user_email, UserEmailObserver::EmailUser.notification_params(notification,type)) + UserEmailObserver.process_notification(notification) end - it "enqueue a delayed job for users that are online" do - user.last_seen_at = 1.minute.ago - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, type: :user_mentioned, user_id: notification.user_id, notification_id: notification.id) - UserEmailObserver.send(:new).after_commit(notification) + context "inactive user" do + + before { notification.user.active = false } + + it "doesn't enqueue a job" do + Jobs.expects(:enqueue_in).with(delay, :user_email, has_entry(type: type)).never + UserEmailObserver.process_notification(notification) + end + + it "enqueues a job if the user is staged" do + notification.user.staged = true + Jobs.expects(:enqueue_in).with(delay, :user_email, UserEmailObserver::EmailUser.notification_params(notification,type)) + UserEmailObserver.process_notification(notification) + end + end - it "doesn't enqueue an email if the user has mention emails disabled" do - user.expects(:email_direct?).returns(false) - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_mentioned)).never - UserEmailObserver.send(:new).after_commit(notification) - end + context "small action" do + + it "doesn't enqueue a job" do + Post.any_instance.expects(:post_type).returns(Post.types[:small_action]) + Jobs.expects(:enqueue_in).with(delay, :user_email, has_entry(type: type)).never + UserEmailObserver.process_notification(notification) + end - it "doesn't enqueue an email if the user account is deactivated" do - user.active = false - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_mentioned)).never - UserEmailObserver.send(:new).after_commit(notification) end end - context 'posted' do + shared_examples "enqueue_public" do + include_examples "enqueue" - let(:user) { Fabricate(:user) } - let!(:notification) { Fabricate(:notification, user: user, notification_type: 9) } + it "doesn't enqueue a job if the user has mention emails disabled" do + notification.user.user_option.update_columns(email_direct: false) + Jobs.expects(:enqueue_in).with(delay, :user_email, has_entry(type: type)).never + UserEmailObserver.process_notification(notification) + end + end - it "enqueues a job for the email" do - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, type: :user_posted, user_id: notification.user_id, notification_id: notification.id) - UserEmailObserver.send(:new).after_commit(notification) + shared_examples "enqueue_private" do + include_examples "enqueue" + + it "doesn't enqueue a job if the user has private message emails disabled" do + notification.user.user_option.update_columns(email_private_messages: false) + Jobs.expects(:enqueue_in).with(delay, :user_email, has_entry(type: type)).never + UserEmailObserver.process_notification(notification) end - it "doesn't enqueue an email if the user has mention emails disabled" do - user.expects(:email_direct?).returns(false) - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_posted)).never - UserEmailObserver.send(:new).after_commit(notification) - end + end - it "doesn't enqueue an email if the user account is deactivated" do - user.active = false - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_posted)).never - UserEmailObserver.send(:new).after_commit(notification) + context 'user_mentioned' do + let(:type) { :user_mentioned } + let(:delay) { SiteSetting.email_time_window_mins.minutes } + let!(:notification) { create_notification(1) } + + include_examples "enqueue_public" + + it "enqueue a delayed job for users that are online" do + notification.user.last_seen_at = 1.minute.ago + Jobs.expects(:enqueue_in).with(delay, :user_email, UserEmailObserver::EmailUser.notification_params(notification,type)) + UserEmailObserver.process_notification(notification) end end context 'user_replied' do + let(:type) { :user_replied } + let(:delay) { SiteSetting.email_time_window_mins.minutes } + let!(:notification) { create_notification(2) } - let(:user) { Fabricate(:user) } - let!(:notification) { Fabricate(:notification, user: user, notification_type: 2) } - - it "enqueues a job for the email" do - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, type: :user_replied, user_id: notification.user_id, notification_id: notification.id) - UserEmailObserver.send(:new).after_commit(notification) - end - - it "doesn't enqueue an email if the user has mention emails disabled" do - user.expects(:email_direct?).returns(false) - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_replied)).never - UserEmailObserver.send(:new).after_commit(notification) - end - - it "doesn't enqueue an email if the user account is deactivated" do - user.active = false - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_replied)).never - UserEmailObserver.send(:new).after_commit(notification) - end - + include_examples "enqueue_public" end context 'user_quoted' do + let(:type) { :user_quoted } + let(:delay) { SiteSetting.email_time_window_mins.minutes } + let!(:notification) { create_notification(3) } - let(:user) { Fabricate(:user) } - let!(:notification) { Fabricate(:notification, user: user, notification_type: 3) } + include_examples "enqueue_public" + end - it "enqueues a job for the email" do - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, type: :user_quoted, user_id: notification.user_id, notification_id: notification.id) - UserEmailObserver.send(:new).after_commit(notification) - end + context 'user_linked' do + let(:type) { :user_linked } + let(:delay) { SiteSetting.email_time_window_mins.minutes } + let!(:notification) { create_notification(11) } - it "doesn't enqueue an email if the user has mention emails disabled" do - user.expects(:email_direct?).returns(false) - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_quoted)).never - UserEmailObserver.send(:new).after_commit(notification) - end + include_examples "enqueue_public" + end - it "doesn't enqueue an email if the user account is deactivated" do - user.active = false - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_quoted)).never - UserEmailObserver.send(:new).after_commit(notification) + context 'user_posted' do + let(:type) { :user_posted } + let(:delay) { SiteSetting.email_time_window_mins.minutes } + let!(:notification) { create_notification(9) } + + include_examples "enqueue_public" + end + + context 'user_private_message' do + let(:type) { :user_private_message } + let(:delay) { SiteSetting.private_email_time_window_seconds } + let!(:notification) { create_notification(6) } + + include_examples "enqueue_private" + + it "doesn't enqueue a job for a small action" do + notification.data_hash["original_post_type"] = Post.types[:small_action] + Jobs.expects(:enqueue_in).with(delay, :user_email, has_entry(type: type)).never + UserEmailObserver.process_notification(notification) end end - context 'email_user_invited_to_private_message' do - - let(:user) { Fabricate(:user) } - let!(:notification) { Fabricate(:notification, user: user, notification_type: 7) } - - it "enqueues a job for the email" do - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, type: :user_invited_to_private_message, user_id: notification.user_id, notification_id: notification.id) - UserEmailObserver.send(:new).after_commit(notification) - end - - it "doesn't enqueue an email if the user has mention emails disabled" do - user.expects(:email_direct?).returns(false) - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_invited_to_private_message)).never - UserEmailObserver.send(:new).after_commit(notification) - end - - it "doesn't enqueue an email if the user account is deactivated" do - user.active = false - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_invited_to_private_message)).never - UserEmailObserver.send(:new).after_commit(notification) - end - - end - - context 'private_message' do - - let(:user) { Fabricate(:user) } - let!(:notification) { Fabricate(:notification, user: user, notification_type: 6) } - - it "enqueues a job for the email" do - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, type: :user_private_message, user_id: notification.user_id, notification_id: notification.id) - UserEmailObserver.send(:new).after_commit(notification) - end - - it "doesn't enqueue an email if the user has private message emails disabled" do - user.expects(:email_private_messages?).returns(false) - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_private_message)).never - UserEmailObserver.send(:new).after_commit(notification) - end - - it "doesn't enqueue an email if the user account is deactivated" do - user.active = false - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_private_message)).never - UserEmailObserver.send(:new).after_commit(notification) - end - - end - - context 'private_message' do - - let(:user) { Fabricate(:user) } - let!(:notification) { Fabricate(:notification, user: user, notification_type: 6) } - - it "enqueues a job for the email" do - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, type: :user_private_message, user_id: notification.user_id, notification_id: notification.id) - UserEmailObserver.send(:new).after_commit(notification) - end - - it "doesn't enqueue an email if the user has private message emails disabled" do - user.expects(:email_private_messages?).returns(false) - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_private_message)).never - UserEmailObserver.send(:new).after_commit(notification) - end + context 'user_invited_to_private_message' do + let(:type) { :user_invited_to_private_message } + let(:delay) { SiteSetting.private_email_time_window_seconds } + let!(:notification) { create_notification(7) } + include_examples "enqueue_public" end context 'user_invited_to_topic' do + let(:type) { :user_invited_to_topic } + let(:delay) { SiteSetting.private_email_time_window_seconds } + let!(:notification) { create_notification(13) } - let(:user) { Fabricate(:user) } - let!(:notification) { Fabricate(:notification, user: user, notification_type: 13) } - - it "enqueues a job for the email" do - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, type: :user_invited_to_topic, user_id: notification.user_id, notification_id: notification.id) - UserEmailObserver.send(:new).after_commit(notification) - end - - it "doesn't enqueue an email if the user has mention emails disabled" do - user.expects(:email_direct?).returns(false) - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_invited_to_topic)).never - UserEmailObserver.send(:new).after_commit(notification) - end - - it "doesn't enqueue an email if the user account is deactivated" do - user.active = false - Jobs.expects(:enqueue_in).with(SiteSetting.email_time_window_mins.minutes, :user_email, has_entry(type: :user_invited_to_topic)).never - UserEmailObserver.send(:new).after_commit(notification) - end - + include_examples "enqueue_public" end end diff --git a/spec/models/user_history_spec.rb b/spec/models/user_history_spec.rb index f33a497d689..659432d9569 100644 --- a/spec/models/user_history_spec.rb +++ b/spec/models/user_history_spec.rb @@ -1,7 +1,23 @@ -require 'spec_helper' +require 'rails_helper' describe UserHistory do + describe '#actions' do + context "verify enum sequence" do + before do + @actions = UserHistory.actions + end + + it "'delete_user' should be at 1st position" do + expect(@actions[:delete_user]).to eq(1) + end + + it "'change_site_text' should be at 29th position" do + expect(@actions[:change_site_text]).to eq(29) + end + end + end + describe '#staff_action_records' do context "with some records" do before do diff --git a/spec/models/user_open_id_spec.rb b/spec/models/user_open_id_spec.rb index f37efc363b1..b7113f2ff89 100644 --- a/spec/models/user_open_id_spec.rb +++ b/spec/models/user_open_id_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserOpenId do diff --git a/spec/models/user_option_spec.rb b/spec/models/user_option_spec.rb new file mode 100644 index 00000000000..8b85a552a44 --- /dev/null +++ b/spec/models/user_option_spec.rb @@ -0,0 +1,126 @@ +require 'rails_helper' +require_dependency 'user_option' + +describe UserOption do + + describe "#ensure_consistency!" do + it "recreates missing user option records" do + user = Fabricate(:user) + user.user_option.destroy + UserOption.ensure_consistency! + + user.reload + + expect(user.user_option.email_always).to eq(SiteSetting.default_email_always) + end + end + + describe "should_be_redirected_to_top" do + let!(:user) { Fabricate(:user) } + + it "should be redirected to top when there is a reason to" do + user.user_option.expects(:redirected_to_top).returns({ reason: "42" }) + expect(user.user_option.should_be_redirected_to_top).to eq(true) + end + + it "should not be redirected to top when there is no reason to" do + user.user_option.expects(:redirected_to_top).returns(nil) + expect(user.user_option.should_be_redirected_to_top).to eq(false) + end + + end + + describe "#mailing_list_mode" do + let!(:forum_user) { Fabricate(:user) } + let!(:mailing_list_user) { Fabricate(:user) } + + before do + forum_user.user_option.update(mailing_list_mode: false) + mailing_list_user.user_option.update(mailing_list_mode: true) + end + + it "should return false when `SiteSetting.disable_mailing_list_mode` is enabled" do + SiteSetting.disable_mailing_list_mode = true + expect(forum_user.user_option.mailing_list_mode).to eq(false) + expect(mailing_list_user.user_option.mailing_list_mode).to eq(false) + end + + it "should return the stored value when `SiteSetting.disable_mailing_list_mode` is disabled" do + SiteSetting.disable_mailing_list_mode = false + expect(forum_user.user_option.mailing_list_mode).to eq(false) + expect(mailing_list_user.user_option.mailing_list_mode).to eq(true) + end + end + + describe ".redirected_to_top" do + let!(:user) { Fabricate(:user) } + + it "should have no reason when `SiteSetting.redirect_users_to_top_page` is disabled" do + SiteSetting.expects(:redirect_users_to_top_page).returns(false) + expect(user.user_option.redirected_to_top).to eq(nil) + end + + context "when `SiteSetting.redirect_users_to_top_page` is enabled" do + before { SiteSetting.expects(:redirect_users_to_top_page).returns(true) } + + it "should have no reason when top is not in the `SiteSetting.top_menu`" do + SiteSetting.expects(:top_menu).returns("latest") + expect(user.user_option.redirected_to_top).to eq(nil) + end + + context "and when top is in the `SiteSetting.top_menu`" do + before { SiteSetting.expects(:top_menu).returns("latest|top") } + + it "should have no reason when there are not enough topics" do + SiteSetting.expects(:min_redirected_to_top_period).returns(nil) + expect(user.user_option.redirected_to_top).to eq(nil) + end + + context "and there are enough topics" do + + before { SiteSetting.expects(:min_redirected_to_top_period).returns(:monthly) } + + describe "a new user" do + before do + user.stubs(:trust_level).returns(0) + user.stubs(:last_seen_at).returns(5.minutes.ago) + end + + it "should have a reason for the first visit" do + expect(user.user_option.redirected_to_top).to eq({ + reason: I18n.t('redirected_to_top_reasons.new_user'), + period: :monthly + }) + end + + it "should not have a reason for next visits" do + user.user_option.expects(:last_redirected_to_top_at).returns(10.minutes.ago) + user.user_option.expects(:update_last_redirected_to_top!).never + + expect(user.user_option.redirected_to_top).to eq(nil) + end + end + + describe "an older user" do + before { user.stubs(:trust_level).returns(1) } + + it "should have a reason when the user hasn't been seen in a month" do + user.last_seen_at = 2.months.ago + user.user_option.expects(:update_last_redirected_to_top!).once + + expect(user.user_option.redirected_to_top).to eq({ + reason: I18n.t('redirected_to_top_reasons.not_seen_in_a_month'), + period: :monthly + }) + end + + end + + end + + end + + end + + end +end diff --git a/spec/models/user_profile_spec.rb b/spec/models/user_profile_spec.rb index 0e7e259360f..cbacd417693 100644 --- a/spec/models/user_profile_spec.rb +++ b/spec/models/user_profile_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserProfile do it 'is created automatically when a user is created' do @@ -37,6 +37,18 @@ describe UserProfile do expect(user_profile).not_to be_valid end + it "doesn't support invalid website" do + user_profile = Fabricate.build(:user_profile, website: "http://https://google.com") + user_profile.user = Fabricate.build(:user) + expect(user_profile).not_to be_valid + end + + it "supports valid website" do + user_profile = Fabricate.build(:user_profile, website: "https://google.com") + user_profile.user = Fabricate.build(:user) + expect(user_profile.valid?).to be true + end + describe 'after save' do let(:user) { Fabricate(:user) } diff --git a/spec/models/user_profile_view_spec.rb b/spec/models/user_profile_view_spec.rb new file mode 100644 index 00000000000..66474b7e0d9 --- /dev/null +++ b/spec/models/user_profile_view_spec.rb @@ -0,0 +1,39 @@ +require 'rails_helper' + +RSpec.describe UserProfileView do + let(:user) { Fabricate(:user) } + let(:other_user) { Fabricate(:user) } + let(:user_profile_id) { user.user_profile.id } + + def add(user_profile_id, ip, user_id=nil, at=nil) + described_class.add(user_profile_id, ip, user_id, at, true) + end + + it "should increase user's profile view count" do + expect{ add(user_profile_id, '1.1.1.1') }.to change{ described_class.count }.by(1) + expect(user.user_profile.reload.views).to eq(1) + expect{ add(user_profile_id, '1.1.1.1', other_user.id) }.to change{ described_class.count }.by(1) + + user_profile = user.user_profile.reload + expect(user_profile.views).to eq(2) + expect(user_profile.user_profile_views).to eq(described_class.all) + end + + it "should not create duplicated profile view for anon user" do + time = Time.zone.now + + 2.times do + add(user_profile_id, '1.1.1.1', nil, time) + expect(described_class.count).to eq(1) + end + end + + it "should not create duplicated profile view for signed in user" do + time = Time.zone.now + + ['1.1.1.1', '2.2.2.2'].each do |ip| + add(user_profile_id, ip, other_user.id, time) + expect(described_class.count).to eq(1) + end + end +end diff --git a/spec/models/user_search_spec.rb b/spec/models/user_search_spec.rb index 48ee7beccda..5d5a55f4f23 100644 --- a/spec/models/user_search_spec.rb +++ b/spec/models/user_search_spec.rb @@ -1,19 +1,21 @@ -require 'spec_helper' +require 'rails_helper' describe UserSearch do let(:topic) { Fabricate :topic } let(:topic2) { Fabricate :topic } let(:topic3) { Fabricate :topic } + let(:topic4) { Fabricate :topic } let(:user1) { Fabricate :user, username: "mrb", name: "Michael Madsen", last_seen_at: 10.days.ago } - let(:user2) { Fabricate :user, username: "mrblue", name: "Eddie Code", last_seen_at: 9.days.ago } + let(:user2) { Fabricate :user, username: "mrblue", name: "Eddie Code", last_seen_at: 9.days.ago } let(:user3) { Fabricate :user, username: "mrorange", name: "Tim Roth", last_seen_at: 8.days.ago } let(:user4) { Fabricate :user, username: "mrpink", name: "Steve Buscemi", last_seen_at: 7.days.ago } let(:user5) { Fabricate :user, username: "mrbrown", name: "Quentin Tarantino", last_seen_at: 6.days.ago } let(:user6) { Fabricate :user, username: "mrwhite", name: "Harvey Keitel", last_seen_at: 5.days.ago } - let!(:inactive) { Fabricate :user, username: "Ghost", active: false } + let!(:inactive) { Fabricate :user, username: "Ghost", active: false } let(:admin) { Fabricate :admin, username: "theadmin" } let(:moderator) { Fabricate :moderator, username: "themod" } + let(:staged) { Fabricate :staged } before do ActiveRecord::Base.observers.enable :all @@ -24,6 +26,8 @@ describe UserSearch do Fabricate :post, user: user4, topic: topic Fabricate :post, user: user5, topic: topic3 Fabricate :post, user: user6, topic: topic + Fabricate :post, user: staged, topic: topic4 + user6.update_attributes(suspended_at: 1.day.ago, suspended_till: 1.year.from_now) end @@ -31,10 +35,17 @@ describe UserSearch do UserSearch.new(*args).search end - # this is a seriously expensive integration test, re-creating this entire test db is too expensive - # reuse - it "operates correctly" do + it 'allows for correct underscore searching' do + Fabricate(:user, username: 'Under_Score') + Fabricate(:user, username: 'undertaker') + expect(search_for("under_sc").length).to eq(1) + expect(search_for("under_").length).to eq(1) + end + + # this is a seriously expensive integration test, + # re-creating this entire test db is too expensive reuse + it "operates correctly" do # normal search results = search_for(user1.name.split(" ").first) expect(results.size).to eq(1) @@ -45,7 +56,7 @@ describe UserSearch do expect(results.size).to eq(1) expect(results.first).to eq(user1) - # username + # username results = search_for(user4.username) expect(results.size).to eq(1) expect(results.first).to eq(user4) @@ -67,10 +78,9 @@ describe UserSearch do expect(results).to include(user6) expect(search_for("mr", searching_user: moderator).size).to eq(6) - results = search_for("mrb", searching_user: admin) + results = search_for(user1.username, searching_user: admin) expect(results.size).to eq(3) - results = search_for("MR", searching_user: admin) expect(results.size).to eq(6) @@ -78,14 +88,13 @@ describe UserSearch do expect(results.size).to eq(2) # topic priority - results = search_for("mrb", topic_id: topic.id) + results = search_for(user1.username, topic_id: topic.id) expect(results.first).to eq(user1) - - results = search_for("mrb", topic_id: topic2.id) + results = search_for(user1.username, topic_id: topic2.id) expect(results[1]).to eq(user2) - results = search_for("mrb", topic_id: topic3.id) + results = search_for(user1.username, topic_id: topic3.id) expect(results[1]).to eq(user5) # When searching by name is enabled, it returns the record @@ -109,7 +118,11 @@ describe UserSearch do expect(results.first.username).to eq(user1.username) # don't return inactive users - results = search_for("Ghost") + results = search_for(inactive.username) + expect(results).to be_blank + + # don't return staged users + results = search_for(staged.username) expect(results).to be_blank end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 87f730ba5e7..84a992ae942 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'user' describe User do @@ -38,7 +38,6 @@ describe User do Jobs.expects(:enqueue).with(:send_system_message, user_id: user.id, message_type: 'welcome_user').never user.enqueue_welcome_message('welcome_user') end - end describe '.approve' do @@ -152,15 +151,15 @@ describe User do it "is properly initialized" do expect(subject.approved_at).to be_blank expect(subject.approved_by_id).to be_blank - expect(subject.email_private_messages).to eq(true) - expect(subject.email_direct).to eq(true) end context 'after_save' do before { subject.save } - it "has an email token" do + it "has correct settings" do expect(subject.email_tokens).to be_present + expect(subject.user_option.email_private_messages).to eq(true) + expect(subject.user_option.email_direct).to eq(true) end end @@ -705,7 +704,19 @@ describe User do # It doesn't raise an exception if called again user.flag_linked_posts_as_spam + end + it "does not flags post as spam if the previous flag for that post was disagreed" do + user.flag_linked_posts_as_spam + + post.reload + expect(post.spam_count).to eq(1) + + PostAction.clear_flags!(post, admin) + user.flag_linked_posts_as_spam + + post.reload + expect(post.spam_count).to eq(0) end end @@ -900,7 +911,7 @@ describe User do expect(user.small_avatar_url).to eq("//test.localhost/letter_avatar/sam/45/#{LetterAvatar.version}.png") SiteSetting.external_system_avatars_enabled = true - expect(user.small_avatar_url).to eq("https://avatars.discourse.org/letter/s/5f9b8f/45.png") + expect(user.small_avatar_url).to eq("//test.localhost/letter_avatar_proxy/v2/letter/s/5f9b8f/45.png") end end @@ -974,111 +985,6 @@ describe User do end end - context "group management" do - let!(:user) { Fabricate(:user) } - - it "by default has no managed groups" do - expect(user.managed_groups).to be_empty - end - - it "can manage multiple groups" do - 3.times do |i| - g = Fabricate(:group, name: "group_#{i}") - g.appoint_manager(user) - end - expect(user.managed_groups.count).to eq(3) - end - end - - describe "should_be_redirected_to_top" do - let!(:user) { Fabricate(:user) } - - it "should be redirected to top when there is a reason to" do - user.expects(:redirected_to_top).returns({ reason: "42" }) - expect(user.should_be_redirected_to_top).to eq(true) - end - - it "should not be redirected to top when there is no reason to" do - user.expects(:redirected_to_top).returns(nil) - expect(user.should_be_redirected_to_top).to eq(false) - end - - end - - describe ".redirected_to_top" do - let!(:user) { Fabricate(:user) } - - it "should have no reason when `SiteSetting.redirect_users_to_top_page` is disabled" do - SiteSetting.expects(:redirect_users_to_top_page).returns(false) - expect(user.redirected_to_top).to eq(nil) - end - - context "when `SiteSetting.redirect_users_to_top_page` is enabled" do - before { SiteSetting.expects(:redirect_users_to_top_page).returns(true) } - - it "should have no reason when top is not in the `SiteSetting.top_menu`" do - SiteSetting.expects(:top_menu).returns("latest") - expect(user.redirected_to_top).to eq(nil) - end - - context "and when top is in the `SiteSetting.top_menu`" do - before { SiteSetting.expects(:top_menu).returns("latest|top") } - - it "should have no reason when there are not enough topics" do - SiteSetting.expects(:min_redirected_to_top_period).returns(nil) - expect(user.redirected_to_top).to eq(nil) - end - - context "and there are enough topics" do - - before { SiteSetting.expects(:min_redirected_to_top_period).returns(:monthly) } - - describe "a new user" do - before do - user.stubs(:trust_level).returns(0) - user.stubs(:last_seen_at).returns(5.minutes.ago) - end - - it "should have a reason for the first visit" do - user.expects(:last_redirected_to_top_at).returns(nil) - user.expects(:update_last_redirected_to_top!).once - - expect(user.redirected_to_top).to eq({ - reason: I18n.t('redirected_to_top_reasons.new_user'), - period: :monthly - }) - end - - it "should not have a reason for next visits" do - user.expects(:last_redirected_to_top_at).returns(10.minutes.ago) - user.expects(:update_last_redirected_to_top!).never - - expect(user.redirected_to_top).to eq(nil) - end - end - - describe "an older user" do - before { user.stubs(:trust_level).returns(1) } - - it "should have a reason when the user hasn't been seen in a month" do - user.last_seen_at = 2.months.ago - user.expects(:update_last_redirected_to_top!).once - - expect(user.redirected_to_top).to eq({ - reason: I18n.t('redirected_to_top_reasons.not_seen_in_a_month'), - period: :monthly - }) - end - - end - - end - - end - - end - - end describe "automatic avatar creation" do it "sets a system avatar for new users" do @@ -1250,46 +1156,61 @@ describe User do context "when user preferences are overriden" do before do - SiteSetting.stubs(:default_email_digest_frequency).returns(1) # daily - SiteSetting.stubs(:default_email_private_messages).returns(false) - SiteSetting.stubs(:default_email_direct).returns(false) - SiteSetting.stubs(:default_email_mailing_list_mode).returns(true) - SiteSetting.stubs(:default_email_always).returns(true) + SiteSetting.default_email_digest_frequency = 1440 # daily + SiteSetting.default_email_private_messages = false + SiteSetting.default_email_direct = false + SiteSetting.default_email_mailing_list_mode = true + SiteSetting.default_email_always = true - SiteSetting.stubs(:default_other_new_topic_duration_minutes).returns(-1) # not viewed - SiteSetting.stubs(:default_other_auto_track_topics_after_msecs).returns(0) # immediately - SiteSetting.stubs(:default_other_external_links_in_new_tab).returns(true) - SiteSetting.stubs(:default_other_enable_quoting).returns(false) - SiteSetting.stubs(:default_other_dynamic_favicon).returns(true) - SiteSetting.stubs(:default_other_disable_jump_reply).returns(true) - SiteSetting.stubs(:default_other_edit_history_public).returns(true) + SiteSetting.default_other_new_topic_duration_minutes = -1 # not viewed + SiteSetting.default_other_auto_track_topics_after_msecs = 0 # immediately + SiteSetting.default_other_external_links_in_new_tab = true + SiteSetting.default_other_enable_quoting = false + SiteSetting.default_other_dynamic_favicon = true + SiteSetting.default_other_disable_jump_reply = true + SiteSetting.default_other_edit_history_public = true - SiteSetting.stubs(:default_categories_watching).returns("1") - SiteSetting.stubs(:default_categories_tracking).returns("2") - SiteSetting.stubs(:default_categories_muted).returns("3") + SiteSetting.default_topics_automatic_unpin = false + + SiteSetting.default_categories_watching = "1" + SiteSetting.default_categories_tracking = "2" + SiteSetting.default_categories_muted = "3" end it "has overriden preferences" do user = Fabricate(:user) - - expect(user.digest_after_days).to eq(1) - expect(user.email_private_messages).to eq(false) - expect(user.email_direct).to eq(false) - expect(user.mailing_list_mode).to eq(true) - expect(user.email_always).to eq(true) - - expect(user.new_topic_duration_minutes).to eq(-1) - expect(user.auto_track_topics_after_msecs).to eq(0) - expect(user.external_links_in_new_tab).to eq(true) - expect(user.enable_quoting).to eq(false) - expect(user.dynamic_favicon).to eq(true) - expect(user.disable_jump_reply).to eq(true) - expect(user.edit_history_public).to eq(true) + options = user.user_option + expect(options.email_always).to eq(true) + expect(options.mailing_list_mode).to eq(true) + expect(options.digest_after_minutes).to eq(1440) + expect(options.email_private_messages).to eq(false) + expect(options.external_links_in_new_tab).to eq(true) + expect(options.enable_quoting).to eq(false) + expect(options.dynamic_favicon).to eq(true) + expect(options.disable_jump_reply).to eq(true) + expect(options.edit_history_public).to eq(true) + expect(options.automatically_unpin_topics).to eq(false) + expect(options.email_direct).to eq(false) + expect(options.new_topic_duration_minutes).to eq(-1) + expect(options.auto_track_topics_after_msecs).to eq(0) expect(CategoryUser.lookup(user, :watching).pluck(:category_id)).to eq([1]) expect(CategoryUser.lookup(user, :tracking).pluck(:category_id)).to eq([2]) expect(CategoryUser.lookup(user, :muted).pluck(:category_id)).to eq([3]) end + end + + context UserOption do + + it "Creates a UserOption row when a user record is created and destroys once done" do + user = Fabricate(:user) + expect(user.user_option.email_always).to eq(false) + + user_id = user.id + user.destroy! + expect(UserOption.find_by(user_id: user_id)).to eq(nil) + + end end diff --git a/spec/models/user_stat_spec.rb b/spec/models/user_stat_spec.rb index 7a75f45f777..e977d3b08a3 100644 --- a/spec/models/user_stat_spec.rb +++ b/spec/models/user_stat_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserStat do @@ -102,6 +102,4 @@ describe UserStat do end end - - end diff --git a/spec/models/user_summary_spec.rb b/spec/models/user_summary_spec.rb new file mode 100644 index 00000000000..77e96a496d4 --- /dev/null +++ b/spec/models/user_summary_spec.rb @@ -0,0 +1,36 @@ +require 'rails_helper' + +describe UserSummary do + + it "produces secure summaries" do + topic = create_post.topic + user = topic.user + _reply = create_post(user: topic.user, topic: topic) + + summary = UserSummary.new(user, Guardian.new) + + expect(summary.topics.length).to eq(1) + expect(summary.replies.length).to eq(1) + + topic.update_columns(deleted_at: Time.now) + + expect(summary.topics.length).to eq(0) + expect(summary.replies.length).to eq(0) + + topic.update_columns(deleted_at: nil, visible: false) + + expect(summary.topics.length).to eq(0) + expect(summary.replies.length).to eq(0) + + category = Fabricate(:category) + topic.update_columns(category_id: category.id, deleted_at: nil, visible: true) + + category.set_permissions(staff: :full) + category.save + + expect(summary.topics.length).to eq(0) + expect(summary.replies.length).to eq(0) + + end + +end diff --git a/spec/models/user_visit_spec.rb b/spec/models/user_visit_spec.rb index 41cc9564b60..ea87011ff3e 100644 --- a/spec/models/user_visit_spec.rb +++ b/spec/models/user_visit_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserVisit do let(:user) { Fabricate(:user) } diff --git a/spec/models/username_validator_spec.rb b/spec/models/username_validator_spec.rb index d03de632648..700cea48505 100644 --- a/spec/models/username_validator_spec.rb +++ b/spec/models/username_validator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UsernameValidator do context "#valid_format?" do diff --git a/spec/phantom_js/smoke_test.js b/spec/phantom_js/smoke_test.js index 94e69310204..779b686eca7 100644 --- a/spec/phantom_js/smoke_test.js +++ b/spec/phantom_js/smoke_test.js @@ -25,9 +25,9 @@ page.onInitialized = function() { }); }; -// page.onConsoleMessage = function(msg) { -// console.log(msg); -// } +page.onConsoleMessage = function(msg) { + console.log(msg); +} page.waitFor = function(desc, fn, cb) { var start = +new Date(); @@ -45,6 +45,7 @@ page.waitFor = function(desc, fn, cb) { } else { if (diff > TIMEOUT) { console.log("FAILED: " + desc + " - " + diff + "ms"); + page.render('/tmp/failed.png'); cb(false); } else { setTimeout(check, 25); @@ -58,27 +59,31 @@ page.waitFor = function(desc, fn, cb) { var actions = []; -var test = function(desc, fn) { +function test(desc, fn) { actions.push({ test: fn, desc: desc }); }; -var exec = function(desc, fn) { +function wait(delay) { + actions.push({ wait: delay }); +} + +function exec(desc, fn) { actions.push({ exec: fn, desc: desc }); }; -var execAsync = function(desc, delay, fn) { +function execAsync(desc, delay, fn) { actions.push({ execAsync: fn, delay: delay, desc: desc }); }; -var upload = function(input, path) { +function upload(input, path) { actions.push({ upload: path, input: input }); }; -// var screenshot = function(filename) { -// actions.push({ screenshot: filename }); -// } +function screenshot(filename) { + actions.push({ screenshot: filename }); +} -var run = function() { +function run() { var allPassed = true; var done = function() { @@ -115,6 +120,11 @@ var run = function() { console.log("SCREENSHOT: " + action.screenshot); page.render(action.screenshot); performNextAction(); + } else if (action.wait) { + console.log("WAIT: " + action.wait + "ms"); + setTimeout(function() { + performNextAction(); + }, action.wait); } } }; @@ -172,34 +182,64 @@ var runTests = function() { return document.querySelector(".current-user"); }); + exec("go home", function() { + $('#site-logo').click(); + }); + + test("it shows a topic list", function() { + return document.querySelector(".topic-list"); + }); + + exec("open composer", function() { + $("#create-topic").click(); + }); + + test('the editor is visible', function() { + return document.querySelector(".d-editor"); + }); + exec("compose new topic", function() { var date = " (" + (+new Date()) + ")", title = "This is a new topic" + date, post = "I can write a new topic inside the smoke test!" + date + "\n\n"; - $("#create-topic").click(); $("#reply-title").val(title).trigger("change"); - $("#reply-control .wmd-input").val(post).trigger("change"); - $("#reply-control .wmd-input").focus()[0].setSelectionRange(post.length, post.length); + $("#reply-control .d-editor-input").val(post).trigger("change"); + $("#reply-control .d-editor-input").focus()[0].setSelectionRange(post.length, post.length); + }); + + test("updates preview", function() { + return document.querySelector(".d-editor-preview p"); }); exec("open upload modal", function() { - $(".wmd-image-button").click(); + $(".d-editor-button-bar .upload").click(); }); test("upload modal is open", function() { return document.querySelector("#filename-input"); }); - upload("#filename-input", "spec/fixtures/images/large & unoptimized.png"); + // TODO: Looks like PhantomJS 2.0.0 has a bug with `uploadFile` + // which breaks this code. - exec("click upload button", function() { - $(".modal .btn-primary").click(); - }); - - test("image is uploaded", function() { - return document.querySelector(".cooked img"); - }); + // upload("#filename-input", "spec/fixtures/images/large & unoptimized.png"); + // test("the file is inserted into the input", function() { + // return document.getElementById('filename-input').files.length + // }); + // screenshot('/tmp/upload-modal.png'); + // + // test("upload modal is open", function() { + // return document.querySelector("#filename-input"); + // }); + // + // exec("click upload button", function() { + // $(".modal .btn-primary").click(); + // }); + // + // test("image is uploaded", function() { + // return document.querySelector(".cooked img"); + // }); exec("submit the topic", function() { $("#reply-control .create").click(); @@ -214,16 +254,16 @@ var runTests = function() { }); test("composer is open", function() { - return document.querySelector("#reply-control .wmd-input"); + return document.querySelector("#reply-control .d-editor-input"); }); exec("compose reply", function() { var post = "I can even write a reply inside the smoke test ;) (" + (+new Date()) + ")"; - $("#reply-control .wmd-input").val(post).trigger("change"); + $("#reply-control .d-editor-input").val(post).trigger("change"); }); test("waiting for the preview", function() { - return $(".wmd-preview").text().trim().indexOf("I can even write") === 0; + return $(".d-editor-preview").text().trim().indexOf("I can even write") === 0; }); execAsync("submit the reply", 6000, function() { @@ -238,7 +278,9 @@ var runTests = function() { run(); }; +phantom.clearCookies(); page.open(system.args[1], function() { + page.evaluate(function() { localStorage.clear(); }); console.log("OPENED: " + system.args[1]); runTests(); }); diff --git a/spec/spec_helper.rb b/spec/rails_helper.rb similarity index 99% rename from spec/spec_helper.rb rename to spec/rails_helper.rb index 701c0de01b7..30921a6e3f4 100644 --- a/spec/spec_helper.rb +++ b/spec/rails_helper.rb @@ -42,6 +42,7 @@ Spork.prefork do config.fail_fast = ENV['RSPEC_FAIL_FAST'] == "1" config.include Helpers config.include MessageBus + config.include RSpecHtmlMatchers config.mock_framework = :mocha config.order = 'random' config.infer_spec_type_from_file_location! diff --git a/spec/serializers/basic_post_serializer_spec.rb b/spec/serializers/basic_post_serializer_spec.rb index 70c09dfbc1b..63743c5d950 100644 --- a/spec/serializers/basic_post_serializer_spec.rb +++ b/spec/serializers/basic_post_serializer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'post' require_dependency 'user' diff --git a/spec/serializers/category_detailed_serializer_spec.rb b/spec/serializers/category_detailed_serializer_spec.rb index eeb0121c16e..cf76aa4c14a 100644 --- a/spec/serializers/category_detailed_serializer_spec.rb +++ b/spec/serializers/category_detailed_serializer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'category' describe CategoryDetailedSerializer do diff --git a/spec/serializers/post_serializer_spec.rb b/spec/serializers/post_serializer_spec.rb index 20643968f8a..4800b0f9caa 100644 --- a/spec/serializers/post_serializer_spec.rb +++ b/spec/serializers/post_serializer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'post_action' describe PostSerializer do diff --git a/spec/serializers/topic_list_item_serializer_spec.rb b/spec/serializers/topic_list_item_serializer_spec.rb index 3cbdc2e40a7..823682e3b25 100644 --- a/spec/serializers/topic_list_item_serializer_spec.rb +++ b/spec/serializers/topic_list_item_serializer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'post_action' describe TopicListItemSerializer do diff --git a/spec/serializers/user_serializer_spec.rb b/spec/serializers/user_serializer_spec.rb index 43e5689a3e8..16320fdfb84 100644 --- a/spec/serializers/user_serializer_spec.rb +++ b/spec/serializers/user_serializer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'user' describe UserSerializer do @@ -15,6 +15,28 @@ describe UserSerializer do end end + context "as current user" do + it "serializes options correctly" do + # so we serialize more stuff + SiteSetting.edit_history_visible_to_public = false + SiteSetting.default_other_auto_track_topics_after_msecs = 0 + SiteSetting.default_other_new_topic_duration_minutes = 60*24 + + user = Fabricate.build(:user, + user_profile: Fabricate.build(:user_profile), + user_option: UserOption.new(edit_history_public: true), + user_stat: UserStat.new + ) + + json = UserSerializer.new(user, scope: Guardian.new(user), root: false).as_json + + expect(json[:user_option][:edit_history_public]).to eq(true) + expect(json[:user_option][:new_topic_duration_minutes]).to eq(60*24) + expect(json[:user_option][:auto_track_topics_after_msecs]).to eq(0) + + end + end + context "with a user" do let(:user) { Fabricate.build(:user, user_profile: Fabricate.build(:user_profile) ) } let(:serializer) { UserSerializer.new(user, scope: Guardian.new, root: false) } @@ -26,7 +48,7 @@ describe UserSerializer do context "with `enable_names` true" do before do - SiteSetting.stubs(:enable_names?).returns(true) + SiteSetting.enable_names = true end it "has a name" do @@ -34,6 +56,7 @@ describe UserSerializer do end end + context "with `enable_names` false" do before do SiteSetting.stubs(:enable_names?).returns(false) diff --git a/spec/services/anonymous_shadow_creator_spec.rb b/spec/services/anonymous_shadow_creator_spec.rb index 85602260988..bda16a7824b 100644 --- a/spec/services/anonymous_shadow_creator_spec.rb +++ b/spec/services/anonymous_shadow_creator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe AnonymousShadowCreator do @@ -30,6 +30,9 @@ describe AnonymousShadowCreator do freeze_time 4.minutes.from_now shadow3 = AnonymousShadowCreator.get(user) + expect(shadow3.user_option.email_digests).to eq(false) + expect(shadow3.user_option.email_private_messages).to eq(false) + expect(shadow2.id).not_to eq(shadow3.id) end diff --git a/spec/services/auto_block_spec.rb b/spec/services/auto_block_spec.rb index 840c4ab9c1a..d23738835a8 100644 --- a/spec/services/auto_block_spec.rb +++ b/spec/services/auto_block_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe SpamRule::AutoBlock do @@ -100,7 +100,7 @@ describe SpamRule::AutoBlock do context 'user is not blocked' do before do - UserBlocker.expects(:block).with(user, nil, has_entries(message: :too_many_spam_flags)).returns(true) + UserBlocker.expects(:block).with(user, Discourse.system_user, message: :too_many_spam_flags).returns(true) end it 'prevents the user from making new posts' do @@ -126,7 +126,7 @@ describe SpamRule::AutoBlock do context 'user is already blocked' do before do - UserBlocker.expects(:block).with(user, nil, has_entries(message: :too_many_spam_flags)).returns(false) + UserBlocker.expects(:block).with(user, Discourse.system_user, message: :too_many_spam_flags).returns(false) end it "doesn't send a pm to moderators if the user is already blocked" do diff --git a/spec/services/badge_granter_spec.rb b/spec/services/badge_granter_spec.rb index 8eec7f2b16b..2eef495663b 100644 --- a/spec/services/badge_granter_spec.rb +++ b/spec/services/badge_granter_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe BadgeGranter do @@ -72,10 +72,12 @@ describe BadgeGranter do end it 'should grant missing badges' do + good_topic = Badge.find(Badge::GoodTopic) + post = Fabricate(:post, like_count: 30) 2.times { BadgeGranter.backfill(Badge.find(Badge::NiceTopic), post_ids: [post.id]) - BadgeGranter.backfill(Badge.find(Badge::GoodTopic)) + BadgeGranter.backfill(good_topic) } # TODO add welcome @@ -83,6 +85,12 @@ describe BadgeGranter do expect(post.user.notifications.count).to eq(2) + notification = post.user.notifications.last + data = notification.data_hash + expect(data["badge_id"]).to eq(good_topic.id) + expect(data["badge_slug"]).to eq(good_topic.slug) + expect(data["username"]).to eq(post.user.username) + expect(Badge.find(Badge::NiceTopic).grant_count).to eq(1) expect(Badge.find(Badge::GoodTopic).grant_count).to eq(1) end @@ -188,7 +196,7 @@ describe BadgeGranter do end it "grants first edit" do - SiteSetting.ninja_edit_window = 0 + SiteSetting.editing_grace_period = 0 post = create_post user = post.user diff --git a/spec/services/color_scheme_revisor_spec.rb b/spec/services/color_scheme_revisor_spec.rb index aab5cac9197..8db267690e6 100644 --- a/spec/services/color_scheme_revisor_spec.rb +++ b/spec/services/color_scheme_revisor_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ColorSchemeRevisor do diff --git a/spec/services/flag_sockpuppets_spec.rb b/spec/services/flag_sockpuppets_spec.rb index fc925dd44b1..9a647e68c69 100644 --- a/spec/services/flag_sockpuppets_spec.rb +++ b/spec/services/flag_sockpuppets_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe SpamRule::FlagSockpuppets do diff --git a/spec/services/group_message_spec.rb b/spec/services/group_message_spec.rb index 64b1591c141..b4ddeaff04f 100644 --- a/spec/services/group_message_spec.rb +++ b/spec/services/group_message_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe GroupMessage do diff --git a/spec/services/post_alerter_spec.rb b/spec/services/post_alerter_spec.rb index 5a87e50dd09..d6889f7493b 100644 --- a/spec/services/post_alerter_spec.rb +++ b/spec/services/post_alerter_spec.rb @@ -1,18 +1,56 @@ -require 'spec_helper' +require 'rails_helper' describe PostAlerter do let!(:evil_trout) { Fabricate(:evil_trout) } + let(:user) { Fabricate(:user) } def create_post_with_alerts(args={}) post = Fabricate(:post, args) PostAlerter.post_created(post) end + context "private message" do + it "notifies for pms correctly" do + pm = Fabricate(:topic, archetype: 'private_message', category_id: nil) + op = Fabricate(:post, user_id: pm.user_id) + pm.allowed_users << pm.user + PostAlerter.post_created(op) + reply = Fabricate(:post, user_id: pm.user_id, topic_id: pm.id, reply_to_post_number: 1) + PostAlerter.post_created(reply) + + reply2 = Fabricate(:post, topic_id: pm.id, reply_to_post_number: 1) + PostAlerter.post_created(reply2) + + # we get a green notification for a reply + expect(Notification.where(user_id: pm.user_id).pluck(:notification_type).first).to eq(Notification.types[:private_message]) + + TopicUser.change(pm.user_id, pm.id, notification_level: TopicUser.notification_levels[:tracking]) + + Notification.destroy_all + + reply3 = Fabricate(:post, topic_id: pm.id) + PostAlerter.post_created(reply3) + + # no notification cause we are tracking + expect(Notification.where(user_id: pm.user_id).count).to eq(0) + + Notification.destroy_all + + reply4 = Fabricate(:post, topic_id: pm.id, reply_to_post_number: 1) + PostAlerter.post_created(reply4) + + # yes notification cause we were replied to + expect(Notification.where(user_id: pm.user_id).count).to eq(1) + + + end + end + context "unread" do it "does not return whispers as unread posts" do op = Fabricate(:post) - whisper = Fabricate(:post, raw: 'this is a whisper post', + _whisper = Fabricate(:post, raw: 'this is a whisper post', user: Fabricate(:admin), topic: op.topic, reply_to_post_number: op.post_number, @@ -23,20 +61,115 @@ describe PostAlerter do end end - context 'likes' do - it 'does not double notify users on likes' do + context 'edits' do + it 'notifies correctly on edits' do + ActiveRecord::Base.observers.enable :all post = Fabricate(:post, raw: 'I love waffles') - PostAction.act(evil_trout, post, PostActionType.types[:like]) admin = Fabricate(:admin) post.revise(admin, {raw: 'I made a revision'}) + # skip this notification cause we already notified on a similar edit + Timecop.freeze(2.hours.from_now) do + post.revise(admin, {raw: 'I made another revision'}) + end + + post.revise(Fabricate(:admin), {raw: 'I made a revision'}) + + Timecop.freeze(4.hours.from_now) do + post.revise(admin, {raw: 'I made another revision'}) + end + + expect(Notification.count(post_number: 1, topic_id: post.topic_id)).to eq(3) + end + end + + context 'likes' do + + it 'notifies on likes after an undo' do + ActiveRecord::Base.observers.enable :all + + post = Fabricate(:post, raw: 'I love waffles') + + PostAction.act(evil_trout, post, PostActionType.types[:like]) + PostAction.remove_act(evil_trout, post, PostActionType.types[:like]) + PostAction.act(evil_trout, post, PostActionType.types[:like]) + + expect(Notification.count(post_number: 1, topic_id: post.topic_id)).to eq(1) + end + + it 'notifies on does not notify when never is selected' do + ActiveRecord::Base.observers.enable :all + + post = Fabricate(:post, raw: 'I love waffles') + + post.user.user_option.update_columns(like_notification_frequency: + UserOption.like_notification_frequency_type[:never]) + + PostAction.act(evil_trout, post, PostActionType.types[:like]) + + + expect(Notification.count(post_number: 1, topic_id: post.topic_id)).to eq(0) + end + + it 'notifies on likes correctly' do + ActiveRecord::Base.observers.enable :all + + post = Fabricate(:post, raw: 'I love waffles') + + PostAction.act(evil_trout, post, PostActionType.types[:like]) + admin = Fabricate(:admin) PostAction.act(admin, post, PostActionType.types[:like]) - # one like and one edit notification + # one like + expect(Notification.count(post_number: 1, topic_id: post.topic_id)).to eq(1) + + + post.user.user_option.update_columns(like_notification_frequency: + UserOption.like_notification_frequency_type[:always]) + + admin2 = Fabricate(:admin) + PostAction.act(admin2, post, PostActionType.types[:like]) + expect(Notification.count(post_number: 1, topic_id: post.topic_id)).to eq(1) + + # adds info to the notification + notification = Notification.find_by(post_number: 1, + topic_id: post.topic_id) + + + expect(notification.data_hash["count"].to_i).to eq(2) + expect(notification.data_hash["username2"]).to eq(evil_trout.username) + + # this is a tricky thing ... removing a like should fix up the notifications + PostAction.remove_act(evil_trout, post, PostActionType.types[:like]) + + # rebuilds the missing notification + expect(Notification.count(post_number: 1, topic_id: post.topic_id)).to eq(1) + notification = Notification.find_by(post_number: 1, + topic_id: post.topic_id) + + expect(notification.data_hash["count"]).to eq(2) + expect(notification.data_hash["username"]).to eq(admin2.username) + expect(notification.data_hash["username2"]).to eq(admin.username) + + + post.user.user_option.update_columns(like_notification_frequency: + UserOption.like_notification_frequency_type[:first_time_and_daily]) + + # this gets skipped + admin3 = Fabricate(:admin) + PostAction.act(admin3, post, PostActionType.types[:like]) + + Timecop.freeze(2.days.from_now) do + admin4 = Fabricate(:admin) + PostAction.act(admin4, post, PostActionType.types[:like]) + end + + # first happend within the same day, no need to notify expect(Notification.count(post_number: 1, topic_id: post.topic_id)).to eq(2) + end end @@ -80,11 +213,18 @@ describe PostAlerter do expect(user.notifications.count).to eq(1) - create_post(user: user, raw: "my magic topic\n##{Discourse.base_url}#{post1.url}") + topic = Fabricate(:topic) + + watcher = Fabricate(:user) + TopicUser.create!(user_id: watcher.id, topic_id: topic.id, notification_level: TopicUser.notification_levels[:watching]) + + create_post(topic_id: topic.id, user: user, raw: "my magic topic\n##{Discourse.base_url}#{post1.url}") user.reload expect(user.notifications.count).to eq(1) + expect(watcher.notifications.count).to eq(1) + # don't notify on reflection post1.reload expect(PostAlerter.new.extract_linked_users(post1).length).to eq(0) @@ -92,9 +232,38 @@ describe PostAlerter do end end + context '@group mentions' do + + it 'notifies users correctly' do + + group = Fabricate(:group, name: 'group', alias_level: Group::ALIAS_LEVELS[:everyone]) + group.add(evil_trout) + + expect { + create_post_with_alerts(raw: "Hello @group how are you?") + }.to change(evil_trout.notifications, :count).by(1) + + expect(GroupMention.count).to eq(1) + + Fabricate(:group, name: 'group-alt', alias_level: Group::ALIAS_LEVELS[:everyone]) + + expect { + create_post_with_alerts(raw: "Hello, @group-alt should not trigger a notification?") + }.to change(evil_trout.notifications, :count).by(0) + + expect(GroupMention.count).to eq(2) + + group.update_columns(alias_level: Group::ALIAS_LEVELS[:members_mods_and_admins]) + expect { + create_post_with_alerts(raw: "Hello @group you are not mentionable") + }.to change(evil_trout.notifications, :count).by(0) + + expect(GroupMention.count).to eq(3) + end + end + context '@mentions' do - let(:user) { Fabricate(:user) } let(:mention_post) { create_post_with_alerts(user: user, raw: 'Hello @eviltrout')} let(:topic) { mention_post.topic } @@ -119,5 +288,42 @@ describe PostAlerter do }.not_to change(user.notifications, :count) end + it "notification comes from editor is mention is added later" do + admin = Fabricate(:admin) + post = create_post_with_alerts(user: user, raw: 'No mention here.') + expect { + post.revise(admin, { raw: "Mention @eviltrout in this edit." }) + }.to change(evil_trout.notifications, :count) + n = evil_trout.notifications.last + expect(n.data_hash["original_username"]).to eq(admin.username) + end end + + describe ".create_notification" do + let(:topic) { Fabricate(:private_message_topic, user: user, created_at: 1.hour.ago) } + let(:post) { Fabricate(:post, topic: topic, created_at: 1.hour.ago) } + + it "creates a notification for PMs" do + post.revise(user, { raw: 'This is the revised post' }, revised_at: Time.zone.now) + + expect { + PostAlerter.new.create_notification(user, Notification.types[:private_message], post) + }.to change { user.notifications.count }.by(1) + + expect(user.notifications.last.data_hash["topic_title"]).to eq(topic.title) + end + + it "keeps the original title for PMs" do + original_title = topic.title + + post.revise(user, { title: "This is the revised title" }, revised_at: Time.now) + + expect { + PostAlerter.new.create_notification(user, Notification.types[:private_message], post) + }.to change { user.notifications.count }.by(1) + + expect(user.notifications.last.data_hash["topic_title"]).to eq(original_title) + end + end + end diff --git a/spec/services/post_owner_changer_spec.rb b/spec/services/post_owner_changer_spec.rb index e6fffb942a9..290e224a754 100644 --- a/spec/services/post_owner_changer_spec.rb +++ b/spec/services/post_owner_changer_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe PostOwnerChanger do describe "change_owner!" do @@ -20,9 +20,15 @@ describe PostOwnerChanger do end it "changes the user" do + bumped_at = topic.bumped_at + + freeze_time 2.days.from_now + old_user = p1.user - described_class.new(post_ids: [p1.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner! + PostOwnerChanger.new(post_ids: [p1.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner! p1.reload + expect(p1.topic.bumped_at).to be_within(1.second).of (bumped_at) + expect(p1.topic.last_post_user_id).to eq(user_a.id) expect(old_user).not_to eq(p1.user) expect(p1.user).to eq(user_a) end diff --git a/spec/services/post_timestamp_changer_spec.rb b/spec/services/post_timestamp_changer_spec.rb index 03ec9a66445..bc0b246f162 100644 --- a/spec/services/post_timestamp_changer_spec.rb +++ b/spec/services/post_timestamp_changer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PostTimestampChanger do describe "change!" do @@ -21,6 +21,8 @@ describe PostTimestampChanger do [:created_at, :updated_at].each do |column| expect(p1.public_send(column)).to be_within_one_second_of(new_timestamp) end + + expect(topic.last_posted_at).to be_within_one_second_of(p2.reload.created_at) end describe 'predated timestamp' do diff --git a/spec/services/random_topic_selector_spec.rb b/spec/services/random_topic_selector_spec.rb index eaaad4c8b69..d57f5519d2b 100644 --- a/spec/services/random_topic_selector_spec.rb +++ b/spec/services/random_topic_selector_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe RandomTopicSelector do @@ -11,8 +11,15 @@ describe RandomTopicSelector do $redis.rpush key, t end + expect(RandomTopicSelector.next(0)).to eq([]) expect(RandomTopicSelector.next(2)).to eq([0,1]) + + $redis.expects(:multi).returns(Discourse.received_readonly!) expect(RandomTopicSelector.next(2)).to eq([2,3]) + $redis.unstub(:multi) + + expect(RandomTopicSelector.next(2)).to eq([2,3]) + expect(RandomTopicSelector.next(2)).to eq([]) end it 'can correctly backfill' do diff --git a/spec/services/spam_rules_enforcer_spec.rb b/spec/services/spam_rules_enforcer_spec.rb index 0d60c465471..0bb0a8790b5 100644 --- a/spec/services/spam_rules_enforcer_spec.rb +++ b/spec/services/spam_rules_enforcer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe SpamRulesEnforcer do diff --git a/spec/services/staff_action_logger_spec.rb b/spec/services/staff_action_logger_spec.rb index cb7d6e17586..676b899dce9 100644 --- a/spec/services/staff_action_logger_spec.rb +++ b/spec/services/staff_action_logger_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe StaffActionLogger do @@ -173,6 +173,16 @@ describe StaffActionLogger do end end + describe "log_site_text_change" do + it "raises an error when params are invalid" do + expect { logger.log_site_text_change(nil, 'new text', 'old text') }.to raise_error(Discourse::InvalidParameters) + end + + it "creates a new UserHistory record" do + expect { logger.log_site_text_change('created', 'new text', 'old text') }.to change { UserHistory.count }.by(1) + end + end + describe "log_user_suspend" do let(:user) { Fabricate(:user, suspended_at: 10.minutes.ago, suspended_till: 1.day.from_now) } @@ -271,4 +281,92 @@ describe StaffActionLogger do expect(logged.topic_id).to be === 1234 end end + + describe 'log_category_settings_change' do + let(:category) { Fabricate(:category, name: 'haha') } + let(:category_group) { Fabricate(:category_group, category: category, permission_type: 1) } + + it "raises an error when category is missing" do + expect { logger.log_category_settings_change(nil, nil) }.to raise_error(Discourse::InvalidParameters) + end + + it "creates new UserHistory records" do + attributes = { + name: 'new_name', + permissions: { category_group.group_name => 2 } + } + + category.update!(attributes) + + logger.log_category_settings_change(category, attributes, + { category_group.group_name => category_group.permission_type } + ) + + expect(UserHistory.count).to eq(2) + + permission_user_history = UserHistory.find_by_subject('permissions') + expect(permission_user_history.category_id).to eq(category.id) + expect(permission_user_history.previous_value).to eq({ category_group.group_name => 1 }.to_json) + expect(permission_user_history.new_value).to eq({ category_group.group_name => 2 }.to_json) + expect(permission_user_history.action).to eq(UserHistory.actions[:change_category_settings]) + expect(permission_user_history.context).to eq(category.url) + + name_user_history = UserHistory.find_by_subject('name') + expect(name_user_history.category).to eq(category) + expect(name_user_history.previous_value).to eq('haha') + expect(name_user_history.new_value).to eq('new_name') + end + + it "does not log permissions changes for category visible to everyone" do + attributes = { name: 'new_name' } + old_permission = category.permissions_params + category.update!(attributes) + + logger.log_category_settings_change(category, attributes.merge({ permissions: { "everyone" => 1 } }), old_permission) + + expect(UserHistory.count).to eq(1) + expect(UserHistory.find_by_subject('name').category).to eq(category) + end + end + + describe 'log_category_deletion' do + let(:parent_category) { Fabricate(:category) } + let(:category) { Fabricate(:category, parent_category: parent_category) } + + it "raises an error when category is missing" do + expect { logger.log_category_deletion(nil) }.to raise_error(Discourse::InvalidParameters) + end + + it "creates a new UserHistory record" do + logger.log_category_deletion(category) + + expect(UserHistory.count).to eq(1) + user_history = UserHistory.last + + expect(user_history.subject).to eq(nil) + expect(user_history.category).to eq(category) + expect(user_history.details).to include("parent_category: #{parent_category.name}") + expect(user_history.context).to eq(category.url) + expect(user_history.action).to eq(UserHistory.actions[:delete_category]) + end + end + + describe 'log_category_creation' do + let(:category) { Fabricate(:category) } + + it "raises an error when category is missing" do + expect { logger.log_category_deletion(nil) }.to raise_error(Discourse::InvalidParameters) + end + + it "creates a new UserHistory record" do + logger.log_category_creation(category) + + expect(UserHistory.count).to eq(1) + user_history = UserHistory.last + + expect(user_history.category).to eq(category) + expect(user_history.context).to eq(category.url) + expect(user_history.action).to eq(UserHistory.actions[:create_category]) + end + end end diff --git a/spec/services/user_activator_spec.rb b/spec/services/user_activator_spec.rb index 689e869994b..928c760f1ba 100644 --- a/spec/services/user_activator_spec.rb +++ b/spec/services/user_activator_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserActivator do diff --git a/spec/services/user_anonymizer_spec.rb b/spec/services/user_anonymizer_spec.rb index a18086d892c..6e7a0227a50 100644 --- a/spec/services/user_anonymizer_spec.rb +++ b/spec/services/user_anonymizer_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe UserAnonymizer do @@ -19,50 +19,84 @@ describe UserAnonymizer do end it "turns off all notifications" do + user.user_option.update_columns( + email_always: true + ) + make_anonymous user.reload - expect(user.email_digests).to eq(false) - expect(user.email_private_messages).to eq(false) - expect(user.email_direct).to eq(false) - expect(user.email_always).to eq(false) - expect(user.mailing_list_mode).to eq(false) + expect(user.user_option.email_digests).to eq(false) + expect(user.user_option.email_private_messages).to eq(false) + expect(user.user_option.email_direct).to eq(false) + expect(user.user_option.email_always).to eq(false) + expect(user.user_option.mailing_list_mode).to eq(false) end - it "resets profile to default values" do - user.update_attributes( name: "Bibi", date_of_birth: 19.years.ago, title: "Super Star" ) + context "Site Settings do not require full name" do + before do + SiteSetting.full_name_required = false + end - profile = user.user_profile(true) - profile.update_attributes( location: "Moose Jaw", - website: "www.bim.com", - bio_raw: "I'm Bibi from Moosejaw. I sing and dance.", - bio_cooked: "I'm Bibi from Moosejaw. I sing and dance.", - profile_background: "http://example.com/bg.jpg", - bio_cooked_version: 2, - card_background: "http://example.com/cb.jpg") - make_anonymous - user.reload + it "resets profile to default values" do + user.update_attributes( name: "Bibi", date_of_birth: 19.years.ago, title: "Super Star" ) - expect(user.name).not_to be_present - expect(user.date_of_birth).to eq(nil) - expect(user.title).not_to be_present - expect(user.auth_token).to eq(nil) + profile = user.user_profile(true) + profile.update_attributes( location: "Moose Jaw", + website: "www.bim.com", + bio_raw: "I'm Bibi from Moosejaw. I sing and dance.", + bio_cooked: "I'm Bibi from Moosejaw. I sing and dance.", + profile_background: "http://example.com/bg.jpg", + bio_cooked_version: 2, + card_background: "http://example.com/cb.jpg") - profile = user.user_profile(true) - expect(profile.location).to eq(nil) - expect(profile.website).to eq(nil) - expect(profile.bio_cooked).to eq(nil) - expect(profile.profile_background).to eq(nil) - expect(profile.bio_cooked_version).to eq(nil) - expect(profile.card_background).to eq(nil) + prev_username = user.username + + make_anonymous + user.reload + + expect(user.username).not_to eq(prev_username) + expect(user.name).not_to be_present + expect(user.date_of_birth).to eq(nil) + expect(user.title).not_to be_present + expect(user.auth_token).to eq(nil) + + profile = user.user_profile(true) + expect(profile.location).to eq(nil) + expect(profile.website).to eq(nil) + expect(profile.bio_cooked).to eq(nil) + expect(profile.profile_background).to eq(nil) + expect(profile.bio_cooked_version).to eq(nil) + expect(profile.card_background).to eq(nil) + end + end + + context "Site Settings require full name" do + before do + SiteSetting.full_name_required = true + end + + it "changes name to anonymized username" do + prev_username = user.username + + user.update_attributes( name: "Bibi", date_of_birth: 19.years.ago, title: "Super Star" ) + + make_anonymous + user.reload + + expect(user.name).not_to eq(prev_username) + expect(user.name).to eq(user.username) + end end it "removes the avatar" do upload = Fabricate(:upload, user: user) user.user_avatar = UserAvatar.new(user_id: user.id, custom_upload_id: upload.id) + user.uploaded_avatar_id = upload.id # chosen in user preferences user.save! expect { make_anonymous }.to change { Upload.count }.by(-1) user.reload expect(user.user_avatar).to eq(nil) + expect(user.uploaded_avatar_id).to eq(nil) end it "logs the action" do diff --git a/spec/services/user_blocker_spec.rb b/spec/services/user_blocker_spec.rb index 2a1c5758a6e..49d526c59b4 100644 --- a/spec/services/user_blocker_spec.rb +++ b/spec/services/user_blocker_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserBlocker do diff --git a/spec/services/user_destroyer_spec.rb b/spec/services/user_destroyer_spec.rb index 5e023d30cd8..e4043e93705 100644 --- a/spec/services/user_destroyer_spec.rb +++ b/spec/services/user_destroyer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require_dependency 'user_destroyer' describe UserDestroyer do diff --git a/spec/services/user_updater_spec.rb b/spec/services/user_updater_spec.rb index eeb7da1251e..d061509025b 100644 --- a/spec/services/user_updater_spec.rb +++ b/spec/services/user_updater_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UserUpdater do @@ -32,26 +32,40 @@ describe UserUpdater do describe '#update' do it 'saves user' do user = Fabricate(:user, name: 'Billy Bob') - updater = described_class.new(acting_user, user) + updater = UserUpdater.new(acting_user, user) updater.update(name: 'Jim Tom') expect(user.reload.name).to eq 'Jim Tom' end - it 'updates bio' do + it 'updates various fields' do user = Fabricate(:user) - updater = described_class.new(acting_user, user) + updater = UserUpdater.new(acting_user, user) - updater.update(bio_raw: 'my new bio') + updater.update(bio_raw: 'my new bio', + email_always: 'true', + mailing_list_mode: true, + digest_after_minutes: "45", + new_topic_duration_minutes: 100, + auto_track_topics_after_msecs: 101, + email_in_reply_to: false + ) + user.reload - expect(user.reload.user_profile.bio_raw).to eq 'my new bio' + expect(user.user_profile.bio_raw).to eq 'my new bio' + expect(user.user_option.email_always).to eq true + expect(user.user_option.mailing_list_mode).to eq true + expect(user.user_option.digest_after_minutes).to eq 45 + expect(user.user_option.new_topic_duration_minutes).to eq 100 + expect(user.user_option.auto_track_topics_after_msecs).to eq 101 + expect(user.user_option.email_in_reply_to).to eq false end context 'when update succeeds' do it 'returns true' do user = Fabricate(:user) - updater = described_class.new(acting_user, user) + updater = UserUpdater.new(acting_user, user) expect(updater.update).to be_truthy end @@ -61,7 +75,7 @@ describe UserUpdater do it 'returns false' do user = Fabricate(:user) user.stubs(save: false) - updater = described_class.new(acting_user, user) + updater = UserUpdater.new(acting_user, user) expect(updater.update).to be_falsey end @@ -73,7 +87,7 @@ describe UserUpdater do guardian = stub guardian.stubs(:can_grant_title?).with(user).returns(true) Guardian.stubs(:new).with(acting_user).returns(guardian) - updater = described_class.new(acting_user, user) + updater = UserUpdater.new(acting_user, user) updater.update(title: 'Minion') diff --git a/spec/services/username_changer_spec.rb b/spec/services/username_changer_spec.rb index debbf70cad5..cf79494f261 100644 --- a/spec/services/username_changer_spec.rb +++ b/spec/services/username_changer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UsernameChanger do diff --git a/spec/services/username_checker_service_spec.rb b/spec/services/username_checker_service_spec.rb index 7b9a4094101..d6736e1ff49 100644 --- a/spec/services/username_checker_service_spec.rb +++ b/spec/services/username_checker_service_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe UsernameCheckerService do diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb index 89f5922cc77..020a240c5e1 100644 --- a/spec/support/helpers.rb +++ b/spec/support/helpers.rb @@ -38,7 +38,14 @@ module Helpers args[:topic_id] = args[:topic].id if args[:topic] user = args.delete(:user) || Fabricate(:user) args[:category] = args[:category].name if args[:category].is_a?(Category) - PostCreator.create(user, args) + creator = PostCreator.new(user, args) + post = creator.create + + if creator.errors.present? + raise StandardError.new(creator.errors.full_messages.join(" ")) + end + + post end def generate_username(length=10) @@ -64,4 +71,12 @@ module Helpers expect(result).to eq(true) end + def fill_email(mail, from, to, body = nil, subject = nil, cc = nil) + result = mail.gsub("FROM", from).gsub("TO", to) + result.gsub!(/Hey.*/m, body) if body + result.sub!(/We .*/, subject) if subject + result.sub!("CC", cc.presence || "") + result + end + end diff --git a/spec/views/omniauth_callbacks/complete.html.erb_spec.rb b/spec/views/omniauth_callbacks/complete.html.erb_spec.rb index 0211cda3dc4..ba571e07808 100644 --- a/spec/views/omniauth_callbacks/complete.html.erb_spec.rb +++ b/spec/views/omniauth_callbacks/complete.html.erb_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" require "auth/authenticator" require_dependency "auth/result" diff --git a/spec/views/omniauth_callbacks/failure.html.erb_spec.rb b/spec/views/omniauth_callbacks/failure.html.erb_spec.rb index 98520a6cb07..ce6adc032af 100644 --- a/spec/views/omniauth_callbacks/failure.html.erb_spec.rb +++ b/spec/views/omniauth_callbacks/failure.html.erb_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe "users/omniauth_callbacks/failure.html.erb" do diff --git a/test/javascripts/acceptance/about-test.js.es6 b/test/javascripts/acceptance/about-test.js.es6 index b45675f1aa4..9819ed8cba5 100644 --- a/test/javascripts/acceptance/about-test.js.es6 +++ b/test/javascripts/acceptance/about-test.js.es6 @@ -4,8 +4,8 @@ acceptance("About"); test("viewing", () => { visit("/about"); andThen(() => { - ok(exists('.about.admins .user-small'), 'has admins'); - ok(exists('.about.moderators .user-small'), 'has moderators'); + ok(exists('.about.admins .user-info'), 'has admins'); + ok(exists('.about.moderators .user-info'), 'has moderators'); ok(exists('.about.stats tr td'), 'has stats'); }); }); diff --git a/test/javascripts/acceptance/admin-site-text-test.js.es6 b/test/javascripts/acceptance/admin-site-text-test.js.es6 new file mode 100644 index 00000000000..0cd17959c18 --- /dev/null +++ b/test/javascripts/acceptance/admin-site-text-test.js.es6 @@ -0,0 +1,54 @@ +import { acceptance } from "helpers/qunit-helpers"; + +acceptance("Admin - Site Texts", { loggedIn: true }); + +test("search for a key", () => { + visit("/admin/customize/site_texts"); + + fillIn('.site-text-search', 'Test'); + andThen(() => { + ok(exists('.site-text')); + ok(exists(".site-text:not(.overridden)")); + ok(exists('.site-text.overridden')); + }); + + + // Only show overridden + click('.extra-options input'); + andThen(() => { + ok(!exists(".site-text:not(.overridden)")); + ok(exists('.site-text.overridden')); + }); +}); + + +test("edit and revert a site text by key", () => { + visit("/admin/customize/site_texts/site.test"); + andThen(() => { + equal(find('.title h3').text(), 'site.test'); + ok(!exists('.save-messages .saved')); + ok(!exists('.save-messages .saved')); + ok(!exists('.revert-site-text')); + }); + + // Change the value + fillIn('.site-text-value', 'New Test Value'); + click(".save-changes"); + + andThen(() => { + ok(exists('.save-messages .saved')); + ok(exists('.revert-site-text')); + }); + + // Revert the changes + click('.revert-site-text'); + andThen(() => { + ok(exists('.bootbox.modal')); + }); + click('.bootbox.modal .btn-primary'); + + andThen(() => { + ok(!exists('.save-messages .saved')); + ok(!exists('.revert-site-text')); + }); +}); diff --git a/test/javascripts/acceptance/badges-test.js.es6 b/test/javascripts/acceptance/badges-test.js.es6 index 31f8bec3b80..77148f10fce 100644 --- a/test/javascripts/acceptance/badges-test.js.es6 +++ b/test/javascripts/acceptance/badges-test.js.es6 @@ -5,12 +5,12 @@ acceptance("Badges"); test("Visit Badge Pages", () => { visit("/badges"); andThen(() => { - ok(exists('.badges-listing tr'), "has a list of badges"); + ok(exists('.badge-groups .badge-card'), "has a list of badges"); }); visit("/badges/9/autobiographer"); andThen(() => { - ok(exists('.badges-listing tr'), "has the badge in the listing"); - ok(exists('.badge-user'), "has the list of users with that badge"); + ok(exists('.badge-card'), "has the badge in the listing"); + ok(exists('.user-info'), "has the list of users with that badge"); }); }); diff --git a/test/javascripts/acceptance/category-edit-test.js.es6 b/test/javascripts/acceptance/category-edit-test.js.es6 index fc13ab53769..d80e3678537 100644 --- a/test/javascripts/acceptance/category-edit-test.js.es6 +++ b/test/javascripts/acceptance/category-edit-test.js.es6 @@ -34,7 +34,7 @@ test("Change the topic template", assert => { click('.edit-category'); click('.edit-category-topic-template'); - fillIn('.wmd-input', 'this is the new topic template'); + fillIn('.d-editor-input', 'this is the new topic template'); click('#save-category'); andThen(() => { assert.ok(!visible('#discourse-modal'), 'it closes the modal'); diff --git a/test/javascripts/acceptance/category-hashtag-test.js.es6 b/test/javascripts/acceptance/category-hashtag-test.js.es6 new file mode 100644 index 00000000000..a15cd9faf52 --- /dev/null +++ b/test/javascripts/acceptance/category-hashtag-test.js.es6 @@ -0,0 +1,34 @@ +import { acceptance } from "helpers/qunit-helpers"; + +acceptance("Category hashtag", { + loggedIn: true, + setup() { + const response = (object) => { + return [ + 200, + {"Content-Type": "application/json"}, + object + ]; + }; + + server.get('/category_hashtags/check', () => { //eslint-disable-line + return response({ valid: [{ slug: "bug", url: '/c/bugs' }] }); + }); + } +}); + +test("category hashtag is cooked properly", () => { + visit("/t/internationalization-localization/280"); + click('#topic-footer-buttons .btn.create'); + + fillIn('.d-editor-input', "this is a category hashtag #bug"); + andThen(() => { + // TODO: Test that the autocomplete shows + equal(find('.d-editor-preview:visible').html().trim(), "

    this is a category hashtag #bug

    "); + }); + + click('#reply-control .btn.create'); + andThen(() => { + equal(find('.topic-post:last .cooked p').html().trim(), "this is a category hashtag #bug"); + }); +}); diff --git a/test/javascripts/acceptance/composer-test.js.es6 b/test/javascripts/acceptance/composer-test.js.es6 index 835a3429642..38789579c18 100644 --- a/test/javascripts/acceptance/composer-test.js.es6 +++ b/test/javascripts/acceptance/composer-test.js.es6 @@ -10,25 +10,25 @@ test("Tests the Composer controls", () => { click('#create-topic'); andThen(() => { - ok(exists('.wmd-input'), 'the composer input is visible'); + ok(exists('.d-editor-input'), 'the composer input is visible'); ok(exists('.title-input .popup-tip.bad.hide'), 'title errors are hidden by default'); - ok(exists('.textarea-wrapper .popup-tip.bad.hide'), 'body errors are hidden by default'); + ok(exists('.d-editor-textarea-wrapper .popup-tip.bad.hide'), 'body errors are hidden by default'); }); click('a.toggle-preview'); andThen(() => { - ok(!exists('.wmd-preview:visible'), "clicking the toggle hides the preview"); + ok(!exists('.d-editor-preview:visible'), "clicking the toggle hides the preview"); }); click('a.toggle-preview'); andThen(() => { - ok(exists('.wmd-preview:visible'), "clicking the toggle shows the preview again"); + ok(exists('.d-editor-preview:visible'), "clicking the toggle shows the preview again"); }); click('#reply-control button.create'); andThen(() => { ok(!exists('.title-input .popup-tip.bad.hide'), 'it shows the empty title error'); - ok(!exists('.textarea-wrapper .popup-tip.bad.hide'), 'it shows the empty body error'); + ok(!exists('.d-editor-wrapper .popup-tip.bad.hide'), 'it shows the empty body error'); }); fillIn('#reply-title', "this is my new topic title"); @@ -36,10 +36,32 @@ test("Tests the Composer controls", () => { ok(exists('.title-input .popup-tip.good'), 'the title is now good'); }); - fillIn('.wmd-input', "this is the *content* of a post"); + fillIn('.d-editor-input', "this is the *content* of a post"); andThen(() => { - equal(find('.wmd-preview').html(), "

    this is the content of a post

    ", "it previews content"); - ok(exists('.textarea-wrapper .popup-tip.good'), 'the body is now good'); + equal(find('.d-editor-preview').html().trim(), "

    this is the content of a post

    ", "it previews content"); + ok(exists('.d-editor-textarea-wrapper .popup-tip.good'), 'the body is now good'); + }); + + andThen(() => { + const textarea = find('#reply-control .d-editor-input')[0]; + textarea.selectionStart = textarea.value.length; + textarea.selectionEnd = textarea.value.length; + + // Testing keyboard events is tough! + const mac = /Mac|iPod|iPhone|iPad/.test(navigator.platform); + const event = document.createEvent('Event'); + event.initEvent('keydown', true, true); + event[mac ? 'metaKey' : 'ctrlKey'] = true; + event.keyCode = 66; + + textarea.dispatchEvent(event); + }); + + andThen(() => { + const example = I18n.t(`composer.bold_text`); + equal(find('#reply-control .d-editor-input').val().trim(), + `this is the *content* of a post**${example}**`, + "it supports keyboard shortcuts"); }); click('#reply-control a.cancel'); @@ -58,7 +80,7 @@ test("Create a topic with server side errors", () => { visit("/"); click('#create-topic'); fillIn('#reply-title', "this title triggers an error"); - fillIn('.wmd-input', "this is the *content* of a post"); + fillIn('.d-editor-input', "this is the *content* of a post"); click('#reply-control button.create'); andThen(() => { ok(exists('.bootbox.modal'), 'it pops up an error message'); @@ -66,7 +88,7 @@ test("Create a topic with server side errors", () => { click('.bootbox.modal a.btn-primary'); andThen(() => { ok(!exists('.bootbox.modal'), 'it dismisses the error'); - ok(exists('.wmd-input'), 'the composer input is visible'); + ok(exists('.d-editor-input'), 'the composer input is visible'); }); }); @@ -74,7 +96,7 @@ test("Create a Topic", () => { visit("/"); click('#create-topic'); fillIn('#reply-title', "Internationalization Localization"); - fillIn('.wmd-input', "this is the *content* of a new topic post"); + fillIn('.d-editor-input', "this is the *content* of a new topic post"); click('#reply-control button.create'); andThen(() => { equal(currentURL(), "/t/internationalization-localization/280", "it transitions to the newly created topic URL"); @@ -85,7 +107,7 @@ test("Create an enqueued Topic", () => { visit("/"); click('#create-topic'); fillIn('#reply-title', "Internationalization Localization"); - fillIn('.wmd-input', "enqueue this content please"); + fillIn('.d-editor-input', "enqueue this content please"); click('#reply-control button.create'); andThen(() => { ok(visible('#discourse-modal'), 'it pops up a modal'); @@ -108,11 +130,11 @@ test("Create a Reply", () => { click('#topic-footer-buttons .btn.create'); andThen(() => { - ok(exists('.wmd-input'), 'the composer input is visible'); + ok(exists('.d-editor-input'), 'the composer input is visible'); ok(!exists('#reply-title'), 'there is no title since this is a reply'); }); - fillIn('.wmd-input', 'this is the content of my reply'); + fillIn('.d-editor-input', 'this is the content of my reply'); click('#reply-control button.create'); andThen(() => { equal(find('.cooked:last p').text(), 'this is the content of my reply'); @@ -122,7 +144,7 @@ test("Create a Reply", () => { test("Posting on a different topic", (assert) => { visit("/t/internationalization-localization/280"); click('#topic-footer-buttons .btn.create'); - fillIn('.wmd-input', 'this is the content for a different topic'); + fillIn('.d-editor-input', 'this is the content for a different topic'); visit("/t/1-3-0beta9-no-rate-limit-popups/28830"); andThen(function() { @@ -145,11 +167,11 @@ test("Create an enqueued Reply", () => { click('#topic-footer-buttons .btn.create'); andThen(() => { - ok(exists('.wmd-input'), 'the composer input is visible'); + ok(exists('.d-editor-input'), 'the composer input is visible'); ok(!exists('#reply-title'), 'there is no title since this is a reply'); }); - fillIn('.wmd-input', 'enqueue this content please'); + fillIn('.d-editor-input', 'enqueue this content please'); click('#reply-control button.create'); andThen(() => { ok(find('.cooked:last p').text() !== 'enqueue this content please', "it doesn't insert the post"); @@ -170,17 +192,17 @@ test("Edit the first post", () => { ok(!exists('.topic-post:eq(0) .post-info.edits'), 'it has no edits icon at first'); - click('.topic-post:eq(0) button[data-action=showMoreActions]'); - click('.topic-post:eq(0) button[data-action=edit]'); + click('.topic-post:eq(0) button.show-more-actions'); + click('.topic-post:eq(0) button.edit'); andThen(() => { - equal(find('.wmd-input').val().indexOf('Any plans to support'), 0, 'it populates the input with the post text'); + equal(find('.d-editor-input').val().indexOf('Any plans to support'), 0, 'it populates the input with the post text'); }); - fillIn('.wmd-input', "This is the new text for the post"); + fillIn('.d-editor-input', "This is the new text for the post"); fillIn('#reply-title', "This is the new text for the title"); click('#reply-control button.create'); andThen(() => { - ok(!exists('.wmd-input'), 'it closes the composer'); + ok(!exists('.d-editor-input'), 'it closes the composer'); ok(exists('.topic-post:eq(0) .post-info.edits'), 'it has the edits icon'); ok(find('#topic-title h1').text().indexOf('This is the new text for the title') !== -1, 'it shows the new title'); ok(find('.topic-post:eq(0) .cooked').text().indexOf('This is the new text for the post') !== -1, 'it updates the post'); @@ -190,75 +212,75 @@ test("Edit the first post", () => { test("Composer can switch between edits", () => { visit("/t/this-is-a-test-topic/9"); - click('.topic-post:eq(0) button[data-action=edit]'); + click('.topic-post:eq(0) button.edit'); andThen(() => { - equal(find('.wmd-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text'); + equal(find('.d-editor-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text'); }); - click('.topic-post:eq(1) button[data-action=edit]'); + click('.topic-post:eq(1) button.edit'); andThen(() => { - equal(find('.wmd-input').val().indexOf('This is the second post.'), 0, 'it populates the input with the post text'); + equal(find('.d-editor-input').val().indexOf('This is the second post.'), 0, 'it populates the input with the post text'); }); }); test("Composer with dirty edit can toggle to another edit", () => { visit("/t/this-is-a-test-topic/9"); - click('.topic-post:eq(0) button[data-action=edit]'); - fillIn('.wmd-input', 'This is a dirty reply'); - click('.topic-post:eq(1) button[data-action=edit]'); + click('.topic-post:eq(0) button.edit'); + fillIn('.d-editor-input', 'This is a dirty reply'); + click('.topic-post:eq(1) button.edit'); andThen(() => { ok(exists('.bootbox.modal'), 'it pops up a confirmation dialog'); }); click('.modal-footer a:eq(0)'); andThen(() => { - equal(find('.wmd-input').val().indexOf('This is the second post.'), 0, 'it populates the input with the post text'); + equal(find('.d-editor-input').val().indexOf('This is the second post.'), 0, 'it populates the input with the post text'); }); }); test("Composer can toggle between edit and reply", () => { visit("/t/this-is-a-test-topic/9"); - click('.topic-post:eq(0) button[data-action=edit]'); + click('.topic-post:eq(0) button.edit'); andThen(() => { - equal(find('.wmd-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text'); + equal(find('.d-editor-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text'); }); - click('.topic-post:eq(0) button[data-action=reply]'); + click('.topic-post:eq(0) button.reply'); andThen(() => { - equal(find('.wmd-input').val(), "", 'it clears the input'); + equal(find('.d-editor-input').val(), "", 'it clears the input'); }); - click('.topic-post:eq(0) button[data-action=edit]'); + click('.topic-post:eq(0) button.edit'); andThen(() => { - equal(find('.wmd-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text'); + equal(find('.d-editor-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text'); }); }); test("Composer with dirty reply can toggle to edit", () => { visit("/t/this-is-a-test-topic/9"); - click('.topic-post:eq(0) button[data-action=reply]'); - fillIn('.wmd-input', 'This is a dirty reply'); - click('.topic-post:eq(0) button[data-action=edit]'); + click('.topic-post:eq(0) button.reply'); + fillIn('.d-editor-input', 'This is a dirty reply'); + click('.topic-post:eq(0) button.edit'); andThen(() => { ok(exists('.bootbox.modal'), 'it pops up a confirmation dialog'); }); click('.modal-footer a:eq(0)'); andThen(() => { - equal(find('.wmd-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text'); + equal(find('.d-editor-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text'); }); }); test("Composer draft with dirty reply can toggle to edit", () => { visit("/t/this-is-a-test-topic/9"); - click('.topic-post:eq(0) button[data-action=reply]'); - fillIn('.wmd-input', 'This is a dirty reply'); + click('.topic-post:eq(0) button.reply'); + fillIn('.d-editor-input', 'This is a dirty reply'); click('.toggler'); - click('.topic-post:eq(0) button[data-action=edit]'); + click('.topic-post:eq(0) button.edit'); andThen(() => { ok(exists('.bootbox.modal'), 'it pops up a confirmation dialog'); }); click('.modal-footer a:eq(0)'); andThen(() => { - equal(find('.wmd-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text'); + equal(find('.d-editor-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text'); }); }); diff --git a/test/javascripts/acceptance/queued-posts-test.js.es6 b/test/javascripts/acceptance/queued-posts-test.js.es6 deleted file mode 100644 index c1a755503a1..00000000000 --- a/test/javascripts/acceptance/queued-posts-test.js.es6 +++ /dev/null @@ -1,75 +0,0 @@ -import { acceptance } from "helpers/qunit-helpers"; - -acceptance("Queued Posts", { loggedIn: true }); - -test("approve a post", () => { - visit("/queued-posts"); - - click('.queued-post:eq(0) button.approve'); - andThen(() => { - ok(!exists('.queued-post'), 'it removes the post'); - }); -}); - -test("reject a post", () => { - visit("/queued-posts"); - - click('.queued-post:eq(0) button.reject'); - andThen(() => { - ok(!exists('.queued-post'), 'it removes the post'); - }); -}); - -test("delete user", () => { - visit("/queued-posts"); - - click('.queued-post:eq(0) button.delete-user'); - andThen(() => { - ok(exists('.bootbox.modal'), 'it pops up a confirmation dialog'); - }); - - click('.modal-footer a:eq(1)'); - andThen(() => { - ok(!exists('.bootbox.modal'), 'it dismisses the modal'); - ok(exists('.queued-post'), "it doesn't remove the post"); - }); - - click('.queued-post:eq(0) button.delete-user'); - click('.modal-footer a:eq(0)'); - andThen(() => { - ok(!exists('.bootbox.modal'), 'it dismisses the modal'); - ok(!exists('.queued-post'), "it removes the post"); - }); -}); - -test("edit a post - cancel", () => { - visit("/queued-posts"); - - click('.queued-post:eq(0) button.edit'); - andThen(() => { - equal(find('.queued-post:eq(0) textarea').val(), 'queued post text', 'it shows an editor'); - }); - - fillIn('.queued-post:eq(0) textarea', 'new post text'); - click('.queued-post:eq(0) button.cancel'); - andThen(() => { - ok(!exists('textarea'), 'it disables editing'); - equal(find('.queued-post:eq(0) .body p').text(), 'queued post text', 'it reverts the new text'); - }); -}); - -test("edit a post - confirm", () => { - visit("/queued-posts"); - - click('.queued-post:eq(0) button.edit'); - andThen(() => { - equal(find('.queued-post:eq(0) textarea').val(), 'queued post text', 'it shows an editor'); - }); - - fillIn('.queued-post:eq(0) textarea', 'new post text'); - click('.queued-post:eq(0) button.confirm'); - andThen(() => { - ok(!exists('textarea'), 'it disables editing'); - equal(find('.queued-post:eq(0) .body p').text(), 'new post text', 'it has the new text'); - }); -}); diff --git a/test/javascripts/acceptance/user-anonymous-test.js.es6 b/test/javascripts/acceptance/user-anonymous-test.js.es6 index 3a7ce74d8fc..2151606d4f2 100644 --- a/test/javascripts/acceptance/user-anonymous-test.js.es6 +++ b/test/javascripts/acceptance/user-anonymous-test.js.es6 @@ -8,42 +8,29 @@ export function hasStream() { }); } -function hasTopicList() { - andThen(() => { - equal(count('.user-stream .item'), 0, "has no stream displayed"); - ok(count('.topic-list tr') > 0, 'it has a topic list'); - }); -} +// function hasTopicList() { +// andThen(() => { +// equal(count('.user-stream .item'), 0, "has no stream displayed"); +// ok(count('.topic-list tr') > 0, 'it has a topic list'); +// }); +// } -test("Filters", () => { - expect(14); - - visit("/users/eviltrout"); - hasStream(); - - visit("/users/eviltrout/activity/topics"); - hasTopicList(); - - visit("/users/eviltrout/activity/posts"); - hasStream(); - - visit("/users/eviltrout/activity/replies"); - hasStream(); - - visit("/users/eviltrout/activity/likes-given"); - hasStream(); - - visit("/users/eviltrout/activity/likes-received"); - hasStream(); - - visit("/users/eviltrout/activity/edits"); - hasStream(); -}); - -test("Restricted Routes", () => { - visit("/users/eviltrout/preferences"); - - andThen(() => { - equal(currentURL(), '/users/eviltrout/activity', "it redirects from preferences"); - }); -}); +// test("Filters", () => { +// visit("/users/eviltrout"); +// hasStream(); +// +// visit("/users/eviltrout/activity/topics"); +// hasTopicList(); +// +// visit("/users/eviltrout/activity/posts"); +// hasStream(); +// +// }); +// +// test("Restricted Routes", () => { +// visit("/users/eviltrout/preferences"); +// +// andThen(() => { +// equal(currentURL(), '/users/eviltrout/activity', "it redirects from preferences"); +// }); +// }); diff --git a/test/javascripts/acceptance/user-test.js.es6 b/test/javascripts/acceptance/user-test.js.es6 index e642d2aad47..c91acb7d57a 100644 --- a/test/javascripts/acceptance/user-test.js.es6 +++ b/test/javascripts/acceptance/user-test.js.es6 @@ -1,9 +1,9 @@ import { acceptance } from "helpers/qunit-helpers"; -import { hasStream } from 'acceptance/user-anonymous-test'; +// import { hasStream } from 'acceptance/user-anonymous-test'; acceptance("User", {loggedIn: true}); -test("Pending", () => { - visit("/users/eviltrout/activity/pending"); - hasStream(); -}); +// test("Pending", () => { +// visit("/users/eviltrout/activity/pending"); +// hasStream(); +// }); diff --git a/test/javascripts/admin/controllers/admin-user-badges-test.js.es6 b/test/javascripts/admin/controllers/admin-user-badges-test.js.es6 index 5c06c69c52f..4a0a676651a 100644 --- a/test/javascripts/admin/controllers/admin-user-badges-test.js.es6 +++ b/test/javascripts/admin/controllers/admin-user-badges-test.js.es6 @@ -5,14 +5,17 @@ moduleFor('controller:admin-user-badges', { }); test("grantableBadges", function() { - const badgeFirst = Badge.create({id: 3, name: "A Badge"}); - const badgeMiddle = Badge.create({id: 1, name: "My Badge"}); - const badgeLast = Badge.create({id: 2, name: "Zoo Badge"}); - const controller = this.subject({ badges: [badgeLast, badgeFirst, badgeMiddle] }); + const badgeFirst = Badge.create({id: 3, name: "A Badge", enabled: true}); + const badgeMiddle = Badge.create({id: 1, name: "My Badge", enabled: true}); + const badgeLast = Badge.create({id: 2, name: "Zoo Badge", enabled: true}); + const badgeDisabled = Badge.create({id: 4, name: "Disabled Badge", enabled: false}); + const controller = this.subject({ badges: [badgeLast, badgeFirst, badgeMiddle, badgeDisabled] }); const sortedNames = [badgeFirst.name, badgeMiddle.name, badgeLast.name]; const badgeNames = controller.get('grantableBadges').map(function(badge) { return badge.name; }); + + not(badgeNames.contains(badgeDisabled), "excludes disabled badges"); deepEqual(badgeNames, sortedNames, "sorts badges by name"); }); diff --git a/test/javascripts/admin/models/admin-user-test.js.es6 b/test/javascripts/admin/models/admin-user-test.js.es6 index 5d0b231857d..16e3cf0dde9 100644 --- a/test/javascripts/admin/models/admin-user-test.js.es6 +++ b/test/javascripts/admin/models/admin-user-test.js.es6 @@ -1,11 +1,13 @@ import { blank, present } from 'helpers/qunit-helpers'; +import AdminUser from 'admin/models/admin-user'; +import ApiKey from 'admin/models/api-key'; module("Discourse.AdminUser"); asyncTestDiscourse('generate key', function() { sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {id: 1234, key: 'asdfasdf'}})); - var adminUser = Discourse.AdminUser.create({id: 333}); + var adminUser = AdminUser.create({id: 333}); blank(adminUser.get('api_key'), 'it has no api key by default'); adminUser.generateApiKey().then(function() { @@ -17,8 +19,8 @@ asyncTestDiscourse('generate key', function() { asyncTestDiscourse('revoke key', function() { - var apiKey = Discourse.ApiKey.create({id: 1234, key: 'asdfasdf'}), - adminUser = Discourse.AdminUser.create({id: 333, api_key: apiKey}); + var apiKey = ApiKey.create({id: 1234, key: 'asdfasdf'}), + adminUser = AdminUser.create({id: 333, api_key: apiKey}); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve()); diff --git a/test/javascripts/admin/models/api-key-test.js.es6 b/test/javascripts/admin/models/api-key-test.js.es6 index 07121c9e164..640845ff802 100644 --- a/test/javascripts/admin/models/api-key-test.js.es6 +++ b/test/javascripts/admin/models/api-key-test.js.es6 @@ -1,9 +1,10 @@ import { present } from 'helpers/qunit-helpers'; +import ApiKey from 'admin/models/api-key'; module("Discourse.ApiKey"); test('create', function() { - var apiKey = Discourse.ApiKey.create({id: 123, user: {id: 345}}); + var apiKey = ApiKey.create({id: 123, user: {id: 345}}); present(apiKey, 'it creates the api key'); present(apiKey.get('user'), 'it creates the user inside'); @@ -12,7 +13,7 @@ test('create', function() { asyncTestDiscourse('find', function() { sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve([])); - Discourse.ApiKey.find().then(function() { + ApiKey.find().then(function() { start(); ok(Discourse.ajax.calledWith("/admin/api"), "it GETs the keys"); }); @@ -20,14 +21,14 @@ asyncTestDiscourse('find', function() { asyncTestDiscourse('generateMasterKey', function() { sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {}})); - Discourse.ApiKey.generateMasterKey().then(function() { + ApiKey.generateMasterKey().then(function() { start(); ok(Discourse.ajax.calledWith("/admin/api/key", {type: 'POST'}), "it POSTs to create a master key"); }); }); asyncTestDiscourse('regenerate', function() { - var apiKey = Discourse.ApiKey.create({id: 3456}); + var apiKey = ApiKey.create({id: 3456}); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {id: 3456}})); apiKey.regenerate().then(function() { @@ -37,7 +38,7 @@ asyncTestDiscourse('regenerate', function() { }); asyncTestDiscourse('revoke', function() { - var apiKey = Discourse.ApiKey.create({id: 3456}); + var apiKey = ApiKey.create({id: 3456}); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve([])); apiKey.revoke().then(function() { diff --git a/test/javascripts/admin/models/flagged-post-test.js.es6 b/test/javascripts/admin/models/flagged-post-test.js.es6 index bf26a06648f..3b5587e041b 100644 --- a/test/javascripts/admin/models/flagged-post-test.js.es6 +++ b/test/javascripts/admin/models/flagged-post-test.js.es6 @@ -1,9 +1,11 @@ +import FlaggedPost from 'admin/models/flagged-post'; + module("Discourse.FlaggedPost"); test('delete first post', function() { sandbox.stub(Discourse, 'ajax'); - Discourse.FlaggedPost.create({ id: 1, topic_id: 2, post_number: 1 }) + FlaggedPost.create({ id: 1, topic_id: 2, post_number: 1 }) .deletePost(); ok(Discourse.ajax.calledWith("/t/2", { type: 'DELETE', cache: false }), "it deleted the topic"); @@ -12,7 +14,7 @@ test('delete first post', function() { test('delete second post', function() { sandbox.stub(Discourse, 'ajax'); - Discourse.FlaggedPost.create({ id: 1, topic_id: 2, post_number: 2 }) + FlaggedPost.create({ id: 1, topic_id: 2, post_number: 2 }) .deletePost(); ok(Discourse.ajax.calledWith("/posts/1", { type: 'DELETE', cache: false }), "it deleted the post"); diff --git a/test/javascripts/components/d-editor-test.js.es6 b/test/javascripts/components/d-editor-test.js.es6 new file mode 100644 index 00000000000..ffcb67d33fb --- /dev/null +++ b/test/javascripts/components/d-editor-test.js.es6 @@ -0,0 +1,594 @@ +import componentTest from 'helpers/component-test'; +import { withPluginApi } from 'discourse/lib/plugin-api'; + +moduleForComponent('d-editor', {integration: true}); + +componentTest('preview updates with markdown', { + template: '{{d-editor value=value}}', + + test(assert) { + assert.ok(this.$('.d-editor-button-bar').length); + fillIn('.d-editor-input', 'hello **world**'); + + andThen(() => { + assert.equal(this.get('value'), 'hello **world**'); + assert.equal(this.$('.d-editor-preview').html().trim(), '

    hello world

    '); + }); + } +}); + +componentTest('preview sanitizes HTML', { + template: '{{d-editor value=value}}', + + test(assert) { + this.set('value', `">`); + andThen(() => { + assert.equal(this.$('.d-editor-preview').html().trim(), '

    \">

    '); + }); + } +}); + +componentTest('updating the value refreshes the preview', { + template: '{{d-editor value=value}}', + + setup() { + this.set('value', 'evil trout'); + }, + + test(assert) { + assert.equal(this.$('.d-editor-preview').html().trim(), '

    evil trout

    '); + + andThen(() => this.set('value', 'zogstrip')); + andThen(() => assert.equal(this.$('.d-editor-preview').html().trim(), '

    zogstrip

    ')); + } +}); + +function jumpEnd(textarea) { + textarea.selectionStart = textarea.value.length; + textarea.selectionEnd = textarea.value.length; + return textarea; +} + +function testCase(title, testFunc) { + componentTest(title, { + template: '{{d-editor value=value}}', + setup() { + this.set('value', 'hello world.'); + }, + test(assert) { + const textarea = jumpEnd(this.$('textarea.d-editor-input')[0]); + testFunc.call(this, assert, textarea); + } + }); +} + +testCase(`selecting the space before a word`, function(assert, textarea) { + textarea.selectionStart = 5; + textarea.selectionEnd = 7; + + click(`button.bold`); + andThen(() => { + assert.equal(this.get('value'), `hello **w**orld.`); + assert.equal(textarea.selectionStart, 8); + assert.equal(textarea.selectionEnd, 9); + }); +}); + +testCase(`selecting the space after a word`, function(assert, textarea) { + textarea.selectionStart = 0; + textarea.selectionEnd = 6; + + click(`button.bold`); + andThen(() => { + assert.equal(this.get('value'), `**hello** world.`); + assert.equal(textarea.selectionStart, 2); + assert.equal(textarea.selectionEnd, 7); + }); +}); + +testCase(`bold button with no selection`, function(assert, textarea) { + click(`button.bold`); + andThen(() => { + const example = I18n.t(`composer.bold_text`); + assert.equal(this.get('value'), `hello world.**${example}**`); + assert.equal(textarea.selectionStart, 14); + assert.equal(textarea.selectionEnd, 14 + example.length); + }); +}); + +testCase(`bold button with a selection`, function(assert, textarea) { + textarea.selectionStart = 6; + textarea.selectionEnd = 11; + + click(`button.bold`); + andThen(() => { + assert.equal(this.get('value'), `hello **world**.`); + assert.equal(textarea.selectionStart, 8); + assert.equal(textarea.selectionEnd, 13); + }); + + click(`button.bold`); + andThen(() => { + assert.equal(this.get('value'), 'hello world.'); + assert.equal(textarea.selectionStart, 6); + assert.equal(textarea.selectionEnd, 11); + }); +}); + +testCase(`bold with a multiline selection`, function (assert, textarea) { + this.set('value', "hello\n\nworld\n\ntest."); + + andThen(() => { + textarea.selectionStart = 0; + textarea.selectionEnd = 12; + }); + + click(`button.bold`); + andThen(() => { + assert.equal(this.get('value'), `**hello**\n\n**world**\n\ntest.`); + assert.equal(textarea.selectionStart, 0); + assert.equal(textarea.selectionEnd, 20); + }); + + click(`button.bold`); + andThen(() => { + assert.equal(this.get('value'), `hello\n\nworld\n\ntest.`); + assert.equal(textarea.selectionStart, 0); + assert.equal(textarea.selectionEnd, 12); + }); +}); + +testCase(`italic button with no selection`, function(assert, textarea) { + click(`button.italic`); + andThen(() => { + const example = I18n.t(`composer.italic_text`); + assert.equal(this.get('value'), `hello world._${example}_`); + + assert.equal(textarea.selectionStart, 13); + assert.equal(textarea.selectionEnd, 13 + example.length); + }); +}); + +testCase(`italic button with a selection`, function(assert, textarea) { + textarea.selectionStart = 6; + textarea.selectionEnd = 11; + + click(`button.italic`); + andThen(() => { + assert.equal(this.get('value'), `hello _world_.`); + assert.equal(textarea.selectionStart, 7); + assert.equal(textarea.selectionEnd, 12); + }); + + click(`button.italic`); + andThen(() => { + assert.equal(this.get('value'), 'hello world.'); + assert.equal(textarea.selectionStart, 6); + assert.equal(textarea.selectionEnd, 11); + }); +}); + +testCase(`italic with a multiline selection`, function (assert, textarea) { + this.set('value', "hello\n\nworld\n\ntest."); + + andThen(() => { + textarea.selectionStart = 0; + textarea.selectionEnd = 12; + }); + + click(`button.italic`); + andThen(() => { + assert.equal(this.get('value'), `_hello_\n\n_world_\n\ntest.`); + assert.equal(textarea.selectionStart, 0); + assert.equal(textarea.selectionEnd, 16); + }); + + click(`button.italic`); + andThen(() => { + assert.equal(this.get('value'), `hello\n\nworld\n\ntest.`); + assert.equal(textarea.selectionStart, 0); + assert.equal(textarea.selectionEnd, 12); + }); +}); + +testCase('link modal (cancel)', function(assert) { + assert.equal(this.$('.insert-link.hidden').length, 1); + + click('button.link'); + andThen(() => { + assert.equal(this.$('.insert-link.hidden').length, 0); + }); + + click('.insert-link button.btn-danger'); + andThen(() => { + assert.equal(this.$('.insert-link.hidden').length, 1); + assert.equal(this.get('value'), 'hello world.'); + }); +}); + +testCase('link modal (simple link)', function(assert, textarea) { + click('button.link'); + fillIn('.insert-link input', 'http://eviltrout.com'); + click('.insert-link button.btn-primary'); + const desc = I18n.t('composer.link_description'); + andThen(() => { + assert.equal(this.$('.insert-link.hidden').length, 1); + assert.equal(this.get('value'), `hello world.[${desc}](http://eviltrout.com)`); + assert.equal(textarea.selectionStart, 13); + assert.equal(textarea.selectionEnd, 13 + desc.length); + }); +}); + +testCase('link modal auto http addition', function(assert) { + click('button.link'); + fillIn('.insert-link input', 'sam.com'); + click('.insert-link button.btn-primary'); + const desc = I18n.t('composer.link_description'); + andThen(() => { + assert.equal(this.get('value'), `hello world.[${desc}](http://sam.com)`); + }); +}); + +testCase('link modal (simple link) with selected text', function(assert, textarea) { + textarea.selectionStart = 0; + textarea.selectionEnd = 12; + + click('button.link'); + fillIn('.insert-link input', 'http://eviltrout.com'); + click('.insert-link button.btn-primary'); + andThen(() => { + assert.equal(this.$('.insert-link.hidden').length, 1); + assert.equal(this.get('value'), '[hello world.](http://eviltrout.com)'); + }); +}); + +testCase('link modal (link with description)', function(assert) { + click('button.link'); + fillIn('.insert-link input', 'http://eviltrout.com "evil trout"'); + click('.insert-link button.btn-primary'); + andThen(() => { + assert.equal(this.$('.insert-link.hidden').length, 1); + assert.equal(this.get('value'), 'hello world.[evil trout](http://eviltrout.com)'); + }); +}); + +componentTest('advanced code', { + template: '{{d-editor value=value}}', + setup() { + this.set('value', +`function xyz(x, y, z) { + if (y === z) { + return true; + } +}`); + }, + + test(assert) { + const textarea = this.$('textarea.d-editor-input')[0]; + textarea.selectionStart = 0; + textarea.selectionEnd = textarea.value.length; + + click('button.code'); + andThen(() => { + assert.equal(this.get('value'), +` function xyz(x, y, z) { + if (y === z) { + return true; + } + }`); + }); + } + +}); + +componentTest('code button', { + template: '{{d-editor value=value}}', + setup() { + this.set('value', "first line\n\nsecond line\n\nthird line"); + }, + + test(assert) { + const textarea = jumpEnd(this.$('textarea.d-editor-input')[0]); + + click('button.code'); + andThen(() => { + assert.equal(this.get('value'), "first line\n\nsecond line\n\nthird line`" + I18n.t('composer.code_text') + "`"); + this.set('value', "first line\n\nsecond line\n\nthird line"); + }); + + andThen(() => { + textarea.selectionStart = 6; + textarea.selectionEnd = 10; + }); + + click('button.code'); + andThen(() => { + assert.equal(this.get('value'), "first `line`\n\nsecond line\n\nthird line"); + assert.equal(textarea.selectionStart, 7); + assert.equal(textarea.selectionEnd, 11); + }); + + click('button.code'); + andThen(() => { + assert.equal(this.get('value'), "first line\n\nsecond line\n\nthird line"); + assert.equal(textarea.selectionStart, 6); + assert.equal(textarea.selectionEnd, 10); + + textarea.selectionStart = 0; + textarea.selectionEnd = 23; + }); + + click('button.code'); + andThen(() => { + assert.equal(this.get('value'), " first line\n\n second line\n\nthird line"); + assert.equal(textarea.selectionStart, 0); + assert.equal(textarea.selectionEnd, 31); + }); + + click('button.code'); + andThen(() => { + assert.equal(this.get('value'), "first line\n\nsecond line\n\nthird line"); + assert.equal(textarea.selectionStart, 0); + assert.equal(textarea.selectionEnd, 23); + }); + } +}); + +testCase('quote button', function(assert, textarea) { + click('button.quote'); + andThen(() => { + assert.equal(this.get('value'), 'hello world.'); + }); + + andThen(() => { + textarea.selectionStart = 6; + textarea.selectionEnd = 11; + }); + + click('button.quote'); + andThen(() => { + assert.equal(this.get('value'), 'hello > world.'); + assert.equal(textarea.selectionStart, 6); + assert.equal(textarea.selectionEnd, 13); + }); + + click('button.quote'); + andThen(() => { + assert.equal(this.get('value'), 'hello world.'); + assert.equal(textarea.selectionStart, 6); + assert.equal(textarea.selectionEnd, 11); + }); +}); + +testCase(`bullet button with no selection`, function(assert, textarea) { + const example = I18n.t('composer.list_item'); + + click(`button.bullet`); + andThen(() => { + assert.equal(this.get('value'), `hello world.\n\n* ${example}`); + assert.equal(textarea.selectionStart, 14); + assert.equal(textarea.selectionEnd, 16 + example.length); + }); + + click(`button.bullet`); + andThen(() => { + assert.equal(this.get('value'), `hello world.\n\n${example}`); + }); +}); + +testCase(`bullet button with a selection`, function(assert, textarea) { + textarea.selectionStart = 6; + textarea.selectionEnd = 11; + + click(`button.bullet`); + andThen(() => { + assert.equal(this.get('value'), `hello\n\n* world\n\n.`); + assert.equal(textarea.selectionStart, 7); + assert.equal(textarea.selectionEnd, 14); + }); + + click(`button.bullet`); + andThen(() => { + assert.equal(this.get('value'), `hello\n\nworld\n\n.`); + assert.equal(textarea.selectionStart, 7); + assert.equal(textarea.selectionEnd, 12); + }); +}); + +testCase(`bullet button with a multiple line selection`, function(assert, textarea) { + this.set('value', "* Hello\n\nWorld\n\nEvil"); + + andThen(() => { + textarea.selectionStart = 0; + textarea.selectionEnd = 20; + }); + + click(`button.bullet`); + andThen(() => { + assert.equal(this.get('value'), "Hello\n\nWorld\n\nEvil"); + assert.equal(textarea.selectionStart, 0); + assert.equal(textarea.selectionEnd, 18); + }); + + click(`button.bullet`); + andThen(() => { + assert.equal(this.get('value'), "* Hello\n\n* World\n\n* Evil"); + assert.equal(textarea.selectionStart, 0); + assert.equal(textarea.selectionEnd, 24); + }); +}); + +testCase(`list button with no selection`, function(assert, textarea) { + const example = I18n.t('composer.list_item'); + + click(`button.list`); + andThen(() => { + assert.equal(this.get('value'), `hello world.\n\n1. ${example}`); + assert.equal(textarea.selectionStart, 14); + assert.equal(textarea.selectionEnd, 17 + example.length); + }); + + click(`button.list`); + andThen(() => { + assert.equal(this.get('value'), `hello world.\n\n${example}`); + assert.equal(textarea.selectionStart, 14); + assert.equal(textarea.selectionEnd, 14 + example.length); + }); +}); + +testCase(`list button with a selection`, function(assert, textarea) { + textarea.selectionStart = 6; + textarea.selectionEnd = 11; + + click(`button.list`); + andThen(() => { + assert.equal(this.get('value'), `hello\n\n1. world\n\n.`); + assert.equal(textarea.selectionStart, 7); + assert.equal(textarea.selectionEnd, 15); + }); + + click(`button.list`); + andThen(() => { + assert.equal(this.get('value'), `hello\n\nworld\n\n.`); + assert.equal(textarea.selectionStart, 7); + assert.equal(textarea.selectionEnd, 12); + }); +}); + +testCase(`list button with line sequence`, function(assert, textarea) { + this.set('value', "Hello\n\nWorld\n\nEvil"); + + andThen(() => { + textarea.selectionStart = 0; + textarea.selectionEnd = 18; + }); + + click(`button.list`); + andThen(() => { + assert.equal(this.get('value'), "1. Hello\n\n2. World\n\n3. Evil"); + assert.equal(textarea.selectionStart, 0); + assert.equal(textarea.selectionEnd, 27); + }); + + click(`button.list`); + andThen(() => { + assert.equal(this.get('value'), "Hello\n\nWorld\n\nEvil"); + assert.equal(textarea.selectionStart, 0); + assert.equal(textarea.selectionEnd, 18); + }); +}); + +testCase(`heading button with no selection`, function(assert, textarea) { + const example = I18n.t('composer.heading_text'); + + click(`button.heading`); + andThen(() => { + assert.equal(this.get('value'), `hello world.\n\n## ${example}`); + assert.equal(textarea.selectionStart, 14); + assert.equal(textarea.selectionEnd, 17 + example.length); + }); + + textarea.selectionStart = 30; + textarea.selectionEnd = 30; + click(`button.heading`); + andThen(() => { + assert.equal(this.get('value'), `hello world.\n\n${example}`); + assert.equal(textarea.selectionStart, 14); + assert.equal(textarea.selectionEnd, 14 + example.length); + }); +}); + +testCase(`rule between things`, function(assert, textarea) { + textarea.selectionStart = 5; + textarea.selectionEnd = 5; + + click(`button.rule`); + andThen(() => { + assert.equal(this.get('value'), `hello\n\n----------\n world.`); + assert.equal(textarea.selectionStart, 18); + assert.equal(textarea.selectionEnd, 18); + }); +}); + +testCase(`rule with no selection`, function(assert, textarea) { + click(`button.rule`); + andThen(() => { + assert.equal(this.get('value'), `hello world.\n\n----------\n`); + assert.equal(textarea.selectionStart, 25); + assert.equal(textarea.selectionEnd, 25); + }); + + click(`button.rule`); + andThen(() => { + assert.equal(this.get('value'), `hello world.\n\n----------\n\n\n----------\n`); + assert.equal(textarea.selectionStart, 38); + assert.equal(textarea.selectionEnd, 38); + }); +}); + +testCase(`rule with a selection`, function(assert, textarea) { + textarea.selectionStart = 6; + textarea.selectionEnd = 11; + + click(`button.rule`); + andThen(() => { + assert.equal(this.get('value'), `hello \n\n----------\n.`); + assert.equal(textarea.selectionStart, 19); + assert.equal(textarea.selectionEnd, 19); + }); +}); + +testCase(`doesn't jump to bottom with long text`, function(assert, textarea) { + + let longText = 'hello world.'; + for (let i=0; i<8; i++) { + longText = longText + longText; + } + this.set('value', longText); + + andThen(() => { + $(textarea).scrollTop(0); + textarea.selectionStart = 3; + textarea.selectionEnd = 3; + }); + + click('button.bold'); + andThen(() => { + assert.equal($(textarea).scrollTop(), 0, 'it stays scrolled up'); + }); +}); + +componentTest('emoji', { + template: '{{d-editor value=value}}', + setup() { + // Test adding a custom button + withPluginApi('0.1', api => { + api.onToolbarCreate(toolbar => { + toolbar.addButton({ + id: 'emoji', + group: 'extras', + icon: 'smile-o', + action: 'emoji' + }); + }); + }); + this.set('value', 'hello world.'); + }, + test(assert) { + assert.equal($('.emoji-modal').length, 0); + + jumpEnd(this.$('textarea.d-editor-input')[0]); + click('button.emoji'); + andThen(() => { + assert.equal($('.emoji-modal').length, 1); + }); + + click('a[data-group-id=0]'); + click('a[title=grinning]'); + + andThen(() => { + assert.ok($('.emoji-modal').length === 0); + assert.equal(this.get('value'), 'hello world.:grinning:'); + }); + } +}); diff --git a/test/javascripts/components/d-link-test.js.es6 b/test/javascripts/components/d-link-test.js.es6 index fc17333d300..a025cc6d769 100644 --- a/test/javascripts/components/d-link-test.js.es6 +++ b/test/javascripts/components/d-link-test.js.es6 @@ -20,8 +20,6 @@ componentTest('with a label', { test(assert) { const $a = this.$('a'); assert.equal($a.text(), I18n.t('user.preferences')); - assert.equal($a.attr('title'), I18n.t('user.preferences')); - assert.equal($a.attr('aria-title'), I18n.t('user.preferences')); } }); @@ -31,8 +29,6 @@ componentTest('with a label and icon', { const $a = this.$('a'); assert.ok(this.$('i.fa-gear', $a).length, 'shows the icon'); assert.equal($a.text(), ` ${I18n.t('user.preferences')}`, "includes a space"); - assert.equal($a.attr('title'), I18n.t('user.preferences')); - assert.equal($a.attr('aria-title'), I18n.t('user.preferences')); } }); diff --git a/test/javascripts/components/home-logo-test.js.es6 b/test/javascripts/components/home-logo-test.js.es6 new file mode 100644 index 00000000000..60eefd94b9f --- /dev/null +++ b/test/javascripts/components/home-logo-test.js.es6 @@ -0,0 +1,90 @@ +import componentTest from 'helpers/component-test'; + +moduleForComponent('home-logo', {integration: true}); + +const bigLogo = '/images/d-logo-sketch.png?test'; +const smallLogo = '/images/d-logo-sketch-small.png?test'; +const mobileLogo = '/images/d-logo-sketch.png?mobile'; +const title = "Cool Forum"; + +componentTest('basics', { + template: '{{home-logo minimized=minimized}}', + setup() { + this.siteSettings.logo_url = bigLogo; + this.siteSettings.logo_small_url= smallLogo; + this.siteSettings.title = title; + this.set('minimized', false); + }, + + test(assert) { + assert.ok(this.$('.title').length === 1); + assert.ok(this.$('a[data-auto-route]').length === 1); + + assert.ok(this.$('img#site-logo.logo-big').length === 1); + assert.equal(this.$('#site-logo').attr('src'), bigLogo); + assert.equal(this.$('#site-logo').attr('alt'), title); + + this.set('minimized', true); + andThen(() => { + assert.ok(this.$('img.logo-small').length === 1); + assert.equal(this.$('img.logo-small').attr('src'), smallLogo); + assert.equal(this.$('img.logo-small').attr('alt'), title); + }); + } +}); + +componentTest('no logo', { + template: '{{home-logo minimized=minimized}}', + setup() { + this.siteSettings.logo_url = ''; + this.siteSettings.logo_small_url = ''; + this.siteSettings.title = title; + this.set('minimized', false); + }, + + test(assert) { + assert.ok(this.$('a[data-auto-route]').length === 1); + + assert.ok(this.$('h2#site-text-logo.text-logo').length === 1); + assert.equal(this.$('#site-text-logo').text(), title); + + this.set('minimized', true); + andThen(() => { + assert.ok(this.$('i.fa-home').length === 1); + }); + } +}); + +componentTest('mobile logo', { + template: "{{home-logo}}", + setup() { + this.siteSettings.mobile_logo_url = mobileLogo; + this.siteSettings.logo_small_url= smallLogo; + this.site.mobileView = true; + }, + + test(assert) { + assert.ok(this.$('img#site-logo.logo-big').length === 1); + assert.equal(this.$('#site-logo').attr('src'), mobileLogo); + } +}); + +componentTest('mobile without logo', { + template: "{{home-logo}}", + setup() { + this.siteSettings.logo_url = bigLogo; + this.site.mobileView = true; + }, + + test(assert) { + assert.ok(this.$('img#site-logo.logo-big').length === 1); + assert.equal(this.$('#site-logo').attr('src'), bigLogo); + } +}); + +componentTest("changing url", { + template: '{{home-logo targetUrl="https://www.discourse.org"}}', + test(assert) { + assert.equal(this.$('a').attr('href'), 'https://www.discourse.org'); + } +}); diff --git a/test/javascripts/components/post-menu-test.js.es6 b/test/javascripts/components/post-menu-test.js.es6 deleted file mode 100644 index a027bb660fa..00000000000 --- a/test/javascripts/components/post-menu-test.js.es6 +++ /dev/null @@ -1,52 +0,0 @@ -import componentTest from 'helpers/component-test'; - -moduleForComponent('post-menu', {integration: true}); - -function setup(store) { - const topic = store.createRecord('topic', {id: 123}); - const post = store.createRecord('post', { - id: 1, - post_number: 1, - topic, - like_count: 3, - actions_summary: [ - {id: 2, count: 3, hidden: false, can_act: true} - ] - }); - - this.on('toggleLike', function() { - post.toggleProperty('likeAction.acted'); - }); - - this.set('post', post); -} - -componentTest('basic render', { - template: '{{post-menu post=post}}', - setup, - test(assert) { - assert.ok(!!this.$('.post-menu-area').length, 'it renders a post menu'); - assert.ok(!!this.$('.actions button[data-share-url]').length, 'it renders a share button'); - } -}); - -componentTest('liking', { - template: '{{post-menu post=post toggleLike="toggleLike"}}', - setup, - test(assert) { - assert.ok(!!this.$('.actions button.like').length); - assert.ok(!!this.$('.actions button.like-count').length); - - click('.actions button.like'); - andThen(() => { - assert.ok(!this.$('.actions button.like').length); - assert.ok(!!this.$('.actions button.has-like').length); - }); - - click('.actions button.has-like'); - andThen(() => { - assert.ok(!!this.$('.actions button.like').length); - assert.ok(!this.$('.actions button.has-like').length); - }); - } -}); diff --git a/test/javascripts/controllers/create-account-test.js.es6 b/test/javascripts/controllers/create-account-test.js.es6 index 4c202880aa0..0f7284be6f4 100644 --- a/test/javascripts/controllers/create-account-test.js.es6 +++ b/test/javascripts/controllers/create-account-test.js.es6 @@ -28,11 +28,11 @@ test('passwordValidation', function() { var controller = subject(); controller.set('passwordRequired', true); - controller.set('accountEmail', 'pork@chops.com'); - controller.set('accountUsername', 'porkchops'); + controller.set('accountEmail', 'pork@chops.com'); + controller.set('accountUsername', 'porkchops'); controller.set('prefilledUsername', 'porkchops'); - controller.set('accountPassword', 'b4fcdae11f9167'); + controller.set('accountPassword', 'b4fcdae11f9167'); equal(controller.get('passwordValidation.ok'), true, 'Password is ok'); equal(controller.get('passwordValidation.reason'), I18n.t('user.password.ok'), 'Password is valid'); diff --git a/test/javascripts/controllers/flag-test.js.es6 b/test/javascripts/controllers/flag-test.js.es6 index beb5dd9af6e..ebff4fd1d7b 100644 --- a/test/javascripts/controllers/flag-test.js.es6 +++ b/test/javascripts/controllers/flag-test.js.es6 @@ -1,4 +1,5 @@ import createStore from 'helpers/create-store'; +import AdminUser from 'admin/models/admin-user'; var buildPost = function(args) { return Discourse.Post.create(_.merge({ @@ -9,7 +10,7 @@ var buildPost = function(args) { }; var buildAdminUser = function(args) { - return Discourse.AdminUser.create(_.merge({ + return AdminUser.create(_.merge({ id: 11, username: 'urist' }, args || {})); diff --git a/test/javascripts/controllers/topic-test.js.es6 b/test/javascripts/controllers/topic-test.js.es6 index 13fdc144eb8..48f0bcdbd02 100644 --- a/test/javascripts/controllers/topic-test.js.es6 +++ b/test/javascripts/controllers/topic-test.js.es6 @@ -6,6 +6,7 @@ moduleFor('controller:topic', 'controller:topic', { }); import Topic from 'discourse/models/topic'; +import AppEvents from 'discourse/lib/app-events'; var buildTopic = function() { return Topic.create({ @@ -62,7 +63,7 @@ test("toggledSelectedPost", function() { }); test("selectAll", function() { - var tc = this.subject({model: buildTopic()}), + var tc = this.subject({model: buildTopic(), appEvents: AppEvents.create()}), post = Discourse.Post.create({id: 123, post_number: 2}), postStream = tc.get('model.postStream'); diff --git a/test/javascripts/ember/resolver-test.js.es6 b/test/javascripts/ember/resolver-test.js.es6 index 948add12d8b..1e5ad1ea593 100644 --- a/test/javascripts/ember/resolver-test.js.es6 +++ b/test/javascripts/ember/resolver-test.js.es6 @@ -1,7 +1,7 @@ import DiscourseResolver from 'discourse/ember/resolver'; -var originalTemplates, originalMobileViewFlag; -var resolver = DiscourseResolver.create(); +let originalTemplates; +let resolver; function lookupTemplate(name, expectedTemplate, message) { var parseName = resolver.parseName(name); @@ -20,13 +20,11 @@ module("lib:resolver", { originalTemplates = Ember.TEMPLATES; Ember.TEMPLATES = {}; - originalMobileViewFlag = Discourse.Mobile.mobileView; - Discourse.Mobile.mobileView = false; + resolver = DiscourseResolver.create(); }, teardown: function() { Ember.TEMPLATES = originalTemplates; - Discourse.Mobile.mobileView = originalMobileViewFlag; } }); @@ -92,7 +90,7 @@ test("resolves mobile templates to 'mobile/' namespace", function() { "baz" ]); - Discourse.Mobile.mobileView = true; + resolver.mobileView = true; lookupTemplate("template:foo", "mobile/foo", "finding mobile version even if normal one is not present"); lookupTemplate("template:bar", "mobile/bar", "preferring mobile version when both mobile and normal versions are present"); diff --git a/test/javascripts/fixtures/badges_fixture.js.es6 b/test/javascripts/fixtures/badges_fixture.js.es6 index a91876c2825..53352f2f783 100644 --- a/test/javascripts/fixtures/badges_fixture.js.es6 +++ b/test/javascripts/fixtures/badges_fixture.js.es6 @@ -1,6 +1,6 @@ /*jshint maxlen:10000000 */ export default { -"/badges.json": {"badge_types":[{"id":2,"name":"Silver"},{"id":3,"name":"Bronze"},{"id":1,"name":"Gold"}],"badge_groupings":[{"id":8,"name":"Development","description":null,"position":5},{"id":4,"name":"Trust Level","description":null,"position":3},{"id":7,"name":"Testing","description":null,"position":4},{"id":1,"name":"Getting Started","description":null,"position":0},{"id":3,"name":"Posting","description":null,"position":2},{"id":2,"name":"Community","description":null,"position":1}],"badges":[{"id":108,"name":"Great contributor","description":"contributed 25 accepted pull request","grant_count":11,"allow_title":true,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":8,"system":false,"badge_type_id":2},{"id":118,"name":"Plugin Author","description":"Developed a plugin for Discourse ","grant_count":10,"allow_title":true,"multiple_grant":false,"icon":"fa-cog","listable":true,"enabled":true,"badge_grouping_id":8,"system":false,"badge_type_id":2},{"id":3,"name":"Leader","description":null,"grant_count":29,"allow_title":true,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":2},{"id":107,"name":"Contributor","description":"contributed an accepted pull request","grant_count":200,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":8,"system":false,"badge_type_id":3},{"id":116,"name":"Tester","description":"Reported 10 bugs that were liked by the Discourse team","grant_count":9,"allow_title":true,"multiple_grant":false,"icon":"fa-bug","listable":true,"enabled":true,"badge_grouping_id":7,"system":false,"badge_type_id":2},{"id":109,"name":"Amazing contributor","description":"contributed 250 accepted pull request","grant_count":0,"allow_title":true,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":8,"system":false,"badge_type_id":1},{"id":2,"name":"Regular User","description":null,"grant_count":467,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":3},{"id":114,"name":"Bug Reporter","description":"Reported a bug that was liked by the Discourse team","grant_count":183,"allow_title":false,"multiple_grant":false,"icon":"fa-bug","listable":true,"enabled":true,"badge_grouping_id":7,"system":false,"badge_type_id":3},{"id":4,"name":"Elder","description":null,"grant_count":4,"allow_title":true,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":1},{"id":17,"name":"Reader","description":null,"grant_count":278,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":1,"name":"Basic User","description":null,"grant_count":5834,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":3},{"id":16,"name":"Read Guidelines","description":null,"grant_count":60,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":7,"name":"Good Post","description":null,"grant_count":22,"allow_title":false,"multiple_grant":true,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":3,"system":true,"badge_type_id":2},{"id":8,"name":"Great Post","description":null,"grant_count":2,"allow_title":false,"multiple_grant":true,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":3,"system":true,"badge_type_id":1},{"id":11,"name":"First Like","description":null,"grant_count":2387,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":12,"name":"First Share","description":null,"grant_count":285,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":13,"name":"First Flag","description":null,"grant_count":42,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":2,"system":true,"badge_type_id":3},{"id":5,"name":"Welcome","description":null,"grant_count":1718,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":2,"system":true,"badge_type_id":3},{"id":15,"name":"First Quote","description":null,"grant_count":270,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":9,"name":"Autobiographer","description":null,"grant_count":545,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":14,"name":"First Link","description":null,"grant_count":397,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":6,"name":"Nice Post","description":null,"grant_count":259,"allow_title":false,"multiple_grant":true,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":3,"system":true,"badge_type_id":3},{"id":10,"name":"Editor","description":null,"grant_count":933,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":2,"system":true,"badge_type_id":3}]}, +"/badges.json": {"badge_types":[{"id":2,"name":"Silver"},{"id":3,"name":"Bronze"},{"id":1,"name":"Gold"}],"badge_groupings":[{"id":8,"name":"Development","description":null,"position":5},{"id":4,"name":"Trust Level","description":null,"position":3},{"id":7,"name":"Testing","description":null,"position":4},{"id":1,"name":"Getting Started","description":null,"position":0},{"id":3,"name":"Posting","description":null,"position":2},{"id":2,"name":"Community","description":null,"position":1}],"badges":[{"id":108,"name":"Great contributor","description":"contributed 25 accepted pull request","grant_count":11,"allow_title":true,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":8,"system":false,"badge_type_id":2},{"id":118,"name":"Plugin Author","description":"Developed a plugin for Discourse ","grant_count":10,"allow_title":true,"multiple_grant":false,"icon":"fa-cog","listable":true,"enabled":true,"badge_grouping_id":8,"system":false,"badge_type_id":2},{"id":3,"name":"Leader","description":null,"grant_count":29,"allow_title":true,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":2},{"id":107,"name":"Contributor","description":"contributed an accepted pull request","grant_count":200,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":8,"system":false,"badge_type_id":3},{"id":116,"name":"Tester","description":"Reported 10 bugs that were liked by the Discourse team","grant_count":9,"allow_title":true,"multiple_grant":false,"icon":"fa-bug","listable":true,"enabled":true,"badge_grouping_id":7,"system":false,"badge_type_id":2},{"id":109,"name":"Amazing contributor","description":"contributed 250 accepted pull request","grant_count":0,"allow_title":true,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":8,"system":false,"badge_type_id":1},{"id":2,"name":"Regular User","description":null,"grant_count":467,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":3},{"id":114,"name":"Bug Reporter","description":"Reported a bug that was liked by the Discourse team","grant_count":183,"allow_title":false,"multiple_grant":false,"icon":"fa-bug","listable":true,"enabled":true,"badge_grouping_id":7,"system":false,"badge_type_id":3},{"id":4,"name":"Elder","description":null,"grant_count":4,"allow_title":true,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":1},{"id":17,"name":"Reader","description":null,"grant_count":278,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":1,"name":"Basic User","description":null,"grant_count":5834,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":3},{"id":16,"name":"Read Guidelines","description":null,"grant_count":60,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":7,"name":"Good Post","description":null,"grant_count":22,"allow_title":false,"multiple_grant":true,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":3,"system":true,"badge_type_id":2},{"id":8,"name":"Great Post","description":null,"grant_count":2,"allow_title":false,"multiple_grant":true,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":3,"system":true,"badge_type_id":1},{"id":11,"name":"First Like","description":null,"grant_count":2387,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":12,"name":"First Share","description":null,"grant_count":285,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":13,"name":"First Flag","description":null,"grant_count":42,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":2,"system":true,"badge_type_id":3},{"id":5,"name":"Welcome","description":null,"grant_count":1718,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":2,"system":true,"badge_type_id":3},{"id":15,"name":"First Quote","description":null,"grant_count":270,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":9,"name":"Autobiographer","description":null,"grant_count":545,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":14,"name":"First Link","description":null,"grant_count":397,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3},{"id":6,"name":"Nice Post","description":null,"grant_count":259,"allow_title":false,"multiple_grant":true,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":3,"system":true,"badge_type_id":3},{"id":10,"name":"Editor","description":null,"grant_count":933,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":2,"system":true,"badge_type_id":3}]}, "/badges/9": {"badge_types":[{"id":3,"name":"Bronze"}],"badge":{"id":9,"name":"Autobiographer","description":null,"grant_count":545,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3}}, "/user_badges.json": {"badges":[{"id":9,"name":"Autobiographer","description":null,"grant_count":545,"allow_title":false,"multiple_grant":false,"icon":"fa-certificate","listable":true,"enabled":true,"badge_grouping_id":1,"system":true,"badge_type_id":3}],"badge_types":[{"id":3,"name":"Bronze"}],"users":[{"id":11209,"username":"icaroperseo","uploaded_avatar_id":33076,"avatar_template":"/user_avatar/meta.discourse.org/icaroperseo/{size}/33076.png"},{"id":-1,"username":"system","uploaded_avatar_id":5241,"avatar_template":"/user_avatar/meta.discourse.org/system/{size}/5241.png"},{"id":11234,"username":"allard","uploaded_avatar_id":33117,"avatar_template":"/user_avatar/meta.discourse.org/allard/{size}/33117.png"},{"id":8944,"username":"hunterboerner","uploaded_avatar_id":33072,"avatar_template":"/user_avatar/meta.discourse.org/hunterboerner/{size}/33072.png"},{"id":11232,"username":"daydreamer","uploaded_avatar_id":33101,"avatar_template":"/user_avatar/meta.discourse.org/daydreamer/{size}/33101.png"},{"id":11160,"username":"boomzilla","uploaded_avatar_id":33029,"avatar_template":"/user_avatar/meta.discourse.org/boomzilla/{size}/33029.png"},{"id":5303,"username":"ybart","uploaded_avatar_id":14132,"avatar_template":"/user_avatar/meta.discourse.org/ybart/{size}/14132.png"},{"id":11142,"username":"Fluffy","uploaded_avatar_id":32957,"avatar_template":"/user_avatar/meta.discourse.org/fluffy/{size}/32957.png"},{"id":8843,"username":"timoroso","uploaded_avatar_id":19114,"avatar_template":"/user_avatar/meta.discourse.org/timoroso/{size}/19114.png"},{"id":10990,"username":"Nagesh","uploaded_avatar_id":32736,"avatar_template":"/user_avatar/meta.discourse.org/nagesh/{size}/32736.png"},{"id":11027,"username":"dullroar","uploaded_avatar_id":32801,"avatar_template":"/user_avatar/meta.discourse.org/dullroar/{size}/32801.png"},{"id":10481,"username":"Air_Cooled_Nut","uploaded_avatar_id":31833,"avatar_template":"/user_avatar/meta.discourse.org/air_cooled_nut/{size}/31833.png"},{"id":10977,"username":"stevebridger","uploaded_avatar_id":32705,"avatar_template":"/user_avatar/meta.discourse.org/stevebridger/{size}/32705.png"},{"id":10921,"username":"lnikkila","uploaded_avatar_id":32627,"avatar_template":"/user_avatar/meta.discourse.org/lnikkila/{size}/32627.png"},{"id":8493,"username":"PJH","uploaded_avatar_id":33082,"avatar_template":"/user_avatar/meta.discourse.org/pjh/{size}/33082.png"},{"id":10635,"username":"Ganzuelo","uploaded_avatar_id":32217,"avatar_template":"/user_avatar/meta.discourse.org/ganzuelo/{size}/32217.png"},{"id":8300,"username":"cpradio","uploaded_avatar_id":4970,"avatar_template":"/user_avatar/meta.discourse.org/cpradio/{size}/4970.png"},{"id":8571,"username":"tobiaseigen","uploaded_avatar_id":9785,"avatar_template":"/user_avatar/meta.discourse.org/tobiaseigen/{size}/9785.png"},{"id":4263,"username":"mcwumbly","uploaded_avatar_id":9796,"avatar_template":"/user_avatar/meta.discourse.org/mcwumbly/{size}/9796.png"},{"id":471,"username":"BhaelOchon","uploaded_avatar_id":6069,"avatar_template":"/user_avatar/meta.discourse.org/bhaelochon/{size}/6069.png"},{"id":5249,"username":"cawas","uploaded_avatar_id":14043,"avatar_template":"/user_avatar/meta.discourse.org/cawas/{size}/14043.png"},{"id":5461,"username":"thepractice","uploaded_avatar_id":2397,"avatar_template":"/user_avatar/meta.discourse.org/thepractice/{size}/2397.png"},{"id":10467,"username":"chris18890","uploaded_avatar_id":31806,"avatar_template":"/user_avatar/meta.discourse.org/chris18890/{size}/31806.png"},{"id":375,"username":"weirdcanada","uploaded_avatar_id":5902,"avatar_template":"/user_avatar/meta.discourse.org/weirdcanada/{size}/5902.png"},{"id":8617,"username":"Mittineague","uploaded_avatar_id":4462,"avatar_template":"/user_avatar/meta.discourse.org/mittineague/{size}/4462.png"},{"id":5962,"username":"TheMarkus","uploaded_avatar_id":15186,"avatar_template":"/user_avatar/meta.discourse.org/themarkus/{size}/15186.png"},{"id":2806,"username":"fayimora","uploaded_avatar_id":10007,"avatar_template":"/user_avatar/meta.discourse.org/fayimora/{size}/10007.png"},{"id":8364,"username":"codetricity","uploaded_avatar_id":3773,"avatar_template":"/user_avatar/meta.discourse.org/codetricity/{size}/3773.png"},{"id":3752,"username":"liberatiluca","uploaded_avatar_id":11568,"avatar_template":"/user_avatar/meta.discourse.org/liberatiluca/{size}/11568.png"},{"id":3483,"username":"Packetknife","uploaded_avatar_id":11144,"avatar_template":"/user_avatar/meta.discourse.org/packetknife/{size}/11144.png"},{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"},{"id":19,"username":"eviltrout","uploaded_avatar_id":5275,"avatar_template":"/user_avatar/meta.discourse.org/eviltrout/{size}/5275.png"},{"id":7229,"username":"DavidGNavas","uploaded_avatar_id":17081,"avatar_template":"/user_avatar/meta.discourse.org/davidgnavas/{size}/17081.png"},{"id":1219,"username":"Gweebz","uploaded_avatar_id":7304,"avatar_template":"/user_avatar/meta.discourse.org/gweebz/{size}/7304.png"},{"id":7743,"username":"ZeroFlux","uploaded_avatar_id":2256,"avatar_template":"/user_avatar/meta.discourse.org/zeroflux/{size}/2256.png"},{"id":8510,"username":"tannerfilip","uploaded_avatar_id":18674,"avatar_template":"/user_avatar/meta.discourse.org/tannerfilip/{size}/18674.png"},{"id":1496,"username":"cfstras","uploaded_avatar_id":7776,"avatar_template":"/user_avatar/meta.discourse.org/cfstras/{size}/7776.png"},{"id":3986,"username":"creativetech","uploaded_avatar_id":11955,"avatar_template":"/user_avatar/meta.discourse.org/creativetech/{size}/11955.png"},{"id":3800,"username":"stealthii","uploaded_avatar_id":11645,"avatar_template":"/user_avatar/meta.discourse.org/stealthii/{size}/11645.png"},{"id":6613,"username":"haiku","uploaded_avatar_id":9781,"avatar_template":"/user_avatar/meta.discourse.org/haiku/{size}/9781.png"},{"id":5351,"username":"erlend_sh","uploaded_avatar_id":9794,"avatar_template":"/user_avatar/meta.discourse.org/erlend_sh/{size}/9794.png"},{"id":5983,"username":"JohnSReid","uploaded_avatar_id":32238,"avatar_template":"/user_avatar/meta.discourse.org/johnsreid/{size}/32238.png"},{"id":701,"username":"johncoder","uploaded_avatar_id":6447,"avatar_template":"/user_avatar/meta.discourse.org/johncoder/{size}/6447.png"},{"id":5707,"username":"trident","uploaded_avatar_id":31178,"avatar_template":"/user_avatar/meta.discourse.org/trident/{size}/31178.png"},{"id":255,"username":"uwe_keim","uploaded_avatar_id":5697,"avatar_template":"/user_avatar/meta.discourse.org/uwe_keim/{size}/5697.png"},{"id":9931,"username":"Frank","uploaded_avatar_id":32861,"avatar_template":"/user_avatar/meta.discourse.org/frank/{size}/32861.png"},{"id":5543,"username":"trevor","uploaded_avatar_id":14507,"avatar_template":"/user_avatar/meta.discourse.org/trevor/{size}/14507.png"},{"id":3987,"username":"Sander78","uploaded_avatar_id":9787,"avatar_template":"/user_avatar/meta.discourse.org/sander78/{size}/9787.png"},{"id":7850,"username":"tudorv","uploaded_avatar_id":2568,"avatar_template":"/user_avatar/meta.discourse.org/tudorv/{size}/2568.png"},{"id":6653,"username":"amitfrid","uploaded_avatar_id":16262,"avatar_template":"/user_avatar/meta.discourse.org/amitfrid/{size}/16262.png"},{"id":4419,"username":"sasivarnakumar","uploaded_avatar_id":12661,"avatar_template":"/user_avatar/meta.discourse.org/sasivarnakumar/{size}/12661.png"},{"id":5710,"username":"elvanja","uploaded_avatar_id":14781,"avatar_template":"/user_avatar/meta.discourse.org/elvanja/{size}/14781.png"},{"id":5401,"username":"nilaykumar","uploaded_avatar_id":14275,"avatar_template":"/user_avatar/meta.discourse.org/nilaykumar/{size}/14275.png"},{"id":6809,"username":"buster","uploaded_avatar_id":31175,"avatar_template":"/user_avatar/meta.discourse.org/buster/{size}/31175.png"},{"id":169,"username":"blowmage","uploaded_avatar_id":5545,"avatar_template":"/user_avatar/meta.discourse.org/blowmage/{size}/5545.png"},{"id":766,"username":"dworthley","uploaded_avatar_id":6561,"avatar_template":"/user_avatar/meta.discourse.org/dworthley/{size}/6561.png"},{"id":1612,"username":"trottier","uploaded_avatar_id":7977,"avatar_template":"/user_avatar/meta.discourse.org/trottier/{size}/7977.png"},{"id":6019,"username":"mandie","uploaded_avatar_id":15273,"avatar_template":"/user_avatar/meta.discourse.org/mandie/{size}/15273.png"},{"id":3724,"username":"Manikin75","uploaded_avatar_id":11520,"avatar_template":"/user_avatar/meta.discourse.org/manikin75/{size}/11520.png"},{"id":1556,"username":"OfferKaye","uploaded_avatar_id":7878,"avatar_template":"/user_avatar/meta.discourse.org/offerkaye/{size}/7878.png"},{"id":4063,"username":"blanco","uploaded_avatar_id":12082,"avatar_template":"/user_avatar/meta.discourse.org/blanco/{size}/12082.png"},{"id":1621,"username":"bnb","uploaded_avatar_id":7992,"avatar_template":"/user_avatar/meta.discourse.org/bnb/{size}/7992.png"},{"id":3095,"username":"ayush","uploaded_avatar_id":10504,"avatar_template":"/user_avatar/meta.discourse.org/ayush/{size}/10504.png"},{"id":754,"username":"danneu","uploaded_avatar_id":6540,"avatar_template":"/user_avatar/meta.discourse.org/danneu/{size}/6540.png"},{"id":6548,"username":"michaeld","uploaded_avatar_id":1594,"avatar_template":"/user_avatar/meta.discourse.org/michaeld/{size}/1594.png"},{"id":4457,"username":"Lee_Ars","uploaded_avatar_id":1597,"avatar_template":"/user_avatar/meta.discourse.org/lee_ars/{size}/1597.png"},{"id":5160,"username":"eriko","uploaded_avatar_id":1915,"avatar_template":"/user_avatar/meta.discourse.org/eriko/{size}/1915.png"},{"id":10150,"username":"ampburner","uploaded_avatar_id":5103,"avatar_template":"/user_avatar/meta.discourse.org/ampburner/{size}/5103.png"},{"id":1,"username":"sam","uploaded_avatar_id":5243,"avatar_template":"/user_avatar/meta.discourse.org/sam/{size}/5243.png"},{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png"},{"id":9536,"username":"nahtnam","uploaded_avatar_id":20077,"avatar_template":"/user_avatar/meta.discourse.org/nahtnam/{size}/20077.png"},{"id":5559,"username":"downey","uploaded_avatar_id":14532,"avatar_template":"/user_avatar/meta.discourse.org/downey/{size}/14532.png"},{"id":6626,"username":"riking","uploaded_avatar_id":9779,"avatar_template":"/user_avatar/meta.discourse.org/riking/{size}/9779.png"},{"id":562,"username":"nightpool","uploaded_avatar_id":6220,"avatar_template":"/user_avatar/meta.discourse.org/nightpool/{size}/6220.png"},{"id":2770,"username":"awesomerobot","uploaded_avatar_id":32393,"avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/32393.png"},{"id":4385,"username":"jeans","uploaded_avatar_id":12606,"avatar_template":"/user_avatar/meta.discourse.org/jeans/{size}/12606.png"},{"id":8222,"username":"techAPJ","uploaded_avatar_id":3281,"avatar_template":"/user_avatar/meta.discourse.org/techapj/{size}/3281.png"},{"id":1274,"username":"binaryphile","uploaded_avatar_id":7399,"avatar_template":"/user_avatar/meta.discourse.org/binaryphile/{size}/7399.png"},{"id":15,"username":"Hanzo","uploaded_avatar_id":5267,"avatar_template":"/user_avatar/meta.discourse.org/hanzo/{size}/5267.png"},{"id":5199,"username":"sefier","uploaded_avatar_id":31207,"avatar_template":"/user_avatar/meta.discourse.org/sefier/{size}/31207.png"},{"id":2316,"username":"pakl","uploaded_avatar_id":9157,"avatar_template":"/user_avatar/meta.discourse.org/pakl/{size}/9157.png"},{"id":393,"username":"freney","uploaded_avatar_id":5932,"avatar_template":"/user_avatar/meta.discourse.org/freney/{size}/5932.png"},{"id":8492,"username":"Onaldan","uploaded_avatar_id":18651,"avatar_template":"/user_avatar/meta.discourse.org/onaldan/{size}/18651.png"},{"id":5002,"username":"jakeberger","uploaded_avatar_id":13630,"avatar_template":"/user_avatar/meta.discourse.org/jakeberger/{size}/13630.png"},{"id":2544,"username":"davideyre","uploaded_avatar_id":9543,"avatar_template":"/user_avatar/meta.discourse.org/davideyre/{size}/9543.png"},{"id":8342,"username":"sethuv","uploaded_avatar_id":3036,"avatar_template":"/user_avatar/meta.discourse.org/sethuv/{size}/3036.png"},{"id":1128,"username":"Tigraine","uploaded_avatar_id":7152,"avatar_template":"/user_avatar/meta.discourse.org/tigraine/{size}/7152.png"},{"id":2477,"username":"billybonks","uploaded_avatar_id":9430,"avatar_template":"/user_avatar/meta.discourse.org/billybonks/{size}/9430.png"},{"id":4549,"username":"davidcelis","uploaded_avatar_id":12882,"avatar_template":"/user_avatar/meta.discourse.org/davidcelis/{size}/12882.png"},{"id":7264,"username":"etrowbridge","uploaded_avatar_id":31199,"avatar_template":"/user_avatar/meta.discourse.org/etrowbridge/{size}/31199.png"},{"id":413,"username":"adam_baldwin","uploaded_avatar_id":5962,"avatar_template":"/user_avatar/meta.discourse.org/adam_baldwin/{size}/5962.png"},{"id":8658,"username":"Datachick","uploaded_avatar_id":18865,"avatar_template":"/user_avatar/meta.discourse.org/datachick/{size}/18865.png"},{"id":5294,"username":"madbomber","uploaded_avatar_id":14118,"avatar_template":"/user_avatar/meta.discourse.org/madbomber/{size}/14118.png"},{"id":4750,"username":"dainbinder","uploaded_avatar_id":13220,"avatar_template":"/user_avatar/meta.discourse.org/dainbinder/{size}/13220.png"},{"id":2735,"username":"royce_williams","uploaded_avatar_id":9887,"avatar_template":"/user_avatar/meta.discourse.org/royce_williams/{size}/9887.png"},{"id":9089,"username":"Keezer","uploaded_avatar_id":31186,"avatar_template":"/user_avatar/meta.discourse.org/keezer/{size}/31186.png"}],"user_badges":[{"id":39085,"granted_at":"2014-07-30T20:06:09.461-04:00","badge_id":9,"user_id":11209,"granted_by_id":-1},{"id":39035,"granted_at":"2014-07-29T15:26:57.028-04:00","badge_id":9,"user_id":11234,"granted_by_id":-1},{"id":39034,"granted_at":"2014-07-29T14:28:43.359-04:00","badge_id":9,"user_id":8944,"granted_by_id":-1},{"id":39027,"granted_at":"2014-07-29T13:14:40.612-04:00","badge_id":9,"user_id":11232,"granted_by_id":-1},{"id":38874,"granted_at":"2014-07-25T14:39:57.034-04:00","badge_id":9,"user_id":11160,"granted_by_id":-1},{"id":38866,"granted_at":"2014-07-25T05:10:33.585-04:00","badge_id":9,"user_id":5303,"granted_by_id":-1},{"id":38838,"granted_at":"2014-07-24T11:57:21.389-04:00","badge_id":9,"user_id":11142,"granted_by_id":-1},{"id":37659,"granted_at":"2014-07-22T03:11:21.336-04:00","badge_id":9,"user_id":8843,"granted_by_id":-1},{"id":37611,"granted_at":"2014-07-21T13:02:19.724-04:00","badge_id":9,"user_id":10990,"granted_by_id":-1},{"id":37537,"granted_at":"2014-07-19T13:56:59.699-04:00","badge_id":9,"user_id":11027,"granted_by_id":-1},{"id":37497,"granted_at":"2014-07-18T10:03:45.294-04:00","badge_id":9,"user_id":10481,"granted_by_id":-1},{"id":37217,"granted_at":"2014-07-15T15:29:45.464-04:00","badge_id":9,"user_id":10977,"granted_by_id":-1},{"id":36865,"granted_at":"2014-07-12T08:45:09.386-04:00","badge_id":9,"user_id":10921,"granted_by_id":-1},{"id":36126,"granted_at":"2014-07-09T08:02:43.143-04:00","badge_id":9,"user_id":8493,"granted_by_id":-1},{"id":32551,"granted_at":"2014-07-06T00:07:44.455-04:00","badge_id":9,"user_id":10635,"granted_by_id":-1},{"id":32550,"granted_at":"2014-07-05T17:45:16.661-04:00","badge_id":9,"user_id":8300,"granted_by_id":-1},{"id":15327,"granted_at":"2014-07-04T16:03:28.852-04:00","badge_id":9,"user_id":8571,"granted_by_id":-1},{"id":7787,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":4263,"granted_by_id":-1},{"id":7786,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":471,"granted_by_id":-1},{"id":7785,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5249,"granted_by_id":-1},{"id":7784,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5461,"granted_by_id":-1},{"id":7783,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":10467,"granted_by_id":-1},{"id":7782,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":375,"granted_by_id":-1},{"id":7781,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":8617,"granted_by_id":-1},{"id":7780,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5962,"granted_by_id":-1},{"id":7779,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":2806,"granted_by_id":-1},{"id":7778,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":8364,"granted_by_id":-1},{"id":7777,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":3752,"granted_by_id":-1},{"id":7776,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":3483,"granted_by_id":-1},{"id":7775,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":32,"granted_by_id":-1},{"id":7774,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":19,"granted_by_id":-1},{"id":7773,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":7229,"granted_by_id":-1},{"id":7772,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":1219,"granted_by_id":-1},{"id":7771,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":7743,"granted_by_id":-1},{"id":7770,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":8510,"granted_by_id":-1},{"id":7769,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":1496,"granted_by_id":-1},{"id":7768,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":3986,"granted_by_id":-1},{"id":7767,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":3800,"granted_by_id":-1},{"id":7766,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":6613,"granted_by_id":-1},{"id":7765,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5351,"granted_by_id":-1},{"id":7764,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5983,"granted_by_id":-1},{"id":7763,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":701,"granted_by_id":-1},{"id":7762,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5707,"granted_by_id":-1},{"id":7761,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":255,"granted_by_id":-1},{"id":7760,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":9931,"granted_by_id":-1},{"id":7759,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":-1,"granted_by_id":-1},{"id":7758,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5543,"granted_by_id":-1},{"id":7757,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":3987,"granted_by_id":-1},{"id":7756,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":7850,"granted_by_id":-1},{"id":7755,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":6653,"granted_by_id":-1},{"id":7754,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":4419,"granted_by_id":-1},{"id":7753,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5710,"granted_by_id":-1},{"id":7752,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5401,"granted_by_id":-1},{"id":7751,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":6809,"granted_by_id":-1},{"id":7750,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":169,"granted_by_id":-1},{"id":7749,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":766,"granted_by_id":-1},{"id":7748,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":1612,"granted_by_id":-1},{"id":7747,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":6019,"granted_by_id":-1},{"id":7746,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":3724,"granted_by_id":-1},{"id":7745,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":1556,"granted_by_id":-1},{"id":7744,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":4063,"granted_by_id":-1},{"id":7743,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":1621,"granted_by_id":-1},{"id":7742,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":3095,"granted_by_id":-1},{"id":7741,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":754,"granted_by_id":-1},{"id":7740,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":6548,"granted_by_id":-1},{"id":7739,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":4457,"granted_by_id":-1},{"id":7738,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5160,"granted_by_id":-1},{"id":7737,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":10150,"granted_by_id":-1},{"id":7736,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":1,"granted_by_id":-1},{"id":7735,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":1995,"granted_by_id":-1},{"id":7734,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":9536,"granted_by_id":-1},{"id":7733,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5559,"granted_by_id":-1},{"id":7732,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":6626,"granted_by_id":-1},{"id":7731,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":562,"granted_by_id":-1},{"id":7730,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":2770,"granted_by_id":-1},{"id":7729,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":4385,"granted_by_id":-1},{"id":7728,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":8222,"granted_by_id":-1},{"id":7727,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":1274,"granted_by_id":-1},{"id":7726,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":15,"granted_by_id":-1},{"id":7725,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5199,"granted_by_id":-1},{"id":7724,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":2316,"granted_by_id":-1},{"id":7723,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":393,"granted_by_id":-1},{"id":7722,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":8492,"granted_by_id":-1},{"id":7721,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5002,"granted_by_id":-1},{"id":7720,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":2544,"granted_by_id":-1},{"id":7719,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":8342,"granted_by_id":-1},{"id":7718,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":1128,"granted_by_id":-1},{"id":7717,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":2477,"granted_by_id":-1},{"id":7716,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":4549,"granted_by_id":-1},{"id":7715,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":7264,"granted_by_id":-1},{"id":7714,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":413,"granted_by_id":-1},{"id":7713,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":8658,"granted_by_id":-1},{"id":7712,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":5294,"granted_by_id":-1},{"id":7711,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":4750,"granted_by_id":-1},{"id":7710,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":2735,"granted_by_id":-1},{"id":7709,"granted_at":"2014-07-03T06:36:46.939-04:00","badge_id":9,"user_id":9089,"granted_by_id":-1}]} }; diff --git a/test/javascripts/fixtures/group-fixtures.js.es6 b/test/javascripts/fixtures/group-fixtures.js.es6 index 03382b9a749..706eef76905 100644 --- a/test/javascripts/fixtures/group-fixtures.js.es6 +++ b/test/javascripts/fixtures/group-fixtures.js.es6 @@ -1,6 +1,6 @@ export default { "/groups/discourse.json": {"basic_group":{"id":47,"automatic":false,"name":"discourse","user_count":8,"alias_level":0,"visible":true}}, "/groups/discourse/counts.json": {"counts":{"posts":17829,"members":7}}, - "/groups/discourse/members.json": {"members":[{"id":2770,"username":"awesomerobot","uploaded_avatar_id":33872,"avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png","name":"","last_seen_at":"2015-01-23T15:53:17.844Z"},{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png","name":"Jeff Atwood","last_seen_at":"2015-01-23T06:05:25.457Z"},{"id":19,"username":"eviltrout","uploaded_avatar_id":5275,"avatar_template":"/user_avatar/meta.discourse.org/eviltrout/{size}/5275.png","name":"Robin Ward","last_seen_at":"2015-01-23T16:03:45.098Z"},{"id":2,"username":"neil","uploaded_avatar_id":5245,"avatar_template":"/user_avatar/meta.discourse.org/neil/{size}/5245.png","name":"Neil Lalonde","last_seen_at":"2015-01-23T15:22:10.244Z"},{"id":1,"username":"sam","uploaded_avatar_id":5243,"avatar_template":"/user_avatar/meta.discourse.org/sam/{size}/5243.png","name":"Sam Saffron","last_seen_at":"2015-01-23T11:07:06.233Z"},{"id":3,"username":"supermathie","uploaded_avatar_id":34097,"avatar_template":"/user_avatar/meta.discourse.org/supermathie/{size}/34097.png","name":"Michael Brown","last_seen_at":"2015-01-22T05:16:42.254Z"},{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png","name":"Régis Hanol","last_seen_at":"2015-01-23T15:45:34.196Z"}],"meta":{"total":7,"limit":50,"offset":0}}, - "/groups/discourse/posts.json": [{"id":94607,"cooked":"

    Right now we have two entirely different styles for new topics and new posts within a topic... we can probably fix that pretty easily.

    \n\n

    \n\n

    So the simple change would be:

    \n\n

    \n\n

    but... while the dot makes the \"• new\" stand out more... it doesn't communicate any information other than \"look at me\" — can we add more context without adding more noise?

    \n\n

    ","created_at":"2015-01-23T15:13:01.935Z","title":"Consistent new indicator","url":"/t/consistent-new-indicator/24355/1","user_title":"designerator","user_long_name":"","category":{"id":9,"name":"ux","color":"5F497A","topic_id":2628,"topic_count":540,"created_at":"2013-02-10T03:52:21.322Z","updated_at":"2015-01-22T18:05:32.152Z","user_id":32,"topics_year":370,"topics_month":33,"topics_week":3,"slug":"ux","description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":5823,"latest_post_id":94610,"latest_topic_id":24355,"position":25,"parent_category_id":null,"posts_year":4264,"posts_month":609,"posts_week":103,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":28,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"ux","auto_close_based_on_last_post":false},"user":{"id":2770,"username":"awesomerobot","uploaded_avatar_id":33872,"avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png"}},{"id":94603,"cooked":"

    Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.

    ","created_at":"2015-01-23T14:59:21.941Z","title":"The end of Clown Vomit, or, simplified category styles","url":"/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/63","user_title":"designerator","user_long_name":"","category":{"id":9,"name":"ux","color":"5F497A","topic_id":2628,"topic_count":540,"created_at":"2013-02-10T03:52:21.322Z","updated_at":"2015-01-22T18:05:32.152Z","user_id":32,"topics_year":370,"topics_month":33,"topics_week":3,"slug":"ux","description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":5823,"latest_post_id":94610,"latest_topic_id":24355,"position":25,"parent_category_id":null,"posts_year":4264,"posts_month":609,"posts_week":103,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":28,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"ux","auto_close_based_on_last_post":false},"user":{"id":2770,"username":"awesomerobot","uploaded_avatar_id":33872,"avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png"}},{"id":94601,"cooked":"

    Yeah I think this category arrangement is the way to go at the very least - much easier to scan two columns...

    \n\n

    Also, maybe square off the bars?

    \n\n

    \n\n

    ","created_at":"2015-01-23T14:51:55.497Z","title":"The end of Clown Vomit, or, simplified category styles","url":"/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/62","user_title":"designerator","user_long_name":"","category":{"id":9,"name":"ux","color":"5F497A","topic_id":2628,"topic_count":540,"created_at":"2013-02-10T03:52:21.322Z","updated_at":"2015-01-22T18:05:32.152Z","user_id":32,"topics_year":370,"topics_month":33,"topics_week":3,"slug":"ux","description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":5823,"latest_post_id":94610,"latest_topic_id":24355,"position":25,"parent_category_id":null,"posts_year":4264,"posts_month":609,"posts_week":103,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":28,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"ux","auto_close_based_on_last_post":false},"user":{"id":2770,"username":"awesomerobot","uploaded_avatar_id":33872,"avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png"}},{"id":94577,"cooked":"

    Yup, that's the latest version \"wink\"

    \n\n

    \n\n

    (click to view animated version)

    ","created_at":"2015-01-23T10:50:55.846Z","title":"Quote reply insertion at cursor position","url":"/t/quote-reply-insertion-at-cursor-position/24344/4","user_title":"team","user_long_name":"Régis Hanol","category":{"id":2,"name":"feature","color":"0E76BD","topic_id":11,"topic_count":1592,"created_at":"2013-02-02T21:42:52.552Z","updated_at":"2015-01-22T18:05:32.647Z","user_id":1,"topics_year":919,"topics_month":60,"topics_week":20,"slug":"feature","description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":14360,"latest_post_id":94600,"latest_topic_id":24344,"position":25,"parent_category_id":null,"posts_year":8617,"posts_month":690,"posts_week":190,"email_in":null,"email_in_allow_strangers":false,"topics_day":2,"posts_day":8,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"feature","auto_close_based_on_last_post":false},"user":{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png"}},{"id":94574,"cooked":"\n\n

    It used to be that but that was fixed a while ago. Are you running a recent version?

    ","created_at":"2015-01-23T10:31:29.222Z","title":"Quote reply insertion at cursor position","url":"/t/quote-reply-insertion-at-cursor-position/24344/2","user_title":"team","user_long_name":"Régis Hanol","category":{"id":2,"name":"feature","color":"0E76BD","topic_id":11,"topic_count":1592,"created_at":"2013-02-02T21:42:52.552Z","updated_at":"2015-01-22T18:05:32.647Z","user_id":1,"topics_year":919,"topics_month":60,"topics_week":20,"slug":"feature","description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":14360,"latest_post_id":94600,"latest_topic_id":24344,"position":25,"parent_category_id":null,"posts_year":8617,"posts_month":690,"posts_week":190,"email_in":null,"email_in_allow_strangers":false,"topics_day":2,"posts_day":8,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"feature","auto_close_based_on_last_post":false},"user":{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png"}},{"id":94572,"cooked":"\n\n

    That's an Ember update that introduced this change.

    ","created_at":"2015-01-23T09:46:00.901Z","title":"Translations frequently broken","url":"/t/translations-frequently-broken/22546/27","user_title":"team","user_long_name":"Régis Hanol","category":{"id":27,"name":"translations","color":"808281","topic_id":14549,"topic_count":146,"created_at":"2014-04-07T20:30:17.623Z","updated_at":"2015-01-22T18:05:33.111Z","user_id":2,"topics_year":134,"topics_month":5,"topics_week":3,"slug":"translations","description":"This category is for discussion about localizing Discourse.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":1167,"latest_post_id":94575,"latest_topic_id":24301,"position":25,"parent_category_id":7,"posts_year":965,"posts_month":60,"posts_week":29,"email_in":null,"email_in_allow_strangers":false,"topics_day":1,"posts_day":5,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"translations","auto_close_based_on_last_post":false},"user":{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png"}},{"id":94555,"cooked":"

    I don't know how to pronounce that in English, but this makes me think of the French word \"disquette\" (floppy disk) \"smile\"

    ","created_at":"2015-01-23T08:17:31.700Z","title":"Introducing Discette - a minimal ember-cli front end to Discourse","url":"/t/introducing-discette-a-minimal-ember-cli-front-end-to-discourse/24321/3","user_title":"team","user_long_name":"Régis Hanol","category":{"id":7,"name":"dev","color":"000","topic_id":1026,"topic_count":574,"created_at":"2013-02-06T08:43:41.550Z","updated_at":"2015-01-22T18:05:32.855Z","user_id":32,"topics_year":298,"topics_month":29,"topics_week":2,"slug":"dev","description":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":4196,"latest_post_id":94590,"latest_topic_id":24349,"position":25,"parent_category_id":null,"posts_year":2095,"posts_month":172,"posts_week":16,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":3,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"dev","auto_close_based_on_last_post":false},"user":{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png"}},{"id":94544,"cooked":"

    @techapj fixed this for 1.2.

    ","created_at":"2015-01-23T05:49:35.881Z","title":"After sign-in, I'm not redirected to the conversation","url":"/t/after-sign-in-im-not-redirected-to-the-conversation/17753/8","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":9,"name":"ux","color":"5F497A","topic_id":2628,"topic_count":540,"created_at":"2013-02-10T03:52:21.322Z","updated_at":"2015-01-22T18:05:32.152Z","user_id":32,"topics_year":370,"topics_month":33,"topics_week":3,"slug":"ux","description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":5823,"latest_post_id":94610,"latest_topic_id":24355,"position":25,"parent_category_id":null,"posts_year":4264,"posts_month":609,"posts_week":103,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":28,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"ux","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94543,"cooked":"

    Oh yes IOS 8.2 -- well, let's see what happens because there is really no fix on our end. Basic HTML / CSS stuff is broken.

    ","created_at":"2015-01-23T05:45:40.306Z","title":"Dealing with iOS 8 Mobile Safari bugs?","url":"/t/dealing-with-ios-8-mobile-safari-bugs/24101/7","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":2,"name":"feature","color":"0E76BD","topic_id":11,"topic_count":1592,"created_at":"2013-02-02T21:42:52.552Z","updated_at":"2015-01-22T18:05:32.647Z","user_id":1,"topics_year":919,"topics_month":60,"topics_week":20,"slug":"feature","description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":14360,"latest_post_id":94600,"latest_topic_id":24344,"position":25,"parent_category_id":null,"posts_year":8617,"posts_month":690,"posts_week":190,"email_in":null,"email_in_allow_strangers":false,"topics_day":2,"posts_day":8,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"feature","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94542,"cooked":"

    Hmm that looks like a bug, @techapj can you have a look?

    ","created_at":"2015-01-23T05:43:55.602Z","title":"RSS is not valid","url":"/t/rss-is-not-valid/24338/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":6,"name":"support","color":"CEA9A9","topic_id":389,"topic_count":1781,"created_at":"2013-02-05T22:16:38.672Z","updated_at":"2015-01-22T18:05:33.572Z","user_id":1,"topics_year":1541,"topics_month":167,"topics_week":49,"slug":"support","description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":12272,"latest_post_id":94602,"latest_topic_id":24346,"position":25,"parent_category_id":null,"posts_year":10571,"posts_month":1254,"posts_week":413,"email_in":null,"email_in_allow_strangers":false,"topics_day":5,"posts_day":70,"logo_url":"","background_url":"","allow_badges":true,"name_lower":"support","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94522,"cooked":"

    Oh I see. @zogstrip can you have a look?

    ","created_at":"2015-01-23T03:00:20.485Z","title":"Pasted image upload size error","url":"/t/pasted-image-upload-size-error/24320/4","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":1,"name":"bug","color":"e9dd00","topic_id":2,"topic_count":1729,"created_at":"2013-02-01T04:56:34.914Z","updated_at":"2015-01-22T18:05:33.426Z","user_id":1,"topics_year":1114,"topics_month":69,"topics_week":22,"slug":"bug","description":"A bug report means something is broken, preventing normal/typical use of Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","text_color":"000000","read_restricted":false,"auto_close_hours":null,"post_count":11179,"latest_post_id":94611,"latest_topic_id":24350,"position":25,"parent_category_id":null,"posts_year":7138,"posts_month":397,"posts_week":121,"email_in":null,"email_in_allow_strangers":false,"topics_day":1,"posts_day":6,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"bug","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94521,"cooked":"\n\n

    Yeah probably.

    \n\n\n\n

    Definitely a good idea. We have seen some eye melting color schemes people have picked for categories.. Much less subcategories.

    \n\n\n\n

    Sure try http://talk.folksy.com -- it's still too much color in boxes. Particularly anywhere a bunch of categories are displayed together, which is a lot of places considering the topic list is the main form of nav, both on the homepage default of latest and in suggested topics at the bottom of every topic...

    \n\n

    ","created_at":"2015-01-23T02:58:27.451Z","title":"The end of Clown Vomit, or, simplified category styles","url":"/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/57","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":9,"name":"ux","color":"5F497A","topic_id":2628,"topic_count":540,"created_at":"2013-02-10T03:52:21.322Z","updated_at":"2015-01-22T18:05:32.152Z","user_id":32,"topics_year":370,"topics_month":33,"topics_week":3,"slug":"ux","description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":5823,"latest_post_id":94610,"latest_topic_id":24355,"position":25,"parent_category_id":null,"posts_year":4264,"posts_month":609,"posts_week":103,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":28,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"ux","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94519,"cooked":"

    What would you suggest writing here that would be more clear?

    ","created_at":"2015-01-23T02:45:36.859Z","title":"What is \"Born mobile, born to touch\" supposed to tell me?","url":"/t/what-is-born-mobile-born-to-touch-supposed-to-tell-me/24329/3","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":3,"name":"meta","color":"aaa","topic_id":24,"topic_count":139,"created_at":"2013-02-03T00:00:15.230Z","updated_at":"2015-01-22T18:05:32.797Z","user_id":1,"topics_year":68,"topics_month":5,"topics_week":1,"slug":"meta","description":"Discussion about meta.discourse.org itself, the organization of this forum about Discourse, how it works, and how we can improve this site.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":1116,"latest_post_id":94559,"latest_topic_id":24208,"position":25,"parent_category_id":null,"posts_year":553,"posts_month":33,"posts_week":8,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":0,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"meta","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94518,"cooked":"

    You should generally create topics to host things like this, then make them wiki, close them, etc.

    ","created_at":"2015-01-23T02:42:20.053Z","title":"How to Create Static Pages in Discourse?","url":"/t/how-to-create-static-pages-in-discourse/24313/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":6,"name":"support","color":"CEA9A9","topic_id":389,"topic_count":1781,"created_at":"2013-02-05T22:16:38.672Z","updated_at":"2015-01-22T18:05:33.572Z","user_id":1,"topics_year":1541,"topics_month":167,"topics_week":49,"slug":"support","description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":12272,"latest_post_id":94602,"latest_topic_id":24346,"position":25,"parent_category_id":null,"posts_year":10571,"posts_month":1254,"posts_week":413,"email_in":null,"email_in_allow_strangers":false,"topics_day":5,"posts_day":70,"logo_url":"","background_url":"","allow_badges":true,"name_lower":"support","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94517,"cooked":"

    Doubtful this is a bug, probably dependent on the PNG encoding.

    \n\n

    Try using PNGOUT, or converting to 8 bit PNGOUT, to see some of the differences. And PNGOUT is lossless!

    ","created_at":"2015-01-23T02:41:30.287Z","title":"Pasted image upload size error","url":"/t/pasted-image-upload-size-error/24320/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":1,"name":"bug","color":"e9dd00","topic_id":2,"topic_count":1729,"created_at":"2013-02-01T04:56:34.914Z","updated_at":"2015-01-22T18:05:33.426Z","user_id":1,"topics_year":1114,"topics_month":69,"topics_week":22,"slug":"bug","description":"A bug report means something is broken, preventing normal/typical use of Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","text_color":"000000","read_restricted":false,"auto_close_hours":null,"post_count":11179,"latest_post_id":94611,"latest_topic_id":24350,"position":25,"parent_category_id":null,"posts_year":7138,"posts_month":397,"posts_week":121,"email_in":null,"email_in_allow_strangers":false,"topics_day":1,"posts_day":6,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"bug","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94516,"cooked":"

    I would worry about getting your expenses down to $5 per month, that seems more likely over time as hosting for Docker compliant sites gets cheaper.

    ","created_at":"2015-01-23T02:40:11.726Z","title":"Monetizing Discourse Talk","url":"/t/monetizing-discourse-talk/24316/4","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":6,"name":"support","color":"CEA9A9","topic_id":389,"topic_count":1781,"created_at":"2013-02-05T22:16:38.672Z","updated_at":"2015-01-22T18:05:33.572Z","user_id":1,"topics_year":1541,"topics_month":167,"topics_week":49,"slug":"support","description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":12272,"latest_post_id":94602,"latest_topic_id":24346,"position":25,"parent_category_id":null,"posts_year":10571,"posts_month":1254,"posts_week":413,"email_in":null,"email_in_allow_strangers":false,"topics_day":5,"posts_day":70,"logo_url":"","background_url":"","allow_badges":true,"name_lower":"support","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94515,"cooked":"

    Liked just for the word \"Discettes\" which is adorable \"heart_eyes\"

    ","created_at":"2015-01-23T02:38:29.185Z","title":"Introducing Discette - a minimal ember-cli front end to Discourse","url":"/t/introducing-discette-a-minimal-ember-cli-front-end-to-discourse/24321/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":7,"name":"dev","color":"000","topic_id":1026,"topic_count":574,"created_at":"2013-02-06T08:43:41.550Z","updated_at":"2015-01-22T18:05:32.855Z","user_id":32,"topics_year":298,"topics_month":29,"topics_week":2,"slug":"dev","description":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":4196,"latest_post_id":94590,"latest_topic_id":24349,"position":25,"parent_category_id":null,"posts_year":2095,"posts_month":172,"posts_week":16,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":3,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"dev","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94514,"cooked":"\n\n

    This is a good idea, are the documents public web URLs? Perhaps we could help build this onebox if so.

    \n\n\n\n

    Hmm. I suspect this could be done via the API. Query all new topics (assuming older topics are already synced), and for those with a certain URL within the topic (first post only? All posts?) ping those URLs.

    \n\n

    This could potentially be done with a webhook on save on the Discourse side.

    \n\n

    Let us know how we can help, very interested in public projects like this.

    ","created_at":"2015-01-23T02:37:39.518Z","title":"How to do \"Object Oriented Discussion\" through Oneboxes?","url":"/t/how-to-do-object-oriented-discussion-through-oneboxes/24328/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":5,"name":"extensibility","color":"FE8432","topic_id":28,"topic_count":295,"created_at":"2013-02-03T08:42:06.329Z","updated_at":"2015-01-22T18:05:32.698Z","user_id":1,"topics_year":187,"topics_month":17,"topics_week":7,"slug":"extensibility","description":"Topics about extending the functionality of Discourse with plugins, themes, add-ons, or other mechanisms for extensibility. ","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":2574,"latest_post_id":94582,"latest_topic_id":24328,"position":25,"parent_category_id":null,"posts_year":1485,"posts_month":196,"posts_week":52,"email_in":null,"email_in_allow_strangers":false,"topics_day":2,"posts_day":8,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"extensibility","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94512,"cooked":"

    Hmm, have not seen problems updating on 1gb instance provided swap is there.

    \n\n

    Anything else running on the machine?

    \n\n

    Maybe reboot, then upgrade Docker from command line, then upgrade Discourse from command line.

    ","created_at":"2015-01-23T02:32:31.383Z","title":"Update Failed and Now Showing Currently Upgrading","url":"/t/update-failed-and-now-showing-currently-upgrading/24332/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":6,"name":"support","color":"CEA9A9","topic_id":389,"topic_count":1781,"created_at":"2013-02-05T22:16:38.672Z","updated_at":"2015-01-22T18:05:33.572Z","user_id":1,"topics_year":1541,"topics_month":167,"topics_week":49,"slug":"support","description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":12272,"latest_post_id":94602,"latest_topic_id":24346,"position":25,"parent_category_id":null,"posts_year":10571,"posts_month":1254,"posts_week":413,"email_in":null,"email_in_allow_strangers":false,"topics_day":5,"posts_day":70,"logo_url":"","background_url":"","allow_badges":true,"name_lower":"support","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94511,"cooked":"

    Hmm, not sure about that, good odds they will be fixed in iOS 8.1 which is due soon.

    ","created_at":"2015-01-23T02:27:16.786Z","title":"Dealing with iOS 8 Mobile Safari bugs?","url":"/t/dealing-with-ios-8-mobile-safari-bugs/24101/5","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":2,"name":"feature","color":"0E76BD","topic_id":11,"topic_count":1592,"created_at":"2013-02-02T21:42:52.552Z","updated_at":"2015-01-22T18:05:32.647Z","user_id":1,"topics_year":919,"topics_month":60,"topics_week":20,"slug":"feature","description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":14360,"latest_post_id":94600,"latest_topic_id":24344,"position":25,"parent_category_id":null,"posts_year":8617,"posts_month":690,"posts_week":190,"email_in":null,"email_in_allow_strangers":false,"topics_day":2,"posts_day":8,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"feature","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}}] + "/groups/discourse/members.json": {"owners":[],"members":[{"id":2770,"username":"awesomerobot","uploaded_avatar_id":33872,"avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png","name":"","last_seen_at":"2015-01-23T15:53:17.844Z"},{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png","name":"Jeff Atwood","last_seen_at":"2015-01-23T06:05:25.457Z"},{"id":19,"username":"eviltrout","uploaded_avatar_id":5275,"avatar_template":"/user_avatar/meta.discourse.org/eviltrout/{size}/5275.png","name":"Robin Ward","last_seen_at":"2015-01-23T16:03:45.098Z"},{"id":2,"username":"neil","uploaded_avatar_id":5245,"avatar_template":"/user_avatar/meta.discourse.org/neil/{size}/5245.png","name":"Neil Lalonde","last_seen_at":"2015-01-23T15:22:10.244Z"},{"id":1,"username":"sam","uploaded_avatar_id":5243,"avatar_template":"/user_avatar/meta.discourse.org/sam/{size}/5243.png","name":"Sam Saffron","last_seen_at":"2015-01-23T11:07:06.233Z"},{"id":3,"username":"supermathie","uploaded_avatar_id":34097,"avatar_template":"/user_avatar/meta.discourse.org/supermathie/{size}/34097.png","name":"Michael Brown","last_seen_at":"2015-01-22T05:16:42.254Z"},{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png","name":"Régis Hanol","last_seen_at":"2015-01-23T15:45:34.196Z"}],"meta":{"total":7,"limit":50,"offset":0}}, + "/groups/discourse/posts.json": [{"id":94607,"cooked":"

    Right now we have two entirely different styles for new topics and new posts within a topic... we can probably fix that pretty easily.

    \n\n

    \n\n

    So the simple change would be:

    \n\n

    \n\n

    but... while the dot makes the \"• new\" stand out more... it doesn't communicate any information other than \"look at me\" — can we add more context without adding more noise?

    \n\n

    ","created_at":"2015-01-23T15:13:01.935Z","title":"Consistent new indicator","url":"/t/consistent-new-indicator/24355/1","user_title":"designerator","user_long_name":"","category":{"id":9,"name":"ux","color":"5F497A","topic_id":2628,"topic_count":540,"created_at":"2013-02-10T03:52:21.322Z","updated_at":"2015-01-22T18:05:32.152Z","user_id":32,"topics_year":370,"topics_month":33,"topics_week":3,"slug":"ux","description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":5823,"latest_post_id":94610,"latest_topic_id":24355,"position":25,"parent_category_id":null,"posts_year":4264,"posts_month":609,"posts_week":103,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":28,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"ux","auto_close_based_on_last_post":false},"user":{"id":2770,"username":"awesomerobot","uploaded_avatar_id":33872,"avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png"}},{"id":94603,"cooked":"

    Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.

    ","created_at":"2015-01-23T14:59:21.941Z","title":"The end of Clown Vomit, or, simplified category styles","url":"/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/63","user_title":"designerator","user_long_name":"","category":{"id":9,"name":"ux","color":"5F497A","topic_id":2628,"topic_count":540,"created_at":"2013-02-10T03:52:21.322Z","updated_at":"2015-01-22T18:05:32.152Z","user_id":32,"topics_year":370,"topics_month":33,"topics_week":3,"slug":"ux","description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":5823,"latest_post_id":94610,"latest_topic_id":24355,"position":25,"parent_category_id":null,"posts_year":4264,"posts_month":609,"posts_week":103,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":28,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"ux","auto_close_based_on_last_post":false},"user":{"id":2770,"username":"awesomerobot","uploaded_avatar_id":33872,"avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png"}},{"id":94601,"cooked":"

    Yeah I think this category arrangement is the way to go at the very least - much easier to scan two columns...

    \n\n

    Also, maybe square off the bars?

    \n\n

    \n\n

    ","created_at":"2015-01-23T14:51:55.497Z","title":"The end of Clown Vomit, or, simplified category styles","url":"/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/62","user_title":"designerator","user_long_name":"","category":{"id":9,"name":"ux","color":"5F497A","topic_id":2628,"topic_count":540,"created_at":"2013-02-10T03:52:21.322Z","updated_at":"2015-01-22T18:05:32.152Z","user_id":32,"topics_year":370,"topics_month":33,"topics_week":3,"slug":"ux","description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":5823,"latest_post_id":94610,"latest_topic_id":24355,"position":25,"parent_category_id":null,"posts_year":4264,"posts_month":609,"posts_week":103,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":28,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"ux","auto_close_based_on_last_post":false},"user":{"id":2770,"username":"awesomerobot","uploaded_avatar_id":33872,"avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png"}},{"id":94577,"cooked":"

    Yup, that's the latest version \"wink\"

    \n\n

    \n\n

    (click to view animated version)

    ","created_at":"2015-01-23T10:50:55.846Z","title":"Quote reply insertion at cursor position","url":"/t/quote-reply-insertion-at-cursor-position/24344/4","user_title":"team","user_long_name":"Régis Hanol","category":{"id":2,"name":"feature","color":"0E76BD","topic_id":11,"topic_count":1592,"created_at":"2013-02-02T21:42:52.552Z","updated_at":"2015-01-22T18:05:32.647Z","user_id":1,"topics_year":919,"topics_month":60,"topics_week":20,"slug":"feature","description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":14360,"latest_post_id":94600,"latest_topic_id":24344,"position":25,"parent_category_id":null,"posts_year":8617,"posts_month":690,"posts_week":190,"email_in":null,"email_in_allow_strangers":false,"topics_day":2,"posts_day":8,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"feature","auto_close_based_on_last_post":false},"user":{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png"}},{"id":94574,"cooked":"\n\n

    It used to be that but that was fixed a while ago. Are you running a recent version?

    ","created_at":"2015-01-23T10:31:29.222Z","title":"Quote reply insertion at cursor position","url":"/t/quote-reply-insertion-at-cursor-position/24344/2","user_title":"team","user_long_name":"Régis Hanol","category":{"id":2,"name":"feature","color":"0E76BD","topic_id":11,"topic_count":1592,"created_at":"2013-02-02T21:42:52.552Z","updated_at":"2015-01-22T18:05:32.647Z","user_id":1,"topics_year":919,"topics_month":60,"topics_week":20,"slug":"feature","description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":14360,"latest_post_id":94600,"latest_topic_id":24344,"position":25,"parent_category_id":null,"posts_year":8617,"posts_month":690,"posts_week":190,"email_in":null,"email_in_allow_strangers":false,"topics_day":2,"posts_day":8,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"feature","auto_close_based_on_last_post":false},"user":{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png"}},{"id":94572,"cooked":"\n\n

    That's an Ember update that introduced this change.

    ","created_at":"2015-01-23T09:46:00.901Z","title":"Translations frequently broken","url":"/t/translations-frequently-broken/22546/27","user_title":"team","user_long_name":"Régis Hanol","category":{"id":27,"name":"translations","color":"808281","topic_id":14549,"topic_count":146,"created_at":"2014-04-07T20:30:17.623Z","updated_at":"2015-01-22T18:05:33.111Z","user_id":2,"topics_year":134,"topics_month":5,"topics_week":3,"slug":"translations","description":"This category is for discussion about localizing Discourse.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":1167,"latest_post_id":94575,"latest_topic_id":24301,"position":25,"parent_category_id":7,"posts_year":965,"posts_month":60,"posts_week":29,"email_in":null,"email_in_allow_strangers":false,"topics_day":1,"posts_day":5,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"translations","auto_close_based_on_last_post":false},"user":{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png"}},{"id":94555,"cooked":"

    I don't know how to pronounce that in English, but this makes me think of the French word \"disquette\" (floppy disk) \"smile\"

    ","created_at":"2015-01-23T08:17:31.700Z","title":"Introducing Discette - a minimal ember-cli front end to Discourse","url":"/t/introducing-discette-a-minimal-ember-cli-front-end-to-discourse/24321/3","user_title":"team","user_long_name":"Régis Hanol","category":{"id":7,"name":"dev","color":"000","topic_id":1026,"topic_count":574,"created_at":"2013-02-06T08:43:41.550Z","updated_at":"2015-01-22T18:05:32.855Z","user_id":32,"topics_year":298,"topics_month":29,"topics_week":2,"slug":"dev","description":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":4196,"latest_post_id":94590,"latest_topic_id":24349,"position":25,"parent_category_id":null,"posts_year":2095,"posts_month":172,"posts_week":16,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":3,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"dev","auto_close_based_on_last_post":false},"user":{"id":1995,"username":"zogstrip","uploaded_avatar_id":8630,"avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png"}},{"id":94544,"cooked":"

    @techapj fixed this for 1.2.

    ","created_at":"2015-01-23T05:49:35.881Z","title":"After sign-in, I'm not redirected to the conversation","url":"/t/after-sign-in-im-not-redirected-to-the-conversation/17753/8","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":9,"name":"ux","color":"5F497A","topic_id":2628,"topic_count":540,"created_at":"2013-02-10T03:52:21.322Z","updated_at":"2015-01-22T18:05:32.152Z","user_id":32,"topics_year":370,"topics_month":33,"topics_week":3,"slug":"ux","description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":5823,"latest_post_id":94610,"latest_topic_id":24355,"position":25,"parent_category_id":null,"posts_year":4264,"posts_month":609,"posts_week":103,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":28,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"ux","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94543,"cooked":"

    Oh yes IOS 8.2 -- well, let's see what happens because there is really no fix on our end. Basic HTML / CSS stuff is broken.

    ","created_at":"2015-01-23T05:45:40.306Z","title":"Dealing with iOS 8 Mobile Safari bugs?","url":"/t/dealing-with-ios-8-mobile-safari-bugs/24101/7","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":2,"name":"feature","color":"0E76BD","topic_id":11,"topic_count":1592,"created_at":"2013-02-02T21:42:52.552Z","updated_at":"2015-01-22T18:05:32.647Z","user_id":1,"topics_year":919,"topics_month":60,"topics_week":20,"slug":"feature","description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":14360,"latest_post_id":94600,"latest_topic_id":24344,"position":25,"parent_category_id":null,"posts_year":8617,"posts_month":690,"posts_week":190,"email_in":null,"email_in_allow_strangers":false,"topics_day":2,"posts_day":8,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"feature","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94542,"cooked":"

    Hmm that looks like a bug, @techapj can you have a look?

    ","created_at":"2015-01-23T05:43:55.602Z","title":"RSS is not valid","url":"/t/rss-is-not-valid/24338/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":6,"name":"support","color":"CEA9A9","topic_id":389,"topic_count":1781,"created_at":"2013-02-05T22:16:38.672Z","updated_at":"2015-01-22T18:05:33.572Z","user_id":1,"topics_year":1541,"topics_month":167,"topics_week":49,"slug":"support","description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":12272,"latest_post_id":94602,"latest_topic_id":24346,"position":25,"parent_category_id":null,"posts_year":10571,"posts_month":1254,"posts_week":413,"email_in":null,"email_in_allow_strangers":false,"topics_day":5,"posts_day":70,"logo_url":"","background_url":"","allow_badges":true,"name_lower":"support","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94522,"cooked":"

    Oh I see. @zogstrip can you have a look?

    ","created_at":"2015-01-23T03:00:20.485Z","title":"Pasted image upload size error","url":"/t/pasted-image-upload-size-error/24320/4","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":1,"name":"bug","color":"e9dd00","topic_id":2,"topic_count":1729,"created_at":"2013-02-01T04:56:34.914Z","updated_at":"2015-01-22T18:05:33.426Z","user_id":1,"topics_year":1114,"topics_month":69,"topics_week":22,"slug":"bug","description":"A bug report means something is broken, preventing normal/typical use of Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","text_color":"000000","read_restricted":false,"auto_close_hours":null,"post_count":11179,"latest_post_id":94611,"latest_topic_id":24350,"position":25,"parent_category_id":null,"posts_year":7138,"posts_month":397,"posts_week":121,"email_in":null,"email_in_allow_strangers":false,"topics_day":1,"posts_day":6,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"bug","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94521,"cooked":"\n\n

    Yeah probably.

    \n\n\n\n

    Definitely a good idea. We have seen some eye melting color schemes people have picked for categories.. Much less subcategories.

    \n\n\n\n

    Sure try http://talk.folksy.com -- it's still too much color in boxes. Particularly anywhere a bunch of categories are displayed together, which is a lot of places considering the topic list is the main form of nav, both on the homepage default of latest and in suggested topics at the bottom of every topic...

    \n\n

    ","created_at":"2015-01-23T02:58:27.451Z","title":"The end of Clown Vomit, or, simplified category styles","url":"/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/57","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":9,"name":"ux","color":"5F497A","topic_id":2628,"topic_count":540,"created_at":"2013-02-10T03:52:21.322Z","updated_at":"2015-01-22T18:05:32.152Z","user_id":32,"topics_year":370,"topics_month":33,"topics_week":3,"slug":"ux","description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":5823,"latest_post_id":94610,"latest_topic_id":24355,"position":25,"parent_category_id":null,"posts_year":4264,"posts_month":609,"posts_week":103,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":28,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"ux","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94519,"cooked":"

    What would you suggest writing here that would be more clear?

    ","created_at":"2015-01-23T02:45:36.859Z","title":"What is \"Born mobile, born to touch\" supposed to tell me?","url":"/t/what-is-born-mobile-born-to-touch-supposed-to-tell-me/24329/3","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":3,"name":"meta","color":"aaa","topic_id":24,"topic_count":139,"created_at":"2013-02-03T00:00:15.230Z","updated_at":"2015-01-22T18:05:32.797Z","user_id":1,"topics_year":68,"topics_month":5,"topics_week":1,"slug":"meta","description":"Discussion about meta.discourse.org itself, the organization of this forum about Discourse, how it works, and how we can improve this site.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":1116,"latest_post_id":94559,"latest_topic_id":24208,"position":25,"parent_category_id":null,"posts_year":553,"posts_month":33,"posts_week":8,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":0,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"meta","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94518,"cooked":"

    You should generally create topics to host things like this, then make them wiki, close them, etc.

    ","created_at":"2015-01-23T02:42:20.053Z","title":"How to Create Static Pages in Discourse?","url":"/t/how-to-create-static-pages-in-discourse/24313/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":6,"name":"support","color":"CEA9A9","topic_id":389,"topic_count":1781,"created_at":"2013-02-05T22:16:38.672Z","updated_at":"2015-01-22T18:05:33.572Z","user_id":1,"topics_year":1541,"topics_month":167,"topics_week":49,"slug":"support","description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":12272,"latest_post_id":94602,"latest_topic_id":24346,"position":25,"parent_category_id":null,"posts_year":10571,"posts_month":1254,"posts_week":413,"email_in":null,"email_in_allow_strangers":false,"topics_day":5,"posts_day":70,"logo_url":"","background_url":"","allow_badges":true,"name_lower":"support","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94517,"cooked":"

    Doubtful this is a bug, probably dependent on the PNG encoding.

    \n\n

    Try using PNGOUT, or converting to 8 bit PNGOUT, to see some of the differences. And PNGOUT is lossless!

    ","created_at":"2015-01-23T02:41:30.287Z","title":"Pasted image upload size error","url":"/t/pasted-image-upload-size-error/24320/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":1,"name":"bug","color":"e9dd00","topic_id":2,"topic_count":1729,"created_at":"2013-02-01T04:56:34.914Z","updated_at":"2015-01-22T18:05:33.426Z","user_id":1,"topics_year":1114,"topics_month":69,"topics_week":22,"slug":"bug","description":"A bug report means something is broken, preventing normal/typical use of Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","text_color":"000000","read_restricted":false,"auto_close_hours":null,"post_count":11179,"latest_post_id":94611,"latest_topic_id":24350,"position":25,"parent_category_id":null,"posts_year":7138,"posts_month":397,"posts_week":121,"email_in":null,"email_in_allow_strangers":false,"topics_day":1,"posts_day":6,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"bug","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94516,"cooked":"

    I would worry about getting your expenses down to $5 per month, that seems more likely over time as hosting for Docker compliant sites gets cheaper.

    ","created_at":"2015-01-23T02:40:11.726Z","title":"Monetizing Discourse Talk","url":"/t/monetizing-discourse-talk/24316/4","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":6,"name":"support","color":"CEA9A9","topic_id":389,"topic_count":1781,"created_at":"2013-02-05T22:16:38.672Z","updated_at":"2015-01-22T18:05:33.572Z","user_id":1,"topics_year":1541,"topics_month":167,"topics_week":49,"slug":"support","description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":12272,"latest_post_id":94602,"latest_topic_id":24346,"position":25,"parent_category_id":null,"posts_year":10571,"posts_month":1254,"posts_week":413,"email_in":null,"email_in_allow_strangers":false,"topics_day":5,"posts_day":70,"logo_url":"","background_url":"","allow_badges":true,"name_lower":"support","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94515,"cooked":"

    Liked just for the word \"Discettes\" which is adorable \"heart_eyes\"

    ","created_at":"2015-01-23T02:38:29.185Z","title":"Introducing Discette - a minimal ember-cli front end to Discourse","url":"/t/introducing-discette-a-minimal-ember-cli-front-end-to-discourse/24321/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":7,"name":"dev","color":"000","topic_id":1026,"topic_count":574,"created_at":"2013-02-06T08:43:41.550Z","updated_at":"2015-01-22T18:05:32.855Z","user_id":32,"topics_year":298,"topics_month":29,"topics_week":2,"slug":"dev","description":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":4196,"latest_post_id":94590,"latest_topic_id":24349,"position":25,"parent_category_id":null,"posts_year":2095,"posts_month":172,"posts_week":16,"email_in":null,"email_in_allow_strangers":false,"topics_day":0,"posts_day":3,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"dev","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94514,"cooked":"\n\n

    This is a good idea, are the documents public web URLs? Perhaps we could help build this onebox if so.

    \n\n\n\n

    Hmm. I suspect this could be done via the API. Query all new topics (assuming older topics are already synced), and for those with a certain URL within the topic (first post only? All posts?) ping those URLs.

    \n\n

    This could potentially be done with a webhook on save on the Discourse side.

    \n\n

    Let us know how we can help, very interested in public projects like this.

    ","created_at":"2015-01-23T02:37:39.518Z","title":"How to do \"Object Oriented Discussion\" through Oneboxes?","url":"/t/how-to-do-object-oriented-discussion-through-oneboxes/24328/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":5,"name":"extensibility","color":"FE8432","topic_id":28,"topic_count":295,"created_at":"2013-02-03T08:42:06.329Z","updated_at":"2015-01-22T18:05:32.698Z","user_id":1,"topics_year":187,"topics_month":17,"topics_week":7,"slug":"extensibility","description":"Topics about extending the functionality of Discourse with plugins, themes, add-ons, or other mechanisms for extensibility. ","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":2574,"latest_post_id":94582,"latest_topic_id":24328,"position":25,"parent_category_id":null,"posts_year":1485,"posts_month":196,"posts_week":52,"email_in":null,"email_in_allow_strangers":false,"topics_day":2,"posts_day":8,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"extensibility","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94512,"cooked":"

    Hmm, have not seen problems updating on 1gb instance provided swap is there.

    \n\n

    Anything else running on the machine?

    \n\n

    Maybe reboot, then upgrade Docker from command line, then upgrade Discourse from command line.

    ","created_at":"2015-01-23T02:32:31.383Z","title":"Update Failed and Now Showing Currently Upgrading","url":"/t/update-failed-and-now-showing-currently-upgrading/24332/2","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":6,"name":"support","color":"CEA9A9","topic_id":389,"topic_count":1781,"created_at":"2013-02-05T22:16:38.672Z","updated_at":"2015-01-22T18:05:33.572Z","user_id":1,"topics_year":1541,"topics_month":167,"topics_week":49,"slug":"support","description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":12272,"latest_post_id":94602,"latest_topic_id":24346,"position":25,"parent_category_id":null,"posts_year":10571,"posts_month":1254,"posts_week":413,"email_in":null,"email_in_allow_strangers":false,"topics_day":5,"posts_day":70,"logo_url":"","background_url":"","allow_badges":true,"name_lower":"support","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}},{"id":94511,"cooked":"

    Hmm, not sure about that, good odds they will be fixed in iOS 8.1 which is due soon.

    ","created_at":"2015-01-23T02:27:16.786Z","title":"Dealing with iOS 8 Mobile Safari bugs?","url":"/t/dealing-with-ios-8-mobile-safari-bugs/24101/5","user_title":"co-founder","user_long_name":"Jeff Atwood","category":{"id":2,"name":"feature","color":"0E76BD","topic_id":11,"topic_count":1592,"created_at":"2013-02-02T21:42:52.552Z","updated_at":"2015-01-22T18:05:32.647Z","user_id":1,"topics_year":919,"topics_month":60,"topics_week":20,"slug":"feature","description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","text_color":"FFFFFF","read_restricted":false,"auto_close_hours":null,"post_count":14360,"latest_post_id":94600,"latest_topic_id":24344,"position":25,"parent_category_id":null,"posts_year":8617,"posts_month":690,"posts_week":190,"email_in":null,"email_in_allow_strangers":false,"topics_day":2,"posts_day":8,"logo_url":null,"background_url":null,"allow_badges":true,"name_lower":"feature","auto_close_based_on_last_post":false},"user":{"id":32,"username":"codinghorror","uploaded_avatar_id":5297,"avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png"}}] }; diff --git a/test/javascripts/fixtures/search-fixtures.js.es6 b/test/javascripts/fixtures/search-fixtures.js.es6 index 344b655ec5c..f979f3d78bb 100644 --- a/test/javascripts/fixtures/search-fixtures.js.es6 +++ b/test/javascripts/fixtures/search-fixtures.js.es6 @@ -505,8 +505,8 @@ export default { }, { "id":26192, - "title":"403 when embedding a Digital Ocean droplet", - "fancy_title":"403 when embedding a Digital Ocean droplet", + "title":"403 when embedding a DigitalOcean droplet", + "fancy_title":"403 when embedding a DigitalOcean droplet", "slug":"403-when-embedding-a-digital-ocean-droplet", "posts_count":7, "reply_count":3, @@ -559,7 +559,7 @@ export default { "posts_count":3, "reply_count":1, "highest_post_number":3, - "image_url":"https://discourse-cdn.global.ssl.fastly.net/meta/images/emoji/twitter/smile.png?v=0", + "image_url":"https://discourse-cdn.global.ssl.fastly.net/meta/images/emoji/twitter/smile.png?v=1", "created_at":"2014-10-07T13:37:19.628Z", "last_posted_at":"2014-10-07T18:46:22.493Z", "bumped":true, diff --git a/test/javascripts/fixtures/site-fixtures.js.es6 b/test/javascripts/fixtures/site-fixtures.js.es6 index 9e29ee832f9..81ce4b86975 100644 --- a/test/javascripts/fixtures/site-fixtures.js.es6 +++ b/test/javascripts/fixtures/site-fixtures.js.es6 @@ -19,7 +19,8 @@ export default { "post_types":{ "regular":1, "moderator_action":2, - "small_action":3 + "small_action":3, + "whisper":4 }, "group_names":[ "admins", diff --git a/test/javascripts/fixtures/top_fixture.js.es6 b/test/javascripts/fixtures/top_fixture.js.es6 index 9dc5c7cd554..3ddc2300c63 100644 --- a/test/javascripts/fixtures/top_fixture.js.es6 +++ b/test/javascripts/fixtures/top_fixture.js.es6 @@ -1,2 +1,2 @@ /*jshint maxlen:10000000 */ -export default {"/top.json":{"users":[{"id":32,"username":"codinghorror","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/codinghorror/{size}/2.png"},{"id":2316,"username":"pakl","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pakl/{size}/2.png"},{"id":1,"username":"sam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sam/{size}/2.png"},{"id":2770,"username":"awesomerobot","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/awesomerobot/{size}/2.png"},{"id":8307,"username":"HAWK","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hawk/{size}/2.png"},{"id":10886,"username":"Onyx","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/onyx/{size}/2.png"},{"id":10855,"username":"abarker","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/abarker/{size}/2.png"},{"id":8300,"username":"cpradio","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cpradio/{size}/2.png"},{"id":5559,"username":"downey","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/downey/{size}/2.png"},{"id":11160,"username":"boomzilla","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/boomzilla/{size}/2.png"},{"id":4263,"username":"mcwumbly","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mcwumbly/{size}/2.png"},{"id":8909,"username":"AdamCapriola","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/adamcapriola/{size}/2.png"},{"id":4500,"username":"bbendick","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bbendick/{size}/2.png"},{"id":3415,"username":"radq","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/radq/{size}/2.png"},{"id":471,"username":"BhaelOchon","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bhaelochon/{size}/2.png"},{"id":7948,"username":"probus","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/probus/{size}/2.png"},{"id":6626,"username":"riking","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/riking/{size}/2.png"},{"id":2989,"username":"meglio","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/meglio/{size}/2.png"},{"id":8493,"username":"PJH","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pjh/{size}/2.png"},{"id":11455,"username":"Dan_G","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/dan_g/{size}/2.png"},{"id":5707,"username":"trident","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/trident/{size}/2.png"},{"id":5351,"username":"erlend_sh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/erlend_sh/{size}/2.png"},{"id":2,"username":"neil","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/neil/{size}/2.png"},{"id":11017,"username":"Matches","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/matches/{size}/2.png"},{"id":19,"username":"eviltrout","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eviltrout/{size}/2.png"},{"id":8325,"username":"StevieD","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/stevied/{size}/2.png"},{"id":6060,"username":"lightyear","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lightyear/{size}/2.png"},{"id":8085,"username":"watchmanmonitor","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/watchmanmonitor/{size}/2.png"},{"id":7717,"username":"lake54","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lake54/{size}/2.png"},{"id":8873,"username":"birarda","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/birarda/{size}/2.png"},{"id":8434,"username":"ArmedGuy","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/armedguy/{size}/2.png"},{"id":8437,"username":"paully21","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/paully21/{size}/2.png"},{"id":9147,"username":"davemaxwell","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/davemaxwell/{size}/2.png"},{"id":9653,"username":"TechnoBear","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/technobear/{size}/2.png"},{"id":11589,"username":"mott555","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mott555/{size}/2.png"},{"id":6607,"username":"aahank","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/aahank/{size}/2.png"},{"id":10816,"username":"Alankrit_Choudh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/alankrit_choudh/{size}/2.png"},{"id":8222,"username":"techAPJ","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/techapj/{size}/2.png"},{"id":11780,"username":"cosban","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cosban/{size}/2.png"},{"id":6819,"username":"gmanjapan","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/gmanjapan/{size}/2.png"},{"id":6548,"username":"michaeld","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/michaeld/{size}/2.png"},{"id":6268,"username":"ChaoticLoki","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/chaoticloki/{size}/2.png"},{"id":8,"username":"geek","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/geek/{size}/2.png"},{"id":8343,"username":"Piioo","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/piioo/{size}/2.png"},{"id":9536,"username":"nahtnam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/nahtnam/{size}/2.png"},{"id":9093,"username":"RRManzke","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/rrmanzke/{size}/2.png"},{"id":8364,"username":"codetricity","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/codetricity/{size}/2.png"},{"id":5013,"username":"zenkamal","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/zenkamal/{size}/2.png"},{"id":10778,"username":"Lid","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lid/{size}/2.png"},{"id":5399,"username":"jeffwidman","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jeffwidman/{size}/2.png"},{"id":11747,"username":"fysics","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/fysics/{size}/2.png"},{"id":11762,"username":"bruceoberg","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bruceoberg/{size}/2.png"},{"id":10856,"username":"youderian","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/youderian/{size}/2.png"},{"id":8810,"username":"fantasticfears","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/fantasticfears/{size}/2.png"},{"id":10098,"username":"jwatte","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jwatte/{size}/2.png"},{"id":9775,"username":"elberet","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/elberet/{size}/2.png"},{"id":704,"username":"AstonJ","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/astonj/{size}/2.png"},{"id":10920,"username":"Webinsane","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/webinsane/{size}/2.png"},{"id":6613,"username":"haiku","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/haiku/{size}/2.png"},{"id":8820,"username":"aaroleung","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/aaroleung/{size}/2.png"},{"id":6746,"username":"shiningdracon","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/shiningdracon/{size}/2.png"},{"id":9909,"username":"unikevin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/unikevin/{size}/2.png"},{"id":11003,"username":"node","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/node/{size}/2.png"},{"id":8571,"username":"tobiaseigen","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/tobiaseigen/{size}/2.png"},{"id":8344,"username":"pyro240","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pyro240/{size}/2.png"},{"id":8399,"username":"edwardlafoy","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/edwardlafoy/{size}/2.png"},{"id":10949,"username":"stu1","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/stu1/{size}/2.png"},{"id":9664,"username":"cameronmartin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cameronmartin/{size}/2.png"},{"id":9931,"username":"Frank","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/frank/{size}/2.png"},{"id":10470,"username":"brpc","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/brpc/{size}/2.png"},{"id":10548,"username":"RabidFX","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/rabidfx/{size}/2.png"},{"id":4983,"username":"hey_julien","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hey_julien/{size}/2.png"},{"id":7074,"username":"Maomao","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/maomao/{size}/2.png"},{"id":7502,"username":"Pablo_Macaluso","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pablo_macaluso/{size}/2.png"},{"id":5609,"username":"camilohollanda","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/camilohollanda/{size}/2.png"},{"id":8059,"username":"Torrelles","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/torrelles/{size}/2.png"},{"id":8105,"username":"trevor_ratliff","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/trevor_ratliff/{size}/2.png"},{"id":8072,"username":"apere006","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/apere006/{size}/2.png"},{"id":9497,"username":"arumdev","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/arumdev/{size}/2.png"},{"id":5017,"username":"tuananh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/tuananh/{size}/2.png"},{"id":11163,"username":"faoileag","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/faoileag/{size}/2.png"},{"id":11265,"username":"cipher1","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cipher1/{size}/2.png"},{"id":5105,"username":"Ricky_Mason","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/ricky_mason/{size}/2.png"},{"id":1353,"username":"sparr","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sparr/{size}/2.png"},{"id":5851,"username":"TheChadMiller","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/thechadmiller/{size}/2.png"},{"id":2520,"username":"anotherchris","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/anotherchris/{size}/2.png"},{"id":5249,"username":"cawas","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cawas/{size}/2.png"},{"id":4457,"username":"Lee_Ars","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lee_ars/{size}/2.png"},{"id":5160,"username":"eriko","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eriko/{size}/2.png"},{"id":4220,"username":"kirantpatil","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/kirantpatil/{size}/2.png"},{"id":3704,"username":"mojzis","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mojzis/{size}/2.png"},{"id":8944,"username":"hunterboerner","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hunterboerner/{size}/2.png"},{"id":6808,"username":"velesin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/velesin/{size}/2.png"},{"id":8933,"username":"JohnONolan","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/johnonolan/{size}/2.png"},{"id":7604,"username":"citkane","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/citkane/{size}/2.png"},{"id":1783,"username":"iainb","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/iainb/{size}/2.png"},{"id":9371,"username":"Vocino","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/vocino/{size}/2.png"},{"id":8617,"username":"Mittineague","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mittineague/{size}/2.png"},{"id":10632,"username":"justinmayer","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/justinmayer/{size}/2.png"},{"id":438,"username":"TuringTest","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/turingtest/{size}/2.png"},{"id":9726,"username":"brybell","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/brybell/{size}/2.png"},{"id":3675,"username":"jk779","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jk779/{size}/2.png"}],"topic_list":{"can_create_topic":false,"draft":null,"draft_key":"new_topic","draft_sequence":null,"for_period":"yearly","topics":[{"id":13088,"title":"Initial Discourse badge design spec","fancy_title":"Initial Discourse badge design spec","slug":"initial-discourse-badge-design-spec","posts_count":129,"reply_count":87,"highest_post_number":132,"image_url":"/uploads/default/3429/a20bcab33be2b6e2.png","created_at":"2014-02-26T04:55:39.741-05:00","last_posted_at":"2014-07-15T17:15:47.236-04:00","bumped":true,"bumped_at":"2014-07-15T17:15:47.236-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":3278,"like_count":305,"has_summary":true,"archetype":"regular","last_poster_username":"HAWK","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2316},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":8307}]},{"id":18063,"title":"10k+ posts causes progress bar to show single number","fancy_title":"10k+ posts causes progress bar to show single number","slug":"10k-posts-causes-progress-bar-to-show-single-number","posts_count":67,"reply_count":57,"highest_post_number":70,"image_url":"/uploads/default/_optimized/fdc/03e/3d48765fc4_690x45.png","created_at":"2014-07-25T13:31:34.474-04:00","last_posted_at":"2014-07-26T04:14:18.323-04:00","bumped":true,"bumped_at":"2014-07-26T04:20:54.730-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":335,"like_count":337,"has_summary":true,"archetype":"regular","last_poster_username":"sam","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":10886},{"extras":null,"description":"Frequent Poster","user_id":10855},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":18827,"title":"Consolidating Activity field","fancy_title":"Consolidating Activity field","slug":"consolidating-activity-field","posts_count":89,"reply_count":81,"highest_post_number":94,"image_url":"/uploads/default/33551/6483991bda61d4e5.png","created_at":"2014-08-13T18:46:09.613-04:00","last_posted_at":"2014-08-18T16:31:12.479-04:00","bumped":true,"bumped_at":"2014-08-18T16:30:13.362-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":226,"like_count":181,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":4263}]},{"id":18397,"title":"Does anyone actually like the \"Likes\" column?","fancy_title":"Does anyone actually like the “Likes” column?","slug":"does-anyone-actually-like-the-likes-column","posts_count":81,"reply_count":94,"highest_post_number":111,"image_url":null,"created_at":"2014-08-02T22:15:54.016-04:00","last_posted_at":"2014-08-25T19:37:00.313-04:00","bumped":true,"bumped_at":"2014-08-25T19:37:00.313-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":460,"like_count":191,"has_summary":true,"archetype":"regular","last_poster_username":"bbendick","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":8909},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":"latest","description":"Most Recent Poster","user_id":4500}]},{"id":13789,"title":"Badges feedback","fancy_title":"Badges feedback","slug":"badges-feedback","posts_count":101,"reply_count":74,"highest_post_number":104,"image_url":null,"created_at":"2014-03-16T20:16:29.885-04:00","last_posted_at":"2014-08-25T13:38:58.464-04:00","bumped":true,"bumped_at":"2014-08-25T13:38:58.464-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2227,"like_count":97,"has_summary":true,"archetype":"regular","last_poster_username":"cpradio","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":8300}]},{"id":13479,"title":"Topic List design experiments","fancy_title":"Topic List design experiments","slug":"topic-list-design-experiments","posts_count":90,"reply_count":70,"highest_post_number":93,"image_url":"/uploads/default/_optimized/8f2/41d/0436a3b666_689x392.png","created_at":"2014-03-06T23:41:26.312-05:00","last_posted_at":"2014-07-30T16:03:05.846-04:00","bumped":true,"bumped_at":"2014-07-30T16:03:05.846-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1532,"like_count":109,"has_summary":true,"archetype":"regular","last_poster_username":"probus","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":471},{"extras":"latest","description":"Most Recent Poster","user_id":7948}]},{"id":11911,"title":"How should we implement polls?","fancy_title":"How should we implement polls?","slug":"how-should-we-implement-polls","posts_count":70,"reply_count":51,"highest_post_number":73,"image_url":null,"created_at":"2014-01-12T21:48:03.160-05:00","last_posted_at":"2014-07-27T18:11:30.077-04:00","bumped":true,"bumped_at":"2014-07-27T18:11:30.077-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2724,"like_count":123,"has_summary":true,"archetype":"regular","last_poster_username":"meglio","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":2989}]},{"id":18524,"title":"Rename \"Dismiss Unread\" to \"Stop Tracking Topics\"","fancy_title":"Rename “Dismiss Unread” to “Stop Tracking Topics”","slug":"rename-dismiss-unread-to-stop-tracking-topics","posts_count":74,"reply_count":53,"highest_post_number":74,"image_url":null,"created_at":"2014-08-06T01:12:01.086-04:00","last_posted_at":"2014-08-12T05:47:20.750-04:00","bumped":true,"bumped_at":"2014-08-12T05:47:20.750-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":149,"like_count":103,"has_summary":true,"archetype":"regular","last_poster_username":"Dan_G","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":8493},{"extras":"latest","description":"Most Recent Poster","user_id":11455}]},{"id":10515,"title":"Flatter styling now deployed","fancy_title":"Flatter styling now deployed","slug":"flatter-styling-now-deployed","posts_count":80,"reply_count":41,"highest_post_number":80,"image_url":null,"created_at":"2013-10-20T19:36:00.465-04:00","last_posted_at":"2014-03-18T14:04:00.515-04:00","bumped":true,"bumped_at":"2014-03-18T14:04:00.515-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1790,"like_count":78,"has_summary":true,"archetype":"regular","last_poster_username":"mcwumbly","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":5707},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":4263}]},{"id":12346,"title":"What about an easier styling/theming system?","fancy_title":"What about an easier styling/theming system?","slug":"what-about-an-easier-styling-theming-system","posts_count":54,"reply_count":26,"highest_post_number":54,"image_url":null,"created_at":"2014-01-31T19:11:51.887-05:00","last_posted_at":"2014-07-01T17:42:38.425-04:00","bumped":true,"bumped_at":"2014-07-01T17:42:38.425-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1740,"like_count":130,"has_summary":true,"archetype":"regular","last_poster_username":"neil","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":2}]},{"id":18875,"title":"Notification when a moderator or admin deletes your message","fancy_title":"Notification when a moderator or admin deletes your message","slug":"notification-when-a-moderator-or-admin-deletes-your-message","posts_count":58,"reply_count":44,"highest_post_number":66,"image_url":null,"created_at":"2014-08-14T18:57:28.722-04:00","last_posted_at":"2014-08-20T12:34:26.180-04:00","bumped":true,"bumped_at":"2014-08-20T12:34:20.630-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":181,"like_count":122,"has_summary":true,"archetype":"regular","last_poster_username":"eviltrout","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":11017},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":11455},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":12257,"title":"Is \"Activity\" too ambiguous?","fancy_title":"Is “Activity” too ambiguous?","slug":"is-activity-too-ambiguous","posts_count":53,"reply_count":40,"highest_post_number":53,"image_url":"/uploads/default/_optimized/542/c04/82250e51e5_690x248.png","created_at":"2014-01-28T14:01:08.745-05:00","last_posted_at":"2014-04-13T18:25:45.492-04:00","bumped":true,"bumped_at":"2014-04-13T18:25:45.492-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":686,"like_count":103,"has_summary":true,"archetype":"regular","last_poster_username":"StevieD","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":7948},{"extras":"latest","description":"Most Recent Poster","user_id":8325}]},{"id":13099,"title":"Replacing Mailing lists: Email-In","fancy_title":"Replacing Mailing lists: Email-In","slug":"replacing-mailing-lists-email-in","posts_count":66,"reply_count":46,"highest_post_number":68,"image_url":null,"created_at":"2014-02-26T13:24:44.965-05:00","last_posted_at":"2014-07-09T18:01:21.166-04:00","bumped":true,"bumped_at":"2014-07-09T19:10:30.547-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1567,"like_count":76,"has_summary":true,"archetype":"regular","last_poster_username":"lake54","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6060},{"extras":null,"description":"Frequent Poster","user_id":5351},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":7717}]},{"id":13045,"title":"Official Single-Sign-On for Discourse","fancy_title":"Official Single-Sign-On for Discourse","slug":"official-single-sign-on-for-discourse","posts_count":61,"reply_count":37,"highest_post_number":64,"image_url":"/uploads/default/_optimized/07c/3bf/3fa1d69ceb_690x207.png","created_at":"2014-02-25T03:30:34.321-05:00","last_posted_at":"2014-08-01T17:44:56.523-04:00","bumped":true,"bumped_at":"2014-08-07T13:27:14.684-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":13052,"like_count":74,"has_summary":true,"archetype":"regular","last_poster_username":"riking","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8873},{"extras":null,"description":"Frequent Poster","user_id":8434},{"extras":null,"description":"Frequent Poster","user_id":8437},{"extras":"latest","description":"Most Recent Poster","user_id":6626}]},{"id":19099,"title":"Should search prioritize recent topics over older topics?","fancy_title":"Should search prioritize recent topics over older topics?","slug":"should-search-prioritize-recent-topics-over-older-topics","posts_count":55,"reply_count":48,"highest_post_number":58,"image_url":"/uploads/default/33840/49e57c5a286a2131.png","created_at":"2014-08-20T12:00:12.737-04:00","last_posted_at":"2014-08-22T17:46:34.073-04:00","bumped":true,"bumped_at":"2014-08-22T17:46:20.038-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":149,"like_count":83,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":9147},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":9653},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":18879,"title":"Further simplifying the columns: quality score > view count","fancy_title":"Further simplifying the columns: quality score > view count","slug":"further-simplifying-the-columns-quality-score-view-count","posts_count":44,"reply_count":32,"highest_post_number":44,"image_url":"/uploads/default/33627/b40ad535eba2b7a3.png","created_at":"2014-08-14T21:19:24.118-04:00","last_posted_at":"2014-08-22T14:25:12.092-04:00","bumped":true,"bumped_at":"2014-08-22T15:21:09.995-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":560,"like_count":95,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":8909},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":11589},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13847,"title":"Allowing SSL for your Discourse Docker setup","fancy_title":"Allowing SSL for your Discourse Docker setup","slug":"allowing-ssl-for-your-discourse-docker-setup","posts_count":47,"reply_count":59,"highest_post_number":58,"image_url":null,"created_at":"2014-03-18T19:45:27.517-04:00","last_posted_at":"2014-08-28T04:03:20.851-04:00","bumped":true,"bumped_at":"2014-08-28T04:17:17.852-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":6927,"like_count":87,"has_summary":false,"archetype":"regular","last_poster_username":"cosban","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6607},{"extras":null,"description":"Frequent Poster","user_id":10816},{"extras":null,"description":"Frequent Poster","user_id":8222},{"extras":"latest","description":"Most Recent Poster","user_id":11780}]},{"id":9621,"title":"Free Hosted Option?","fancy_title":"Free Hosted Option?","slug":"free-hosted-option","posts_count":43,"reply_count":33,"highest_post_number":43,"image_url":null,"created_at":"2013-09-05T16:22:20.790-04:00","last_posted_at":"2014-04-08T00:24:46.320-04:00","bumped":true,"bumped_at":"2014-04-08T00:24:46.320-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1844,"like_count":93,"has_summary":false,"archetype":"regular","last_poster_username":"ChaoticLoki","category_id":8,"posters":[{"extras":null,"description":"Original Poster","user_id":6819},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":6268}]},{"id":18873,"title":"Alternative to blue colors for coldmapping","fancy_title":"Alternative to blue colors for coldmapping","slug":"alternative-to-blue-colors-for-coldmapping","posts_count":47,"reply_count":23,"highest_post_number":47,"image_url":null,"created_at":"2014-08-14T18:33:21.844-04:00","last_posted_at":"2014-08-15T10:46:08.175-04:00","bumped":true,"bumped_at":"2014-08-15T10:46:08.175-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":122,"like_count":84,"has_summary":false,"archetype":"regular","last_poster_username":"boomzilla","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":10855},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":8},{"extras":"latest","description":"Most Recent Poster","user_id":11160}]},{"id":11763,"title":"Google AdSense plugin is now available","fancy_title":"Google AdSense plugin is now available","slug":"google-adsense-plugin-is-now-available","posts_count":57,"reply_count":36,"highest_post_number":58,"image_url":"/uploads/default/_optimized/66d/cf0/d69e6709fe_496x500.PNG","created_at":"2014-01-05T14:28:58.037-05:00","last_posted_at":"2014-08-08T07:55:23.454-04:00","bumped":true,"bumped_at":"2014-08-08T07:55:23.454-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2085,"like_count":62,"has_summary":true,"archetype":"regular","last_poster_username":"michaeld","category_id":22,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":8343},{"extras":null,"description":"Frequent Poster","user_id":9536},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":9093}]},{"id":13485,"title":"What do you like/dislike about the NodeBB design?","fancy_title":"What do you like/dislike about the NodeBB design?","slug":"what-do-you-like-dislike-about-the-nodebb-design","posts_count":52,"reply_count":28,"highest_post_number":53,"image_url":null,"created_at":"2014-03-07T03:38:14.227-05:00","last_posted_at":"2014-08-20T15:19:00.969-04:00","bumped":true,"bumped_at":"2014-08-19T20:22:04.123-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1495,"like_count":68,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8364},{"extras":null,"description":"Frequent Poster","user_id":5013},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":2770}]},{"id":17454,"title":"Spambots from Tor exit points keep taking over my forum","fancy_title":"Spambots from Tor exit points keep taking over my forum","slug":"spambots-from-tor-exit-points-keep-taking-over-my-forum","posts_count":46,"reply_count":32,"highest_post_number":46,"image_url":"/uploads/default/_optimized/b0d/ab3/20401b97ce_690x454.png","created_at":"2014-07-11T03:20:49.433-04:00","last_posted_at":"2014-08-19T18:09:10.799-04:00","bumped":true,"bumped_at":"2014-08-19T18:02:57.107-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1243,"like_count":78,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":6,"posters":[{"extras":null,"description":"Original Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":10778},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":19317,"title":"Introducing Discourse 1.0","fancy_title":"Introducing Discourse 1.0","slug":"introducing-discourse-1-0","posts_count":36,"reply_count":3,"highest_post_number":36,"image_url":null,"created_at":"2014-08-26T15:43:01.370-04:00","last_posted_at":"2014-08-28T13:16:42.484-04:00","bumped":true,"bumped_at":"2014-08-28T13:16:42.484-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":709,"like_count":103,"has_summary":false,"archetype":"regular","last_poster_username":"youderian","category_id":13,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5399},{"extras":null,"description":"Frequent Poster","user_id":11747},{"extras":null,"description":"Frequent Poster","user_id":11762},{"extras":"latest","description":"Most Recent Poster","user_id":10856}]},{"id":13184,"title":"Discourse General Polish prior to V1","fancy_title":"Discourse General Polish prior to V1","slug":"discourse-general-polish-prior-to-v1","posts_count":44,"reply_count":30,"highest_post_number":48,"image_url":"/plugins/emoji/images/arrow_left.png","created_at":"2014-02-27T19:10:41.496-05:00","last_posted_at":"2014-06-08T03:32:02.009-04:00","bumped":true,"bumped_at":"2014-06-06T03:30:23.984-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":1864,"like_count":77,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":8222},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":17694,"title":"Release schedule post version 1.0","fancy_title":"Release schedule post version 1.0","slug":"release-schedule-post-version-1-0","posts_count":44,"reply_count":35,"highest_post_number":44,"image_url":null,"created_at":"2014-07-17T19:45:21.459-04:00","last_posted_at":"2014-07-23T03:51:03.564-04:00","bumped":true,"bumped_at":"2014-07-29T17:20:06.942-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":539,"like_count":70,"has_summary":false,"archetype":"regular","last_poster_username":"probus","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":10098},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":"latest","description":"Most Recent Poster","user_id":7948}]},{"id":18533,"title":"My latest forum... but it's not running Discourse - here's why","fancy_title":"My latest forum… but it’s not running Discourse - here’s why","slug":"my-latest-forum-but-its-not-running-discourse-heres-why","posts_count":37,"reply_count":27,"highest_post_number":38,"image_url":null,"created_at":"2014-08-06T06:01:35.608-04:00","last_posted_at":"2014-08-15T13:27:13.386-04:00","bumped":true,"bumped_at":"2014-08-15T13:27:13.386-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1185,"like_count":73,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":704},{"extras":null,"description":"Frequent Poster","user_id":10920},{"extras":null,"description":"Frequent Poster","user_id":6613},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13287,"title":"Chinese search issues","fancy_title":"Chinese search issues","slug":"chinese-search-issues","posts_count":60,"reply_count":41,"highest_post_number":60,"image_url":"https://f.cloud.github.com/assets/6783175/2296397/3dcabcf8-a09e-11e3-9f5a-2a94d981fced.png","created_at":"2014-03-01T10:12:14.845-05:00","last_posted_at":"2014-07-10T17:03:25.796-04:00","bumped":true,"bumped_at":"2014-07-10T17:03:25.796-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":947,"like_count":25,"has_summary":true,"archetype":"regular","last_poster_username":"sam","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":8820},{"extras":null,"description":"Frequent Poster","user_id":6746},{"extras":null,"description":"Frequent Poster","user_id":9909},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":17727,"title":"Compliance with EU Cookie Law","fancy_title":"Compliance with EU Cookie Law","slug":"compliance-with-eu-cookie-law","posts_count":46,"reply_count":32,"highest_post_number":46,"image_url":null,"created_at":"2014-07-18T17:39:38.499-04:00","last_posted_at":"2014-07-26T18:01:33.751-04:00","bumped":true,"bumped_at":"2014-07-26T18:01:33.751-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":836,"like_count":48,"has_summary":false,"archetype":"regular","last_poster_username":"node","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":11003},{"extras":null,"description":"Frequent Poster","user_id":11017},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":9536}]},{"id":15336,"title":"Switch from Gravatar to HTML/CSS letters for no-avatar users","fancy_title":"Switch from Gravatar to HTML/CSS letters for no-avatar users","slug":"switch-from-gravatar-to-html-css-letters-for-no-avatar-users","posts_count":39,"reply_count":25,"highest_post_number":39,"image_url":"/uploads/default/_optimized/d29/bc1/25fa89ae0a_415x500.png","created_at":"2014-05-05T18:46:02.221-04:00","last_posted_at":"2014-05-28T18:07:12.448-04:00","bumped":true,"bumped_at":"2014-05-28T18:07:09.701-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":1011,"like_count":63,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":26,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":8571},{"extras":null,"description":"Frequent Poster","user_id":8344}]},{"id":12957,"title":"Discourse for iOS","fancy_title":"Discourse for iOS","slug":"discourse-for-ios","posts_count":43,"reply_count":24,"highest_post_number":43,"image_url":"http://a4.mzstatic.com/us/r30/Purple/v4/8d/85/93/8d859353-625c-8abc-5c00-36be5f293709/mzl.luwjaamb.png","created_at":"2014-02-21T20:37:44.606-05:00","last_posted_at":"2014-08-20T15:09:19.767-04:00","bumped":true,"bumped_at":"2014-08-20T15:09:19.767-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1082,"like_count":48,"has_summary":false,"archetype":"regular","last_poster_username":"erlend_sh","category_id":5,"posters":[{"extras":null,"description":"Original Poster","user_id":8399},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":10949},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":5351}]},{"id":14973,"title":"Symbol for like - why is it a heart?","fancy_title":"Symbol for like - why is it a heart?","slug":"symbol-for-like-why-is-it-a-heart","posts_count":29,"reply_count":14,"highest_post_number":29,"image_url":null,"created_at":"2014-04-22T12:24:22.822-04:00","last_posted_at":"2014-05-08T17:41:27.803-04:00","bumped":true,"bumped_at":"2014-05-08T17:41:27.803-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1421,"like_count":73,"has_summary":false,"archetype":"regular","last_poster_username":"Frank","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":9664},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":9931}]},{"id":16875,"title":"Options to disable hijack of CMD+F / CTRL+F and \"/\" keys for search?","fancy_title":"Options to disable hijack of CMD+F / CTRL+F and “/” keys for search?","slug":"options-to-disable-hijack-of-cmd-f-ctrl-f-and-keys-for-search","posts_count":44,"reply_count":36,"highest_post_number":44,"image_url":null,"created_at":"2014-06-25T17:04:48.413-04:00","last_posted_at":"2014-08-25T04:01:38.132-04:00","bumped":true,"bumped_at":"2014-08-25T04:01:38.132-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":541,"like_count":41,"has_summary":false,"archetype":"regular","last_poster_username":"RabidFX","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":10470},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":"latest","description":"Most Recent Poster","user_id":10548}]},{"id":9975,"title":"Translators We Want You!","fancy_title":"Translators We Want You!","slug":"translators-we-want-you","posts_count":50,"reply_count":28,"highest_post_number":50,"image_url":null,"created_at":"2013-09-23T13:47:39.521-04:00","last_posted_at":"2014-03-16T16:21:13.891-04:00","bumped":true,"bumped_at":"2014-03-16T16:21:13.891-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1262,"like_count":26,"has_summary":true,"archetype":"regular","last_poster_username":"Torrelles","category_id":27,"posters":[{"extras":null,"description":"Original Poster","user_id":4983},{"extras":null,"description":"Frequent Poster","user_id":7074},{"extras":null,"description":"Frequent Poster","user_id":7502},{"extras":null,"description":"Frequent Poster","user_id":5609},{"extras":"latest","description":"Most Recent Poster","user_id":8059}]},{"id":12112,"title":"The system user needs a cool avatar","fancy_title":"The system user needs a cool avatar","slug":"the-system-user-needs-a-cool-avatar","posts_count":35,"reply_count":24,"highest_post_number":35,"image_url":"/uploads/default/31460/c596ef65a9d0533c.png","created_at":"2014-01-21T22:26:01.574-05:00","last_posted_at":"2014-01-31T16:54:22.261-05:00","bumped":true,"bumped_at":"2014-01-31T16:54:22.261-05:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":848,"like_count":55,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":8105},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":11718,"title":"Reply button while logged out","fancy_title":"Reply button while logged out","slug":"reply-button-while-logged-out","posts_count":46,"reply_count":42,"highest_post_number":46,"image_url":null,"created_at":"2014-01-02T17:11:14.130-05:00","last_posted_at":"2014-04-05T10:20:11.921-04:00","bumped":true,"bumped_at":"2014-04-05T10:20:11.921-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":830,"like_count":32,"has_summary":false,"archetype":"regular","last_poster_username":"apere006","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":8072},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":9497},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":471}]},{"id":18698,"title":"Site setting for sending analytics data to Discourse.org","fancy_title":"Site setting for sending analytics data to Discourse.org","slug":"site-setting-for-sending-analytics-data-to-discourse-org","posts_count":27,"reply_count":18,"highest_post_number":27,"image_url":null,"created_at":"2014-08-10T11:47:04.016-04:00","last_posted_at":"2014-08-11T15:36:21.664-04:00","bumped":true,"bumped_at":"2014-08-11T15:36:04.020-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":135,"like_count":72,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":17443,"title":"Can I Keep Nofollow for All User Links, Including from Trust Level 3?","fancy_title":"Can I Keep Nofollow for All User Links, Including from Trust Level 3?","slug":"can-i-keep-nofollow-for-all-user-links-including-from-trust-level-3","posts_count":40,"reply_count":30,"highest_post_number":41,"image_url":null,"created_at":"2014-07-10T22:06:49.357-04:00","last_posted_at":"2014-07-14T19:20:37.014-04:00","bumped":true,"bumped_at":"2014-07-14T19:20:37.014-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":237,"like_count":42,"has_summary":false,"archetype":"regular","last_poster_username":"cpradio","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5017},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":8300}]},{"id":18821,"title":"Suggestion: # of likes in a topic in the tool tip","fancy_title":"Suggestion: # of likes in a topic in the tool tip","slug":"suggestion-of-likes-in-a-topic-in-the-tool-tip","posts_count":27,"reply_count":22,"highest_post_number":27,"image_url":null,"created_at":"2014-08-13T15:23:46.745-04:00","last_posted_at":"2014-08-15T07:40:57.684-04:00","bumped":true,"bumped_at":"2014-08-15T07:40:57.684-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":133,"like_count":68,"has_summary":false,"archetype":"regular","last_poster_username":"boomzilla","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":11163},{"extras":null,"description":"Frequent Poster","user_id":11265},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8493},{"extras":"latest","description":"Most Recent Poster","user_id":11160}]},{"id":9741,"title":"Difference between Reddit and Discourse","fancy_title":"Difference between Reddit and Discourse","slug":"difference-between-reddit-and-discourse","posts_count":42,"reply_count":32,"highest_post_number":42,"image_url":null,"created_at":"2013-09-11T22:17:39.971-04:00","last_posted_at":"2013-09-17T19:01:36.139-04:00","bumped":true,"bumped_at":"2013-09-17T19:01:36.139-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":3303,"like_count":35,"has_summary":false,"archetype":"regular","last_poster_username":"anotherchris","category_id":3,"posters":[{"extras":null,"description":"Original Poster","user_id":5105},{"extras":null,"description":"Frequent Poster","user_id":1353},{"extras":null,"description":"Frequent Poster","user_id":5851},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":2520}]},{"id":12156,"title":"Beginners Guide to Deploy Discourse on Digital Ocean using Docker","fancy_title":"Beginners Guide to Deploy Discourse on Digital Ocean using Docker","slug":"beginners-guide-to-deploy-discourse-on-digital-ocean-using-docker","posts_count":28,"reply_count":157,"highest_post_number":219,"image_url":"http://www.discourse.org/images/install/droplet-step-1.png","created_at":"2014-01-23T14:58:17.918-05:00","last_posted_at":"2014-08-26T10:06:25.833-04:00","bumped":true,"bumped_at":"2014-08-26T10:06:25.833-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":10112,"like_count":63,"has_summary":false,"archetype":"regular","last_poster_username":"cawas","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":8222},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":8364},{"extras":"latest","description":"Most Recent Poster","user_id":5249}]},{"id":12522,"title":"Permission Changes (moderators have less)","fancy_title":"Permission Changes (moderators have less)","slug":"permission-changes-moderators-have-less","posts_count":42,"reply_count":30,"highest_post_number":43,"image_url":null,"created_at":"2014-02-06T22:34:05.332-05:00","last_posted_at":"2014-08-01T12:26:40.440-04:00","bumped":true,"bumped_at":"2014-08-01T12:26:40.440-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1806,"like_count":37,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":10291,"title":"CAS sso auth plugin","fancy_title":"CAS sso auth plugin","slug":"cas-sso-auth-plugin","posts_count":48,"reply_count":32,"highest_post_number":51,"image_url":null,"created_at":"2013-10-09T17:01:21.524-04:00","last_posted_at":"2014-08-27T16:08:25.417-04:00","bumped":true,"bumped_at":"2014-08-27T16:08:25.417-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1433,"like_count":20,"has_summary":false,"archetype":"regular","last_poster_username":"eriko","category_id":22,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5160},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4220},{"extras":null,"description":"Frequent Poster","user_id":3704},{"extras":null,"description":"Frequent Poster","user_id":32}]},{"id":16877,"title":"Discourse V1.0 Next Month","fancy_title":"Discourse V1.0 Next Month","slug":"discourse-v1-0-next-month","posts_count":25,"reply_count":11,"highest_post_number":26,"image_url":null,"created_at":"2014-06-25T18:54:32.020-04:00","last_posted_at":"2014-08-14T13:07:09.405-04:00","bumped":true,"bumped_at":"2014-08-14T13:07:09.405-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1113,"like_count":65,"has_summary":false,"archetype":"regular","last_poster_username":"Dan_G","category_id":13,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":null,"description":"Frequent Poster","user_id":8944},{"extras":null,"description":"Frequent Poster","user_id":10920},{"extras":"latest","description":"Most Recent Poster","user_id":11455}]},{"id":18257,"title":"Move the new/unread counters to the first column in topic list","fancy_title":"Move the new/unread counters to the first column in topic list","slug":"move-the-new-unread-counters-to-the-first-column-in-topic-list","posts_count":32,"reply_count":25,"highest_post_number":32,"image_url":null,"created_at":"2014-07-30T02:33:42.679-04:00","last_posted_at":"2014-08-01T12:33:11.694-04:00","bumped":true,"bumped_at":"2014-08-01T12:33:11.694-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":217,"like_count":51,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13249,"title":"Syncing the editor viewport scroll","fancy_title":"Syncing the editor viewport scroll","slug":"syncing-the-editor-viewport-scroll","posts_count":35,"reply_count":15,"highest_post_number":35,"image_url":null,"created_at":"2014-02-28T19:03:57.708-05:00","last_posted_at":"2014-04-06T21:04:59.528-04:00","bumped":true,"bumped_at":"2014-04-06T21:04:59.528-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":980,"like_count":44,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6808},{"extras":null,"description":"Frequent Poster","user_id":8933},{"extras":null,"description":"Frequent Poster","user_id":19},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":9711,"title":"Now testing: mobile (small screen) layouts on key pages","fancy_title":"Now testing: mobile (small screen) layouts on key pages","slug":"now-testing-mobile-small-screen-layouts-on-key-pages","posts_count":43,"reply_count":31,"highest_post_number":51,"image_url":"/uploads/meta_discourse/1787/beb2b60fba4c46c3.png","created_at":"2013-09-10T19:45:51.532-04:00","last_posted_at":"2014-02-05T02:03:24.974-05:00","bumped":true,"bumped_at":"2014-02-05T13:45:55.088-05:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1635,"like_count":27,"has_summary":false,"archetype":"regular","last_poster_username":"iainb","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2},{"extras":null,"description":"Frequent Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":7604},{"extras":"latest","description":"Most Recent Poster","user_id":1783}]},{"id":15048,"title":"Linking a Discourse User db with a Mumble server (Murmur)","fancy_title":"Linking a Discourse User db with a Mumble server (Murmur)","slug":"linking-a-discourse-user-db-with-a-mumble-server-murmur","posts_count":48,"reply_count":40,"highest_post_number":48,"image_url":null,"created_at":"2014-04-24T18:30:17.568-04:00","last_posted_at":"2014-05-30T20:43:13.387-04:00","bumped":true,"bumped_at":"2014-05-30T20:43:13.387-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":625,"like_count":17,"has_summary":false,"archetype":"regular","last_poster_username":"Vocino","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":9371},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6613}]},{"id":17945,"title":"Unread/new badge style?","fancy_title":"Unread/new badge style?","slug":"unread-new-badge-style","posts_count":35,"reply_count":23,"highest_post_number":35,"image_url":"/uploads/default/_optimized/b61/a61/3508713cc1_690x202.png","created_at":"2014-07-23T10:49:18.864-04:00","last_posted_at":"2014-07-28T13:52:16.773-04:00","bumped":true,"bumped_at":"2014-07-28T13:52:16.773-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":279,"like_count":43,"has_summary":false,"archetype":"regular","last_poster_username":"Mittineague","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":8617}]},{"id":16803,"title":"Auto-hide persistent fixed header on scroll","fancy_title":"Auto-hide persistent fixed header on scroll","slug":"auto-hide-persistent-fixed-header-on-scroll","posts_count":39,"reply_count":27,"highest_post_number":39,"image_url":null,"created_at":"2014-06-23T13:25:32.523-04:00","last_posted_at":"2014-07-07T10:45:40.399-04:00","bumped":true,"bumped_at":"2014-07-07T10:45:40.399-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":792,"like_count":34,"has_summary":false,"archetype":"regular","last_poster_username":"mcwumbly","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":10632},{"extras":null,"description":"Frequent Poster","user_id":438},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":4263}]},{"id":15858,"title":"Configuring Google OAuth2 login for Discourse","fancy_title":"Configuring Google OAuth2 login for Discourse","slug":"configuring-google-oauth2-login-for-discourse","posts_count":36,"reply_count":24,"highest_post_number":40,"image_url":"/uploads/default/_optimized/9ae/174/5a30a33f56_690x399.png","created_at":"2014-05-21T18:46:55.403-04:00","last_posted_at":"2014-08-17T15:30:40.593-04:00","bumped":true,"bumped_at":"2014-08-17T15:29:45.558-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":5257,"like_count":41,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":2},{"extras":null,"description":"Frequent Poster","user_id":9726},{"extras":null,"description":"Frequent Poster","user_id":3675},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":32}]}]}}}; +export default {"/top.json":{"users":[{"id":32,"username":"codinghorror","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/codinghorror/{size}/2.png"},{"id":2316,"username":"pakl","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pakl/{size}/2.png"},{"id":1,"username":"sam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sam/{size}/2.png"},{"id":2770,"username":"awesomerobot","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/awesomerobot/{size}/2.png"},{"id":8307,"username":"HAWK","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hawk/{size}/2.png"},{"id":10886,"username":"Onyx","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/onyx/{size}/2.png"},{"id":10855,"username":"abarker","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/abarker/{size}/2.png"},{"id":8300,"username":"cpradio","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cpradio/{size}/2.png"},{"id":5559,"username":"downey","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/downey/{size}/2.png"},{"id":11160,"username":"boomzilla","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/boomzilla/{size}/2.png"},{"id":4263,"username":"mcwumbly","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mcwumbly/{size}/2.png"},{"id":8909,"username":"AdamCapriola","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/adamcapriola/{size}/2.png"},{"id":4500,"username":"bbendick","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bbendick/{size}/2.png"},{"id":3415,"username":"radq","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/radq/{size}/2.png"},{"id":471,"username":"BhaelOchon","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bhaelochon/{size}/2.png"},{"id":7948,"username":"probus","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/probus/{size}/2.png"},{"id":6626,"username":"riking","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/riking/{size}/2.png"},{"id":2989,"username":"meglio","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/meglio/{size}/2.png"},{"id":8493,"username":"PJH","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pjh/{size}/2.png"},{"id":11455,"username":"Dan_G","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/dan_g/{size}/2.png"},{"id":5707,"username":"trident","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/trident/{size}/2.png"},{"id":5351,"username":"erlend_sh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/erlend_sh/{size}/2.png"},{"id":2,"username":"neil","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/neil/{size}/2.png"},{"id":11017,"username":"Matches","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/matches/{size}/2.png"},{"id":19,"username":"eviltrout","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eviltrout/{size}/2.png"},{"id":8325,"username":"StevieD","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/stevied/{size}/2.png"},{"id":6060,"username":"lightyear","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lightyear/{size}/2.png"},{"id":8085,"username":"watchmanmonitor","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/watchmanmonitor/{size}/2.png"},{"id":7717,"username":"lake54","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lake54/{size}/2.png"},{"id":8873,"username":"birarda","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/birarda/{size}/2.png"},{"id":8434,"username":"ArmedGuy","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/armedguy/{size}/2.png"},{"id":8437,"username":"paully21","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/paully21/{size}/2.png"},{"id":9147,"username":"davemaxwell","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/davemaxwell/{size}/2.png"},{"id":9653,"username":"TechnoBear","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/technobear/{size}/2.png"},{"id":11589,"username":"mott555","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mott555/{size}/2.png"},{"id":6607,"username":"aahank","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/aahank/{size}/2.png"},{"id":10816,"username":"Alankrit_Choudh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/alankrit_choudh/{size}/2.png"},{"id":8222,"username":"techAPJ","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/techapj/{size}/2.png"},{"id":11780,"username":"cosban","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cosban/{size}/2.png"},{"id":6819,"username":"gmanjapan","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/gmanjapan/{size}/2.png"},{"id":6548,"username":"michaeld","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/michaeld/{size}/2.png"},{"id":6268,"username":"ChaoticLoki","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/chaoticloki/{size}/2.png"},{"id":8,"username":"geek","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/geek/{size}/2.png"},{"id":8343,"username":"Piioo","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/piioo/{size}/2.png"},{"id":9536,"username":"nahtnam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/nahtnam/{size}/2.png"},{"id":9093,"username":"RRManzke","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/rrmanzke/{size}/2.png"},{"id":8364,"username":"codetricity","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/codetricity/{size}/2.png"},{"id":5013,"username":"zenkamal","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/zenkamal/{size}/2.png"},{"id":10778,"username":"Lid","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lid/{size}/2.png"},{"id":5399,"username":"jeffwidman","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jeffwidman/{size}/2.png"},{"id":11747,"username":"fysics","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/fysics/{size}/2.png"},{"id":11762,"username":"bruceoberg","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bruceoberg/{size}/2.png"},{"id":10856,"username":"youderian","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/youderian/{size}/2.png"},{"id":8810,"username":"fantasticfears","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/fantasticfears/{size}/2.png"},{"id":10098,"username":"jwatte","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jwatte/{size}/2.png"},{"id":9775,"username":"elberet","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/elberet/{size}/2.png"},{"id":704,"username":"AstonJ","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/astonj/{size}/2.png"},{"id":10920,"username":"Webinsane","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/webinsane/{size}/2.png"},{"id":6613,"username":"haiku","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/haiku/{size}/2.png"},{"id":8820,"username":"aaroleung","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/aaroleung/{size}/2.png"},{"id":6746,"username":"shiningdracon","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/shiningdracon/{size}/2.png"},{"id":9909,"username":"unikevin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/unikevin/{size}/2.png"},{"id":11003,"username":"node","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/node/{size}/2.png"},{"id":8571,"username":"tobiaseigen","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/tobiaseigen/{size}/2.png"},{"id":8344,"username":"pyro240","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pyro240/{size}/2.png"},{"id":8399,"username":"edwardlafoy","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/edwardlafoy/{size}/2.png"},{"id":10949,"username":"stu1","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/stu1/{size}/2.png"},{"id":9664,"username":"cameronmartin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cameronmartin/{size}/2.png"},{"id":9931,"username":"Frank","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/frank/{size}/2.png"},{"id":10470,"username":"brpc","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/brpc/{size}/2.png"},{"id":10548,"username":"RabidFX","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/rabidfx/{size}/2.png"},{"id":4983,"username":"hey_julien","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hey_julien/{size}/2.png"},{"id":7074,"username":"Maomao","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/maomao/{size}/2.png"},{"id":7502,"username":"Pablo_Macaluso","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pablo_macaluso/{size}/2.png"},{"id":5609,"username":"camilohollanda","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/camilohollanda/{size}/2.png"},{"id":8059,"username":"Torrelles","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/torrelles/{size}/2.png"},{"id":8105,"username":"trevor_ratliff","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/trevor_ratliff/{size}/2.png"},{"id":8072,"username":"apere006","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/apere006/{size}/2.png"},{"id":9497,"username":"arumdev","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/arumdev/{size}/2.png"},{"id":5017,"username":"tuananh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/tuananh/{size}/2.png"},{"id":11163,"username":"faoileag","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/faoileag/{size}/2.png"},{"id":11265,"username":"cipher1","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cipher1/{size}/2.png"},{"id":5105,"username":"Ricky_Mason","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/ricky_mason/{size}/2.png"},{"id":1353,"username":"sparr","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sparr/{size}/2.png"},{"id":5851,"username":"TheChadMiller","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/thechadmiller/{size}/2.png"},{"id":2520,"username":"anotherchris","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/anotherchris/{size}/2.png"},{"id":5249,"username":"cawas","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cawas/{size}/2.png"},{"id":4457,"username":"Lee_Ars","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lee_ars/{size}/2.png"},{"id":5160,"username":"eriko","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eriko/{size}/2.png"},{"id":4220,"username":"kirantpatil","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/kirantpatil/{size}/2.png"},{"id":3704,"username":"mojzis","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mojzis/{size}/2.png"},{"id":8944,"username":"hunterboerner","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hunterboerner/{size}/2.png"},{"id":6808,"username":"velesin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/velesin/{size}/2.png"},{"id":8933,"username":"JohnONolan","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/johnonolan/{size}/2.png"},{"id":7604,"username":"citkane","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/citkane/{size}/2.png"},{"id":1783,"username":"iainb","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/iainb/{size}/2.png"},{"id":9371,"username":"Vocino","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/vocino/{size}/2.png"},{"id":8617,"username":"Mittineague","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mittineague/{size}/2.png"},{"id":10632,"username":"justinmayer","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/justinmayer/{size}/2.png"},{"id":438,"username":"TuringTest","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/turingtest/{size}/2.png"},{"id":9726,"username":"brybell","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/brybell/{size}/2.png"},{"id":3675,"username":"jk779","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jk779/{size}/2.png"}],"topic_list":{"can_create_topic":false,"draft":null,"draft_key":"new_topic","draft_sequence":null,"for_period":"yearly","topics":[{"id":13088,"title":"Initial Discourse badge design spec","fancy_title":"Initial Discourse badge design spec","slug":"initial-discourse-badge-design-spec","posts_count":129,"reply_count":87,"highest_post_number":132,"image_url":"/uploads/default/3429/a20bcab33be2b6e2.png","created_at":"2014-02-26T04:55:39.741-05:00","last_posted_at":"2014-07-15T17:15:47.236-04:00","bumped":true,"bumped_at":"2014-07-15T17:15:47.236-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":3278,"like_count":305,"has_summary":true,"archetype":"regular","last_poster_username":"HAWK","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2316},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":8307}]},{"id":18063,"title":"10k+ posts causes progress bar to show single number","fancy_title":"10k+ posts causes progress bar to show single number","slug":"10k-posts-causes-progress-bar-to-show-single-number","posts_count":67,"reply_count":57,"highest_post_number":70,"image_url":"/uploads/default/_optimized/fdc/03e/3d48765fc4_690x45.png","created_at":"2014-07-25T13:31:34.474-04:00","last_posted_at":"2014-07-26T04:14:18.323-04:00","bumped":true,"bumped_at":"2014-07-26T04:20:54.730-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":335,"like_count":337,"has_summary":true,"archetype":"regular","last_poster_username":"sam","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":10886},{"extras":null,"description":"Frequent Poster","user_id":10855},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":18827,"title":"Consolidating Activity field","fancy_title":"Consolidating Activity field","slug":"consolidating-activity-field","posts_count":89,"reply_count":81,"highest_post_number":94,"image_url":"/uploads/default/33551/6483991bda61d4e5.png","created_at":"2014-08-13T18:46:09.613-04:00","last_posted_at":"2014-08-18T16:31:12.479-04:00","bumped":true,"bumped_at":"2014-08-18T16:30:13.362-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":226,"like_count":181,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":4263}]},{"id":18397,"title":"Does anyone actually like the \"Likes\" column?","fancy_title":"Does anyone actually like the “Likes” column?","slug":"does-anyone-actually-like-the-likes-column","posts_count":81,"reply_count":94,"highest_post_number":111,"image_url":null,"created_at":"2014-08-02T22:15:54.016-04:00","last_posted_at":"2014-08-25T19:37:00.313-04:00","bumped":true,"bumped_at":"2014-08-25T19:37:00.313-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":460,"like_count":191,"has_summary":true,"archetype":"regular","last_poster_username":"bbendick","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":8909},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":"latest","description":"Most Recent Poster","user_id":4500}]},{"id":13789,"title":"Badges feedback","fancy_title":"Badges feedback","slug":"badges-feedback","posts_count":101,"reply_count":74,"highest_post_number":104,"image_url":null,"created_at":"2014-03-16T20:16:29.885-04:00","last_posted_at":"2014-08-25T13:38:58.464-04:00","bumped":true,"bumped_at":"2014-08-25T13:38:58.464-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2227,"like_count":97,"has_summary":true,"archetype":"regular","last_poster_username":"cpradio","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":8300}]},{"id":13479,"title":"Topic List design experiments","fancy_title":"Topic List design experiments","slug":"topic-list-design-experiments","posts_count":90,"reply_count":70,"highest_post_number":93,"image_url":"/uploads/default/_optimized/8f2/41d/0436a3b666_689x392.png","created_at":"2014-03-06T23:41:26.312-05:00","last_posted_at":"2014-07-30T16:03:05.846-04:00","bumped":true,"bumped_at":"2014-07-30T16:03:05.846-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1532,"like_count":109,"has_summary":true,"archetype":"regular","last_poster_username":"probus","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":471},{"extras":"latest","description":"Most Recent Poster","user_id":7948}]},{"id":11911,"title":"How should we implement polls?","fancy_title":"How should we implement polls?","slug":"how-should-we-implement-polls","posts_count":70,"reply_count":51,"highest_post_number":73,"image_url":null,"created_at":"2014-01-12T21:48:03.160-05:00","last_posted_at":"2014-07-27T18:11:30.077-04:00","bumped":true,"bumped_at":"2014-07-27T18:11:30.077-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2724,"like_count":123,"has_summary":true,"archetype":"regular","last_poster_username":"meglio","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":2989}]},{"id":18524,"title":"Rename \"Dismiss Unread\" to \"Stop Tracking Topics\"","fancy_title":"Rename “Dismiss Unread” to “Stop Tracking Topics”","slug":"rename-dismiss-unread-to-stop-tracking-topics","posts_count":74,"reply_count":53,"highest_post_number":74,"image_url":null,"created_at":"2014-08-06T01:12:01.086-04:00","last_posted_at":"2014-08-12T05:47:20.750-04:00","bumped":true,"bumped_at":"2014-08-12T05:47:20.750-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":149,"like_count":103,"has_summary":true,"archetype":"regular","last_poster_username":"Dan_G","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":8493},{"extras":"latest","description":"Most Recent Poster","user_id":11455}]},{"id":10515,"title":"Flatter styling now deployed","fancy_title":"Flatter styling now deployed","slug":"flatter-styling-now-deployed","posts_count":80,"reply_count":41,"highest_post_number":80,"image_url":null,"created_at":"2013-10-20T19:36:00.465-04:00","last_posted_at":"2014-03-18T14:04:00.515-04:00","bumped":true,"bumped_at":"2014-03-18T14:04:00.515-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1790,"like_count":78,"has_summary":true,"archetype":"regular","last_poster_username":"mcwumbly","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":5707},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":4263}]},{"id":12346,"title":"What about an easier styling/theming system?","fancy_title":"What about an easier styling/theming system?","slug":"what-about-an-easier-styling-theming-system","posts_count":54,"reply_count":26,"highest_post_number":54,"image_url":null,"created_at":"2014-01-31T19:11:51.887-05:00","last_posted_at":"2014-07-01T17:42:38.425-04:00","bumped":true,"bumped_at":"2014-07-01T17:42:38.425-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1740,"like_count":130,"has_summary":true,"archetype":"regular","last_poster_username":"neil","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":2}]},{"id":18875,"title":"Notification when a moderator or admin deletes your message","fancy_title":"Notification when a moderator or admin deletes your message","slug":"notification-when-a-moderator-or-admin-deletes-your-message","posts_count":58,"reply_count":44,"highest_post_number":66,"image_url":null,"created_at":"2014-08-14T18:57:28.722-04:00","last_posted_at":"2014-08-20T12:34:26.180-04:00","bumped":true,"bumped_at":"2014-08-20T12:34:20.630-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":181,"like_count":122,"has_summary":true,"archetype":"regular","last_poster_username":"eviltrout","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":11017},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":11455},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":12257,"title":"Is \"Activity\" too ambiguous?","fancy_title":"Is “Activity” too ambiguous?","slug":"is-activity-too-ambiguous","posts_count":53,"reply_count":40,"highest_post_number":53,"image_url":"/uploads/default/_optimized/542/c04/82250e51e5_690x248.png","created_at":"2014-01-28T14:01:08.745-05:00","last_posted_at":"2014-04-13T18:25:45.492-04:00","bumped":true,"bumped_at":"2014-04-13T18:25:45.492-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":686,"like_count":103,"has_summary":true,"archetype":"regular","last_poster_username":"StevieD","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":7948},{"extras":"latest","description":"Most Recent Poster","user_id":8325}]},{"id":13099,"title":"Replacing Mailing lists: Email-In","fancy_title":"Replacing Mailing lists: Email-In","slug":"replacing-mailing-lists-email-in","posts_count":66,"reply_count":46,"highest_post_number":68,"image_url":null,"created_at":"2014-02-26T13:24:44.965-05:00","last_posted_at":"2014-07-09T18:01:21.166-04:00","bumped":true,"bumped_at":"2014-07-09T19:10:30.547-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1567,"like_count":76,"has_summary":true,"archetype":"regular","last_poster_username":"lake54","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6060},{"extras":null,"description":"Frequent Poster","user_id":5351},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":7717}]},{"id":13045,"title":"Official Single-Sign-On for Discourse","fancy_title":"Official Single-Sign-On for Discourse","slug":"official-single-sign-on-for-discourse","posts_count":61,"reply_count":37,"highest_post_number":64,"image_url":"/uploads/default/_optimized/07c/3bf/3fa1d69ceb_690x207.png","created_at":"2014-02-25T03:30:34.321-05:00","last_posted_at":"2014-08-01T17:44:56.523-04:00","bumped":true,"bumped_at":"2014-08-07T13:27:14.684-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":13052,"like_count":74,"has_summary":true,"archetype":"regular","last_poster_username":"riking","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8873},{"extras":null,"description":"Frequent Poster","user_id":8434},{"extras":null,"description":"Frequent Poster","user_id":8437},{"extras":"latest","description":"Most Recent Poster","user_id":6626}]},{"id":19099,"title":"Should search prioritize recent topics over older topics?","fancy_title":"Should search prioritize recent topics over older topics?","slug":"should-search-prioritize-recent-topics-over-older-topics","posts_count":55,"reply_count":48,"highest_post_number":58,"image_url":"/uploads/default/33840/49e57c5a286a2131.png","created_at":"2014-08-20T12:00:12.737-04:00","last_posted_at":"2014-08-22T17:46:34.073-04:00","bumped":true,"bumped_at":"2014-08-22T17:46:20.038-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":149,"like_count":83,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":9147},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":9653},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":18879,"title":"Further simplifying the columns: quality score > view count","fancy_title":"Further simplifying the columns: quality score > view count","slug":"further-simplifying-the-columns-quality-score-view-count","posts_count":44,"reply_count":32,"highest_post_number":44,"image_url":"/uploads/default/33627/b40ad535eba2b7a3.png","created_at":"2014-08-14T21:19:24.118-04:00","last_posted_at":"2014-08-22T14:25:12.092-04:00","bumped":true,"bumped_at":"2014-08-22T15:21:09.995-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":560,"like_count":95,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":8909},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":11589},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13847,"title":"Allowing SSL for your Discourse Docker setup","fancy_title":"Allowing SSL for your Discourse Docker setup","slug":"allowing-ssl-for-your-discourse-docker-setup","posts_count":47,"reply_count":59,"highest_post_number":58,"image_url":null,"created_at":"2014-03-18T19:45:27.517-04:00","last_posted_at":"2014-08-28T04:03:20.851-04:00","bumped":true,"bumped_at":"2014-08-28T04:17:17.852-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":6927,"like_count":87,"has_summary":false,"archetype":"regular","last_poster_username":"cosban","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6607},{"extras":null,"description":"Frequent Poster","user_id":10816},{"extras":null,"description":"Frequent Poster","user_id":8222},{"extras":"latest","description":"Most Recent Poster","user_id":11780}]},{"id":9621,"title":"Free Hosted Option?","fancy_title":"Free Hosted Option?","slug":"free-hosted-option","posts_count":43,"reply_count":33,"highest_post_number":43,"image_url":null,"created_at":"2013-09-05T16:22:20.790-04:00","last_posted_at":"2014-04-08T00:24:46.320-04:00","bumped":true,"bumped_at":"2014-04-08T00:24:46.320-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1844,"like_count":93,"has_summary":false,"archetype":"regular","last_poster_username":"ChaoticLoki","category_id":8,"posters":[{"extras":null,"description":"Original Poster","user_id":6819},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":6268}]},{"id":18873,"title":"Alternative to blue colors for coldmapping","fancy_title":"Alternative to blue colors for coldmapping","slug":"alternative-to-blue-colors-for-coldmapping","posts_count":47,"reply_count":23,"highest_post_number":47,"image_url":null,"created_at":"2014-08-14T18:33:21.844-04:00","last_posted_at":"2014-08-15T10:46:08.175-04:00","bumped":true,"bumped_at":"2014-08-15T10:46:08.175-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":122,"like_count":84,"has_summary":false,"archetype":"regular","last_poster_username":"boomzilla","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":10855},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":8},{"extras":"latest","description":"Most Recent Poster","user_id":11160}]},{"id":11763,"title":"Google AdSense plugin is now available","fancy_title":"Google AdSense plugin is now available","slug":"google-adsense-plugin-is-now-available","posts_count":57,"reply_count":36,"highest_post_number":58,"image_url":"/uploads/default/_optimized/66d/cf0/d69e6709fe_496x500.PNG","created_at":"2014-01-05T14:28:58.037-05:00","last_posted_at":"2014-08-08T07:55:23.454-04:00","bumped":true,"bumped_at":"2014-08-08T07:55:23.454-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2085,"like_count":62,"has_summary":true,"archetype":"regular","last_poster_username":"michaeld","category_id":22,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":8343},{"extras":null,"description":"Frequent Poster","user_id":9536},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":9093}]},{"id":13485,"title":"What do you like/dislike about the NodeBB design?","fancy_title":"What do you like/dislike about the NodeBB design?","slug":"what-do-you-like-dislike-about-the-nodebb-design","posts_count":52,"reply_count":28,"highest_post_number":53,"image_url":null,"created_at":"2014-03-07T03:38:14.227-05:00","last_posted_at":"2014-08-20T15:19:00.969-04:00","bumped":true,"bumped_at":"2014-08-19T20:22:04.123-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1495,"like_count":68,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8364},{"extras":null,"description":"Frequent Poster","user_id":5013},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":2770}]},{"id":17454,"title":"Spambots from Tor exit points keep taking over my forum","fancy_title":"Spambots from Tor exit points keep taking over my forum","slug":"spambots-from-tor-exit-points-keep-taking-over-my-forum","posts_count":46,"reply_count":32,"highest_post_number":46,"image_url":"/uploads/default/_optimized/b0d/ab3/20401b97ce_690x454.png","created_at":"2014-07-11T03:20:49.433-04:00","last_posted_at":"2014-08-19T18:09:10.799-04:00","bumped":true,"bumped_at":"2014-08-19T18:02:57.107-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1243,"like_count":78,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":6,"posters":[{"extras":null,"description":"Original Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":10778},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":19317,"title":"Introducing Discourse 1.0","fancy_title":"Introducing Discourse 1.0","slug":"introducing-discourse-1-0","posts_count":36,"reply_count":3,"highest_post_number":36,"image_url":null,"created_at":"2014-08-26T15:43:01.370-04:00","last_posted_at":"2014-08-28T13:16:42.484-04:00","bumped":true,"bumped_at":"2014-08-28T13:16:42.484-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":709,"like_count":103,"has_summary":false,"archetype":"regular","last_poster_username":"youderian","category_id":13,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5399},{"extras":null,"description":"Frequent Poster","user_id":11747},{"extras":null,"description":"Frequent Poster","user_id":11762},{"extras":"latest","description":"Most Recent Poster","user_id":10856}]},{"id":13184,"title":"Discourse General Polish prior to V1","fancy_title":"Discourse General Polish prior to V1","slug":"discourse-general-polish-prior-to-v1","posts_count":44,"reply_count":30,"highest_post_number":48,"image_url":"/plugins/emoji/images/arrow_left.png","created_at":"2014-02-27T19:10:41.496-05:00","last_posted_at":"2014-06-08T03:32:02.009-04:00","bumped":true,"bumped_at":"2014-06-06T03:30:23.984-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":1864,"like_count":77,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":8222},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":17694,"title":"Release schedule post version 1.0","fancy_title":"Release schedule post version 1.0","slug":"release-schedule-post-version-1-0","posts_count":44,"reply_count":35,"highest_post_number":44,"image_url":null,"created_at":"2014-07-17T19:45:21.459-04:00","last_posted_at":"2014-07-23T03:51:03.564-04:00","bumped":true,"bumped_at":"2014-07-29T17:20:06.942-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":539,"like_count":70,"has_summary":false,"archetype":"regular","last_poster_username":"probus","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":10098},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":"latest","description":"Most Recent Poster","user_id":7948}]},{"id":18533,"title":"My latest forum... but it's not running Discourse - here's why","fancy_title":"My latest forum… but it’s not running Discourse - here’s why","slug":"my-latest-forum-but-its-not-running-discourse-heres-why","posts_count":37,"reply_count":27,"highest_post_number":38,"image_url":null,"created_at":"2014-08-06T06:01:35.608-04:00","last_posted_at":"2014-08-15T13:27:13.386-04:00","bumped":true,"bumped_at":"2014-08-15T13:27:13.386-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1185,"like_count":73,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":704},{"extras":null,"description":"Frequent Poster","user_id":10920},{"extras":null,"description":"Frequent Poster","user_id":6613},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13287,"title":"Chinese search issues","fancy_title":"Chinese search issues","slug":"chinese-search-issues","posts_count":60,"reply_count":41,"highest_post_number":60,"image_url":"https://f.cloud.github.com/assets/6783175/2296397/3dcabcf8-a09e-11e3-9f5a-2a94d981fced.png","created_at":"2014-03-01T10:12:14.845-05:00","last_posted_at":"2014-07-10T17:03:25.796-04:00","bumped":true,"bumped_at":"2014-07-10T17:03:25.796-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":947,"like_count":25,"has_summary":true,"archetype":"regular","last_poster_username":"sam","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":8820},{"extras":null,"description":"Frequent Poster","user_id":6746},{"extras":null,"description":"Frequent Poster","user_id":9909},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":17727,"title":"Compliance with EU Cookie Law","fancy_title":"Compliance with EU Cookie Law","slug":"compliance-with-eu-cookie-law","posts_count":46,"reply_count":32,"highest_post_number":46,"image_url":null,"created_at":"2014-07-18T17:39:38.499-04:00","last_posted_at":"2014-07-26T18:01:33.751-04:00","bumped":true,"bumped_at":"2014-07-26T18:01:33.751-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":836,"like_count":48,"has_summary":false,"archetype":"regular","last_poster_username":"node","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":11003},{"extras":null,"description":"Frequent Poster","user_id":11017},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":9536}]},{"id":15336,"title":"Switch from Gravatar to HTML/CSS letters for no-avatar users","fancy_title":"Switch from Gravatar to HTML/CSS letters for no-avatar users","slug":"switch-from-gravatar-to-html-css-letters-for-no-avatar-users","posts_count":39,"reply_count":25,"highest_post_number":39,"image_url":"/uploads/default/_optimized/d29/bc1/25fa89ae0a_415x500.png","created_at":"2014-05-05T18:46:02.221-04:00","last_posted_at":"2014-05-28T18:07:12.448-04:00","bumped":true,"bumped_at":"2014-05-28T18:07:09.701-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":1011,"like_count":63,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":26,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":8571},{"extras":null,"description":"Frequent Poster","user_id":8344}]},{"id":12957,"title":"Discourse for iOS","fancy_title":"Discourse for iOS","slug":"discourse-for-ios","posts_count":43,"reply_count":24,"highest_post_number":43,"image_url":"http://a4.mzstatic.com/us/r30/Purple/v4/8d/85/93/8d859353-625c-8abc-5c00-36be5f293709/mzl.luwjaamb.png","created_at":"2014-02-21T20:37:44.606-05:00","last_posted_at":"2014-08-20T15:09:19.767-04:00","bumped":true,"bumped_at":"2014-08-20T15:09:19.767-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1082,"like_count":48,"has_summary":false,"archetype":"regular","last_poster_username":"erlend_sh","category_id":5,"posters":[{"extras":null,"description":"Original Poster","user_id":8399},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":10949},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":5351}]},{"id":14973,"title":"Symbol for like - why is it a heart?","fancy_title":"Symbol for like - why is it a heart?","slug":"symbol-for-like-why-is-it-a-heart","posts_count":29,"reply_count":14,"highest_post_number":29,"image_url":null,"created_at":"2014-04-22T12:24:22.822-04:00","last_posted_at":"2014-05-08T17:41:27.803-04:00","bumped":true,"bumped_at":"2014-05-08T17:41:27.803-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1421,"like_count":73,"has_summary":false,"archetype":"regular","last_poster_username":"Frank","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":9664},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":9931}]},{"id":16875,"title":"Options to disable hijack of CMD+F / CTRL+F and \"/\" keys for search?","fancy_title":"Options to disable hijack of CMD+F / CTRL+F and “/” keys for search?","slug":"options-to-disable-hijack-of-cmd-f-ctrl-f-and-keys-for-search","posts_count":44,"reply_count":36,"highest_post_number":44,"image_url":null,"created_at":"2014-06-25T17:04:48.413-04:00","last_posted_at":"2014-08-25T04:01:38.132-04:00","bumped":true,"bumped_at":"2014-08-25T04:01:38.132-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":541,"like_count":41,"has_summary":false,"archetype":"regular","last_poster_username":"RabidFX","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":10470},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":"latest","description":"Most Recent Poster","user_id":10548}]},{"id":9975,"title":"Translators We Want You!","fancy_title":"Translators We Want You!","slug":"translators-we-want-you","posts_count":50,"reply_count":28,"highest_post_number":50,"image_url":null,"created_at":"2013-09-23T13:47:39.521-04:00","last_posted_at":"2014-03-16T16:21:13.891-04:00","bumped":true,"bumped_at":"2014-03-16T16:21:13.891-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1262,"like_count":26,"has_summary":true,"archetype":"regular","last_poster_username":"Torrelles","category_id":27,"posters":[{"extras":null,"description":"Original Poster","user_id":4983},{"extras":null,"description":"Frequent Poster","user_id":7074},{"extras":null,"description":"Frequent Poster","user_id":7502},{"extras":null,"description":"Frequent Poster","user_id":5609},{"extras":"latest","description":"Most Recent Poster","user_id":8059}]},{"id":12112,"title":"The system user needs a cool avatar","fancy_title":"The system user needs a cool avatar","slug":"the-system-user-needs-a-cool-avatar","posts_count":35,"reply_count":24,"highest_post_number":35,"image_url":"/uploads/default/31460/c596ef65a9d0533c.png","created_at":"2014-01-21T22:26:01.574-05:00","last_posted_at":"2014-01-31T16:54:22.261-05:00","bumped":true,"bumped_at":"2014-01-31T16:54:22.261-05:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":848,"like_count":55,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":8105},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":11718,"title":"Reply button while logged out","fancy_title":"Reply button while logged out","slug":"reply-button-while-logged-out","posts_count":46,"reply_count":42,"highest_post_number":46,"image_url":null,"created_at":"2014-01-02T17:11:14.130-05:00","last_posted_at":"2014-04-05T10:20:11.921-04:00","bumped":true,"bumped_at":"2014-04-05T10:20:11.921-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":830,"like_count":32,"has_summary":false,"archetype":"regular","last_poster_username":"apere006","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":8072},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":9497},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":471}]},{"id":18698,"title":"Site setting for sending analytics data to Discourse.org","fancy_title":"Site setting for sending analytics data to Discourse.org","slug":"site-setting-for-sending-analytics-data-to-discourse-org","posts_count":27,"reply_count":18,"highest_post_number":27,"image_url":null,"created_at":"2014-08-10T11:47:04.016-04:00","last_posted_at":"2014-08-11T15:36:21.664-04:00","bumped":true,"bumped_at":"2014-08-11T15:36:04.020-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":135,"like_count":72,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":17443,"title":"Can I Keep Nofollow for All User Links, Including from Trust Level 3?","fancy_title":"Can I Keep Nofollow for All User Links, Including from Trust Level 3?","slug":"can-i-keep-nofollow-for-all-user-links-including-from-trust-level-3","posts_count":40,"reply_count":30,"highest_post_number":41,"image_url":null,"created_at":"2014-07-10T22:06:49.357-04:00","last_posted_at":"2014-07-14T19:20:37.014-04:00","bumped":true,"bumped_at":"2014-07-14T19:20:37.014-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":237,"like_count":42,"has_summary":false,"archetype":"regular","last_poster_username":"cpradio","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5017},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":8300}]},{"id":18821,"title":"Suggestion: # of likes in a topic in the tool tip","fancy_title":"Suggestion: # of likes in a topic in the tool tip","slug":"suggestion-of-likes-in-a-topic-in-the-tool-tip","posts_count":27,"reply_count":22,"highest_post_number":27,"image_url":null,"created_at":"2014-08-13T15:23:46.745-04:00","last_posted_at":"2014-08-15T07:40:57.684-04:00","bumped":true,"bumped_at":"2014-08-15T07:40:57.684-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":133,"like_count":68,"has_summary":false,"archetype":"regular","last_poster_username":"boomzilla","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":11163},{"extras":null,"description":"Frequent Poster","user_id":11265},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8493},{"extras":"latest","description":"Most Recent Poster","user_id":11160}]},{"id":9741,"title":"Difference between Reddit and Discourse","fancy_title":"Difference between Reddit and Discourse","slug":"difference-between-reddit-and-discourse","posts_count":42,"reply_count":32,"highest_post_number":42,"image_url":null,"created_at":"2013-09-11T22:17:39.971-04:00","last_posted_at":"2013-09-17T19:01:36.139-04:00","bumped":true,"bumped_at":"2013-09-17T19:01:36.139-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":3303,"like_count":35,"has_summary":false,"archetype":"regular","last_poster_username":"anotherchris","category_id":3,"posters":[{"extras":null,"description":"Original Poster","user_id":5105},{"extras":null,"description":"Frequent Poster","user_id":1353},{"extras":null,"description":"Frequent Poster","user_id":5851},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":2520}]},{"id":12156,"title":"Beginners Guide to Deploy Discourse on DigitalOcean using Docker","fancy_title":"Beginners Guide to Deploy Discourse on DigitalOcean using Docker","slug":"beginners-guide-to-deploy-discourse-on-digital-ocean-using-docker","posts_count":28,"reply_count":157,"highest_post_number":219,"image_url":"http://www.discourse.org/images/install/droplet-step-1.png","created_at":"2014-01-23T14:58:17.918-05:00","last_posted_at":"2014-08-26T10:06:25.833-04:00","bumped":true,"bumped_at":"2014-08-26T10:06:25.833-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":10112,"like_count":63,"has_summary":false,"archetype":"regular","last_poster_username":"cawas","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":8222},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":8364},{"extras":"latest","description":"Most Recent Poster","user_id":5249}]},{"id":12522,"title":"Permission Changes (moderators have less)","fancy_title":"Permission Changes (moderators have less)","slug":"permission-changes-moderators-have-less","posts_count":42,"reply_count":30,"highest_post_number":43,"image_url":null,"created_at":"2014-02-06T22:34:05.332-05:00","last_posted_at":"2014-08-01T12:26:40.440-04:00","bumped":true,"bumped_at":"2014-08-01T12:26:40.440-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1806,"like_count":37,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":10291,"title":"CAS sso auth plugin","fancy_title":"CAS sso auth plugin","slug":"cas-sso-auth-plugin","posts_count":48,"reply_count":32,"highest_post_number":51,"image_url":null,"created_at":"2013-10-09T17:01:21.524-04:00","last_posted_at":"2014-08-27T16:08:25.417-04:00","bumped":true,"bumped_at":"2014-08-27T16:08:25.417-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1433,"like_count":20,"has_summary":false,"archetype":"regular","last_poster_username":"eriko","category_id":22,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5160},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4220},{"extras":null,"description":"Frequent Poster","user_id":3704},{"extras":null,"description":"Frequent Poster","user_id":32}]},{"id":16877,"title":"Discourse V1.0 Next Month","fancy_title":"Discourse V1.0 Next Month","slug":"discourse-v1-0-next-month","posts_count":25,"reply_count":11,"highest_post_number":26,"image_url":null,"created_at":"2014-06-25T18:54:32.020-04:00","last_posted_at":"2014-08-14T13:07:09.405-04:00","bumped":true,"bumped_at":"2014-08-14T13:07:09.405-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1113,"like_count":65,"has_summary":false,"archetype":"regular","last_poster_username":"Dan_G","category_id":13,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":null,"description":"Frequent Poster","user_id":8944},{"extras":null,"description":"Frequent Poster","user_id":10920},{"extras":"latest","description":"Most Recent Poster","user_id":11455}]},{"id":18257,"title":"Move the new/unread counters to the first column in topic list","fancy_title":"Move the new/unread counters to the first column in topic list","slug":"move-the-new-unread-counters-to-the-first-column-in-topic-list","posts_count":32,"reply_count":25,"highest_post_number":32,"image_url":null,"created_at":"2014-07-30T02:33:42.679-04:00","last_posted_at":"2014-08-01T12:33:11.694-04:00","bumped":true,"bumped_at":"2014-08-01T12:33:11.694-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":217,"like_count":51,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13249,"title":"Syncing the editor viewport scroll","fancy_title":"Syncing the editor viewport scroll","slug":"syncing-the-editor-viewport-scroll","posts_count":35,"reply_count":15,"highest_post_number":35,"image_url":null,"created_at":"2014-02-28T19:03:57.708-05:00","last_posted_at":"2014-04-06T21:04:59.528-04:00","bumped":true,"bumped_at":"2014-04-06T21:04:59.528-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":980,"like_count":44,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6808},{"extras":null,"description":"Frequent Poster","user_id":8933},{"extras":null,"description":"Frequent Poster","user_id":19},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":9711,"title":"Now testing: mobile (small screen) layouts on key pages","fancy_title":"Now testing: mobile (small screen) layouts on key pages","slug":"now-testing-mobile-small-screen-layouts-on-key-pages","posts_count":43,"reply_count":31,"highest_post_number":51,"image_url":"/uploads/meta_discourse/1787/beb2b60fba4c46c3.png","created_at":"2013-09-10T19:45:51.532-04:00","last_posted_at":"2014-02-05T02:03:24.974-05:00","bumped":true,"bumped_at":"2014-02-05T13:45:55.088-05:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1635,"like_count":27,"has_summary":false,"archetype":"regular","last_poster_username":"iainb","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2},{"extras":null,"description":"Frequent Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":7604},{"extras":"latest","description":"Most Recent Poster","user_id":1783}]},{"id":15048,"title":"Linking a Discourse User db with a Mumble server (Murmur)","fancy_title":"Linking a Discourse User db with a Mumble server (Murmur)","slug":"linking-a-discourse-user-db-with-a-mumble-server-murmur","posts_count":48,"reply_count":40,"highest_post_number":48,"image_url":null,"created_at":"2014-04-24T18:30:17.568-04:00","last_posted_at":"2014-05-30T20:43:13.387-04:00","bumped":true,"bumped_at":"2014-05-30T20:43:13.387-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":625,"like_count":17,"has_summary":false,"archetype":"regular","last_poster_username":"Vocino","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":9371},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6613}]},{"id":17945,"title":"Unread/new badge style?","fancy_title":"Unread/new badge style?","slug":"unread-new-badge-style","posts_count":35,"reply_count":23,"highest_post_number":35,"image_url":"/uploads/default/_optimized/b61/a61/3508713cc1_690x202.png","created_at":"2014-07-23T10:49:18.864-04:00","last_posted_at":"2014-07-28T13:52:16.773-04:00","bumped":true,"bumped_at":"2014-07-28T13:52:16.773-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":279,"like_count":43,"has_summary":false,"archetype":"regular","last_poster_username":"Mittineague","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":8617}]},{"id":16803,"title":"Auto-hide persistent fixed header on scroll","fancy_title":"Auto-hide persistent fixed header on scroll","slug":"auto-hide-persistent-fixed-header-on-scroll","posts_count":39,"reply_count":27,"highest_post_number":39,"image_url":null,"created_at":"2014-06-23T13:25:32.523-04:00","last_posted_at":"2014-07-07T10:45:40.399-04:00","bumped":true,"bumped_at":"2014-07-07T10:45:40.399-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":792,"like_count":34,"has_summary":false,"archetype":"regular","last_poster_username":"mcwumbly","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":10632},{"extras":null,"description":"Frequent Poster","user_id":438},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":4263}]},{"id":15858,"title":"Configuring Google OAuth2 login for Discourse","fancy_title":"Configuring Google OAuth2 login for Discourse","slug":"configuring-google-oauth2-login-for-discourse","posts_count":36,"reply_count":24,"highest_post_number":40,"image_url":"/uploads/default/_optimized/9ae/174/5a30a33f56_690x399.png","created_at":"2014-05-21T18:46:55.403-04:00","last_posted_at":"2014-08-17T15:30:40.593-04:00","bumped":true,"bumped_at":"2014-08-17T15:29:45.558-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":5257,"like_count":41,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":2},{"extras":null,"description":"Frequent Poster","user_id":9726},{"extras":null,"description":"Frequent Poster","user_id":3675},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":32}]}]}}}; diff --git a/test/javascripts/fixtures/user_fixtures.js.es6 b/test/javascripts/fixtures/user_fixtures.js.es6 index a84974b6959..c123605c3a3 100644 --- a/test/javascripts/fixtures/user_fixtures.js.es6 +++ b/test/javascripts/fixtures/user_fixtures.js.es6 @@ -1,6 +1,6 @@ /*jshint maxlen:10000000 */ export default { -"/users/eviltrout.json": {"user_badges":[{"id":5870,"granted_at":"2014-05-16T02:39:38.388Z","badge_id":4,"user_id":19,"granted_by_id":-1},{"id":40673,"granted_at":"2014-03-31T14:23:18.060Z","post_id":7241,"post_number":19,"badge_id":23,"user_id":19,"granted_by_id":-1,"topic_id":3153},{"id":5868,"granted_at":"2014-05-16T02:39:38.380Z","badge_id":3,"user_id":19,"granted_by_id":-1}],"badges":[{"id":4,"name":"Leader","description":null,"grant_count":7,"allow_title":true,"multiple_grant":false,"icon":"fa-user","image":null,"listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":1},{"id":23,"name":"Great Share","description":null,"grant_count":14,"allow_title":false,"multiple_grant":true,"icon":"fa-certificate","image":null,"listable":true,"enabled":true,"badge_grouping_id":2,"system":true,"badge_type_id":1},{"id":3,"name":"Regular","description":null,"grant_count":30,"allow_title":true,"multiple_grant":false,"icon":"fa-user","image":null,"listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":2}],"badge_types":[{"id":1,"name":"Gold","sort_order":9},{"id":2,"name":"Silver","sort_order":8},{"id":3,"name":"Bronze","sort_order":7}],"users":[{"id":19,"username":"eviltrout","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eviltrout/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png"},{"id":-1,"username":"system","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/system/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png"}],"topics":[{"id":3153,"title":"Is it better for Discourse to use JavaScript or CoffeeScript?","fancy_title":"Is it better for Discourse to use JavaScript or CoffeeScript?","slug":"is-it-better-for-discourse-to-use-javascript-or-coffeescript","posts_count":56}],"user":{"id":19,"username":"eviltrout","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eviltrout/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png","name":"Robin Ward","email":"robin.ward@gmail.com","last_posted_at":"2015-05-07T15:23:35.074Z","last_seen_at":"2015-05-13T14:34:23.188Z","bio_raw":"Co-founder of Discourse. Previously, I created Forumwarz. Follow me on Twitter.","bio_cooked":"

    Co-founder of Discourse. Previously, I created Forumwarz. Follow me on Twitter.

    ","created_at":"2013-02-03T15:19:22.704Z","website":"http://eviltrout.com","location":"Toronto","can_edit":false,"can_edit_username":true,"can_edit_email":true,"can_edit_name":true,"stats":[{"action_type":13,"count":342,"id":null},{"action_type":12,"count":109,"id":null},{"action_type":4,"count":27,"id":null},{"action_type":5,"count":1607,"id":null},{"action_type":6,"count":771,"id":null},{"action_type":1,"count":333,"id":null},{"action_type":2,"count":2671,"id":null},{"action_type":7,"count":949,"id":null},{"action_type":9,"count":42,"id":null},{"action_type":3,"count":8,"id":null},{"action_type":11,"count":20,"id":null}],"can_send_private_messages":true,"can_send_private_message_to_user":false,"bio_excerpt":"Co-founder of Discourse. Previously, I created Forumwarz. Follow me on Twitter.","trust_level":4,"moderator":true,"admin":true,"title":"co-founder","badge_count":23,"notification_count":3244,"has_title_badges":true,"custom_fields":{},"user_fields":{"1":"33"},"pending_count":0,"post_count":1987,"can_be_deleted":false,"can_delete_all_posts":false,"locale":"","email_digests":true,"email_private_messages":true,"email_direct":true,"email_always":true,"digest_after_days":7,"mailing_list_mode":false,"auto_track_topics_after_msecs":60000,"new_topic_duration_minutes":1440,"external_links_in_new_tab":false,"dynamic_favicon":true,"enable_quoting":true,"muted_category_ids":[],"tracked_category_ids":[],"watched_category_ids":[3],"private_messages_stats":{"all":101,"mine":13,"unread":3},"disable_jump_reply":false,"gravatar_avatar_upload_id":5275,"custom_avatar_upload_id":1573,"card_image_badge":"https://meta-discourse.global.ssl.fastly.net/uploads/default/36220/15b19c80dd99d5a5.png","card_image_badge_id":120,"muted_usernames":[],"invited_by":{"id":1,"username":"sam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sam/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png"},"custom_groups":[{"id":44,"automatic":false,"name":"ubuntu","user_count":11,"alias_level":0,"visible":true,"automatic_membership_email_domains":null,"automatic_membership_retroactive":false,"primary_group":false,"title":null},{"id":47,"automatic":false,"name":"discourse","user_count":7,"alias_level":0,"visible":true,"automatic_membership_email_domains":null,"automatic_membership_retroactive":false,"primary_group":false,"title":null}],"featured_user_badge_ids":[5870,40673,5868],"card_badge":{"id":120,"name":"Garbage Man","description":"This Discourse developer successfully called something \"garbage!\"","grant_count":3,"allow_title":false,"multiple_grant":false,"icon":"https://meta-discourse.global.ssl.fastly.net/uploads/default/36220/15b19c80dd99d5a5.png","image":"https://meta-discourse.global.ssl.fastly.net/uploads/default/36220/15b19c80dd99d5a5.png","listable":false,"enabled":false,"badge_grouping_id":8,"system":false,"badge_type_id":3}}}, -"/user_actions.json": {"user_actions":[{"action_type":7,"created_at":"2014-01-16T14:13:05Z","excerpt":"So again, \n\nWhat is the problem?\n\nI need to check user_trust_level , i get the 'username' from a form via ajax, i need to check what level he is on discourse \n\nAlso, if possible, i would like to get other details as well, like email address etc. \n\nI took a look at : https://github.com/discourse/dis…","avatar_template":"//www.gravatar.com/avatar/bdab7e61b3191e483492fd680f563fed.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/bdab7e61b3191e483492fd680f563fed.png?s={size}&r=pg&d=identicon","slug":"how-to-check-the-user-level-via-ajax","topic_id":11993,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"Abhishek_Gupta","name":"Abhishek Gupta","user_id":8021,"acting_username":"Abhishek_Gupta","acting_name":"Abhishek Gupta","acting_user_id":8021,"title":"How to check the user level via ajax?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-15T16:53:49Z","excerpt":"A good fix would be to have the ERB template do an if statement. We'd happily accept a PR that did this if you feel up to it: \n\n <% if SiteSetting.logo_url.present? %>\n display logo html\n<% else %>\n display title html\n<% end %>","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","topic_id":10911,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-15T15:21:37Z","excerpt":"A good fix would be to have the ERB template do an if statement. We'd happily accept a PR that did this if you feel up to it: \n\n <% if SiteSetting.logo_url.present? %>\n display logo html\n<% else %>\n display title html\n<% end %>","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","topic_id":10911,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-15T12:22:12Z","excerpt":"OK - i see what you mean. From the piwik code I should add: \n\n_paq.push(["setDocumentTitle", document.domain + "/" + document.title]);\n\n? \n\nUnfortunately I have had to give up on Piwik for now because I have switched the forum to SSL on a free cert and have used up the free subdomain for the forum. …","avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":26,"reply_to_post_number":25,"username":"citkane","name":"Michael Jonker","user_id":7604,"acting_username":"citkane","acting_name":"Michael Jonker","acting_user_id":7604,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T11:16:36Z","excerpt":"@eviltrout recently added support for multiple API keys [wink] \n\n[]","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"allow-for-multiple-api-keys","topic_id":7444,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Allow for multiple API Keys","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T10:58:46Z","excerpt":"@eviltrout added a tooltip when you click on the user's avatar which allows you to show the posts made by that user \n\n[image]","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"to-group-posts-by-a-user","topic_id":7412,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":3,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"To group posts by a user","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T10:36:15Z","excerpt":"@eviltrout implemented per-user API key a while ago [wink] \n\n [image]\nTopics_-_Discourse_Meta-5.png884x339 29.6 KB\n","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"auth-using-rest-api","topic_id":5937,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Auth using REST API?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T09:55:17Z","excerpt":"@eviltrout has recently introduced this feature and has even blogged about it: \n\n \n \n \n \n eviltrout.com\n \n \n \n \n \n Hiding Offscreen Content in Ember.js - Evil Trout's Blog","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"infinite-scrolling-reusing-dom-nodes","topic_id":5186,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Infinite scrolling: Reusing DOM nodes","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-15T00:54:32Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:59:51Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"znation","acting_name":"znation","acting_user_id":8163,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:46:50Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T21:43:28Z","excerpt":"Thanks for your help @eviltrout! I will consider making that change and sending a pull request. I may not get to it for a while. \n\nI am embedding Discourse on another site and it is mostly going well. I have indeed been using your blog for inspiration.","avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"znation","name":"znation","user_id":8163,"acting_username":"znation","acting_name":"znation","acting_user_id":8163,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:21:52Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T21:03:07Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T20:42:51Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T20:29:23Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T19:20:28Z","excerpt":"Perhaps the ['trackpageView'] is not the correct API call? We can probably send more information across such as the URL.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":25,"reply_to_post_number":24,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T19:19:46Z","excerpt":"Nope but I bet you can find one!","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":3,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T18:37:05Z","excerpt":"I'd be glad to write a pull request to take use there. Is there a specific part of their documentation you have in mind?","avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"watchmanmonitor","name":"Watchman Monitoring","user_id":8085,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T16:04:28Z","excerpt":"Thanks @eviltrout , the code in the 'bottom of pages' now reads: \n\n<script type="text/javascript">\nDiscourse.PageTracker.current().on('change', function() {\n console.log('tracked!')\n _paq.push(['trackPageView']);\n});\n</script>\n\nThe console is logging 'tracked!' and piwik is logging for each page c…","avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":23,"reply_to_post_number":22,"username":"citkane","name":"Michael Jonker","user_id":7604,"acting_username":"citkane","acting_name":"Michael Jonker","acting_user_id":7604,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T15:58:27Z","excerpt":"This topic is now archived. It is frozen and cannot be changed in any way.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"regression-cannot-sort-topic-list","topic_id":11944,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Regression: Cannot sort topic list","deleted":false,"hidden":false,"moderator_action":true,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T15:26:57Z","excerpt":"I do think that leading them into the official rails documentation at that point is not a bad idea. Like "congratulations, everything is ready but now you'll need to understand the platform we built it in to be productive."","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T08:28:00Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-14T00:21:26Z","excerpt":"In pull request 1821, @eviltrout asked: \n\n "About rails s: I wouldn't be against adding it but at what point do we stop holding their hand and expect them to know how rails works? I'm sure rails documentation could do a better job than us. Actually maybe we should just link to that? \n\nWhat point to …","avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"watchmanmonitor","name":"Watchman Monitoring","user_id":8085,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-13T21:58:28Z","excerpt":"It looks uneeded, but you need to review a fair amount of code to confirm it is not needed. \n\nI am going to keep it for now cause its safer under some weird edge conditions.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"ruby-question-about-use-of-klass-self-in-the-site-customization-rb","topic_id":11889,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Ruby question about use of klass=self in the site_customization.rb","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T21:11:32Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-13T21:10:57Z","excerpt":"Having a look, the fix is a bit scary imho, we should fix the root issue.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":11,"reply_to_post_number":10,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T20:50:34Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//localhost:3000/uploads/default/avatars/527/614/d16e1504d9/{size}.jpg","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"trident","acting_name":"Ben T","acting_user_id":5707,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T20:44:56Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T20:40:21Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T19:52:04Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T19:01:19Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T18:50:14Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T18:47:33Z","excerpt":"I am pretty sure that the denizens of SO are correct and the variable is unneeded. @sam can confirm but it seems like it was once needed for something that has since been removed and the variable declaration was left intact.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"ruby-question-about-use-of-klass-self-in-the-site-customization-rb","topic_id":11889,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Ruby question about use of klass=self in the site_customization.rb","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T18:45:41Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T17:19:08Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T16:41:31Z","excerpt":"I'd love to see API support. @sam and @eviltrout, I can facilitate an intro to the piwik guys if you want—I've written about them before and they're typically super-responsive. Because I know you guys are totally hunting for new stuff to do [wink]","avatar_template":"//localhost:3000/uploads/default/avatars/95a/06d/c337428568/{size}.png","acting_avatar_template":"//localhost:3000/uploads/default/avatars/95a/06d/c337428568/{size}.png","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":20,"reply_to_post_number":null,"username":"Lee_Ars","name":"Lee_Ars","user_id":4457,"acting_username":"Lee_Ars","acting_name":"Lee_Ars","acting_user_id":4457,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T16:15:51Z","excerpt":"The code looks okay but it's hard to debug this way. \n\nOne thing you could do is add a: console.log('tracked!') just before line 8. Then open a developer console and see if the javascript is running properly.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T15:10:41Z","excerpt":"This is really interesting. I'd like to hear your findings.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"focus-events-track-which-window-is-the-last-active-instance-of-a-forum-edit","topic_id":11872,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":9,"reply_to_post_number":8,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Focus events: Track which window is the last active instance of a forum Edit","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T15:02:45Z","excerpt":"The code looks okay but it's hard to debug this way. \n\nOne thing you could do is add a: console.log('tracked!') just before line 8. Then open a developer console and see if the javascript is running properly.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T14:53:13Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T06:27:26Z","excerpt":"Can this be archived @eviltrout?","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"search-not-working-for-staff-users","topic_id":11371,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":13,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Search not working for Staff users","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T05:32:46Z","excerpt":"When you navigate to another topic using the "suggested topics" area we are not registering a page view with Google. \n\n@eviltrout perhaps we should do this from discourse location instead of application controller?","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"google-analytics-is-not-registering-page-views","topic_id":11914,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Google analytics is not registering page views","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T02:50:25Z","excerpt":"@eviltrout any ideas here, the code seems correct","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":17,"reply_to_post_number":16,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-12T22:31:35Z","excerpt":"This is an interesting approach an an interesting feature. @eviltrout your thoughts. Essentially allows us to have notifications cross tabs.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"focus-events-track-which-window-is-the-last-active-instance-of-a-forum-edit","topic_id":11872,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":1,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Focus events: Track which window is the last active instance of a forum Edit","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-12T18:01:04Z","excerpt":"This was the link \n\nmetric_fu \n\n[metric_fu](https://github.com/metricfu/metric_fu/blob/b1bf8feb921916fc265f041efa3157a6a6530a9b/lib/metric_fu/logging/mf_debugger.rb#L24)\n\nSeems to work fine now that @eviltrout worked so hard to get us MDTest 1.1 compliant.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"underscores-in-linked-text-can-cause-markdown-bug","topic_id":10848,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Underscores in linked text can cause markdown bug","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-12T04:14:06Z","excerpt":"Awesome plugin, but doesn't seem to work out of the box with images \n\nhttps://github.com/discourse/discourse-spoiler-alert/issues/2","avatar_template":"//localhost:3000/uploads/default/avatars/276/f19/3826efe463/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/276/f19/3826efe463/{size}.jpg","slug":"brand-new-plugin-interface","topic_id":8793,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":64,"reply_to_post_number":44,"username":"xrvk","name":"Eero Heikkinen","user_id":8068,"acting_username":"xrvk","acting_name":"Eero Heikkinen","acting_user_id":8068,"title":"Brand new plugin interface","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T23:36:11Z","excerpt":"A few things, \n\n@eviltrout myself and many others have discourse_docker hosted on digital ocean, my user cpu is usually around 2% I have plenty of capacity. \n\nI know that stonehearth and other larger scale discourse work on digital ocean fine. Officially we strongly recommend a 2GB instance, thoug…","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"performance-issue-on-digital-ocean-with-discourse-docker","topic_id":11895,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Performance issue on Digital Ocean with discourse_docker","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:58:23Z","excerpt":"Confirmed on try.discourse.org, this is still an issue. \n\n@eviltrout can you add that to your list -- unless you are a staff member you should not be able to delete (your own) posts from an archived topic.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"archived-discussions-still-allow-posts-to-be-deleted","topic_id":6479,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Archived discussions still allow posts to be deleted","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:35:38Z","excerpt":"Agree, @eviltrout can you make sure the usercard is using the same logic as the user page in displaying profile info?","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"usercard-does-not-resize-for-obnoxiously-large-images","topic_id":11007,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":4,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Usercard does not resize for obnoxiously large images","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:34:06Z","excerpt":"@eviltrout can you make sure the "import post" button is suppressed on the user page when editing "about me"? \n\n(I agree it is like a "lose all my work" button on that page if you happen to press it..) \n\nThen I can archive this.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"quote-post-button-should-be-disabled-or-raise-an-error-when-creating-a-new-topic","topic_id":834,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":4,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"\"Quote Post\" button should be disabled or raise an error when creating a new topic","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-10T21:00:11Z","excerpt":">\n\nLooks good now. Thanks for these fixes @eviltrout, we (and markdown-js) are now MDTest 1.1 compliant!","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"text-editor-issue-with-the-code-block","topic_id":10050,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Text Editor issue with the code block","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":1,"created_at":"2014-01-10T20:07:46Z","excerpt":"We can't repro that one, also seems a bit obscure. But thank you very much for all the reports, whenever I see a bug entry from YOU I always know it is going to be a good one based on experience here and elsewhere. [trophy]","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"security-error-on-console-noticed-on-meta","topic_id":11825,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":12,"reply_to_post_number":11,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Security Error on console (noticed on meta)","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T19:48:08Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T19:47:17Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/42776c4982dff1fa45ee8248532f8ad0.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"neil","acting_name":"Neil","acting_user_id":2,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:39:24Z","excerpt":"We should consider doing what Google Drive does: they intercept cmd-f and pop up a box that allows you to dynamically search.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"ctrl-f-search-is-interrupted-by-quotation-popup","topic_id":7114,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":12,"reply_to_post_number":11,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Ctrl+F search is interrupted by quotation popup","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:29:15Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:24:37Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-10T17:02:35Z","excerpt":"Fixed [smile] \n\ntop - 12:02:00 up 12 days, 2:16, 1 user, load average: 0.28, 0.92, 0.97\nTasks: 115 total, 1 running, 114 sleeping, 0 stopped, 0 zombie\nCpu0 : 0.7%us, 0.3%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st\nCpu1 : 0.7%us, 0.3%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi,…","avatar_template":"//localhost:3000/uploads/default/avatars/886/ea8/e533d87fd9/{size}.png","acting_avatar_template":"//localhost:3000/uploads/default/avatars/886/ea8/e533d87fd9/{size}.png","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":23,"reply_to_post_number":22,"username":"michaeld","name":"Michael","user_id":6548,"acting_username":"michaeld","acting_name":"Michael","acting_user_id":6548,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T16:58:12Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//localhost:3000/uploads/default/avatars/527/614/d16e1504d9/{size}.jpg","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"trident","acting_name":"Ben T","acting_user_id":5707,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null}]}, +"/users/eviltrout.json": {"user_badges":[{"id":5870,"granted_at":"2014-05-16T02:39:38.388Z","badge_id":4,"user_id":19,"granted_by_id":-1},{"id":40673,"granted_at":"2014-03-31T14:23:18.060Z","post_id":7241,"post_number":19,"badge_id":23,"user_id":19,"granted_by_id":-1,"topic_id":3153},{"id":5868,"granted_at":"2014-05-16T02:39:38.380Z","badge_id":3,"user_id":19,"granted_by_id":-1}],"badges":[{"id":4,"name":"Leader","description":null,"grant_count":7,"allow_title":true,"multiple_grant":false,"icon":"fa-user","image":null,"listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":1},{"id":23,"name":"Great Share","description":null,"grant_count":14,"allow_title":false,"multiple_grant":true,"icon":"fa-certificate","image":null,"listable":true,"enabled":true,"badge_grouping_id":2,"system":true,"badge_type_id":1},{"id":3,"name":"Regular","description":null,"grant_count":30,"allow_title":true,"multiple_grant":false,"icon":"fa-user","image":null,"listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":2}],"badge_types":[{"id":1,"name":"Gold","sort_order":9},{"id":2,"name":"Silver","sort_order":8},{"id":3,"name":"Bronze","sort_order":7}],"users":[{"id":19,"username":"eviltrout","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eviltrout/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png"},{"id":-1,"username":"system","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/system/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png"}],"topics":[{"id":3153,"title":"Is it better for Discourse to use JavaScript or CoffeeScript?","fancy_title":"Is it better for Discourse to use JavaScript or CoffeeScript?","slug":"is-it-better-for-discourse-to-use-javascript-or-coffeescript","posts_count":56}],"user":{"user_option":{},"id":19,"username":"eviltrout","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eviltrout/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png","name":"Robin Ward","email":"robin.ward@gmail.com","last_posted_at":"2015-05-07T15:23:35.074Z","last_seen_at":"2015-05-13T14:34:23.188Z","bio_raw":"Co-founder of Discourse. Previously, I created Forumwarz. Follow me on Twitter.","bio_cooked":"

    Co-founder of Discourse. Previously, I created Forumwarz. Follow me on Twitter.

    ","created_at":"2013-02-03T15:19:22.704Z","website":"http://eviltrout.com","location":"Toronto","can_edit":false,"can_edit_username":true,"can_edit_email":true,"can_edit_name":true,"stats":[{"action_type":13,"count":342,"id":null},{"action_type":12,"count":109,"id":null},{"action_type":4,"count":27,"id":null},{"action_type":5,"count":1607,"id":null},{"action_type":6,"count":771,"id":null},{"action_type":1,"count":333,"id":null},{"action_type":2,"count":2671,"id":null},{"action_type":7,"count":949,"id":null},{"action_type":9,"count":42,"id":null},{"action_type":3,"count":8,"id":null},{"action_type":11,"count":20,"id":null}],"can_send_private_messages":true,"can_send_private_message_to_user":false,"bio_excerpt":"Co-founder of Discourse. Previously, I created Forumwarz. Follow me on Twitter.","trust_level":4,"moderator":true,"admin":true,"title":"co-founder","badge_count":23,"notification_count":3244,"has_title_badges":true,"custom_fields":{},"user_fields":{"1":"33"},"pending_count":0,"post_count":1987,"can_be_deleted":false,"can_delete_all_posts":false,"locale":"","email_digests":true,"email_private_messages":true,"email_direct":true,"email_always":true,"digest_after_minutes":10080,"mailing_list_mode":false,"auto_track_topics_after_msecs":60000,"new_topic_duration_minutes":1440,"external_links_in_new_tab":false,"dynamic_favicon":true,"enable_quoting":true,"muted_category_ids":[],"tracked_category_ids":[],"watched_category_ids":[3],"private_messages_stats":{"all":101,"mine":13,"unread":3},"disable_jump_reply":false,"gravatar_avatar_upload_id":5275,"custom_avatar_upload_id":1573,"card_image_badge":"https://meta-discourse.global.ssl.fastly.net/uploads/default/36220/15b19c80dd99d5a5.png","card_image_badge_id":120,"muted_usernames":[],"invited_by":{"id":1,"username":"sam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sam/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png"},"custom_groups":[{"id":44,"automatic":false,"name":"ubuntu","user_count":11,"alias_level":0,"visible":true,"automatic_membership_email_domains":null,"automatic_membership_retroactive":false,"primary_group":false,"title":null},{"id":47,"automatic":false,"name":"discourse","user_count":7,"alias_level":0,"visible":true,"automatic_membership_email_domains":null,"automatic_membership_retroactive":false,"primary_group":false,"title":null}],"featured_user_badge_ids":[5870,40673,5868],"card_badge":{"id":120,"name":"Garbage Man","description":"This Discourse developer successfully called something \"garbage!\"","grant_count":3,"allow_title":false,"multiple_grant":false,"icon":"https://meta-discourse.global.ssl.fastly.net/uploads/default/36220/15b19c80dd99d5a5.png","image":"https://meta-discourse.global.ssl.fastly.net/uploads/default/36220/15b19c80dd99d5a5.png","listable":false,"enabled":false,"badge_grouping_id":8,"system":false,"badge_type_id":3}}}, +"/user_actions.json": {"user_actions":[{"action_type":7,"created_at":"2014-01-16T14:13:05Z","excerpt":"So again, \n\nWhat is the problem?\n\nI need to check user_trust_level , i get the 'username' from a form via ajax, i need to check what level he is on discourse \n\nAlso, if possible, i would like to get other details as well, like email address etc. \n\nI took a look at : https://github.com/discourse/dis…","avatar_template":"//www.gravatar.com/avatar/bdab7e61b3191e483492fd680f563fed.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/bdab7e61b3191e483492fd680f563fed.png?s={size}&r=pg&d=identicon","slug":"how-to-check-the-user-level-via-ajax","topic_id":11993,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"Abhishek_Gupta","name":"Abhishek Gupta","user_id":8021,"acting_username":"Abhishek_Gupta","acting_name":"Abhishek Gupta","acting_user_id":8021,"title":"How to check the user level via ajax?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-15T16:53:49Z","excerpt":"A good fix would be to have the ERB template do an if statement. We'd happily accept a PR that did this if you feel up to it: \n\n <% if SiteSetting.logo_url.present? %>\n display logo html\n<% else %>\n display title html\n<% end %>","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","topic_id":10911,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-15T15:21:37Z","excerpt":"A good fix would be to have the ERB template do an if statement. We'd happily accept a PR that did this if you feel up to it: \n\n <% if SiteSetting.logo_url.present? %>\n display logo html\n<% else %>\n display title html\n<% end %>","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","topic_id":10911,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-15T12:22:12Z","excerpt":"OK - i see what you mean. From the piwik code I should add: \n\n_paq.push(["setDocumentTitle", document.domain + "/" + document.title]);\n\n? \n\nUnfortunately I have had to give up on Piwik for now because I have switched the forum to SSL on a free cert and have used up the free subdomain for the forum. …","avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":26,"reply_to_post_number":25,"username":"citkane","name":"Michael Jonker","user_id":7604,"acting_username":"citkane","acting_name":"Michael Jonker","acting_user_id":7604,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T11:16:36Z","excerpt":"@eviltrout recently added support for multiple API keys [wink] \n\n[]","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"allow-for-multiple-api-keys","topic_id":7444,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Allow for multiple API Keys","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T10:58:46Z","excerpt":"@eviltrout added a tooltip when you click on the user's avatar which allows you to show the posts made by that user \n\n[image]","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"to-group-posts-by-a-user","topic_id":7412,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":3,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"To group posts by a user","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T10:36:15Z","excerpt":"@eviltrout implemented per-user API key a while ago [wink] \n\n [image]\nTopics_-_Discourse_Meta-5.png884x339 29.6 KB\n","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"auth-using-rest-api","topic_id":5937,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Auth using REST API?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T09:55:17Z","excerpt":"@eviltrout has recently introduced this feature and has even blogged about it: \n\n \n \n \n \n eviltrout.com\n \n \n \n \n \n Hiding Offscreen Content in Ember.js - Evil Trout's Blog","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"infinite-scrolling-reusing-dom-nodes","topic_id":5186,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Infinite scrolling: Reusing DOM nodes","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-15T00:54:32Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:59:51Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"znation","acting_name":"znation","acting_user_id":8163,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:46:50Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T21:43:28Z","excerpt":"Thanks for your help @eviltrout! I will consider making that change and sending a pull request. I may not get to it for a while. \n\nI am embedding Discourse on another site and it is mostly going well. I have indeed been using your blog for inspiration.","avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"znation","name":"znation","user_id":8163,"acting_username":"znation","acting_name":"znation","acting_user_id":8163,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:21:52Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T21:03:07Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T20:42:51Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T20:29:23Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T19:20:28Z","excerpt":"Perhaps the ['trackpageView'] is not the correct API call? We can probably send more information across such as the URL.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":25,"reply_to_post_number":24,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T19:19:46Z","excerpt":"Nope but I bet you can find one!","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":3,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T18:37:05Z","excerpt":"I'd be glad to write a pull request to take use there. Is there a specific part of their documentation you have in mind?","avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"watchmanmonitor","name":"Watchman Monitoring","user_id":8085,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T16:04:28Z","excerpt":"Thanks @eviltrout , the code in the 'bottom of pages' now reads: \n\n<script type="text/javascript">\nDiscourse.PageTracker.current().on('change', function() {\n console.log('tracked!')\n _paq.push(['trackPageView']);\n});\n</script>\n\nThe console is logging 'tracked!' and piwik is logging for each page c…","avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":23,"reply_to_post_number":22,"username":"citkane","name":"Michael Jonker","user_id":7604,"acting_username":"citkane","acting_name":"Michael Jonker","acting_user_id":7604,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T15:58:27Z","excerpt":"This topic is now archived. It is frozen and cannot be changed in any way.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"regression-cannot-sort-topic-list","topic_id":11944,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Regression: Cannot sort topic list","deleted":false,"hidden":false,"moderator_action":true,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T15:26:57Z","excerpt":"I do think that leading them into the official rails documentation at that point is not a bad idea. Like "congratulations, everything is ready but now you'll need to understand the platform we built it in to be productive."","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T08:28:00Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-14T00:21:26Z","excerpt":"In pull request 1821, @eviltrout asked: \n\n "About rails s: I wouldn't be against adding it but at what point do we stop holding their hand and expect them to know how rails works? I'm sure rails documentation could do a better job than us. Actually maybe we should just link to that? \n\nWhat point to …","avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"watchmanmonitor","name":"Watchman Monitoring","user_id":8085,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-13T21:58:28Z","excerpt":"It looks uneeded, but you need to review a fair amount of code to confirm it is not needed. \n\nI am going to keep it for now cause its safer under some weird edge conditions.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"ruby-question-about-use-of-klass-self-in-the-site-customization-rb","topic_id":11889,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Ruby question about use of klass=self in the site_customization.rb","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T21:11:32Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-13T21:10:57Z","excerpt":"Having a look, the fix is a bit scary imho, we should fix the root issue.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":11,"reply_to_post_number":10,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T20:50:34Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//localhost:3000/uploads/default/avatars/527/614/d16e1504d9/{size}.jpg","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"trident","acting_name":"Ben T","acting_user_id":5707,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T20:44:56Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T20:40:21Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T19:52:04Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T19:01:19Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T18:50:14Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T18:47:33Z","excerpt":"I am pretty sure that the denizens of SO are correct and the variable is unneeded. @sam can confirm but it seems like it was once needed for something that has since been removed and the variable declaration was left intact.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"ruby-question-about-use-of-klass-self-in-the-site-customization-rb","topic_id":11889,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Ruby question about use of klass=self in the site_customization.rb","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T18:45:41Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T17:19:08Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T16:41:31Z","excerpt":"I'd love to see API support. @sam and @eviltrout, I can facilitate an intro to the piwik guys if you want—I've written about them before and they're typically super-responsive. Because I know you guys are totally hunting for new stuff to do [wink]","avatar_template":"//localhost:3000/uploads/default/avatars/95a/06d/c337428568/{size}.png","acting_avatar_template":"//localhost:3000/uploads/default/avatars/95a/06d/c337428568/{size}.png","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":20,"reply_to_post_number":null,"username":"Lee_Ars","name":"Lee_Ars","user_id":4457,"acting_username":"Lee_Ars","acting_name":"Lee_Ars","acting_user_id":4457,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T16:15:51Z","excerpt":"The code looks okay but it's hard to debug this way. \n\nOne thing you could do is add a: console.log('tracked!') just before line 8. Then open a developer console and see if the javascript is running properly.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T15:10:41Z","excerpt":"This is really interesting. I'd like to hear your findings.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"focus-events-track-which-window-is-the-last-active-instance-of-a-forum-edit","topic_id":11872,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":9,"reply_to_post_number":8,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Focus events: Track which window is the last active instance of a forum Edit","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T15:02:45Z","excerpt":"The code looks okay but it's hard to debug this way. \n\nOne thing you could do is add a: console.log('tracked!') just before line 8. Then open a developer console and see if the javascript is running properly.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T14:53:13Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T06:27:26Z","excerpt":"Can this be archived @eviltrout?","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"search-not-working-for-staff-users","topic_id":11371,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":13,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Search not working for Staff users","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T05:32:46Z","excerpt":"When you navigate to another topic using the "suggested topics" area we are not registering a page view with Google. \n\n@eviltrout perhaps we should do this from discourse location instead of application controller?","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"google-analytics-is-not-registering-page-views","topic_id":11914,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Google analytics is not registering page views","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T02:50:25Z","excerpt":"@eviltrout any ideas here, the code seems correct","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":17,"reply_to_post_number":16,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-12T22:31:35Z","excerpt":"This is an interesting approach an an interesting feature. @eviltrout your thoughts. Essentially allows us to have notifications cross tabs.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"focus-events-track-which-window-is-the-last-active-instance-of-a-forum-edit","topic_id":11872,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":1,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Focus events: Track which window is the last active instance of a forum Edit","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-12T18:01:04Z","excerpt":"This was the link \n\nmetric_fu \n\n[metric_fu](https://github.com/metricfu/metric_fu/blob/b1bf8feb921916fc265f041efa3157a6a6530a9b/lib/metric_fu/logging/mf_debugger.rb#L24)\n\nSeems to work fine now that @eviltrout worked so hard to get us MDTest 1.1 compliant.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"underscores-in-linked-text-can-cause-markdown-bug","topic_id":10848,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Underscores in linked text can cause markdown bug","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-12T04:14:06Z","excerpt":"Awesome plugin, but doesn't seem to work out of the box with images \n\nhttps://github.com/discourse/discourse-spoiler-alert/issues/2","avatar_template":"//localhost:3000/uploads/default/avatars/276/f19/3826efe463/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/276/f19/3826efe463/{size}.jpg","slug":"brand-new-plugin-interface","topic_id":8793,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":64,"reply_to_post_number":44,"username":"xrvk","name":"Eero Heikkinen","user_id":8068,"acting_username":"xrvk","acting_name":"Eero Heikkinen","acting_user_id":8068,"title":"Brand new plugin interface","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T23:36:11Z","excerpt":"A few things, \n\n@eviltrout myself and many others have discourse_docker hosted on DigitalOcean, my user cpu is usually around 2% I have plenty of capacity. \n\nI know that stonehearth and other larger scale discourse work on DigitalOcean fine. Officially we strongly recommend a 2GB instance, thoug…","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"performance-issue-on-digital-ocean-with-discourse-docker","topic_id":11895,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Performance issue on DigitalOcean with discourse_docker","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:58:23Z","excerpt":"Confirmed on try.discourse.org, this is still an issue. \n\n@eviltrout can you add that to your list -- unless you are a staff member you should not be able to delete (your own) posts from an archived topic.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"archived-discussions-still-allow-posts-to-be-deleted","topic_id":6479,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Archived discussions still allow posts to be deleted","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:35:38Z","excerpt":"Agree, @eviltrout can you make sure the usercard is using the same logic as the user page in displaying profile info?","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"usercard-does-not-resize-for-obnoxiously-large-images","topic_id":11007,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":4,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Usercard does not resize for obnoxiously large images","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:34:06Z","excerpt":"@eviltrout can you make sure the "import post" button is suppressed on the user page when editing "about me"? \n\n(I agree it is like a "lose all my work" button on that page if you happen to press it..) \n\nThen I can archive this.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"quote-post-button-should-be-disabled-or-raise-an-error-when-creating-a-new-topic","topic_id":834,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":4,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"\"Quote Post\" button should be disabled or raise an error when creating a new topic","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-10T21:00:11Z","excerpt":">\n\nLooks good now. Thanks for these fixes @eviltrout, we (and markdown-js) are now MDTest 1.1 compliant!","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"text-editor-issue-with-the-code-block","topic_id":10050,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Text Editor issue with the code block","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":1,"created_at":"2014-01-10T20:07:46Z","excerpt":"We can't repro that one, also seems a bit obscure. But thank you very much for all the reports, whenever I see a bug entry from YOU I always know it is going to be a good one based on experience here and elsewhere. [trophy]","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"security-error-on-console-noticed-on-meta","topic_id":11825,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":12,"reply_to_post_number":11,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Security Error on console (noticed on meta)","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T19:48:08Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T19:47:17Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/42776c4982dff1fa45ee8248532f8ad0.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"neil","acting_name":"Neil","acting_user_id":2,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:39:24Z","excerpt":"We should consider doing what Google Drive does: they intercept cmd-f and pop up a box that allows you to dynamically search.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"ctrl-f-search-is-interrupted-by-quotation-popup","topic_id":7114,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":12,"reply_to_post_number":11,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Ctrl+F search is interrupted by quotation popup","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:29:15Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:24:37Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-10T17:02:35Z","excerpt":"Fixed [smile] \n\ntop - 12:02:00 up 12 days, 2:16, 1 user, load average: 0.28, 0.92, 0.97\nTasks: 115 total, 1 running, 114 sleeping, 0 stopped, 0 zombie\nCpu0 : 0.7%us, 0.3%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st\nCpu1 : 0.7%us, 0.3%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi,…","avatar_template":"//localhost:3000/uploads/default/avatars/886/ea8/e533d87fd9/{size}.png","acting_avatar_template":"//localhost:3000/uploads/default/avatars/886/ea8/e533d87fd9/{size}.png","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":23,"reply_to_post_number":22,"username":"michaeld","name":"Michael","user_id":6548,"acting_username":"michaeld","acting_name":"Michael","acting_user_id":6548,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T16:58:12Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//localhost:3000/uploads/default/avatars/527/614/d16e1504d9/{size}.jpg","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"trident","acting_name":"Ben T","acting_user_id":5707,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null}]}, "/topics/created-by/eviltrout.json": {"users":[{"id":19,"username":"eviltrout","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon"},{"id":5460,"username":"ned","avatar_template":"//localhost:3000/uploads/default/avatars/06b/90d/3b3ea7e56b/{size}.png"},{"id":402,"username":"thebrianbarlow","avatar_template":"//www.gravatar.com/avatar/5ddf2459e8edd6cf52dfff6cb41ca70d.png?s={size}&r=pg&d=identicon"},{"id":5707,"username":"trident","avatar_template":"//localhost:3000/uploads/default/avatars/527/614/d16e1504d9/{size}.jpg"},{"id":32,"username":"codinghorror","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon"},{"id":1995,"username":"zogstrip","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon"},{"id":2702,"username":"ryanflorence","avatar_template":"//www.gravatar.com/avatar/749001c9fe6927c4b069a45c2a3d68f7.png?s={size}&r=pg&d=identicon"},{"id":9,"username":"tms","avatar_template":"//www.gravatar.com/avatar/3981cd271c302f5cba628c6b6d2b32ee.png?s={size}&r=pg&d=identicon"},{"id":1,"username":"sam","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon"},{"id":2636,"username":"lonnon","avatar_template":"//www.gravatar.com/avatar/9489ef302fbff6c19bba507d09f8cd1d.png?s={size}&r=pg&d=identicon"}],"topic_list":{"can_create_topic":false,"draft":null,"draft_key":"new_topic","draft_sequence":null,"topics":[{"id":7764,"title":"New: Reply via Email Support!","fancy_title":"New: Reply via Email Support!","slug":"new-reply-via-email-support","posts_count":32,"reply_count":24,"highest_post_number":35,"image_url":"/uploads/meta_discourse/1227/8f4e5818dfaa56c7.png","created_at":"2013-06-25T11:58:39.000-04:00","last_posted_at":"2014-01-09T18:53:06.000-05:00","bumped":true,"bumped_at":"2014-01-09T17:09:40.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":2201,"like_count":46,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":19},{"extras":null,"description":"Most Posts","user_id":5460},{"extras":null,"description":"Frequent Poster","user_id":402},{"extras":null,"description":"Frequent Poster","user_id":5707},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":9318,"title":"Discourse has a new Markdown Parser!","fancy_title":"Discourse has a new Markdown Parser!","slug":"discourse-has-a-new-markdown-parser","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-08-24T14:08:06.000-04:00","last_posted_at":"2013-08-24T14:08:06.000-04:00","bumped":true,"bumped_at":"2013-08-24T14:13:25.000-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":812,"like_count":13,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":19}]},{"id":7019,"title":"Discourse Ember Refactorings","fancy_title":"Discourse Ember Refactorings","slug":"discourse-ember-refactorings","posts_count":5,"reply_count":3,"highest_post_number":5,"image_url":null,"created_at":"2013-05-30T11:16:36.000-04:00","last_posted_at":"2013-06-02T11:22:58.000-04:00","bumped":true,"bumped_at":"2013-06-02T11:22:58.000-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":1075,"like_count":15,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":19},{"extras":null,"description":"Most Posts","user_id":1995},{"extras":null,"description":"Frequent Poster","user_id":2702}]},{"id":4650,"title":"Migrating off Active Record Observers","fancy_title":"Migrating off Active Record Observers","slug":"migrating-off-active-record-observers","posts_count":8,"reply_count":7,"highest_post_number":8,"image_url":null,"created_at":"2013-03-11T11:26:13.000-04:00","last_posted_at":"2013-05-14T18:40:16.000-04:00","bumped":true,"bumped_at":"2013-05-14T18:40:16.000-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":377,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":19},{"extras":null,"description":"Most Posts","user_id":9},{"extras":null,"description":"Frequent Poster","user_id":1995},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":4960,"title":"Vagrant Updates!","fancy_title":"Vagrant Updates!","slug":"vagrant-updates","posts_count":5,"reply_count":3,"highest_post_number":5,"image_url":"/plugins/emoji/images/fish.png","created_at":"2013-03-20T22:29:22.000-04:00","last_posted_at":"2013-03-21T19:06:40.000-04:00","bumped":true,"bumped_at":"2013-03-21T19:06:40.000-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":500,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":19},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":1995}]},{"id":2918,"title":"New: Updated Docs","fancy_title":"New: Updated Docs","slug":"new-updated-docs","posts_count":3,"reply_count":2,"highest_post_number":3,"image_url":null,"created_at":"2013-02-12T12:13:02.000-05:00","last_posted_at":"2013-02-15T17:57:19.000-05:00","bumped":true,"bumped_at":"2013-02-15T17:57:19.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":457,"like_count":10,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":10,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":19},{"extras":null,"description":"Most Posts","user_id":2636}]}]}} }; diff --git a/test/javascripts/helpers/component-test.js.es6 b/test/javascripts/helpers/component-test.js.es6 index 181ae533171..995fb476218 100644 --- a/test/javascripts/helpers/component-test.js.es6 +++ b/test/javascripts/helpers/component-test.js.es6 @@ -1,29 +1,36 @@ import AppEvents from 'discourse/lib/app-events'; import createStore from 'helpers/create-store'; +import { autoLoadModules } from 'discourse/initializers/auto-load-modules'; export default function(name, opts) { opts = opts || {}; test(name, function(assert) { - if (opts.setup) { - const store = createStore(); - opts.setup.call(this, store); - } const appEvents = AppEvents.create(); + this.site = Discourse.Site.current(); this.container.register('site-settings:main', Discourse.SiteSettings, { instantiate: false }); this.container.register('app-events:main', appEvents, { instantiate: false }); this.container.register('capabilities:main', Ember.Object); + this.container.register('site:main', this.site, { instantiate: false }); this.container.injection('component', 'siteSettings', 'site-settings:main'); this.container.injection('component', 'appEvents', 'app-events:main'); this.container.injection('component', 'capabilities', 'capabilities:main'); + this.container.injection('component', 'site', 'site:main'); - andThen(() => { - this.render(opts.template); - }); + this.siteSettings = Discourse.SiteSettings; - andThen(() => { - opts.test.call(this, assert); - }); + autoLoadModules(); + + if (opts.setup) { + const store = createStore(); + this.currentUser = Discourse.User.create(); + this.container.register('store:main', store, { instantiate: false }); + this.container.register('current-user:main', this.currentUser, { instantiate: false }); + opts.setup.call(this, store); + } + + andThen(() => this.render(opts.template)); + andThen(() => opts.test.call(this, assert)); }); } diff --git a/test/javascripts/helpers/create-pretender.js.es6 b/test/javascripts/helpers/create-pretender.js.es6 index 0b6f555294f..0aaad1ff901 100644 --- a/test/javascripts/helpers/create-pretender.js.es6 +++ b/test/javascripts/helpers/create-pretender.js.es6 @@ -1,3 +1,6 @@ +import storePretender from 'helpers/store-pretender'; +import fixturePretender from 'helpers/fixture-pretender'; + function parsePostData(query) { const result = {}; query.split("&").forEach(function(part) { @@ -25,61 +28,21 @@ function response(code, obj) { return [code, {"Content-Type": "application/json"}, obj]; } -function success() { - return response({ success: true }); -} +const success = () => response({ success: true }); +const loggedIn = () => !!Discourse.User.current(); -const _widgets = [ - {id: 123, name: 'Trout Lure'}, - {id: 124, name: 'Evil Repellant'} -]; -const _moreWidgets = [ - {id: 223, name: 'Bass Lure'}, - {id: 224, name: 'Good Repellant'} -]; - -const fruits = [{id: 1, name: 'apple', farmer_id: 1, color_ids: [1,2], category_id: 4}, - {id: 2, name: 'banana', farmer_id: 1, color_ids: [3], category_id: 3}, - {id: 3, name: 'grape', farmer_id: 2, color_ids: [2], category_id: 5}]; - -const farmers = [{id: 1, name: 'Old MacDonald'}, - {id: 2, name: 'Luke Skywalker'}]; - -const colors = [{id: 1, name: 'Red'}, - {id: 2, name: 'Green'}, - {id: 3, name: 'Yellow'}]; - -function loggedIn() { - return !!Discourse.User.current(); -} +const helpers = { response, success, parsePostData }; export default function() { const server = new Pretender(function() { + storePretender.call(this, helpers); + const fixturesByUrl = fixturePretender.call(this, helpers); - const fixturesByUrl = {}; + this.get('/admin/plugins', () => response({ plugins: [] })); - // Load any fixtures automatically - const self = this; - Ember.keys(require._eak_seen).forEach(function(entry) { - if (/^fixtures/.test(entry)) { - const fixture = require(entry, null, null, true); - if (fixture && fixture.default) { - const obj = fixture.default; - Ember.keys(obj).forEach(function(url) { - fixturesByUrl[url] = obj[url]; - self.get(url, function() { - return response(obj[url]); - }); - }); - } - } - }); - - this.get('/admin/plugins', () => { return response({ plugins: [] }); }); - - this.get('/composer-messages', () => { return response([]); }); + this.get('/composer-messages', () => response([])); this.get("/latest.json", () => { const json = fixturesByUrl['/latest.json']; @@ -101,27 +64,19 @@ export default function() { return response(json); }); - this.put('/users/eviltrout', () => { - return response({ user: {} }); - }); + this.put('/users/eviltrout', () => response({ user: {} })); - this.get("/t/280.json", function() { - return response(fixturesByUrl['/t/280/1.json']); - }); + this.get("/t/280.json", () => response(fixturesByUrl['/t/280/1.json'])); - this.get("/t/28830.json", function() { - return response(fixturesByUrl['/t/28830/1.json']); - }); + this.get("/t/28830.json", () => response(fixturesByUrl['/t/28830/1.json'])); - this.get("/t/9.json", function() { - return response(fixturesByUrl['/t/9/1.json']); - }); + this.get("/t/9.json", () => response(fixturesByUrl['/t/9/1.json'])); - this.get("/t/id_for/:slug", function() { + this.get("/t/id_for/:slug", () => { return response({id: 280, slug: "internationalization-localization", url: "/t/internationalization-localization/280"}); }); - this.get("/404-body", function() { + this.get("/404-body", () => { return [200, {"Content-Type": "text/html"}, "
    not found
    "]; }); @@ -130,14 +85,28 @@ export default function() { this.get('/users/:username/staff-info.json', () => response({})); - this.put('/categories/:category_id', function(request) { + this.get('/post_action_users', () => { + return response({ + post_action_users: [ + {id: 1, username: 'eviltrout', avatar_template: '/user_avatar/default/eviltrout/{size}/1.png', username_lower: 'eviltrout' } + ] + }); + }); + + this.get('/post_replies', () => { + return response({ post_replies: [{ id: 1234, cooked: 'wat' }] }); + }); + + this.get('/post_reply_histories', () => { + return response({ post_reply_histories: [{ id: 1234, cooked: 'wat' }] }); + }); + + this.put('/categories/:category_id', request => { const category = parsePostData(request.requestBody); return response({category}); }); - this.get('/draft.json', function() { - return response({}); - }); + this.get('/draft.json', () => response({})); this.put('/queued_posts/:queued_post_id', function(request) { return response({ queued_post: {id: request.params.queued_post_id } }); @@ -173,37 +142,26 @@ export default function() { return response({available: true}); }); - this.post('/users', function() { - return response({success: true}); - }); + this.post('/users', () => response({success: true})); - this.get('/login.html', function() { - return [200, {}, 'LOGIN PAGE']; - }); + this.get('/login.html', () => [200, {}, 'LOGIN PAGE']); this.delete('/posts/:post_id', success); this.put('/posts/:post_id/recover', success); + this.get('/posts/:post_id/expand-embed', success); - this.put('/posts/:post_id', (request) => { + this.put('/posts/:post_id', request => { const data = parsePostData(request.requestBody); data.post.id = request.params.post_id; data.post.version = 2; return response(200, data.post); }); - this.get('/t/403.json', () => { - return response(403, {}); - }); + this.get('/t/403.json', () => response(403, {})); + this.get('/t/404.json', () => response(404, "not found")); + this.get('/t/500.json', () => response(502, {})); - this.get('/t/404.json', () => { - return response(404, "not found"); - }); - - this.get('/t/500.json', () => { - return response(502, {}); - }); - - this.put('/t/:slug/:id', (request) => { + this.put('/t/:slug/:id', request => { const data = parsePostData(request.requestBody); return response(200, { basic_topic: {id: request.params.id, @@ -212,6 +170,16 @@ export default function() { slug: request.params.slug } }); }); + this.get('/t/:topic_id/posts.json', request => { + const postIds = request.queryParams.post_ids; + const posts = postIds.map(p => ({id: parseInt(p), post_number: parseInt(p) })); + return response(200, { post_stream: { posts } }); + }); + + this.get('/posts/:post_id/reply-history.json', () => { + return response(200, [ { id: 2222, post_number: 2222 } ]); + }); + this.post('/posts', function(request) { const data = parsePostData(request.requestBody); @@ -230,64 +198,27 @@ export default function() { }); }); - this.get('/fruits/:id', function() { - const fruit = fruits[0]; - return response({ __rest_serializer: "1", fruit, farmers, colors }); - }); + this.post('/topics/timings', () => response(200, {})); - this.get('/fruits', function() { - return response({ __rest_serializer: "1", fruits, farmers, colors }); - }); + const siteText = {id: 'site.test', value: 'Test McTest'}; + const overridden = {id: 'site.overridden', value: 'Overridden', overridden: true }; + this.get('/admin/customize/site_texts', request => { - this.get('/widgets/:widget_id', function(request) { - const w = _widgets.findBy('id', parseInt(request.params.widget_id)); - if (w) { - return response({widget: w}); + if (request.queryParams.overridden) { + return response(200, {site_texts: [overridden] }); } else { - return response(404); + return response(200, {site_texts: [siteText, overridden] }); } }); - this.post('/widgets', function(request) { - const widget = parsePostData(request.requestBody).widget; - widget.id = 100; - return response(200, {widget}); - }); + this.get('/admin/customize/site_texts/:key', () => response(200, {site_text: siteText })); + this.delete('/admin/customize/site_texts/:key', () => response(200, {site_text: siteText })); - this.put('/widgets/:widget_id', function(request) { - const widget = parsePostData(request.requestBody).widget; - return response({ widget }); - }); - - this.put('/cool_things/:cool_thing_id', function(request) { - const cool_thing = parsePostData(request.requestBody).cool_thing; - return response({ cool_thing }); - }); - - - this.get('/widgets', function(request) { - let result = _widgets; - - const qp = request.queryParams; - if (qp) { - if (qp.name) { result = result.filterBy('name', qp.name); } - if (qp.id) { result = result.filterBy('id', parseInt(qp.id)); } - } - - return response({ widgets: result, - total_rows_widgets: 4, - load_more_widgets: '/load-more-widgets', - refresh_widgets: '/widgets?refresh=true' }); - }); - - this.get('/load-more-widgets', function() { - return response({ widgets: _moreWidgets, total_rows_widgets: 4, load_more_widgets: '/load-more-widgets' }); - }); - - this.delete('/widgets/:widget_id', success); - - this.post('/topics/timings', function() { - return response(200, {}); + this.put('/admin/customize/site_texts/:key', request => { + const result = parsePostData(request.requestBody); + result.id = request.params.key; + result.can_revert = true; + return response(200, {site_text: result}); }); }); @@ -304,9 +235,6 @@ export default function() { throw error; }; - server.checkPassthrough = function(request) { - return request.requestHeaders['Discourse-Script']; - }; - + server.checkPassthrough = request => request.requestHeaders['Discourse-Script']; return server; } diff --git a/test/javascripts/helpers/fixture-pretender.js.es6 b/test/javascripts/helpers/fixture-pretender.js.es6 new file mode 100644 index 00000000000..dea96b35a98 --- /dev/null +++ b/test/javascripts/helpers/fixture-pretender.js.es6 @@ -0,0 +1,20 @@ +export default function(helpers) { + const { response } = helpers; + const fixturesByUrl = {}; + + // Load any fixtures automatically + Ember.keys(require._eak_seen).forEach(entry => { + if (/^fixtures/.test(entry)) { + const fixture = require(entry, null, null, true); + if (fixture && fixture.default) { + const obj = fixture.default; + Ember.keys(obj).forEach(url => { + fixturesByUrl[url] = obj[url]; + this.get(url, () => response(obj[url])); + }); + } + } + }); + + return fixturesByUrl; +}; diff --git a/test/javascripts/helpers/qunit-helpers.js.es6 b/test/javascripts/helpers/qunit-helpers.js.es6 index 44812f7ec68..c6905856612 100644 --- a/test/javascripts/helpers/qunit-helpers.js.es6 +++ b/test/javascripts/helpers/qunit-helpers.js.es6 @@ -41,7 +41,6 @@ function acceptance(name, options) { Discourse.Utilities.avatarImg = () => ""; // For now don't do scrolling stuff in Test Mode - Ember.CloakedCollectionView.scrolled = Ember.K; HeaderView.reopen({examineDockHeader: Ember.K}); var siteJson = siteFixtures['site.json'].site; diff --git a/test/javascripts/helpers/site-settings.js b/test/javascripts/helpers/site-settings.js index 7adde6c8845..0beed5c9799 100644 --- a/test/javascripts/helpers/site-settings.js +++ b/test/javascripts/helpers/site-settings.js @@ -80,7 +80,7 @@ Discourse.SiteSettingsOriginal = { "tos_accept_required":false, "faq_url":"", "allow_restore":false, - "maximum_backups":7, + "maximum_backups":5, "version_checks":true, "suppress_uncategorized_badge":true, "min_search_term_length":3, diff --git a/test/javascripts/helpers/store-pretender.js.es6 b/test/javascripts/helpers/store-pretender.js.es6 new file mode 100644 index 00000000000..de7ff6b27c8 --- /dev/null +++ b/test/javascripts/helpers/store-pretender.js.es6 @@ -0,0 +1,79 @@ +const _widgets = [ + {id: 123, name: 'Trout Lure'}, + {id: 124, name: 'Evil Repellant'} +]; + +const _moreWidgets = [ + {id: 223, name: 'Bass Lure'}, + {id: 224, name: 'Good Repellant'} +]; + +const fruits = [{id: 1, name: 'apple', farmer_id: 1, color_ids: [1,2], category_id: 4}, + {id: 2, name: 'banana', farmer_id: 1, color_ids: [3], category_id: 3}, + {id: 3, name: 'grape', farmer_id: 2, color_ids: [2], category_id: 5}]; + +const farmers = [{id: 1, name: 'Old MacDonald'}, + {id: 2, name: 'Luke Skywalker'}]; + +const colors = [{id: 1, name: 'Red'}, + {id: 2, name: 'Green'}, + {id: 3, name: 'Yellow'}]; + +export default function(helpers) { + const { response, success, parsePostData } = helpers; + + this.get('/fruits/:id', function() { + const fruit = fruits[0]; + return response({ __rest_serializer: "1", fruit, farmers, colors }); + }); + + this.get('/fruits', function() { + return response({ __rest_serializer: "1", fruits, farmers, colors, extras: {hello: 'world'} }); + }); + + this.get('/widgets/:widget_id', function(request) { + const w = _widgets.findBy('id', parseInt(request.params.widget_id)); + if (w) { + return response({widget: w}); + } else { + return response(404); + } + }); + + this.post('/widgets', function(request) { + const widget = parsePostData(request.requestBody).widget; + widget.id = 100; + return response(200, {widget}); + }); + + this.put('/widgets/:widget_id', function(request) { + const widget = parsePostData(request.requestBody).widget; + return response({ widget }); + }); + + this.put('/cool_things/:cool_thing_id', function(request) { + const cool_thing = parsePostData(request.requestBody).cool_thing; + return response({ cool_thing }); + }); + + this.get('/widgets', function(request) { + let result = _widgets; + + const qp = request.queryParams; + if (qp) { + if (qp.name) { result = result.filterBy('name', qp.name); } + if (qp.id) { result = result.filterBy('id', parseInt(qp.id)); } + } + + return response({ widgets: result, + total_rows_widgets: 4, + load_more_widgets: '/load-more-widgets', + refresh_widgets: '/widgets?refresh=true' }); + }); + + this.get('/load-more-widgets', function() { + return response({ widgets: _moreWidgets, total_rows_widgets: 4, load_more_widgets: '/load-more-widgets' }); + }); + + this.delete('/widgets/:widget_id', success); +}; diff --git a/test/javascripts/helpers/widget-test.js.es6 b/test/javascripts/helpers/widget-test.js.es6 new file mode 100644 index 00000000000..d30170ff1db --- /dev/null +++ b/test/javascripts/helpers/widget-test.js.es6 @@ -0,0 +1,9 @@ +import componentTest from 'helpers/component-test'; + +export function moduleForWidget(name) { + moduleForComponent(name, `widget:${name}`, { integration: true }); +} + +export function widgetTest(name, opts) { + return componentTest(name, opts); +} diff --git a/test/javascripts/lib/bbcode-test.js.es6 b/test/javascripts/lib/bbcode-test.js.es6 index 7aa30ed91bb..86ca8d685e2 100644 --- a/test/javascripts/lib/bbcode-test.js.es6 +++ b/test/javascripts/lib/bbcode-test.js.es6 @@ -1,4 +1,5 @@ import Quote from 'discourse/lib/quote'; +import Post from 'discourse/models/post'; module("Discourse.BBCode"); @@ -48,15 +49,6 @@ test('code', function() { "it doesn't trim leading whitespace"); }); -test('spoiler', function() { - format("[spoiler]it's a sled[/spoiler]", "it's a sled", "supports spoiler tags on text"); - format("[spoiler][/spoiler]", - "", "supports spoiler tags on images"); - format("[spoiler] This is the **bold** :smiley: [/spoiler]", " This is the bold \":smiley:\" ", "supports spoiler tags on emojis"); - format("[spoiler] Why not both ?[/spoiler]", " Why not both ?", "supports images and text"); - format("In a p tag a spoiler [spoiler] [/spoiler] can work.", "In a p tag a spoiler can work.", "supports images and text in a p tag"); -}); - test('lists', function() { format("[ul][li]option one[/li][/ul]", "
    • option one
    ", "creates an ul"); format("[ol][li]option one[/li][/ol]", "
    1. option one
    ", "creates an ol"); @@ -70,24 +62,10 @@ test('tags with arguments', function() { format("[b]first[/b] [b]second[/b]", "first second", "can bold two things on the same line"); }); -test("size tags", function() { - format("[size=35]BIG [b]whoop[/b][/size]", - "BIG whoop", - "supports [size=]"); - format("[size=asdf]regular[/size]", - "regular", - "it only supports numbers in bbcode"); - format("[size=35]NEWLINE\n\ntest[/size]", - "

    NEWLINE

    test

    ", - "works with newlines"); - format("[size=35][quote=\"user\"]quote[/quote][/size]", - "", - "works with nested complex blocks"); -}); test("quotes", function() { - var post = Discourse.Post.create({ + var post = Post.create({ cooked: "

    lorem ipsum

    ", username: "eviltrout", post_number: 1, @@ -176,5 +154,3 @@ test("quotes with trailing formatting", function() { "
    EvilTrout:

    hello

    \n\n

    Test

    ", "it allows trailing formatting"); }); - - diff --git a/test/javascripts/lib/click-track-test.js.es6 b/test/javascripts/lib/click-track-test.js.es6 index 3b228d59aec..403a2c15f53 100644 --- a/test/javascripts/lib/click-track-test.js.es6 +++ b/test/javascripts/lib/click-track-test.js.es6 @@ -16,21 +16,22 @@ module("lib:click-track", { windowOpen = sandbox.stub(window, "open").returns(win); sandbox.stub(win, "focus"); - fixture().html([ - '
    ', - ' ', - '
    '].join("\n")); + fixture().html( + ``); } }); @@ -64,6 +65,10 @@ test("does not track clicks on quote buttons", function() { ok(track(generateClickEventOn('.quote-other-topic'))); }); +test("does not track clicks on category badges", () => { + ok(!track(generateClickEventOn('.hashtag'))); +}); + test("removes the href and put it as a data attribute", function() { track(generateClickEventOn('a')); diff --git a/test/javascripts/lib/computed-test.js.es6 b/test/javascripts/lib/computed-test.js.es6 index 4a228d33b39..a708ac21e10 100644 --- a/test/javascripts/lib/computed-test.js.es6 +++ b/test/javascripts/lib/computed-test.js.es6 @@ -98,7 +98,7 @@ test("url", function() { t = testClass.create({ username: 'eviltrout' }); equal(t.get('userUrl'), "/users/eviltrout", "it supports urls without a prefix"); - Discourse.BaseUri = "/prefixed/"; + Discourse.BaseUri = "/prefixed"; t = testClass.create({ username: 'eviltrout' }); equal(t.get('userUrl'), "/prefixed/users/eviltrout", "it supports urls with a prefix"); }); diff --git a/test/javascripts/lib/discourse-test.js.es6 b/test/javascripts/lib/discourse-test.js.es6 new file mode 100644 index 00000000000..8f3725fa442 --- /dev/null +++ b/test/javascripts/lib/discourse-test.js.es6 @@ -0,0 +1,7 @@ +module("lib:discourse"); + +test("getURL on subfolder install", function() { + Discourse.BaseUri = "/forum"; + equal(Discourse.getURL("/"), "/forum/", "root url has subfolder"); + equal(Discourse.getURL("/users/neil"), "/forum/users/neil", "relative url has subfolder"); +}); \ No newline at end of file diff --git a/test/javascripts/lib/emoji-test.js.es6 b/test/javascripts/lib/emoji-test.js.es6 index fcf2c92eea8..4f3ba3c8e7d 100644 --- a/test/javascripts/lib/emoji-test.js.es6 +++ b/test/javascripts/lib/emoji-test.js.es6 @@ -8,22 +8,24 @@ var testUnescape = function(input, expected, description) { test("Emoji.unescape", function(){ + const v = Discourse.Emoji.ImageVersion; + testUnescape("Not emoji :O) :frog) :smile)", "Not emoji :O) :frog) :smile)", "title without emoji"); testUnescape("Not emoji :frog :smile", "Not emoji :frog :smile", "end colon is not optional"); - testUnescape("emoticons :)", "emoticons smile", "emoticons are still supported"); + testUnescape("emoticons :)", "emoticons slight_smile", "emoticons are still supported"); testUnescape("With emoji :O: :frog: :smile:", - "With emoji O frog smile", + `With emoji O frog smile`, "title with emoji"); testUnescape("a:smile:a", "a:smile:a", "word characters not allowed next to emoji"); - testUnescape("(:frog:) :)", "(frog) smile", "non-word characters allowed next to emoji"); - testUnescape(":smile: hi", "smile hi", "start of line"); - testUnescape("hi :smile:", "hi smile", "end of line"); + testUnescape("(:frog:) :)", `(frog) slight_smile`, "non-word characters allowed next to emoji"); + testUnescape(":smile: hi", `smile hi`, "start of line"); + testUnescape("hi :smile:", `hi smile`, "end of line"); }); test("Emoji.search", function(){ // able to find an alias - equal(Discourse.Emoji.search("coll").length, 1); + equal(Discourse.Emoji.search("+1").length, 1); }); diff --git a/test/javascripts/lib/markdown-test.js.es6 b/test/javascripts/lib/markdown-test.js.es6 index 25c2a69014b..6e8f6e86a00 100644 --- a/test/javascripts/lib/markdown-test.js.es6 +++ b/test/javascripts/lib/markdown-test.js.es6 @@ -202,7 +202,7 @@ test("Quotes", function() { test("Mentions", function() { - var alwaysTrue = { mentionLookup: (function() { return true; }) }; + var alwaysTrue = { mentionLookup: (function() { return "user"; }) }; cookedOptions("Hello @sam", alwaysTrue, "

    Hello @sam

    ", @@ -276,6 +276,10 @@ test("Mentions", function() { "
    1. this is a list

    2. this is an @eviltrout mention

    ", "it mentions properly in a list."); + cooked("Hello @foo/@bar", + "

    Hello @foo/@bar

    ", + "handles mentions separated by a slash."); + cookedOptions("@eviltrout", alwaysTrue, "

    @eviltrout

    ", "it doesn't onebox mentions"); @@ -285,6 +289,46 @@ test("Mentions", function() { "it allows mentions within HTML tags"); }); +test("Category hashtags", () => { + var alwaysTrue = { categoryHashtagLookup: (function() { return ["http://test.discourse.org/category-hashtag", "category-hashtag"]; }) }; + + cookedOptions("Check out #category-hashtag", alwaysTrue, + "

    Check out #category-hashtag

    ", + "it translates category hashtag into links"); + + cooked("Check out #category-hashtag", + "

    Check out #category-hashtag

    ", + "it does not translate category hashtag into links if it is not a valid category hashtag"); + + cookedOptions("[#category-hashtag](http://www.test.com)", alwaysTrue, + "

    #category-hashtag

    ", + "it does not translate category hashtag within links"); + + cooked("```\n# #category-hashtag\n```", + "

    # #category-hashtag

    ", + "it does not translate category hashtags to links in code blocks"); + + cooked("># #category-hashtag\n", + "

    #category-hashtag

    ", + "it handles category hashtags in simple quotes"); + + cooked("# #category-hashtag", + "

    #category-hashtag

    ", + "it works within ATX-style headers"); + + cooked("don't `#category-hashtag`", + "

    don't #category-hashtag

    ", + "it does not mention in an inline code block"); + + cooked("test #hashtag1/#hashtag2", + "

    test #hashtag1/#hashtag2

    ", + "it does not convert category hashtag not bounded by spaces"); + + cooked("#category-hashtag", + "

    #category-hashtag

    ", + "it works between HTML tags"); +}); + test("Heading", function() { cooked("**Bold**\n----------", "

    Bold

    ", "It will bold the heading"); @@ -466,9 +510,9 @@ test("sanitize", function() { cooked("\n", "


    ", "it doesn't circumvent XSS with comments"); - cooked("a", "

    a

    ", "it sanitizes spans"); - cooked("a", "

    a

    ", "it sanitizes spans"); - cooked("a", "

    a

    ", "it sanitizes spans"); + cooked("a", "

    a

    ", "it sanitizes spans"); + cooked("a", "

    a

    ", "it sanitizes spans"); + cooked("a", "

    a

    ", "it sanitizes spans"); }); test("URLs in BBCode tags", function() { diff --git a/test/javascripts/lib/utilities-test.js.es6 b/test/javascripts/lib/utilities-test.js.es6 index 8d0fd1c1d99..3cea33cbedd 100644 --- a/test/javascripts/lib/utilities-test.js.es6 +++ b/test/javascripts/lib/utilities-test.js.es6 @@ -1,3 +1,4 @@ +/* global Int8Array:true */ import { blank } from 'helpers/qunit-helpers'; module("Discourse.Utilities"); @@ -95,7 +96,7 @@ test("getUploadMarkdown", function() { }); test("isAnImage", function() { - _.each(["png", "jpg", "jpeg", "bmp", "gif", "tif", "tiff"], function(extension) { + _.each(["png", "jpg", "jpeg", "bmp", "gif", "tif", "tiff", "ico"], function(extension) { var image = "image." + extension; ok(utils.isAnImage(image), image + " is recognized as an image"); ok(utils.isAnImage("http://foo.bar/path/to/" + image), image + " is recognized as an image"); @@ -158,3 +159,26 @@ test("defaultHomepage", function() { Discourse.SiteSettings.top_menu = "latest|top|hot"; equal(utils.defaultHomepage(), "latest", "default homepage is the first item in the top_menu site setting"); }); + +test("caretRowCol", () => { + var textarea = document.createElement('textarea'); + const content = document.createTextNode("01234\n56789\n012345"); + textarea.appendChild(content); + document.body.appendChild(textarea); + + const assertResult = (setCaretPos, expectedRowNum, expectedColNum) => { + Discourse.Utilities.setCaretPosition(textarea, setCaretPos); + + const result = Discourse.Utilities.caretRowCol(textarea); + equal(result.rowNum, expectedRowNum, "returns the right row of the caret"); + equal(result.colNum, expectedColNum, "returns the right col of the caret"); + }; + + assertResult(0, 1, 0); + assertResult(5, 1, 5); + assertResult(6, 2, 0); + assertResult(11, 2, 5); + assertResult(14, 3, 2); + + document.body.removeChild(textarea); +}); diff --git a/test/javascripts/mdtest/mdtest.js.erb b/test/javascripts/mdtest/mdtest.js.erb index 6a9591efdde..f1c9a713814 100644 --- a/test/javascripts/mdtest/mdtest.js.erb +++ b/test/javascripts/mdtest/mdtest.js.erb @@ -5,7 +5,7 @@ module("MDTest", { }); // This is cheating, but the trivial differences between sanitization -// do not affect formatting. +// do not affect formatting. function normalize(str) { return str.replace(/\n\s*/g, ''). replace(/ \/\>/g, '>'). diff --git a/test/javascripts/models/badge-test.js.es6 b/test/javascripts/models/badge-test.js.es6 index a91b49ecd35..0b92f88ce44 100644 --- a/test/javascripts/models/badge-test.js.es6 +++ b/test/javascripts/models/badge-test.js.es6 @@ -9,32 +9,6 @@ test('newBadge', function() { ok(!badge2.get('newBadge'), "badges with ids are not new"); }); -test('displayName', function() { - const badge1 = Badge.create({id: 1, name: "Test Badge 1"}); - equal(badge1.get('displayName'), "Test Badge 1", "falls back to the original name in the absence of a translation"); - - sandbox.stub(I18n, "t").returnsArg(0); - const badge2 = Badge.create({id: 2, name: "Test Badge 2"}); - equal(badge2.get('displayName'), "badges.badge.test_badge_2.name", "uses translation when available"); -}); - -test('translatedDescription', function() { - const badge1 = Badge.create({id: 1, name: "Test Badge 1", description: "TEST"}); - equal(badge1.get('translatedDescription'), null, "returns null when no translation exists"); - - const badge2 = Badge.create({id: 2, name: "Test Badge 2 **"}); - sandbox.stub(I18n, "t").returns("description translation"); - equal(badge2.get('translatedDescription'), "description translation", "users translated description"); -}); - -test('displayDescription', function() { - const badge1 = Badge.create({id: 1, name: "Test Badge 1", description: "TEST"}); - equal(badge1.get('displayDescription'), "TEST", "returns original description when no translation exists"); - - const badge2 = Badge.create({id: 2, name: "Test Badge 2 **"}); - sandbox.stub(I18n, "t").returns("description translation"); - equal(badge2.get('displayDescription'), "description translation", "users translated description"); -}); test('createFromJson array', function() { const badgesJson = {"badge_types":[{"id":6,"name":"Silver 1"}],"badges":[{"id":1126,"name":"Badge 1","description":null,"badge_type_id":6}]}; diff --git a/test/javascripts/models/category-test.js.es6 b/test/javascripts/models/category-test.js.es6 index 48735f88e42..cb6c9858e2c 100644 --- a/test/javascripts/models/category-test.js.es6 +++ b/test/javascripts/models/category-test.js.es6 @@ -1,4 +1,5 @@ import createStore from 'helpers/create-store'; +import Category from 'discourse/models/category'; module("model:category"); @@ -50,6 +51,8 @@ test('findBySlug', function() { deepEqual(Discourse.Category.findBySlug('뉴스피드', '熱帶風暴畫眉'), newsFeed, 'we can find a category with CJK slug whose parent slug is also CJK'); deepEqual(Discourse.Category.findBySlug('时间', 'darth'), time, 'we can find a category with CJK slug whose parent slug is english'); deepEqual(Discourse.Category.findBySlug('bah', '熱帶風暴畫眉'), bah, 'we can find a category with english slug whose parent slug is CJK'); + + sandbox.restore(); }); test('findSingleBySlug', function() { @@ -122,3 +125,60 @@ test('postCountStats', function() { result = category5.get('postCountStats'); equal(result.length, 0, "should show nothing"); }); + +test('search with category name', () => { + const store = createStore(), + category1 = store.createRecord('category', { id: 1, name: 'middle term', slug: 'different-slug' }), + category2 = store.createRecord('category', { id: 2, name: 'middle term', slug: 'another-different-slug' }); + + sandbox.stub(Category, "listByActivity").returns([category1, category2]); + + deepEqual(Category.search('term', { limit: 0 }), [], "returns an empty array when limit is 0"); + deepEqual(Category.search(''), [category1, category2], "orders by activity if no term is matched"); + deepEqual(Category.search('term'), [category1, category2], "orders by activity"); + + category2.set('name', 'TeRm start'); + deepEqual(Category.search('tErM'), [category2, category1], "ignores case of category name and search term"); + + category2.set('name', 'term start'); + deepEqual(Category.search('term'), [category2, category1], "orders matching begin with and then contains"); + + sandbox.restore(); + + const child_category1 = store.createRecord('category', { id: 3, name: 'term start', parent_category_id: category1.get('id') }), + read_restricted_category = store.createRecord('category', { id: 4, name: 'some term', read_restricted: true }); + + sandbox.stub(Category, "listByActivity").returns([read_restricted_category, category1, child_category1, category2]); + + deepEqual(Category.search(''), + [category1, category2, read_restricted_category], + "prioritize non read_restricted and does not include child categories when term is blank"); + + deepEqual(Category.search('', { limit: 3 }), + [category1, category2, read_restricted_category], + "prioritize non read_restricted and does not include child categories categories when term is blank with limit"); + + deepEqual(Category.search('term'), + [child_category1, category2, category1, read_restricted_category], + "prioritize non read_restricted"); + + deepEqual(Category.search('term', { limit: 3 }), + [child_category1, category2, read_restricted_category], + "prioritize non read_restricted with limit"); + + sandbox.restore(); +}); + +test('search with category slug', () => { + const store = createStore(), + category1 = store.createRecord('category', { id: 1, name: 'middle term', slug: 'different-slug' }), + category2 = store.createRecord('category', { id: 2, name: 'middle term', slug: 'another-different-slug' }); + + sandbox.stub(Category, "listByActivity").returns([category1, category2]); + + deepEqual(Category.search('different-slug'), [category1, category2], "returns the right categories"); + deepEqual(Category.search('another-different'), [category2], "returns the right categories"); + + category2.set('slug', 'ANOTher-DIFfereNT'); + deepEqual(Category.search('anOtHer-dIfFeREnt'), [category2], "ignores case of category slug and search term"); +}); diff --git a/test/javascripts/models/composer-test.js.es6 b/test/javascripts/models/composer-test.js.es6 index a31c569caeb..c156c92306e 100644 --- a/test/javascripts/models/composer-test.js.es6 +++ b/test/javascripts/models/composer-test.js.es6 @@ -1,13 +1,10 @@ import { blank } from 'helpers/qunit-helpers'; import { currentUser } from 'helpers/qunit-helpers'; -import KeyValueStore from 'discourse/lib/key-value-store'; import Composer from 'discourse/models/composer'; import createStore from 'helpers/create-store'; module("model:composer"); -const keyValueStore = new KeyValueStore("_test_composer"); - function createComposer(opts) { opts = opts || {}; opts.user = opts.user || currentUser(); @@ -185,26 +182,10 @@ test('initial category when uncategorized is not allowed', function() { ok(!composer.get('categoryId'), "Uncategorized by default. Must choose a category."); }); -test('showPreview', function() { - const newComposer = function() { - return openComposer({action: 'createTopic', draftKey: 'asfd', draftSequence: 1}); - }; - - Discourse.Mobile.mobileView = true; - equal(newComposer().get('showPreview'), false, "Don't show preview in mobile view"); - - keyValueStore.set({ key: 'composer.showPreview', value: 'true' }); - equal(newComposer().get('showPreview'), false, "Don't show preview in mobile view even if KeyValueStore wants to"); - keyValueStore.remove('composer.showPreview'); - - Discourse.Mobile.mobileView = false; - equal(newComposer().get('showPreview'), true, "Show preview by default in desktop view"); -}); - test('open with a quote', function() { const quote = '[quote="neil, post:5, topic:413"]\nSimmer down you two.\n[/quote]'; const newComposer = function() { - return openComposer({action: Discourse.Composer.REPLY, draftKey: 'asfd', draftSequence: 1, quote: quote}); + return openComposer({action: Composer.REPLY, draftKey: 'asfd', draftSequence: 1, quote: quote}); }; equal(newComposer().get('originalText'), quote, "originalText is the quote" ); diff --git a/test/javascripts/models/email-log-test.js.es6 b/test/javascripts/models/email-log-test.js.es6 index bce4017fb1a..98d4b714f9c 100644 --- a/test/javascripts/models/email-log-test.js.es6 +++ b/test/javascripts/models/email-log-test.js.es6 @@ -1,5 +1,7 @@ +import EmailLog from 'admin/models/email-log'; + module("Discourse.EmailLog"); test("create", function() { - ok(Discourse.EmailLog.create(), "it can be created without arguments"); + ok(EmailLog.create(), "it can be created without arguments"); }); diff --git a/test/javascripts/models/post-stream-test.js.es6 b/test/javascripts/models/post-stream-test.js.es6 index f7795de6834..0b9a7d3dfaa 100644 --- a/test/javascripts/models/post-stream-test.js.es6 +++ b/test/javascripts/models/post-stream-test.js.es6 @@ -27,44 +27,11 @@ test('defaults', function() { present(postStream.get('topic')); }); -test('daysSincePrevious when appending', function(assert) { - const postStream = buildStream(10000001, [1,2,3]); - const store = postStream.store; - - const p1 = store.createRecord('post', {id: 1, post_number: 1, created_at: "2015-05-29T18:17:35.868Z"}), - p2 = store.createRecord('post', {id: 2, post_number: 2, created_at: "2015-06-01T01:07:25.761Z"}), - p3 = store.createRecord('post', {id: 3, post_number: 3, created_at: "2015-06-02T01:07:25.761Z"}); - - postStream.appendPost(p1); - postStream.appendPost(p2); - postStream.appendPost(p3); - - assert.ok(!p1.get('daysSincePrevious')); - assert.equal(p2.get('daysSincePrevious'), 2); - assert.equal(p3.get('daysSincePrevious'), 1); -}); - -test('daysSincePrevious when prepending', function(assert) { - const postStream = buildStream(10000001, [1,2,3]); - const store = postStream.store; - - const p1 = store.createRecord('post', {id: 1, post_number: 1, created_at: "2015-05-29T18:17:35.868Z"}), - p2 = store.createRecord('post', {id: 2, post_number: 2, created_at: "2015-06-01T01:07:25.761Z"}), - p3 = store.createRecord('post', {id: 3, post_number: 3, created_at: "2015-06-02T01:07:25.761Z"}); - - postStream.prependPost(p3); - postStream.prependPost(p2); - postStream.prependPost(p1); - - assert.ok(!p1.get('daysSincePrevious')); - assert.equal(p2.get('daysSincePrevious'), 2); - assert.equal(p3.get('daysSincePrevious'), 1); -}); - test('appending posts', function() { const postStream = buildStream(4567, [1, 3, 4]); const store = postStream.store; + equal(postStream.get('firstPostId'), 1); equal(postStream.get('lastPostId'), 4, "the last post id is 4"); ok(!postStream.get('hasPosts'), "there are no posts by default"); @@ -283,66 +250,39 @@ test("storePost", function() { const postWithoutId = store.createRecord('post', {raw: 'hello world'}); stored = postStream.storePost(postWithoutId); equal(stored, postWithoutId, "it returns the same post back"); - equal(postStream.get('postIdentityMap.size'), 1, "it does not add a new entry into the identity map"); }); test("identity map", function() { - const postStream = buildStream(1234), - store = postStream.store; + const postStream = buildStream(1234); + const store = postStream.store; const p1 = postStream.appendPost(store.createRecord('post', {id: 1, post_number: 1})); - postStream.appendPost(store.createRecord('post', {id: 3, post_number: 4})); + const p3 = postStream.appendPost(store.createRecord('post', {id: 3, post_number: 4})); equal(postStream.findLoadedPost(1), p1, "it can return cached posts by id"); blank(postStream.findLoadedPost(4), "it can't find uncached posts"); - deepEqual(postStream.listUnloadedIds([10, 11, 12]), [10, 11, 12], "it returns a list of all unloaded ids"); - blank(postStream.listUnloadedIds([1, 3]), "if we have loaded all posts it's blank"); - deepEqual(postStream.listUnloadedIds([1, 2, 3, 4]), [2, 4], "it only returns unloaded posts"); -}); - -asyncTestDiscourse("loadIntoIdentityMap with no data", function() { - const postStream = buildStream(1234); - expect(1); - - sandbox.stub(Discourse, "ajax"); - postStream.loadIntoIdentityMap([]).then(function() { - ok(!Discourse.ajax.calledOnce, "an empty array returned a promise yet performed no ajax request"); - start(); + // Find posts by ids uses the identity map + postStream.findPostsByIds([1, 2, 3]).then(result => { + equal(result.length, 3); + equal(result.objectAt(0), p1); + equal(result.objectAt(1).get('post_number'), 2); + equal(result.objectAt(2), p3); }); }); -asyncTestDiscourse("loadIntoIdentityMap with post ids", function() { - const postStream = buildStream(1234); - expect(1); +test("loadIntoIdentityMap with no data", () => { + buildStream(1234).loadIntoIdentityMap([]).then(result => { + equal(result.length, 0, 'requesting no posts produces no posts'); + }); +}); - sandbox.stub(Discourse, "ajax").returns(Ember.RSVP.resolve({ - post_stream: { - posts: [{id: 10, post_number: 10}] - } - })); +test("loadIntoIdentityMap with post ids", function() { + const postStream = buildStream(1234); postStream.loadIntoIdentityMap([10]).then(function() { present(postStream.findLoadedPost(10), "it adds the returned post to the store"); - start(); - }); -}); - -asyncTestDiscourse("loading a post's history", function() { - const postStream = buildStream(1234); - const store = postStream.store; - expect(3); - - const post = store.createRecord('post', {id: 4321}); - const secondPost = store.createRecord('post', {id: 2222}); - - sandbox.stub(Discourse, "ajax").returns(Ember.RSVP.resolve([secondPost])); - postStream.findReplyHistory(post).then(function() { - ok(Discourse.ajax.calledOnce, "it made the ajax request"); - present(postStream.findLoadedPost(2222), "it stores the returned post in the identity map"); - present(post.get('replyHistory'), "it sets the replyHistory attribute for the post"); - start(); }); }); @@ -429,36 +369,6 @@ test("staging and committing a post", function() { ok(postStream.get('lastAppended'), found, "comitting a post changes lastAppended"); }); -test('triggerNewPostInStream', function() { - const postStream = buildStream(225566); - const store = postStream.store; - - sandbox.stub(postStream, 'appendMore'); - sandbox.stub(postStream, "refresh").returns(new Ember.RSVP.resolve()); - - postStream.triggerNewPostInStream(null); - ok(!postStream.appendMore.calledOnce, "asking for a null id does nothing"); - - postStream.toggleSummary(); - postStream.triggerNewPostInStream(1); - ok(!postStream.appendMore.calledOnce, "it will not trigger when summary is active"); - - postStream.cancelFilter(); - postStream.toggleParticipant('eviltrout'); - postStream.triggerNewPostInStream(1); - ok(!postStream.appendMore.calledOnce, "it will not trigger when a participant filter is active"); - - postStream.cancelFilter(); - postStream.triggerNewPostInStream(1); - ok(!postStream.appendMore.calledOnce, "it wont't delegate to appendMore because the last post is not loaded"); - - postStream.cancelFilter(); - postStream.appendPost(store.createRecord('post', {id: 1, post_number: 2})); - postStream.triggerNewPostInStream(2); - ok(postStream.appendMore.calledOnce, "delegates to appendMore because the last post is loaded"); -}); - - test("loadedAllPosts when the id changes", function() { // This can happen in a race condition between staging a post and it coming through on the // message bus. If the id of a post changes we should reconsider the loadedAllPosts property. @@ -494,3 +404,45 @@ test("comitting and triggerNewPostInStream race condition", function() { equal(postStream.get('filteredPostsCount'), 1, "it does not add the same post twice"); }); +test("postsWithPlaceholders", () => { + const postStream = buildStream(4964, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + const postsWithPlaceholders = postStream.get('postsWithPlaceholders'); + const store = postStream.store; + + const testProxy = Ember.ArrayProxy.create({ content: postsWithPlaceholders }); + + const p1 = store.createRecord('post', {id: 1, post_number: 1}); + const p2 = store.createRecord('post', {id: 2, post_number: 2}); + const p3 = store.createRecord('post', {id: 3, post_number: 3}); + const p4 = store.createRecord('post', {id: 4, post_number: 4}); + + postStream.appendPost(p1); + postStream.appendPost(p2); + postStream.appendPost(p3); + + // Test enumerable and array access + equal(postsWithPlaceholders.get('length'), 3); + equal(testProxy.get('length'), 3); + equal(postsWithPlaceholders.nextObject(0), p1); + equal(postsWithPlaceholders.objectAt(0), p1); + equal(postsWithPlaceholders.nextObject(1, p1), p2); + equal(postsWithPlaceholders.objectAt(1), p2); + equal(postsWithPlaceholders.nextObject(2, p2), p3); + equal(postsWithPlaceholders.objectAt(2), p3); + + const promise = postStream.appendMore(); + equal(postsWithPlaceholders.get('length'), 8, 'we immediately have a larger placeholder window'); + equal(testProxy.get('length'), 8); + ok(!!postsWithPlaceholders.nextObject(3, p3)); + ok(!!postsWithPlaceholders.objectAt(4)); + ok(postsWithPlaceholders.objectAt(3) !== p4); + ok(testProxy.objectAt(3) !== p4); + + return promise.then(() => { + equal(postsWithPlaceholders.objectAt(3), p4); + equal(postsWithPlaceholders.get('length'), 8, 'have a larger placeholder window when loaded'); + equal(testProxy.get('length'), 8); + equal(testProxy.objectAt(3), p4); + }); + +}); diff --git a/test/javascripts/models/post-test.js.es6 b/test/javascripts/models/post-test.js.es6 index 77365775004..1f881df1209 100644 --- a/test/javascripts/models/post-test.js.es6 +++ b/test/javascripts/models/post-test.js.es6 @@ -14,7 +14,6 @@ test('defaults', function() { var post = Discourse.Post.create({id: 1}); blank(post.get('deleted_at'), "it has no deleted_at by default"); blank(post.get('deleted_by'), "there is no deleted_by by default"); - equal(post.get('replyHistory.length'), 0, "there is no reply history by default"); }); test('new_user', function() { @@ -47,16 +46,6 @@ test('updateFromPost', function() { equal(post.get('raw'), "different raw", "raw field updated"); }); -test('hasHistory', function() { - var post = Discourse.Post.create({id: 1}); - ok(!post.get('hasHistory'), 'posts without versions have no history'); - post.set('version', 1); - ok(!post.get('hasHistory'), 'posts with one version have no history'); - post.set('version', 2); - ok(post.get('hasHistory'), 'posts with more than one version have a history'); -}); - - test('destroy by staff', function() { var user = Discourse.User.create({username: 'staff', staff: true}), post = buildPost({user: user}); diff --git a/test/javascripts/models/report-test.js.es6 b/test/javascripts/models/report-test.js.es6 index 9ae550d1570..3fcdd9d037c 100644 --- a/test/javascripts/models/report-test.js.es6 +++ b/test/javascripts/models/report-test.js.es6 @@ -1,9 +1,10 @@ import { blank } from 'helpers/qunit-helpers'; +import Report from 'admin/models/report'; -module("Discourse.Report"); +module("Report"); function reportWithData(data) { - return Discourse.Report.create({ + return Report.create({ type: 'topics', data: _.map(data, function(val, index) { return { x: moment().subtract(index, "days").format('YYYY-MM-DD'), y: val }; diff --git a/test/javascripts/models/staff-action-log-test.js.es6 b/test/javascripts/models/staff-action-log-test.js.es6 index 9dbac57d0c3..933dd6271d8 100644 --- a/test/javascripts/models/staff-action-log-test.js.es6 +++ b/test/javascripts/models/staff-action-log-test.js.es6 @@ -1,5 +1,7 @@ -module("Discourse.StaffActionLog"); +import StaffActionLog from 'admin/models/staff-action-log'; + +module("StaffActionLog"); test("create", function() { - ok(Discourse.StaffActionLog.create(), "it can be created without arguments"); + ok(StaffActionLog.create(), "it can be created without arguments"); }); diff --git a/test/javascripts/models/store-test.js.es6 b/test/javascripts/models/store-test.js.es6 index 6f39c2186ad..4c72c2ae738 100644 --- a/test/javascripts/models/store-test.js.es6 +++ b/test/javascripts/models/store-test.js.es6 @@ -116,7 +116,6 @@ test('destroyRecord when new', function(assert) { }); }); - test('find embedded', function(assert) { const store = createStore(); return store.find('fruit', 2).then(function(f) { @@ -136,6 +135,7 @@ test('findAll embedded', function(assert) { return store.findAll('fruit').then(function(fruits) { assert.equal(fruits.objectAt(0).get('farmer.name'), 'Old MacDonald'); assert.equal(fruits.objectAt(0).get('farmer'), fruits.objectAt(1).get('farmer'), 'points at the same object'); + assert.equal(fruits.get('extras.hello'), 'world', 'it can supply extra information'); const fruitCols = fruits.objectAt(0).get('colors'); assert.equal(fruitCols.length, 2); diff --git a/test/javascripts/models/topic-test.js.es6 b/test/javascripts/models/topic-test.js.es6 index 3aab0b4159b..f1d2469b43e 100644 --- a/test/javascripts/models/topic-test.js.es6 +++ b/test/javascripts/models/topic-test.js.es6 @@ -75,7 +75,9 @@ test("recover", function() { test('fancyTitle', function() { var topic = Topic.create({ fancy_title: ":smile: with all :) the emojis :pear::peach:" }); + const v = Discourse.Emoji.ImageVersion; + equal(topic.get('fancyTitle'), - "smile with all smile the emojis pearpeach", + `smile with all slight_smile the emojis pearpeach`, "supports emojis"); }); diff --git a/test/javascripts/models/version-check-test.js.es6 b/test/javascripts/models/version-check-test.js.es6 index c0e6d3e8b25..4b8b6bc94f1 100644 --- a/test/javascripts/models/version-check-test.js.es6 +++ b/test/javascripts/models/version-check-test.js.es6 @@ -1,8 +1,10 @@ -module("Discourse.VersionCheck"); +import VersionCheck from 'admin/models/version-check'; + +module("VersionCheck"); test('dataIsOld', function() { var dataIsOld = function(args, expected, message) { - equal(Discourse.VersionCheck.create(args).get('dataIsOld'), expected, message); + equal(VersionCheck.create(args).get('dataIsOld'), expected, message); }; dataIsOld({updated_at: moment().subtract(2, 'hours').toJSON()}, false, '2 hours ago'); @@ -15,7 +17,7 @@ test('staleData', function() { return moment().subtract(hoursAgo, 'hours').toJSON(); }; var staleData = function(args, expected, message) { - equal(Discourse.VersionCheck.create(args).get('staleData'), expected, message); + equal(VersionCheck.create(args).get('staleData'), expected, message); }; staleData({missing_versions_count: 0, installed_version: '0.9.3', latest_version: '0.9.3', updated_at: updatedAt(2)}, false, 'up to date'); diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js index 5b9a489e06b..99efffb5efa 100644 --- a/test/javascripts/test_helper.js +++ b/test/javascripts/test_helper.js @@ -1,17 +1,13 @@ /*global document, sinon, QUnit, Logster */ //= require env - //= require ../../app/assets/javascripts/preload_store - -// probe framework first //= require probes - -// Externals we need to load first //= require jquery.debug //= require jquery.ui.widget //= require handlebars //= require ember.debug +//= require ember-template-compiler //= require message-bus //= require ember-qunit //= require fake_xml_http_request @@ -21,9 +17,6 @@ //= require ../../app/assets/javascripts/locales/i18n //= require ../../app/assets/javascripts/locales/en -// Pagedown customizations -//= require ../../app/assets/javascripts/pagedown_custom.js - //= require vendor //= require htmlparser.js @@ -48,6 +41,8 @@ // //= require ../../public/javascripts/jquery.magnific-popup-min.js +window.inTestEnv = true; + window.assetPath = function(url) { if (url.indexOf('defer') === 0) { return "/assets/" + url; @@ -91,7 +86,7 @@ QUnit.testStart(function(ctx) { // Allow our tests to change site settings and have them reset before the next test Discourse.SiteSettings = dup(Discourse.SiteSettingsOriginal); - Discourse.BaseUri = "/"; + Discourse.BaseUri = ""; Discourse.BaseUrl = "localhost"; Discourse.Session.resetCurrent(); Discourse.User.resetCurrent(); @@ -109,15 +104,15 @@ QUnit.testStart(function(ctx) { window.sandbox.stub(ScrollingDOMMethods, "bindOnScroll"); window.sandbox.stub(ScrollingDOMMethods, "unbindOnScroll"); + // Unless we ever need to test this, let's leave it off. + $.fn.autocomplete = Ember.K; + // Don't debounce in test unless we're testing debouncing if (ctx.module.indexOf('debounce') === -1) { Ember.run.debounce = Ember.run; } }); -// Don't cloak in testing -Ember.CloakedCollectionView = Ember.CollectionView; - QUnit.testDone(function() { Ember.run.debounce = origDebounce; window.sandbox.restore(); diff --git a/test/javascripts/widgets/actions-summary-test.js.es6 b/test/javascripts/widgets/actions-summary-test.js.es6 new file mode 100644 index 00000000000..8d549ff4992 --- /dev/null +++ b/test/javascripts/widgets/actions-summary-test.js.es6 @@ -0,0 +1,80 @@ +import { moduleForWidget, widgetTest } from 'helpers/widget-test'; + +moduleForWidget('actions-summary'); + +widgetTest('listing actions', { + template: '{{mount-widget widget="actions-summary" args=args}}', + setup() { + this.set('args', { + actionsSummary: [ + {action: 'off_topic', description: 'very off topic'}, + {action: 'spam', description: 'suspicious message'} + ] + }); + }, + test(assert) { + assert.equal(this.$('.post-actions .post-action').length, 2); + + click('.post-action:eq(0) .action-link a'); + andThen(() => { + assert.equal(this.$('.post-action:eq(0) img.avatar').length, 1, 'clicking it shows the user'); + }); + } +}); + +widgetTest('undo', { + template: '{{mount-widget widget="actions-summary" args=args undoPostAction="undoPostAction"}}', + setup() { + this.set('args', { + actionsSummary: [ + {action: 'off_topic', description: 'very off topic', canUndo: true}, + ] + }); + + this.on('undoPostAction', () => this.undid = true); + }, + test(assert) { + assert.equal(this.$('.post-actions .post-action').length, 1); + + click('.action-link.undo'); + andThen(() => { + assert.ok(this.undid, 'it triggered the action'); + }); + } +}); + +widgetTest('deferFlags', { + template: '{{mount-widget widget="actions-summary" args=args deferPostActionFlags="deferPostActionFlags"}}', + setup() { + this.set('args', { + actionsSummary: [ + {action: 'off_topic', description: 'very off topic', canDeferFlags: true, count: 1}, + ] + }); + + this.on('deferPostActionFlags', () => this.deferred = true); + }, + test(assert) { + assert.equal(this.$('.post-actions .post-action').length, 1); + + click('.action-link.defer-flags'); + andThen(() => { + assert.ok(this.deferred, 'it triggered the action'); + }); + } +}); + +widgetTest('post deleted', { + template: '{{mount-widget widget="actions-summary" args=args}}', + setup() { + this.set('args', { + deleted_at: "2016-01-01", + deletedByUsername: 'eviltrout', + deletedByAvatarTemplate: '/images/avatar.png' + }); + }, + test(assert) { + assert.ok(this.$('.post-action .fa-trash-o').length === 1, 'it has the deleted icon'); + assert.ok(this.$('.avatar[title=eviltrout]').length === 1, 'it has the deleted by avatar'); + } +}); diff --git a/test/javascripts/widgets/post-gutter-test.js.es6 b/test/javascripts/widgets/post-gutter-test.js.es6 new file mode 100644 index 00000000000..55c4152cb28 --- /dev/null +++ b/test/javascripts/widgets/post-gutter-test.js.es6 @@ -0,0 +1,54 @@ +import { moduleForWidget, widgetTest } from 'helpers/widget-test'; + +moduleForWidget('post-gutter'); + +widgetTest("duplicate links", { + template: '{{mount-widget widget="post-gutter" args=args}}', + setup() { + this.set('args', { + links: [ + { title: "Evil Trout Link", url: "http://eviltrout.com" }, + { title: "Evil Trout Link", url: "http://dupe.eviltrout.com" } + ] + }); + }, + test(assert) { + assert.equal(this.$('.post-links a.track-link').length, 1, 'it hides the dupe link'); + } +}); + +widgetTest("collapsed links", { + template: '{{mount-widget widget="post-gutter" args=args}}', + setup() { + this.set('args', { + links: [ + { title: "Link 1", url: "http://eviltrout.com?1" }, + { title: "Link 2", url: "http://eviltrout.com?2" }, + { title: "Link 3", url: "http://eviltrout.com?3" }, + { title: "Link 4", url: "http://eviltrout.com?4" }, + { title: "Link 5", url: "http://eviltrout.com?5" }, + { title: "Link 6", url: "http://eviltrout.com?6" }, + { title: "Link 7", url: "http://eviltrout.com?7" }, + ] + }); + }, + test(assert) { + assert.equal(this.$('.post-links a.track-link').length, 5, 'collapses by default'); + click('a.toggle-more'); + andThen(() => { + assert.equal(this.$('.post-links a.track-link').length, 7); + }); + } +}); + +widgetTest("reply as new topic", { + template: '{{mount-widget widget="post-gutter" args=args newTopicAction="newTopicAction"}}', + setup() { + this.set('args', { canReplyAsNewTopic: true }); + this.on('newTopicAction', () => this.newTopicTriggered = true); + }, + test(assert) { + click('a.reply-new'); + andThen(() => assert.ok(this.newTopicTriggered)); + } +}); diff --git a/test/javascripts/widgets/post-stream-test.js.es6 b/test/javascripts/widgets/post-stream-test.js.es6 new file mode 100644 index 00000000000..396ae206c0e --- /dev/null +++ b/test/javascripts/widgets/post-stream-test.js.es6 @@ -0,0 +1,66 @@ +import { moduleForWidget, widgetTest } from 'helpers/widget-test'; +import Topic from 'discourse/models/topic'; +import Post from 'discourse/models/post'; + +moduleForWidget('post-stream'); + +function postStreamTest(name, attrs) { + widgetTest(name, { + template: `{{mount-widget widget="post-stream" args=(as-hash posts=posts)}}`, + setup() { + this.set('posts', attrs.posts.call(this)); + }, + test: attrs.test + }); +} + +postStreamTest('basics', { + posts() { + const site = this.container.lookup('site:main'); + const topic = Topic.create({ details: { created_by: { id: 123 } } }); + return [ + Post.create({ topic, id: 1, post_number: 1, user_id: 123, primary_group_name: 'trout', + avatar_template: '/images/avatar.png' }), + Post.create({ topic, id: 2, post_number: 2, post_type: site.get('post_types.moderator_action') }), + Post.create({ topic, id: 3, post_number: 3, hidden: true }), + Post.create({ topic, id: 4, post_number: 4, post_type: site.get('post_types.whisper') }), + Post.create({ topic, id: 5, post_number: 5, wiki: true, via_email: true }) + ]; + }, + + test(assert) { + assert.equal(this.$('.post-stream').length, 1); + assert.equal(this.$('.topic-post').length, 5, 'renders all posts'); + + // look for special class bindings + assert.equal(this.$('.topic-post:eq(0).topic-owner').length, 1, 'it applies the topic owner class'); + assert.equal(this.$('.topic-post:eq(0).group-trout').length, 1, 'it applies the primary group class'); + assert.equal(this.$('.topic-post:eq(0).regular').length, 1, 'it applies the regular class'); + assert.equal(this.$('.topic-post:eq(1).moderator').length, 1, 'it applies the moderator class'); + assert.equal(this.$('.topic-post:eq(2).post-hidden').length, 1, 'it applies the hidden class'); + assert.equal(this.$('.topic-post:eq(3).whisper').length, 1, 'it applies the whisper class'); + assert.equal(this.$('.topic-post:eq(4).wiki').length, 1, 'it applies the wiki class'); + + // it renders an article for the body with appropriate attributes + assert.equal(this.$('article#post_2').length, 1); + assert.equal(this.$('article[data-user-id=123]').length, 1); + assert.equal(this.$('article[data-post-id=3]').length, 1); + assert.equal(this.$('article#post_5.via-email').length, 1); + + assert.equal(this.$('article:eq(0) .main-avatar').length, 1, 'renders the main avatar'); + } +}); + +postStreamTest('deleted posts', { + posts() { + const topic = Topic.create({ details: { created_by: { id: 123 } } }); + return [ + Post.create({ topic, id: 1, post_number: 1, deleted_at: new Date().toString() }), + ]; + }, + + test(assert) { + assert.equal(this.$('.topic-post.deleted').length, 1, 'it applies the deleted class'); + assert.equal(this.$('.deleted-user-avatar').length, 1, 'it has the trash avatar'); + } +}); diff --git a/test/javascripts/widgets/post-test.js.es6 b/test/javascripts/widgets/post-test.js.es6 new file mode 100644 index 00000000000..5c853c0dd65 --- /dev/null +++ b/test/javascripts/widgets/post-test.js.es6 @@ -0,0 +1,784 @@ +import { moduleForWidget, widgetTest } from 'helpers/widget-test'; + +moduleForWidget('post'); + +widgetTest('basic elements', { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { shareUrl: '/example', post_number: 1 }); + }, + test(assert) { + assert.ok(this.$('.names').length, 'includes poster name'); + + assert.ok(this.$('a.post-date').length, 'includes post date'); + assert.ok(this.$('a.post-date[data-share-url]').length); + assert.ok(this.$('a.post-date[data-post-number]').length); + } +}); + +widgetTest('wiki', { + template: '{{mount-widget widget="post" args=args editPost="editPost"}}', + setup() { + this.set('args', { wiki: true }); + this.on('editPost', () => this.editPostCalled = true); + }, + test(assert) { + click('.post-info.wiki'); + andThen(() => { + assert.ok(this.editPostCalled, 'clicking the wiki icon edits the post'); + }); + } +}); + +widgetTest('via-email', { + template: '{{mount-widget widget="post" args=args showRawEmail="showRawEmail"}}', + setup() { + this.set('args', { via_email: true, canViewRawEmail: true }); + this.on('showRawEmail', () => this.rawEmailShown = true); + }, + test(assert) { + click('.post-info.via-email'); + andThen(() => { + assert.ok(this.rawEmailShown, 'clicking the enveloppe shows the raw email'); + }); + } +}); + +widgetTest('via-email without permission', { + template: '{{mount-widget widget="post" args=args showRawEmail="showRawEmail"}}', + setup() { + this.set('args', { via_email: true, canViewRawEmail: false }); + this.on('showRawEmail', () => this.rawEmailShown = true); + }, + test(assert) { + click('.post-info.via-email'); + andThen(() => { + assert.ok(!this.rawEmailShown, `clicking the enveloppe doesn't show the raw email`); + }); + } +}); + +widgetTest('history', { + template: '{{mount-widget widget="post" args=args showHistory="showHistory"}}', + setup() { + this.set('args', { version: 3, canViewEditHistory: true }); + this.on('showHistory', () => this.historyShown = true); + }, + test(assert) { + click('.post-info.edits'); + andThen(() => { + assert.ok(this.historyShown, 'clicking the pencil shows the history'); + }); + } +}); + +widgetTest('history without view permission', { + template: '{{mount-widget widget="post" args=args showHistory="showHistory"}}', + setup() { + this.set('args', { version: 3, canViewEditHistory: false }); + this.on('showHistory', () => this.historyShown = true); + }, + test(assert) { + click('.post-info.edits'); + andThen(() => { + assert.ok(!this.historyShown, `clicking the pencil doesn't show the history`); + }); + } +}); + +widgetTest('whisper', { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { isWhisper: true }); + }, + test(assert) { + assert.ok(this.$('.topic-post.whisper').length === 1); + assert.ok(this.$('.post-info.whisper').length === 1); + } +}); + +widgetTest('like count button', { + template: '{{mount-widget widget="post" model=post args=args}}', + setup(store) { + const topic = store.createRecord('topic', {id: 123}); + const post = store.createRecord('post', { + id: 1, + post_number: 1, + topic, + like_count: 3, + actions_summary: [ {id: 2, count: 1, hidden: false, can_act: true} ] + }); + this.set('post', post); + this.set('args', { likeCount: 1 }); + }, + test(assert) { + assert.ok(this.$('button.like-count').length === 1); + assert.ok(this.$('.who-liked').length === 0); + + // toggle it on + click('button.like-count'); + andThen(() => { + assert.ok(this.$('.who-liked').length === 1); + assert.ok(this.$('.who-liked a.trigger-user-card').length === 1); + }); + + // toggle it off + click('button.like-count'); + andThen(() => { + assert.ok(this.$('.who-liked').length === 0); + assert.ok(this.$('.who-liked a.trigger-user-card').length === 0); + }); + } +}); + +widgetTest(`like count with no likes`, { + template: '{{mount-widget widget="post" model=post args=args}}', + setup() { + this.set('args', { likeCount: 0 }); + }, + test(assert) { + assert.ok(this.$('button.like-count').length === 0); + } +}); + +widgetTest('share button', { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { shareUrl: 'http://share-me.example.com' }); + }, + test(assert) { + assert.ok(!!this.$('.actions button[data-share-url]').length, 'it renders a share button'); + } +}); + +widgetTest('liking', { + template: '{{mount-widget widget="post-menu" args=args toggleLike="toggleLike"}}', + setup() { + const args = { showLike: true, canToggleLike: true }; + this.set('args', args); + this.on('toggleLike', () => { + args.liked = !args.liked; + args.likeCount = args.liked ? 1 : 0; + }); + }, + test(assert) { + assert.ok(!!this.$('.actions button.like').length); + assert.ok(this.$('.actions button.like-count').length === 0); + + click('.actions button.like'); + andThen(() => { + assert.ok(!this.$('.actions button.like').length); + assert.ok(!!this.$('.actions button.has-like').length); + assert.ok(this.$('.actions button.like-count').length === 1); + }); + + click('.actions button.has-like'); + andThen(() => { + assert.ok(!!this.$('.actions button.like').length); + assert.ok(!this.$('.actions button.has-like').length); + assert.ok(this.$('.actions button.like-count').length === 0); + }); + } +}); + +widgetTest('edit button', { + template: '{{mount-widget widget="post" args=args editPost="editPost"}}', + setup() { + this.set('args', { canEdit: true }); + this.on('editPost', () => this.editPostCalled = true); + }, + test(assert) { + click('button.edit'); + andThen(() => { + assert.ok(this.editPostCalled, 'it triggered the edit action'); + }); + } +}); + +widgetTest(`edit button - can't edit`, { + template: '{{mount-widget widget="post" args=args editPost="editPost"}}', + setup() { + this.set('args', { canEdit: false }); + }, + test(assert) { + assert.equal(this.$('button.edit').length, 0, `button is not displayed`); + } +}); + +widgetTest('recover button', { + template: '{{mount-widget widget="post" args=args deletePost="deletePost"}}', + setup() { + this.set('args', { canDelete: true }); + this.on('deletePost', () => this.deletePostCalled = true); + }, + test(assert) { + click('button.delete'); + andThen(() => { + assert.ok(this.deletePostCalled, 'it triggered the delete action'); + }); + } +}); + +widgetTest('delete topic button', { + template: '{{mount-widget widget="post" args=args deletePost="deletePost"}}', + setup() { + this.set('args', { canDeleteTopic: true }); + this.on('deletePost', () => this.deletePostCalled = true); + }, + test(assert) { + click('button.delete'); + andThen(() => { + assert.ok(this.deletePostCalled, 'it triggered the delete action'); + }); + } +}); + +widgetTest(`delete topic button - can't delete`, { + template: '{{mount-widget widget="post" args=args deletePost="deletePost"}}', + setup() { + this.set('args', { canDeleteTopic: false }); + }, + test(assert) { + assert.equal(this.$('button.delete').length, 0, `button is not displayed`); + } +}); + +widgetTest('recover topic button', { + template: '{{mount-widget widget="post" args=args recoverPost="recoverPost"}}', + setup() { + this.set('args', { canRecoverTopic: true }); + this.on('recoverPost', () => this.recovered = true); + }, + test(assert) { + click('button.recover'); + andThen(() => assert.ok(this.recovered)); + } +}); + +widgetTest(`recover topic button - can't recover`, { + template: '{{mount-widget widget="post" args=args deletePost="deletePost"}}', + setup() { + this.set('args', { canRecoverTopic: false }); + }, + test(assert) { + assert.equal(this.$('button.recover').length, 0, `button is not displayed`); + } +}); + +widgetTest('delete post button', { + template: '{{mount-widget widget="post" args=args deletePost="deletePost"}}', + setup() { + this.set('args', { canDelete: true }); + this.on('deletePost', () => this.deletePostCalled = true); + }, + test(assert) { + click('button.delete'); + andThen(() => { + assert.ok(this.deletePostCalled, 'it triggered the delete action'); + }); + } +}); + +widgetTest(`delete post button - can't delete`, { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { canDelete: false }); + }, + test(assert) { + assert.equal(this.$('button.delete').length, 0, `button is not displayed`); + } +}); + +widgetTest('recover post button', { + template: '{{mount-widget widget="post" args=args recoverPost="recoverPost"}}', + setup() { + this.set('args', { canRecover: true }); + this.on('recoverPost', () => this.recovered = true); + }, + test(assert) { + click('button.recover'); + andThen(() => assert.ok(this.recovered)); + } +}); + +widgetTest(`recover post button - can't recover`, { + template: '{{mount-widget widget="post" args=args deletePost="deletePost"}}', + setup() { + this.set('args', { canRecover: false }); + }, + test(assert) { + assert.equal(this.$('button.recover').length, 0, `button is not displayed`); + } +}); + +widgetTest(`flagging`, { + template: '{{mount-widget widget="post" args=args showFlags="showFlags"}}', + setup() { + this.set('args', { canFlag: true }); + this.on('showFlags', () => this.flagsShown = true); + }, + test(assert) { + assert.ok(this.$('button.create-flag').length === 1); + + click('button.create-flag'); + andThen(() => { + assert.ok(this.flagsShown, 'it triggered the action'); + }); + } +}); + +widgetTest(`flagging: can't flag`, { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { canFlag: false }); + }, + test(assert) { + assert.ok(this.$('button.create-flag').length === 0); + } +}); + +widgetTest(`read indicator`, { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { read: true }); + }, + test(assert) { + assert.ok(this.$('.read-state.read').length); + } +}); + +widgetTest(`unread indicator`, { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { read: false }); + }, + test(assert) { + assert.ok(this.$('.read-state').length); + } +}); + +widgetTest("reply directly above (supressed)", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { + replyToUsername: 'eviltrout', + replyToAvatarTemplate: '/images/avatar.png', + replyDirectlyAbove: true + }); + }, + test(assert) { + assert.equal(this.$('a.reply-to-tab').length, 0, 'hides the tab'); + assert.equal(this.$('.avoid-tab').length, 0, "doesn't have the avoid tab class"); + } +}); + +widgetTest("reply a few posts above (supressed)", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { + replyToUsername: 'eviltrout', + replyToAvatarTemplate: '/images/avatar.png', + replyDirectlyAbove: false + }); + }, + test(assert) { + assert.ok(this.$('a.reply-to-tab').length, 'shows the tab'); + assert.equal(this.$('.avoid-tab').length, 1, "has the avoid tab class"); + } +}); + +widgetTest("reply directly above", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { + replyToUsername: 'eviltrout', + replyToAvatarTemplate: '/images/avatar.png', + replyDirectlyAbove: true + }); + this.siteSettings.suppress_reply_directly_above = false; + }, + test(assert) { + assert.equal(this.$('.avoid-tab').length, 1, "has the avoid tab class"); + click('a.reply-to-tab'); + andThen(() => { + assert.equal(this.$('section.embedded-posts.top .cooked').length, 1); + assert.equal(this.$('section.embedded-posts i.fa-arrow-up').length, 1); + }); + } +}); + +widgetTest("cooked content hidden", { + template: '{{mount-widget widget="post" args=args expandHidden="expandHidden"}}', + setup() { + this.set('args', { cooked_hidden: true }); + this.on('expandHidden', () => this.unhidden = true); + }, + test(assert) { + click('.topic-body .expand-hidden'); + andThen(() => { + assert.ok(this.unhidden, 'triggers the action'); + }); + } +}); + +widgetTest("expand first post", { + template: '{{mount-widget widget="post" model=post args=args}}', + setup(store) { + this.set('args', { expandablePost: true }); + this.set('post', store.createRecord('post', { id: 1234 })); + }, + test(assert) { + click('.topic-body .expand-post'); + andThen(() => { + assert.equal(this.$('.expand-post').length, 0, 'button is gone'); + }); + } +}); + +widgetTest("can't bookmark", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { canBookmark: false }); + }, + test(assert) { + assert.equal(this.$('button.bookmark').length, 0); + assert.equal(this.$('button.bookmarked').length, 0); + } +}); + +widgetTest("bookmark", { + template: '{{mount-widget widget="post" args=args toggleBookmark="toggleBookmark"}}', + setup() { + const args = { canBookmark: true }; + + this.set('args', args); + this.on('toggleBookmark', () => args.bookmarked = true); + }, + test(assert) { + assert.equal(this.$('.post-menu-area .bookmark').length, 1); + assert.equal(this.$('button.bookmarked').length, 0); + + click('button.bookmark'); + andThen(() => { + assert.equal(this.$('button.bookmarked').length, 1); + }); + } +}); + +widgetTest("can't show admin menu when you can't manage", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { canManage: false }); + }, + test(assert) { + assert.equal(this.$('.post-menu-area .show-post-admin-menu').length, 0); + } +}); + +widgetTest("show admin menu", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { canManage: true }); + }, + test(assert) { + assert.equal(this.$('.post-admin-menu').length, 0); + click('.post-menu-area .show-post-admin-menu'); + andThen(() => { + assert.equal(this.$('.post-admin-menu').length, 1, 'it shows the popup'); + }); + click('.post-menu-area'); + andThen(() => { + assert.equal(this.$('.post-admin-menu').length, 0, 'clicking outside clears the popup'); + }); + } +}); + +widgetTest("toggle moderator post", { + template: '{{mount-widget widget="post" args=args togglePostType="togglePostType"}}', + setup() { + this.set('args', { canManage: true }); + this.on('togglePostType', () => this.toggled = true); + }, + test(assert) { + click('.post-menu-area .show-post-admin-menu'); + click('.post-admin-menu .toggle-post-type'); + andThen(() => { + assert.ok(this.toggled); + assert.equal(this.$('.post-admin-menu').length, 0, 'also hides the menu'); + }); + } +}); +widgetTest("toggle moderator post", { + template: '{{mount-widget widget="post" args=args togglePostType="togglePostType"}}', + setup() { + this.set('args', { canManage: true }); + this.on('togglePostType', () => this.toggled = true); + }, + test(assert) { + click('.post-menu-area .show-post-admin-menu'); + click('.post-admin-menu .toggle-post-type'); + andThen(() => { + assert.ok(this.toggled); + assert.equal(this.$('.post-admin-menu').length, 0, 'also hides the menu'); + }); + } +}); + +widgetTest("rebake post", { + template: '{{mount-widget widget="post" args=args rebakePost="rebakePost"}}', + setup() { + this.set('args', { canManage: true }); + this.on('rebakePost', () => this.baked = true); + }, + test(assert) { + click('.post-menu-area .show-post-admin-menu'); + click('.post-admin-menu .rebuild-html'); + andThen(() => { + assert.ok(this.baked); + assert.equal(this.$('.post-admin-menu').length, 0, 'also hides the menu'); + }); + } +}); + +widgetTest("unhide post", { + template: '{{mount-widget widget="post" args=args unhidePost="unhidePost"}}', + setup() { + this.set('args', { canManage: true, hidden: true }); + this.on('unhidePost', () => this.unhidden = true); + }, + test(assert) { + click('.post-menu-area .show-post-admin-menu'); + click('.post-admin-menu .unhide-post'); + andThen(() => { + assert.ok(this.unhidden); + assert.equal(this.$('.post-admin-menu').length, 0, 'also hides the menu'); + }); + } +}); + +widgetTest("change owner", { + template: '{{mount-widget widget="post" args=args changePostOwner="changePostOwner"}}', + setup() { + this.currentUser.admin = true; + this.set('args', { canManage: true }); + this.on('changePostOwner', () => this.owned = true); + }, + test(assert) { + click('.post-menu-area .show-post-admin-menu'); + click('.post-admin-menu .change-owner'); + andThen(() => { + assert.ok(this.owned); + assert.equal(this.$('.post-admin-menu').length, 0, 'also hides the menu'); + }); + } +}); + +widgetTest("reply", { + template: '{{mount-widget widget="post" args=args replyToPost="replyToPost"}}', + setup() { + this.set('args', { canCreatePost: true }); + this.on('replyToPost', () => this.replied = true); + }, + test(assert) { + click('.post-controls .create'); + andThen(() => { + assert.ok(this.replied); + }); + } +}); + +widgetTest("reply - without permissions", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { canCreatePost: false }); + }, + test(assert) { + assert.equal(this.$('.post-controls .create').length, 0); + } +}); + +widgetTest("replies - no replies", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', {replyCount: 0}); + }, + test(assert) { + assert.equal(this.$('button.show-replies').length, 0); + } +}); + +widgetTest("replies - multiple replies", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.siteSettings.suppress_reply_directly_below = true; + this.set('args', {replyCount: 2, replyDirectlyBelow: true}); + }, + test(assert) { + assert.equal(this.$('button.show-replies').length, 1); + } +}); + +widgetTest("replies - one below, suppressed", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.siteSettings.suppress_reply_directly_below = true; + this.set('args', {replyCount: 1, replyDirectlyBelow: true}); + }, + test(assert) { + assert.equal(this.$('button.show-replies').length, 0); + } +}); + +widgetTest("replies - one below, not suppressed", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.siteSettings.suppress_reply_directly_below = false; + this.set('args', {id: 6654, replyCount: 1, replyDirectlyBelow: true}); + }, + test(assert) { + click('button.show-replies'); + andThen(() => { + assert.equal(this.$('section.embedded-posts.bottom .cooked').length, 1); + assert.equal(this.$('section.embedded-posts i.fa-arrow-down').length, 1); + }); + } +}); + +widgetTest("topic map not shown", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { showTopicMap: false }); + }, + test(assert) { + assert.equal(this.$('.topic-map').length, 0); + } +}); + +widgetTest("topic map - few posts", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { + showTopicMap: true, + topicPostsCount: 2, + participants: [ + {username: 'eviltrout'}, + {username: 'codinghorror'}, + ] + }); + }, + test(assert) { + assert.equal(this.$('li.avatars a.poster').length, 0, 'shows no participants when collapsed'); + + click('nav.buttons button'); + andThen(() => { + assert.equal(this.$('.topic-map-expanded a.poster').length, 2, 'shows all when expanded'); + }); + } +}); + +widgetTest("topic map - participants", { + template: '{{mount-widget widget="post" args=args toggleParticipant="toggleParticipant"}}', + setup() { + this.set('args', { + showTopicMap: true, + topicPostsCount: 10, + participants: [ + {username: 'eviltrout'}, + {username: 'codinghorror'}, + {username: 'sam'}, + {username: 'ZogStrIP'}, + ], + userFilters: ['sam', 'codinghorror'] + }); + + this.on('toggleParticipant', () => this.participantToggled = true); + }, + test(assert) { + assert.equal(this.$('li.avatars a.poster').length, 3, 'limits to three participants'); + + click('nav.buttons button'); + andThen(() => { + assert.equal(this.$('li.avatars a.poster').length, 0); + assert.equal(this.$('.topic-map-expanded a.poster').length, 4, 'shows all when expanded'); + assert.equal(this.$('a.poster.toggled').length, 2, 'two are toggled'); + }); + + click('.topic-map-expanded a.poster:eq(0)'); + andThen(() => assert.ok(this.participantToggled)); + } +}); + +widgetTest("topic map - links", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { + showTopicMap: true, + topicLinks: [ + {url: 'http://link1.example.com', clicks: 0}, + {url: 'http://link2.example.com', clicks: 0}, + {url: 'http://link3.example.com', clicks: 0}, + {url: 'http://link4.example.com', clicks: 0}, + {url: 'http://link5.example.com', clicks: 0}, + {url: 'http://link6.example.com', clicks: 0}, + ] + }); + }, + test(assert) { + assert.equal(this.$('.topic-map').length, 1); + assert.equal(this.$('.map.map-collapsed').length, 1); + assert.equal(this.$('.topic-map-expanded').length, 0); + + click('nav.buttons button'); + andThen(() => { + assert.equal(this.$('.map.map-collapsed').length, 0); + assert.equal(this.$('.topic-map i.fa-chevron-up').length, 1); + assert.equal(this.$('.topic-map-expanded').length, 1); + assert.equal(this.$('.topic-map-expanded .topic-link').length, 5, 'it limits the links displayed'); + }); + + click('.link-summary a'); + andThen(() => { + assert.equal(this.$('.topic-map-expanded .topic-link').length, 6, 'all links now shown'); + }); + } +}); + +widgetTest("topic map - no summary", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { showTopicMap: true }); + }, + test(assert) { + assert.equal(this.$('.toggle-summary').length, 0); + } +}); + +widgetTest("topic map - has summary", { + template: '{{mount-widget widget="post" args=args toggleSummary="toggleSummary"}}', + setup() { + this.set('args', { showTopicMap: true, hasTopicSummary: true }); + this.on('toggleSummary', () => this.summaryToggled = true); + }, + test(assert) { + assert.equal(this.$('.toggle-summary').length, 1); + + click('.toggle-summary button'); + andThen(() => assert.ok(this.summaryToggled)); + } +}); + +widgetTest("pm map", { + template: '{{mount-widget widget="post" args=args}}', + setup() { + this.set('args', { + showTopicMap: true, + showPMMap: true, + allowedGroups: [], + allowedUsers: [ Ember.Object.create({ username: 'eviltrout' }) ] + }); + }, + test(assert) { + assert.equal(this.$('.private-message-map').length, 1); + assert.equal(this.$('.private-message-map .user').length, 1); + } +}); diff --git a/test/javascripts/widgets/poster-name-test.js.es6 b/test/javascripts/widgets/poster-name-test.js.es6 new file mode 100644 index 00000000000..5e6782625a2 --- /dev/null +++ b/test/javascripts/widgets/poster-name-test.js.es6 @@ -0,0 +1,67 @@ +import { moduleForWidget, widgetTest } from 'helpers/widget-test'; + +moduleForWidget('poster-name'); + +widgetTest('basic rendering', { + template: '{{mount-widget widget="poster-name" args=args}}', + setup() { + this.set('args', { + username: 'eviltrout', + usernameUrl: '/users/eviltrout', + name: 'Robin Ward', + user_title: 'Trout Master' }); + }, + test(assert) { + assert.ok(this.$('.names').length); + assert.ok(this.$('span.username').length); + assert.ok(this.$('a[data-auto-route=true]').length); + assert.ok(this.$('a[data-user-card=eviltrout]').length); + assert.equal(this.$('.username a').text(), 'eviltrout'); + assert.equal(this.$('.full-name a').text(), 'Robin Ward'); + assert.equal(this.$('.user-title').text(), 'Trout Master'); + } +}); + +widgetTest('extra classes and glyphs', { + template: '{{mount-widget widget="poster-name" args=args}}', + setup() { + this.set('args', { + username: 'eviltrout', + usernameUrl: '/users/eviltrout', + staff: true, + admin: true, + moderator: true, + new_user: true, + primary_group_name: 'fish' + }); + }, + test(assert) { + assert.ok(this.$('span.staff').length); + assert.ok(this.$('span.admin').length); + assert.ok(this.$('span.moderator').length); + assert.ok(this.$('i.fa-shield').length); + assert.ok(this.$('span.new-user').length); + assert.ok(this.$('span.fish').length); + } +}); + +widgetTest('disable display name on posts', { + template: '{{mount-widget widget="poster-name" args=args}}', + setup() { + this.siteSettings.display_name_on_posts = false; + this.set('args', { username: 'eviltrout', name: 'Robin Ward' }); + }, + test(assert) { + assert.equal(this.$('.full-name').length, 0); + } +}); + +widgetTest("doesn't render a name if it's similar to the username", { + template: '{{mount-widget widget="poster-name" args=args}}', + setup() { + this.set('args', { username: 'eviltrout', name: 'evil-trout' }); + }, + test(assert) { + assert.equal(this.$('.full-name').length, 0); + } +}); diff --git a/test/javascripts/widgets/widget-test.js.es6 b/test/javascripts/widgets/widget-test.js.es6 new file mode 100644 index 00000000000..5680516f6bf --- /dev/null +++ b/test/javascripts/widgets/widget-test.js.es6 @@ -0,0 +1,245 @@ +import { moduleForWidget, widgetTest } from 'helpers/widget-test'; +import { createWidget } from 'discourse/widgets/widget'; +import { withPluginApi } from 'discourse/lib/plugin-api'; + +moduleForWidget('base'); + +widgetTest('widget attributes are passed in via args', { + template: `{{mount-widget widget="hello-test" args=args}}`, + + setup() { + createWidget('hello-test', { + tagName: 'div.test', + + html(attrs) { + return `Hello ${attrs.name}`; + }, + }); + + this.set('args', { name: 'Robin' }); + }, + + test(assert) { + assert.equal(this.$('.test').text(), "Hello Robin"); + } +}); + +widgetTest('buildClasses', { + template: `{{mount-widget widget="classname-test" args=args}}`, + + setup() { + createWidget('classname-test', { + tagName: 'div.test', + + buildClasses(attrs) { + return ['static', attrs.dynamic]; + } + }); + + this.set('args', { dynamic: 'cool-class' }); + }, + + test(assert) { + assert.ok(this.$('.test.static.cool-class').length, 'it has all the classes'); + } +}); + +widgetTest('buildAttributes', { + template: `{{mount-widget widget="attributes-test" args=args}}`, + + setup() { + createWidget('attributes-test', { + tagName: 'div.test', + + buildAttributes(attrs) { + return { "data-evil": 'trout', "aria-label": attrs.label }; + } + }); + + this.set('args', { label: 'accessibility' }); + }, + + test(assert) { + assert.ok(this.$('.test[data-evil=trout]').length); + assert.ok(this.$('.test[aria-label=accessibility]').length); + } +}); + +widgetTest('buildId', { + template: `{{mount-widget widget="id-test" args=args}}`, + + setup() { + createWidget('id-test', { + buildId(attrs) { + return `test-${attrs.id}`; + } + }); + + this.set('args', { id: 1234 }); + }, + + test(assert) { + assert.ok(this.$('#test-1234').length); + } +}); + +widgetTest('widget state', { + template: `{{mount-widget widget="state-test"}}`, + + setup() { + createWidget('state-test', { + tagName: 'button.test', + + defaultState() { + return { clicks: 0 }; + }, + + html(attrs, state) { + return `${state.clicks} clicks`; + }, + + click() { + this.state.clicks++; + } + }); + }, + + test(assert) { + assert.ok(this.$('button.test').length, 'it renders the button'); + assert.equal(this.$('button.test').text(), "0 clicks"); + + click(this.$('button')); + andThen(() => { + assert.equal(this.$('button.test').text(), "1 clicks"); + }); + } +}); + +widgetTest('widget update with promise', { + template: `{{mount-widget widget="promise-test"}}`, + + setup() { + createWidget('promise-test', { + tagName: 'button.test', + + html(attrs, state) { + return state.name || "No name"; + }, + + click() { + return new Ember.RSVP.Promise(resolve => { + Ember.run.next(() => { + this.state.name = "Robin"; + resolve(); + }); + }); + } + }); + }, + + test(assert) { + assert.equal(this.$('button.test').text(), "No name"); + + click(this.$('button')); + andThen(() => { + assert.equal(this.$('button.test').text(), "Robin"); + }); + } +}); + +widgetTest('widget attaching', { + template: `{{mount-widget widget="attach-test"}}`, + + setup() { + createWidget('test-embedded', { tagName: 'div.embedded' }); + + createWidget('attach-test', { + tagName: 'div.container', + html() { + return this.attach('test-embedded'); + }, + }); + }, + + test(assert) { + assert.ok(this.$('.container').length, "renders container"); + assert.ok(this.$('.container .embedded').length, "renders attached"); + } +}); + +widgetTest('widget decorating', { + template: `{{mount-widget widget="decorate-test"}}`, + + setup() { + createWidget('decorate-test', { + tagName: 'div.decorate', + html() { + return "main content"; + }, + }); + + withPluginApi('0.1', api => { + api.decorateWidget('decorate-test:before', dec => { + return dec.h('b', 'before'); + }); + + api.decorateWidget('decorate-test:after', dec => { + return dec.h('i', 'after'); + }); + }); + }, + + test(assert) { + assert.ok(this.$('.decorate').length); + assert.equal(this.$('.decorate b').text(), 'before'); + assert.equal(this.$('.decorate i').text(), 'after'); + } +}); + +widgetTest('widget settings', { + template: `{{mount-widget widget="settings-test"}}`, + + setup() { + createWidget('settings-test', { + tagName: 'div.settings', + + settings: { + age: 36 + }, + + html() { + return `age is ${this.settings.age}`; + }, + }); + }, + + test(assert) { + assert.equal(this.$('.settings').text(), 'age is 36'); + } +}); + +widgetTest('override settings', { + template: `{{mount-widget widget="ov-settings-test"}}`, + + setup() { + createWidget('ov-settings-test', { + tagName: 'div.settings', + + settings: { + age: 36 + }, + + html() { + return `age is ${this.settings.age}`; + }, + }); + + withPluginApi('0.1', api => { + api.changeWidgetSetting('ov-settings-test', 'age', 37); + }); + }, + + test(assert) { + assert.equal(this.$('.settings').text(), 'age is 37'); + } +}); diff --git a/test/stylesheets/test_helper.css b/test/stylesheets/test_helper.css index c0d5f7f11ec..f0e5ac700c7 100644 --- a/test/stylesheets/test_helper.css +++ b/test/stylesheets/test_helper.css @@ -5,3 +5,11 @@ .modal-backdrop { display: none; } + +.emoji-modal-wrapper { + display: none; +} + +.emoji-modal { + position: relative; +} diff --git a/vendor/assets/javascripts/browser-update.js.erb b/vendor/assets/javascripts/browser-update.js.erb index ef9d05b31d4..918c6f775ef 100644 --- a/vendor/assets/javascripts/browser-update.js.erb +++ b/vendor/assets/javascripts/browser-update.js.erb @@ -17,7 +17,7 @@ var $buo = function() { badAndroid = true; } - // sam: my main concern here is mobile, but its an outlier, for now we support ie9, set conditionally and stuff with pushState + // sam: my main concern here is mobile, but its an outlier, for now we support ie10, set conditionally and stuff with pushState if (window.ie === "new" || (window.history && window.history.pushState && !badAndroid)) { return; } @@ -62,4 +62,4 @@ var $buo = function() { $bu=$buo(); -})(this); \ No newline at end of file +})(this); diff --git a/vendor/assets/javascripts/handlebars.runtime.js b/vendor/assets/javascripts/handlebars.runtime.js new file mode 100644 index 00000000000..95049f3b8d4 --- /dev/null +++ b/vendor/assets/javascripts/handlebars.runtime.js @@ -0,0 +1,1240 @@ +/*! + + handlebars v4.0.5 + +Copyright (C) 2011-2015 by Yehuda Katz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +@license +*/ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["Handlebars"] = factory(); + else + root["Handlebars"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _interopRequireWildcard = __webpack_require__(1)['default']; + + var _interopRequireDefault = __webpack_require__(2)['default']; + + exports.__esModule = true; + + var _handlebarsBase = __webpack_require__(3); + + var base = _interopRequireWildcard(_handlebarsBase); + + // Each of these augment the Handlebars object. No need to setup here. + // (This is done to easily share code between commonjs and browse envs) + + var _handlebarsSafeString = __webpack_require__(17); + + var _handlebarsSafeString2 = _interopRequireDefault(_handlebarsSafeString); + + var _handlebarsException = __webpack_require__(5); + + var _handlebarsException2 = _interopRequireDefault(_handlebarsException); + + var _handlebarsUtils = __webpack_require__(4); + + var Utils = _interopRequireWildcard(_handlebarsUtils); + + var _handlebarsRuntime = __webpack_require__(18); + + var runtime = _interopRequireWildcard(_handlebarsRuntime); + + var _handlebarsNoConflict = __webpack_require__(19); + + var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict); + + // For compatibility and usage outside of module systems, make the Handlebars object a namespace + function create() { + var hb = new base.HandlebarsEnvironment(); + + Utils.extend(hb, base); + hb.SafeString = _handlebarsSafeString2['default']; + hb.Exception = _handlebarsException2['default']; + hb.Utils = Utils; + hb.escapeExpression = Utils.escapeExpression; + + hb.VM = runtime; + hb.template = function (spec) { + return runtime.template(spec, hb); + }; + + return hb; + } + + var inst = create(); + inst.create = create; + + _handlebarsNoConflict2['default'](inst); + + inst['default'] = inst; + + exports['default'] = inst; + module.exports = exports['default']; + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + "use strict"; + + exports["default"] = function (obj) { + if (obj && obj.__esModule) { + return obj; + } else { + var newObj = {}; + + if (obj != null) { + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; + } + } + + newObj["default"] = obj; + return newObj; + } + }; + + exports.__esModule = true; + +/***/ }, +/* 2 */ +/***/ function(module, exports) { + + "use strict"; + + exports["default"] = function (obj) { + return obj && obj.__esModule ? obj : { + "default": obj + }; + }; + + exports.__esModule = true; + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _interopRequireDefault = __webpack_require__(2)['default']; + + exports.__esModule = true; + exports.HandlebarsEnvironment = HandlebarsEnvironment; + + var _utils = __webpack_require__(4); + + var _exception = __webpack_require__(5); + + var _exception2 = _interopRequireDefault(_exception); + + var _helpers = __webpack_require__(6); + + var _decorators = __webpack_require__(14); + + var _logger = __webpack_require__(16); + + var _logger2 = _interopRequireDefault(_logger); + + var VERSION = '4.0.5'; + exports.VERSION = VERSION; + var COMPILER_REVISION = 7; + + exports.COMPILER_REVISION = COMPILER_REVISION; + var REVISION_CHANGES = { + 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it + 2: '== 1.0.0-rc.3', + 3: '== 1.0.0-rc.4', + 4: '== 1.x.x', + 5: '== 2.0.0-alpha.x', + 6: '>= 2.0.0-beta.1', + 7: '>= 4.0.0' + }; + + exports.REVISION_CHANGES = REVISION_CHANGES; + var objectType = '[object Object]'; + + function HandlebarsEnvironment(helpers, partials, decorators) { + this.helpers = helpers || {}; + this.partials = partials || {}; + this.decorators = decorators || {}; + + _helpers.registerDefaultHelpers(this); + _decorators.registerDefaultDecorators(this); + } + + HandlebarsEnvironment.prototype = { + constructor: HandlebarsEnvironment, + + logger: _logger2['default'], + log: _logger2['default'].log, + + registerHelper: function registerHelper(name, fn) { + if (_utils.toString.call(name) === objectType) { + if (fn) { + throw new _exception2['default']('Arg not supported with multiple helpers'); + } + _utils.extend(this.helpers, name); + } else { + this.helpers[name] = fn; + } + }, + unregisterHelper: function unregisterHelper(name) { + delete this.helpers[name]; + }, + + registerPartial: function registerPartial(name, partial) { + if (_utils.toString.call(name) === objectType) { + _utils.extend(this.partials, name); + } else { + if (typeof partial === 'undefined') { + throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined'); + } + this.partials[name] = partial; + } + }, + unregisterPartial: function unregisterPartial(name) { + delete this.partials[name]; + }, + + registerDecorator: function registerDecorator(name, fn) { + if (_utils.toString.call(name) === objectType) { + if (fn) { + throw new _exception2['default']('Arg not supported with multiple decorators'); + } + _utils.extend(this.decorators, name); + } else { + this.decorators[name] = fn; + } + }, + unregisterDecorator: function unregisterDecorator(name) { + delete this.decorators[name]; + } + }; + + var log = _logger2['default'].log; + + exports.log = log; + exports.createFrame = _utils.createFrame; + exports.logger = _logger2['default']; + +/***/ }, +/* 4 */ +/***/ function(module, exports) { + + 'use strict'; + + exports.__esModule = true; + exports.extend = extend; + exports.indexOf = indexOf; + exports.escapeExpression = escapeExpression; + exports.isEmpty = isEmpty; + exports.createFrame = createFrame; + exports.blockParams = blockParams; + exports.appendContextPath = appendContextPath; + var escape = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`', + '=': '=' + }; + + var badChars = /[&<>"'`=]/g, + possible = /[&<>"'`=]/; + + function escapeChar(chr) { + return escape[chr]; + } + + function extend(obj /* , ...source */) { + for (var i = 1; i < arguments.length; i++) { + for (var key in arguments[i]) { + if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { + obj[key] = arguments[i][key]; + } + } + } + + return obj; + } + + var toString = Object.prototype.toString; + + exports.toString = toString; + // Sourced from lodash + // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt + /* eslint-disable func-style */ + var isFunction = function isFunction(value) { + return typeof value === 'function'; + }; + // fallback for older versions of Chrome and Safari + /* istanbul ignore next */ + if (isFunction(/x/)) { + exports.isFunction = isFunction = function (value) { + return typeof value === 'function' && toString.call(value) === '[object Function]'; + }; + } + exports.isFunction = isFunction; + + /* eslint-enable func-style */ + + /* istanbul ignore next */ + var isArray = Array.isArray || function (value) { + return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false; + }; + + exports.isArray = isArray; + // Older IE versions do not directly support indexOf so we must implement our own, sadly. + + function indexOf(array, value) { + for (var i = 0, len = array.length; i < len; i++) { + if (array[i] === value) { + return i; + } + } + return -1; + } + + function escapeExpression(string) { + if (typeof string !== 'string') { + // don't escape SafeStrings, since they're already safe + if (string && string.toHTML) { + return string.toHTML(); + } else if (string == null) { + return ''; + } else if (!string) { + return string + ''; + } + + // Force a string conversion as this will be done by the append regardless and + // the regex test will do this transparently behind the scenes, causing issues if + // an object's to string has escaped characters in it. + string = '' + string; + } + + if (!possible.test(string)) { + return string; + } + return string.replace(badChars, escapeChar); + } + + function isEmpty(value) { + if (!value && value !== 0) { + return true; + } else if (isArray(value) && value.length === 0) { + return true; + } else { + return false; + } + } + + function createFrame(object) { + var frame = extend({}, object); + frame._parent = object; + return frame; + } + + function blockParams(params, ids) { + params.path = ids; + return params; + } + + function appendContextPath(contextPath, id) { + return (contextPath ? contextPath + '.' : '') + id; + } + +/***/ }, +/* 5 */ +/***/ function(module, exports) { + + 'use strict'; + + exports.__esModule = true; + + var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; + + function Exception(message, node) { + var loc = node && node.loc, + line = undefined, + column = undefined; + if (loc) { + line = loc.start.line; + column = loc.start.column; + + message += ' - ' + line + ':' + column; + } + + var tmp = Error.prototype.constructor.call(this, message); + + // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. + for (var idx = 0; idx < errorProps.length; idx++) { + this[errorProps[idx]] = tmp[errorProps[idx]]; + } + + /* istanbul ignore else */ + if (Error.captureStackTrace) { + Error.captureStackTrace(this, Exception); + } + + if (loc) { + this.lineNumber = line; + this.column = column; + } + } + + Exception.prototype = new Error(); + + exports['default'] = Exception; + module.exports = exports['default']; + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _interopRequireDefault = __webpack_require__(2)['default']; + + exports.__esModule = true; + exports.registerDefaultHelpers = registerDefaultHelpers; + + var _helpersBlockHelperMissing = __webpack_require__(7); + + var _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing); + + var _helpersEach = __webpack_require__(8); + + var _helpersEach2 = _interopRequireDefault(_helpersEach); + + var _helpersHelperMissing = __webpack_require__(9); + + var _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing); + + var _helpersIf = __webpack_require__(10); + + var _helpersIf2 = _interopRequireDefault(_helpersIf); + + var _helpersLog = __webpack_require__(11); + + var _helpersLog2 = _interopRequireDefault(_helpersLog); + + var _helpersLookup = __webpack_require__(12); + + var _helpersLookup2 = _interopRequireDefault(_helpersLookup); + + var _helpersWith = __webpack_require__(13); + + var _helpersWith2 = _interopRequireDefault(_helpersWith); + + function registerDefaultHelpers(instance) { + _helpersBlockHelperMissing2['default'](instance); + _helpersEach2['default'](instance); + _helpersHelperMissing2['default'](instance); + _helpersIf2['default'](instance); + _helpersLog2['default'](instance); + _helpersLookup2['default'](instance); + _helpersWith2['default'](instance); + } + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _utils = __webpack_require__(4); + + exports['default'] = function (instance) { + instance.registerHelper('blockHelperMissing', function (context, options) { + var inverse = options.inverse, + fn = options.fn; + + if (context === true) { + return fn(this); + } else if (context === false || context == null) { + return inverse(this); + } else if (_utils.isArray(context)) { + if (context.length > 0) { + if (options.ids) { + options.ids = [options.name]; + } + + return instance.helpers.each(context, options); + } else { + return inverse(this); + } + } else { + if (options.data && options.ids) { + var data = _utils.createFrame(options.data); + data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name); + options = { data: data }; + } + + return fn(context, options); + } + }); + }; + + module.exports = exports['default']; + +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _interopRequireDefault = __webpack_require__(2)['default']; + + exports.__esModule = true; + + var _utils = __webpack_require__(4); + + var _exception = __webpack_require__(5); + + var _exception2 = _interopRequireDefault(_exception); + + exports['default'] = function (instance) { + instance.registerHelper('each', function (context, options) { + if (!options) { + throw new _exception2['default']('Must pass iterator to #each'); + } + + var fn = options.fn, + inverse = options.inverse, + i = 0, + ret = '', + data = undefined, + contextPath = undefined; + + if (options.data && options.ids) { + contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.'; + } + + if (_utils.isFunction(context)) { + context = context.call(this); + } + + if (options.data) { + data = _utils.createFrame(options.data); + } + + function execIteration(field, index, last) { + if (data) { + data.key = field; + data.index = index; + data.first = index === 0; + data.last = !!last; + + if (contextPath) { + data.contextPath = contextPath + field; + } + } + + ret = ret + fn(context[field], { + data: data, + blockParams: _utils.blockParams([context[field], field], [contextPath + field, null]) + }); + } + + if (context && typeof context === 'object') { + if (_utils.isArray(context)) { + for (var j = context.length; i < j; i++) { + if (i in context) { + execIteration(i, i, i === context.length - 1); + } + } + } else { + var priorKey = undefined; + + for (var key in context) { + if (context.hasOwnProperty(key)) { + // We're running the iterations one step out of sync so we can detect + // the last iteration without have to scan the object twice and create + // an itermediate keys array. + if (priorKey !== undefined) { + execIteration(priorKey, i - 1); + } + priorKey = key; + i++; + } + } + if (priorKey !== undefined) { + execIteration(priorKey, i - 1, true); + } + } + } + + if (i === 0) { + ret = inverse(this); + } + + return ret; + }); + }; + + module.exports = exports['default']; + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _interopRequireDefault = __webpack_require__(2)['default']; + + exports.__esModule = true; + + var _exception = __webpack_require__(5); + + var _exception2 = _interopRequireDefault(_exception); + + exports['default'] = function (instance) { + instance.registerHelper('helperMissing', function () /* [args, ]options */{ + if (arguments.length === 1) { + // A missing field in a {{foo}} construct. + return undefined; + } else { + // Someone is actually trying to call something, blow up. + throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"'); + } + }); + }; + + module.exports = exports['default']; + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _utils = __webpack_require__(4); + + exports['default'] = function (instance) { + instance.registerHelper('if', function (conditional, options) { + if (_utils.isFunction(conditional)) { + conditional = conditional.call(this); + } + + // Default behavior is to render the positive path if the value is truthy and not empty. + // The `includeZero` option may be set to treat the condtional as purely not empty based on the + // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative. + if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) { + return options.inverse(this); + } else { + return options.fn(this); + } + }); + + instance.registerHelper('unless', function (conditional, options) { + return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash }); + }); + }; + + module.exports = exports['default']; + +/***/ }, +/* 11 */ +/***/ function(module, exports) { + + 'use strict'; + + exports.__esModule = true; + + exports['default'] = function (instance) { + instance.registerHelper('log', function () /* message, options */{ + var args = [undefined], + options = arguments[arguments.length - 1]; + for (var i = 0; i < arguments.length - 1; i++) { + args.push(arguments[i]); + } + + var level = 1; + if (options.hash.level != null) { + level = options.hash.level; + } else if (options.data && options.data.level != null) { + level = options.data.level; + } + args[0] = level; + + instance.log.apply(instance, args); + }); + }; + + module.exports = exports['default']; + +/***/ }, +/* 12 */ +/***/ function(module, exports) { + + 'use strict'; + + exports.__esModule = true; + + exports['default'] = function (instance) { + instance.registerHelper('lookup', function (obj, field) { + return obj && obj[field]; + }); + }; + + module.exports = exports['default']; + +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _utils = __webpack_require__(4); + + exports['default'] = function (instance) { + instance.registerHelper('with', function (context, options) { + if (_utils.isFunction(context)) { + context = context.call(this); + } + + var fn = options.fn; + + if (!_utils.isEmpty(context)) { + var data = options.data; + if (options.data && options.ids) { + data = _utils.createFrame(options.data); + data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]); + } + + return fn(context, { + data: data, + blockParams: _utils.blockParams([context], [data && data.contextPath]) + }); + } else { + return options.inverse(this); + } + }); + }; + + module.exports = exports['default']; + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _interopRequireDefault = __webpack_require__(2)['default']; + + exports.__esModule = true; + exports.registerDefaultDecorators = registerDefaultDecorators; + + var _decoratorsInline = __webpack_require__(15); + + var _decoratorsInline2 = _interopRequireDefault(_decoratorsInline); + + function registerDefaultDecorators(instance) { + _decoratorsInline2['default'](instance); + } + +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _utils = __webpack_require__(4); + + exports['default'] = function (instance) { + instance.registerDecorator('inline', function (fn, props, container, options) { + var ret = fn; + if (!props.partials) { + props.partials = {}; + ret = function (context, options) { + // Create a new partials stack frame prior to exec. + var original = container.partials; + container.partials = _utils.extend({}, original, props.partials); + var ret = fn(context, options); + container.partials = original; + return ret; + }; + } + + props.partials[options.args[0]] = options.fn; + + return ret; + }); + }; + + module.exports = exports['default']; + +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _utils = __webpack_require__(4); + + var logger = { + methodMap: ['debug', 'info', 'warn', 'error'], + level: 'info', + + // Maps a given level value to the `methodMap` indexes above. + lookupLevel: function lookupLevel(level) { + if (typeof level === 'string') { + var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase()); + if (levelMap >= 0) { + level = levelMap; + } else { + level = parseInt(level, 10); + } + } + + return level; + }, + + // Can be overridden in the host environment + log: function log(level) { + level = logger.lookupLevel(level); + + if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) { + var method = logger.methodMap[level]; + if (!console[method]) { + // eslint-disable-line no-console + method = 'log'; + } + + for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + message[_key - 1] = arguments[_key]; + } + + console[method].apply(console, message); // eslint-disable-line no-console + } + } + }; + + exports['default'] = logger; + module.exports = exports['default']; + +/***/ }, +/* 17 */ +/***/ function(module, exports) { + + // Build out our basic SafeString type + 'use strict'; + + exports.__esModule = true; + function SafeString(string) { + this.string = string; + } + + SafeString.prototype.toString = SafeString.prototype.toHTML = function () { + return '' + this.string; + }; + + exports['default'] = SafeString; + module.exports = exports['default']; + +/***/ }, +/* 18 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _interopRequireWildcard = __webpack_require__(1)['default']; + + var _interopRequireDefault = __webpack_require__(2)['default']; + + exports.__esModule = true; + exports.checkRevision = checkRevision; + exports.template = template; + exports.wrapProgram = wrapProgram; + exports.resolvePartial = resolvePartial; + exports.invokePartial = invokePartial; + exports.noop = noop; + + var _utils = __webpack_require__(4); + + var Utils = _interopRequireWildcard(_utils); + + var _exception = __webpack_require__(5); + + var _exception2 = _interopRequireDefault(_exception); + + var _base = __webpack_require__(3); + + function checkRevision(compilerInfo) { + var compilerRevision = compilerInfo && compilerInfo[0] || 1, + currentRevision = _base.COMPILER_REVISION; + + if (compilerRevision !== currentRevision) { + if (compilerRevision < currentRevision) { + var runtimeVersions = _base.REVISION_CHANGES[currentRevision], + compilerVersions = _base.REVISION_CHANGES[compilerRevision]; + throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').'); + } else { + // Use the embedded version info since the runtime doesn't know about this revision yet + throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').'); + } + } + } + + function template(templateSpec, env) { + /* istanbul ignore next */ + if (!env) { + throw new _exception2['default']('No environment passed to template'); + } + if (!templateSpec || !templateSpec.main) { + throw new _exception2['default']('Unknown template object: ' + typeof templateSpec); + } + + templateSpec.main.decorator = templateSpec.main_d; + + // Note: Using env.VM references rather than local var references throughout this section to allow + // for external users to override these as psuedo-supported APIs. + env.VM.checkRevision(templateSpec.compiler); + + function invokePartialWrapper(partial, context, options) { + if (options.hash) { + context = Utils.extend({}, context, options.hash); + if (options.ids) { + options.ids[0] = true; + } + } + + partial = env.VM.resolvePartial.call(this, partial, context, options); + var result = env.VM.invokePartial.call(this, partial, context, options); + + if (result == null && env.compile) { + options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env); + result = options.partials[options.name](context, options); + } + if (result != null) { + if (options.indent) { + var lines = result.split('\n'); + for (var i = 0, l = lines.length; i < l; i++) { + if (!lines[i] && i + 1 === l) { + break; + } + + lines[i] = options.indent + lines[i]; + } + result = lines.join('\n'); + } + return result; + } else { + throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode'); + } + } + + // Just add water + var container = { + strict: function strict(obj, name) { + if (!(name in obj)) { + throw new _exception2['default']('"' + name + '" not defined in ' + obj); + } + return obj[name]; + }, + lookup: function lookup(depths, name) { + var len = depths.length; + for (var i = 0; i < len; i++) { + if (depths[i] && depths[i][name] != null) { + return depths[i][name]; + } + } + }, + lambda: function lambda(current, context) { + return typeof current === 'function' ? current.call(context) : current; + }, + + escapeExpression: Utils.escapeExpression, + invokePartial: invokePartialWrapper, + + fn: function fn(i) { + var ret = templateSpec[i]; + ret.decorator = templateSpec[i + '_d']; + return ret; + }, + + programs: [], + program: function program(i, data, declaredBlockParams, blockParams, depths) { + var programWrapper = this.programs[i], + fn = this.fn(i); + if (data || depths || blockParams || declaredBlockParams) { + programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths); + } else if (!programWrapper) { + programWrapper = this.programs[i] = wrapProgram(this, i, fn); + } + return programWrapper; + }, + + data: function data(value, depth) { + while (value && depth--) { + value = value._parent; + } + return value; + }, + merge: function merge(param, common) { + var obj = param || common; + + if (param && common && param !== common) { + obj = Utils.extend({}, common, param); + } + + return obj; + }, + + noop: env.VM.noop, + compilerInfo: templateSpec.compiler + }; + + function ret(context) { + var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; + + var data = options.data; + + ret._setup(options); + if (!options.partial && templateSpec.useData) { + data = initData(context, data); + } + var depths = undefined, + blockParams = templateSpec.useBlockParams ? [] : undefined; + if (templateSpec.useDepths) { + if (options.depths) { + depths = context !== options.depths[0] ? [context].concat(options.depths) : options.depths; + } else { + depths = [context]; + } + } + + function main(context /*, options*/) { + return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths); + } + main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams); + return main(context, options); + } + ret.isTop = true; + + ret._setup = function (options) { + if (!options.partial) { + container.helpers = container.merge(options.helpers, env.helpers); + + if (templateSpec.usePartial) { + container.partials = container.merge(options.partials, env.partials); + } + if (templateSpec.usePartial || templateSpec.useDecorators) { + container.decorators = container.merge(options.decorators, env.decorators); + } + } else { + container.helpers = options.helpers; + container.partials = options.partials; + container.decorators = options.decorators; + } + }; + + ret._child = function (i, data, blockParams, depths) { + if (templateSpec.useBlockParams && !blockParams) { + throw new _exception2['default']('must pass block params'); + } + if (templateSpec.useDepths && !depths) { + throw new _exception2['default']('must pass parent depths'); + } + + return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths); + }; + return ret; + } + + function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) { + function prog(context) { + var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; + + var currentDepths = depths; + if (depths && context !== depths[0]) { + currentDepths = [context].concat(depths); + } + + return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths); + } + + prog = executeDecorators(fn, prog, container, depths, data, blockParams); + + prog.program = i; + prog.depth = depths ? depths.length : 0; + prog.blockParams = declaredBlockParams || 0; + return prog; + } + + function resolvePartial(partial, context, options) { + if (!partial) { + if (options.name === '@partial-block') { + partial = options.data['partial-block']; + } else { + partial = options.partials[options.name]; + } + } else if (!partial.call && !options.name) { + // This is a dynamic partial that returned a string + options.name = partial; + partial = options.partials[partial]; + } + return partial; + } + + function invokePartial(partial, context, options) { + options.partial = true; + if (options.ids) { + options.data.contextPath = options.ids[0] || options.data.contextPath; + } + + var partialBlock = undefined; + if (options.fn && options.fn !== noop) { + options.data = _base.createFrame(options.data); + partialBlock = options.data['partial-block'] = options.fn; + + if (partialBlock.partials) { + options.partials = Utils.extend({}, options.partials, partialBlock.partials); + } + } + + if (partial === undefined && partialBlock) { + partial = partialBlock; + } + + if (partial === undefined) { + throw new _exception2['default']('The partial ' + options.name + ' could not be found'); + } else if (partial instanceof Function) { + return partial(context, options); + } + } + + function noop() { + return ''; + } + + function initData(context, data) { + if (!data || !('root' in data)) { + data = data ? _base.createFrame(data) : {}; + data.root = context; + } + return data; + } + + function executeDecorators(fn, prog, container, depths, data, blockParams) { + if (fn.decorator) { + var props = {}; + prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths); + Utils.extend(prog, props); + } + return prog; + } + +/***/ }, +/* 19 */ +/***/ function(module, exports) { + + /* WEBPACK VAR INJECTION */(function(global) {/* global window */ + 'use strict'; + + exports.__esModule = true; + + exports['default'] = function (Handlebars) { + /* istanbul ignore next */ + var root = typeof global !== 'undefined' ? global : window, + $Handlebars = root.Handlebars; + /* istanbul ignore next */ + Handlebars.noConflict = function () { + if (root.Handlebars === Handlebars) { + root.Handlebars = $Handlebars; + } + return Handlebars; + }; + }; + + module.exports = exports['default']; + /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) + +/***/ } +/******/ ]) +}); +; \ No newline at end of file diff --git a/app/assets/javascripts/discourse/lib/highlight.js b/vendor/assets/javascripts/highlight.js similarity index 100% rename from app/assets/javascripts/discourse/lib/highlight.js rename to vendor/assets/javascripts/highlight.js diff --git a/vendor/assets/javascripts/jquery.debug.js b/vendor/assets/javascripts/jquery.debug.js index 79d631ff463..1e0ba997403 100644 --- a/vendor/assets/javascripts/jquery.debug.js +++ b/vendor/assets/javascripts/jquery.debug.js @@ -1,15 +1,15 @@ /*! - * jQuery JavaScript Library v2.1.3 + * jQuery JavaScript Library v2.2.0 * http://jquery.com/ * * Includes Sizzle.js * http://sizzlejs.com/ * - * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2014-12-18T15:11Z + * Date: 2016-01-08T20:02Z */ (function( global, factory ) { @@ -41,10 +41,11 @@ // Can't be in strict mode, several libs including ASP.NET trace // the stack via arguments.caller.callee and Firefox dies if // you try to trace through "use strict" call chains. (#13335) -// - +//"use strict"; var arr = []; +var document = window.document; + var slice = arr.slice; var concat = arr.concat; @@ -64,13 +65,11 @@ var support = {}; var - // Use the correct document accordingly with window argument (sandbox) - document = window.document, - - version = "2.1.3", + version = "2.2.0", // Define a local copy of jQuery jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); @@ -90,6 +89,7 @@ var }; jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used jquery: version, @@ -133,16 +133,14 @@ jQuery.fn = jQuery.prototype = { }, // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); + each: function( callback ) { + return jQuery.each( this, callback ); }, map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); - })); + } ) ); }, slice: function() { @@ -160,11 +158,11 @@ jQuery.fn = jQuery.prototype = { eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { - return this.prevObject || this.constructor(null); + return this.prevObject || this.constructor(); }, // For internal use only. @@ -176,7 +174,7 @@ jQuery.fn = jQuery.prototype = { jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, + target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; @@ -191,7 +189,7 @@ jQuery.extend = jQuery.fn.extend = function() { } // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { target = {}; } @@ -202,8 +200,10 @@ jQuery.extend = jQuery.fn.extend = function() { } for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { + if ( ( options = arguments[ i ] ) != null ) { + // Extend the base object for ( name in options ) { src = target[ name ]; @@ -215,13 +215,15 @@ jQuery.extend = jQuery.fn.extend = function() { } // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + if ( copyIsArray ) { copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; + clone = src && jQuery.isArray( src ) ? src : []; } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; + clone = src && jQuery.isPlainObject( src ) ? src : {}; } // Never move original objects, clone them @@ -239,7 +241,8 @@ jQuery.extend = jQuery.fn.extend = function() { return target; }; -jQuery.extend({ +jQuery.extend( { + // Unique for each copy of jQuery on the page expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), @@ -253,7 +256,7 @@ jQuery.extend({ noop: function() {}, isFunction: function( obj ) { - return jQuery.type(obj) === "function"; + return jQuery.type( obj ) === "function"; }, isArray: Array.isArray, @@ -263,14 +266,17 @@ jQuery.extend({ }, isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") // ...but misinterprets leading-number strings, particularly hex literals ("0x...") // subtraction forces infinities to NaN // adding 1 corrects loss of precision from parseFloat (#15100) - return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; }, isPlainObject: function( obj ) { + // Not plain objects: // - Any object or value whose internal [[Class]] property is not "[object Object]" // - DOM nodes @@ -301,9 +307,10 @@ jQuery.extend({ if ( obj == null ) { return obj + ""; } + // Support: Android<4.0, iOS<6 (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call(obj) ] || "object" : + class2type[ toString.call( obj ) ] || "object" : typeof obj; }, @@ -315,16 +322,19 @@ jQuery.extend({ code = jQuery.trim( code ); if ( code ) { + // If the code includes a valid, prologue position // strict mode pragma, execute code by injecting a // script tag into the document. - if ( code.indexOf("use strict") === 1 ) { - script = document.createElement("script"); + if ( code.indexOf( "use strict" ) === 1 ) { + script = document.createElement( "script" ); script.text = code; document.head.appendChild( script ).parentNode.removeChild( script ); } else { - // Otherwise, avoid the DOM node creation, insertion - // and removal by using an indirect global eval + + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + indirect( code ); } } @@ -341,49 +351,20 @@ jQuery.extend({ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }, - // args is for internal usage only - each: function( obj, callback, args ) { - var value, - i = 0, - length = obj.length, - isArray = isArraylike( obj ); + each: function( obj, callback ) { + var length, i = 0; - if ( args ) { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; } } - - // A special, fast, case for the most common use of each } else { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; } } } @@ -403,7 +384,7 @@ jQuery.extend({ var ret = results || []; if ( arr != null ) { - if ( isArraylike( Object(arr) ) ) { + if ( isArrayLike( Object( arr ) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr @@ -455,14 +436,13 @@ jQuery.extend({ // arg is for internal usage only map: function( elems, callback, arg ) { - var value, + var length, value, i = 0, - length = elems.length, - isArray = isArraylike( elems ), ret = []; // Go through the array, translating each of the items to their new values - if ( isArray ) { + if ( isArrayLike( elems ) ) { + length = elems.length; for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); @@ -523,38 +503,50 @@ jQuery.extend({ // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support -}); +} ); + +// JSHint would error on this code due to the Symbol not being defined in ES5. +// Defining this global in .jshintrc would create a danger of using the global +// unguarded in another place, it seems safer to just disable JSHint for these +// three lines. +/* jshint ignore: start */ +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} +/* jshint ignore: end */ // Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); +} ); -function isArraylike( obj ) { - var length = obj.length, +function isArrayLike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, type = jQuery.type( obj ); if ( type === "function" || jQuery.isWindow( obj ) ) { return false; } - if ( obj.nodeType === 1 && length ) { - return true; - } - return type === "array" || length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj; } var Sizzle = /*! - * Sizzle CSS Selector Engine v2.2.0-pre + * Sizzle CSS Selector Engine v2.2.1 * http://sizzlejs.com/ * - * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2014-12-16 + * Date: 2015-10-17 */ (function( window ) { @@ -622,25 +614,21 @@ var i, // Regular expressions - // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/css3-syntax/#characters - characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - // Loosely modeled on CSS identifier characters - // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors - // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = characterEncoding.replace( "w", "w#" ), + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", - pseudos = ":(" + characterEncoding + ")(?:\\((" + + pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + @@ -663,9 +651,9 @@ var i, ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { - "ID": new RegExp( "^#(" + characterEncoding + ")" ), - "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), - "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + @@ -743,103 +731,129 @@ try { } function Sizzle( selector, context, results, seed ) { - var match, elem, m, nodeType, - // QSA vars - i, groups, old, nid, newContext, newSelector; + var m, i, elem, nid, nidselect, match, groups, newSelector, + newContext = context && context.ownerDocument, - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; - context = context || document; results = results || []; - nodeType = context.nodeType; + // Return early from calls with invalid selector or context if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { return results; } - if ( !seed && documentIsHTML ) { + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { - // Try to shortcut find operations when possible (e.g., not under DocumentFragment) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { - // Speed-up: Sizzle("#ID") - if ( (m = match[1]) ) { - if ( nodeType === 9 ) { - elem = context.getElementById( m ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document (jQuery #6963) - if ( elem && elem.parentNode ) { - // Handle the case where IE, Opera, and Webkit return items - // by name instead of ID - if ( elem.id === m ) { results.push( elem ); return results; } - } else { - return results; } - } else { - // Context is not a document - if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && - contains( context, elem ) && elem.id === m ) { - results.push( elem ); - return results; - } - } - // Speed-up: Sizzle("TAG") - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Speed-up: Sizzle(".CLASS") - } else if ( (m = match[3]) && support.getElementsByClassName ) { - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // QSA path - if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - nid = old = expando; - newContext = context; - newSelector = nodeType !== 1 && selector; - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - groups = tokenize( selector ); - - if ( (old = context.getAttribute("id")) ) { - nid = old.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", nid ); - } - nid = "[id='" + nid + "'] "; - - i = groups.length; - while ( i-- ) { - groups[i] = nid + toSelector( groups[i] ); - } - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; - newSelector = groups.join(","); - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); return results; - } catch(qsaError) { - } finally { - if ( !old ) { - context.removeAttribute("id"); + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; + while ( i-- ) { + groups[i] = nidselect + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } } } } @@ -852,7 +866,7 @@ function Sizzle( selector, context, results, seed ) { /** * Create key-value caches of limited size - * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ @@ -907,7 +921,7 @@ function assert( fn ) { */ function addHandle( attrs, handler ) { var arr = attrs.split("|"), - i = attrs.length; + i = arr.length; while ( i-- ) { Expr.attrHandle[ arr[i] ] = handler; @@ -1020,33 +1034,29 @@ setDocument = Sizzle.setDocument = function( node ) { var hasCompare, parent, doc = node ? node.ownerDocument || node : preferredDoc; - // If no document and documentElement is available, return + // Return early if doc is invalid or already selected if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } - // Set our document + // Update global variables document = doc; - docElem = doc.documentElement; - parent = doc.defaultView; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); - // Support: IE>8 - // If iframe document is assigned to "document" variable and if iframe has been reloaded, - // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 - // IE6-8 do not support the defaultView property so parent will be undefined - if ( parent && parent !== parent.top ) { - // IE11 does not have attachEvent, so all must suffer + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( (parent = document.defaultView) && parent.top !== parent ) { + // Support: IE 11 if ( parent.addEventListener ) { parent.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only } else if ( parent.attachEvent ) { parent.attachEvent( "onunload", unloadHandler ); } } - /* Support tests - ---------------------------------------------------------------------- */ - documentIsHTML = !isXML( doc ); - /* Attributes ---------------------------------------------------------------------- */ @@ -1063,12 +1073,12 @@ setDocument = Sizzle.setDocument = function( node ) { // Check if getElementsByTagName("*") returns only elements support.getElementsByTagName = assert(function( div ) { - div.appendChild( doc.createComment("") ); + div.appendChild( document.createComment("") ); return !div.getElementsByTagName("*").length; }); // Support: IE<9 - support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); // Support: IE<10 // Check if getElementById returns elements by name @@ -1076,7 +1086,7 @@ setDocument = Sizzle.setDocument = function( node ) { // so use a roundabout getElementsByName test support.getById = assert(function( div ) { docElem.appendChild( div ).id = expando; - return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + return !document.getElementsByName || !document.getElementsByName( expando ).length; }); // ID find and filter @@ -1084,9 +1094,7 @@ setDocument = Sizzle.setDocument = function( node ) { Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var m = context.getElementById( id ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [ m ] : []; + return m ? [ m ] : []; } }; Expr.filter["ID"] = function( id ) { @@ -1103,7 +1111,8 @@ setDocument = Sizzle.setDocument = function( node ) { Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); return node && node.value === attrId; }; }; @@ -1143,7 +1152,7 @@ setDocument = Sizzle.setDocument = function( node ) { // Class Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( documentIsHTML ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { return context.getElementsByClassName( className ); } }; @@ -1163,7 +1172,7 @@ setDocument = Sizzle.setDocument = function( node ) { // See http://bugs.jquery.com/ticket/13378 rbuggyQSA = []; - if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { // Build QSA regex // Regex strategy adopted from Diego Perini assert(function( div ) { @@ -1173,7 +1182,7 @@ setDocument = Sizzle.setDocument = function( node ) { // since its presence should be enough // http://bugs.jquery.com/ticket/12359 docElem.appendChild( div ).innerHTML = "" + - "" + ""; // Support: IE8, Opera 11-12.16 @@ -1190,7 +1199,7 @@ setDocument = Sizzle.setDocument = function( node ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); } - // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { rbuggyQSA.push("~="); } @@ -1213,7 +1222,7 @@ setDocument = Sizzle.setDocument = function( node ) { assert(function( div ) { // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment - var input = doc.createElement("input"); + var input = document.createElement("input"); input.setAttribute( "type", "hidden" ); div.appendChild( input ).setAttribute( "name", "D" ); @@ -1261,7 +1270,7 @@ setDocument = Sizzle.setDocument = function( node ) { hasCompare = rnative.test( docElem.compareDocumentPosition ); // Element contains another - // Purposefully does not implement inclusive descendent + // Purposefully self-exclusive // As in, an element does not contain itself contains = hasCompare || rnative.test( docElem.contains ) ? function( a, b ) { @@ -1315,10 +1324,10 @@ setDocument = Sizzle.setDocument = function( node ) { (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { // Choose the first element that is related to our preferred document - if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { return -1; } - if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { return 1; } @@ -1346,8 +1355,8 @@ setDocument = Sizzle.setDocument = function( node ) { // Parentless nodes are either documents or disconnected if ( !aup || !bup ) { - return a === doc ? -1 : - b === doc ? 1 : + return a === document ? -1 : + b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? @@ -1384,7 +1393,7 @@ setDocument = Sizzle.setDocument = function( node ) { 0; }; - return doc; + return document; }; Sizzle.matches = function( expr, elements ) { @@ -1401,6 +1410,7 @@ Sizzle.matchesSelector = function( elem, expr ) { expr = expr.replace( rattributeQuotes, "='$1']" ); if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { @@ -1674,11 +1684,12 @@ Expr = Sizzle.selectors = { } : function( elem, context, xml ) { - var cache, outerCache, node, diff, nodeIndex, start, + var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType; + useCache = !xml && !ofType, + diff = false; if ( parent ) { @@ -1687,7 +1698,10 @@ Expr = Sizzle.selectors = { while ( dir ) { node = elem; while ( (node = node[ dir ]) ) { - if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + return false; } } @@ -1701,11 +1715,21 @@ Expr = Sizzle.selectors = { // non-xml :nth-child(...) stores cache data on `parent` if ( forward && useCache ) { + // Seek `elem` from a previously-cached index - outerCache = parent[ expando ] || (parent[ expando ] = {}); - cache = outerCache[ type ] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = cache[0] === dirruns && cache[2]; + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; node = nodeIndex && parent.childNodes[ nodeIndex ]; while ( (node = ++nodeIndex && node && node[ dir ] || @@ -1715,29 +1739,55 @@ Expr = Sizzle.selectors = { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { - outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; break; } } - // Use previously-cached element index if available - } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { - diff = cache[1]; - - // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) } else { - // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); - if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { - // Cache the index of each encountered element - if ( useCache ) { - (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; - } + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); - if ( node === elem ) { - break; + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } } } } @@ -2099,10 +2149,10 @@ function addCombinator( matcher, combinator, base ) { // Check against all ancestor/preceding elements function( elem, context, xml ) { - var oldCache, outerCache, + var oldCache, uniqueCache, outerCache, newCache = [ dirruns, doneName ]; - // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if ( xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { @@ -2115,14 +2165,19 @@ function addCombinator( matcher, combinator, base ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ expando ] || (elem[ expando ] = {}); - if ( (oldCache = outerCache[ dir ]) && + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( (oldCache = uniqueCache[ dir ]) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements return (newCache[ 2 ] = oldCache[ 2 ]); } else { // Reuse newcache so results back-propagate to previous elements - outerCache[ dir ] = newCache; + uniqueCache[ dir ] = newCache; // A match means we're done; a fail means we have to keep checking if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { @@ -2347,18 +2402,21 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) { len = elems.length; if ( outermost ) { - outermostContext = context !== document && context; + outermostContext = context === document || context || outermost; } // Add elements passing elementMatchers directly to results - // Keep `i` a string if there are no elements so `matchedCount` will be "00" below // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id for ( ; i !== len && (elem = elems[i]) != null; i++ ) { if ( byElement && elem ) { j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context, xml ) ) { + if ( matcher( elem, context || document, xml) ) { results.push( elem ); break; } @@ -2382,8 +2440,17 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) { } } - // Apply set filters to unmatched elements + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. if ( bySet && i !== matchedCount ) { j = 0; while ( (matcher = setMatchers[j++]) ) { @@ -2475,10 +2542,11 @@ select = Sizzle.select = function( selector, context, results, seed ) { results = results || []; - // Try to minimize operations if there is no seed and only one group + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) if ( match.length === 1 ) { - // Take a shortcut and set the context if the root selector is an ID + // Reduce context if the leading compound selector is an ID tokens = match[0] = match[0].slice( 0 ); if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && support.getById && context.nodeType === 9 && documentIsHTML && @@ -2533,7 +2601,7 @@ select = Sizzle.select = function( selector, context, results, seed ) { context, !documentIsHTML, results, - rsibling.test( selector ) && testContext( context.parentNode ) || context + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context ); return results; }; @@ -2609,17 +2677,46 @@ return Sizzle; jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.pseudos; -jQuery.unique = Sizzle.uniqueSort; +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + var rneedsContext = jQuery.expr.match.needsContext; -var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); +var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); @@ -2631,14 +2728,14 @@ function winnow( elements, qualifier, not ) { return jQuery.grep( elements, function( elem, i ) { /* jshint -W018 */ return !!qualifier.call( elem, i, elem ) !== not; - }); + } ); } if ( qualifier.nodeType ) { return jQuery.grep( elements, function( elem ) { return ( elem === qualifier ) !== not; - }); + } ); } @@ -2651,8 +2748,8 @@ function winnow( elements, qualifier, not ) { } return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; - }); + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); } jQuery.filter = function( expr, elems, not ) { @@ -2666,10 +2763,10 @@ jQuery.filter = function( expr, elems, not ) { jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { return elem.nodeType === 1; - })); + } ) ); }; -jQuery.fn.extend({ +jQuery.fn.extend( { find: function( selector ) { var i, len = this.length, @@ -2677,13 +2774,13 @@ jQuery.fn.extend({ self = this; if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter(function() { + return this.pushStack( jQuery( selector ).filter( function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } - }) ); + } ) ); } for ( i = 0; i < len; i++ ) { @@ -2696,10 +2793,10 @@ jQuery.fn.extend({ return ret; }, filter: function( selector ) { - return this.pushStack( winnow(this, selector || [], false) ); + return this.pushStack( winnow( this, selector || [], false ) ); }, not: function( selector ) { - return this.pushStack( winnow(this, selector || [], true) ); + return this.pushStack( winnow( this, selector || [], true ) ); }, is: function( selector ) { return !!winnow( @@ -2713,7 +2810,7 @@ jQuery.fn.extend({ false ).length; } -}); +} ); // Initialize a jQuery object @@ -2727,7 +2824,7 @@ var rootjQuery, // Strict HTML recognition (#11290: must start with <) rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - init = jQuery.fn.init = function( selector, context ) { + init = jQuery.fn.init = function( selector, context, root ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) @@ -2735,9 +2832,16 @@ var rootjQuery, return this; } + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + // Handle HTML strings if ( typeof selector === "string" ) { - if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; @@ -2746,23 +2850,24 @@ var rootjQuery, } // Match html or make sure no context is specified for #id - if ( match && (match[1] || !context) ) { + if ( match && ( match[ 1 ] || !context ) ) { // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; // Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge( this, jQuery.parseHTML( - match[1], + match[ 1 ], context && context.nodeType ? context.ownerDocument || context : document, true ) ); // HANDLE: $(html, props) - if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { + // Properties of context are called as methods if possible if ( jQuery.isFunction( this[ match ] ) ) { this[ match ]( context[ match ] ); @@ -2778,14 +2883,15 @@ var rootjQuery, // HANDLE: $(#id) } else { - elem = document.getElementById( match[2] ); + elem = document.getElementById( match[ 2 ] ); // Support: Blackberry 4.6 // gEBID returns nodes no longer in the document (#6963) if ( elem && elem.parentNode ) { + // Inject the element directly into the jQuery object this.length = 1; - this[0] = elem; + this[ 0 ] = elem; } this.context = document; @@ -2795,7 +2901,7 @@ var rootjQuery, // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); + return ( context || root ).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) @@ -2805,15 +2911,16 @@ var rootjQuery, // HANDLE: $(DOMElement) } else if ( selector.nodeType ) { - this.context = this[0] = selector; + this.context = this[ 0 ] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) { - return typeof rootjQuery.ready !== "undefined" ? - rootjQuery.ready( selector ) : + return root.ready !== undefined ? + root.ready( selector ) : + // Execute immediately if ready is not present selector( jQuery ); } @@ -2834,6 +2941,7 @@ rootjQuery = jQuery( document ); var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, @@ -2842,48 +2950,19 @@ var rparentsprev = /^(?:parents|prev(?:Until|All))/, prev: true }; -jQuery.extend({ - dir: function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; - }, - - sibling: function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; - } -}); - -jQuery.fn.extend({ +jQuery.fn.extend( { has: function( target ) { var targets = jQuery( target, this ), l = targets.length; - return this.filter(function() { + return this.filter( function() { var i = 0; for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { + if ( jQuery.contains( this, targets[ i ] ) ) { return true; } } - }); + } ); }, closest: function( selectors, context ) { @@ -2896,14 +2975,15 @@ jQuery.fn.extend({ 0; for ( ; i < l; i++ ) { - for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments - if ( cur.nodeType < 11 && (pos ? - pos.index(cur) > -1 : + if ( cur.nodeType < 11 && ( pos ? + pos.index( cur ) > -1 : // Don't pass non-elements to Sizzle cur.nodeType === 1 && - jQuery.find.matchesSelector(cur, selectors)) ) { + jQuery.find.matchesSelector( cur, selectors ) ) ) { matched.push( cur ); break; @@ -2911,7 +2991,7 @@ jQuery.fn.extend({ } } - return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); }, // Determine the position of an element within the set @@ -2937,7 +3017,7 @@ jQuery.fn.extend({ add: function( selector, context ) { return this.pushStack( - jQuery.unique( + jQuery.uniqueSort( jQuery.merge( this.get(), jQuery( selector, context ) ) ) ); @@ -2945,26 +3025,26 @@ jQuery.fn.extend({ addBack: function( selector ) { return this.add( selector == null ? - this.prevObject : this.prevObject.filter(selector) + this.prevObject : this.prevObject.filter( selector ) ); } -}); +} ); function sibling( cur, dir ) { - while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} return cur; } -jQuery.each({ +jQuery.each( { parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); + return dir( elem, "parentNode" ); }, parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); + return dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); @@ -2973,22 +3053,22 @@ jQuery.each({ return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); + return dir( elem, "nextSibling" ); }, prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); + return dir( elem, "previousSibling" ); }, nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); + return dir( elem, "nextSibling", until ); }, prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); + return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { - return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + return siblings( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { - return jQuery.sibling( elem.firstChild ); + return siblings( elem.firstChild ); }, contents: function( elem ) { return elem.contentDocument || jQuery.merge( [], elem.childNodes ); @@ -3006,9 +3086,10 @@ jQuery.each({ } if ( this.length > 1 ) { + // Remove duplicates if ( !guaranteedUnique[ name ] ) { - jQuery.unique( matched ); + jQuery.uniqueSort( matched ); } // Reverse order for parents* and prev-derivatives @@ -3019,20 +3100,17 @@ jQuery.each({ return this.pushStack( matched ); }; -}); -var rnotwhite = (/\S+/g); +} ); +var rnotwhite = ( /\S+/g ); -// String to Object options format cache -var optionsCache = {}; - -// Convert String-formatted options into Object-formatted ones and store in cache +// Convert String-formatted options into Object-formatted ones function createOptions( options ) { - var object = optionsCache[ options ] = {}; + var object = {}; jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { object[ flag ] = true; - }); + } ); return object; } @@ -3063,156 +3141,186 @@ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? - ( optionsCache[ options ] || createOptions( options ) ) : + createOptions( options ) : jQuery.extend( {}, options ); - var // Last fire value (for non-forgettable lists) + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists memory, + // Flag to know if list was already fired fired, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, + + // Flag to prevent firing + locked, + // Actual callback list list = [], - // Stack of fire calls for repeatable lists - stack = !options.once && [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + // Fire callbacks - fire = function( data ) { - memory = options.memory && data; - fired = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - firing = true; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { - memory = false; // To prevent further calls using add - break; + fire = function() { + + // Enforce single-firing + locked = options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } } } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + firing = false; - if ( list ) { - if ( stack ) { - if ( stack.length ) { - fire( stack.shift() ); - } - } else if ( memory ) { + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { list = []; + + // Otherwise, this object is spent } else { - self.disable(); + list = ""; } } }, + // Actual Callbacks object self = { + // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { - // First, we save the current length - var start = list.length; - (function add( args ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { jQuery.each( args, function( _, arg ) { - var type = jQuery.type( arg ); - if ( type === "function" ) { + if ( jQuery.isFunction( arg ) ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } - } else if ( arg && arg.length && type !== "string" ) { + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + // Inspect recursively add( arg ); } - }); - })( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away - } else if ( memory ) { - firingStart = start; - fire( memory ); + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); } } return this; }, + // Remove a callback from the list remove: function() { - if ( list ) { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - // Handle firing indexes - if ( firing ) { - if ( index <= firingLength ) { - firingLength--; - } - if ( index <= firingIndex ) { - firingIndex--; - } - } + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; } - }); - } + } + } ); return this; }, + // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { - return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; }, + // Remove all callbacks from the list empty: function() { - list = []; - firingLength = 0; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory ) { - self.disable(); + if ( list ) { + list = []; } return this; }, - // Is it locked? - locked: function() { - return !stack; + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + // Call all callbacks with the given context and arguments fireWith: function( context, args ) { - if ( list && ( !fired || stack ) ) { + if ( !locked ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; - if ( firing ) { - stack.push( args ); - } else { - fire( args ); + queue.push( args ); + if ( !firing ) { + fire(); } } return this; }, + // Call all the callbacks with the given arguments fire: function() { self.fireWith( this, arguments ); return this; }, + // To know if the callbacks have already been called at least once fired: function() { return !!fired; @@ -3223,14 +3331,15 @@ jQuery.Callbacks = function( options ) { }; -jQuery.extend({ +jQuery.extend( { Deferred: function( func ) { var tuples = [ + // action, add listener, listener list, final state - [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], - [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], - [ "notify", "progress", jQuery.Callbacks("memory") ] + [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ) ] ], state = "pending", promise = { @@ -3243,25 +3352,30 @@ jQuery.extend({ }, then: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; - return jQuery.Deferred(function( newDefer ) { + return jQuery.Deferred( function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ](function() { + deferred[ tuple[ 1 ] ]( function() { var returned = fn && fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise() + .progress( newDefer.notify ) .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); + .fail( newDefer.reject ); } else { - newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); } - }); - }); + } ); + } ); fns = null; - }).promise(); + } ).promise(); }, + // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { @@ -3279,11 +3393,12 @@ jQuery.extend({ stateString = tuple[ 3 ]; // promise[ done | fail | progress ] = list.add - promise[ tuple[1] ] = list.add; + promise[ tuple[ 1 ] ] = list.add; // Handle state if ( stateString ) { - list.add(function() { + list.add( function() { + // state = [ resolved | rejected ] state = stateString; @@ -3292,12 +3407,12 @@ jQuery.extend({ } // deferred[ resolve | reject | notify ] - deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; - deferred[ tuple[0] + "With" ] = list.fireWith; - }); + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); // Make the deferred a promise promise.promise( deferred ); @@ -3318,9 +3433,11 @@ jQuery.extend({ length = resolveValues.length, // the count of uncompleted subordinates - remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + remaining = length !== 1 || + ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, - // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + // the master Deferred. + // If resolveValues consist of only a single Deferred, just use that. deferred = remaining === 1 ? subordinate : jQuery.Deferred(), // Update function for both resolve and progress values @@ -3346,9 +3463,9 @@ jQuery.extend({ for ( ; i < length; i++ ) { if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { resolveValues[ i ].promise() + .progress( updateFunc( i, progressContexts, progressValues ) ) .done( updateFunc( i, resolveContexts, resolveValues ) ) - .fail( deferred.reject ) - .progress( updateFunc( i, progressContexts, progressValues ) ); + .fail( deferred.reject ); } else { --remaining; } @@ -3362,20 +3479,22 @@ jQuery.extend({ return deferred.promise(); } -}); +} ); // The deferred used on DOM ready var readyList; jQuery.fn.ready = function( fn ) { + // Add the callback jQuery.ready.promise().done( fn ); return this; }; -jQuery.extend({ +jQuery.extend( { + // Is the DOM ready to be used? Set to true once it occurs. isReady: false, @@ -3417,14 +3536,14 @@ jQuery.extend({ jQuery( document ).off( "ready" ); } } -}); +} ); /** * The ready event handler and self cleanup method */ function completed() { - document.removeEventListener( "DOMContentLoaded", completed, false ); - window.removeEventListener( "load", completed, false ); + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); jQuery.ready(); } @@ -3433,20 +3552,23 @@ jQuery.ready.promise = function( obj ) { readyList = jQuery.Deferred(); - // Catch cases where $(document).ready() is called after the browser event has already occurred. - // We once tried to use readyState "interactive" here, but it caused issues like the one - // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 - if ( document.readyState === "complete" ) { + // Catch cases where $(document).ready() is called + // after the browser event has already occurred. + // Support: IE9-10 only + // Older IE sometimes signals "interactive" too soon + if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready - setTimeout( jQuery.ready ); + window.setTimeout( jQuery.ready ); } else { // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed, false ); + document.addEventListener( "DOMContentLoaded", completed ); // A fallback to window.onload, that will always work - window.addEventListener( "load", completed, false ); + window.addEventListener( "load", completed ); } } return readyList.promise( obj ); @@ -3460,7 +3582,7 @@ jQuery.ready.promise(); // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function -var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, len = elems.length, bulk = key == null; @@ -3469,7 +3591,7 @@ var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGe if ( jQuery.type( key ) === "object" ) { chainable = true; for ( i in key ) { - jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + access( elems, fn, i, key[ i ], true, emptyGet, raw ); } // Sets one value @@ -3481,6 +3603,7 @@ var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGe } if ( bulk ) { + // Bulk operations run against the entire set if ( raw ) { fn.call( elems, value ); @@ -3497,7 +3620,11 @@ var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGe if ( fn ) { for ( ; i < len; i++ ) { - fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); } } } @@ -3508,14 +3635,10 @@ var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGe // Gets bulk ? fn.call( elems ) : - len ? fn( elems[0], key ) : emptyGet; + len ? fn( elems[ 0 ], key ) : emptyGet; }; +var acceptData = function( owner ) { - -/** - * Determines whether an object can have data - */ -jQuery.acceptData = function( owner ) { // Accepts only: // - Node // - Node.ELEMENT_NODE @@ -3527,66 +3650,79 @@ jQuery.acceptData = function( owner ) { }; -function Data() { - // Support: Android<4, - // Old WebKit does not have Object.preventExtensions/freeze method, - // return new empty object instead with no [[set]] accessor - Object.defineProperty( this.cache = {}, 0, { - get: function() { - return {}; - } - }); + +function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; -Data.accepts = jQuery.acceptData; Data.prototype = { - key: function( owner ) { + + register: function( owner, initial ) { + var value = initial || {}; + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable, non-writable property + // configurability must be true to allow the property to be + // deleted with the delete operator + } else { + Object.defineProperty( owner, this.expando, { + value: value, + writable: true, + configurable: true + } ); + } + return owner[ this.expando ]; + }, + cache: function( owner ) { + // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. - // Always return the key for a frozen object. - if ( !Data.accepts( owner ) ) { - return 0; + // Always return an empty object. + if ( !acceptData( owner ) ) { + return {}; } - var descriptor = {}, - // Check if the owner object already has a cache key - unlock = owner[ this.expando ]; + // Check if the owner object already has a cache + var value = owner[ this.expando ]; // If not, create one - if ( !unlock ) { - unlock = Data.uid++; + if ( !value ) { + value = {}; - // Secure it in a non-enumerable, non-writable property - try { - descriptor[ this.expando ] = { value: unlock }; - Object.defineProperties( owner, descriptor ); + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { - // Support: Android<4 - // Fallback to a less secure definition - } catch ( e ) { - descriptor[ this.expando ] = unlock; - jQuery.extend( owner, descriptor ); + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } } } - // Ensure the cache object - if ( !this.cache[ unlock ] ) { - this.cache[ unlock ] = {}; - } - - return unlock; + return value; }, set: function( owner, data, value ) { var prop, - // There may be an unlock assigned to this node, - // if there is no entry for this "owner", create one inline - // and set the unlock as though an owner entry had always existed - unlock = this.key( owner ), - cache = this.cache[ unlock ]; + cache = this.cache( owner ); // Handle: [ owner, key, value ] args if ( typeof data === "string" ) { @@ -3594,30 +3730,22 @@ Data.prototype = { // Handle: [ owner, { properties } ] args } else { - // Fresh assignments by object are shallow copied - if ( jQuery.isEmptyObject( cache ) ) { - jQuery.extend( this.cache[ unlock ], data ); - // Otherwise, copy the properties one-by-one to the cache object - } else { - for ( prop in data ) { - cache[ prop ] = data[ prop ]; - } + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ prop ] = data[ prop ]; } } return cache; }, get: function( owner, key ) { - // Either a valid cache is found, or will be created. - // New caches will be created and the unlock returned, - // allowing direct access to the newly created - // empty data object. A valid owner object must be provided. - var cache = this.cache[ this.key( owner ) ]; - return key === undefined ? - cache : cache[ key ]; + this.cache( owner ) : + owner[ this.expando ] && owner[ this.expando ][ key ]; }, access: function( owner, key, value ) { var stored; + // In cases where either: // // 1. No key was specified @@ -3630,15 +3758,15 @@ Data.prototype = { // 2. The data stored at the key // if ( key === undefined || - ((key && typeof key === "string") && value === undefined) ) { + ( ( key && typeof key === "string" ) && value === undefined ) ) { stored = this.get( owner, key ); return stored !== undefined ? - stored : this.get( owner, jQuery.camelCase(key) ); + stored : this.get( owner, jQuery.camelCase( key ) ); } - // [*]When the key is not a string, or both a key and value + // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties @@ -3652,15 +3780,20 @@ Data.prototype = { }, remove: function( owner, key ) { var i, name, camel, - unlock = this.key( owner ), - cache = this.cache[ unlock ]; + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } if ( key === undefined ) { - this.cache[ unlock ] = {}; + this.register( owner ); } else { + // Support array or space separated string of keys if ( jQuery.isArray( key ) ) { + // If "name" is an array of keys... // When data is initially created, via ("key", "val") signature, // keys will be converted to camelCase. @@ -3670,10 +3803,12 @@ Data.prototype = { name = key.concat( key.map( jQuery.camelCase ) ); } else { camel = jQuery.camelCase( key ); + // Try the string as a key before any manipulation if ( key in cache ) { name = [ key, camel ]; } else { + // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace name = camel; @@ -3683,25 +3818,34 @@ Data.prototype = { } i = name.length; + while ( i-- ) { delete cache[ name[ i ] ]; } } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <= 35-45+ + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://code.google.com/p/chromium/issues/detail?id=378607 + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } }, hasData: function( owner ) { - return !jQuery.isEmptyObject( - this.cache[ owner[ this.expando ] ] || {} - ); - }, - discard: function( owner ) { - if ( owner[ this.expando ] ) { - delete this.cache[ owner[ this.expando ] ]; - } + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); } }; -var data_priv = new Data(); +var dataPriv = new Data(); -var data_user = new Data(); +var dataUser = new Data(); @@ -3716,7 +3860,7 @@ var data_user = new Data(); // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /([A-Z])/g; + rmultiDash = /[A-Z]/g; function dataAttr( elem, key, data ) { var name; @@ -3724,7 +3868,7 @@ function dataAttr( elem, key, data ) { // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { @@ -3732,14 +3876,15 @@ function dataAttr( elem, key, data ) { data = data === "true" ? true : data === "false" ? false : data === "null" ? null : + // Only convert to a number if it doesn't change the string +data + "" === data ? +data : rbrace.test( data ) ? jQuery.parseJSON( data ) : data; - } catch( e ) {} + } catch ( e ) {} // Make sure we set the data so it isn't changed later - data_user.set( elem, key, data ); + dataUser.set( elem, key, data ); } else { data = undefined; } @@ -3747,31 +3892,31 @@ function dataAttr( elem, key, data ) { return data; } -jQuery.extend({ +jQuery.extend( { hasData: function( elem ) { - return data_user.hasData( elem ) || data_priv.hasData( elem ); + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { - return data_user.access( elem, name, data ); + return dataUser.access( elem, name, data ); }, removeData: function( elem, name ) { - data_user.remove( elem, name ); + dataUser.remove( elem, name ); }, // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to data_priv methods, these can be deprecated. + // with direct calls to dataPriv methods, these can be deprecated. _data: function( elem, name, data ) { - return data_priv.access( elem, name, data ); + return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { - data_priv.remove( elem, name ); + dataPriv.remove( elem, name ); } -}); +} ); -jQuery.fn.extend({ +jQuery.fn.extend( { data: function( key, value ) { var i, name, data, elem = this[ 0 ], @@ -3780,9 +3925,9 @@ jQuery.fn.extend({ // Gets all values if ( key === undefined ) { if ( this.length ) { - data = data_user.get( elem ); + data = dataUser.get( elem ); - if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { i = attrs.length; while ( i-- ) { @@ -3791,12 +3936,12 @@ jQuery.fn.extend({ if ( attrs[ i ] ) { name = attrs[ i ].name; if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice(5) ); + name = jQuery.camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } } - data_priv.set( elem, "hasDataAttrs", true ); + dataPriv.set( elem, "hasDataAttrs", true ); } } @@ -3805,14 +3950,13 @@ jQuery.fn.extend({ // Sets multiple values if ( typeof key === "object" ) { - return this.each(function() { - data_user.set( this, key ); - }); + return this.each( function() { + dataUser.set( this, key ); + } ); } return access( this, function( value ) { - var data, - camelKey = jQuery.camelCase( key ); + var data, camelKey; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the @@ -3820,16 +3964,24 @@ jQuery.fn.extend({ // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if ( elem && value === undefined ) { + // Attempt to get data from the cache // with the key as-is - data = data_user.get( elem, key ); + data = dataUser.get( elem, key ) || + + // Try to find dashed key if it exists (gh-2779) + // This is for 2.2.x only + dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() ); + if ( data !== undefined ) { return data; } + camelKey = jQuery.camelCase( key ); + // Attempt to get data from the cache // with the key camelized - data = data_user.get( elem, camelKey ); + data = dataUser.get( elem, camelKey ); if ( data !== undefined ) { return data; } @@ -3846,46 +3998,48 @@ jQuery.fn.extend({ } // Set the data... - this.each(function() { + camelKey = jQuery.camelCase( key ); + this.each( function() { + // First, attempt to store a copy or reference of any // data that might've been store with a camelCased key. - var data = data_user.get( this, camelKey ); + var data = dataUser.get( this, camelKey ); // For HTML5 data-* attribute interop, we have to // store property names with dashes in a camelCase form. // This might not apply to all properties...* - data_user.set( this, camelKey, value ); + dataUser.set( this, camelKey, value ); // *... In the case of properties that might _actually_ // have dashes, we need to also store a copy of that // unchanged property. - if ( key.indexOf("-") !== -1 && data !== undefined ) { - data_user.set( this, key, value ); + if ( key.indexOf( "-" ) > -1 && data !== undefined ) { + dataUser.set( this, key, value ); } - }); + } ); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { - return this.each(function() { - data_user.remove( this, key ); - }); + return this.each( function() { + dataUser.remove( this, key ); + } ); } -}); +} ); -jQuery.extend({ +jQuery.extend( { queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; - queue = data_priv.get( elem, type ); + queue = dataPriv.get( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || jQuery.isArray( data ) ) { - queue = data_priv.access( elem, type, jQuery.makeArray(data) ); + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); } else { queue.push( data ); } @@ -3932,15 +4086,15 @@ jQuery.extend({ // Not public - generate a queueHooks object, or return the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; - return data_priv.get( elem, key ) || data_priv.access( elem, key, { - empty: jQuery.Callbacks("once memory").add(function() { - data_priv.remove( elem, [ type + "queue", key ] ); - }) - }); + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); } -}); +} ); -jQuery.fn.extend({ +jQuery.fn.extend( { queue: function( type, data ) { var setter = 2; @@ -3951,30 +4105,31 @@ jQuery.fn.extend({ } if ( arguments.length < setter ) { - return jQuery.queue( this[0], type ); + return jQuery.queue( this[ 0 ], type ); } return data === undefined ? this : - this.each(function() { + this.each( function() { var queue = jQuery.queue( this, type, data ); // Ensure a hooks for this queue jQuery._queueHooks( this, type ); - if ( type === "fx" && queue[0] !== "inprogress" ) { + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { jQuery.dequeue( this, type ); } - }); + } ); }, dequeue: function( type ) { - return this.each(function() { + return this.each( function() { jQuery.dequeue( this, type ); - }); + } ); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, + // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { @@ -3996,7 +4151,7 @@ jQuery.fn.extend({ type = type || "fx"; while ( i-- ) { - tmp = data_priv.get( elements[ i ], type + "queueHooks" ); + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); @@ -4005,28 +4160,243 @@ jQuery.fn.extend({ resolve(); return defer.promise( obj ); } -}); -var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; - return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + return jQuery.css( elem, "display" ) === "none" || + !jQuery.contains( elem.ownerDocument, elem ); }; -var rcheckableType = (/^(?:checkbox|radio)$/i); + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { return tween.cur(); } : + function() { return jQuery.css( elem, prop, "" ); }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([\w:-]+)/ ); + +var rscriptType = ( /^$|\/(?:java|ecma)script/i ); -(function() { +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE9 + option: [ 1, "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
    " ], + col: [ 2, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + _default: [ 0, "", "" ] +}; + +// Support: IE9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE9-11+ + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== "undefined" ? + context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { var fragment = document.createDocumentFragment(), div = fragment.appendChild( document.createElement( "div" ) ), input = document.createElement( "input" ); - // Support: Safari<=5.1 + // Support: Android 4.0-4.3, Safari<=5.1 // Check state lost if the name is set (#11217) // Support: Windows Web Apps (WWA) // `name` and `type` must use .setAttribute for WWA (#14901) @@ -4044,19 +4414,13 @@ var rcheckableType = (/^(?:checkbox|radio)$/i); // Make sure textarea (and checkbox) defaultValue is properly cloned div.innerHTML = ""; support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; -})(); -var strundefined = typeof undefined; - - - -support.focusinBubbles = "onfocusin" in window; +} )(); var rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; @@ -4066,12 +4430,75 @@ function returnFalse() { return false; } +// Support: IE9 +// See #13393 for more info function safeActiveElement() { try { return document.activeElement; } catch ( err ) { } } +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. @@ -4085,7 +4512,7 @@ jQuery.event = { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, - elemData = data_priv.get( elem ); + elemData = dataPriv.get( elem ); // Don't attach events to noData or text/comment nodes (but allow plain objects) if ( !elemData ) { @@ -4105,14 +4532,15 @@ jQuery.event = { } // Init the element's event structure and main handler, if this is the first - if ( !(events = elemData.events) ) { + if ( !( events = elemData.events ) ) { events = elemData.events = {}; } - if ( !(eventHandle = elemData.handle) ) { + if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded - return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply( elem, arguments ) : undefined; }; } @@ -4121,9 +4549,9 @@ jQuery.event = { types = ( types || "" ).match( rnotwhite ) || [ "" ]; t = types.length; while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // There *must* be a type, no attaching namespace-only handlers if ( !type ) { @@ -4140,7 +4568,7 @@ jQuery.event = { special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers - handleObj = jQuery.extend({ + handleObj = jQuery.extend( { type: type, origType: origType, data: data, @@ -4148,18 +4576,20 @@ jQuery.event = { guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join(".") + namespace: namespaces.join( "." ) }, handleObjIn ); // Init the event handler queue if we're the first - if ( !(handlers = events[ type ]) ) { + if ( !( handlers = events[ type ] ) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); + elem.addEventListener( type, eventHandle ); } } } @@ -4191,9 +4621,9 @@ jQuery.event = { var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, - elemData = data_priv.hasData( elem ) && data_priv.get( elem ); + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - if ( !elemData || !(events = elemData.events) ) { + if ( !elemData || !( events = elemData.events ) ) { return; } @@ -4201,9 +4631,9 @@ jQuery.event = { types = ( types || "" ).match( rnotwhite ) || [ "" ]; t = types.length; while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { @@ -4216,7 +4646,8 @@ jQuery.event = { special = jQuery.event.special[ type ] || {}; type = ( selector ? special.delegateType : special.bindType ) || type; handlers = events[ type ] || []; - tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); // Remove matching events origCount = j = handlers.length; @@ -4226,7 +4657,8 @@ jQuery.event = { if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { handlers.splice( j, 1 ); if ( handleObj.selector ) { @@ -4241,7 +4673,9 @@ jQuery.event = { // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( origCount && !handlers.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); } @@ -4249,145 +4683,12 @@ jQuery.event = { } } - // Remove the expando if it's no longer used + // Remove data and the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { - delete elemData.handle; - data_priv.remove( elem, "events" ); + dataPriv.remove( elem, "handle events" ); } }, - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf(".") >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf(":") < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join("."); - event.namespace_re = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === (elem.ownerDocument || document) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && jQuery.acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && - jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - dispatch: function( event ) { // Make a writable jQuery.Event from the native event object @@ -4396,11 +4697,11 @@ jQuery.event = { var i, j, ret, matched, handleObj, handlerQueue = [], args = slice.call( arguments ), - handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; + args[ 0 ] = event; event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired @@ -4413,24 +4714,25 @@ jQuery.event = { // Run delegates first; they may want to stop propagation beneath us i = 0; - while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; j = 0; - while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { // Triggered event must either 1) have no namespace, or 2) have namespace(s) // a subset or equal to those in the bound event (both can have no namespace). - if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); if ( ret !== undefined ) { - if ( (event.result = ret) === false ) { + if ( ( event.result = ret ) === false ) { event.preventDefault(); event.stopPropagation(); } @@ -4453,15 +4755,20 @@ jQuery.event = { delegateCount = handlers.delegateCount, cur = event.target; + // Support (at least): Chrome, IE9 // Find delegate handlers // Black-hole SVG instance trees (#13180) - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + // + // Support: Firefox<=42+ + // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) + if ( delegateCount && cur.nodeType && + ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { for ( ; cur !== this; cur = cur.parentNode || this ) { + // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.disabled !== true || event.type !== "click" ) { + if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { matches = []; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; @@ -4471,7 +4778,7 @@ jQuery.event = { if ( matches[ sel ] === undefined ) { matches[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) >= 0 : + jQuery( sel, this ).index( cur ) > -1 : jQuery.find( sel, this, null, [ cur ] ).length; } if ( matches[ sel ] ) { @@ -4479,7 +4786,7 @@ jQuery.event = { } } if ( matches.length ) { - handlerQueue.push({ elem: cur, handlers: matches }); + handlerQueue.push( { elem: cur, handlers: matches } ); } } } @@ -4487,19 +4794,20 @@ jQuery.event = { // Add the remaining (directly-bound) handlers if ( delegateCount < handlers.length ) { - handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); } return handlerQueue; }, // Includes some event props shared by KeyEvent and MouseEvent - props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + + "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), fixHooks: {}, keyHooks: { - props: "char charCode key keyCode".split(" "), + props: "char charCode key keyCode".split( " " ), filter: function( event, original ) { // Add which for key events @@ -4512,7 +4820,8 @@ jQuery.event = { }, mouseHooks: { - props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " + + "screenX screenY toElement" ).split( " " ), filter: function( event, original ) { var eventDoc, doc, body, button = original.button; @@ -4523,8 +4832,12 @@ jQuery.event = { doc = eventDoc.documentElement; body = eventDoc.body; - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + event.pageX = original.clientX + + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - + ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - + ( doc && doc.clientTop || body && body.clientTop || 0 ); } // Add which for click: 1 === left; 2 === middle; 3 === right @@ -4581,10 +4894,12 @@ jQuery.event = { special: { load: { + // Prevent triggered image.load events from bubbling to window.load noBubble: true }, focus: { + // Fire native event if possible so blur/focus sequence is correct trigger: function() { if ( this !== safeActiveElement() && this.focus ) { @@ -4604,6 +4919,7 @@ jQuery.event = { delegateType: "focusout" }, click: { + // For checkbox, fire native event so checked state will be right trigger: function() { if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { @@ -4628,41 +4944,21 @@ jQuery.event = { } } } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } } }; jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); + elem.removeEventListener( type, handle ); } }; jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { + if ( !( this instanceof jQuery.Event ) ) { return new jQuery.Event( src, props ); } @@ -4675,6 +4971,7 @@ jQuery.Event = function( src, props ) { // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && + // Support: Android<4.0 src.returnValue === false ? returnTrue : @@ -4700,6 +4997,7 @@ jQuery.Event = function( src, props ) { // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { + constructor: jQuery.Event, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, @@ -4709,7 +5007,7 @@ jQuery.Event.prototype = { this.isDefaultPrevented = returnTrue; - if ( e && e.preventDefault ) { + if ( e ) { e.preventDefault(); } }, @@ -4718,7 +5016,7 @@ jQuery.Event.prototype = { this.isPropagationStopped = returnTrue; - if ( e && e.stopPropagation ) { + if ( e ) { e.stopPropagation(); } }, @@ -4727,7 +5025,7 @@ jQuery.Event.prototype = { this.isImmediatePropagationStopped = returnTrue; - if ( e && e.stopImmediatePropagation ) { + if ( e ) { e.stopImmediatePropagation(); } @@ -4736,8 +5034,14 @@ jQuery.Event.prototype = { }; // Create mouseenter/leave events using mouseover/out and event-time checks -// Support: Chrome 15+ -jQuery.each({ +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://code.google.com/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", @@ -4753,9 +5057,9 @@ jQuery.each({ related = event.relatedTarget, handleObj = event.handleObj; - // For mousenter/leave call the handler if related is outside the target. + // For mouseenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; @@ -4763,115 +5067,32 @@ jQuery.each({ return ret; } }; -}); +} ); -// Support: Firefox, Chrome, Safari -// Create "bubbling" focus and blur events -if ( !support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - var doc = this.ownerDocument || this, - attaches = data_priv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this, - attaches = data_priv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - data_priv.remove( doc, fix ); - - } else { - data_priv.access( doc, fix, attaches ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); +jQuery.fn.extend( { + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); }, one: function( types, selector, data, fn ) { - return this.on( types, selector, data, fn, 1 ); + return on( this, types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( - handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { + // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); @@ -4879,6 +5100,7 @@ jQuery.fn.extend({ return this; } if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) fn = selector; selector = undefined; @@ -4886,70 +5108,39 @@ jQuery.fn.extend({ if ( fn === false ) { fn = returnFalse; } - return this.each(function() { + return this.each( function() { jQuery.event.remove( this, types, fn, selector ); - }); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - var elem = this[0]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } + } ); } -}); +} ); var - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, - rtagName = /<([\w:]+)/, - rhtml = /<|&#?\w+;/, - rnoInnerhtml = /<(?:script|style|link)/i, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, + + // Support: IE 10-11, Edge 10240+ + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g, + rcleanScript = /^\s*\s*$/g; - // We have to close these tags to support XHTML (#13200) - wrapMap = { - - // Support: IE9 - option: [ 1, "" ], - - thead: [ 1, "", "
    " ], - col: [ 2, "", "
    " ], - tr: [ 2, "", "
    " ], - td: [ 3, "", "
    " ], - - _default: [ 0, "", "" ] - }; - -// Support: IE9 -wrapMap.optgroup = wrapMap.option; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// Support: 1.x compatibility -// Manipulating tables requires a tbody function manipulationTarget( elem, content ) { - return jQuery.nodeName( elem, "table" ) && - jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + if ( jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - elem.getElementsByTagName("tbody")[0] || - elem.appendChild( elem.ownerDocument.createElement("tbody") ) : - elem; + return elem.getElementsByTagName( "tbody" )[ 0 ] || elem; + } + + return elem; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { - elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; return elem; } function restoreScript( elem ) { @@ -4958,24 +5149,12 @@ function restoreScript( elem ) { if ( match ) { elem.type = match[ 1 ]; } else { - elem.removeAttribute("type"); + elem.removeAttribute( "type" ); } return elem; } -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - data_priv.set( - elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) - ); - } -} - function cloneCopyEvent( src, dest ) { var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; @@ -4984,9 +5163,9 @@ function cloneCopyEvent( src, dest ) { } // 1. Copy private data: events, handlers, etc. - if ( data_priv.hasData( src ) ) { - pdataOld = data_priv.access( src ); - pdataCur = data_priv.set( dest, pdataOld ); + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); events = pdataOld.events; if ( events ) { @@ -5002,24 +5181,14 @@ function cloneCopyEvent( src, dest ) { } // 2. Copy user data - if ( data_user.hasData( src ) ) { - udataOld = data_user.access( src ); + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); udataCur = jQuery.extend( {}, udataOld ); - data_user.set( dest, udataCur ); + dataUser.set( dest, udataCur ); } } -function getAll( context, tag ) { - var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : - context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : - []; - - return tag === undefined || tag && jQuery.nodeName( context, tag ) ? - jQuery.merge( [ context ], ret ) : - ret; -} - // Fix IE bugs, see support tests function fixInput( src, dest ) { var nodeName = dest.nodeName.toLowerCase(); @@ -5034,7 +5203,122 @@ function fixInput( src, dest ) { } } -jQuery.extend({ +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + clone: function( elem, dataAndEvents, deepDataAndEvents ) { var i, l, srcElements, destElements, clone = elem.cloneNode( true ), @@ -5077,102 +5361,14 @@ jQuery.extend({ return clone; }, - buildFragment: function( elems, context, scripts, selection ) { - var elem, tmp, tag, wrap, contains, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { - // Support: QtWebKit, PhantomJS - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement("div") ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: QtWebKit, PhantomJS - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( (elem = nodes[ i++ ]) ) { - - // #4087 - If origin and destination elements are the same, and this is - // that element, do not do anything - if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( (elem = tmp[ j++ ]) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; - }, - cleanData: function( elems ) { - var data, elem, type, key, + var data, elem, type, special = jQuery.event.special, i = 0; - for ( ; (elem = elems[ i ]) !== undefined; i++ ) { - if ( jQuery.acceptData( elem ) ) { - key = elem[ data_priv.expando ]; - - if ( key && (data = data_priv.cache[ key ]) ) { + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { @@ -5184,91 +5380,86 @@ jQuery.extend({ } } } - if ( data_priv.cache[ key ] ) { - // Discard any remaining `private` data - delete data_priv.cache[ key ]; - } + + // Support: Chrome <= 35-45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <= 35-45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; } } - // Discard any remaining `user` data - delete data_user.cache[ elem[ data_user.expando ] ]; } } -}); +} ); + +jQuery.fn.extend( { + + // Keep domManip exposed until 3.0 (gh-2225) + domManip: domManip, + + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, -jQuery.fn.extend({ text: function( value ) { return access( this, function( value ) { return value === undefined ? jQuery.text( this ) : - this.empty().each(function() { + this.empty().each( function() { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.textContent = value; } - }); + } ); }, null, value, arguments.length ); }, append: function() { - return this.domManip( arguments, function( elem ) { + return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.appendChild( elem ); } - }); + } ); }, prepend: function() { - return this.domManip( arguments, function( elem ) { + return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.insertBefore( elem, target.firstChild ); } - }); + } ); }, before: function() { - return this.domManip( arguments, function( elem ) { + return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } - }); + } ); }, after: function() { - return this.domManip( arguments, function( elem ) { + return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } - }); - }, - - remove: function( selector, keepData /* Internal Use Only */ ) { - var elem, - elems = selector ? jQuery.filter( selector, this ) : this, - i = 0; - - for ( ; (elem = elems[i]) != null; i++ ) { - if ( !keepData && elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem ) ); - } - - if ( elem.parentNode ) { - if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { - setGlobalEval( getAll( elem, "script" ) ); - } - elem.parentNode.removeChild( elem ); - } - } - - return this; + } ); }, empty: function() { var elem, i = 0; - for ( ; (elem = this[i]) != null; i++ ) { + for ( ; ( elem = this[ i ] ) != null; i++ ) { if ( elem.nodeType === 1 ) { // Prevent memory leaks @@ -5286,9 +5477,9 @@ jQuery.fn.extend({ dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - return this.map(function() { + return this.map( function() { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - }); + } ); }, html: function( value ) { @@ -5305,7 +5496,7 @@ jQuery.fn.extend({ if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - value = value.replace( rxhtmlTag, "<$1>" ); + value = jQuery.htmlPrefilter( value ); try { for ( ; i < l; i++ ) { @@ -5321,7 +5512,7 @@ jQuery.fn.extend({ elem = 0; // If using innerHTML throws an exception, use the fallback method - } catch( e ) {} + } catch ( e ) {} } if ( elem ) { @@ -5331,115 +5522,25 @@ jQuery.fn.extend({ }, replaceWith: function() { - var arg = arguments[ 0 ]; + var ignored = []; - // Make the changes, replacing each context element with the new content - this.domManip( arguments, function( elem ) { - arg = this.parentNode; + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; - jQuery.cleanData( getAll( this ) ); - - if ( arg ) { - arg.replaceChild( elem, this ); - } - }); - - // Force removal if there was no new content (e.g., from empty arguments) - return arg && (arg.length || arg.nodeType) ? this : this.remove(); - }, - - detach: function( selector ) { - return this.remove( selector, true ); - }, - - domManip: function( args, callback ) { - - // Flatten any nested arrays - args = concat.apply( [], args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = this.length, - set = this, - iNoClone = l - 1, - value = args[ 0 ], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return this.each(function( index ) { - var self = set.eq( index ); - if ( isFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - self.domManip( args, callback ); - }); - } - - if ( l ) { - fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - if ( first ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - // Support: QtWebKit - // jQuery.merge because push.apply(_, arraylike) throws - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( this[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { - - if ( node.src ) { - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); - } - } else { - jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); - } - } - } + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); } } - } - return this; + // Force callback invocation + }, ignored ); } -}); +} ); -jQuery.each({ +jQuery.each( { appendTo: "append", prependTo: "prepend", insertBefore: "before", @@ -5464,28 +5565,29 @@ jQuery.each({ return this.pushStack( ret ); }; -}); +} ); var iframe, - elemdisplay = {}; + elemdisplay = { + + // Support: Firefox + // We have to pre-define these values for FF (#10227) + HTML: "block", + BODY: "block" + }; /** * Retrieve the actual display of a element * @param {String} name nodeName of the element * @param {Object} doc Document object */ + // Called only from within defaultDisplay function actualDisplay( name, doc ) { - var style, - elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), - // getDefaultComputedStyle might be reliably used only on attached element - display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? - - // Use of this method is a temporary fix (more like optimization) until something better comes along, - // since it was removed from specification and supported only in FF - style.display : jQuery.css( elem[ 0 ], "display" ); + display = jQuery.css( elem[ 0 ], "display" ); // We don't have any data stored on the element, // so use "detach" method as fast way to get rid of the element @@ -5509,7 +5611,8 @@ function defaultDisplay( nodeName ) { if ( display === "none" || !display ) { // Use the already-created iframe if possible - iframe = (iframe || jQuery( "